def run(self): '''main method of the thread, make the request and handle the response ''' dbg('running request ' + self.request.action, 'req', 1) response = self.make_request(self.request) self.handle_response(self.request, response) dbg('request finished', 'req', 1)
def invite(self, account): '''invite a contact to the conversation''' if self.status != Conversation.STATUS_ESTABLISHED: self.pending_invites.append(account) else: dbg('sending CAL ' + account, 'conv', 3) self.socket.send_command('CAL', (account,))
def add_contact_by_group(self, accounts, groups): '''add all the contacts, all the groups and the relations, also mark as disabled the accounts and groups that were removed and remove the accounts from groups of relations that were removed''' self.add_contacts(accounts) self.add_groups(groups) for (cid, account) in accounts.iteritems(): local_account = self.accounts.get(account.account, None) if local_account is None: dbg(account.account + ' not found in self.accounts', 'logger', 1) continue existing = set(local_account.groups) to_include = set(account.groups) new_groups = to_include.difference(existing) removed = existing.difference(to_include) for gid in new_groups: local_group = self.groups[gid] if gid not in local_account.groups: self.insert_account_by_group(local_account.id_account, local_group.id) for gid in removed: local_group = self.groups[gid] local_account.groups.remove(gid) self.delete_account_by_group(local_account.id_account, local_group.id)
def __init__(self, session, msg_queue, contact, message, lockkey='', seq=1, first=True): '''command_queue is a reference to a queue that is used by the worker to get commands that other threads need to send''' me = session.contacts.me passport_id = session.extras['messengersecure.live.com']['security'] nick = '=?%s?%s?=%s?=' % ( 'utf-8','B', me.display_name.encode('base64').strip()) run_id = str(uuid4()) content = message.encode('base64').strip() send_xml = XmlManager.get('sendoim', me.account, nick, common.MSNP_VER, common.BUILD_VER, contact, passport_id, challenge._PRODUCT_ID, str(lockkey), str(seq), run_id, str(seq), content) send_xml = send_xml.replace('\\r\\n', '\r\n') Requester.__init__(self, session, 'http://messenger.live.com/ws/2006/09/oim/Store2', 'ows.messenger.msn.com',443,'/OimWS/oim.asmx', send_xml.strip()) self.contact = contact self.message = message self.oid = '' self.seq = seq self.first = first self.msg_queue = msg_queue dbg('FROM:%s TO:%s' % (me.display_name, contact), 'req', 1)
def _close(self): '''set all the attributes to reflect a closed conversation caution: it doesn't stop the main thread''' dbg('closing conversation', 'conv', 1) self.status = Conversation.STATUS_CLOSED self.started = False self.socket.quit()
def load(self, path, clear=False, section='DEFAULT'): '''load the config file from path, clear old values if clear is set to True''' parser = ConfigParser.SafeConfigParser() parser.read(path) if clear: self.__dict__ = {} for (name, value) in parser.items(section): try: if name.startswith('b_'): value = bool(int(value)) elif name.startswith('i_'): value = int(value) elif name.startswith('f_'): value = float(value) elif name.startswith('d_'): value = Config.string_to_dict(value) elif name.startswith('l_'): value = Config.string_to_list(value) else: value = value.replace('ยง', '%') setattr(self, name, value) except ValueError: dbg('invalid config value ' + name + ' ' + value, 'config', 1)
def save_logs_as_txt(results, path): '''save the chats in results (from get_chats or get_chats_between) as txt to path ''' handle = file(path, 'w') for (stat, timestamp, message, nick) in results: date_text = time.strftime('[%c]', time.gmtime(timestamp)) tokens = message.split('\r\n', 3) type_ = tokens[0] if type_ == 'text/x-msnmsgr-datacast': handle.write(date_text + ' ' + nick + ': ' + '<<nudge>>\n') elif type_.find('text/plain;') != -1: try: (type_, format, empty, text) = tokens handle.write("%s %s: %s\n" % \ (date_text, nick, text)) except ValueError: dbg('Invalid number of tokens' + str(tokens), 'contactinfo', 1) else: dbg('unknown message type on ContactInfo', 'contactinfo', 1) handle.close()
def run(self): '''main method''' data = None self.logger = Logger(self.path) self.actions['get_event'] = self.logger.get_event self.actions['get_nicks'] = self.logger.get_nicks self.actions['get_messages'] = self.logger.get_messages self.actions['get_status'] = self.logger.get_status self.actions['get_images'] = self.logger.get_images self.actions['get_sent_messages'] = self.logger.get_sent_messages self.actions['get_chats'] = self.logger.get_chats self.actions['get_chats_between'] = self.logger.get_chats_between self.actions['add_groups'] = self.logger.add_groups self.actions['add_contacts'] = self.logger.add_contacts self.actions['add_contact_by_group'] = self.logger.add_contact_by_group while True: try: data = self.input.get(True) quit = self._process(data) if quit: self.logger.close() dbg('closing logger thread', 'logger', 1) break except Queue.Empty: pass
def _handle_action_conv_invite(self, cid, account): '''handle e3.Action.ACTION_CONV_INVITE ''' if cid in self.conversations: self.conversations[cid].invite(account) else: dbg('conversation ' + cid + ' not found', 'worker', 4)
def _handle_action_close_conversation(self, cid): '''handle e3.Action.ACTION_CLOSE_CONVERSATION ''' if cid in self.conversations: self.conversations[cid].command_queue.put('quit') del self.conversations[cid] else: dbg('conversation ' + cid + ' not found', 'worker', 4)
def _on_contact_joined(self, cid, account): '''called when a contact join the conversation''' conversation = self.conversations.get(float(cid), None) if conversation: conversation.on_contact_joined(account) else: dbg('on_contact_joined: conversation is None', 'convmanager', 1)
def _process(self, message): '''process the data''' dbg('<<< ' + str(message), 'worker', 2) if self.in_login: self._process_login(message) else: self._process_normal(message)
def _receive(self): """receive data from the socket""" data = self._readline() # if we got something add it to the output queue if data: dbg("<<< " + data, "sock", 3) self.output.put(data) return True return False
def _process(self, message): '''process a command and call the respective handler''' dbg('<c< ' + str(message), 'conv', 2) handler = self._handlers.get(message.command, None) if handler: handler(message) else: self._on_unknown_command(message)
def do_passport_identification(self): '''do the passport identification and get our passport id''' hash_ = self.session.extras['hash'].split()[-1] template = XmlManager.get('passport', self.session.account.account, self.session.account.password) if '@msn.com' not in self.session.account.account: server = "login.live.com" url = "/RST.srf" else: server = "msnia.login.live.com" url = "/pp550/RST.srf" #create the headers headers = { \ 'Accept' : 'text/*', 'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', 'Host' : server, 'Content-Length' : str(len(template)), 'Connection' : 'Keep-Alive', 'Cache-Control' : 'no-cache' } succeeded = False for i in range(5): response = None # send the SOAP request for i in range(3): try: conn = httplib.HTTPSConnection(server, 443) conn.request('POST', url, template, headers) response = conn.getresponse() break except Exception, exception: pass if response: data = response.read() dbg(data, 'worker', 3) else: self.session.add_event(e3.Event.EVENT_LOGIN_FAILED, 'Can\'t connect to HTTPS server: ' + str(exception)) self._on_login_failed() if data.find('<faultcode>psf:Redirect</faultcode>') > 0: url = urlparse.urlparse(data.split('<psf:redirectUrl>')\ [1].split('</psf:redirectUrl>')[0]) server = url[1] url = url[2] else: succeeded = True break
def rename_group_cb(response, group, new_name): '''callback called by rename_group''' if response == gui.stock.ACCEPT: if group.name == new_name: dbg("old and new name are the same", 'handler', 1) elif new_name: self.session.rename_group(group.identifier, new_name) else: dbg("new name not valid", 'handler', 1)
def set_default_by_id(self, id_): '''set the default extension through its id (generated by _get_class_name method), if the id is not available it will raise ValueError''' if id_ not in self.classes: dbg('extension id %s not registered on %s' % (id_, self.name,), 'extension') else: self.default = self.classes[id_]
def handle_response(self, request, response): '''handle the response''' if response.status == 200: if self.gid in self.session.groups: del self.session.groups[self.gid] self.session.add_event(e3.Event.EVENT_GROUP_REMOVE_SUCCEED, self.gid) else: dbg(response.body + '\n' + request.body, 'req', 4) self.session.add_event(e3.Event.EVENT_GROUP_REMOVE_FAILED, self.gid)
def handle_response(self, request, response): '''handle the response''' if response.status == 200: self.session.contacts.contacts[self.account].alias = self.alias self.session.add_event(e3.Event.EVENT_CONTACT_ALIAS_SUCCEED, self.account) else: dbg(response.body + '\n' + request.body, 'req', 4) self.session.add_event(e3.Event.EVENT_CONTACT_ALIAS_FAILED, self.account)
def oims_notify(self): if self.waiting_requests == len(self.requested): self.requested.sort(key=lambda oim:oim.date) for oim in self.requested: dbg('[OIM] ' + oim.nick + ' ' + oim.mail + ' ' + str(oim.date) + \ ' ' + oim.message, 'oim', 1) #self.put(Manager.ACTION_OIM_DELETE, oim.id) self.session.add_event(Event.EVENT_OIM_RECEIVED, oim) self.waiting_requests = 0 self.requested = []
def set_message_cb(response, old_pm, new_pm): '''callback for the set_message method''' if response == gui.stock.ACCEPT: if old_pm == new_pm: dbg('old and new personal messages are the same', 'handler', 1) return self.session.set_message(new_pm)
def handle_response(self, request, response): '''handle the response''' if response.status == 200: self.session.groups[self.gid] = e3.Group(self.name, self.gid) self.session.add_event(e3.Event.EVENT_GROUP_RENAME_SUCCEED, self.gid, self.name) else: dbg(response.body + '\n' + request.body, 'req', 4) self.session.add_event(e3.Event.EVENT_GROUP_RENAME_FAILED, self.gid, self.name)
def handle_response(self, request, response): '''handle the response''' if response.status == 200: if self.account in self.session.contacts.pending: del self.session.contacts.pending[self.account] self.session.add_event(e3.Event.EVENT_CONTACT_REJECT_SUCCEED, self.account) else: dbg(response.body + '\n' + request.body, 'req', 4) self.session.add_event(e3.Event.EVENT_CONTACT_REJECT_FAILED, self.account)
def handle_response(self, request, response): '''handle the response''' if response.status == 200: gid = common.get_value_between(response.body, '<guid>', '</guid>') self.session.groups[gid] = e3.Group(self.name, gid) self.session.add_event(e3.Event.EVENT_GROUP_ADD_SUCCEED, self.name, gid) else: dbg(response.body + '\n' + request.body, 'req', 4) self.session.add_event(e3.Event.EVENT_GROUP_ADD_FAILED, self.name)
def _stat(self): '''called internally each time a transaction is made, here we control how often a commit is made''' if self._count >= Logger.COMMIT_LIMIT: t1 = time.time() self.connection.commit() dbg('commit ' + str(time.time() - t1), 'logger', 4) self._count = 0 self._count += 1
def _on_row_activated(self, treeview, path, view_column): '''callback called when the user selects a row''' group = self.get_group_selected() contact = self.get_contact_selected() if group: self.group_selected.emit(group) elif contact: self.contact_selected.emit(contact) else: dbg('nothing selected?', 'contactlist', 1)
def _on_message_send_failed(self, cid, message): '''called when a message is received''' conversation = self.conversations.get(float(cid), None) if conversation is not None: error = conversation.formatter.format_error( 'message couldn\'t be sent: ') conversation.output.append(error) conversation.output.append( self.format_from_message(message)) else: dbg('conversation ' + cid + ' not found', 'convmanager', 1)
def handle_response(self, request, response): '''handle the response''' if response.status == 200: self.session.contacts.contacts[self.account].groups.append(self.gid) self.session.groups[self.gid].contacts.append(self.account) self.session.add_event(e3.Event.EVENT_GROUP_ADD_CONTACT_SUCCEED, self.gid, self.cid) else: dbg(response.body + '\n' + request.body, 'req', 4) self.session.add_event(e3.Event.EVENT_GROUP_ADD_CONTACT_FAILED, self.gid, self.cid)
def set_alias_cb(response, account, old_alias, new_alias): '''callback for the set_alias method, the parameters and the values are described on that method''' if response == gui.stock.ACCEPT: if old_alias == new_alias: dbg('old alias and new alias are the same', 'handler', 1) return self.session.set_alias(account, new_alias) elif response == gui.stock.CLEAR: self.session.set_alias(account, '')
def set_nick_cb(response, old_nick, new_nick): '''callback for the set_nick method''' if response == gui.stock.ACCEPT: if old_nick == new_nick: dbg('old nick and new nick are the same', 'handler', 1) return elif new_nick == '': dbg('empty new nick', 'handler', 1) return self.session.set_nick(new_nick)