use spaces for indention as mandated by PEP-8

This commit is contained in:
Steffen Vogel 2019-04-26 00:37:34 +02:00
parent 3ccb164f20
commit d022243f6c
10 changed files with 2274 additions and 2272 deletions

View File

@ -6,68 +6,68 @@ import time
import os import os
class Bot(): class Bot():
def __init__(self, session, name = "Bot"): def __init__(self, session, name = "Bot"):
self.session = session self.session = session
self.name = name self.name = name
self.commands = { self.commands = {
"help": self._help, "help": self._help,
"groups": self._groups, "groups": self._groups,
"getgroups": self._getgroups "getgroups": self._getgroups
} }
def parse(self, message): def parse(self, message):
args = message.strip().split(" ") args = message.strip().split(" ")
cmd = args.pop(0) cmd = args.pop(0)
if len(cmd) > 0 and cmd[0] == '\\': if len(cmd) > 0 and cmd[0] == '\\':
try: try:
self.call(cmd[1:], args) self.call(cmd[1:], args)
except KeyError: except KeyError:
self.send("invalid command") self.send("invalid command")
except TypeError: except TypeError:
self.send("invalid syntax") self.send("invalid syntax")
else: else:
self.send("a valid command starts with a backslash") self.send("a valid command starts with a backslash")
def call(self, cmd, args = []): def call(self, cmd, args = []):
func = self.commands[cmd.lower()] func = self.commands[cmd.lower()]
spec = inspect.getargspec(func) spec = inspect.getargspec(func)
maxs = len(spec.args) - 1 maxs = len(spec.args) - 1
reqs = maxs - len(spec.defaults or []) reqs = maxs - len(spec.defaults or [])
if (reqs > len(args)) or (len(args) > maxs): if (reqs > len(args)) or (len(args) > maxs):
raise TypeError() raise TypeError()
thread = threading.Thread(target=func, args=tuple(args)) thread = threading.Thread(target=func, args=tuple(args))
thread.start() thread.start()
def send(self, message): def send(self, message):
self.session.backend.handleMessage(self.session.user, self.name, message) self.session.backend.handleMessage(self.session.user, self.name, message)
# commands # commands
def _help(self): def _help(self):
self.send("""following bot commands are available: self.send("""following bot commands are available:
\\help show this message \\help show this message
following user commands are available: following user commands are available:
\\lastseen request last online timestamp from buddy \\lastseen request last online timestamp from buddy
following group commands are available following group commands are available
\\leave permanently leave group chat \\leave permanently leave group chat
\\groups print all attended groups \\groups print all attended groups
\\getgroups get current groups from WA""") \\getgroups get current groups from WA""")
def _groups(self): def _groups(self):
for group in self.session.groups: for group in self.session.groups:
buddy = self.session.groups[group].owner buddy = self.session.groups[group].owner
try: try:
nick = self.session.buddies[buddy].nick nick = self.session.buddies[buddy].nick
except KeyError: except KeyError:
nick = buddy nick = buddy
self.send(self.session.groups[group].id + "@" + self.session.backend.spectrum_jid + " " + self.session.groups[group].subject + " Owner: " + nick ) self.send(self.session.groups[group].id + "@" + self.session.backend.spectrum_jid + " " + self.session.groups[group].subject + " Owner: " + nick )
def _getgroups(self): def _getgroups(self):
#self.session.call("group_getGroups", ("participating",)) #self.session.call("group_getGroups", ("participating",))
self.session.requestGroupsList(self.session._updateGroups) self.session.requestGroupsList(self.session._updateGroups)

View File

@ -7,207 +7,207 @@ import Spectrum2
from . import deferred from . import deferred
class Buddy(): class Buddy():
def __init__(self, owner, number, nick, statusMsg, groups, image_hash): def __init__(self, owner, number, nick, statusMsg, groups, image_hash):
self.nick = nick self.nick = nick
self.owner = owner self.owner = owner
self.number = "%s" % number self.number = "%s" % number
self.groups = groups self.groups = groups
self.image_hash = image_hash if image_hash is not None else "" self.image_hash = image_hash if image_hash is not None else ""
self.statusMsg = u"" self.statusMsg = u""
self.lastseen = 0 self.lastseen = 0
self.presence = 0 self.presence = 0
def update(self, nick, groups, image_hash): def update(self, nick, groups, image_hash):
self.nick = nick self.nick = nick
self.groups = groups self.groups = groups
if image_hash is not None: if image_hash is not None:
self.image_hash = image_hash self.image_hash = image_hash
def __str__(self): def __str__(self):
# we must return str here # we must return str here
return str("%s (nick=%s)") % (self.number, self.nick) return str("%s (nick=%s)") % (self.number, self.nick)
class BuddyList(dict): class BuddyList(dict):
def __init__(self, owner, backend, user, session): def __init__(self, owner, backend, user, session):
self.owner = owner self.owner = owner
self.backend = backend self.backend = backend
self.session = session self.session = session
self.user = user self.user = user
self.logger = logging.getLogger(self.__class__.__name__) self.logger = logging.getLogger(self.__class__.__name__)
def _load(self, buddies): def _load(self, buddies):
for buddy in buddies: for buddy in buddies:
number = buddy.buddyName number = buddy.buddyName
nick = buddy.alias nick = buddy.alias
statusMsg = buddy.statusMessage statusMsg = buddy.statusMessage
groups = [g for g in buddy.group] groups = [g for g in buddy.group]
image_hash = buddy.iconHash image_hash = buddy.iconHash
self[number] = Buddy(self.owner, number, nick, statusMsg, self[number] = Buddy(self.owner, number, nick, statusMsg,
groups, image_hash) groups, image_hash)
self.logger.debug("Update roster") self.logger.debug("Update roster")
contacts = self.keys() contacts = self.keys()
contacts.remove('bot') contacts.remove('bot')
self.session.sendSync(contacts, delta=False, interactive=True, self.session.sendSync(contacts, delta=False, interactive=True,
success=self.onSync) success=self.onSync)
self.logger.debug("Roster add: %s" % list(contacts)) self.logger.debug("Roster add: %s" % list(contacts))
for number in contacts: for number in contacts:
buddy = self[number] buddy = self[number]
self.updateSpectrum(buddy) self.updateSpectrum(buddy)
def onSync(self, existing, nonexisting, invalid): def onSync(self, existing, nonexisting, invalid):
"""We should only presence subscribe to existing numbers""" """We should only presence subscribe to existing numbers"""
for number in existing: for number in existing:
self.session.subscribePresence(number) self.session.subscribePresence(number)
self.logger.debug("%s is requesting statuses of: %s" % (self.user, existing)) self.logger.debug("%s is requesting statuses of: %s" % (self.user, existing))
self.session.requestStatuses(existing, success = self.onStatus) self.session.requestStatuses(existing, success = self.onStatus)
self.logger.debug("Removing nonexisting buddies %s" % nonexisting) self.logger.debug("Removing nonexisting buddies %s" % nonexisting)
for number in nonexisting: for number in nonexisting:
self.remove(number) self.remove(number)
try: del self[number] try: del self[number]
except KeyError: self.logger.warn("non-existing buddy really didn't exist: %s" % number) except KeyError: self.logger.warn("non-existing buddy really didn't exist: %s" % number)
self.logger.debug("Removing invalid buddies %s" % invalid) self.logger.debug("Removing invalid buddies %s" % invalid)
for number in invalid: for number in invalid:
self.remove(number) self.remove(number)
try: del self[number] try: del self[number]
except KeyError: self.logger.warn("non-existing buddy really didn't exist: %s" % number) except KeyError: self.logger.warn("non-existing buddy really didn't exist: %s" % number)
def onStatus(self, contacts): def onStatus(self, contacts):
self.logger.debug("%s received statuses of: %s" % (self.user, contacts)) self.logger.debug("%s received statuses of: %s" % (self.user, contacts))
for number, (status, time) in contacts.iteritems(): for number, (status, time) in contacts.iteritems():
try: buddy = self[number] try: buddy = self[number]
except KeyError: self.logger.warn("received status of buddy not in list: %s" % number) except KeyError: self.logger.warn("received status of buddy not in list: %s" % number)
if status is None: if status is None:
buddy.statusMsg = "" buddy.statusMsg = ""
else: else:
buddy.statusMsg = status buddy.statusMsg = status
self.updateSpectrum(buddy) self.updateSpectrum(buddy)
def load(self, buddies): def load(self, buddies):
if self.session.loggedIn: if self.session.loggedIn:
self._load(buddies) self._load(buddies)
else: else:
self.session.loginQueue.append(lambda: self._load(buddies)) self.session.loginQueue.append(lambda: self._load(buddies))
def update(self, number, nick, groups, image_hash): def update(self, number, nick, groups, image_hash):
if number in self: if number in self:
buddy = self[number] buddy = self[number]
buddy.update(nick, groups, image_hash) buddy.update(nick, groups, image_hash)
else: else:
buddy = Buddy(self.owner, number, nick, "", groups, image_hash) buddy = Buddy(self.owner, number, nick, "", groups, image_hash)
self[number] = buddy self[number] = buddy
self.logger.debug("Roster add: %s" % buddy) self.logger.debug("Roster add: %s" % buddy)
self.session.sendSync([number], delta = True, interactive = True) self.session.sendSync([number], delta = True, interactive = True)
self.session.subscribePresence(number) self.session.subscribePresence(number)
self.session.requestStatuses([number], success = self.onStatus) self.session.requestStatuses([number], success = self.onStatus)
if image_hash == "" or image_hash is None: if image_hash == "" or image_hash is None:
self.requestVCard(number) self.requestVCard(number)
self.updateSpectrum(buddy) self.updateSpectrum(buddy)
return buddy return buddy
def updateSpectrum(self, buddy): def updateSpectrum(self, buddy):
if buddy.presence == 0: if buddy.presence == 0:
status = Spectrum2.protocol_pb2.STATUS_NONE status = Spectrum2.protocol_pb2.STATUS_NONE
elif buddy.presence == 'unavailable': elif buddy.presence == 'unavailable':
status = Spectrum2.protocol_pb2.STATUS_AWAY status = Spectrum2.protocol_pb2.STATUS_AWAY
else: else:
status = Spectrum2.protocol_pb2.STATUS_ONLINE status = Spectrum2.protocol_pb2.STATUS_ONLINE
statusmsg = buddy.statusMsg statusmsg = buddy.statusMsg
if buddy.lastseen != 0: if buddy.lastseen != 0:
timestamp = time.localtime(buddy.lastseen) timestamp = time.localtime(buddy.lastseen)
statusmsg += time.strftime("\n Last seen: %a, %d %b %Y %H:%M:%S", timestamp) statusmsg += time.strftime("\n Last seen: %a, %d %b %Y %H:%M:%S", timestamp)
iconHash = buddy.image_hash if buddy.image_hash is not None else "" iconHash = buddy.image_hash if buddy.image_hash is not None else ""
self.logger.debug("Updating buddy %s (%s) in %s, image_hash = %s" % self.logger.debug("Updating buddy %s (%s) in %s, image_hash = %s" %
(buddy.nick, buddy.number, buddy.groups, iconHash)) (buddy.nick, buddy.number, buddy.groups, iconHash))
self.logger.debug("Status Message: %s" % statusmsg) self.logger.debug("Status Message: %s" % statusmsg)
self.backend.handleBuddyChanged(self.user, buddy.number, buddy.nick, self.backend.handleBuddyChanged(self.user, buddy.number, buddy.nick,
buddy.groups, status, statusMessage=statusmsg, iconHash=iconHash) buddy.groups, status, statusMessage=statusmsg, iconHash=iconHash)
def remove(self, number): def remove(self, number):
try: try:
buddy = self[number] buddy = self[number]
del self[number] del self[number]
self.backend.handleBuddyChanged(self.user, number, "", [], self.backend.handleBuddyChanged(self.user, number, "", [],
Spectrum2.protocol_pb2.STATUS_NONE) Spectrum2.protocol_pb2.STATUS_NONE)
self.backend.handleBuddyRemoved(self.user, number) self.backend.handleBuddyRemoved(self.user, number)
self.session.unsubscribePresence(number) self.session.unsubscribePresence(number)
# TODO Sync remove # TODO Sync remove
return buddy return buddy
except KeyError: except KeyError:
return None return None
def requestVCard(self, buddy, ID=None): def requestVCard(self, buddy, ID=None):
if "/" in buddy: if "/" in buddy:
room, nick = buddy.split("/") room, nick = buddy.split("/")
group = self.session.groups[room] group = self.session.groups[room]
buddynr = None buddynr = None
for othernumber, othernick in group.participants.iteritems(): for othernumber, othernick in group.participants.iteritems():
if othernick == nick: if othernick == nick:
buddynr = othernumber buddynr = othernumber
break break
if buddynr is None: if buddynr is None:
return return
else: else:
buddynr = buddy buddynr = buddy
if buddynr == self.user or buddynr == self.user.split('@')[0]: if buddynr == self.user or buddynr == self.user.split('@')[0]:
buddynr = self.session.legacyName buddynr = self.session.legacyName
# Get profile picture # Get profile picture
self.logger.debug('Requesting profile picture of %s' % buddynr) self.logger.debug('Requesting profile picture of %s' % buddynr)
response = deferred.Deferred() response = deferred.Deferred()
# Error probably means image doesn't exist # Error probably means image doesn't exist
error = deferred.Deferred() error = deferred.Deferred()
self.session.requestProfilePicture(buddynr, onSuccess=response.run, self.session.requestProfilePicture(buddynr, onSuccess=response.run,
onFailure=error.run) onFailure=error.run)
response = response.arg(0) response = response.arg(0)
pictureData = response.pictureData() pictureData = response.pictureData()
# Send VCard # Send VCard
if ID != None: if ID != None:
deferred.call(self.logger.debug, 'Sending VCard (%s) with image id %s: %s' % deferred.call(self.logger.debug, 'Sending VCard (%s) with image id %s: %s' %
(ID, response.pictureId(), pictureData.then(base64.b64encode))) (ID, response.pictureId(), pictureData.then(base64.b64encode)))
deferred.call(self.backend.handleVCard, self.user, ID, buddy, "", "", deferred.call(self.backend.handleVCard, self.user, ID, buddy, "", "",
pictureData) pictureData)
# If error # If error
error.when(self.logger.debug, 'Sending VCard (%s) without image' % ID) error.when(self.logger.debug, 'Sending VCard (%s) without image' % ID)
error.when(self.backend.handleVCard, self.user, ID, buddy, "", "", "") error.when(self.backend.handleVCard, self.user, ID, buddy, "", "", "")
# Send image hash # Send image hash
if not buddynr == self.session.legacyName: if not buddynr == self.session.legacyName:
try: try:
obuddy = self[buddynr] obuddy = self[buddynr]
nick = obuddy.nick nick = obuddy.nick
groups = obuddy.groups groups = obuddy.groups
except KeyError: except KeyError:
nick = "" nick = ""
groups = [] groups = []
def sha1hash(data): def sha1hash(data):
hashlib.sha1(data).hexdigest() hashlib.sha1(data).hexdigest()
image_hash = pictureData.then(sha1hash) image_hash = pictureData.then(sha1hash)
deferred.call(self.logger.debug, 'Image hash is %s' % image_hash) deferred.call(self.logger.debug, 'Image hash is %s' % image_hash)
deferred.call(self.update, buddynr, nick, groups, image_hash) deferred.call(self.update, buddynr, nick, groups, image_hash)
# No image # No image
error.when(self.logger.debug, 'No image') error.when(self.logger.debug, 'No image')
error.when(self.update, buddynr, nick, groups, '') error.when(self.update, buddynr, nick, groups, '')
def refresh(self, number): def refresh(self, number):
self.session.unsubscribePresence(number) self.session.unsubscribePresence(number)
self.session.subscribePresence(number) self.session.subscribePresence(number)
self.requestVCard(number) self.requestVCard(number)
self.session.requestStatuses([number], success = self.onStatus) self.session.requestStatuses([number], success = self.onStatus)

View File

@ -1,139 +1,139 @@
from functools import partial from functools import partial
class Deferred(object): class Deferred(object):
""" """
Represents a delayed computation. This is a more elegant way to deal with Represents a delayed computation. This is a more elegant way to deal with
callbacks. callbacks.
A Deferred object can be thought of as a computation whose value is yet to A Deferred object can be thought of as a computation whose value is yet to
be determined. We can manipulate the Deferred as if it where a regular be determined. We can manipulate the Deferred as if it where a regular
value by using the then method. Computations dependent on the Deferred will value by using the then method. Computations dependent on the Deferred will
only proceed when the run method is called. only proceed when the run method is called.
Attributes of a Deferred can be accessed directly as methods. The result of Attributes of a Deferred can be accessed directly as methods. The result of
calling these functions will be Deferred. calling these functions will be Deferred.
Example: Example:
image = Deferred() image = Deferred()
getImageWithCallback(image.run) getImageWithCallback(image.run)
image.then(displayFunc) image.then(displayFunc)
colors = Deferred() colors = Deferred()
colors.append('blue') colors.append('blue')
colors.then(print) colors.then(print)
colors.run(['red', 'green']) #=> ['red', 'green', 'blue'] colors.run(['red', 'green']) #=> ['red', 'green', 'blue']
""" """
def __init__(self): def __init__(self):
self.subscribers = [] self.subscribers = []
self.computed = False self.computed = False
self.args = None self.args = None
self.kwargs = None self.kwargs = None
def run(self, *args, **kwargs): def run(self, *args, **kwargs):
""" """
Give a value to the deferred. Calling this method more than once will Give a value to the deferred. Calling this method more than once will
result in a DeferredHasValue exception to be raised. result in a DeferredHasValue exception to be raised.
""" """
if self.computed: if self.computed:
raise DeferredHasValue("Deferred object already has a value.") raise DeferredHasValue("Deferred object already has a value.")
else: else:
self.args = args self.args = args
self.kwargs = kwargs self.kwargs = kwargs
for func, deferred in self.subscribers: for func, deferred in self.subscribers:
deferred.run(func(*args, **kwargs)) deferred.run(func(*args, **kwargs))
self.computed = True self.computed = True
def then(self, func): def then(self, func):
""" """
Apply func to Deferred value. Returns a Deferred whose value will be Apply func to Deferred value. Returns a Deferred whose value will be
the result of applying func. the result of applying func.
""" """
result = Deferred() result = Deferred()
if self.computed: if self.computed:
result.run(func(*self.args, **self.kwargs)) result.run(func(*self.args, **self.kwargs))
else: else:
self.subscribers.append((func, result)) self.subscribers.append((func, result))
return result return result
def arg(self, n): def arg(self, n):
""" """
Returns the nth positional argument of a deferred as a deferred Returns the nth positional argument of a deferred as a deferred
Args: Args:
n - the index of the positional argument n - the index of the positional argument
""" """
def helper(*args, **kwargs): def helper(*args, **kwargs):
return args[n] return args[n]
return self.then(helper) return self.then(helper)
def when(self, func, *args, **kwargs): def when(self, func, *args, **kwargs):
""" Calls when func(*args, **kwargs) when deferred gets a value """ """ Calls when func(*args, **kwargs) when deferred gets a value """
def helper(*args2, **kwargs2): def helper(*args2, **kwargs2):
func(*args, **kwargs) func(*args, **kwargs)
return self.then(helper) return self.then(helper)
def __getattr__(self, method_name): def __getattr__(self, method_name):
return getattr(Then(self), method_name) return getattr(Then(self), method_name)
class Then(object): class Then(object):
""" """
Allows you to call methods on a Deferred. Allows you to call methods on a Deferred.
Example: Example:
colors = Deferred() colors = Deferred()
Then(colors).append('blue') Then(colors).append('blue')
colors.run(['red', 'green']) colors.run(['red', 'green'])
colors.then(print) #=> ['red', 'green', 'blue'] colors.then(print) #=> ['red', 'green', 'blue']
""" """
def __init__(self, deferred): def __init__(self, deferred):
self.deferred = deferred self.deferred = deferred
def __getattr__(self, name): def __getattr__(self, name):
def tryCall(obj, *args, **kwargs): def tryCall(obj, *args, **kwargs):
if callable(obj): if callable(obj):
return obj(*args, **kwargs) return obj(*args, **kwargs)
else: else:
return obj return obj
def helper(*args, **kwargs): def helper(*args, **kwargs):
func = (lambda x: tryCall(getattr(x, name), *args, **kwargs)) func = (lambda x: tryCall(getattr(x, name), *args, **kwargs))
return self.deferred.then(func) return self.deferred.then(func)
return helper return helper
def call(func, *args, **kwargs): def call(func, *args, **kwargs):
""" """
Call a function with deferred arguments Call a function with deferred arguments
Example: Example:
colors = Deferred() colors = Deferred()
colors.append('blue') colors.append('blue')
colors.run(['red', 'green']) colors.run(['red', 'green'])
call(print, colors) #=> ['red', 'green', 'blue'] call(print, colors) #=> ['red', 'green', 'blue']
call(print, 'hi', colors) #=> hi ['red', 'green', 'blue'] call(print, 'hi', colors) #=> hi ['red', 'green', 'blue']
""" """
for i, c in enumerate(args): for i, c in enumerate(args):
if isinstance(c, Deferred): if isinstance(c, Deferred):
# Function without deferred arguments # Function without deferred arguments
normalfunc = partial(func, *args[:i]) normalfunc = partial(func, *args[:i])
# Function with deferred and possibly deferred arguments # Function with deferred and possibly deferred arguments
def restfunc(*arg2, **kwarg2): def restfunc(*arg2, **kwarg2):
apply_deferred = partial(normalfunc, *arg2, **kwarg2) apply_deferred = partial(normalfunc, *arg2, **kwarg2)
return call(apply_deferred, *args[i + 1:], **kwargs) return call(apply_deferred, *args[i + 1:], **kwargs)
return c.then(restfunc) return c.then(restfunc)
items = kwargs.items() items = kwargs.items()
for i, (k, v) in enumerate(items): for i, (k, v) in enumerate(items):
if isinstance(v, Deferred): if isinstance(v, Deferred):
# Function without deferred arguments # Function without deferred arguments
normalfunc = partial(func, *args, **dict(items[:i])) normalfunc = partial(func, *args, **dict(items[:i]))
# Function with deferred and possibly deferred arguments # Function with deferred and possibly deferred arguments
def restfunc2(*arg2, **kwarg2): def restfunc2(*arg2, **kwarg2):
apply_deferred = partial(normalfunc, *arg2, **kwarg2) apply_deferred = partial(normalfunc, *arg2, **kwarg2)
return call(apply_deferred, **dict(items[i + 1:])) return call(apply_deferred, **dict(items[i + 1:]))
return v.then(restfunc2) return v.then(restfunc2)
# No items deferred # No items deferred
return func(*args, **kwargs) return func(*args, **kwargs)
class DeferredHasValue(Exception): class DeferredHasValue(Exception):
def __init__(self, string): def __init__(self, string):
super(DeferredHasValue, self).__init__(string) super(DeferredHasValue, self).__init__(string)

View File

@ -2,83 +2,83 @@ import Spectrum2
class Group(): class Group():
def __init__(self, id, owner, subject, subjectOwner, backend, user): def __init__(self, id, owner, subject, subjectOwner, backend, user):
self.id = id self.id = id
self.subject = subject self.subject = subject
self.subjectOwner = subjectOwner self.subjectOwner = subjectOwner
self.owner = owner self.owner = owner
self.joined = False self.joined = False
self.backend = backend self.backend = backend
self.user = user self.user = user
self.nick = "me" self.nick = "me"
# Participants is a number -> nickname dict # Participants is a number -> nickname dict
self.participants = {} self.participants = {}
def addParticipants(self, participants, buddies, yourNumber): def addParticipants(self, participants, buddies, yourNumber):
""" """
Adds participants to the group. Adds participants to the group.
Args: Args:
- participants: (Iterable) phone numbers of participants - participants: (Iterable) phone numbers of participants
- buddies: (dict) Used to get the nicknames of the participants - buddies: (dict) Used to get the nicknames of the participants
- yourNumber: The number you are using - yourNumber: The number you are using
""" """
for jid in participants: for jid in participants:
number = jid.split('@')[0] number = jid.split('@')[0]
try: try:
nick = buddies[number].nick nick = buddies[number].nick
except KeyError: except KeyError:
nick = number nick = number
if number == yourNumber: if number == yourNumber:
nick = self.nick nick = self.nick
if nick == "": if nick == "":
nick = number nick = number
self.participants[number] = nick self.participants[number] = nick
def sendParticipantsToSpectrum(self, yourNumber): def sendParticipantsToSpectrum(self, yourNumber):
for number, nick in self.participants.iteritems(): for number, nick in self.participants.iteritems():
if number == self.owner: if number == self.owner:
flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_MODERATOR flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_MODERATOR
else: else:
flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_NONE flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_NONE
if number == yourNumber: if number == yourNumber:
flags = flags | Spectrum2.protocol_pb2.PARTICIPANT_FLAG_ME flags = flags | Spectrum2.protocol_pb2.PARTICIPANT_FLAG_ME
try: try:
self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_ONLINE, self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_ONLINE,
self.backend.sessions[self.user].buddies[number].image_hash) self.backend.sessions[self.user].buddies[number].image_hash)
except KeyError: except KeyError:
self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_ONLINE) self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_ONLINE)
def removeParticipants(self, participants): def removeParticipants(self, participants):
for jid in participants: for jid in participants:
number = jid.split('@')[0] number = jid.split('@')[0]
nick = self.participants[number] nick = self.participants[number]
flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_NONE flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_NONE
self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_NONE) self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_NONE)
del self.participants[number] del self.participants[number]
def leaveRoom(self): def leaveRoom(self):
for number in self.participants: for number in self.participants:
nick = self.participants[number] nick = self.participants[number]
flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_ROOM_NOT_FOUND flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_ROOM_NOT_FOUND
self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_NONE) self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_NONE)
def changeNick(self, number, new_nick): def changeNick(self, number, new_nick):
if self.participants[number] == new_nick: if self.participants[number] == new_nick:
return return
if number == self.owner: if number == self.owner:
flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_MODERATOR flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_MODERATOR
else: else:
flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_NONE flags = Spectrum2.protocol_pb2.PARTICIPANT_FLAG_NONE
self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_ONLINE, new_nick) self._updateParticipant(number, flags, Spectrum2.protocol_pb2.STATUS_ONLINE, new_nick)
self.participants[number] = new_nick self.participants[number] = new_nick
def _updateParticipant(self, number, flags, status, imageHash = "", newNick = ""): def _updateParticipant(self, number, flags, status, imageHash = "", newNick = ""):
nick = self.participants[number] nick = self.participants[number]
# Notice the status message is the buddy's number # Notice the status message is the buddy's number
if self.joined: if self.joined:
self.backend.handleParticipantChanged( self.backend.handleParticipantChanged(
self.user, nick, self.id, flags, self.user, nick, self.id, flags,
status, number, newname = newNick, iconHash = imageHash) status, number, newname = newNick, iconHash = imageHash)

View File

@ -8,142 +8,142 @@ from . import threadutils
class RegisterSession(YowsupApp): class RegisterSession(YowsupApp):
""" """
A dummy Session object that is used to register a user to whatsapp A dummy Session object that is used to register a user to whatsapp
""" """
WANT_CC = 0 WANT_CC = 0
WANT_SMS = 1 WANT_SMS = 1
def __init__(self, backend, user, legacyName, extra): def __init__(self, backend, user, legacyName, extra):
self.user = user self.user = user
self.number = legacyName self.number = legacyName
self.backend = backend self.backend = backend
self.countryCode = '' self.countryCode = ''
self.logger = logging.getLogger(self.__class__.__name__) self.logger = logging.getLogger(self.__class__.__name__)
self.state = self.WANT_CC self.state = self.WANT_CC
def login(self, password=""): def login(self, password=""):
self.backend.handleConnected(self.user) self.backend.handleConnected(self.user)
self.backend.handleBuddyChanged(self.user, 'bot', 'bot', self.backend.handleBuddyChanged(self.user, 'bot', 'bot',
['Admin'], Spectrum2.protocol_pb2.STATUS_ONLINE) ['Admin'], Spectrum2.protocol_pb2.STATUS_ONLINE)
self.backend.handleMessage(self.user, 'bot', self.backend.handleMessage(self.user, 'bot',
'Please enter your country code') 'Please enter your country code')
def sendMessageToWA(self, buddy, message, ID='', xhtml=''): def sendMessageToWA(self, buddy, message, ID='', xhtml=''):
if buddy == 'bot' and self.state == self.WANT_CC: if buddy == 'bot' and self.state == self.WANT_CC:
try: try:
country_code = int(message.strip()) country_code = int(message.strip())
except ValueError: except ValueError:
self.backend.handleMessage(self.user, 'bot', self.backend.handleMessage(self.user, 'bot',
'Country code must be a number') 'Country code must be a number')
else: # Succeded in decoding country code else: # Succeded in decoding country code
country_code = "%s" % country_code country_code = "%s" % country_code
if country_code != self.number[:len(country_code)]: if country_code != self.number[:len(country_code)]:
self.backend.handleMessage(self.user, self.backend.handleMessage(self.user,
'bot', 'Number does not start with provided country code') 'bot', 'Number does not start with provided country code')
else: else:
self.backend.handleMessage(self.user, 'bot', 'Requesting sms code') self.backend.handleMessage(self.user, 'bot', 'Requesting sms code')
self.logger.debug('Requesting SMS code for %s' % self.user) self.logger.debug('Requesting SMS code for %s' % self.user)
self.countryCode = country_code self.countryCode = country_code
self._requestSMSCodeNonBlock() self._requestSMSCodeNonBlock()
elif buddy == 'bot' and self.state == self.WANT_SMS: elif buddy == 'bot' and self.state == self.WANT_SMS:
code = message.strip() code = message.strip()
if self._checkSMSFormat(code): if self._checkSMSFormat(code):
self._requestPassword(code) self._requestPassword(code)
else: else:
self.backend.handleMessage(self.user, self.backend.handleMessage(self.user,
'bot', 'Invalid code. Must be of the form XXX-XXX.') 'bot', 'Invalid code. Must be of the form XXX-XXX.')
else: else:
self.logger.warn('Unauthorised user (%s) attempting to send messages' % self.logger.warn('Unauthorised user (%s) attempting to send messages' %
self.user) self.user)
self.backend.handleMessage(self.user, buddy, self.backend.handleMessage(self.user, buddy,
'You are not logged in yet. You can only send messages to bot.') 'You are not logged in yet. You can only send messages to bot.')
def _checkSMSFormat(self, sms): def _checkSMSFormat(self, sms):
splitting = sms.split('-') splitting = sms.split('-')
if len(splitting) != 2: if len(splitting) != 2:
return False return False
a, b = splitting a, b = splitting
if len(a) != 3 and len(b) != 3: if len(a) != 3 and len(b) != 3:
return False return False
try: try:
int(a) int(a)
int(b) int(b)
except ValueError: except ValueError:
return False return False
return True return True
def _requestSMSCodeNonBlock(self): def _requestSMSCodeNonBlock(self):
number = self.number[len(self.countryCode):] number = self.number[len(self.countryCode):]
threadFunc = lambda: self.requestSMSCode(self.countryCode, number) threadFunc = lambda: self.requestSMSCode(self.countryCode, number)
threadutils.runInThread(threadFunc, self._confirmation) threadutils.runInThread(threadFunc, self._confirmation)
self.backend.handleMessage(self.user, 'bot', 'SMS Code Sent') self.backend.handleMessage(self.user, 'bot', 'SMS Code Sent')
def _confirmation(self, result): def _confirmation(self, result):
self.state = self.WANT_SMS self.state = self.WANT_SMS
resultStr = self._resultToString(result) resultStr = self._resultToString(result)
self.backend.handleMessage(self.user, 'bot', 'Response:') self.backend.handleMessage(self.user, 'bot', 'Response:')
self.backend.handleMessage(self.user, 'bot', resultStr) self.backend.handleMessage(self.user, 'bot', resultStr)
self.backend.handleMessage(self.user, 'bot', 'Please enter SMS Code') self.backend.handleMessage(self.user, 'bot', 'Please enter SMS Code')
def _requestPassword(self, smsCode): def _requestPassword(self, smsCode):
cc = self.countryCode cc = self.countryCode
number = self.number[len(cc):] number = self.number[len(cc):]
threadFunc = lambda: self.requestPassword(cc, number, smsCode) threadFunc = lambda: self.requestPassword(cc, number, smsCode)
threadutils.runInThread(threadFunc, self._gotPassword) threadutils.runInThread(threadFunc, self._gotPassword)
self.backend.handleMessage(self.user, 'bot', 'Getting Password') self.backend.handleMessage(self.user, 'bot', 'Getting Password')
def _gotPassword(self, result): def _gotPassword(self, result):
resultStr = self._resultToString(result) resultStr = self._resultToString(result)
self.backend.handleMessage(self.user, 'bot', 'Response:') self.backend.handleMessage(self.user, 'bot', 'Response:')
self.backend.handleMessage(self.user, 'bot', resultStr) self.backend.handleMessage(self.user, 'bot', resultStr)
self.backend.handleMessage(self.user, 'bot', 'Logging you in') self.backend.handleMessage(self.user, 'bot', 'Logging you in')
password = result['pw'] password = result['pw']
self.backend.relogin(self.user, self.number, password, None) self.backend.relogin(self.user, self.number, password, None)
def _resultToString(self, result): def _resultToString(self, result):
unistr = str if sys.version_info >= (3, 0) else unicode unistr = str if sys.version_info >= (3, 0) else unicode
out = [] out = []
for k, v in result.items(): for k, v in result.items():
if v is None: if v is None:
continue continue
out.append("%s: %s" % (k, v)) out.append("%s: %s" % (k, v))
return "\n".join(out) return "\n".join(out)
# Dummy methods. Whatsapp backend might call these, but they should have no # Dummy methods. Whatsapp backend might call these, but they should have no
# effect # effect
def logout(self): def logout(self):
pass pass
def joinRoom(self, room, nickname): def joinRoom(self, room, nickname):
pass pass
def leaveRoom(self, room): def leaveRoom(self, room):
pass pass
def changeStatusMessage(self, statusMessage): def changeStatusMessage(self, statusMessage):
pass pass
def changeStatus(self, status): def changeStatus(self, status):
pass pass
def loadBuddies(self, buddies): def loadBuddies(self, buddies):
pass pass
def updateBuddy(self, buddies): def updateBuddy(self, buddies):
pass pass
def removeBuddy(self, buddies): def removeBuddy(self, buddies):
pass pass
def sendTypingStarted(self, buddy): def sendTypingStarted(self, buddy):
pass pass
def sendTypingStopped(self, buddy): def sendTypingStopped(self, buddy):
pass pass
def requestVCard(self, buddy, ID): def requestVCard(self, buddy, ID):
pass pass
def setProfilePicture(self, previewPicture, fullPicture = None): def setProfilePicture(self, previewPicture, fullPicture = None):
pass pass

File diff suppressed because it is too large Load Diff

View File

@ -5,16 +5,16 @@ import threading
eventQueue = queue.Queue() eventQueue = queue.Queue()
def runInThread(threadFunc, callback): def runInThread(threadFunc, callback):
""" """
Executes threadFunc in a new thread. The result of threadFunc will be Executes threadFunc in a new thread. The result of threadFunc will be
pass as the first argument to callback. callback will be called in the main pass as the first argument to callback. callback will be called in the main
thread. thread.
""" """
def helper(): def helper():
# Execute threadfunc in new thread # Execute threadfunc in new thread
result = threadFunc() result = threadFunc()
# Queue callback to be call in main thread # Queue callback to be call in main thread
eventQueue.put(lambda: callback(result)) eventQueue.put(lambda: callback(result))
thread = threading.Thread(target=helper) thread = threading.Thread(target=helper)
thread.start() thread.start()

View File

@ -21,8 +21,8 @@ parser.add_argument('--log', type=str)
parser.add_argument('--host', type=str, required=True) parser.add_argument('--host', type=str, required=True)
parser.add_argument('--port', type=int, required=True) parser.add_argument('--port', type=int, required=True)
parser.add_argument('--service.backend_id', metavar="ID", type=int, required=True) parser.add_argument('--service.backend_id', metavar="ID", type=int, required=True)
parser.add_argument('config', type=str)
parser.add_argument('-j', type=str, metavar="JID", required=True) parser.add_argument('-j', type=str, metavar="JID", required=True)
parser.add_argument('config', type=str)
args, unknown = parser.parse_known_args() args, unknown = parser.parse_known_args()
@ -75,14 +75,16 @@ def main():
try: try:
asyncore.loop(timeout=1.0, count=10, use_poll = True) asyncore.loop(timeout=1.0, count=10, use_poll = True)
try: try:
callback = YowStack._YowStack__detachedQueue.get(False) #doesn't block callback = YowStack._YowStack__detachedQueue.get(False) # doesn't block
callback() callback()
except queue.Empty: except queue.Empty:
pass pass
else: else:
break break
if closed: if closed:
break break
while True: while True:
try: try:
callback = threadutils.eventQueue.get_nowait() callback = threadutils.eventQueue.get_nowait()

View File

@ -5,140 +5,140 @@ from .session import Session
from .registersession import RegisterSession from .registersession import RegisterSession
class WhatsAppBackend(Spectrum2.Backend): class WhatsAppBackend(Spectrum2.Backend):
def __init__(self, io, spectrum_jid, specConf): def __init__(self, io, spectrum_jid, specConf):
Spectrum2.Backend.__init__(self) Spectrum2.Backend.__init__(self)
self.logger = logging.getLogger(self.__class__.__name__) self.logger = logging.getLogger(self.__class__.__name__)
self.io = io self.io = io
self.specConf = specConf self.specConf = specConf
self.sessions = { } self.sessions = { }
self.spectrum_jid = spectrum_jid self.spectrum_jid = spectrum_jid
# Used to prevent duplicate messages # Used to prevent duplicate messages
self.lastMsgId = {} self.lastMsgId = {}
self.logger.debug("Backend started") self.logger.debug("Backend started")
# RequestsHandlers # RequestsHandlers
def handleLoginRequest(self, user, legacyName, password, extra): def handleLoginRequest(self, user, legacyName, password, extra):
self.logger.debug("handleLoginRequest(user=%s, legacyName=%s)" % (user, legacyName)) self.logger.debug("handleLoginRequest(user=%s, legacyName=%s)" % (user, legacyName))
# Key word means we should register a new password # Key word means we should register a new password
if password == 'register': if password == 'register':
if user not in self.sessions: if user not in self.sessions:
self.sessions[user] = RegisterSession(self, user, legacyName, extra) self.sessions[user] = RegisterSession(self, user, legacyName, extra)
else: else:
if user not in self.sessions: if user not in self.sessions:
self.sessions[user] = Session(self, user, legacyName, extra) self.sessions[user] = Session(self, user, legacyName, extra)
self.sessions[user].login(password) self.sessions[user].login(password)
def handleLogoutRequest(self, user, legacyName): def handleLogoutRequest(self, user, legacyName):
self.logger.debug("handleLogoutRequest(user=%s, legacyName=%s)" % (user, legacyName)) self.logger.debug("handleLogoutRequest(user=%s, legacyName=%s)" % (user, legacyName))
if user in self.sessions: if user in self.sessions:
self.sessions[user].logout() self.sessions[user].logout()
del self.sessions[user] del self.sessions[user]
def handleMessageSendRequest(self, user, buddy, message, xhtml="", ID=""): def handleMessageSendRequest(self, user, buddy, message, xhtml="", ID=""):
self.logger.debug("handleMessageSendRequest(user=%s, buddy=%s, message=%s, xhtml=%s, ID=%s)" % self.logger.debug("handleMessageSendRequest(user=%s, buddy=%s, message=%s, xhtml=%s, ID=%s)" %
( user, buddy, message, xhtml, ID)) ( user, buddy, message, xhtml, ID))
# For some reason spectrum occasionally sends to identical messages to # For some reason spectrum occasionally sends to identical messages to
# a buddy, one to the bare jid and one to the /bot resource. This # a buddy, one to the bare jid and one to the /bot resource. This
# causes duplicate messages. Thus we should not send consecutive # causes duplicate messages. Thus we should not send consecutive
# messages with the same id # messages with the same id
if ID == '': if ID == '':
self.sessions[user].sendMessageToWA(buddy, message, ID, xhtml) self.sessions[user].sendMessageToWA(buddy, message, ID, xhtml)
elif user not in self.lastMsgId or self.lastMsgId[user] != ID: elif user not in self.lastMsgId or self.lastMsgId[user] != ID:
self.sessions[user].sendMessageToWA(buddy, message, ID, xhtml) self.sessions[user].sendMessageToWA(buddy, message, ID, xhtml)
self.lastMsgId[user] = ID self.lastMsgId[user] = ID
def handleJoinRoomRequest(self, user, room, nickname, pasword): def handleJoinRoomRequest(self, user, room, nickname, pasword):
self.logger.debug("handleJoinRoomRequest(user=%s, room=%s, nickname=%s)" % (user, room, nickname)) self.logger.debug("handleJoinRoomRequest(user=%s, room=%s, nickname=%s)" % (user, room, nickname))
self.sessions[user].joinRoom(room, nickname) self.sessions[user].joinRoom(room, nickname)
def handleLeaveRoomRequest(self, user, room): def handleLeaveRoomRequest(self, user, room):
self.logger.debug("handleLeaveRoomRequest(user=%s, room=%s)" % (user, room)) self.logger.debug("handleLeaveRoomRequest(user=%s, room=%s)" % (user, room))
self.sessions[user].leaveRoom(room) self.sessions[user].leaveRoom(room)
def handleStatusChangeRequest(self, user, status, statusMessage): def handleStatusChangeRequest(self, user, status, statusMessage):
self.logger.debug("handleStatusChangeRequest(user=%s, status=%d, statusMessage=%s)" % (user, status, statusMessage)) self.logger.debug("handleStatusChangeRequest(user=%s, status=%d, statusMessage=%s)" % (user, status, statusMessage))
self.sessions[user].changeStatusMessage(statusMessage) self.sessions[user].changeStatusMessage(statusMessage)
self.sessions[user].changeStatus(status) self.sessions[user].changeStatus(status)
def handleBuddies(self, buddies): def handleBuddies(self, buddies):
"""Called when user logs in. Used to initialize roster.""" """Called when user logs in. Used to initialize roster."""
self.logger.debug("handleBuddies(buddies=%s)" % buddies) self.logger.debug("handleBuddies(buddies=%s)" % buddies)
buddies = [b for b in buddies.buddy] buddies = [b for b in buddies.buddy]
if len(buddies) > 0: if len(buddies) > 0:
user = buddies[0].userName user = buddies[0].userName
self.sessions[user].loadBuddies(buddies) self.sessions[user].loadBuddies(buddies)
def handleBuddyUpdatedRequest(self, user, buddy, nick, groups): def handleBuddyUpdatedRequest(self, user, buddy, nick, groups):
self.logger.debug("handleBuddyUpdatedRequest(user=%s, buddy=%s, nick=%s, groups=%s)" % (user, buddy, nick, groups)) self.logger.debug("handleBuddyUpdatedRequest(user=%s, buddy=%s, nick=%s, groups=%s)" % (user, buddy, nick, groups))
self.sessions[user].updateBuddy(buddy, nick, groups) self.sessions[user].updateBuddy(buddy, nick, groups)
def handleBuddyRemovedRequest(self, user, buddy, groups): def handleBuddyRemovedRequest(self, user, buddy, groups):
self.logger.debug("handleBuddyRemovedRequest(user=%s, buddy=%s, groups=%s)" % (user, buddy, groups)) self.logger.debug("handleBuddyRemovedRequest(user=%s, buddy=%s, groups=%s)" % (user, buddy, groups))
self.sessions[user].removeBuddy(buddy) self.sessions[user].removeBuddy(buddy)
def handleTypingRequest(self, user, buddy): def handleTypingRequest(self, user, buddy):
self.logger.debug("handleTypingRequest(user=%s, buddy=%s)" % (user, buddy)) self.logger.debug("handleTypingRequest(user=%s, buddy=%s)" % (user, buddy))
self.sessions[user].sendTypingStarted(buddy) self.sessions[user].sendTypingStarted(buddy)
def handleTypedRequest(self, user, buddy): def handleTypedRequest(self, user, buddy):
self.logger.debug("handleTypedRequest(user=%s, buddy=%s)" % (user, buddy)) self.logger.debug("handleTypedRequest(user=%s, buddy=%s)" % (user, buddy))
self.sessions[user].sendTypingStopped(buddy) self.sessions[user].sendTypingStopped(buddy)
def handleStoppedTypingRequest(self, user, buddy): def handleStoppedTypingRequest(self, user, buddy):
self.logger.debug("handleStoppedTypingRequest(user=%s, buddy=%s)" % (user, buddy)) self.logger.debug("handleStoppedTypingRequest(user=%s, buddy=%s)" % (user, buddy))
self.sessions[user].sendTypingStopped(buddy) self.sessions[user].sendTypingStopped(buddy)
def handleVCardRequest(self, user, buddy, ID): def handleVCardRequest(self, user, buddy, ID):
self.logger.debug("handleVCardRequest(user=%s, buddy=%s, ID=%s)" % (user, buddy, ID)) self.logger.debug("handleVCardRequest(user=%s, buddy=%s, ID=%s)" % (user, buddy, ID))
self.sessions[user].requestVCard(buddy, ID) self.sessions[user].requestVCard(buddy, ID)
def handleVCardUpdatedRequest(self, user, photo, nickname): def handleVCardUpdatedRequest(self, user, photo, nickname):
self.logger.debug("handleVCardUpdatedRequest(user=%s, nickname=%s)" % (user, nickname)) self.logger.debug("handleVCardUpdatedRequest(user=%s, nickname=%s)" % (user, nickname))
self.sessions[user].setProfilePicture(photo) self.sessions[user].setProfilePicture(photo)
def handleBuddyBlockToggled(self, user, buddy, blocked): def handleBuddyBlockToggled(self, user, buddy, blocked):
self.logger.debug("handleBuddyBlockedToggled(user=%s, buddy=%s, blocked=%s)" % (user, buddy, blocked)) self.logger.debug("handleBuddyBlockedToggled(user=%s, buddy=%s, blocked=%s)" % (user, buddy, blocked))
def relogin(self, user, legacyName, password, extra): def relogin(self, user, legacyName, password, extra):
""" """
Used to re-initialize the session object. Used when finished with Used to re-initialize the session object. Used when finished with
registration session and the user needs to login properly registration session and the user needs to login properly
""" """
self.logger.debug("relogin(user=%s, legacyName=%s)" % (user, legacyName)) self.logger.debug("relogin(user=%s, legacyName=%s)" % (user, legacyName))
# Change password in spectrum database # Change password in spectrum database
self.handleQuery('register %s %s %s' % (user, legacyName, password)) self.handleQuery('register %s %s %s' % (user, legacyName, password))
# Key word means we should register a new password # Key word means we should register a new password
if password == 'register': # This shouldn't happen, but just in case if password == 'register': # This shouldn't happen, but just in case
self.sessions[user] = RegisterSession(self, user, legacyName, extra) self.sessions[user] = RegisterSession(self, user, legacyName, extra)
else: else:
self.sessions[user] = Session(self, user, legacyName, extra) self.sessions[user] = Session(self, user, legacyName, extra)
self.sessions[user].login(password) self.sessions[user].login(password)
# TODO # TODO
def handleAttentionRequest(self, user, buddy, message): def handleAttentionRequest(self, user, buddy, message):
pass pass
def handleFTStartRequest(self, user, buddy, fileName, size, ftID): def handleFTStartRequest(self, user, buddy, fileName, size, ftID):
self.logger.debug('File send request %s, for user %s, from %s, size: %s' % self.logger.debug('File send request %s, for user %s, from %s, size: %s' %
(fileName, user, buddy, size)) (fileName, user, buddy, size))
def handleFTFinishRequest(self, user, buddy, fileName, size, ftID): def handleFTFinishRequest(self, user, buddy, fileName, size, ftID):
pass pass
def handleFTPauseRequest(self, ftID): def handleFTPauseRequest(self, ftID):
pass pass
def handleFTContinueRequest(self, ftID): def handleFTContinueRequest(self, ftID):
pass pass
def handleRawXmlRequest(self, xml): def handleRawXmlRequest(self, xml):
pass pass
def handleMessageAckRequest(self, user, legacyName, ID = 0): def handleMessageAckRequest(self, user, legacyName, ID = 0):
self.logger.info("Meassage ACK request for %s !!" % legacyName) self.logger.info("Meassage ACK request for %s !!" % legacyName)
def sendData(self, data): def sendData(self, data):
self.io.sendData(data) self.io.sendData(data)

File diff suppressed because it is too large Load Diff