| 1 |
|
|---|
| 2 |
from time import time, sleep |
|---|
| 3 |
from twisted.words.protocols import oscar |
|---|
| 4 |
from twisted.internet import protocol, reactor |
|---|
| 5 |
import getpass, re, string, sys |
|---|
| 6 |
|
|---|
| 7 |
import SABBrain |
|---|
| 8 |
|
|---|
| 9 |
(i_time, i_recipient, i_message, i_away) = (0, 1, 2, 3) |
|---|
| 10 |
|
|---|
| 11 |
SN = 'sigartbot' |
|---|
| 12 |
PASS = 'illinois' |
|---|
| 13 |
|
|---|
| 14 |
hostport = ('login.oscar.aol.com', 5190) |
|---|
| 15 |
bot = None |
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
not_typing = '\x00\x00' |
|---|
| 19 |
stopped_typing = '\x00\x01' |
|---|
| 20 |
typing = '\x00\x02' |
|---|
| 21 |
|
|---|
| 22 |
class B(oscar.BOSConnection): |
|---|
| 23 |
capabilities = [oscar.CAP_CHAT] |
|---|
| 24 |
lingua = 0 |
|---|
| 25 |
brain = None |
|---|
| 26 |
|
|---|
| 27 |
def initDone(self): |
|---|
| 28 |
self.requestSelfInfo().addCallback(self.gotSelfInfo) |
|---|
| 29 |
self.requestSSI().addCallback(self.gotBuddyList) |
|---|
| 30 |
self.brain = SABBrain.SABBrain(SN, True) |
|---|
| 31 |
self.brain.log.enabled = '-debug' in sys.argv |
|---|
| 32 |
self.away_message = None |
|---|
| 33 |
global bot |
|---|
| 34 |
bot = self |
|---|
| 35 |
|
|---|
| 36 |
def gotSelfInfo(self, user): |
|---|
| 37 |
|
|---|
| 38 |
self.name = user.name |
|---|
| 39 |
|
|---|
| 40 |
def gotBuddyList(self, l): |
|---|
| 41 |
|
|---|
| 42 |
self.activateSSI() |
|---|
| 43 |
self.setProfile("No Information Provided") |
|---|
| 44 |
self.setIdleTime(0) |
|---|
| 45 |
self.clientReady() |
|---|
| 46 |
|
|---|
| 47 |
def updateBuddy(self, user): |
|---|
| 48 |
|
|---|
| 49 |
pass |
|---|
| 50 |
|
|---|
| 51 |
def offlineBuddy(self, user): |
|---|
| 52 |
print 'offline', user.name |
|---|
| 53 |
|
|---|
| 54 |
def receiveMessage(self, user, multiparts, flags): |
|---|
| 55 |
|
|---|
| 56 |
self.getAway(user.name).addCallback(self.gotAway, user.name) |
|---|
| 57 |
|
|---|
| 58 |
|
|---|
| 59 |
message = multiparts[0][0].encode('ascii','ignore') |
|---|
| 60 |
|
|---|
| 61 |
|
|---|
| 62 |
if self.away_message: |
|---|
| 63 |
self.brain.queue.add_outgoing(user.name, '<html><font color="#0000ff">' + self.away_message + '</font>', away=True) |
|---|
| 64 |
|
|---|
| 65 |
|
|---|
| 66 |
else: |
|---|
| 67 |
|
|---|
| 68 |
self.lastUser = user.name |
|---|
| 69 |
message = re.sub('<.*?>', '', message) |
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
if ((user.name.replace(' ', '').lower() == 'aolsystemmsg') or (message.find('[Offline') != -1)): |
|---|
| 73 |
return |
|---|
| 74 |
|
|---|
| 75 |
|
|---|
| 76 |
self.brain.queue.add_incoming(user.name, message) |
|---|
| 77 |
global typing |
|---|
| 78 |
self.sendTypingNotification(user.name, not_typing) |
|---|
| 79 |
|
|---|
| 80 |
def messageAck(self, (username, response)): |
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
pass |
|---|
| 84 |
|
|---|
| 85 |
def format_message(self, message): |
|---|
| 86 |
'''Adds a custom font and color formatting HTML to 'message' and returns it''' |
|---|
| 87 |
return '<body bgcolor="#DFDFDF"><FONT COLOR="#0080ff" FACE="Comic Sans MS" SIZE=2>' + message.encode('ascii','ignore') + '</FONT>' |
|---|
| 88 |
|
|---|
| 89 |
def gotAway(self, away, user): |
|---|
| 90 |
return |
|---|
| 91 |
if away != None: |
|---|
| 92 |
print 'away', user, ':', away |
|---|
| 93 |
else: |
|---|
| 94 |
print 'back', user |
|---|
| 95 |
|
|---|
| 96 |
def sendTypingNotification(self, recipient, type): |
|---|
| 97 |
'''Sends 'recipient' a 'type' typing notification''' |
|---|
| 98 |
self.sendSNAC(0x04, 0x14, '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' + chr(len(recipient)) + recipient + type) |
|---|
| 99 |
|
|---|
| 100 |
def process_queue(self): |
|---|
| 101 |
'''Send any messages that are ready to go out''' |
|---|
| 102 |
(i_time, i_recipient, i_message) = (0, 1, 2) |
|---|
| 103 |
|
|---|
| 104 |
|
|---|
| 105 |
info = self.brain.queue.process() |
|---|
| 106 |
if info is not None: |
|---|
| 107 |
global not_typing |
|---|
| 108 |
self.sendTypingNotification(info[i_recipient], not_typing) |
|---|
| 109 |
message = self.brain.queue.code_to_smiley(info[i_message]) |
|---|
| 110 |
self.sendMessage(info[i_recipient], self.format_message(message), wantAck=1, autoResponse=info[i_away]).addCallback(self.messageAck) |
|---|
| 111 |
|
|---|
| 112 |
class OA(oscar.OscarAuthenticator): |
|---|
| 113 |
BOSClass = B |
|---|
| 114 |
|
|---|
| 115 |
if __name__ == "__main__": |
|---|
| 116 |
|
|---|
| 117 |
print "Signing into AOL...", |
|---|
| 118 |
protocol.ClientCreator(reactor, OA, SN, PASS, icq=0).connectTCP(*hostport) |
|---|
| 119 |
reactor.startRunning(installSignalHandlers=True) |
|---|
| 120 |
print "done!" |
|---|
| 121 |
|
|---|
| 122 |
|
|---|
| 123 |
while reactor.running: |
|---|
| 124 |
|
|---|
| 125 |
reactor.iterate(1) |
|---|
| 126 |
|
|---|
| 127 |
|
|---|
| 128 |
if bot != None: |
|---|
| 129 |
bot.process_queue() |
|---|
| 130 |
|
|---|
| 131 |
sleep(0.01) |
|---|
| 132 |
|
|---|