#!/usr/bin/env python3 'whits.py - by Sean B. Palmer' import sys, os, re, time, getopt import irc3, stream title = 'Gallimaufry of Whits' uri = 'http://inamidst.com/whits/' tag = 'tag:inamidst.com,2006:whits' author = 'Sean B. Palmer' nick = 'sbp' botnick = 'whitsbot' server = 'irc.freenode.net' channel = '#whits' os.chdir('/Users/sbp/web/inamidst.com/www/whits') def process(text): separator = text == '%%' replacement = text.startswith('sub: ') regular = not (separator or replacement) if regular: add_to_homepage(text) elif separator: entry = create_homepage_entry() add_to_feed(entry) elif replacement: substitute_item(text) def nextlabel(line): if not 'class="' in line: return 'a' a, b = line.split('class="', 1) prior = b.split('"', 1)[0] def next(label): if label.endswith('z'): return next(label[:-1]) + 'a' else: return label[:-1] + chr(ord(label[-1]) + 1) return next(prior) def hypertext(text, label): r_hyperlink = re.compile(r'\{([^}]+) (http://[^ }]+)\}') text = r_hyperlink.sub(r'\g<1>', text) return '

%s

' % (label, text) def add_to_homepage(text): with stream.Stream('index.html') as index: def create(text): index.write('
' % strftime('%d %B %Y')) index.write(hypertext(text, 'a')) index.write('
') index.write('') ui.notify('Published {a} to new homepage entry') if index.before('1st', ''): label = nextlabel(index.previous) index.write(hypertext(text, label)) ui.notify('Published {%s} to homepage' % label) return True else: create(text) def substitute_item(text): line = text[5:] # strip off the leading "sub: " try: label, value = line.split(': ', 1) except Exception as err: ui.notify('Error: ' + str(err)) return with stream.Stream('index.html') as index: if index.instead('1st', 'class="%s"' % label): index.write(hypertext(value, label)) ui.notify('Substituted new value for {%s}' % label) def create_homepage_entry(): with stream.Stream('index.html') as index: if index.instead('1st', '' in index.next): index.write(previous) return None index.collect() div = previous.replace(''): entry = index.collected() else: raise ValueError() return entry def strftime(format): return time.strftime(format, time.gmtime()) def cdata(markup): markup = ''.join(markup) return '', ']]>]]>' def add_to_feed(entry): if entry is None: ui.notify('No entry to add') return False now = strftime('%Y-%m-%dT%H:%M:%SZ') with stream.Stream('feed.atom') as feed: def create(feed, entry): feed.write(' ' % uri) feed.write(' %s:%s' % (tag, now)) feed.write(' ' % uri) feed.write(' %s' % strftime('%d %B %Y %H:%M')) feed.write(' %s' % now) feed.write(' %s' % author) feed.write(' ') feed.write(cdata(entry)) feed.write(' ') feed.write(' ') ui.notify('Created feed entry') created = False if feed.instead('1st', ''): feed.write(' %s' % now) if '' in feed.next: create(feed, entry) created = True if feed.before('1st', ''): feed.write('') feed.close() def utf8(arg): return str(arg).encode('utf-8') class WhitsClient(irc3.Client): def dispatch(self, command, sender, *args): print(utf8(command), utf8(sender), utf8(args)) if (command == '251'): self.join(channel) self.msg(channel, '-- %s --' % title) elif (command == 'PRIVMSG'): recipient, text = args if not sender.startswith(nick + '!'): return if not recipient.startswith('#'): return process(text) def notify(self, message): self.msg(channel, message) def irc(): global ui ui = WhitsClient(botnick) ui.run(server) def shell(): global ui Shell = type('Shell', (object,), { 'notify': lambda self, *args: sys.stdout.write(' '.join(args) + '\n') }) ui = Shell() process(sys.argv[1]) def exit(*args): for arg in args: if isinstance(arg, int): sys.exit(arg) elif hasattr(arg, '__call__'): arg() else: print(arg) sys.exit() def main(argv=None): argv = sys.argv if (argv is None) else argv try: opts, args = getopt.getopt(argv[1:], 'i', ['irc']) except getopt.GetoptError as err: exit(err, 2) else: flags = {flag for (flag, value) in opts} or {} # whits.py -i | whits.py --irc if (flags == {'-i'}) or (flags == {'--irc'}) and (not args): irc() # whits.py 'Command line input.' elif (flags == {}) and (len(args) == 1): shell() else: exit('Error: Unknown command\n', 2) if __name__ == '__main__': main()