happybot/timer.py
2024-12-01 17:11:28 -05:00

102 lines
3.1 KiB
Python

#!/usr/bin/env python3
import re
from subprocess import Popen, PIPE, run
import os
from uuid import uuid4
from sys import argv
# Not multi-process-safe. Hopefully it doesn't get fucked up too much.
# This is crap. Not designed, but just... hacked together.
def cmd(*args):
proc = Popen(args, stdout=PIPE)
while True:
line = proc.stdout.readline()
if line:
try:
yield str(line[:-1], 'utf-8', 'ignore')
except:
pass
else:
break
datafile = '/home/zgrep/offtopiabday/at.txt'
def read():
with open(datafile) as fh:
data = [ x.split(' ') for x in fh.read().split('\n') ]
try:
return { int(n): (c, u, i) for (n, c, u, i) in data }
except:
return {}
def write(data):
s = []
for (n, (c, u, i)) in data.items():
s.append(str(n) + ' ' + c + ' ' + u + ' ' + i)
s = '\n'.join(s)
with open(datafile, 'w') as fh:
fh.write(s)
def add(timespec, msg, chan, usr):
uid = str(uuid4())
with open('/home/zgrep/offtopiabday/atm/' + uid + '.txt', 'w') as fh:
fh.write(msg)
timespec = timespec.lstrip('-')
command = "/home/zgrep/offtopiabday/atc.sh '{}' '{}' '{}'".format(uid, usr, chan)
p = run(['at', '-q', 'h', timespec], stdout=PIPE, stderr=PIPE, input=command, encoding='ascii')
output = str(p.stderr).strip().split('\n')[-1]
if output.startswith('at: '):
output = output[4:]
if p.returncode != 0:
os.remove('/home/zgrep/offtopiabday/atm/' + uid + '.txt')
return f'Error {p.returncode}: {output}'
try:
job = int(output.split()[1])
except:
os.remove('/home/zgrep/offtopiabday/atm/' + uid + '.txt')
return f'Could not extract job number from: {output}'
data = read()
data[job] = (chan, usr, uid)
write(data)
return output
def remove(job, chan, usr):
data = read()
if job not in data:
return 'No such job, {}.'.format(job)
if chan != data[job][0]:
return 'That job is for another channel.'
os.remove('/home/zgrep/offtopiabday/atm/' + data[job][2] + '.txt')
run(['at', '-r', str(job)])
del data[job]
write(data)
return 'Removed job {}.'.format(job)
def main():
if len(argv) != 2:
print('Usage:', argv[0], '#channel')
exit(1)
chan = argv[1]
chanpath = '/home/zgrep/offtopiabday/irc.freenode.net/' + chan
for line in cmd('tail', '-n', '0', '-f', chanpath + '/out'):
date, time, nick, line = line.split(' ', 3)
nick = nick[1:-1]
if nick in ('happybot', 'hatebot', '!', '-!-'):
continue
m = re.match(r'@?(?:happybot|hatebot)[:,]? (?:at|timer) (?:-r ([0-9]+)|-*(.+?) (?:do|say) (.+))$', line)
if m:
remove_i, timespec, message = m.groups()
if remove_i:
remove_i = int(remove_i)
reply = remove(remove_i, chan, nick)
else:
reply = add(timespec, message, chan, nick)
with open(chanpath + '/in', 'w') as fh:
fh.write('\u200b' + nick + ': ' + reply + '\n')
if __name__ == '__main__':
main()