PYTHON 30
Scribe-bot.py Guest on 31st July 2020 12:46:59 PM
  1. #!/usr/local/bin/python
  2. ''' $Revision: 1.1 $ of $Date: 2000/11/08 19:26:46 $ by $Author: connolly $
  3.  
  4. derived from stuf by
  5.         Neale Picket http://www.pobox.com/~neale/src/net/
  6.  
  7. Automated meeting/notebook scribe.
  8. -- joins any channel to which it is invited
  9.  
  10. sort of handles
  11. -- agenda requests now
  12. -- persistent record (i.e. writing to local file web space)
  13. -- log topics
  14.  
  15.  
  16. TODO:
  17. review of action items
  18. record attendance (present, regrets)
  19. record decisions (voting? dissent?)
  20.  
  21. REFERENCES
  22.  
  23. for irc: URI syntax
  24. http://www.w3.org/Addressing/draft-mirashi-url-irc-01.txt
  25. http://www.w3.org/Addressing/schemes#irc
  26. '''
  27.  
  28. import irc
  29. import BoundIRC
  30. import time
  31. import select
  32. import whrandom
  33. import regsub
  34. import string
  35. import urllib
  36. from cgi import escape
  37.  
  38.  
  39. class MyBot(BoundIRC.BoundIRC):
  40.     def __init__(self, srv, nick, channel, log_dir, log_addr):
  41.         BoundIRC.BoundIRC.__init__(self)
  42.  
  43.         self._ircAddr = srv
  44.         self.initial_channels = [channel]
  45.         self._logs = {}
  46.         self._log_dir = log_dir
  47.         self._log_addr = log_addr
  48.         self.agenda = []
  49.    
  50.         self.bind('001', self.do_start)
  51.         self.bind('PRIVMSG', self.log_msg)
  52.         self.bind('PRIVMSG', self.log_link, '^(->|link:)')
  53. #       self.bind('PRIVMSG', self.display_privmsg)
  54.         self.bind('INVITE', self.do_invite)
  55.         self.bind('TOPIC', self.log_topic)
  56.         self.bind('PRIVMSG', self.leave, "^%s, excuse us" % (nick,))
  57.         self.bind('PRIVMSG', self.agenda_request, "scribe, agenda request:")
  58.         self.bind('PRIVMSG', self.agenda_summary, "scribe, agenda summary")
  59.         self.bind('PRIVMSG', self.spam,
  60.                   "spam")
  61.  
  62.  
  63.     def do_start(self, sender, recip, forum, addl, raw):
  64.         for channel in self.initial_channels:
  65.             forum.write_raw("JOIN", channel)
  66.             ch = sender.neighbor(channel)
  67.             dummy = self.log_for(ch)
  68.  
  69.     def do_invite(self, sender, recip, forum, addl, raw):
  70.         forum.write_raw("JOIN", forum.name())
  71.         dummy = self.log_for(forum)
  72.  
  73.     def leave(self, sender, recip, forum, addl, raw):
  74.         addr = self.close_log(forum.name())
  75.         forum.act('closes log at %s' % (addr,))
  76.         forum.write_raw("PART", forum.name())
  77.  
  78.     def agenda_request(self, sender, recip, forum, addl, raw):
  79.         item = addl[0]
  80.         item = item[string.index(item, ':')+1:]
  81.  
  82.         self.agenda.append(item)
  83.         forum.tell('agenda %d: %s' % (len(self.agenda), self.agenda[-1]))
  84.  
  85.     def agenda_summary(self, sender, recip, forum, addl, raw):
  86.         forum.tell('Agenda Requests')
  87.         forum.tell('===============')
  88.         for i in range(0, len(self.agenda)):
  89.             forum.tell('agenda %d: %s' % (i+1, self.agenda[i]))
  90.         forum.tell('== end')
  91.  
  92.  
  93.     def log_msg(self, sender, recip, forum, addl, raw):
  94.         msg = addl[0]
  95.         secs = time.time()
  96.         now = time.gmtime(secs)
  97.  
  98.         log = self.log_for(forum)
  99.  
  100.         log.write('<dt><a name="m%d">%02d:%02d %s</a></dt><dd>%s</dd\n>' % \
  101.                                  (secs, now[3], now[4],
  102.                                   escape(sender.name()), escape(msg)))
  103.         log.flush()
  104.  
  105.     def log_link(self, sender, recip, forum, addl, raw):
  106.         msg = addl[0]
  107.         secs = time.time()
  108.  
  109.         log = self.log_for(forum)
  110.  
  111.         dummy, href, text = string.split(msg, None, 2)
  112.        
  113.         log.write('<ul><li><a name="anch%d" href="%s">%s</a></li></ul\n>' % \
  114.                                  (secs, href, escape(text)))
  115.         log.flush()
  116.  
  117.  
  118.     def log_topic(self, sender, recip, forum, addl, raw):
  119.         log = self.log_for(forum)
  120.         topic = addl[0]
  121.         log = self.log_for(forum)
  122.         secs = time.time()
  123.         log.write('</dl><hr /><h2><a name="t%d">%s</a></h2><p><em>%s UTC</em></p><dl\n>'                  % \
  124.                   (secs, escape(topic), time.asctime(time.gmtime(secs))))
  125.         log.flush()
  126.        
  127.  
  128.     def close_logs(self):
  129.         channels = self._logs.keys()
  130.         for f in channels:
  131.             dummy = self.close_log(f)
  132.  
  133.     def close_log(self, f):
  134.         (log, when, rel) = self._logs[f]
  135.         log.write('</dl><p><em>log closed at %s UTC</em></p></body></html\n>\n' % \
  136.                   (time.asctime(time.gmtime(time.time())), ))
  137.         log.close()
  138.         del self._logs[f]
  139.         return '%s%s' % (self._log_addr, rel)
  140.  
  141.  
  142.     def log_for(self, chan):
  143.         chname = chan.name()
  144.         nowf = time.time()
  145.         nowt = time.gmtime(nowf)
  146.  
  147.         log = None
  148.         olog = None
  149.  
  150.         if self._logs.has_key(chname):
  151.             (log, when, rel) = self._logs[chname]
  152.             if nowf - when > 60*60*12: # rotate logs twice per day
  153.                 olog = log
  154.                 orel = rel
  155.                 owhen = when
  156.                 log = None
  157.                
  158.         if not log:
  159.             (u, f, r) = self.log_ptr(chname, nowf)
  160.             log = open(f, 'w+') # watch out for overwrites?
  161.             self._logs[chname] = (log, nowf, r)
  162.             chan.act('starts log at %s (%s)' % (u, f))
  163.  
  164.             timestr = time.asctime(nowt)
  165.             ech = escape(chname)
  166.            
  167.             log.write('''<html xmlns="http://www.w3.org/1999/xhtml"
  168. ><head><title>%s IRC log %s</title></head
  169. ><body><h1>%s log</h1
  170. ><p><em>This is a log for <a href="%s%s">the %s channel</a>, starting at %s UTC.</em></p
  171. ><address>bot $Revision: 1.1 $ of $Date: 2000/11/08 19:26:46 $ by <a href="http://www.w3.org/People/Connolly/">Dan</a> Mar 2000</address></p
  172. >''' % \
  173.                       (ech, timestr,
  174.                        ech,
  175.                        self._ircAddr, urllib.quote(chname[1:]), ech, timestr))
  176.            
  177.             if olog:
  178.                 olog.write('''</dl
  179. ><p><em>next log: <a href="%s">%s UTC</a></em></p
  180. ></body></html>
  181. ''' % \
  182.                            (r, time.asctime(nowt)))
  183.                 log.write('''
  184. <p><em>previous log: <a href="%s">%s UTC</a></em></p
  185. >''' % \
  186.                           (orel, time.asctime(time.gmtime(owhen))))
  187.                 olog.close()
  188.                
  189.             log.write("<dl\n>")
  190.             log.flush()
  191.            
  192.         return log
  193.    
  194.  
  195.     def log_ptr(self, where, when):
  196.         nq = urllib.quote(where)
  197.         w = time.strftime("%04Y-%02m-%02dT%02H%02M%02SZ", time.gmtime(when))
  198.         l = '%s-%s.html' % (w, nq)
  199.         return ('%s/%s' % (self._log_addr, l),
  200.                 '%s/%s-%s.html' %(self._log_dir, w, where),
  201.                 l)
  202.  
  203.    
  204.     def display_privmsg(self, sender, recip, forum, addl, raw):
  205.         if forum is sender:
  206.             print "[%s: %s]" % (sender.name(), addl[0])
  207.         else:
  208.             print "<%s> %s" % (sender.name(), addl[0])
  209.  
  210.     def act(self, sender, recip, forum, addl, raw):
  211.         forum.ctcp("ACTION", string.join(addl))
  212.  
  213.     def say(self, sender, recip, forum, addl, raw):
  214.         forum.tell(string.join(addl))
  215.  
  216.     def spam(self, sender, recip, forum, addl, raw):
  217.         forum.tell("Spam, spam, spam, spam, Spammity Spam!  Wonderful SPAM!")
  218.  
  219.     def order_something(self, sender, recip, forum, addl, raw):
  220.         if forum is sender:
  221.             instigator = "you"
  222.         else:
  223.             instigator = sender.name()
  224.         stuff = string.split(addl[0])[1:]
  225.         try:
  226.             for_pos = stuff.index('for')
  227.             forum.ctcp("ACTION",
  228.                        ("hands %s %s, compliments of %s."
  229.                         % (string.join(stuff[for_pos+1:]),
  230.                            string.join(stuff[:for_pos]),
  231.                            instigator)))
  232.         except ValueError:
  233.             forum.ctcp("ACTION",
  234.                        ("hands %s %s."
  235.                        % (instigator,
  236.                           string.join(stuff))))
  237.  
  238.  
  239. def main(argv):
  240.     nick, chan, dir, addr, server = (argv[1], argv[2], argv[3], argv[4], argv[5])
  241.     port = 6665
  242.    
  243.     mine = MyBot('irc://%s:%d/' % (server, port), nick, chan,
  244.                  dir, addr)
  245.     mine.connect(server, port, nick, gecos=addr)
  246.  
  247.     try:
  248.         while 1:
  249.             inready, outready, ignored = select.select([mine], [], [])
  250.             for i in inready:
  251.                 i.handle_input()
  252.     except KeyboardInterrupt:
  253.         mine.close_logs()
  254.         mine.write('QUIT', 'normal exit.')
  255.  
  256.  
  257. if __name__ == '__main__':
  258.     import sys
  259.     main(sys.argv)

Paste is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.