home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyo (Python 2.6) from __future__ import with_statement from util import strlist, lookup_table, bitflags_enabled, myip, callsback from util.packable import Packable from oscar.rendezvous.peer import OscarPeer from oscar.rendezvous.rendezvous import rendezvous_tlvs from oscar.OscarUtil import tlv_list import oscar import common import time import struct from logging import getLogger log = getLogger('oscar.rdv.directim') info = log.info import os.path as os import wx from util.BeautifulSoup import BeautifulSoup from functools import partial from oscar import OscarException from common.Protocol import StateMixin import hooks def directconnect(protocol, screenname): if not isinstance(screenname, str): raise TypeError('screenname must be a str') isinstance(screenname, str) ostrip = lambda s: s.lower().replace(' ', '') if ostrip(screenname) == ostrip(protocol.self_buddy.name): raise OscarException('You cannot direct connect with yourself.') ostrip(screenname) == ostrip(protocol.self_buddy.name) cookie = int(time.time() ** 2) protocol.rdv_sessions[cookie] = dim = OscarDirectIM(protocol, screenname, cookie) dim.request() return dim class ODCHeader(Packable): fmt = strlist('\n version 4s # always ODC2\n hdrlen H # length of header\n one H # 1\n six H # 6\n zero H # 0\n cookie Q # sixteen byte rendezvous cookie\n null Q\n length I\n encoding H\n subset H\n flags I\n zero I\n screenname 16s\n null2 16s ') def make(cls, *a, **k): k.update(dict(version = 'ODC2', static = 76, one = 1, six = 6, zero = 0, null = 0, null2 = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')) return cls(*a, **k) make = classmethod(make) bitflags = lookup_table({ 1: 'autoresponse', 2: 'typingpacket', 4: 'typed', 8: 'typing', 32: 'confirmation', 64: 'mac_confirmation' }) invars = [ (lambda o: o.version == 'ODC2')] class OscarDirectIM(OscarPeer, StateMixin): class Statuses: DISCONNECTED = 'Disconnected' CONNECTING = 'Connecting' ERROR = 'Error' CONNECTED = 'Connected' OFFLINE = DISCONNECTED class Reasons: NONE = 'None' def __init__(self, protocol, screenname, cookie): StateMixin.__init__(self, self.Statuses.CONNECTING) direct_im_cap = oscar.capabilities.by_name['direct_im'] OscarPeer.__init__(self, protocol, screenname, cookie, direct_im_cap) self.buddy = protocol.buddies[screenname] def accept(self): info('%r accepted', self) self.establish_dc() def handle_request(self, rendtlvs): self.send_rdv('cancel') def setup_convo(self): self.convo = self.protocol.convo_for(self.screenname) self.convo.setnotifyif('type', 'dc') self.convo.dc = self self.change_state(self.Statuses.CONNECTED) def on_odc_connection(self): self.socket.receive_next(ODCHeader, self.odc_header_received) self.setup_convo() self.send_odc(flags = 96) def odc_header_received(self, data): (packet, data) = ODCHeader.unpack(data) flags = bitflags_enabled(ODCHeader.bitflags, packet.flags) info('incoming ODC header - enabled flags: %s', ', '.join(flags)) typeset = partial(self.convo.set_typing_status, self.screenname) if 'typingpacket' in flags: if 'typing' in flags: typeset('typing') elif 'typed' in flags: typeset('typed') else: typeset(None) next = self.socket.receive_next leftover = packet.hdrlen - ODCHeader._struct.size if leftover: next(leftover, self.read_leftover(packet.length)) elif packet.length > 0: next(packet.length, self.odc_body_received) else: next(ODCHeader, self.odc_header_received) def read_leftover(self, paklen): info('read %d leftover bytes', paklen) next = self.socket.receive_next def callback(data): if paklen > 0: next(paklen, self.odc_body_received) else: next(ODCHeader, self.odc_header_received) return callback def odc_body_received(self, data): info('odc_body_received') import stdpaths assetdir = stdpaths.userdata self.convo.incoming_message(self.screenname, msg) self.socket.receive_next(ODCHeader, self.odc_header_received) def send_odc(self, data = '', flags = 0): bname = self.protocol.self_buddy.name packet = ODCHeader.make(cookie = self.cookie, screenname = bname) packet.flags = flags if isinstance(data, list): packet.length = sum((lambda .0: for d in .0: len(d))(data)) info('send_odc got a list, summed length is %d', packet.length) else: packet.length = len(data) info('send_odc got a string, length is %d', packet.length) packet.hdrlen = len(packet) info('sending ODC header to screenname %s (%d bytes of %r)', bname, len(packet), str(type(packet))) if isinstance(data, list): self.socket.push(packet.pack() + ''.join(data)) else: self.socket.push(packet.pack() + data) def send_typing(self, status): flag = { 'typing': 8, 'typed': 4, None: 0 }[status] self.send_odc(flags = 2 | flag) def request(self): self.establish_out_dc() def ch2accept(self, data): info('incoming dIM got channel 2 accept') def send_message(self, message): self.send_odc(message) def decline(self): self.send_rdv('cancel') def ch2cancel(self, data): info('%r cancelled', self) if hasattr(self, 'convo'): self.convo.setnotifyif('type', 'im') self.change_state(self.Statuses.DISCONNECTED) def disconnect(self): self.socket.close() del self.convo.dc self.convo.setnotifyif('type', 'im') self.change_state(self.Statuses.DISCONNECTED) def __repr__(self): return '<OscarDirectIM with %s>' % self.screenname def initialize(): log.info('\tloading rendezvous handler: direct IM') import oscar.rendezvous.peer as peer peer.register_rdv_factory('direct_im', OscarDirectIM) hooks.Hook('oscar.rdv.load').register(initialize)