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 delete_table(self, table): """ @brief Delete a table in database @param table String """ sql = "DROP TABLE if exists %s;" % table Log.debug('DB -> %s' % sql) self.execute(sql)
def create_table(self, table, cols): """ @brief Creates a table in database @param table String @param cols String, the cols in table """ sql = "CREATE TABLE if not exists %s (%s);" % (table, cols) Log.debug('DB -> %s' % sql) self.execute(sql)
def close(self): """ @brief close connection to database """ Log.debug('DB -> close') # 关闭数据库连接 self.conn.close()
def create_db(self, db_name): """ @brief Creates a database @param db_name String """ if self.conf['database'] not in self.show_database(): sql = 'CREATE DATABASE IF NOT EXISTS %s CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci' % db_name Log.debug('DB -> %s' % sql) self.execute(sql)
def insert(self, table, value): """ @brief Insert a row in table @param table String @param value Tuple """ sql = ("INSERT INTO %s VALUES (" + ",".join(['?'] * len(value)) + ");") % table Log.debug('DB -> %s' % sql) self.execute(sql, value)
def insert(self, table, value): """ @brief Insert a row in table @param table String @param value Tuple """ col_name = self.table_cols[table][1:] sql = "INSERT INTO %s(%s) VALUES (%s)" % (table, str(','.join(col_name)), array_join(value, ',')) Log.debug('DB -> %s' % sql) self.execute(sql)
def insertmany(self, table, values): """ @brief Insert many rows in table @param table String @param values Array of tuple """ col_name = self.table_cols[table][1:] sql = 'INSERT INTO %s(%s) VALUES (%s)' % (table, ','.join(col_name), ','.join(['%s'] * len(values[0]))) Log.debug('DB -> %s' % sql) self.execute(sql, values)
def delete_table(self, table): """ @brief Delete a table in database @param table String """ if table in self.table_cols: sql = "DROP TABLE IF EXISTS %s" % table Log.debug('DB -> %s' % sql) self.execute(sql) self.table_cols.pop(table)
def delete(self, table, field='', condition=''): """ @brief execute sql commands, return result if it has @param table String @param field String @param condition String """ sql = "DELETE FROM %s WHERE %s=%s" % (table, field, condition) Log.debug('DB -> %s' % sql) self.execute(sql)
def create_table(self, table, cols): """ @brief Creates a table in database @param table String @param cols String, the cols in table """ if table not in self.table_cols: sql = 'CREATE TABLE IF NOT EXISTS %s(id int primary key auto_increment, %s) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci' % (table, cols) Log.debug('DB -> %s' % sql) self.execute(sql) self.table_cols[table] = ['id'] + [c.strip().split(' ')[0] for c in cols.split(',')]
def check_schedule_task(self): # update group member list at 00:00 am every morning print '[*] check_schedule_task 执行定时任务,同步group member list' t = time.localtime() if t.tm_hour == 0 and t.tm_min <= 1: # update group member Log.debug('update group member list everyday') self.db.delete_table(Constant.TABLE_GROUP_LIST()) self.db.delete_table(Constant.TABLE_GROUP_USER_LIST()) self.db.create_table(Constant.TABLE_GROUP_LIST(), Constant.TABLE_GROUP_LIST_COL) self.db.create_table(Constant.TABLE_GROUP_USER_LIST(), Constant.TABLE_GROUP_USER_LIST_COL) self.wechat.fetch_group_contacts()
def update(self, table, dic, condition=''): k_arr = [] v_arr = [] for (k, v) in dic.items(): k_arr.append('%s=?' % k) v_arr.append(v) sql = "UPDATE %s SET %s" % (table, ','.join(k_arr)) if condition: sql += " WHERE %s" % condition Log.debug('DB -> %s' % sql) self.execute(sql, tuple(v_arr))
def select(self, table, field='', condition=''): """ @brief select all result from table @param table String @param field String @param condition String @return result Tuple """ sql = "SELECT * FROM %s" % table if field and condition: sql += " WHERE %s='%s'" % (field, condition) Log.debug('DB -> %s' % sql) return self.execute(sql)
def str2qr_terminal(text): """ @brief convert string to qrcode matrix and outprint @param text The string """ Log.debug(text) qr = qrcode.QRCode() print(qr) qr.border = 1 qr.add_data(text) mat = qr.get_matrix() print(mat) print_qr(mat)
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 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 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 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 save_file(filename, data, dirName): """ @brief Saves raw data to file. @param filename String @param data Binary data @param dirName String @return file path """ Log.debug('save file: ' + filename) fn = filename if not os.path.exists(dirName): os.makedirs(dirName) fn = os.path.join(dirName, filename) with open(fn, 'wb') as f: f.write(data) return fn
def save_json(filename, data, dirName, mode='w+'): """ @brief Saves dict to json file. @param filename String @param data Dict @param dirName String @return file path """ Log.debug('save json: ' + filename) fn = filename if not os.path.exists(dirName): os.makedirs(dirName) fn = os.path.join(dirName, filename) with open(fn, mode) as f: f.write(json.dumps(data, indent=4) + '\n') return fn
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 select(self, table, field='', condition=''): """ @brief select all result from table @param table String @param field String @param condition String @return result Tuple """ result = [] if field and condition: cond = (condition,) sql = "SELECT * FROM %s WHERE %s=?" % (table, field) Log.debug('DB -> %s' % sql) result = self.execute(sql, cond) else: sql = "SELECT * FROM %s" % table Log.debug('DB -> %s' % sql) result = self.execute(sql) return result
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 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 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 handle_mod(self, r): # ModContactCount: 变更联系人或群聊成员数目 # ModContactList: 变更联系人或群聊列表,或群名称 Log.debug('handle modify') self.handle_msg(r) for m in r['ModContactList']: if m['UserName'][:2] == '@@': # group in_list = False g_id = m['UserName'] for g in self.GroupList: # group member change if g_id == g['UserName']: g['MemberCount'] = m['MemberCount'] g['NickName'] = m['NickName'] self.GroupMemeberList[g_id] = m['MemberList'] in_list = True if self.msg_handler: self.msg_handler.handle_group_member_change(g_id, m['MemberList']) break if not in_list: # a new group self.GroupList.append(m) self.GroupMemeberList[g_id] = m['MemberList'] if self.msg_handler: self.msg_handler.handle_group_list_change(m) self.msg_handler.handle_group_member_change(g_id, m['MemberList']) elif m['UserName'][0] == '@': # user in_list = False for u in self.MemberList: u_id = m['UserName'] if u_id == u['UserName']: u = m in_list = True break # if don't have then add it if not in_list: self.MemberList.append(m)
def recover(self): """ @brief Recover from snapshot data. @return Bool: whether operation succeed. """ cm = ConfigManager() [self.uuid, self.redirect_uri, self.uin, self.sid, self.skey, self.pass_ticket, self.synckey, device_id, self.last_login] = cm.get_wechat_config() print([self.uuid, self.redirect_uri, self.uin,\ self.sid, self.skey, self.pass_ticket,\ self.synckey, device_id, self.last_login]) if device_id: self.device_id = device_id self.base_request = { 'Uin': int(self.uin), 'Sid': self.sid, 'Skey': self.skey, 'DeviceID': self.device_id, } # set cookie Log.debug('set cookie') self.cookie = set_cookie(self.cookie_file) return True