summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--icqRoombot.tac10
-rw-r--r--omegle/icq.py146
-rw-r--r--omegle/icqBuddy.py14
-rw-r--r--omegle/icqChatroomBuddy.py5
-rw-r--r--omegle/icqRoombot.py4
-rw-r--r--unfoggedbot.py241
6 files changed, 334 insertions, 86 deletions
diff --git a/icqRoombot.tac b/icqRoombot.tac
index 2f6fba1..a883d76 100644
--- a/icqRoombot.tac
+++ b/icqRoombot.tac
@@ -1,15 +1,17 @@
#!/usr/bin/env twistd
# vim: set ft=python sw=4 et syntax=python:
-from omegle.icq import ReconnectOscarFactory
+from omegle.icq import ReconnectingOSCARLoginFactory
from omegle.icqRoombot import ICQRoombot
from twisted.application import internet, service
-uin, password = ('370496181', 'megahal123')
+#uin, password = ('370496181', 'megahal123')
+uin, password = ('566193419', 'gagagaga')
host, port = ('login.oscar.aol.com', 5190)
-factory = ReconnectOscarFactory(ICQRoombot, uin, password, icq=1)
+f = ReconnectingOSCARLoginFactory(uin, password)
+f.BOSClass = ICQRoombot
application = service.Application('icqRoombot')
-service = internet.TCPClient(host, port, factory)
+service = internet.TCPClient(host, port, f)
service.setServiceParent(application)
diff --git a/omegle/icq.py b/omegle/icq.py
index 3cb5c7f..b134dd6 100644
--- a/omegle/icq.py
+++ b/omegle/icq.py
@@ -3,36 +3,38 @@
# Yves Fischer, xapek.org 2009
import struct
-from twisted.words.protocols import oscar
-from twisted.internet import reactor, protocol
+#from twisted.words.protocols import oscar
+from tlib import oscar
+from twisted.internet import reactor, protocol, defer
from twisted.internet.protocol import ClientFactory
-CAP_TYPING = '\x56\x3f\xc8\x09\x0b\x6f\x41\xbd\x9f\x79\x42\x26\x09\xdf\xa2\xf3'
+__all__ = ['ReconnectingOSCARLoginFactory', 'ExtendedBOSConnection']
+CAP_TYPING = '\x56\x3f\xc8\x09\x0b\x6f\x41\xbd\x9f\x79\x42\x26\x09\xdf\xa2\xf3'
class ExtendedBOSConnection( oscar.BOSConnection ):
- capabilities = [oscar.CAP_CHAT,CAP_TYPING]
+ capabilities = [oscar.CAP_CHAT, CAP_TYPING]
- def __init__(self,s,p,**kwargs):
- oscar.BOSConnection.__init__(self, s, p,**kwargs)
+ def __init__(self,username, cookie, authenticator = None):
+ oscar.BOSConnection.__init__(self, username, cookie)
+ self.authenticator = authenticator
+ print self.authenticator
- """
- handles typing SNAC
- """
+ """handles typing SNAC"""
def oscar_04_14(self,snac):
data = snac[3]
- if len(data) == len("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\t222840035\x00\x02"):
+ if len(data) == len('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\t222840035\x00\x02'):
user = data[11:20]
state = data[20:22]
- if state == "\x00\x00": #finish
- self.receiveTyping(user, "finish")
- elif state == "\x00\x01": #idle
- self.receiveTyping(user, "idle")
- elif state == "\x00\x02": #begin
- self.receiveTyping(user, "begin")
+ if state == '\x00\x00': #finish
+ self.receiveTyping(user, 'finish')
+ elif state == '\x00\x01': #idle
+ self.receiveTyping(user, 'idle')
+ elif state == '\x00\x02': #begin
+ self.receiveTyping(user, 'begin')
else:
- print "Unknown state in typing snac\nuser %s\ndata %s\nsnac %s\nstate %X%X" % (user,data,snac,state[0],sate[1])
+ print 'Unknown state in typing snac\nuser %s\ndata %s\nsnac %s\nstate %X%X' % (user,data,snac,state[0],sate[1])
else:
- print "komisches tpying snac"
+ print 'komisches tpying snac'
def receiveTyping(self, user, state):
pass
@@ -45,25 +47,25 @@ class ExtendedBOSConnection( oscar.BOSConnection ):
pass
def updateBuddy(self, user):
- print "updateBuddy %s" % user
+ print 'updateBuddy %s' % user
def gotBuddyList( self, buddylist ):
self.activateSSI()
- self.setProfile("Forget ICQ, MSN, Yahoo and the other shitty protocols! Use XMPP/Jabber!")
+ self.setProfile('Forget ICQ, MSN, Yahoo and the other shitty protocols! Use XMPP/Jabber!')
self.setIdleTime( 0 )
self.clientReady()
for user in buddylist[0][0].users:
- print "icq: Authorize %s" % user.name
+ print 'icq: Authorize %s' % user.name
self.sendAuthorizationResponse(user.name, True, '')
- """message - utf8 """
+ """message - utf8"""
def receiveCleanMessage( self, user, message, flags ):
raise NotImplementedError('receiveCleanMessage( self, user, message, flags )')
def _getMessage(self,multiparts):
message = None
if len(multiparts[0]) == 2:
- if multiparts[0][1] == "unicode":
+ if multiparts[0][1] == 'unicode':
message = unicode(multiparts[0][0])
else:
message = multiparts[0][0].decode(multiparts[0][1],'latin1')
@@ -73,80 +75,80 @@ class ExtendedBOSConnection( oscar.BOSConnection ):
def receiveMessage( self, user, multiparts, flags ):
- print "icq: receiveMessage(%s,%s,%s)" % (user,multiparts,flags)
- if flags != None and "auto" in flags:
- print "'auto' message, abort"
- return
+ print 'icq: receiveMessage(%s,%s,%s)' % (user,multiparts,flags)
+ if flags != None and 'auto' in flags:
+ return #skip 'auto' messages
- # because i cant receive the "budded added signal" i auth on every message
+ # because i cant receive the 'buddy added signal' i auth on every message
self.sendAuthorizationResponse(user.name, True, '')
#cleanup message
try:
message = self._getMessage( multiparts )
#filter qip \x00CHAR\x00CHAR - qip sucks at unicode?
- message = filter(lambda x: x!=u"\x00", message)
+ message = filter(lambda x: x!=u'\x00', message)
self.receiveCleanMessage( user, message, flags )
except Exception,e:
- print "Exception: %s" % e
-
- def chatReceiveMessage( self, chat, user, message ):
- self.receiveMessage( self, user, message, [] )
+ print 'Exception: %s' % e
def sendAuthorizationResponse(self, uin, success, responsString):
- packet = struct.pack("b", len(uin)) + uin
+ packet = struct.pack('b', len(uin)) + uin
if success:
- packet += struct.pack("b", 1)
+ packet += struct.pack('b', 1)
else:
- packet += struct.pack("b", 0)
- packet += struct.pack(">H", len(responsString)) + responsString
+ packet += struct.pack('b', 0)
+ packet += struct.pack('>H', len(responsString)) + responsString
self.sendSNACnr(0x13, 0x1a, packet)
def sendMessage(self, user, messageUtf8):
message = messageUtf8.encode('latin1','replace')
oscar.BOSConnection.sendMessage(self,user,message)
- def connectionLost(self,reason):
- print "Connection lost"
- oscar.BOSConnection.connectionLost(self,reason)
- self.shutdown()
- self.transport.loseConnection()
- self.authenticator.connectionLost(reason)
-
-class Authenticator( oscar.OscarAuthenticator ):
- def connectionLost(self,reason):
- oscar.OscarAuthenticator.connectionLost(self,reason)
- self.factory.connectionLost(reason)
-
- def connectToBOS(self, server, port):
- c = protocol.ClientCreator(reactor, self.BOSClass,
- self.username, self.cookie)
- c.authenticator = self
- return c.connectTCP(server, port)
-
+ def connectionLost(self, reason):
+ self.factory.clientConnectionLost(self, reason)
+ oscar.BOSConnection.connectionLost(self,reason)
-class ReconnectOscarFactory(ClientFactory):
- def __init__(self, BOSClass, uid, password,icq=1):
- self.BOSClass = BOSClass
+class ReconnectingOSCARFactory(protocol.ClientFactory):
+ delay = 10.0
+ BOSClass = oscar.BOSConnection
+ def __init__(self, uid, cookie, password, host, port):
self.uid = uid
+ self.cookie = cookie
self.password = password
- self.icq = icq
-
+ self.host = host
+ self.port = port
def buildProtocol(self, addr):
- p = Authenticator(self.uid, self.password,icq=self.icq)
+ p = self.BOSClass(self.uid, self.cookie)
p.factory = self
+ return p
+ def clientConnectionLost(self, connector, reason):
+ reactor.callLater(self.delay, self._reconnect)
+ def _reconnect(self):
+ print "_reconnect"
+ f = ReconnectingOSCARLoginFactory(self.uid, self.password)
+ f.BOSClass = self.BOSClass
+ return reactor.connectTCP(self.host, self.port, f)
+
+class Authenticator(oscar.OscarAuthenticator):
+ BOSClass = oscar.BOSConnection
+ def connectToBOS(self, host, port):
+ f = ReconnectingOSCARFactory(self.username, self.cookie, self.password, host, port)
+ f.BOSClass = self.BOSClass
+ reactor.connectTCP(host, port, f)
+ return defer.Deferred() #dummy
+
+class ReconnectingOSCARLoginFactory(protocol.ReconnectingClientFactory):
+ BOSClass = oscar.BOSConnection
+ def __init__(self, uid, password):
+ self.uid = uid
+ self.password = password
+ def buildProtocol(self, addr):
+ p = Authenticator(self.uid, self.password)
p.BOSClass = self.BOSClass
+ p.factory = self
return p
-
- def startedConnecting(self, connector):
- print 'Started to connect to oscar'
-
- def connectionLost(self,reason):
- print "CONECTION LOST - start njew factory"
- reactor.callLater(4.0, reactor.connectTCP,
- 'login.icq.com', 5238, self)
-# reactor.connectTCP('login.icq.com', 5238, OscarFactory(self.uin, self.password,icq=1))
-
-
+ ## only reconnect on *failures*
+ def clientConnectionLost(self, con, reason):
+ pass
diff --git a/omegle/icqBuddy.py b/omegle/icqBuddy.py
index c51419f..1a9d609 100644
--- a/omegle/icqBuddy.py
+++ b/omegle/icqBuddy.py
@@ -9,10 +9,9 @@ from twisted.internet import reactor
from twisted.python import log
from omegle import OmegleChat
-from icq import ExtendedBOSConnection, ReconnectOscarFactory
+from icq import ExtendedBOSConnection, ReconnectingOSCARLoginFactory
-ICQ_UIN = '446323989'
-ICQ_PASSWORD = 'gagaga'
+ICQ_UIN, ICQ_PASSWORD = ('446323989', 'gagaga')
def random_greetings():
gr = (
@@ -20,7 +19,9 @@ def random_greetings():
"Connected with Omegle, be retarted with strangers!",
"Omegle ... its like pedo-roulette",
"Under law 153:276:935 section 864, Omegle is required to inform you that the person you are currently chatting with owns the IP address of a registered sex offender. Please be careful when chatting with this person, and remember never to give out your personal information. The person you are chatting with cannot see this message.",
+ "You're Now On Omegle, Note: In China Too Young Is Just a Name",
)
+
return "==== %s" % gr[random.randint(0,len(gr)-1)]
class OmegleICQChat(OmegleChat):
@@ -67,7 +68,8 @@ class ICQBuddy( ExtendedBOSConnection ):
self.omegleConns = {}
def shutdown( self ):
- for conn in self.omegleConns:
+ for k in self.omegleConns.keys():
+ conn = self.omegleConns[k]
if conn.is_connected:
conn.disconnect()
@@ -116,6 +118,8 @@ if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
log.startLogging(sys.stdout)
- factory = ReconnectOscarFactory(ICQBuddy, ICQ_UIN,ICQ_PASSWORD,icq=1)
+ f = ReconnectingOSCARLoginFactory(ICQ_UIN, ICQ_PASSWORD)
+ f.BOSClass = ICQBuddy
+ reactor.connectTCP('login.icq.com', 5238, f)
reactor.run()
diff --git a/omegle/icqChatroomBuddy.py b/omegle/icqChatroomBuddy.py
index a235334..be92c58 100644
--- a/omegle/icqChatroomBuddy.py
+++ b/omegle/icqChatroomBuddy.py
@@ -8,7 +8,7 @@ from twisted.internet import reactor, protocol
from twisted.python import log
from omegle.icqBuddy import ICQBuddy
-from icq import ReconnectOscarFactory
+from icq import ReconnectingOSCARLoginFactory
ICQ_UIN = '446323989'
ICQ_PASSWORD = 'gagaga'
@@ -29,6 +29,7 @@ if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
log.startLogging(sys.stdout)
- factory = ReconnectOscarFactory(OmegleICQChatroomBuddy, ICQ_UIN,ICQ_PASSWORD,icq=1)
+ factory = ReconnectingOSCARLoginFactory(ICQ_UIN,ICQ_PASSWORD)
+ factory.BOSClass = OmegleICQChatroomBuddy
reactor.connectTCP('login.icq.com', 5238, factory)
reactor.run()
diff --git a/omegle/icqRoombot.py b/omegle/icqRoombot.py
index 3f463a5..17a0a3d 100644
--- a/omegle/icqRoombot.py
+++ b/omegle/icqRoombot.py
@@ -1,8 +1,6 @@
#!/usr/bin/python
# Yves Fischer, xapek.org 2009
-
-import sys
-from icq import ExtendedBOSConnection, ReconnectOscarFactory
+from icq import ExtendedBOSConnection
from random import randint
from twisted.internet import reactor
diff --git a/unfoggedbot.py b/unfoggedbot.py
new file mode 100644
index 0000000..4c943ba
--- /dev/null
+++ b/unfoggedbot.py
@@ -0,0 +1,241 @@
+#! /usr/bin/python
+#from twisted.words.protocols import oscar
+import oscar
+## local copy taken from the py-aimt project.
+## some API differences, but it automagically does rate-limiting stuff.
+from twisted.internet import protocol, reactor
+from twisted.enterprise.adbapi import ConnectionPool
+from twisted.python import log
+import re, feedparser, socket, sets, os
+#socket.setdefaulttimeout(60)
+
+
+DB = "ubotdb"
+RC = ".unfoggedbotrc"
+host, port = ('login.oscar.aol.com', 5190)
+
+## longer SQL.
+GETCOMMENT = "SELECT comment_id,link,thread_url,author,content,title FROM rss_items WHERE processed = 0 ORDER BY comment_id ASC LIMIT 1"
+GETPOST = "SELECT post_id, post_url, title FROM posts WHERE processed = 0 ORDER BY post_id ASC LIMIT 1"
+GETSUBSCRIBERS = "SELECT screen_name FROM subscriptions WHERE thread_url = ?"
+INSERTCOMMENTS = "INSERT OR IGNORE INTO rss_items (link, processed, thread_url, author, content, title) VALUES (?, ?, ?, ?, ?, ?)"
+INSERTPOSTS = "INSERT OR IGNORE INTO posts (post_url, title, processed) VALUES (?, ?, ?)"
+
+db = ConnectionPool("pysqlite2.dbapi2", DB)
+
+permalink = re.compile("http://(www\.)?unfogged\.com/archives/week_...._.._..\.html#(\d+)")
+commentlink = re.compile("http://(www\.)?unfogged\.com/archives/comments_(\d+).html")
+
+ignorefirst = lambda f: lambda *a: f(*a[1:])
+mkmsg = lambda txt: [[txt.decode('utf-8').encode('utf-16-be'), 'unicode']]
+
+class UnfoggedBot(oscar.BOSConnection):
+ def __init__(self, username, cookie):
+ oscar.BOSConnection.__init__(self, username, cookie)
+ self.offlines = sets.Set()
+ self.lost = False
+ db.runOperation("UPDATE posts SET processed = 1")\
+ .addCallback(ignorefirst(db.runOperation),
+ "UPDATE rss_items SET processed = 1")\
+ .addCallback(ignorefirst(self.getnew))
+
+ def connectionMade(self):
+ oscar.BOSConnection.connectionMade(self)
+ self.lost = False
+
+ def connectionLost(self, reason):
+ oscar.BOSConnection.connectionLost(self, reason)
+ self.lost = True
+
+ def initDone(self):
+ log.msg("%s: in initDone" % self)
+ self.requestSelfInfo()
+ self.requestSSI().addCallback(self.gotBuddylist)
+
+ def gotBuddylist(self, l):
+ self.activateSSI()
+ self.clientReady()
+
+ def offlineBuddy(self, user):
+ log.msg("User %s went offline" % user)
+ self.offlines.add(user.name)
+
+ def updateBuddy(self, user):
+ msg = "User %s status change" % user.name
+ if user.name in self.offlines:
+ msg += "; removing from offlines set"
+ self.offlines.remove(user.name)
+ log.msg(msg)
+
+
+ def _getnew(self, txn):
+ if self.lost: return
+ comment = txn.execute(GETCOMMENT).fetchall()
+ if comment:
+ turl = comment[0][2]
+ crecipients = txn.execute(GETSUBSCRIBERS, (turl,)).fetchall()
+ else: crecipients = [[[]]]
+ post = txn.execute(GETPOST).fetchall()
+ precipients = txn.execute("SELECT screen_name FROM subscriptions WHERE thread_url = ?", ("posts",)).fetchall()
+ return (comment,
+ post,
+ [cr[0] for cr in crecipients],
+ [pr[0] for pr in precipients],
+ )
+
+ def getnew(self):
+ if self.lost: return
+ reactor.callLater(3, self.getnew)
+ db.runInteraction(self._getnew).addCallback(self.sendnew)
+
+ def markread(self, txn, cid, pid):
+ if self.lost: return
+ if cid:
+ txn.execute("UPDATE rss_items SET processed = 1 WHERE comment_id = ?", (cid,))
+ if pid:
+ txn.execute("UPDATE posts SET processed = 1 WHERE post_id = ?", (pid,))
+
+ def sendnew(self, (comment, post, crecs, precs)):
+ if comment:
+ cid, link, turl, auth, cnt, title = comment[0]
+ if len(cnt) >= 500:
+ cnt = cnt[:497]+"..." #possibly cutting off tags
+ msg = mkmsg('<b>%s</b> on <b><a href="%s">%s</a></b>: %s' %\
+ (auth, link, title, cnt))
+ crecs = [c for c in crecs if c not in self.offlines]
+ if crecs: log.msg("Sending message to %s" % crecs)
+ for crec in crecs:
+ self.sendMessage(crec, msg)
+ else: cid = None
+ if post:
+ pid, link, title = post[0]
+ msg = mkmsg('New post!\n<a href="%s">%s</a>' % (link, title))
+ precs = [p for p in precs if p not in self.offlines]
+ if precs: log.msg("Sending new post alert to %s" % precs)
+ for prec in precs:
+ self.sendMessage(prec, msg)
+ else: pid = None
+ db.runInteraction(self.markread, cid, pid)
+
+ def receiveMessage(self, user, multiparts, flags):
+ try:
+ msg = str(multiparts[0][0])
+ except IndexError:
+ log.msg("Index error on msg: \"%s\"?" % multiparts)
+ return
+ if self.trycommentsub(user, msg): return
+ if re.search("(un)?subscribe posts", msg):
+ db.runQuery("SELECT screen_name FROM subscriptions WHERE thread_url = ?", ("posts",)).addCallback(self.addremovepostsub, user.name)
+
+ def trycommentsub(self, user, msg):
+ for pat in (permalink, commentlink):
+ m = pat.search(msg)
+ if m:
+ thread_id = re.sub('^0+', '', m.group(2))
+ thread_url = "http://www.unfogged.com/archives/comments_%s.html" % thread_id
+ break
+ else:
+ return
+ return db.runInteraction(self._subinfo, thread_url).addCallback(self.addremovecommentsub, thread_url, user.name)
+
+
+ def _subinfo(self, txn, turl):
+ subscribers = txn.execute(GETSUBSCRIBERS, (turl,)).fetchall()
+ try:
+ threadname = txn.execute("SELECT title FROM posts WHERE post_url = ?", (turl,)).fetchall()[0][0]
+ except IndexError:
+ threadname = turl
+ return ((str(s[0]) for s in subscribers), str(threadname))
+
+ def addremovecommentsub(self, (subscribers, threadname), threadurl, uname):
+ def sendfromcb(_, msg): self.sendMessage(uname, mkmsg(msg))
+ if uname in subscribers:
+ log.msg("unsubscribe %s from %s" % (uname, threadname))
+ db.runOperation("DELETE FROM subscriptions WHERE screen_name = ? AND thread_url = ?", (uname, threadurl)).addCallback(sendfromcb, 'subscription to "%s" disabled.' % threadname)
+ else:
+ log.msg("subscribe %s to %s" % (uname, threadname))
+ db.runOperation("INSERT INTO subscriptions (screen_name, thread_url) VALUES (?, ?)", (uname, threadurl)).addCallback(sendfromcb, 'subscription to "%s" enabled.' % threadname)
+
+ def addremovepostsub(self, subscribers, uname):
+ def sendfromcb(_, msg): self.sendMessage(uname, mkmsg(msg))
+ if uname in (str(s[0]) for s in subscribers):
+ log.msg("unsubscribe %s from posts" % uname)
+ db.runOperation("DELETE FROM subscriptions WHERE screen_name = ? AND thread_url = ?", (uname, "posts")).addCallback(sendfromcb, "subscription to posts disabled.")
+ else:
+ log.msg("subscribe %s to posts" % uname)
+ db.runOperation("INSERT INTO subscriptions (screen_name, thread_url) VALUES (?, ?)", (uname, "posts")).addCallback(sendfromcb, "subscription to posts enabled.")
+
+class ReconnectingOSCARFactory(protocol.ClientFactory):
+ delay = 10.0
+ protocol = UnfoggedBot
+ def __init__(self, un, cookie):
+ self.un = un
+ self.cookie = cookie
+ def buildProtocol(self, addr):
+ p = self.protocol(self.un, self.cookie)
+ p.factory = self
+ return p
+ def clientConnectionLost(self, connector, reason):
+ reactor.callLater(self.delay, self._reconnect)
+ def _reconnect(self):
+ f = ReconnectingOSCARLoginFactory(sn, pass_)
+ return reactor.connectTCP(host, port, f)
+
+class OA(oscar.OscarAuthenticator):
+ BOSClass = UnfoggedBot
+ connectfactory = ReconnectingOSCARFactory
+ def connectToBOS(self, server, port):
+ if not self.connectfactory:
+ c = protocol.ClientCreator(reactor, self.BOSClass, self.username, self.cookie)
+ return c.connectTCP(server, int(port))
+ else:
+ f = self.connectfactory(self.username, self.cookie)
+ return reactor.connectTCP(server, int(port), f)
+
+class ReconnectingOSCARLoginFactory(protocol.ReconnectingClientFactory):
+ protocol = OA
+ def __init__(self, sn, pass_):
+ self.sn = sn
+ self.pass_ = pass_
+ def buildProtocol(self, addr):
+ p = self.protocol(self.sn, self.pass_, icq=0)
+ p.factory = self
+ return p
+ ## only reconnect on *failures*
+ def clientConnectionLost(self, con, reason):
+ pass
+
+def getrss():
+##on the assumption that this can be done w/o using too much time,
+##I have taken this out of a separate thread.
+ comments = feedparser.parse("/home/unfogged/unfogged/html/bridgeplate.rdf")
+ posts = feedparser.parse("/home/unfogged/unfogged/html/index.xml")
+ updaterss(comments, posts)
+ reactor.callLater(15, getrss)
+
+def updaterss(comments, posts):
+ def doinsertions(txn, commentdata, postdata):
+ txn.executemany(INSERTCOMMENTS, commentdata)
+ txn.executemany(INSERTPOSTS, postdata)
+ commentdata, postdata = [], []
+ for e in comments.entries:
+ title = e.title.split("comments on ")[1][1:-1]
+ thread_url = e.link.split('#')[0]
+ commentdata.append((e.link, 0, thread_url, e.contributors[0]['name'],
+ e.description, title))
+ postdata = []
+ for e in posts.entries:
+ postdata.append((e.link, e.title, 0))
+ db.runInteraction(doinsertions, commentdata, postdata)
+
+
+if __name__ == '__main__':
+ execfile(RC) # values of "sn" and "pass_"
+ import sys
+ sys.stderr = sys.stdout = open("ubot.log", "a+")
+ log.startLogging(sys.stdout)
+ f = ReconnectingOSCARLoginFactory(sn, pass_)
+ reactor.connectTCP(host, port, f)
+
+ getrss()
+ reactor.run()