#!/usr/bin/env python # coding: utf-8 #=================================================== from config import Log from config import Constant #--------------------------------------------------- import qrcode import re import os import sys import json import urllib import urllib2 import cookielib import cPickle as pickle import traceback import time import hashlib #=================================================== def _decode_data(data): """ @brief decode array or dict to utf-8 @param data array or dict @return utf-8 """ if isinstance(data, dict): rv = {} for key, value in data.iteritems(): if isinstance(key, unicode): key = key.encode('utf-8') rv[key] = _decode_data(value) return rv elif isinstance(data, list): rv = [] for item in data: item = _decode_data(item) rv.append(item) return rv elif isinstance(data, unicode): return data.encode('utf-8') else: return data def str2qr_terminal(text): """ @brief convert string to qrcode matrix and outprint @param text The string """ Log.debug(text) qr = qrcode.QRCode() qr.border = 1 qr.add_data(text) mat = qr.get_matrix() print_qr(mat) def str2qr_image(text, image_path): """ @brief convert string to qrcode image & save @param text The string @param image_path Save image to the path """ qr = qrcode.QRCode() qr.border = 1 qr.add_data(text) qr.make(fit=True) img = qr.make_image() img.save(image_path) def print_qr(mat): for i in mat: BLACK = Constant.QRCODE_BLACK WHITE = Constant.QRCODE_WHITE echo(''.join([BLACK if j else WHITE for j in i])+'\n') def echo(str): Log.info(str[:-1]) sys.stdout.write(str) sys.stdout.flush() 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 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 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 generate_file_name(filename): """ @brief generate file name @return new file name """ i = filename.rfind('.') ext = filename[i:] tmp = filename + str(int(time.time())) hash_md5 = hashlib.md5(tmp) return hash_md5.hexdigest() + ext 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 pickle_save(data, file): """ @brief Use pickle to save python object into file @param data The pyhton data @param file The file """ basedir = os.path.dirname(file) if not os.path.exists(basedir): os.makedirs(basedir) with open(file, 'wb') as f: pickle.dump(data, f, pickle.HIGHEST_PROTOCOL) def pickle_load(file): """ @brief Use pickle to load python object from file @param file The file @return python data """ if os.path.isfile(file): with open(file, 'rb') as f: return pickle.load(f) return None def search_content(key, content, fmat='attr'): """ @brief Search content from xml or html format @param key String @param content String @param fmat attr xml @return String """ if fmat == 'attr': pm = re.search(key + '\s?=\s?"([^"<]+)"', content) if pm: return pm.group(1) elif fmat == 'xml': pm = re.search('<{0}>([^<]+)'.format(key), content) if not pm: pm = re.search( '<{0}><\!\[CDATA\[(.*?)\]\]>'.format(key), content) if pm: return pm.group(1) return 'unknown' def is_str(s): """ @brief Determines if string. @param s String @return True if string, False otherwise. """ return isinstance(s, basestring) def trans_coding(data): """ @brief Transform string to unicode @param data String @return unicode """ if not data: return data result = None if type(data) == unicode: result = data elif type(data) == str: result = data.decode('utf-8') return result def trans_emoji(text): """ @brief Transform emoji html text to unicode @param text String @return emoji unicode """ def _emoji(matched): hex = matched.group(1) return ('\\U%08x' % int(hex, 16)).decode('unicode-escape').encode('utf-8') replace_t = re.sub(Constant.REGEX_EMOJI, _emoji, text) return replace_t 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 split_array(arr, n): for i in xrange(0, len(arr), n): yield arr[i:i+n]