pyircbot/pyircbot/modules/Tell.py

189 lines
7.8 KiB
Python
Raw Normal View History

2014-10-12 00:46:18 -07:00
"""
.. module:: Tell
2015-11-01 18:03:11 -08:00
:synopsis: Deliver a message to a user when they're next seen
2014-10-12 00:46:18 -07:00
.. moduleauthor:: Dave Pedu <dave@davepedu.com>
"""
2017-11-27 18:58:20 -08:00
from pyircbot.modulebase import ModuleBase, command, hook
2014-10-12 00:46:18 -07:00
import datetime
from time import mktime
2017-11-27 18:58:20 -08:00
from pyircbot.modules.ModInfo import info
2014-10-12 00:46:18 -07:00
2017-01-01 14:59:01 -08:00
2014-10-12 00:46:18 -07:00
class Tell(ModuleBase):
2015-11-01 18:03:11 -08:00
def __init__(self, bot, moduleName):
2017-01-01 14:59:01 -08:00
ModuleBase.__init__(self, bot, moduleName)
2015-11-01 18:03:11 -08:00
self.db = None
serviceProviders = self.bot.getmodulesbyservice("sqlite")
2017-01-01 14:59:01 -08:00
if len(serviceProviders) == 0:
2015-11-01 18:03:11 -08:00
self.log.error("Tell: Could not find a valid sqlite service provider")
else:
self.log.info("Tell: Selecting sqlite service provider: %s" % serviceProviders[0])
self.db = serviceProviders[0].opendb("tell.db")
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
if not self.db.tableExists("tells"):
self.log.info("Remind: Creating table: tells")
2017-01-01 14:59:01 -08:00
self.db.query("""CREATE TABLE IF NOT EXISTS `tells` (
2015-11-01 18:03:11 -08:00
`id` INTEGER PRIMARY KEY,
`sender` varchar(64),
`channel` varchar(64),
`when` INTEGER,
`recip` varchar(64),
`message` varchar(2048)
) ;""").close()
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
# Purge expired tells
2017-01-01 14:59:01 -08:00
self.db.query("DELETE FROM `tells` WHERE `when`<?",
(int(mktime(datetime.datetime.now().timetuple())) - self.config["maxage"],)).close()
2017-11-27 18:58:20 -08:00
@hook("PRIVMSG", "JOIN")
def showtell(self, msg, cmd):
2015-11-01 18:03:11 -08:00
# Look for tells for this person
2017-11-27 18:58:20 -08:00
c = self.db.query("SELECT * FROM `tells` WHERE `recip`=?", (msg.prefix.nick,))
2015-11-01 18:03:11 -08:00
tells = c.fetchall()
c.close()
for tell in tells:
agostr = Tell.timesince(datetime.datetime.fromtimestamp(tell["when"]))
recip = None
2017-01-01 14:59:01 -08:00
if tell["channel"] == "":
2017-11-27 18:58:20 -08:00
recip = msg.prefix.nick
2015-11-01 18:03:11 -08:00
else:
recip = tell["channel"]
self.bot.act_PRIVMSG(recip, "%s: %s said %s ago: %s" % (
2017-11-27 18:58:20 -08:00
msg.prefix.nick,
2015-11-01 18:03:11 -08:00
tell["sender"],
agostr,
tell["message"]
))
# Delete
self.db.query("DELETE FROM `tells` WHERE `id`=?", (tell["id"],))
2017-01-01 14:59:01 -08:00
2017-11-27 23:20:51 -08:00
@info("tell <person> <message> relay a message when the target is online", cmds=["tell"])
2017-11-27 18:58:20 -08:00
@command("tell", allow_private=True)
def tellcmds(self, msg, cmd):
if len(cmd.args) < 2:
self.bot.act_PRIVMSG(msg.args[0], "%s: .tell <person> <message> - Tell someone something the next time "
"they're seen. Example: .tell antiroach Do your homework!" % msg.prefix.nick)
return
2017-01-01 14:59:01 -08:00
2017-11-27 18:58:20 -08:00
recip = cmd.args[0]
message = ' '.join(cmd.args[1:]).strip()
2017-01-01 14:59:01 -08:00
2017-12-02 23:48:44 -08:00
c = self.db.query("SELECT COUNT(*) as `cnt` FROM `tells` WHERE `recip`=?;", (recip, ))
user_total = c.fetchall()[0]['cnt']
c.close()
if user_total >= self.config.get("max", 3):
2017-11-27 18:58:20 -08:00
return
2017-01-01 14:59:01 -08:00
2017-11-27 18:58:20 -08:00
self.db.query("INSERT INTO `tells` (`sender`, `channel`, `when`, `recip`, `message`) VALUES "
"(?, ?, ?, ?, ?);", (msg.prefix.nick,
msg.args[0] if "#" in msg.args[0] else "",
int(mktime(datetime.datetime.now().timetuple())),
recip,
message)).close()
2017-01-01 14:59:01 -08:00
2017-11-27 18:58:20 -08:00
self.bot.act_PRIVMSG(msg.args[0], "%s: I'll pass that along." % msg.prefix.nick)
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
# Copyright (c) Django Software Foundation and individual contributors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of Django nor the names of its contributors may be used
# to endorse or promote products derived from this software without
# specific prior written permission.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
#ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
#(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
#ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
@staticmethod
def timesince(d, now=None):
"""
Takes two datetime objects and returns the time between d and now
as a nicely formatted string, e.g. "10 minutes". If d occurs after now,
then "0 minutes" is returned.
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
Units used are years, months, weeks, days, hours, and minutes.
Seconds and microseconds are ignored. Up to two adjacent units will be
displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are
possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not.
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
"""
2017-01-01 14:59:01 -08:00
chunks = ((60 * 60 * 24 * 365, ('year', 'years')),
(60 * 60 * 24 * 30, ('month', 'months')),
(60 * 60 * 24 * 7, ('week', 'weeks')),
(60 * 60 * 24, ('day', 'days')),
(60 * 60, ('hour', 'hours')),
(60, ('minute', 'minutes')))
2015-11-01 18:03:11 -08:00
# Convert int or float (unix epoch) to datetime.datetime for comparison
if isinstance(d, int) or isinstance(d, float):
d = datetime.datetime.fromtimestamp(d)
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
# Convert datetime.date to datetime.datetime for comparison.
if not isinstance(d, datetime.datetime):
d = datetime.datetime(d.year, d.month, d.day)
if now and not isinstance(now, datetime.datetime):
now = datetime.datetime(now.year, now.month, now.day)
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
if not now:
now = datetime.datetime.now()
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
# ignore microsecond part of 'd' since we removed it from 'now'
delta = now - (d - datetime.timedelta(0, 0, d.microsecond))
since = delta.days * 24 * 60 * 60 + delta.seconds
if since <= 0:
# d is in the future compared to now, stop processing.
return u'0 ' + 'minutes'
for i, (seconds, name) in enumerate(chunks):
count = since // seconds
if count != 0:
break
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
if count == 1:
s = '%(number)d %(type)s' % {'number': count, 'type': name[0]}
else:
s = '%(number)d %(type)s' % {'number': count, 'type': name[1]}
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
if i + 1 < len(chunks):
# Now get the second item
seconds2, name2 = chunks[i + 1]
count2 = (since - (seconds * count)) // seconds2
if count2 != 0:
if count2 == 1:
s += ', %d %s' % (count2, name2[0])
else:
s += ', %d %s' % (count2, name2[1])
return s
2017-01-01 14:59:01 -08:00
2015-11-01 18:03:11 -08:00
@staticmethod
2017-01-01 14:59:01 -08:00
def timeuntil(d, now=None): # not used?
2015-11-01 18:03:11 -08:00
"""
Like timesince, but returns a string measuring the time until
the given time.
"""
if not now:
now = datetime.datetime.now()
2017-01-01 14:59:01 -08:00
return Tell.timesince(now, d)