def auto_reload(mod): """ @brief reload modules @param mod: the need reload modules """ try: module = sys.modules[mod] except: Log.error(traceback.format_exc()) return False filename = module.__file__ # .pyc 修改时间不会变 # 所以就用 .py 的修改时间 if filename.endswith(".pyc"): filename = filename.replace(".pyc", ".py") mod_time = os.path.getmtime(filename) if not "loadtime" in module.__dict__: module.loadtime = 0 try: if mod_time > module.loadtime: reload(module) else: return False except: Log.error(traceback.format_exc()) return False module.loadtime = mod_time echo('[*] load \'%s\' successful.\n' % mod) return True
def send_file(self, user_id, file_path): """ @brief send file @param user_id String @param file_path String @return Bool: whether operation succeed """ title = file_path.split('/')[-1] data = { 'appid': Constant.API_WXAPPID, 'title': title, 'totallen': '', 'attachid': '', 'type': self.wx_conf['APPMSGTYPE_ATTACH'], 'fileext': title.split('.')[-1], } response = self.webwxuploadmedia(file_path) if response is not None: data['totallen'] = response['StartPos'] data['attachid'] = response['MediaId'] else: Log.error('File upload error') return self.webwxsendappmsg(user_id, data)
def post(url, params, jsonfmt=True): """ @brief http post request @param url String @param params Dict, post params @param jsonfmt Bool, whether is json format @return http response """ Log.debug('POST -> '+url) Log.debug(params) if jsonfmt: request = urllib2.Request(url=url, data=json.dumps(params, ensure_ascii=False).encode('utf8')) request.add_header(*Constant.HTTP_HEADER_CONTENTTYPE) else: request = urllib2.Request(url=url, data=urllib.urlencode(params)) while True: try: response = urllib2.urlopen(request, timeout=30) data = response.read() response.close() if jsonfmt: Log.debug(data) return json.loads(data, object_hook=_decode_data) return data except (KeyboardInterrupt, SystemExit): raise except: Log.error(traceback.format_exc()) time.sleep(1)
def get(url, api=None): """ @brief http get request @param url String @param api wechat api @return http response """ Log.debug('GET -> ' + url) request = urllib2.Request(url=url) request.add_header(*Constant.HTTP_HEADER_CONNECTION) request.add_header(*Constant.HTTP_HEADER_REFERER) if api in ['webwxgetvoice', 'webwxgetvideo']: request.add_header(*Constant.HTTP_HEADER_RANGE) while True: try: response = urllib2.urlopen(request, timeout=30) data = response.read() response.close() if api == None: Log.debug(data) return data except (KeyboardInterrupt, SystemExit): raise except: Log.error(traceback.format_exc()) time.sleep(1)
def post(url, params, jsonfmt=True): """ @brief http post request @param url String @param params Dict, post params @param jsonfmt Bool, whether is json format @return http response """ Log.debug('POST -> ' + url) Log.debug(params) if jsonfmt: request = urllib2.Request( url=url, data=json.dumps(params, ensure_ascii=False).encode('utf8')) request.add_header(*Constant.HTTP_HEADER_CONTENTTYPE) else: request = urllib2.Request(url=url, data=urllib.urlencode(params)) while True: try: response = urllib2.urlopen(request, timeout=30) data = response.read() response.close() if jsonfmt: Log.debug(data) return json.loads(data, object_hook=_decode_data) return data except (KeyboardInterrupt, SystemExit): raise except: Log.error(traceback.format_exc()) time.sleep(1)
def snapshot(self): """ @brief Save basic infos for next login. @return Bool: whether operation succeed. """ try: conf = { 'uuid': self.uuid, 'redirect_uri': self.redirect_uri, 'uin': self.uin, 'sid': self.sid, 'skey': self.skey, 'pass_ticket': self.pass_ticket, 'synckey': self.synckey, 'device_id': self.device_id, 'last_login': time.time(), } cm = ConfigManager() Log.debug('save wechat config') cm.set_wechat_config(conf) # save cookie Log.debug('save cookie') if self.cookie: self.cookie.save(ignore_discard=True) # save contacts Log.debug('save contacts') self.save_contacts() except Exception, e: Log.error(traceback.format_exc()) return False
def main(args): rospy.init_node('wechat', anonymous=True) signal.signal(signal.SIGINT, quit) signal.signal(signal.SIGTERM, quit) if cm.get('setting', 'server_mode') == 'True': serverProcess = threading.Thread(target=run_server) serverProcess.start() cmdProcess = threading.Thread(target=cmd_input) cmdProcess.setDaemon(True) cmdProcess.start() while not rospy.is_shutdown(): try: wechat.start() except KeyboardInterrupt: echo(Constant.LOG_MSG_QUIT) wechat.exit_code = 1 else: Log.error(traceback.format_exc()) finally: wechat.stop() # send a mail to tell the wxbot is failing subject = 'wxbot stop message' log_file = open(eval(cm.get('handler_fileHandler', 'args'))[0], 'r') mail_content = '<pre>' + str( wechat) + '\n\n-----\nLogs:\n-----\n\n' + ''.join( log_file.readlines()[-100:]) + '</pre>' sg.send_mail(subject, mail_content, 'text/html') log_file.close() if wechat.exit_code == 0: echo(Constant.MAIN_RESTART) else: # kill process os.system(Constant.LOG_MSG_KILL_PROCESS % os.getpid())
def upload_method(cron_id, vpn_ip, work_path, exchange, task_type): try: run_date = datetime.datetime.now().strftime("%Y%m%d") # remote check remote_check_flag = dir_check(vpn_ip, work_path) local_files = get_local_files(task_type, vpn_ip, work_path) print local_files # local check local_check_flag, size = loacal_files_check(local_files) if not local_files or not remote_check_flag or not local_check_flag: cron_trigger(cron_id, -1, size, run_date) return False his_cron_id = cron_trigger(cron_id, 0, size, run_date) if his_cron_id < 0: return False file_str = " ".join(local_files) cmd = "rsync -avz --progress %s %s@%s:%s" % (file_str, "mycapitaltrade", vpn_ip, work_path) print cmd tf_out = tempfile.NamedTemporaryFile() tf_out_r = open(tf_out.name, "r") proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=tf_out) while proc.poll() is None: multiple_listen_stdout(cron_id, his_cron_id, size, run_date, tf_out_r) time.sleep(0.5) else: multiple_listen_stdout(cron_id, his_cron_id, size, run_date, tf_out_r) tf_out_r.close() tf_out.close() return True except: Log.error("rsync log failed. %s" % traceback.format_exc()) return False
def get_config_strategy(file_content): ret_list = [] try: config_obj = xmltodict.parse(file_content) st_obj = config_obj["MyExchange"]["strategies"]["strategy"] if not isinstance(st_obj, list): st_obj = [st_obj] for st in st_obj: ret_list.append(st["@model_file"]) except Exception, ex: Log.error("xml parse error! %s" % ex)
def loacal_files_check(files): if not files: return False, 0 try: total_size = 0 for tfile in files: total_size += os.path.getsize(tfile) return True, total_size except os.error: Log.error("files %s not exist or can't access" % files) return False, 0
def ret_run(str, func, *args): t = time.time() r = False try: r = func(*args) return r except: if bool(config("setting", "maillisten")): sendmsg(config("run", "run_name"), str + ":" + traceback.format_exc()) Log.error(str + ":" + traceback.format_exc()) return False
def run(str, func, *args): t = time.time() # echo(str) r = False try: r = func(*args) except: Log.error(traceback.format_exc()) if r: totalTime = int(time.time() - t) # echo(Constant.RUN_RESULT_SUCCESS % totalTime) else: pass
def recover_contacts(self): """ @brief recover contacts. @return Bool: whether operation succeed. """ try: self.User = pickle_load(self.pickle_file['User']) self.MemberList = pickle_load(self.pickle_file['MemberList']) self.GroupList = pickle_load(self.pickle_file['GroupList']) self.GroupMemeberList = pickle_load(self.pickle_file['GroupMemeberList']) self.SpecialUsersList = pickle_load(self.pickle_file['SpecialUsersList']) return True except Exception, e: Log.error(traceback.format_exc())
def get_ev_files(vpn_ip, path): pre_dir = os.path.dirname(path) my_capital = os.path.join(pre_dir, "my_capital.config") cli = SSHClient() try: ret = cli.cmd(vpn_ip, "cmd.run", ["cat %s" % my_capital]) if ret.get(vpn_ip).get("retcode") == 0: capital_content = ret.get(vpn_ip).get("return") sts = get_config_strategy(capital_content) print "sts: ", sts return strategy_map_ev(sts) except Exception, ex: traceback.print_exc() Log.error("get ev files error! %s" % ex)
def run(str, func, *args): t = time.time() echo(str) r = False try: r = func(*args) except: Log.error(traceback.format_exc()) if r: totalTime = int(time.time() - t) echo(Constant.RUN_RESULT_SUCCESS % totalTime) else: echo(Constant.RUN_RESULT_FAIL) exit()
def set_cookie(cookie_file): """ @brief Load cookie from file @param cookie_file @param user_agent @return cookie, LWPCookieJar """ cookie = cookielib.LWPCookieJar(cookie_file) try: cookie.load(ignore_discard=True) except: Log.error(traceback.format_exc()) opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie)) opener.addheaders = Constant.HTTP_HEADER_USERAGENT urllib2.install_opener(opener) return cookie
def insertmany(self, table, values): """ @brief Insert many rows in table @param table String @param values Array of tuple """ c = self.conn.cursor() self.lock.acquire() n = len(values[0]) sql = ("INSERT INTO %s VALUES (" + ",".join(['?'] * n) + ");") % table Log.debug('DB -> %s' % sql) try: c.executemany(sql, values) except Exception, e: Log.error(traceback.format_exc())
def get_data(self, multi=1): base_url = urljoin(self.etcd_host, path.join('v2/keys', self.etcd_root.strip('/'))) Log.debug('baseUrl: %s' % base_url) try: root_all = [] sub_keys = json.loads(requests.get(base_url).content) m_parten = '%s/[0-9]{1,3}$' % self.etcd_root for each_keys in sub_keys['node']['nodes']: rst = self.mul_gid(m_parten, each_keys, multi=multi) if rst: root_all += [i.get() for i in rst if i.get()] return root_all except IOError: Log.error('Network is unavailable') except KeyError: Log.error('Etcd response no available key')
def execute(self, sql, value=None): """ @brief execute sql commands, return result if it has @param sql String @param value Tuple @return result Array """ c = self.conn.cursor() self.lock.acquire() hasReturn = sql.lstrip().upper().startswith("SELECT") try: if value: c.execute(sql, value) else: c.execute(sql) if hasReturn: result = c.fetchall() except Exception, e: Log.error(traceback.format_exc())
def mass_send(method, data, func): j = {'ret': -1, 'unsend_list': []} if method == 'POST' and data: to_list = data['to_list'] msg = data['msg'] media_type = data.get('media_type', '') if media_type in ['img', 'emot']: file_path = os.path.join(app.config['UPLOAD_FOLDER'], msg) response = wechat.webwxuploadmedia(file_path) if response is not None: msg = response['MediaId'] elif media_type == 'file': file_path = os.path.join(app.config['UPLOAD_FOLDER'], msg) data = { 'appid': Constant.API_WXAPPID, 'title': msg, 'totallen': '', 'attachid': '', 'type': wechat.wx_conf['APPMSGTYPE_ATTACH'], 'fileext': msg.split('.')[-1], } response = wechat.webwxuploadmedia(file_path) if response is not None: data['totallen'] = response['StartPos'] data['attachid'] = response['MediaId'] else: Log.error('File upload error') msg = data for groups in split_array(to_list, 20): for g in groups: r = func(g, msg) if not r: j['unsend_list'].append(g) time.sleep(1) j['ret'] = len(j['unsend_list']) return j
def post(session, url, params, jsonfmt=True): """ @brief http post request @param url String @param params Dict, post params @param jsonfmt Bool, whether is json format @return http response """ Log.debug('POST -> '+url) Log.debug(params) header = {} if jsonfmt: # request = urllib2.Request(url=url, data=json.dumps(params, ensure_ascii=False).encode('utf8')) # request.add_header(*Constant.HTTP_HEADER_CONTENTTYPE) data = json.dumps(params, ensure_ascii=False).encode('utf8') header[Constant.HTTP_HEADER_CONTENTTYPE[0]] = Constant.HTTP_HEADER_CONTENTTYPE[1] else: # request = urllib2.Request(url=url, data=urllib.urlencode(params)) data = params while True: try: # response = urllib2.urlopen(request, timeout=30) # data = response.read() # response.close() r = session.post(url, data=data, headers=header, timeout=5) if jsonfmt: # Log.debug(data) return json.loads(r.content, object_hook=_decode_data) # return r.json() return r.content except (KeyboardInterrupt, SystemExit): raise except: Log.error(traceback.format_exc()) time.sleep(0.5) echo('re post\n')
def mass_send(method, data, func): j = {'ret': -1, 'unsend_list':[]} if method == 'POST' and data: to_list = data['to_list'] msg = data['msg'] media_type = data.get('media_type', '') if media_type in ['img', 'emot']: file_path = os.path.join(app.config['UPLOAD_FOLDER'], msg) response = wechat.webwxuploadmedia(file_path) if response is not None: msg = response['MediaId'] elif media_type == 'file': file_path = os.path.join(app.config['UPLOAD_FOLDER'], msg) data = { 'appid': Constant.API_WXAPPID, 'title': msg, 'totallen': '', 'attachid': '', 'type': wechat.wx_conf['APPMSGTYPE_ATTACH'], 'fileext': msg.split('.')[-1], } response = wechat.webwxuploadmedia(file_path) if response is not None: data['totallen'] = response['StartPos'] data['attachid'] = response['MediaId'] else: Log.error('File upload error') msg = data for groups in split_array(to_list, 20): for g in groups: r = func(g, msg) if not r: j['unsend_list'].append(g) time.sleep(1) j['ret'] = len(j['unsend_list']) return j
def get(session, url, api=None): """ @brief http get request @param url String @param api wechat api @return http response """ Log.debug('GET -> ' + url) header = {} header[Constant.HTTP_HEADER_CONNECTION[0]] = Constant.HTTP_HEADER_CONNECTION[1] header[Constant.HTTP_HEADER_REFERER[0]] = Constant.HTTP_HEADER_REFERER[1] # request = urllib2.Request(url=url) # request.add_header(*Constant.HTTP_HEADER_CONNECTION) # request.add_header(*Constant.HTTP_HEADER_REFERER) if api in ['webwxgetvoice', 'webwxgetvideo']: # request.add_header(*Constant.HTTP_HEADER_RANGE) header[Constant.HTTP_HEADER_RANGE[0]] = Constant.HTTP_HEADER_RANGE[1] while True: try: r = session.get(url, headers=header) return r.content # response = urllib2.urlopen(request, timeout=30) # data = response.read() # response.close() # if api == None: # Log.debug(data) # return data except (KeyboardInterrupt, SystemExit): raise except: Log.error(traceback.format_exc()) time.sleep(0.5) echo('re get\n')
def assets_create(self, data): f_uuid = self.node_create(data[1]) d_uuid = self.domain_create(data[2]) a_uuid = self.admin_user_create(data[3]) jms_assets = self.assets_list() for each_asset in data[0]: each_asset['nodes'] = self.node_child_create( f_uuid, each_asset['group']) each_asset['domain'] = d_uuid each_asset['admin_user'] = a_uuid if each_asset['id'] in [x['id'] for x in jms_assets]: self.assets_update(each_asset, jms_assets) else: rst = requests.post(url=self.url + '/api/v1/assets/assets/', headers=self.headers, data=json.dumps(each_asset)) if str(rst.status_code).startswith('2'): Log.info('create asset %s %s' % (each_asset['hostname'], rst.status_code)) else: Log.error('create asset faild %s: %s' % (rst.status_code, rst.text))
def webwxuploadmedia(self, file_path): """ @brief upload image @param file_path String @return Dict: json """ url = self.wx_conf['API_webwxuploadmedia'] + '?f=json' # 计数器 self.media_count = self.media_count + 1 fn = file_path # mime_type: # 'application/pdf' # 'image/jpeg' # 'image/png' # ... mime_type = mimetypes.guess_type(fn, strict=False)[0] if not mime_type: mime_type = 'text/plain' # 文档格式 # 微信服务器目前应该支持3种类型: # pic 直接显示,包含图片,表情 # video 不清楚 # doc 显示为文件,包含PDF等 media_type = 'pic' if mime_type.split('/')[0] == 'image' else 'doc' time_format = "%a %b %d %Y %T GMT%z (%Z)" last_modifie_date = time.strftime(time_format, time.localtime()) file_size = os.path.getsize(fn) pass_ticket = self.pass_ticket client_media_id = str(int(time.time() * 1000)) + \ str(random.random())[:5].replace('.', '') webwx_data_ticket = '' for item in self.cookie: if item.name == 'webwx_data_ticket': webwx_data_ticket = item.value break if (webwx_data_ticket == ''): Log.error("No Cookie\n") return None uploadmediarequest = json.dumps({ "BaseRequest": self.base_request, "ClientMediaId": client_media_id, "TotalLen": file_size, "StartPos": 0, "DataLen": file_size, "MediaType": 4 }, ensure_ascii=False).encode('utf8') multipart_encoder = MultipartEncoder( fields={ 'id': 'WU_FILE_' + str(self.media_count), 'name': fn, 'type': mime_type, 'lastModifieDate': last_modifie_date, 'size': str(file_size), 'mediatype': media_type, 'uploadmediarequest': uploadmediarequest, 'webwx_data_ticket': webwx_data_ticket, 'pass_ticket': pass_ticket, 'filename': ( fn, open(fn, 'rb'), mime_type.split('/')[1] ) }, boundary=( '-----------------------------' '1575017231431605357584454111' ) ) headers = { 'Host': self.wx_filehost, 'User-Agent': self.user_agent, 'Accept': ( 'text/html,application/xhtml+xml,' 'application/xml;q=0.9,*/*;q=0.8' ), 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'https://' + self.wx_host, 'Content-Type': multipart_encoder.content_type, 'Origin': 'https://' + self.wx_host, 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', } r = requests.post(url, data=multipart_encoder, headers=headers) dic = json.loads(r.text) #修复无法发送Media消息BUG if dic['BaseResponse']['Ret'] == 0: return dic return None
def error(str): Log.error(str[:-1]) sys.stdout.write(str) sys.stdout.flush()
def get_local_files(task_type, vpn_ip, path): get_files_handler = {"Upload Ev": get_ev_files, "Upload Ot": get_ot_files} if task_type in get_files_handler.keys(): return get_files_handler[task_type](vpn_ip, path) Log.error("task type not found %s" % task_type) return False
def start(self): # echo(Constant.LOG_MSG_START) # run(Constant.LOG_MSG_RECOVER, self.recover) # timeOut = time.time() - self.last_login # echo(Constant.LOG_MSG_TRY_INIT) # if self.webwxinit(): # echo(Constant.LOG_MSG_SUCCESS) # run(Constant.LOG_MSG_RECOVER_CONTACT, self.recover_contacts) # else: # 若本地信息无法初始化微信,则需要进行重新登录 # 上面属于未登出状态重新启动的处理 # 正常来说都应该进行二维码验证 # 上面处理在不需要进行帐号信息本地存储的状态下可以注释 # echo(Constant.LOG_MSG_FAIL) while True: # first try to login by uin without qrcode # echo(Constant.LOG_MSG_ASSOCIATION_LOGIN) # if self.association_login(): # echo(Constant.LOG_MSG_SUCCESS) # else: # echo(Constant.LOG_MSG_FAIL) # scan qrcode to login # 正常扫描二维码登录步骤 run(Constant.LOG_MSG_GET_UUID, self.getuuid) echo(Constant.LOG_MSG_GET_QRCODE) self.genqrcode() echo(Constant.LOG_MSG_SCAN_QRCODE) if not self.waitforlogin(): continue echo(Constant.LOG_MSG_CONFIRM_LOGIN) if not self.waitforlogin(0): continue break run(Constant.LOG_MSG_LOGIN, self.login) run(Constant.LOG_MSG_INIT, self.webwxinit) run(Constant.LOG_MSG_STATUS_NOTIFY, self.webwxstatusnotify) run(Constant.LOG_MSG_GET_CONTACT, self.webwxgetcontact) echo(Constant.LOG_MSG_CONTACT_COUNT % (self.MemberCount, len(self.MemberList))) echo(Constant.LOG_MSG_OTHER_CONTACT_COUNT % (len(self.addGroupIDList), len(self.ContactList), len(self.SpecialUsersList), len(self.PublicUsersList))) run(Constant.LOG_MSG_GET_GROUP_MEMBER, self.fetch_group_contacts) # 使用对话设置cookies self.cookie = self.session.cookies while True: [retcode, selector] = self.synccheck() Log.debug('retcode: %s, selector: %s' % (retcode, selector)) self.exit_code = int(retcode) if retcode == '1100': echo(Constant.LOG_MSG_LOGOUT) break if retcode == '1101': echo(Constant.LOG_MSG_LOGIN_OTHERWHERE) break if retcode == '1102': echo(Constant.LOG_MSG_QUIT_ON_PHONE) break elif retcode == '0': if selector == '2' or selector == '4' or selector == '7' or selector == '6' or selector == '3': # 6 -> 新朋友,3 -> 自己信息的修改, # 有新消息 r = self.webwxsync() # 获取新消息的内容 # 保存群聊到通讯录 # 修改群名称 # 新增或删除联系人 # 群聊成员数目变化 if r is not None: try: echo('into handle_mod\n') self.handle_mod(r) except: Log.error(traceback.format_exc()) elif selector == '0': # 无更新 echo('no new info\n') time.sleep(self.time_out) else: r = self.webwxsync() Log.debug('webwxsync: %s\n' % json.dumps(r)) # 执行定时任务 if self.msg_handler: flag = self.msg_handler.check_exit() if flag: echo('达到运行时长,即将退出\n') break
""" @brief send file to mass users or gourps """ j = mass_send(request.method, request.json, wechat.webwxsendappmsg) return jsonify(j) def run_server(): app.run(port=PORT) if cm.get('setting', 'server_mode') == 'True': serverProcess = threading.Thread(target=run_server) serverProcess.start() while True: try: wechat.start() except KeyboardInterrupt: echo(Constant.LOG_MSG_QUIT) wechat.exit_code = 1 else: Log.error(traceback.format_exc()) finally: wechat.stop() if wechat.exit_code == 0: echo(Constant.MAIN_RESTART) else: # kill process os.system(Constant.LOG_MSG_KILL_PROCESS % os.getpid())
def start(self): echo(Constant.LOG_MSG_START) run(Constant.LOG_MSG_RECOVER, self.recover) timeOut = time.time() - self.last_login echo(Constant.LOG_MSG_TRY_INIT) if self.webwxinit(): echo(Constant.LOG_MSG_SUCCESS) run(Constant.LOG_MSG_RECOVER_CONTACT, self.recover_contacts) else: echo(Constant.LOG_MSG_FAIL) while True: # first try to login by uin without qrcode echo(Constant.LOG_MSG_ASSOCIATION_LOGIN) if self.association_login(): echo(Constant.LOG_MSG_SUCCESS) else: echo(Constant.LOG_MSG_FAIL) # scan qrcode to login run(Constant.LOG_MSG_GET_UUID, self.getuuid) echo(Constant.LOG_MSG_GET_QRCODE) self.genqrcode() echo(Constant.LOG_MSG_SCAN_QRCODE) if not self.waitforlogin(): continue echo(Constant.LOG_MSG_CONFIRM_LOGIN) if not self.waitforlogin(0): continue break run(Constant.LOG_MSG_LOGIN, self.login) run(Constant.LOG_MSG_INIT, self.webwxinit) run(Constant.LOG_MSG_STATUS_NOTIFY, self.webwxstatusnotify) run(Constant.LOG_MSG_GET_CONTACT, self.webwxgetcontact) echo(Constant.LOG_MSG_CONTACT_COUNT % ( self.MemberCount, len(self.MemberList) )) echo(Constant.LOG_MSG_OTHER_CONTACT_COUNT % ( len(self.GroupList), len(self.ContactList), len(self.SpecialUsersList), len(self.PublicUsersList) )) run(Constant.LOG_MSG_GET_GROUP_MEMBER, self.fetch_group_contacts) run(Constant.LOG_MSG_SNAPSHOT, self.snapshot) while True: [retcode, selector] = self.synccheck() Log.debug('retcode: %s, selector: %s' % (retcode, selector)) self.exit_code = int(retcode) if retcode == '1100': echo(Constant.LOG_MSG_LOGOUT) break if retcode == '1101': echo(Constant.LOG_MSG_LOGIN_OTHERWHERE) break if retcode == '1102': echo(Constant.LOG_MSG_QUIT_ON_PHONE) break elif retcode == '0': if selector == '2': r = self.webwxsync() if r is not None: try: self.handle_msg(r) except: Log.error(traceback.format_exc()) elif selector == '7': r = self.webwxsync() elif selector == '0': time.sleep(self.time_out) elif selector == '4': # 保存群聊到通讯录 # 修改群名称 # 新增或删除联系人 # 群聊成员数目变化 r = self.webwxsync() if r is not None: try: self.handle_mod(r) except: Log.error(traceback.format_exc()) elif selector == '3' or selector == '6': break else: r = self.webwxsync() Log.debug('webwxsync: %s\n' % json.dumps(r)) # 执行定时任务 if self.msg_handler: self.msg_handler.check_schedule_task()
""" j = mass_send(flask.request.method, flask.request.json, wechat.webwxsendappmsg) return flask.Response(json.dumps(j), mimetype='application/json') def run_server(): app.run(port=PORT) if cm.get('setting', 'server_mode') == 'True': serverProcess = threading.Thread(target=run_server) serverProcess.start() while True: try: wechat.start() except KeyboardInterrupt: echo(Constant.LOG_MSG_QUIT) wechat.exit_code = 1 else: Log.error(traceback.format_exc()) finally: wechat.stop() if wechat.exit_code == 0: echo(Constant.MAIN_RESTART) else: # kill process os.system(Constant.LOG_MSG_KILL_PROCESS % os.getpid())
def doTaggedMapUpdates(self, grid_pos, mapUpdatesList): if not self.isValidPosition(grid_pos): Log.error("Received invalid position %s" % (str(grid_pos))) return self.__doSeqTaggedMapUpdates__(grid_pos, mapUpdatesList)
def webwxuploadmedia(self, file_path): """ @brief upload image @param file_path String @return Dict: json """ url = self.wx_conf['API_webwxuploadmedia'] + '?f=json' # 计数器 self.media_count = self.media_count + 1 fn = file_path # mime_type: # 'application/pdf' # 'image/jpeg' # 'image/png' # ... mime_type = mimetypes.guess_type(fn, strict=False)[0] if not mime_type: mime_type = 'text/plain' # 文档格式 # 微信服务器目前应该支持3种类型: # pic 直接显示,包含图片,表情 # video 不清楚 # doc 显示为文件,包含PDF等 media_type = 'pic' if mime_type.split('/')[0] == 'image' else 'doc' time_format = "%a %b %d %Y %T GMT%z (%Z)" last_modifie_date = time.strftime(time_format, time.localtime()) file_size = os.path.getsize(fn) pass_ticket = self.pass_ticket client_media_id = str(int(time.time() * 1000)) + \ str(random.random())[:5].replace('.', '') webwx_data_ticket = '' for item in self.cookie: if item.name == 'webwx_data_ticket': webwx_data_ticket = item.value break if (webwx_data_ticket == ''): Log.error("No Cookie\n") return None uploadmediarequest = json.dumps( { "BaseRequest": self.base_request, "ClientMediaId": client_media_id, "TotalLen": file_size, "StartPos": 0, "DataLen": file_size, "MediaType": 4 }, ensure_ascii=False).encode('utf8') multipart_encoder = MultipartEncoder( fields={ 'id': 'WU_FILE_' + str(self.media_count), 'name': fn, 'type': mime_type, 'lastModifieDate': last_modifie_date, 'size': str(file_size), 'mediatype': media_type, 'uploadmediarequest': uploadmediarequest, 'webwx_data_ticket': webwx_data_ticket, 'pass_ticket': pass_ticket, 'filename': (fn, open(fn, 'rb'), mime_type.split('/')[1]) }, boundary=('-----------------------------' '1575017231431605357584454111')) headers = { 'Host': self.wx_filehost, 'User-Agent': self.user_agent, 'Accept': ('text/html,application/xhtml+xml,' 'application/xml;q=0.9,*/*;q=0.8'), 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Referer': 'https://' + self.wx_host, 'Content-Type': multipart_encoder.content_type, 'Origin': 'https://' + self.wx_host, 'Connection': 'keep-alive', 'Pragma': 'no-cache', 'Cache-Control': 'no-cache', } r = requests.post(url, data=multipart_encoder, headers=headers) dic = json.loads(r.text) #修复无法发送Media消息BUG if dic['BaseResponse']['Ret'] == 0: return dic return None
def start(self): echo(Constant.LOG_MSG_START) run(Constant.LOG_MSG_RECOVER, self.recover) timeOut = time.time() - self.last_login echo(Constant.LOG_MSG_TRY_INIT) if self.webwxinit(): echo(Constant.LOG_MSG_SUCCESS) run(Constant.LOG_MSG_RECOVER_CONTACT, self.recover_contacts) else: echo(Constant.LOG_MSG_FAIL) while True: # first try to login by uin without qrcode echo(Constant.LOG_MSG_ASSOCIATION_LOGIN) if self.association_login(): echo(Constant.LOG_MSG_SUCCESS) else: echo(Constant.LOG_MSG_FAIL) # scan qrcode to login run(Constant.LOG_MSG_GET_UUID, self.getuuid) echo(Constant.LOG_MSG_GET_QRCODE) self.genqrcode() echo(Constant.LOG_MSG_SCAN_QRCODE) if not self.waitforlogin(): continue echo(Constant.LOG_MSG_CONFIRM_LOGIN) if not self.waitforlogin(0): continue break run(Constant.LOG_MSG_LOGIN, self.login) run(Constant.LOG_MSG_INIT, self.webwxinit) run(Constant.LOG_MSG_STATUS_NOTIFY, self.webwxstatusnotify) run(Constant.LOG_MSG_GET_CONTACT, self.webwxgetcontact) echo(Constant.LOG_MSG_CONTACT_COUNT % (self.MemberCount, len(self.MemberList))) echo(Constant.LOG_MSG_OTHER_CONTACT_COUNT % (len(self.GroupList), len(self.ContactList), len(self.SpecialUsersList), len(self.PublicUsersList))) run(Constant.LOG_MSG_GET_GROUP_MEMBER, self.fetch_group_contacts) run(Constant.LOG_MSG_SNAPSHOT, self.snapshot) while True: [retcode, selector] = self.synccheck() Log.debug('retcode: %s, selector: %s' % (retcode, selector)) self.exit_code = int(retcode) if retcode == '1100': echo(Constant.LOG_MSG_LOGOUT) break if retcode == '1101': echo(Constant.LOG_MSG_LOGIN_OTHERWHERE) break if retcode == '1102': echo(Constant.LOG_MSG_QUIT_ON_PHONE) break elif retcode == '0': if selector == '2': r = self.webwxsync() if r is not None: try: self.handle_msg(r) except: Log.error(traceback.format_exc()) elif selector == '7': r = self.webwxsync() elif selector == '0': time.sleep(self.time_out) elif selector == '4': # 保存群聊到通讯录 # 修改群名称 # 新增或删除联系人 # 群聊成员数目变化 r = self.webwxsync() if r is not None: try: self.handle_mod(r) except: Log.error(traceback.format_exc()) elif selector == '3' or selector == '6': break else: r = self.webwxsync() Log.debug('webwxsync: %s\n' % json.dumps(r)) # 执行定时任务 if self.msg_handler: self.msg_handler.check_schedule_task() if self.bot: r = self.bot.time_schedule() if r: self.webwxsendmsg(r, 'filehelper')
def handle_msg(self, r): Log.debug('handle message') n = len(r['AddMsgList']) if n == 0: # 权宜之计 time.sleep(self.time_out) return if self.log_mode: echo(Constant.LOG_MSG_NEW_MSG % n) for raw_msg in r['AddMsgList']: msgType = raw_msg['MsgType'] msgId = raw_msg['MsgId'] content = raw_msg['Content'].replace('<', '<').replace('>', '>') content = trans_coding(content).encode('utf-8') rmsg = {} reply_flag = False # 获取收发人信息 from_id = raw_msg['FromUserName'] to_id = raw_msg['ToUserName'] if from_id[0:2] == '@@': from_user = self.get_group_by_id(from_id) if re.search(":<br/>", content, re.IGNORECASE): who_id = content.split(':<br/>')[0] from_who = self.get_group_user_by_id(who_id, from_id) rmsg['FromWho'] = from_who to_user = self.get_group_user_by_id(to_id, from_id) content_use = ':<br/>'.join(content.split(':<br/>')[1:]) reply_flag = True elif to_id[0:2] == '@@': from_user = self.get_group_user_by_id(from_id, to_id) to_user = self.get_group_by_id(to_id) echo(content + '\n') content_use = ':<br/>'.join(content.split(':<br/>')[1:]) else: from_user = self.get_user_by_id(from_id) to_user = self.get_user_by_id(to_id) content_use = content if from_id != self.User['UserName']: reply_flag = True rmsg['raw_msg'] = raw_msg rmsg['FromUser'] = from_user rmsg['ToUser'] = to_user # 消息内容分类获取 if msgType == self.wx_conf['MSGTYPE_TEXT']: # 地理位置消息 if content_use.find('pictype=location') != -1: location = content_use.split(':<br/>')[0] rmsg['location'] = location rmsg['text'] = location rmsg['log'] = Constant.LOG_MSG_LOCATION % location # 普通文本消息 else: rmsg['text'] = content_use rmsg['log'] = content_use # 文字信息分类处理 self.add_operate_list(rmsg, reply_flag) elif msgType == self.wx_conf['MSGTYPE_IMAGE']: data = self.webwxgetmsgimg(msgId) fn = 'img_' + msgId + '.jpg' dir = self.save_data_folders['webwxgetmsgimg'] path = save_file(fn, data, dir) rmsg['text'] = '[图片]' rmsg['image'] = path rmsg['log'] = Constant.LOG_MSG_PICTURE % path elif msgType == self.wx_conf['MSGTYPE_VOICE']: data = self.webwxgetvoice(msgId) fn = 'voice_' + msgId + '.mp3' dir = self.save_data_folders['webwxgetvoice'] path = save_file(fn, data, dir) rmsg['text'] = '[音频]' rmsg['voice'] = path rmsg['log'] = Constant.LOG_MSG_VOICE % path elif msgType == self.wx_conf['MSGTYPE_SHARECARD']: info = raw_msg['RecommendInfo'] card = Constant.LOG_MSG_NAME_CARD % ( info['NickName'], info['Alias'], info['Province'], info['City'], Constant.LOG_MSG_SEX_OPTION[info['Sex']]) namecard = '%s %s %s %s %s' % ( info['NickName'], info['Alias'], info['Province'], info['City'], Constant.LOG_MSG_SEX_OPTION[info['Sex']]) rmsg['text'] = '[名片]' + trans_coding(namecard).encode('utf-8') rmsg['namecard'] = namecard rmsg['log'] = card elif msgType == self.wx_conf['MSGTYPE_EMOTICON']: url = search_content('cdnurl', content_use) rmsg['text'] = '[表情]' rmsg['emoticon'] = url rmsg['log'] = Constant.LOG_MSG_EMOTION % url elif msgType == self.wx_conf['MSGTYPE_APP']: card = '' # 链接, 音乐, 微博 if raw_msg['AppMsgType'] in [ self.wx_conf['APPMSGTYPE_AUDIO'], self.wx_conf['APPMSGTYPE_URL'], self.wx_conf['APPMSGTYPE_OPEN'] ]: card = Constant.LOG_MSG_APP_LINK % ( Constant.LOG_MSG_APP_LINK_TYPE[raw_msg['AppMsgType']], raw_msg['FileName'], search_content('des', content_use, 'xml'), raw_msg['Url'], search_content('appname', content_use, 'xml')) rmsg['text'] = '[分享链接]' rmsg['link'] = raw_msg['Url'] rmsg['log'] = card # 图片 elif raw_msg['AppMsgType'] == self.wx_conf['APPMSGTYPE_IMG']: data = self.webwxgetmsgimg(msgId) fn = 'img_' + msgId + '.jpg' dir = self.save_data_folders['webwxgetmsgimg'] path = save_file(fn, data, dir) card = Constant.LOG_MSG_APP_IMG % ( path, search_content('appname', content_use, 'xml')) rmsg['text'] = '[图片]' rmsg['image'] = path rmsg['log'] = card else: rmsg['text'] = '' rmsg['log'] = Constant.LOG_MSG_UNKNOWN_MSG % (msgType, content_use) elif msgType == self.wx_conf['MSGTYPE_STATUSNOTIFY']: Log.info(Constant.LOG_MSG_NOTIFY_PHONE) rmsg['text'] = '[状态通知]' rmsg['log'] = Constant.LOG_MSG_NOTIFY_PHONE[:-1] elif msgType == self.wx_conf['MSGTYPE_MICROVIDEO']: data = self.webwxgetvideo(msgId) fn = 'video_' + msgId + '.mp4' dir = self.save_data_folders['webwxgetvideo'] path = save_file(fn, data, dir) rmsg['text'] = '[小视频]' rmsg['video'] = path rmsg['log'] = Constant.LOG_MSG_VIDEO % path elif msgType == self.wx_conf['MSGTYPE_RECALLED']: recall_id = search_content('msgid', content_use, 'xml') text = Constant.LOG_MSG_RECALL rmsg['text'] = text rmsg['recall_msg_id'] = recall_id rmsg['log'] = text elif msgType == self.wx_conf['MSGTYPE_SYS']: rmsg['text'] = content_use rmsg['sys_notif'] = content_use rmsg['log'] = content_use elif msgType == self.wx_conf['MSGTYPE_VERIFYMSG']: name = search_content('fromnickname', content_use) rmsg['text'] = '[添加好友请求]' rmsg['log'] = Constant.LOG_MSG_ADD_FRIEND % name # 好友自动同意在此处添加 count = len(self.AddUserList) add_user = { 'Order': count + 1, 'UserName': raw_msg['RecommendInfo']['UserName'], 'NickName': raw_msg['RecommendInfo']['NickName'], 'Ticket': raw_msg['RecommendInfo']['Ticket'] } self.AddUserList.append(add_user) # 先添加与列表中,之后可根据命令提示来允许添加谁 elif msgType == self.wx_conf['MSGTYPE_VIDEO']: # 暂时无法对该类型进行处理,即视频信息 rmsg['text'] = '[视频消息]' rmsg['log'] = Constant.LOG_MSG_UNKNOWN_MSG % (msgType, content_use) else: rmsg['text'] = '' rmsg['log'] = Constant.LOG_MSG_UNKNOWN_MSG % (msgType, content_use) if self.log_mode: self.show_msg(rmsg) try: if self.msg_handler: self.msg_handler.save_into_db(self.DBStoreMSGList) self.msg_handler.handle_commands(self.CommandList) self.msg_handler.get_bot_reply(self.GroupNeedReplyList, self.UserNeedReplyList) self.msg_handler.auto_reply(self.ReplyList) self.msg_handler.save_into_db(self.DBStoreBOTReplyList) except: traceback.print_exc() Log.error(traceback.format_exc()) finally: self.CommandList = [] self.DBStoreMSGList = [] self.GroupNeedReplyList = [] self.UserNeedReplyList = [] self.ReplyList = [] self.DBStoreBOTReplyList = []