102 lines
3.1 KiB
Python
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()
|