Refactor seen.py module

master
sfan5 2017-04-10 12:42:16 +02:00
parent 96770e471e
commit 56b8cff07a
2 changed files with 74 additions and 100 deletions

View File

@ -39,7 +39,7 @@ Required arguments are enclosed in { and }, optional arguments are enclosed in [
<tr> <td>!b64d {string}</td> <td>Base64-decode a string</td> <td>Anyone</td> </tr> <tr> <td>!b64d {string}</td> <td>Base64-decode a string</td> <td>Anyone</td> </tr>
<tr> <td>!rand [min] {max}</td> <td>Says a random number between(incl.) min and max</td> <td>Anyone</td> </tr> <tr> <td>!rand [min] {max}</td> <td>Says a random number between(incl.) min and max</td> <td>Anyone</td> </tr>
<tr> <td><b>seen.py</b></td> <td></td> <td></td> </tr> <tr> <td><b>seen.py</b></td> <td></td> <td></td> </tr>
<tr> <td>!seen {person}</td> <td>Output when person was last seen</td> <td>Anyone</td> </tr> <tr> <td>!seen {person}</td> <td>Reports when person was last seen</td> <td>Anyone</td> </tr>
<tr> <td><b>server.py</b></td> <td></td> <td></td> </tr> <tr> <td><b>server.py</b></td> <td></td> <td></td> </tr>
<tr> <td>!server [query] [query] ...</td> <td>Search servers at servers.minetest.net</td> <td>Anyone</td> </tr> <tr> <td>!server [query] [query] ...</td> <td>Search servers at servers.minetest.net</td> <td>Anyone</td> </tr>
<tr> <td></td> <td>addr:{string} searches in Address</td> <td></td> </tr> <tr> <td></td> <td>addr:{string} searches in Address</td> <td></td> </tr>

172
seen.py
View File

@ -1,136 +1,110 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
seen.py - Phenny Seen Module seen.py - Phenny Seen Module
Copyright 2008, Sean B. Palmer, inamidst.com Copyright 2017 sfan5
Modified by sfan5 2013 Licensed under GNU General Public License v2.0
Licensed under the Eiffel Forum License 2.
http://inamidst.com/phenny/
""" """
import os.path
import time import time
from threading import Thread, Lock from threading import Thread, Lock
import sqlite3 import sqlite3
DBPATH = "seen.sqlite"
updates = list() updates = list()
update_l = Lock() updates_l = Lock()
dblock = Lock()
def opendb():
db = sqlite3.connect("seen.sqlite")
return db
def updatethread(): def updatethread():
global updates, update_l global updates, updates_l
db = opendb() db = sqlite3.connect(DBPATH)
c = db.cursor() while True:
while True: if len(updates) == 0:
if len(updates) > 0: time.sleep(15)
update_l.acquire() continue
up = updates updates_l.acquire()
updates = list() up = updates
update_l.release() updates = list()
dblock.acquire() updates_l.release()
for u in up:
c.execute("SELECT * FROM seen WHERE nick = ?", (u[2],)) db.executemany("REPLACE INTO seen(channel, time, nick) VALUES (?, ?, ?)", up)
if c.fetchone() != None: db.commit()
d = (u[0], u[1], u[2]) db.close()
c.execute('UPDATE seen SET channel = ?, time = ? WHERE nick = ?', d)
else:
d = (u[2], u[0], u[1])
c.execute('INSERT INTO seen VALUES (?,?,?)', d)
db.commit()
dblock.release()
else:
time.sleep(5)
def pushupdate(sender, nick): def pushupdate(sender, nick):
ts = int(time.mktime(time.gmtime())) ts = int(time.mktime(time.gmtime()))
nick = nick.lower() nick = nick.lower()
update_l.acquire()
updates.append((sender, ts, nick))
update_l.release()
def api_seen(nick): updates_l.acquire()
dblock.acquire() updates.append((sender, ts, nick))
db = opendb() updates_l.release()
c = db.cursor()
c.execute("SELECT channel, time FROM seen WHERE nick = ?", (nick,))
r = c.fetchone()
c.close()
db.close()
dblock.release()
return r
class SomeObject(object):
pass
seen_api = SomeObject() class SeenApi(object):
seen_api.seen = api_seen @staticmethod
def seen(nick):
db = sqlite3.connect(DBPATH)
c = db.execute("SELECT channel, time FROM seen WHERE nick = ?", (nick, ))
r = c.fetchone()
db.close()
return r
_export = { _export = {
'seen': seen_api, 'seen': SeenApi,
} }
def seen(phenny, input): def seen(phenny, input):
"""seen <nick> - Reports when <nick> was last seen.""" """seen <nick> - Reports when <nick> was last seen."""
nick = input.group(2) nick = input.group(2)
if not nick: if not nick:
return phenny.reply("Need a nickname to search for...") return phenny.reply("Need a nickname to search for...")
nick = nick.lower() nick = nick.lower()
log.log("event", "%s queried Seen database for '%s'" % (log.fmt_user(input), nick), phenny) log.log("event", "%s queried Seen database for '%s'" % (log.fmt_user(input), nick), phenny)
r = api_seen(nick) r = SeenApi.seen(nick)
if r is None:
return phenny.reply("Sorry, I haven't seen %s around." % nick)
if r: channel, t = r[0], r[1]
channel, t = r[0], r[1] t = time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime(t))
t = time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime(t)) phenny.reply("%s was last seen at %s on %s" % (nick, t, channel))
msg = "%s was last seen at %s on %s" % (nick, t, channel)
phenny.reply(msg)
else:
phenny.reply("Sorry, I haven't seen %s around." % nick)
seen.rule = (['seen'], r'(\S+)') seen.rule = (['seen'], r'(\S+)')
def note(phenny, input):
if input.sender.startswith('#'):
pushupdate(input.sender, input.nick)
note.rule = r'.*' def create_note(event=None):
note.priority = 'low' def f(phenny, input):
note.thread = False if input.sender.startswith("#"):
note.nohook = True pushupdate(input.sender, input.nick)
f.rule = r'.*'
f.priority = "low"
f.thread = False
f.nohook = True
if event is not None:
f.event = event
return f
def note_join(phenny, input): note = create_note()
if input.sender.startswith('#'): note_join = create_note("JOIN")
pushupdate(input.sender, input.nick) note_part = create_note("PART")
note_join.rule = r'.*'
note_join.event = 'JOIN'
note_join.priority = 'low'
note_join.thread = False
note_join.nohook = True
def note_part(phenny, input): if not os.path.exists(DBPATH):
if input.sender.startswith('#'): db = sqlite3.connect(DBPATH)
pushupdate(input.sender, input.nick) db.execute('''
CREATE TABLE `seen` (
note_part.rule = r'.*' `nick` tinytext NOT NULL,
note_part.event = 'PART' `channel` tinytext NOT NULL,
note_part.priority = 'low' `time` int NOT NULL,
note_part.thread = False PRIMARY KEY (`nick`)
note_part.nohook = True )
''')
db = sqlite3.connect("seen.sqlite") db.close()
c = db.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS seen (nick text, channel text, time int)''')
c.close()
db.close()
t = Thread(target=updatethread, name="seen.py database thread") t = Thread(target=updatethread, name="seen.py database thread")
t.start() t.start()
if __name__ == '__main__': if __name__ == '__main__':
print(__doc__.strip()) print(__doc__.strip())