def _consume_message(self, res_obj, sock): assert (sock is not None) attr = res_obj.headers.get_field_value from_uri = attr("F") logger.info("Get message from: %s" % from_uri) msg = rm_markups(to_unicode_obj(res_obj.body)) if from_uri != SERVICE_PROVIDER_URI: i_send_ack(res_obj, sock) contact = self.user.group_agent.get_contact_by_uri(from_uri) if not contact: """ This message send you before him delete you from his buddy list. """ name = u"陌生人 (飞信号: %s) " % get_sid_from_uri(from_uri) else: name = contact.get_display_name() else: name = to_unicode_obj("系统信息") self.goto_or_create_tab_after_received_msg(from_uri) chat_history_model = self.chat_history[from_uri] self.chat_win.append_to_chat_history(chat_history_model, name, msg, OTHER_LOG_TPL)
def sipc_auth_t_finished(self): kill_qthread(self.sipc_auth_t_killer) res_obj = self.sipc_auth_t.get_return() code = res_obj.code if code == SIPResponse.OK: self._retry_times = 0 i_update_user_after_sipc_auth_success(self.user, res_obj) self.show_contact_list_win() return elif code == SIPResponse.EXTENSION_REQUIRED: # login location changed self.verification = i_generate_verification_pic(self.user, res_obj) body = "%s<br />%s" % (self.verification.text, self.verification.tips) (btn_val, chars) = GetVerificationDialog.get_input(body = body, path = self.verification.picture_path) if btn_val: logger.info("(SIPC auth) Input recognise chars: %s" % chars) self.verification.chars = chars self.sipc_auth_t_run() else: self.verification = None self.user = None self.show_or_hide_login_widgets(show = True) return self.show_or_hide_login_widgets(show = True) popup_error(self, "SIPC authentication response code: %d" % code)
def sipc_auth_t_finished(self): kill_qthread(self.sipc_auth_t_killer) res_obj = self.sipc_auth_t.get_return() code = res_obj.code if code == SIPResponse.OK: self._retry_times = 0 i_update_user_after_sipc_auth_success(self.user, res_obj) self.show_contact_list_win() return elif code == SIPResponse.EXTENSION_REQUIRED: # login location changed self.verification = i_generate_verification_pic(self.user, res_obj) body = "%s<br />%s" % (self.verification.text, self.verification.tips) (btn_val, chars) = GetVerificationDialog.get_input( body=body, path=self.verification.picture_path) if btn_val: logger.info("(SIPC auth) Input recognise chars: %s" % chars) self.verification.chars = chars self.sipc_auth_t_run() else: self.verification = None self.user = None self.show_or_hide_login_widgets(show=True) return self.show_or_hide_login_widgets(show=True) popup_error(self, "SIPC authentication response code: %d" % code)
def load_sys_config_from_local_json(user): if user.sid: sys_config = get_data_from_local_json(user.sid, "sys_config.json") if sys_config: logger.info("local sys_config.json found") config = user.get_config() map_dict_to_obj(sys_config, config)
def _parse_custom_config_node(user, body_dom): custom_config_node = body_dom.getElementsByTagName("custom-config")[0] custom_config_version = custom_config_node.getAttribute("version") if user.custom_config_version == custom_config_version: logger.info("custom_config_version matched, skip update") return custon_config = custom_config_node.childNodes[0].data data = {"data" : custon_config, "sid" : user.sid} save_data_to_local_json(data, "custom_config.json")
def load_user_data_from_local_json(account_no, user): account = get_account_basic_info_by_account_no(account_no) if not account: logger.error("local personal config not found") return # there is basic account data, it is not the first time sign in sid = account["sid"] user_info_versions = get_data_from_local_json(sid, "user_info_versions.json") if user_info_versions: logger.info("local user_info_versions.json found") user.version = user_info_versions["version"] user.custom_config_version = user_info_versions[ "custom_config_version"] user.contact_list_version = user_info_versions["contact_list_version"] else: #delete_config_from_local_json(sid, "user_info_versions.json") return user.set_user_path(sid) user.set_portrait_save_path() # get from SIPC auth response body, results -> user-info -> personal node personal_node = get_data_from_local_json(sid, "personal_node.json") if personal_node: update_personal_node_from_local_config(user, personal_node) # update_personal_node_from_local_config(user, personal_config) custom_config = get_data_from_local_json(sid, "custom_config_node.json") if custom_config: user.custom_config_version = custom_config["data"] # results -> user-info > buddy-list node group_data = get_data_from_local_json(sid, "group_list_node.json") group_agent = GroupAgent() if group_data: groups_d = group_data["groups"] for gid, gname in groups_d.iteritems(): group = Group(gid, gname) #group = Group(int(gid), gname) group_agent.add_group(group) for gid, gname in groups_d.iteritems(): cat_datas = get_data_from_local_json(sid, "%s_list.json" % gname) cats_d = cat_datas["contacts"] for cat_d in cats_d.values(): cat = Contact(user) map_dict_to_obj(cat_d, cat) group_agent.add_contact(cat) user.group_agent = group_agent
def i_download_portrait_by_uri(user, uri, debug=False): params = { "Uri": uri, "Size": 120, "c": user.get_ssi_cookie(), } config = user.get_config() parses = urlparse.urlparse(config.get_uri) root_path = [i for i in parses.path.split('/') if i][0] path = "/%s/getportrait.aspx" % root_path query = urllib.urlencode(params) url = "%s?%s" % (path, query) headers = { "Accept": config.portrait_file_type, } httplib.HTTPConnection.response_class = HTTPResponse conn = httplib.HTTPConnection(parses.netloc) # if debug: # debuglevel = 1 # else: # debuglevel = 0 # conn.set_debuglevel(debuglevel) conn.request("GET", url, headers=headers) res_obj = conn.getresponse() conn.close() if debug: logger.info("request") print "url", url from pprint import pprint as pp print "headers:", pp(headers) if debug: logger.info("response") print "code:", res_obj.code print "msg:", res_obj.msg if res_obj.code == httplib.OK: sid = get_sid_from_uri(uri) ct = res_obj.headers.get_field_value('Content-Type') format_suffix = ct.split('/')[-1].lower() #format_suffix = "jpg" portrait_save_path = os.path.join(user.get_portrait_save_path(), "%s.%s" % (sid, format_suffix)) with open(portrait_save_path, "wb") as f: f.write(res_obj.body) return res_obj
def i_download_portrait_by_uri(user, uri, debug = False): params = { "Uri" : uri, "Size" : 120, "c" : user.get_ssi_cookie(), } config = user.get_config() parses = urlparse.urlparse(config.get_uri) root_path = [i for i in parses.path.split('/') if i][0] path = "/%s/getportrait.aspx" % root_path query = urllib.urlencode(params) url = "%s?%s" % (path, query) headers = { "Accept" : config.portrait_file_type, } httplib.HTTPConnection.response_class = HTTPResponse conn = httplib.HTTPConnection(parses.netloc) # if debug: # debuglevel = 1 # else: # debuglevel = 0 # conn.set_debuglevel(debuglevel) conn.request("GET", url, headers = headers) res_obj = conn.getresponse() conn.close() if debug: logger.info("request") print "url", url from pprint import pprint as pp print "headers:", pp(headers) if debug: logger.info("response") print "code:", res_obj.code print "msg:", res_obj.msg if res_obj.code == httplib.OK: sid = get_sid_from_uri(uri) ct = res_obj.headers.get_field_value('Content-Type') format_suffix = ct.split('/')[-1].lower() #format_suffix = "jpg" portrait_save_path = os.path.join(user.get_portrait_save_path(), "%s.%s" % (sid, format_suffix)) with open(portrait_save_path, "wb") as f: f.write(res_obj.body) return res_obj
def load_user_data_from_local_json(account_no, user): account = get_account_basic_info_by_account_no(account_no) if not account: logger.error("local personal config not found") return # there is basic account data, it is not the first time sign in sid = account["sid"] user_info_versions = get_data_from_local_json(sid, "user_info_versions.json") if user_info_versions: logger.info("local user_info_versions.json found") user.version = user_info_versions["version"] user.custom_config_version = user_info_versions["custom_config_version"] user.contact_list_version = user_info_versions["contact_list_version"] else: #delete_config_from_local_json(sid, "user_info_versions.json") return user.set_user_path(sid) user.set_portrait_save_path() # get from SIPC auth response body, results -> user-info -> personal node personal_node = get_data_from_local_json(sid, "personal_node.json") if personal_node: update_personal_node_from_local_config(user, personal_node) # update_personal_node_from_local_config(user, personal_config) custom_config = get_data_from_local_json(sid, "custom_config_node.json") if custom_config: user.custom_config_version = custom_config["data"] # results -> user-info > buddy-list node group_data = get_data_from_local_json(sid, "group_list_node.json") group_agent = GroupAgent() if group_data: groups_d = group_data["groups"] for gid, gname in groups_d.iteritems(): group = Group(gid, gname) #group = Group(int(gid), gname) group_agent.add_group(group) for gid, gname in groups_d.iteritems(): cat_datas = get_data_from_local_json(sid, "%s_list.json" % gname) cats_d = cat_datas["contacts"] for cat_d in cats_d.values(): cat = Contact(user) map_dict_to_obj(cat_d, cat) group_agent.add_contact(cat) user.group_agent = group_agent
def _parse_personal_node(user, body_dom): # results -> user-info -> personal personal_node = body_dom.getElementsByTagName("personal")[0] pn_attr = personal_node.getAttribute version = pn_attr("version") if user.version == version: logger.info("version matched, skip update") return map_node_attr_to_obj(personal_node, user) data = xml_node_attributes2dict(personal_node) data["sid"] = user.sid save_data_to_local_json(data, "personal_node.json")
def _consume_noti_sync_user_info_v4(self, res_obj): body_dom = minidom.parseString(res_obj.body) contact_list_nodes = body_dom.getElementsByTagName("contact-list") if not contact_list_nodes: return assert len(contact_list_nodes) == 1 contact_list_node = contact_list_nodes[0] contact_list_version = contact_list_node.getAttribute("version") if self.user.contact_list_version != contact_list_version: self.user.contact_list_version = contact_list_version buddy_nodes = body_dom.getElementsByTagName("buddy") for buddy_node in buddy_nodes: attr = buddy_node.getAttribute user_id = attr("user-id") contact = self.user.group_agent.get_contact_by_user_id(user_id) # someone send add buddy application to you, # and you send buddy application before any reply, # contact will be not found in self.user.contact_list. if not contact: continue if attr("action") == "remove": logger.error("!!! Your buddy (uri: %s) %s you" % (contact.uri, attr("action"))) convs = self.user.conversations() conv = convs.get(contact.uri, None) if conv: assert conv.sock != self.user.get_sock() conv.over() del conv self.user.group_agent.remove_user_by_user_id(user_id) elif attr("action") == "add": logger.info("!!! Your buddy (uri: %s) %s you" % (contact.uri, attr("action"))) cat = Contact(user=self.blah.user) map_node_attr_to_obj(buddy_node, cat) self.user.contact_list.append(cat) cat.buddy_lists = attr("buddy-lists") cat.online_notify = attr("online-notify") cat.permission_values = attr("permission-values")
def send_msg_t_finished(self): logger.info("in send_msg_t_finished") convs_d = dict() convs = self.user.get_conversations() for to_uri, conv in convs.iteritems(): if conv.send_msg_thread and conv.send_msg_thread.isFinished(): conv.send_msg_thread = None CONTACT_IS_ONLINE = conv.sock and (conv.sock is not self.user.get_sock()) if CONTACT_IS_ONLINE and not conv.listen_thread: self.blah.contact_list_win.add_listener_for_conversation_sock(conv) convs_d[to_uri] = conv else: convs_d[to_uri] = conv self.user.set_conversations(convs_d)
def _parse_contact_list_node(user, body_dom): """ Should it add myself to contact_list: user.contact_list.append(user.to_contact()). """ contact_list_node = body_dom.getElementsByTagName("contact-list")[0] contact_list_version = contact_list_node.getAttribute("version") if user.contact_list_version == contact_list_version: logger.info("contact_list_version matched, skip update") return # Notice: in libblah, `buddy_lists` means `buddy group lists` user.group_agent = _parse_buddy_lists_node(contact_list_node) _parse_buddies_node(user, contact_list_node) _parse_chat_friends_node(user, contact_list_node) _parse_blacklist_node(user, contact_list_node) save_contact_list_to_local(user)
def _consume_noti_sync_user_info_v4(self, res_obj): body_dom = minidom.parseString(res_obj.body) contact_list_nodes = body_dom.getElementsByTagName("contact-list") if not contact_list_nodes: return assert len(contact_list_nodes) == 1 contact_list_node = contact_list_nodes[0] contact_list_version = contact_list_node.getAttribute("version") if self.user.contact_list_version != contact_list_version: self.user.contact_list_version = contact_list_version buddy_nodes = body_dom.getElementsByTagName("buddy") for buddy_node in buddy_nodes: attr = buddy_node.getAttribute user_id = attr("user-id") contact = self.user.group_agent.get_contact_by_user_id(user_id) # someone send add buddy application to you, # and you send buddy application before any reply, # contact will be not found in self.user.contact_list. if not contact: continue if attr("action") == "remove": logger.error("!!! Your buddy (uri: %s) %s you" % (contact.uri, attr("action"))) convs = self.user.conversations() conv = convs.get(contact.uri, None) if conv: assert conv.sock != self.user.get_sock() conv.over() del conv self.user.group_agent.remove_user_by_user_id(user_id) elif attr("action") == "add": logger.info("!!! Your buddy (uri: %s) %s you" % (contact.uri, attr("action"))) cat = Contact(user = self.blah.user) map_node_attr_to_obj(buddy_node, cat) self.user.contact_list.append(cat) cat.buddy_lists = attr("buddy-lists") cat.online_notify = attr("online-notify") cat.permission_values = attr("permission-values")
def ssi_auth_t_finished(self): # why not necessary to call disconnect(SIGNAL) here # http://doc.qt.nokia.com/4.7/qobject.html#disconnect-3 kill_qthread(self.ssi_auth_t_killer) res_obj = self.ssi_auth_t.get_return() code = res_obj.code if code == httplib.OK: i_update_user_after_ssi_auth_success(self.user, res_obj, self.get_if_remember_passwd()) self._retry_times = 0 self.download_sys_config_t_run() elif code == HTTPResponse.PASSWD_ERROR: self.user = None self.show_or_hide_login_widgets(show=True) popup_error(self, u"密码错误") elif code in (HTTPResponse.CCPS_CHECK_ERROR, HTTPResponse.NEED_VERIFY): self.verification = i_generate_verification_pic(self.user, res_obj) body = "%s<br />%s" % (self.verification.text, self.verification.tips) (btn_val, chars) = GetVerificationDialog.get_input( body=body, path=self.verification.picture_path) if btn_val: logger.info("(SSI auth)Input recognise chars: %s" % chars) self.verification.chars = chars self.ssi_auth_t_run() else: self.verification = None self.user = None self.show_or_hide_login_widgets(show=True) else: raise Exception("SSI authentication response code: %d" % code)
def ssi_auth_t_finished(self): # why not necessary to call disconnect(SIGNAL) here # http://doc.qt.nokia.com/4.7/qobject.html#disconnect-3 kill_qthread(self.ssi_auth_t_killer) res_obj = self.ssi_auth_t.get_return() code = res_obj.code if code == httplib.OK: i_update_user_after_ssi_auth_success(self.user, res_obj, self.get_if_remember_passwd()) self._retry_times = 0 self.download_sys_config_t_run() elif code == HTTPResponse.PASSWD_ERROR: self.user = None self.show_or_hide_login_widgets(show = True) popup_error(self, u"密码错误") elif code in (HTTPResponse.CCPS_CHECK_ERROR, HTTPResponse.NEED_VERIFY): self.verification = i_generate_verification_pic(self.user, res_obj) body = "%s<br />%s" % (self.verification.text, self.verification.tips) (btn_val, chars) = GetVerificationDialog.get_input(body = body, path = self.verification.picture_path) if btn_val: logger.info("(SSI auth)Input recognise chars: %s" % chars) self.verification.chars = chars self.ssi_auth_t_run() else: self.verification = None self.user = None self.show_or_hide_login_widgets(show = True) else: raise Exception("SSI authentication response code: %d" % code)
def check_runtime(): pl = get_platform() logger.info('Platform: %s' % pl) logger.info("Python Version: %s" % get_python_version()) logger.info("Qt4 Version: %s" % get_qt_version()) # required Mac or Linux if pl not in ("Darwin", "Linux"): logger.error("Blah only supports Mac OS X and Linux") sys.exit(-1) # required >= Python-2.6 ver = sys.version_info[1] if ver < 6: logger.error("Blah requires >=Python-2.6, found %s" % get_python_version()) sys.exit(-1) qt_vers = [int(i) for i in get_qt_version().split('.')] # required >= Qt-4.6 if qt_vers[1] < 6: logger.error("Blah requires >=Qt-4.6, found %s" % get_qt_version()) sys.exit(-1)
def get_sock_for_send_msg(user, to_uri, debug = False): """ Parse (ip, port) get by start_chat request, create a new socket object to register and invite buddy to start a online conversation. """ conversations = user.get_conversations() conv = conversations[to_uri] while not conv.start_chat_response: time.sleep(0.1) res_obj = conv.start_chat_response auth_val = res_obj.headers.get_field_value("A") ip, port, credential = _get_ip_port_credential_from_auth_field(auth_val) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conv.sock = sock sock.connect((ip, port)) call_id = conv.call_id sip_type = SIP(SIP.REGISTER) sid = user.sid headers = { "F" : sid, "I" : call_id, "Q" : "%d %s" % (DEFAULT_SIP_SEQUENCE, str(sip_type)), "K" : ["text/html-fragment", "multiparty", "nudge"], "A" : 'TICKS auth="%s"' % credential, } conn = SIPConnection(sock, sip_type = sip_type, headers = headers) conn.send(debug = debug) # invite_buddy_to_start_chat(user, call_id, to_uri, debug) sip_type = SIP(SIP.SERVICE) sip_event = SIPEvent(SIPEvent.INVITE_BUDDY) headers = { "F" : sid, "I" : call_id, "Q" : "%d %s" % (DEFAULT_SIP_SEQUENCE, str(sip_type)), "N" : str(sip_event), } body = '<args><contacts><contact uri="%s" /></contacts></args>' % to_uri conn = SIPConnection(sock, sip_type = sip_type, headers = headers, body = body) res_obj = conn.send(debug = debug) if res_obj.code != SIPResponse.OK: sock.close() logger.error("get sock for cat failed") return None # recevie option response, we can do detect user if is offline or hide from response buf = SIPConnection.recv(sock, debug = debug) res_obj = SIPResponse(buf) logger.info("user is offline: %s" % str(detect_user_if_is_offline_from_invite_response(res_obj))) if detect_user_if_is_offline_from_invite_response(res_obj): sock.close() return None assert res_obj != None # recevie conversation response buf = SIPConnection.recv(sock, debug = debug) res_obj = SIPResponse(buf) assert res_obj != None return res_obj
def create_chat_history_model_if_not_exists(self, contact_uri): if contact_uri not in self.blah.contact_list_win.chat_history: logger.info("create chat history model for %s" % contact_uri) model = create_chat_history_model() self.blah.contact_list_win.chat_history[contact_uri] = model
def thread_running(self): logger.info('thread running ... ')