#!/usr/bin/python # # Last Modified: 000503 # Author: N. Nordman (_nino@home.se) # # Description: # # A script that triggers on channel messages starting with !slasdot, with or without argument and # then displays one or more slashdot headers. Hooks up with x-chat and installs a signal handler # for the XP_CHANMSG signal. This is then parsed for the !slashdot [arg] syntax # ( r"^!slashdot( \d{1,2})?$" ). If this is found the script creates a SlashReader object to do the # actual reading, passing along any parameter. The output of this is then captured and broadcasted # to the channel from which the !slashdot was issued. This is not really suited for having for # a client since x-chat freezes during processing of scripts. And since the slashdot server # is pretty slow this *is* pretty inconvinient. Preferably this should be modified for use with a # bot of some kind. import XChat import string import sys import re import time import urllib # Class SlashReader description: # # Contains the class SlashReader which can be used to read headers from slashdot, from the slashdot.xml file. # Can also be used as a standalone script. # # Usage: # # The SlashReader class contains one function member, Read([topic_nr]), that can be used to read the # headers. It returns a list of strings. If called without topic_nr or with topic_nr == None it will # return all current slashdot headers. If topic_nr is not None just the topic specified by topic_nr # is return along with it's associated url. class SlashReader: "SlashReader: A class for reading slashdot headers" regTitle = re.compile("(.*)<[/]title>") regUrl = re.compile("<url>(.*)<[/]url>") xmlURL = 'http://www.slashdot.org/slashdot.xml' def Read(self, nr=None): """Reads the headers. If nr != None only a specific topic is displayed with its associated URL. The header(s) (with URL) is returned as a list of strings.""" try: f = urllib.urlopen(self.xmlURL) doc = f.readlines() f.close() i = 1 retlist = [] for item in doc: m = self.regTitle.search(item) if m: if not nr or i == nr: retlist.append( `i` + ". " + string.strip(m.group(1))) i = i + 1 elif nr and i == nr + 1: m = self.regUrl.search(item) if m: retlist.append( "\t--> " + string.strip(m.group(1))) return retlist except IOError: return None def chan_msg_handler(name, flags, args): trigger = re.compile(r"^!slashdot( \d{1,2})?$") serv = args[0].get_server() chan = args[1].get_string() from_nick = args[2].get_string() text = args[3].get_string() my_nick = serv.info()['nick'] # first of all we see if we're really triggered m = trigger.match(text) if m: # alright, get a session object to the correct channel try: sess = XChat.Session() sess.set(serv.info()['hostname'], serv.info()['port'], my_nick, chan) except LookupError: x_chat.get_current_session().print_text("slash 1.0: Could not find originating channel.") return # alright, create a slashreader obj and read the headline(s) [topic_nr] # first we get any eventual parameter if m.group(1): para = int(m.group(1)) else: para = None sr = SlashReader() # note that handling a channel message and producing another channel message quite easily can # lead to recursion ad infinitum. not so in our case since our produced channel message(s) is # guaranteed to never get matched with the trigger. output = sr.Read(para) for line in output: sess.handle_cmd("/me : %s" % line) time.sleep(0.5) return x_chat = XChat.XChat() x_chat.register("slash 1.0", """A script that responds to !slashdot public string and displays slashdot headers. By N. Nordman 2000(_nino@home.se).""") x_chat.hook_signal("XP_CHANMSG", chan_msg_handler)