package main import ( "bufio" "database/sql" "fmt" "log" "os" "strconv" "strings" "time" _ "github.com/go-sql-driver/mysql" "github.com/xconstruct/go-pushbullet" ) const NAME string = "Tʜᴇ Lᴏʀᴅ" var BibleDB *sql.DB var BibleQuery *sql.Stmt var Client *RDramaClient var WAIT_TIME time.Duration var ONE_SEC time.Duration var BibleBotID int func main() { ERRCOUNT := 0 WAIT_TIME, err := time.ParseDuration("1m") if err != nil { log.Fatal("Error parsing time") } time.Sleep(WAIT_TIME) ONE_SEC, err = time.ParseDuration("1s") if err != nil { log.Fatal("Error parsing time 2") } fmt.Printf("Running...\n") siteURL := os.Getenv("RDRAMA_URL") if siteURL == "" { log.Fatal("RDRAMA_URL environment variable not set") } siteToken := os.Getenv("RDRAMA_API_TOKEN") if siteToken == "" { log.Fatal("RDRAMA_API_TOKEN environment variable not set") } botId := os.Getenv("BIBLEBOT_ID") if botId == "" { log.Fatal("BIBLEBOT_ID environment variable not set") } BibleBotID, err = strconv.Atoi(botId) if err != nil { log.Fatal("Error loading BIBLEBOT_ID: ", botId) } Client = NewRDramaClient(siteURL, siteToken) username := os.Getenv("MARIADB_USER") password := os.Getenv("MARIADB_PASSWORD") host := os.Getenv("BIBLEDB_HOST") database := os.Getenv("MARIADB_DATABASE") for ERRCOUNT < 5 { BibleDB, err = sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s", username, password, host, database)) if err != nil { fmt.Println("ERROR connecting: ", err) fmt.Println("DB string: ", fmt.Sprintf("%s:%s@tcp(%s)/%s", username, password, host, database)) ERRCOUNT = ERRCOUNT + 1 time.Sleep(WAIT_TIME) } else { ERRCOUNT = 0 break } } defer BibleDB.Close() BibleQuery, err = BibleDB.Prepare("SELECT t FROM t_web WHERE id BETWEEN ? AND ?") if err != nil { fmt.Println(err) log.Fatal("Unable to prepare query") } defer BibleQuery.Close() now := time.Now() lastrun := time.Date(now.Year(), now.Month(), now.Day(), now.Hour()-1, 0, 0, 0, time.UTC) file, err := os.Open("lastrun.txt") if err == nil { // Create a new scanner to read the file scanner := bufio.NewScanner(file) // Read the first line of the file scanner.Scan() line := scanner.Text() // Convert the line to an integer num, err := strconv.ParseInt(line, 10, 64) if err == nil { newTime := time.Unix(num, 0) // fmt.Println("New time: ", newTime) if newTime != time.Unix(0, 0) { lastrun = newTime } } else { fmt.Println("error parsing time", err) } file.Close() } else { fmt.Println("Err opening lastrun: ", err) } for ERRCOUNT < 5 { fmt.Println("\n\n-------------------------------------------------------") fmt.Printf("Posts between %v - %v\n", lastrun, now) posts, err := Client.GetPosts(SearchParams{ Hole: "dankchristianmemes", After: lastrun, Before: now, }) if err == nil { fmt.Printf("Found posts: %d\n", len(posts)) for _, post := range posts { // fmt.Printf("%s: %s\n", comment.AuthorName, comment.Text) if post.Author.ID != BibleBotID { // originally forgot this lol handleAndReply(fmt.Sprintf("%s\n%s", post.Title, post.Text), fmt.Sprintf("p_%v", post.ID)) } else { fmt.Println("Skipping own post") } } } else { ERRCOUNT = ERRCOUNT + 1 time.Sleep(WAIT_TIME) now = time.Now() continue } fmt.Printf("Comments between %v - %v\n", lastrun, now) comments, err := Client.GetComments(SearchParams{ Hole: "dankchristianmemes", After: lastrun, Before: now, }) if err == nil { fmt.Printf("Found comments: %d\n", len(comments)) for _, comment := range comments { // fmt.Printf("%s: %s\n", comment.AuthorName, comment.Text) if comment.Author.ID != BibleBotID { handleAndReply(comment.Text, fmt.Sprintf("c_%v", comment.ID)) } else { fmt.Println("Skipping own comment") } // Client.UpvoteComment(comment.ID) // not allowed for bots } lastrun = now.Add(ONE_SEC) file, err = os.Create("lastrun.txt") if err == nil { _, err = file.WriteString(strconv.FormatInt(lastrun.Unix(), 10)) if err != nil { fmt.Println("FILE ERROR: ", err) } err = file.Sync() if err != nil { fmt.Println("FILE ERROR: ", err) } file.Close() } if err != nil { fmt.Println("FILE ERROR: ", err) } } else { fmt.Println(err) ERRCOUNT = ERRCOUNT + 1 } time.Sleep(WAIT_TIME) now = time.Now() } // tell pushbullet that Biblebot failed pushbullet_key := os.Getenv("PUSHBULLET_KEY") pushbullet_device := os.Getenv("PUSHBULLET_DEVICE_ID") if pushbullet_key != "" && pushbullet_device != "" { pb := pushbullet.New(pushbullet_key) err = pb.PushNote(pushbullet_device, "Biblebot shut down due to error", err.Error()) if err != nil { fmt.Println("Pushbullet error reporting failed") } } } func handleAndReply(text string, parent_fullname string) { refs := GetReferences(strings.ToUpper(text)) if len(refs) == 0 { return } var post strings.Builder for _, ref := range refs { rows, err := BibleQuery.Query(ref.StartKey, ref.EndKey) if err != nil { fmt.Println(err) continue } canName, err := ref.CanonicalName() post.WriteString("**") if err != nil { post.WriteString(ref.RegexMatch) } else { post.WriteString(canName) } post.WriteString("**\n> ") for rows.Next() { var verse string err = rows.Scan(&verse) if err != nil { fmt.Println(err) continue } verse = strings.ReplaceAll(verse, "Yahweh", NAME) verse = strings.ReplaceAll(verse, "\n", "\n> ") post.WriteString(verse) post.WriteString(" ") } rows.Close() post.WriteString("\n\n") } fmt.Println(post.String()) err := Client.PostComment(post.String(), parent_fullname) if err != nil { fmt.Println(err) } else { time.Sleep(ONE_SEC) } }