// checkForDuplicates checks for duplicates of the url in the database. func (ext *ExtensionDuplicates) ProcessURL(bot *papaBot.Bot, channel, sender, msg string, urlinfo *papaBot.UrlInfo) { result, err := bot.Db.Query(` SELECT IFNULL(nick, ""), IFNULL(timestamp, datetime('now')), count(*) FROM urls WHERE link=? AND channel=? ORDER BY timestamp DESC LIMIT 1`, urlinfo.URL, channel) if err != nil { bot.Log.Warningf("Can't query the database for duplicates: %s", err) return } defer result.Close() // Announce a duplicate if result.Next() { var nick string var timestr string var count uint if err = result.Scan(&nick, ×tr, &count); err != nil { bot.Log.Warningf("Error getting duplicates: %s", err) return } timestamp, _ := time.Parse("2006-01-02 15:04:05", timestr) duplicate := "" // Only one duplicate if count == 1 { if bot.AreSamePeople(nick, sender) { nick = ext.Texts.DuplicateYou } elapsed := utils.HumanizedSince(utils.MustForceLocalTimezone(timestamp)) duplicate = utils.Format(ext.Texts.TempDuplicateFirst, map[string]string{"nick": nick, "elapsed": elapsed}) } else if count > 1 { // More duplicates exist if bot.AreSamePeople(nick, sender) { nick = ext.Texts.DuplicateYou } elapsed := utils.HumanizedSince(utils.MustForceLocalTimezone(timestamp)) duplicate = utils.Format(ext.Texts.TempDuplicateMulti, map[string]string{"nick": nick, "elapsed": elapsed, "count": fmt.Sprintf("%d", count)}) } // Only announce once per 5 minutes per link. if duplicate != "" && time.Since(ext.announced[channel+urlinfo.URL]) > 5*time.Minute { // Can we fit into the ShortInfo? if urlinfo.ShortInfo == "" { urlinfo.ShortInfo = duplicate } else if len(urlinfo.ShortInfo) < 50 { urlinfo.ShortInfo += " | " + duplicate } else { // Better send as separate noitce. bot.SendNotice(channel, duplicate) } ext.announced[channel+urlinfo.URL] = time.Now() } } return }
// loadCounters will load the counters from the database. func (ext *ExtensionCounters) loadCounters(bot *papaBot.Bot) { ext.counters = map[int]*extensionCountersCounter{} result, err := bot.Db.Query( `SELECT id, channel, creator, announce_text, interval, target_date FROM counters`) if err != nil { bot.Log.Warningf("Error while loading counters: %s", err) return } defer result.Close() // Get vars. for result.Next() { var c extensionCountersCounter var dateStr string var id int var interval int if err = result.Scan(&id, &c.channel, &c.creator, &c.text, &interval, &dateStr); err != nil { bot.Log.Warningf("Can't load counter: %s", err) continue } c.interval = time.Duration(interval) // Parse the text template. c.textTmp, err = template.New(fmt.Sprintf("counter_%d", id)).Parse(c.text) if err != nil { bot.Log.Warningf("Can't parse counter template '%s': %s", c.text, err) } // Handle the date. c.date, err = time.Parse("2006-01-02 15:04:05", dateStr) if err != nil { bot.Log.Fatalf("Can't parse counter date %s: %s", dateStr, err) } c.date = utils.MustForceLocalTimezone(c.date) // Calculate next tick. Start from next daily tick and move backwards. nextTick := bot.NextDailyTick() for { c.nextTick = nextTick nextTick = nextTick.Add(-time.Duration(c.interval) * time.Hour) if time.Since(nextTick) > 0 { // We moved too far back. break } } bot.Log.Debugf("Counter %d, next tick: %s", id, c.nextTick) ext.counters[id] = &c } }