def send_sms(cls, msg, level): if level not in ('error', 'fatal'): raise ValueError("level MUST be error or fatal") to_ls = cls.error_s_ls if level == 'error' else cls.fatal_s_ls result = [] for mobile in to_ls: http_client = HttpRpcClient() headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' } msg = { 'apiKey': API_KEY, 'appId': APP_ID, 'templateId': TEMPLATE['LOGGER'], 'mobile': mobile, 'param': msg } body = ujson.dumps(msg) response = ujson.loads(http_client.fetch_async(URL, headers, body)) if response['result'] != 'SUCCESS': logger.error('SMSService error_code: %s at %s' % (response['reason'], time.ctime())) result.append(response) return result
def __init__(self, openfire_ip=None, openfire_port=None): assert openfire_ip assert openfire_port self.openfire_ip = openfire_ip self.openfire_port = openfire_port self.user_http = HttpRpcClient(self.openfire_ip, self.openfire_port)
class UserService(object): __metaclass__ = Singleton Authorization = "qOAWYYau" def __init__(self, openfire_ip=None, openfire_port=None): assert openfire_ip assert openfire_port self.openfire_ip = openfire_ip self.openfire_port = openfire_port self.user_http = HttpRpcClient(self.openfire_ip, self.openfire_port) @except_adaptor() def add_user(self, user_name, password): url = "plugins/userService/users" header = { "Authorization": self.Authorization, "Content-Type": "application/xml" } body = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <user> <username>%s</username> <password>%s</password> </user>""" % (user_name, password) return self.user_http.fetch_async(url, header, body) @except_adaptor() def del_user(self, user_name): url = "plugins/userService/users/%s" % user_name header = {"Authorization": self.Authorization} return self.user_http.fetch_async(url, header, method="DELETE") @except_adaptor() def new_jid(self, user_name, password): """ 生产jid :param user_name:用户名 :param password:密码 :return:{"jid": new_jid, "password": password} """ try: self.add_user(user_name, password) except HTTPError, e: error_reason = xmltodict.parse(e.read()) if error_reason.get('error', {}).get('exception', None) == UserAlreadyExistException: logger.warn( "RegisterHandle new_jid failed!!!, jid for user_name:%s, password:%s has exist!!" % (user_name, password)) # 由于默认user_name就是jid的user_name,所以不能出现user_name不存在,但是jid存在的情况 # 但是由于是测试阶段,有可能手动添加JID,所以暂时忽略这种bug # assert False, error_reason new_jid = JidMgr().gen_jid(user_name, self.openfire_ip) return {"jid": new_jid, "password": password}
class UserService(object): __metaclass__ = Singleton Authorization = "qOAWYYau" def __init__(self, openfire_ip=None, openfire_port=None): assert openfire_ip assert openfire_port self.openfire_ip = openfire_ip self.openfire_port = openfire_port self.user_http = HttpRpcClient(self.openfire_ip, self.openfire_port) @except_adaptor() def add_user(self, user_name, password): url = "plugins/userService/users" header = {"Authorization": self.Authorization, "Content-Type": "application/xml"} body = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <user> <username>%s</username> <password>%s</password> </user>""" % ( user_name, password, ) return self.user_http.fetch_async(url, header, body) @except_adaptor() def del_user(self, user_name): url = "plugins/userService/users/%s" % user_name header = {"Authorization": self.Authorization} return self.user_http.fetch_async(url, header, method="DELETE") @except_adaptor() def new_jid(self, user_name, password): """ 生产jid :param user_name:用户名 :param password:密码 :return:{"jid": new_jid, "password": password} """ try: self.add_user(user_name, password) except HTTPError, e: error_reason = xmltodict.parse(e.read()) if error_reason.get("error", {}).get("exception", None) == UserAlreadyExistException: logger.warn( "RegisterHandle new_jid failed!!!, jid for user_name:%s, password:%s has exist!!" % (user_name, password) ) # 由于默认user_name就是jid的user_name,所以不能出现user_name不存在,但是jid存在的情况 # 但是由于是测试阶段,有可能手动添加JID,所以暂时忽略这种bug # assert False, error_reason new_jid = JidMgr().gen_jid(user_name, self.openfire_ip) return {"jid": new_jid, "password": password}
def get_userinfo(username): # remove wx# prefix username = username[3:] token = gen_wechat_access_token(GDevRdsInts) url = WX_USERINFO_URL.format(token, username) user_info = HttpRpcClient().fetch_async(url=url) return ujson.loads(user_info.body)
def new_connection(ip, port, protocol=PT_TCP): """ 新连接 :param ip:服务器ip :param port:服务器端口 :param protocol:服务器协议 """ logger.warn("ServiceMgrCacher::new_connection %s %s:%s!!!" % (protocol, ip, port)) if protocol == PT_TCP: return TcpRpcClient(str(ip), int(port)) elif protocol == PT_HTTP: return HttpRpcClient(str(ip), int(port)) elif protocol == PT_HTTPS: return HttpRpcClient(str(ip), int(port), True) else: return None
def _get(self): try: result = eval(HttpRpcClient(ssl=True).fetch_async(CLIENT_ACCESS_TOKEN_URL)) assert isinstance(result, dict) assert "errcode" not in result, result except: logger.error(traceback.format_exc()) return None self.access_token = result['access_token']
def post(self, mobile, code, seconds, param_sign, token): """ :param mobile: 手机号码 :param code: 验证码 :param seconds: 有效时间 :param param_sign: 参数验证 :param token:令牌 :return: """ if not valid_phone(mobile): return {'result': 'FAIL', 'reason': 'INVALID_MOBILE'} checked = False if param_sign and not Signer().check_sign(param_sign, mobile, code, seconds): checked = True if not checked and token: register_setting = ServiceMgrCacher.find_service(US_REGISTER) if not register_setting: return tcp_client = TcpRpcClient(str(register_setting['ip']), register_setting['port']['tcp']) result = tcp_client.fetch_async('verify_access_token', token) if result['result'] == error_code.ERROR_SUCCESS: checked = True if not checked: return {'result': 'FAIL', 'reason': 'INVALID_VERIFICATION'} http_client = HttpRpcClient() headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' } msg = { 'apiKey': API_KEY, 'appId': APP_ID, 'templateId': TEMPLATE['GENERAL'], 'mobile': mobile, 'param': '%s,%s' % (code, seconds2minutes(seconds)) } body = ujson.dumps(msg) result = ujson.loads(http_client.fetch_async(URL, headers, body)) return result
def get(self, code, *args, **kwargs): grant_type = 'authorization_code' args = '?appid={0}&secret={1}&code={2}&grant_type={3}'.format( APPID, APPSECRET, code, grant_type) url = 'https://api.weixin.qq.com/sns/oauth2/access_token' + args resp = HttpRpcClient().fetch_async(url=url) resp = resp.body logger.debug('resp = %r', resp) resp = ujson.loads(resp) #get wechat user info token = resp.get('access_token') openid = resp.get('openid') userinfo_args = '?access_token={0}&openid={1}&lang=zh_CN'.format( token, openid) userinfo_url = 'https://api.weixin.qq.com/sns/userinfo' + userinfo_args user_resp = HttpRpcClient().fetch_async(url=userinfo_url) str_user_resp = user_resp.body logger.debug('user_resp = %r', str_user_resp) user_resp = ujson.loads(str_user_resp) self.render('wechat_add_device.html', payload=user_resp)
def get(self, user_name, applicant, gid, allowed, msg='', *args, **kwargs): primary = GDevRdsInts.send_cmd(*get_group_primary(gid)) if not primary: return {'status': 1} if primary != user_name: return {'status': 2} sn = GDevRdsInts.send_cmd(*get_sn_of_gid(gid)) if allowed: GDevRdsInts.send_multi_cmd( *combine_redis_cmds(follow_group(gid, sn, applicant))) if applicant[:3] == 'wx#': # applicant from wechat logger.debug(u'wechat user follow: ', applicant) GDevRdsInts.send_cmd(*hset_wechat_gid(applicant, gid)) token = gen_wechat_access_token(GAccRdsInts) customerServiceUrl = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + token payload = \ { "touser": applicant[3:], "msgtype": "text", "text": { "content": "恭喜你设备添加成功。可以给平板发送照片了!" } } resp = HttpRpcClient().fetch_async(url=customerServiceUrl, body=ujson.dumps( payload, ensure_ascii=False)) logger.debug('wechat resp.code = %r, body = %r', resp.code, resp.body) return {'status': 0} payload = ujson.dumps({ 'reviewer': user_name, 'allowed': allowed, 'msg': msg, 'gid': gid }) logger.debug(u'follow review, applicant=%r, payload=%r' % (applicant, payload)) # 把关注验证结果放到申请人的消息列表里 GDevRdsInts.send_multi_cmd(*combine_redis_cmds( set_user_group_msglist(applicant, gid, 'follow_review', payload))) GMQDispRdsInts.send_cmd(*shortcut_mq( 'cloud_push', push_pack( user_name, 'follow_review', 2, payload, account=applicant))) return {'status': 0}
def _gen_auth_info(self, code): try: result = eval(HttpRpcClient(ssl=True).fetch_async(UAUTH_ACCESSS_TOKEN_URL(code))) assert isinstance(result, dict) assert "errcode" not in result or result['errcode'] == WXBizMsgCrypt_OK, result assert "access_token" in result, result assert "refresh_token" in result, result assert "openid" in result, result except: logger.error(traceback.format_exc()) return None self.auth_info_dic[code] = result return result
def get(self, code): grant_type = 'authorization_code' args = '?appid={0}&secret={1}&code={2}&grant_type={3}'.format( APPID, APPSECRET, code, grant_type) url = 'https://api.weixin.qq.com/sns/oauth2/access_token' + args resp = HttpRpcClient().fetch_async(url=url) resp = resp.body logger.debug('resp = %r', resp) resp = ujson.loads(resp) #get wechat user info token = resp.get('access_token') openid = resp.get('openid') if openid: username = '******' + openid dev_set = GDevRdsInts.send_cmd(*getall_wechat_devs(username)) dev_list = [{ 'gid': dev[0], 'nickname': dev[1] } for dev in dev_set.iteritems()] logger.debug('dev_list = %r, username = %r', dev_list, username) self.render('wechat_manage_dev.html', dev_list=dev_list, username=username) return
def gen_wechat_ticker(redis_ints, access_token): """ 自动获取wehcat ticker,如果不存在则创建之 :param redis_ints: redis 对象 :param access_token: 微信授权访问码 :return: ticker """ ticker = redis_ints.send_cmd(*get_wechat_ticket()) if ticker: return ticker get_ticket_result = ujson.loads(HttpRpcClient().fetch_async( url=WX_GET_TICKER_URL.format(access_token=access_token))) ticker = get_ticket_result.get("ticker") ticker_exp = get_ticket_result.get('expires_in') redis_ints.send_cmd(*set_wechat_ticket(ticker, ticker_exp)) logger.debug('get_ticker:%s, ticker=%s, expires_in=%s', time.strftime('%Y-%d-%m %H:%M:%S', time.localtime()), ticker, ticker_exp) return ticker
def gen_wechat_access_token(redis_ints): """ 自动获取wechat授权访问码,如果不存在则创建之 :param redis_ints: redis 对象 :return: access_token """ access_token = redis_ints.send_cmd(*get_wechat_access_token()) if access_token: return access_token get_token_result = ujson.loads( HttpRpcClient().fetch_async(url=WX_GET_ACCESS_TOKEN_URL)) access_token = get_token_result.get('access_token') assert access_token, 'get wechat access token failed. errcode: %r, errmsg: %r' % ( get_token_result.get('errcode'), get_token_result.get('errmsg')) expires = get_token_result.get('expires_in') redis_ints.send_cmd(*set_wechat_access_token(access_token, expires)) logger.debug('get_access_token:%s, access_token=%s, expires_in=%s', time.strftime('%Y-%d-%m %H:%M:%S', time.localtime()), access_token, expires) return access_token
def save_wechat_file(pic_url, from_user_name, msg_id, file_type, create_time, media_id=''): if file_type == '1': url = pic_url fn = msg_id + '.jpg' elif file_type == '2' or file_type == '3': token = gen_wechat_access_token(GAccRdsInts) url = WX_MEDIA_DOWN_URL.format(token, media_id) logger.debug('url = %s' % url) img = None try: for _ in xrange(3): img = HttpRpcClient().fetch_async(url=url) if img.code == 200: break except Exception, ex: logger.debug(u'url = %r, img = %r', url, img) logger.error(u'get wechat file failed: {0}'.format(ex), exc_info=True)
def locate(self, service_type): """ 获取服务连接:从pandora获取服务信息,并连接相关服务端口 :param service_type:服务类型 :return:connection """ locate_service_dic = locate(self.pandora_http_client, service_type) key_ls = filter(lambda p: p == "https" or p == "http", locate_service_dic.keys()) if not key_ls: return None protocol = key_ls[0] host = locate_service_dic.get(protocol, None) if not host: return None connection = self.connect_dic.get(host, None) if not connection: ip, port = host.split(":") connection = HttpRpcClient(ip, port, protocol == "https") assert connection self.connect_dic[host] = connection return connection
def post(self, user_name, share_id, reply_to='', comment_id='', text='', type='', file='', *args, **kwargs): share_info = GDevRdsInts.send_cmd(*retrieve_share_info(share_id)) if share_info is None: return {'status': 1} comment_id_list = GDevRdsInts.send_cmd(*get_comment(share_id)) if comment_id != '' and comment_id not in comment_id_list: logger.debug('comment, comment_id={0}'.format(comment_id)) return {'status': 2} now = str(time.time()) new_comment_id = ':'.join(('comment', now, user_name)) GDevRdsInts.send_multi_cmd(*combine_redis_cmds( add_comment(share_id, new_comment_id), save_comment_info(share_id, new_comment_id, reply_to, comment_id, text, type, file))) accounts = [reply_to] if reply_to is not None else [] accounts += [share_id.split(':')[-1]] like_list = GDevRdsInts.send_cmd(*get_like(share_id)) accounts += like_list for acc in accounts: if acc[:3] == 'wx#': files = json.loads(share_info.get('files')) fn, ref = files.popitem() fn = bs2utf8(fn) ref = bs2utf8(ref) logger.debug('files = %r, fn = %r, ref = %r', files, fn, ref) tk = gen_file_tk(acc, fn, 0, 0) if fn[-4:] == '.jpg': pic_url = BEIQI_FILE_DOWN_URL + urllib.urlencode({ 'tk': tk, 'r': ref }) url = "" if not file: url = WECHAT_COMMENT_PAGE_URL + urllib.urlencode( {'text': text}) token = gen_wechat_access_token(GAccRdsInts) customerServiceUrl = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + token nickname = GDevRdsInts.send_cmd(*get_user_nickname(user_name)) payload = { "touser": acc[3:], "msgtype": "news", "news": { "articles": [{ "title": nickname + "评论了你的回复", "description": text, "url": url, "picurl": pic_url }] } } logger.debug('pic_url = %r', pic_url) resp = HttpRpcClient().fetch_async(url=customerServiceUrl, body=ujson.dumps( payload, ensure_ascii=False)) logger.debug('custom service send. resp = %r, payload = %r', resp.body, payload) else: GMQDispRdsInts.send_cmd(*shortcut_mq( 'cloud_push', # sourcer, cb, from, description push_pack(user_name, 'comment', 2, ':'.join((user_name, share_id, reply_to, comment_id, text, type, file)), account=acc))) return {'comment_id': new_comment_id}
def gaode_loc(accesstype="", imei="", smac="", serverip="", cdms=0, imsi="", network="", tel="", bts="", nearbts="", mmac="", macs="", output="json"): """ 高德定位 :param accesstype: 移动端接入网络方式,必填,默认无 可选值: 移动接入网络:0 wifi接入网络:1 :param imei: 手机imei号 ,必填,默认无 此参数能够提高定位精度和准确度,且定位不到时可依据此参数进行跟踪排查,如没有则无法排查和跟踪问题 :param smac: 手机mac码 ,非必填,但建议填写 ,默认无 此参数能够提高定位精度和准确度,且定位不到时可依据此参数进行跟踪排查,如没有则无法排查和跟踪问题 :param serverip: 设备接入基站时对应的网关IP ,非必填,但建议填写 ,默认无 此参数能够提高定位精度和准确度,且定位不到时可依据此参数进行跟踪排查,如没有则无法排查和跟踪问题 :param cdma: 是否为cdma ,accesstype=0时,必填 ,默认0, 是否为cdma 非cdma:0 是cdma:1 :param imsi: 移动用户识别码 ,非必填,但建议填写 ,默认无 此参数能够提高定位精度和准确度,且定位不到时可依据此参数进行跟踪排查,如没有则无法排查和跟踪问题 :param network: 无线网络类型 ,accesstype=0时,必填 ,默认无 GSM/GPRS/EDGE/HSUPA/HSDPA/WCDMA :param tel : 手机号码 ,非必填,accesstype=0时,必填 ,默认无 :param bts : 接入基站信息,accesstype=0时,必填 ,默认无 非CDMA格式为:mcc,mnc,lac,cellid,signal CDMA格式为:sid,nid,bid,lon,lat,signal, 其中lon,lat可为空,格式为:sid,nid,bid,,,signal :param nearbts: 周边基站信息(不含接入基站信息), 非必填 ,默认无 基站信息1|基站信息2|基站信息3… :param mmac: 已连热点mac信息 , 非必填,但强烈建议填写,默认无 mac,signal,ssid。 如:f0:7d:68:9e:7d:18,-41,TPLink :param macs : wifi列表中mac信息 , accesstype=1时,必填 ,默认无 单mac信息同mmac,mac之间使用“|”分隔。必须填写2个及2个以上,30个以内的方可正常定位。请不要包含移动wifi信息 :param output : 返回数据格式类型 , 可选 ,默认:json 可选值:json,xml :return: 字符串格式 """ params = { "accesstype": accesstype, "imei": imei, "smac": smac, "serverip": serverip, "cdms": cdms, "imsi": imsi, "network": network, "tel": tel, "bts": bts, "nearbts": nearbts, "mmac": mmac, "macs": macs, "output": output, "key": GAODE_LOC_APP_KEY } FULL_URL = GAODE_LOC_URL + "?" + "&".join("%s=%s" % (k, urllib2.quote(v)) for k, v in params.items()) logger.debug('gaode_loc, FULL_URL=%r' % FULL_URL) return HttpRpcClient().fetch_async(url=FULL_URL)
content_type = img.headers.get('Content-Type') logger.debug(u'content_type = %s' % content_type) if content_type.split('/')[0] == 'image': file_type = '1' logger.debug(u'from_user_name=%s, fn=%s', from_user_name, fn) ul = 0 by_app = 0 tk = gen_file_tk(from_user_name, fn, ul, by_app) logger.debug(u'save wechat file. tk = %r' % tk) up_args = { 'tk': tk, 'src': file_type, 'by': from_user_name, 'usage': 'share' } for _ in xrange(3): logger.debug(u'save wechat file. up_url = %s' % (BEIQI_FILE_UP_URL + urllib.urlencode(up_args))) resp = HttpRpcClient().fetch_async(url=BEIQI_FILE_UP_URL + urllib.urlencode(up_args), body=img.body) if resp.code == 200: break if resp.code != 200: logger.error(u'file up resp.code = %r', resp.code) return None logger.debug(u'file up resp.code = %r', resp.code) resp = ujson.loads(resp.body) return fn, tk, resp.get('r')
def get_menu(self): return eval(HttpRpcClient(ssl=True).fetch_async(url=MENU_GET_URL(CltAccessTokenGetter().access_token)))
def create_menu(self, menu): assert menu result = eval(HttpRpcClient(ssl=True).fetch_async(url=MENU_CREATE_URL(CltAccessTokenGetter().access_token), body=menu)) assert result['errcode'] == WXBizMsgCrypt_OK, result logger.warn("MenuManager::create_menu!!!!!!!!!!! new wechat menu:%s" % menu)
def __init__(self, pandora_host, pandora_port): self.pandora_http_client = HttpRpcClient(pandora_host, pandora_port) assert self.pandora_http_client self.connect_dic = {}