#!/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>")
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)