// Parse a row returned from SQLite into a Factoid. func parseFactoid(row []interface{}, out chan *factoids.Factoid) { values := parseMultipleValues(toString(row[cValue])) c := &factoids.FactoidStat{ Nick: base.Nick(toString(row[cCreator])), Chan: "", Count: 1, } c.Timestamp, _ = parseTimestamp(row[cCreated]) m := &factoids.FactoidStat{Chan: "", Count: 0} if ts, ok := parseTimestamp(row[cModified]); ok { m.Timestamp = ts m.Nick = base.Nick(toString(row[cModifier])) m.Count = 1 } else { m.Timestamp = c.Timestamp m.Nick = c.Nick } p := &factoids.FactoidPerms{ parseReadOnly(row[cAccess]), base.Nick(toString(row[cCreator])), } for _, val := range values { t, v := parseValue(toString(row[cKey]), toString(row[cRel]), val) if v == "" { // skip the many factoids with empty values. continue } out <- &factoids.Factoid{ Key: toString(row[cKey]), Value: v, Type: t, Chance: 1.0, Created: c, Modified: m, Accessed: c, Perms: p, Id: bson.NewObjectId(), } } }
func recordKick(line *base.Line) { n, c := line.Storable() kn := base.Nick(line.Args[1]) // seenNickFromLine doesn't work with the hacks for KICKING and KICKED // First, handle KICKING kr := sc.LastSeenDoing(line.Nick, "KICKING") if kr == nil { kr = seen.SawNick(n, c, "KICKING", line.Args[2]) } else { kr.Nick, kr.Chan = n, c kr.Timestamp, kr.Text = time.Now(), line.Args[2] } kr.OtherNick = kn _, err := sc.Upsert(kr.Id(), kr) if err != nil { bot.Reply(line, "Failed to store seen data: %v", err) } // Now, handle KICKED ke := sc.LastSeenDoing(line.Args[1], "KICKED") if ke == nil { ke = seen.SawNick(kn, c, "KICKED", line.Args[2]) } else { ke.Nick, ke.Chan = kn, c ke.Timestamp, ke.Text = time.Now(), line.Args[2] } ke.OtherNick = n _, err = sc.Upsert(ke.Id(), ke) if err != nil { bot.Reply(line, "Failed to store seen data: %v", err) } }
// remind func set(line *base.Line) { // s == <target> <reminder> in|at|on <time> s := strings.Fields(line.Args[1]) if len(s) < 4 { bot.ReplyN(line, "Invalid remind syntax. Sucka.") return } i := len(s) - 1 for i > 0 { lc := strings.ToLower(s[i]) if lc == "in" || lc == "at" || lc == "on" { break } i-- } if i < 1 { bot.ReplyN(line, "Invalid remind syntax. Sucka.") return } reminder := strings.Join(s[1:i], " ") timestr := strings.ToLower(strings.Join(s[i+1:], " ")) // TODO(fluffle): surface better errors from datetime.Parse at, ok := datetime.Parse(timestr) if !ok { bot.ReplyN(line, "Couldn't parse time string '%s'", timestr) return } now := time.Now() start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local) if at.Before(now) && at.After(start) { // Perform some basic hacky corrections before giving up if strings.Contains(timestr, "am") || strings.Contains(timestr, "pm") { at = at.Add(24 * time.Hour) } else { at = at.Add(12 * time.Hour) } } if at.Before(now) { bot.ReplyN(line, "Time '%s' is in the past.", timestr) return } n, c := line.Storable() // TODO(fluffle): Use state tracking! And do this better. t := base.Nick(s[0]) if t.Lower() == strings.ToLower(line.Nick) || t.Lower() == "me" { t = n } r := reminders.NewReminder(reminder, at, t, n, c) if err := rc.Insert(r); err != nil { bot.ReplyN(line, "Error saving reminder: %v", err) return } // Any previously-generated list of reminders is now obsolete. delete(listed, line.Nick) bot.ReplyN(line, "%s", r.Acknowledge()) Remind(r) }
func parseUrl(row []interface{}) *urls.Url { return &urls.Url{ Nick: base.Nick(row[cNick].(string)), Chan: base.Chan(row[cChannel].(string)), Url: row[cUrl].(string), Timestamp: time.Unix(row[cTime].(int64), 0), Id: bson.NewObjectId(), } }
func parseQuote(row []interface{}, out chan *quotes.Quote) { out <- "es.Quote{ Quote: row[cQuote].(string), QID: int(row[cID].(int64)), Nick: base.Nick(row[cNick].(string)), Chan: base.Chan(row[cChannel].(string)), Accessed: 0, Timestamp: time.Unix(row[cTime].(int64), 0), Id: bson.NewObjectId(), } }
// tell func tell(line *base.Line) { // s == <target> <stuff> idx := strings.Index(line.Args[1], " ") if idx == -1 { bot.ReplyN(line, "Tell who what?") return } tell := line.Args[1][idx+1:] n, c := line.Storable() t := base.Nick(line.Args[1][:idx]) if t.Lower() == strings.ToLower(line.Nick) || t.Lower() == "me" { bot.ReplyN(line, "You're a dick. Oh, wait, that wasn't *quite* it...") return } r := reminders.NewTell(tell, t, n, c) if err := rc.Insert(r); err != nil { bot.ReplyN(line, "Error saving tell: %v", err) return } // Any previously-generated list of reminders is now obsolete. delete(listed, line.Nick) bot.ReplyN(line, "%s", r.Acknowledge()) }