Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/services/console/lib/purk/irc.py
diff options
context:
space:
mode:
Diffstat (limited to 'services/console/lib/purk/irc.py')
-rw-r--r--services/console/lib/purk/irc.py328
1 files changed, 0 insertions, 328 deletions
diff --git a/services/console/lib/purk/irc.py b/services/console/lib/purk/irc.py
deleted file mode 100644
index d5a01aa..0000000
--- a/services/console/lib/purk/irc.py
+++ /dev/null
@@ -1,328 +0,0 @@
-import socket
-import sys
-
-from conf import conf
-import ui
-import windows
-import info
-
-DISCONNECTED = 0
-CONNECTING = 1
-INITIALIZING = 2
-CONNECTED = 3
-
-def parse_irc(msg, server):
- msg = msg.split(' ')
-
- # if our very first character is :
- # then this is the source,
- # otherwise insert the server as the source
- if msg and msg[0].startswith(':'):
- msg[0] = msg[0][1:]
- else:
- msg.insert(0, server)
-
- # loop through the msg until we find
- # something beginning with :
- for i, token in enumerate(msg):
- if token.startswith(':'):
- # remove the :
- msg[i] = msg[i][1:]
-
- # join up the rest
- msg[i:] = [' '.join(msg[i:])]
- break
-
- # filter out the empty pre-":" tokens and add on the text to the end
- return [m for m in msg[:-1] if m] + msg[-1:]
-
- # note: this sucks and makes very little sense, but it matches the BNF
- # as far as we've tested, which seems to be the goal
-
-def default_nicks():
- try:
- nicks = [conf.get('nick')] + conf.get('altnicks',[])
- if not nicks[0]:
- import getpass
- nicks = [getpass.getuser()]
- except:
- nicks = ["mrurk"]
- return nicks
-
-class Network(object):
- socket = None
-
- def __init__(self, core, server="irc.default.org", port=6667, nicks=[],
- username="", fullname="", name=None, **kwargs):
- self.manager = core.manager
- self.server = server
- self.port = port
- self.events = core.events
-
- self.name = name or server
-
- self.nicks = nicks or default_nicks()
- self.me = self.nicks[0]
-
- self.username = username or "urk"
- self.fullname = fullname or conf.get("fullname", self.username)
- self.password = ''
-
- self.isupport = {
- 'NETWORK': server,
- 'PREFIX': '(ohv)@%+',
- 'CHANMODES': 'b,k,l,imnpstr',
- }
- self.prefixes = {'o':'@', 'h':'%', 'v':'+', '@':'o', '%':'h', '+':'v'}
-
- self.status = DISCONNECTED
- self.failedhosts = [] #hosts we've tried and failed to connect to
- self.channel_prefixes = '&#+$' # from rfc2812
-
- self.on_channels = set()
- self.requested_joins = set()
- self.requested_parts = set()
-
- self.buffer = ''
-
- #called when we get a result from the dns lookup
- def on_dns(self, result, error):
- if error:
- self.disconnect(error=error[1])
- else:
- #import os
- #import random
- #random.seed()
- #random.shuffle(result)
- if socket.has_ipv6: #prefer ipv6
- result = [(f, t, p, c, a) for (f, t, p, c, a) in result if f == socket.AF_INET6]+result
- elif hasattr(socket,"AF_INET6"): #ignore ipv6
- result = [(f, t, p, c, a) for (f, t, p, c, a) in result if f != socket.AF_INET6]
-
- self.failedlasthost = False
-
- for f, t, p, c, a in result:
- if (f, t, p, c, a) not in self.failedhosts:
- try:
- self.socket = socket.socket(f, t, p)
- except:
- continue
- self.source = ui.fork(self.on_connect, self.socket.connect, a)
- self.failedhosts.append((f, t, p, c, a))
- if set(self.failedhosts) >= set(result):
- self.failedlasthost = True
- break
- else:
- self.failedlasthost = True
- if len(result):
- self.failedhosts[:] = (f, t, p, c, a),
- f, t, p, c, a = result[0]
- try:
- self.socket = socket.socket(f, t, p)
- self.source = ui.fork(self.on_connect, self.socket.connect, a)
- except:
- self.disconnect(error="Couldn't find a host we can connect to")
- else:
- self.disconnect(error="Couldn't find a host we can connect to")
-
- #called when socket.open() returns
- def on_connect(self, result, error):
- if error:
- self.disconnect(error=error[1])
- #we should immediately retry if we failed to open the socket and there are hosts left
- if self.status == DISCONNECTED and not self.failedlasthost:
- windows.get_default(self).write("* Retrying with next available host")
- self.connect()
- else:
- self.source = source = ui.Source()
- self.status = INITIALIZING
- self.failedhosts[:] = ()
-
- self.events.trigger('SocketConnect', network=self)
-
- if source.enabled:
- self.source = ui.fork(self.on_read, self.socket.recv, 8192)
-
- #called when we read data or failed to read data
- def on_read(self, result, error):
- if error:
- self.disconnect(error=error[1])
- elif not result:
- self.disconnect(error="Connection closed by remote host")
- else:
- self.source = source = ui.Source()
-
- self.buffer = (self.buffer + result).split("\r\n")
-
- for line in self.buffer[:-1]:
- self.got_msg(line)
-
- if self.buffer:
- self.buffer = self.buffer[-1]
- else:
- self.buffer = ''
-
- if source.enabled:
- self.source = ui.fork(self.on_read, self.socket.recv, 8192)
-
- def raw(self, msg):
- self.events.trigger("OwnRaw", network=self, raw=msg)
-
- if self.status >= INITIALIZING:
- self.socket.send(msg + "\r\n")
-
- def got_msg(self, msg):
- pmsg = parse_irc(msg, self.server)
-
- e_data = self.events.data(
- raw=msg,
- msg=pmsg,
- text=pmsg[-1],
- network=self,
- window=windows.get_default(self, self.manager)
- )
-
- if "!" in pmsg[0]:
- e_data.source, e_data.address = pmsg[0].split('!',1)
-
- else:
- e_data.source, e_data.address = pmsg[0], ''
-
- if len(pmsg) > 2:
- e_data.target = pmsg[2]
- else:
- e_data.target = pmsg[-1]
-
- self.events.trigger('Raw', e_data)
-
- def connect(self):
- if not self.status:
- self.status = CONNECTING
-
- self.source = ui.fork(self.on_dns, socket.getaddrinfo, self.server, self.port, 0, socket.SOCK_STREAM)
-
- self.events.trigger('Connecting', network=self)
-
- def disconnect(self, error=None):
- if self.socket:
- self.socket.close()
-
- if self.source:
- self.source.unregister()
- self.source = None
-
- self.socket = None
-
- self.status = DISCONNECTED
-
- #note: connecting from onDisconnect is probably a Bad Thing
- self.events.trigger('Disconnect', network=self, error=error)
-
- #trigger a nick change if the nick we want is different from the one we
- # had.
- if self.me != self.nicks[0]:
- self.events.trigger(
- 'Nick', network=self, window=windows.get_default(self),
- source=self.me, target=self.nicks[0], address='',
- text=self.nicks[0]
- )
- self.me = self.nicks[0]
-
- def norm_case(self, string):
- return string.lower()
-
- def quit(self, msg=None):
- if self.status:
- try:
- if msg == None:
- msg = conf.get('quitmsg', "%s - %s" % (info.long_version, info.website))
- self.raw("QUIT :%s" % msg)
- except:
- pass
- self.disconnect()
-
- def join(self, target, key='', requested=True):
- if key:
- key = ' '+key
- self.raw("JOIN %s%s" % (target,key))
- if requested:
- for chan in target.split(' ',1)[0].split(','):
- if chan == '0':
- self.requested_parts.update(self.on_channels)
- else:
- self.requested_joins.add(self.norm_case(chan))
-
- def part(self, target, msg="", requested=True):
- if msg:
- msg = " :" + msg
-
- self.raw("PART %s%s" % (target, msg))
- if requested:
- for chan in target.split(' ',1)[0].split(','):
- self.requested_parts.add(self.norm_case(target))
-
- def msg(self, target, msg):
- self.raw("PRIVMSG %s :%s" % (target, msg))
-
- self.events.trigger(
- 'OwnText', source=self.me, target=str(target), text=msg,
- network=self, window=windows.get_default(self, self.manager)
- )
-
- def notice(self, target, msg):
- self.raw("NOTICE %s :%s" % (target, msg))
-
- self.events.trigger(
- 'OwnNotice', source=self.me, target=str(target), text=msg,
- network=self, window=windows.get_default(self)
- )
-
-#a Network that is never connected
-class DummyNetwork(Network):
- def __nonzero__(self):
- return False
-
- def __init__(self, core):
- Network.__init__(self, core)
-
- self.name = self.server = self.isupport['NETWORK'] = "None"
-
- def connect(self):
- raise NotImplementedError, "Cannot connect dummy network."
-
- def raw(self, msg):
- raise NotImplementedError, "Cannot send %s over the dummy network." % repr(msg)
-
-#dummy_network = DummyNetwork()
-
-#this was ported from srvx's tools.c
-def match_glob(text, glob, t=0, g=0):
- while g < len(glob):
- if glob[g] in '?*':
- star_p = q_cnt = 0
- while g < len(glob):
- if glob[g] == '*':
- star_p = True
- elif glob[g] == '?':
- q_cnt += 1
- else:
- break
- g += 1
- t += q_cnt
- if t > len(text):
- return False
- if star_p:
- if g == len(glob):
- return True
- for i in xrange(t, len(text)):
- if text[i] == glob[g] and match_glob(text, glob, i+1, g+1):
- return True
- return False
- else:
- if t == len(text) and g == len(glob):
- return True
- if t == len(text) or g == len(glob) or text[t] != glob[g]:
- return False
- t += 1
- g += 1
- return t == len(text)