def user_seen(event, bot): target = event.argument if not target: return bot.say("Seen who?") hidden = bot.getOption("hidden", module="users") if bot.isModuleAvailable("alias"): # do magic for group group = ALIAS_MODULE.group_list(bot.dbQuery, target) if group: msgs = [] for member in group: seen = _user_seen(bot.dbQuery, member) if seen['seenwhere'] in hidden: msgs.append( SEENMSG % (target, distance_of_time_in_words(seen['lastseen']))) else: msgs.append( SEENMSGWSOURCE % (target, distance_of_time_in_words(seen['lastseen']), seen['seenwhere'], seen['lastmsg'])) if len(group) > 3: try: return "%s, see %s" % (event.nick, ADDONS.paste( "\n".join(msgs), title="Seen %s" % target)) except AttributeError: return bot.say("Too many users and no paste available.") else: first = True for msg in msgs: if first: bot.say("%s, %s" % (event.nick, msg)) else: bot.say(msg) first = False return # not group, look for alias: nick = ALIAS_MODULE.lookup_alias(bot.dbQuery, target) seen = _user_seen(bot.dbQuery, nick if nick else target) else: seen = _user_seen(target) if not seen: bot.say("%s, lol dunno." % event.nick) else: if seen['seenwhere'] in hidden: bot.say("%s, %s" % (event.nick, SEENMSG % (target, distance_of_time_in_words(seen['lastseen'])))) else: bot.say("%s, %s" % (event.nick, SEENMSGWSOURCE % (target, distance_of_time_in_words(seen['lastseen']), seen['seenwhere'], seen['lastmsg']))) return
def user_seen(event, bot): target = event.argument if not target: return bot.say("Seen who?") hidden = bot.getOption("hidden", module="pbm_users") if bot.isModuleAvailable("pbm_alias"): # do magic for group group = ALIAS_MODULE.group_list(bot.dbQuery, target) if group: msgs = [] for member in group: seen = _user_seen(bot.dbQuery, member) if seen['seenwhere'] in hidden: msgs.append(SEENMSG % (target, distance_of_time_in_words(seen['lastseen']) )) else: msgs.append(SEENMSGWSOURCE % (target, distance_of_time_in_words(seen['lastseen']), seen['seenwhere'], seen['lastmsg'])) if len(group) > 3: try: return "%s, see %s" % (event.nick, bot.getAddon("paste")("\n".join(msgs), title="Seen %s" % target)) except AttributeError: return bot.say("Too many users and no paste available.") else: first = True for msg in msgs: if first: bot.say("%s, %s" % (event.nick, msg)) else: bot.say(msg) first = False return # not group, look for alias: nick = ALIAS_MODULE.lookup_alias(bot.dbQuery, target) seen = _user_seen(bot.dbQuery, nick if nick else target) else: seen = _user_seen(target) if not seen: bot.say("%s, lol dunno." % event.nick) else: if seen['seenwhere'] in hidden: bot.say("%s, %s" % (event.nick, SEENMSG % (target, distance_of_time_in_words(seen['lastseen'])) )) else: bot.say("%s, %s" % (event.nick, SEENMSGWSOURCE % (target, distance_of_time_in_words(seen['lastseen']), seen['seenwhere'], seen['lastmsg']))) return
def deliver_tell(event, bot): # if alias module available use it user = None if bot.isModuleAvailable("pbm_alias"): # pretty convoluted but faster than fetching both modules every time # may return none if this event gets captured for a first time user before user module # also faster this way than making 2 db calls for USER_MODULE.get_username user = USERS_MODULE.ALIAS_MODULE.lookup_alias(bot.dbQuery, event.nick) if not user: user = event.nick toldtime = int(timegm(gmtime())) # This seems like it might be a bit of a waste. But it should stop the rare occurance of "double tell delivery" (I've only seen it happen once.) tells = bot.dbBatch( ( # Query1, get tells ('''SELECT id,source,telltime,origintime,remind,msg FROM tell WHERE user=? AND delivered=0 AND telltime<? ORDER BY telltime;''', (user,toldtime)), # Query2, update query ('''UPDATE tell SET delivered=1,toldtime=? WHERE user=? AND delivered=0 AND telltime<?;''',(toldtime, user, toldtime)), ) )[0] # 0 gets the results from the first query only if tells: collate = False lines = None if len(tells) > 3: collate = True lines = [] for tell in tells: if tell['remind']: source = tell['source'] if source: data = [event.nick, source, tell['msg'], distance_of_time_in_words(tell['origintime'], toldtime), distance_of_time_in_words(tell['telltime'], toldtime, suffix="late")] fmt = REMINDFORMAT else: data = [event.nick, tell['msg'], distance_of_time_in_words(tell['origintime'], toldtime), distance_of_time_in_words(tell['telltime'], toldtime, suffix="late")] fmt = SELFREMINDFORMAT if collate: lines.append(fmt.format(*data)) else: bot.say(fmt, strins=data, fcfs=True) else: data = [event.nick, tell['source'], tell['msg'], distance_of_time_in_words(tell['telltime'], toldtime)] if collate: lines.append(TELLFORMAT.format(*data)) else: bot.say(TELLFORMAT, strins=data, fcfs=True) if collate: msg = "Tells/reminds for (%s): %%s" % event.nick title = "Tells/reminds for (%s)" % event.nick pastehelper(bot, msg, items=lines, altmsg="%s", force=True, title=title)
def deliver_alerts(chan_or_user=None, alerts=None, bot=None): if not bot: return current_time = int(timegm(gmtime())) filtered_alerts = [] row_ids = [] for a in alerts: id = str(a['id']) if bot.dbQuery('''SELECT 1 FROM alert WHERE delivered=0 AND id=?''', (id,)): row_ids.append(id) filtered_alerts.append(a) alerts = filtered_alerts if not alerts: return collate = False lines = None if len(alerts) > 3: collate = True lines = [] for a in alerts: row_ids.append(id) receiving_user = a['target_user'] source_user = a['source_user'] if source_user: data = [a['target_user'], source_user, a['msg'], distance_of_time_in_words(a['created_time'], current_time)] fmt = ALERT_FORMAT else: data = [a['target_user'], a['msg'], distance_of_time_in_words(a['created_time'], current_time)] fmt = SELF_ALERT_FORMAT if collate: lines.append(fmt.format(*data)) else: bot.sendmsg(chan_or_user, fmt, strins=data, fcfs=True) if collate: msg = "Alerts for (%s): %%s" % receiving_user title = "Alerts for (%s)" % receiving_user pastehelper(bot, msg, items=lines, altmsg="%s", force=True, title=title) for row_id in row_ids: bot.dbQuery('''UPDATE alert SET delivered=1 WHERE id=?;''', (row_id, ))
def alert(event, bot): """ alert target datespec msg. Alert a user <target> about a message <msg> at <datespec> time. datespec can be relative (in) or calendar/day based (on), e.g. 'in 5 minutes'""" target, dtime1, dtime2, msg = argumentSplit(event.argument, 4) if not target: return bot.say(functionHelp(alert)) if dtime1.lower() == "tomorrow": target, dtime1, msg = argumentSplit(event.argument, 3) # reparse is easiest way I guess... resolves #30 if need to readdress dtime2 = "" else: if not (dtime1 and dtime2): return bot.say("Need time to alert.") if not msg: return bot.say("Need something to alert (%s)" % target) origuser = USERS_MODULE.get_username(bot, event.nick) users, unknown, dupes, _ = _lookup_users(bot, target, origuser, False) if not users: return bot.say("Sorry, don't know (%s)." % target) dtime = "%s %s" % (dtime1, dtime2) # user location aware destination times locmod = None goomod = None timelocale = False try: locmod = bot.getModule("pbm_location") goomod = bot.getModule("pbm_googleapi") timelocale = True except ConfigException: pass origin_time = timegm(gmtime()) alocal_time = localtime(origin_time) local_offset = timegm(alocal_time) - origin_time if locmod and goomod: t = origin_time loc = locmod.getlocation(bot.dbQuery, origuser) if not loc: timelocale = False t = alocal_time else: tz = goomod.google_timezone(loc[1], loc[2], t) if not tz: timelocale = False t = alocal_time else: t = gmtime(t + tz[2] + tz[3]) #[2] dst [3] timezone offset else: t = alocal_time ntime = parseDateTime(dtime, t) if not ntime: return bot.say("Don't know what time and/or day and/or date (%s) is." % dtime) # go on, change it. I dare you. if timelocale: t = timegm(t) - tz[2] - tz[3] ntime = ntime - tz[2] - tz[3] else: t = timegm(t) - local_offset ntime = ntime - local_offset if ntime < t or ntime > (t + MAX_REMIND_TIME): return bot.say("Don't sass me with your back to the future alerts.") if ntime < (t + 5): return bot.say("2fast") targets = [] for user, target in users: if user == origuser: source_user = None else: source_user = event.nick if event.isPM(): chan_or_user = event.nick else: chan_or_user = event.target bot.dbQuery('''INSERT INTO alert(target_user, alert_time, created_time, source, source_user, msg) VALUES (?,?,?,?,?,?);''', (user, int(ntime), int(origin_time), chan_or_user, source_user, msg)) if ntime < (t + LOOP_INTERVAL): Timers.restarttimer(TIMER_NAME) if not source_user: targets.append("you") else: targets.append(target) bot.say(RPL_ALERT_FORMAT % (event.nick, english_list(targets), distance_of_time_in_words(ntime, t), UNKNOWN % english_list(unknown) if unknown else "", MULTIUSER % "Alerting" if dupes else ""))
def remind(event, bot): """ remind target datespec msg. Will remind a user <target> about a message <msg> at <datespec> time. datespec can be relative (in) or calendar/day based (on), e.g. 'in 5 minutes'""" target, dtime1, dtime2, msg = argumentSplit(event.argument, 4) if not target: return bot.say(functionHelp(tell)) if dtime1.lower() == "tomorrow": target, dtime1, msg = argumentSplit(event.argument, 3) # reparse is easiest way I guess... resolves #30 if need to readdress dtime2 = "" else: if not (dtime1 and dtime2): return bot.say("Need time to remind.") if not msg: return bot.say("Need something to remind (%s)" % target) origuser = USERS_MODULE.get_username(bot, event.nick) users, unknown, dupes, _ = _generate_users(bot, target, origuser, False) if not users: return bot.say("Sorry, don't know (%s)." % target) dtime = "%s %s" % (dtime1, dtime2) # user location aware destination times locmod = None goomod = None timelocale = False try: locmod = bot.getModule("pbm_location") goomod = bot.getModule("pbm_googleapi") timelocale = True except ConfigException: pass origintime = timegm(gmtime()) alocaltime = localtime(origintime) localoffset = timegm(alocaltime) - origintime if locmod and goomod: t = origintime loc = locmod.getlocation(bot.dbQuery, origuser) if not loc: timelocale = False t = alocaltime else: tz = goomod.google_timezone(loc[1], loc[2], t) if not tz: timelocale = False t = alocaltime else: t = gmtime(t + tz[2] + tz[3]) #[2] dst [3] timezone offset else: t = alocaltime ntime = parseDateTime(dtime, t) if not ntime: return bot.say("Don't know what time and/or day and/or date (%s) is." % dtime) # go on, change it. I dare you. if timelocale: t = timegm(t) - tz[2] - tz[3] ntime = ntime - tz[2] - tz[3] else: t = timegm(t) - localoffset ntime = ntime - localoffset if ntime < t or ntime > t+MAX_REMIND_TIME: return bot.say("Don't sass me with your back to the future reminds.") targets = [] for user, target in users: if user == origuser: source = None else: source = event.nick bot.dbQuery('''INSERT INTO tell(user, telltime, origintime, remind, source, msg) VALUES (?,?,?,?,?,?);''', (user, int(ntime), int(origintime), 1, source, msg)) if not source: targets.append("you") else: targets.append(target) bot.say(RPLREMINDFORMAT % (event.nick, english_list(targets), distance_of_time_in_words(ntime, t), UNKNOWN % english_list(unknown) if unknown else "", MULTIUSER % "Reminding" if dupes else ""))