def get(self): try: data = self.get_query_args() data = Schema({ 'app_name': schema_utf8, 'platform': schema_utf8, Optional('version', default=0): Use(int), }).validate(data) app_name = data['app_name'] platform = data['platform'] version = data['version'] except (SchemaError, Exception): logging.exception("参数解析出错") self.write_parse_args_failed_response() return utc_now = TimeZone.utc_now() if version == 0: app = Application.objects( app_name=app_name, platform=platform, release_time__lte=utc_now).order_by("-release_time").first() else: app = Application.objects(app_name=app_name, platform=platform, version=version).first() if not app: self.write_not_found_entity_response() return app.update(inc__download_times=1) self.write_response(content=app.link)
def save(self, *args, **kwargs): """ 重写保存 """ # 保存的时候检查有没有leancloud的conversation,没有则创建 if not self.channel_leancloud_id: cl_c = _Conversation() cl_c.set("n", self.name) cl_c.set("sys", True) cl_c.save() self.channel_leancloud_id = cl_c.id else: qs = Query(_Conversation) cl_c = qs.get(self.channel_leancloud_id) if cl_c.get("name") != self.name: cl_c.set("name", self.name) cl_c.save() # 更新 update_time self.update_time = TimeZone.utc_now() super(Channel, self).save(*args, **kwargs)
def get(self): try: data = self.get_query_args() data = Schema({ 'app_name': schema_utf8, 'platform': schema_utf8 }).validate(data) app_name = data['app_name'] platform = data['platform'] except (SchemaError, Exception): logging.exception("参数解析出错") self.write_parse_args_failed_response() return utc_now = TimeZone.utc_now() app = Application.objects( app_name=app_name, platform=platform, release_time__lte=utc_now).order_by("-release_time").first() if not app: self.write_not_found_entity_response() return self.write_response(content=app.format_response())
def update_status(cls, operator_type, expr, operation, operator, current_status=None, **kwargs): """ 更新对象的状态 :param operator_type: 'OUTSIDE'/'INSIDE' :param expr: 运单对象 :param current_status: 当前状态, 如果为None就拿expr的status字段 :param operation: 运单事件类型 :param operator: 运单责任人 :param kwargs: 除去状态, 其他需要修改的信息. 目前支持: var_a: info a var_b: info b :return: (True, expr) 或 (False, error_msg) """ if current_status is None: current_status = expr.status next_state = cls.get_next_state(operator_type, current_status, operation) next_status = next_state['next'] if next_state else None if operator_type == 'INSIDE': # ===> 上帝操作!!! <=== if operation == cls.EVENT_RESET: next_status = cls.STATUS_CREATED_CREATED # ===> 不给钱操作!!! <=== elif operation == cls.EVENT_NO_CASH: next_status = cls.STATUS_FINISHED_NO_CASH # 日志 debug_str = 'expr[%s]: from [%s] to [%s], event[%s].' % ( expr.number, current_status['sub_status'], next_status, operation) logging.info(debug_str) if next_status else logging.warning(debug_str) if next_status: start = time.time() # ==> 更新状态, 修改相关信息 from_status = current_status status, sub_status = next_status.split('.') kwargs['status'] = dict(status=status, sub_status=sub_status) # 过滤掉不需要的字段 kw = Express.filter_expr(kwargs, excludes=('number', 'pkg_id', 'fee', 'watcher', 'assignee')) # 事件发生后, 记录操作人的操作时间: 目前只记录EVENT_SJ, EVENT_QJ, EVENT_TT time_name = ExprState.build_time_name(operator.get("m_type"), operation) now = TimeZone.utc_now() if time_name: kw["times__" + time_name] = now # ==> 判断是否有多余的expr,trace参数要修改 trace_msg = None if next_state and 'do' in next_state: s1 = time.time() kw, trace_msg = next_state['do'](kw, expr=expr, now=now, operator=operator) e1 = time.time() logging.info('@@@: [do] = %s' % datetime.timedelta(seconds=(e1 - s1))) expr.modify(**kw) # ==> 事件记录 msg = kwargs.get('msg', '') fsm_log = dict(number=expr.number, from_status=from_status['sub_status'], to_status=sub_status, event=operation, event_source=expr.third_party.get('name', '') if expr.third_party else '', operator=operator, msg=trace_msg if trace_msg else msg, create_time=now) Trace(**fsm_log).save() # ==> 判断是否要发送短信提醒 if "sms" in next_state: next_state['sms'](expr, msg=msg) end = time.time() logging.info('@@@: [expr] = %s' % datetime.timedelta(seconds=(end - start))) return expr else: raise ValueError('操作失败')
def api_trigger_man_event(operation): """ @api {post} /deliveryman/event 事件 @apiDescription 触发派件员事件, 如果需要, 更新派件员状态和基本信息. @apiName api_trigger_man_event @apiGroup man @apiParam {int} man_id URI中: 派件员工号 @apiParam {str(32)} event URI中: 派件员事件/操作类型, 支持: `ADD_ACCOUNT`, `ADD_FAMILIAR`, `DEL_FAMILIAR`, `COMPLETE_INFO`, `EVENT_RESET` @apiParam {int} [operator_id] 操作人id @apiParam {str(382)} [remark] 操作备注 @apiParamExample {json} 请求url示例: /deliveryman/event @apiParamExample {json} 请求body示例: { "operator_id": 7774123, "remark": "运营拉黑" } @apiSuccessExample {json} 成功示例: HTTP/1.1 200 OK { "status": "CHECK_WORKING" } @apiErrorExample {json} 失败示例: HTTP/1.1 400 ValueError { "message": "State change failed." } @apiErrorExample {json} 失败示例: HTTP/1.1 400 ValueError { "message": "Event[EVENT_CITY_SCORE_APP_YE] should be in EMAP..." } """ operation = str(operation).upper().strip() kw = ctx.request.input() # 添加支付宝账户 if operation == OPERATIONS.ADD_ACCOUNT: # required: id, account{name, id} result = Man.objects(id=kw.man_id).update_one( add_to_set__accounts=dict(name=kw.name, id=kw.id), full_result=True) if result['nModified'] == 0: logging.warning("Account[%s:%s] already added for man=[%s]." % (kw.id, kw.name, kw.man_id)) raise ValueError("帐号重复添加.") # 添加送单区域 elif operation == OPERATIONS.ADD_FAMILIAR: result = Man.objects(id=kw.man_id).update_one( add_to_set__familiars=dict(name=kw.name, city=kw.city, addr=kw.addr, lat=kw.lat, lng=kw.lng), full_result=True) if result['nModified'] == 0: logging.warning("Familiar already added for man=[%s]." % kw.man_id) raise ValueError("送单区域重复添加.") # 移除送单区域 elif operation == OPERATIONS.DEL_FAMILIAR: Man.objects(id=kw.man_id).update_one(pull__familiars=dict( name=kw.name, city=kw.city, addr=kw.addr, lat=kw.lat, lng=kw.lng)) # 添加取货点(限定是区域经理) elif operation == OPERATIONS.ADD_PICKUP: pick_up = dict(name=kw.name, city=kw.city, addr=kw.addr, lat=kw.lat, lng=kw.lng) result = Man.objects(id=kw.man_id).update_one( add_to_set__pick_up_locations=pick_up, full_result=True) if result['nModified'] == 0: logging.warning("Pick-up location %s already added for man=[%s]." % (pick_up, kw.man_id)) raise ValueError("取货点重复添加.") # 移除取货点(限定是区域经理) elif operation == OPERATIONS.DEL_PICKUP: pick_up = dict(name=kw.name, city=kw.city, addr=kw.addr, lat=kw.lat, lng=kw.lng) Man.objects(id=kw.man_id).update_one(pull__pick_up_locations=pick_up) # 完善资料/修改资料(特殊的事件,不单单是改状态,涉及到基本信息修改) elif operation == ManFSM.EVENT_COMPLETE_INFO: # 对完善资料特殊添加时间信息 if 'recommended_by' in kw: kw['recommended_by']['time'] = TimeZone.utc_now() kw.id_card_num = str(kw.id_card_num).strip().upper() man = Man.objects(id_card_num=kw.id_card_num).first() # 该身份证号码已经存在且不是本人 if man and str(man.pk) != str(kw.man_id): logging.warning( "Man[%s][%s] with id_card_num[%s] already exists." % (man.pk, man.name, kw.id_card_num)) raise ValueError("该身份证号码已存在") # 身份证号可用, 根据man_id找到需要更新资料的人. man = Man.objects(id=kw.man_id).first() # 此人存在 if man: operator_type = kw.operator_type kw.pop('operator_type') # 更新参数: name, id_card_num, avatar, id_card_back modified_man = ManFSM.update_status(operator_type, man, ManFSM.EVENT_COMPLETE_INFO, **kw) # 资料更新失败: if not modified_man: logging.warning("Update info for man[%s][%s][%s] failed." % (man.pk, man.name, man.status)) raise ValueError("资料更新失败") return ManLogic.pack_man(modified_man) # 此人不存在 else: logging.warning( "Trying to update a man[%s]'s info that does not exist." % kw.man_id) raise ValueError("资料更新失败") elif operation in ManFSM.APP_EVENTS or operation in ManFSM.FE_EVENTS: # 根据man_id找到需要变更的人. man = Man.objects(id=kw.man_id).first() # 此人存在 if man: operator_type = kw.operator_type kw.pop('operator_type') modified_man = ManFSM.update_status(operator_type, man, operation, **kw) if not modified_man: logging.warning( "State transfer for man[%s][%s][%s] using [%s] failed." % (kw.man_id, man.name, man.status, operation)) raise ValueError("操作失败.") return ManLogic.pack_man(modified_man) else: raise ValueError("OPERATION[%s] should be in %s." % (operation, set(OPERATIONS.keys()).union( ManFSM.FE_EVENTS).union(ManFSM.APP_EVENTS)))
def api_shop_operation(operation): def set_token(inner_who): token = hashlib.md5('%s%s' % (inner_who, utc_8_now())).hexdigest() key = key_shop_token.format(content=token) # 插入token到redis中, 7天有效期: get shop:token:fe11ad907e2fa779ed2f363ef589d3f9 => 7740959 redis_client.setex(key, inner_who, 7 * 24 * 3600) return token operation = str(operation).upper().strip() kw = ctx.request.input() # ==> 商户注册 if operation == OPERATIONS.REGISTER: kw = Schema({ 'tel': schema_unicode, 'sms_code': schema_unicode, 'password': schema_unicode, Optional('name'): schema_unicode, 'contact': { Optional('name', default=''): schema_unicode_empty, Optional('tel', default=''): schema_unicode_empty }, Optional("loc"): { "address": schema_unicode, "longitude": schema_float, "latitude": schema_float, Optional(object): object }, Optional('recommended_by'): { 'tel': schema_unicode_empty }, }).validate(ctx.request.input()) tel = kw['tel'] sms_code = kw['sms_code'] password = kw['password'] # song.123feng.com/APP注册: 手机号+验证码 if tel: sms_key = key_sms_code.format(tel=tel) # 验证成功: 验证码匹配 get sms:code:15901739717 => 123456 sms_code_in_redis = redis_client.get(sms_key) if sms_code_in_redis == sms_code: shop = Shop.objects(tel=tel).first() if not shop: # 记录商户到mongodb(如无记录): status=STATUS_VALID # 记录商户到mongodb(如无记录): status=STATUS_INFO_YES if 'recommended_by' in kw: kw['recommended_by']['time'] = TimeZone.utc_now() kw_filtered = ShopLogic.filter_shop(kw) shop = Shop(**kw_filtered).save() # ===== 注册风信账户 ===== http_client = HTTPClient() http_client.fetch(account.req_create( account_type=conf.ACCOUNT_TYPE_SHOP, account_id=str(shop.pk)), raise_error=False) else: # 允许重复注册, 改一下密码 shop.password = password shop.save() shop.reload() shop_id = str(shop.pk) content = set_token(shop_id) s_packed = ShopLogic.pack_shop(shop) s_packed.update(dict(token=content)) return s_packed # 登录失败 else: logging.info( "SMS code validation for [%s]=[%s] failed, expected[%s]." % (tel, sms_code, sms_code_in_redis)) raise ValueError("验证码验证失败.") # ==> 商户事件 elif operation in ShopFSM.FE_INSIDE_EVENTS or operation in ShopFSM.OUTSIDE_EVENTS: # 对完善资料特殊添加时间信息 if operation == ShopFSM.EVENT_COMPLETE_INFO and 'recommended_by' in kw: kw['recommended_by']['time'] = TimeZone.utc_now() # 对修改定价特殊处理: 能用tel找商户id if operation == ShopFSM.EVENT_ALTER_INFO: shop = Shop.objects(tel=kw.tel).first() # 其他事件一概用shop_id else: shop = Shop.objects(id=kw.shop_id).first() if shop: operator_type = kw.operator_type kw.pop('operator_type') modified_shop = ShopFSM.update_status(operator_type, shop, operation, **kw) if not modified_shop: raise ValueError( "State transfer for shop[%s][%s][%s] using [%s] failed." % (kw.shop_id, shop.name, shop.status, operation)) return ShopLogic.pack_shop(modified_shop) else: pass
data=urllib.parse.urlencode(params), headers=headers, timeout=5) except Exception as e: print((traceback.format_exc())) return False, {'error': str(e)} response = r.json() if "response_params" in response: return True, {} else: return False, response if __name__ == '__main__': from tools_lib.common_util.archived.gtz import TimeZone msg = { "source": "deliver", "type": "force_deliver_notice", "content": { "title": "测试", "body": "同志们好,首长好", "create_time": TimeZone.datetime_to_str(TimeZone.utc_now()), } } print((baidu_push_v3('3737072413124982526', msg, device_type=PLATFORM_ANDROID)))
def get(self): now = TimeZone.utc_now() self.write_response(content=TimeZone.datetime_to_str(now))
def shop_reward(): logging.info("invitation shop reward start...") man_conn = mongodb_client['profile']['man'] shop_conn = mongodb_client['profile']['shop'] express = mongodb_client['aeolus']['express'] now = TimeZone.utc_now() local = TimeZone.local_now() cursor = shop_conn.find({ "recommended_by.tel": { "$exists": True }, "recommended_by.time": { "$gt": TimeZone.decrement_months(now, 2) } }) m_type = "shop_invitation" for doc in cursor: man = man_conn.find_one({"tel": doc['recommended_by']['tel']}) if not man: logging.warning("no man tel:%s", doc['recommended_by']['tel']) continue shop_id = str(doc['_id']) shop_name = utf8(doc.get("name", "新客户")) man = format_man(man, 'parttime') invite_time = TimeZone.naive_to_aware(doc['recommended_by']['time'], pytz.utc) # 拿出这个人对应商户所有的奖励, 用来计算已经奖励了多少钱 reward_list = Rewards.objects(man__id=man['id'], source__shop_id=shop_id, m_type=m_type) # 计算还剩多少可以奖励 count = 0 for r in reward_list: count += r.money count = int(count) left = 100 - count # 如果没剩了, 不能再奖励了 if left <= 0: continue # 计算最近一次需要计算的日期, try: reward = reward_list[0] start_date = TimeZone.utc_to_local( TimeZone.increment_days(reward.create_time, 1)).date() except IndexError: start_date = TimeZone.utc_to_local(invite_time).date() # 最多计算到昨天 end_date = local.date() # 从开始日期开始到昨天都需要计算 for day in TimeZone.date_xrange(start_date, end_date): start_time, end_time = TimeZone.day_range(value=day) # 限制一下start_time start_time = start_time if start_time > invite_time else invite_time _count = express.find({ "creator.id": shop_id, "times.sj_time": { "$gte": start_time, "$lte": end_time }, }).count() if _count == 0: continue c = _count if _count < left else left money = c * 1.0 # 先将时间加上本地tzinfo, 然后再转换时区, 直接指定tzinfo会出错, 差6分钟, 故意躲加1小时 create_time = TimeZone.datetime_to_utc( TimeZone.naive_to_aware( datetime(day.year, day.month, day.day, 1))) Rewards(m_type=m_type, title="邀请客户", desc="%s当日下单%s单" % (shop_name, c), man=man, money=money, source={ "shop_id": shop_id, "shop_name": shop_name }, create_time=create_time).save() logging.info( "reward: m_type[%s], date[%s], man[%s], shop_id[%s], money[%s]", m_type, day, man['id'], shop_id, money) left -= c if left <= 0: break