def expire_at_today(self, key, hour=0): from tools_lib.common_util.archived.gtz import TimeZone tomorrow = TimeZone.increment_days(TimeZone.local_now()) self.expireat( key, TimeZone.increment_hours( TimeZone.transfer_datetime_to_beginning(tomorrow), hour))
def expire_at_this_end_of_month(self, key): # 本月月底过期 from tools_lib.common_util.archived.gtz import TimeZone local_now = TimeZone.local_now() end_of_this_month = TimeZone.utc_to_local( TimeZone.month_range(local_now.year, local_now.month)[1]) self.expireat(key, end_of_this_month) self.delete()
def redirect_song_export_express(creator_id, start_time, end_time): """ [HTTPRequest]SONG导出运单信息 :param creator: 下单者id,商户id :param start_time: 起始时间 :param end_time: 终止时间 """ url = settings.BL_DAS_API_PREFIX + "/express/export/song" url = url_concat( url, { "shop_id": creator_id, "start_time": TimeZone.datetime_to_str(start_time), "end_time": TimeZone.datetime_to_str(end_time) }) return HTTPRequest(url, method="GET", **timeouts)
def get(self): """ 导出运单 """ try: data = self.get_query_args() creator_id = data["shop_id"] start_time = TimeZone.str_to_datetime(data["start_time"]) end_time = TimeZone.str_to_datetime(data["end_time"]) except: self.resp_error("参数错误") return yield self.resp_redirect( express.redirect_song_export_express(creator_id, start_time=start_time, end_time=end_time))
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 sign_in(): sign_in = client['profile']['sign_in'] start, end = TimeZone.day_range(value=TimeZone.local_now()) pprint( "姓名", "电话", "时间", "地址", "POI", "经度", "维度", ) for doc in sign_in.find({"create_time": {"$gte": start, "$lte": end}}): pprint(doc['name'], doc['tel'], TimeZone.utc_to_local(doc['create_time']), doc['loc']['addr'], doc['loc']['name'], doc['loc']['lng'], doc['loc']['lat'])
def schedule(self, scheduled_time): """ 定时发送 :param scheduled_time: :return: schedule token for cancelling """ json_data = { "type": conf.MQ_TYPE_SCHEDULE, "scheduled_time": TimeZone.datetime_to_str(scheduled_time), "data": self } return self._send(json.dumps(json_data))
def get_zj_statistics(start_date, end_date): url = IP_PORT_API + "/shop/flow/complex_query" query = { "filter_col": ["shop_id", "type", "sum(cash) as total", "create_time"], "query": { "op": "AND", "exprs": [{ "create_time": { ">=": TimeZone.date_to_str(start_date), "<": TimeZone.date_to_str(end_date) } }, { "type": { "in": ["TOP_UP", "PAY"] } }, { "is_not": 1, "shop_name": { "like": "%测试%" } }] }, "group_by": "shop_id,type", "count": 3000 } resp = requests.post(url, json=query) if resp.status_code != 200: return 0, 0 top_up = 0 pay = 0 for item in resp.json(): if item['type'] == "PAY": pay += float(item['total']) elif item['type'] == "TOP_UP": top_up += float(item['total']) return top_up, pay
def modify_sj_time(expr_cursor): i = 0 for doc in expr_cursor: i += 1 times = [] _times = [] for k, t in list(doc['times'].items()): if k != 'sj_time': times.append(t) times = sorted(times) for t in times: _times.append(TimeZone.datetime_to_str(t, pattern='%H:%M')) sj_time = min(times) result = mc.update_one({'_id': doc['_id']}, {'$set': { 'times.sj_time': sj_time }}) print(('%s, %s, min%s => [%s], %s, %s' % (i, doc['number'], _times, TimeZone.datetime_to_str(sj_time, pattern='%H:%M'), result.matched_count, result.modified_count)))
def api_deliveryman_sign_in(): """ 派件系人员签到 :param man_id: 根据 id 查出 name, tel, avatar :param loc: {name, addr, lng, lat} :param device: {mac_id, ...} :return: 失败返回400和message """ params = ctx.request.input() # ==> 根据id拿基本信息 man = Man.objects(id=params.man_id).first() # ==> 检查今日签到次数 now = TimeZone.local_now() start_time, _end_time = TimeZone.day_range(value=now) start_time = TimeZone.datetime_to_str(start_time) sign_in_count = SignIn.objects(**{ 'man_id': params.man_id, 'create_time__gte': start_time }).count() if sign_in_count >= 50: logging.warn("Man[%s][%s] try to sign in over 10 times." % (params.man_id, man.name)) raise ValueError("一天最多签到10次") # ==> 记录这次签到 name = man.name if man.name else '' avatar = man.avatar if man.avatar else '' SignIn(man_id=params.man_id, name=name, tel=man.tel, avatar=avatar, loc=params.loc, device=params.device, create_time=now).save(force_insert=True) return { 'create_time': TimeZone.datetime_to_str(now, pattern='%Y-%m-%dT%H:%M:%S') }
def format_response(self): return { "cli": self.channel_leancloud_id, "name": self.name, "description": self.description, "icon": get_image_url(self.icon), "sticky": self.sticky, "top": self.top, "talkable": self.talkable, "disabled": self.disabled, "manager": self.manager, "answerer": self.answerer, "subscriber_condition": self.subscriber_condition, "create_time": TimeZone.datetime_to_str(self.create_time) }
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 get(self): # 商户名,商户注册电话,余额,当日消费,当日10:00前下单,当日10:00~14:00下单,当日14:00之后下单,当日待取件,总计待妥投 try: data = Schema({ "date": schema_date, }).validate(self.get_query_args()) date = data['date'] except SchemaError: self.resp_error('参数[date]解析失败') return middle = {} # 1. 商户名,商户注册电话,当日消费,当日10:00前下单,当日10:00~14:00下单,当日14:00之后下单 start_time, end_time = TimeZone.day_range(value=date) pipeline = [ # 取今天的所有有效运单 { "$match": { "create_time": { "$gt": start_time, "$lt": end_time }, "status.sub_status": {"$ne": ExprState.SUB_STATUS_CANCEL} } }, # 按照[商户,小时]分组 { "$group": { "_id": { "creator_id": "$creator.id", "hour": {"$hour": {"$add": ['$create_time', 28800000]}}, }, "tel": {"$first": "$creator.tel"}, "name": {"$first": "$creator.name"}, "expr_count": {"$sum": 1}, # 暂时除了pre_created的运单才算是消费了 "expense": {"$sum": {"$cond": [{"$ne": ["$status.status", "PRE_CREATED"]}, "$fee.fh", 0]}} } }, # 根据[商户,小时]分组计算10:00前,10:00~14:00,14:00后下单数量 { "$group": { "_id": { "creator_id": "$_id.creator_id", }, "tel": {"$first": "$tel"}, "name": {"$first": "$name"}, "expense": {"$sum": "$expense"}, "count_before_10am": {"$sum": {"$cond": [{"$lt": ["$_id.hour", 10]}, "$expr_count", 0]}}, "count_10am_to_2pm": {"$sum": { "$cond": [{"$and": [{"$gte": ["$_id.hour", 10]}, {"$lt": ["$_id.hour", 14]}]}, "$expr_count", 0]}}, "count_after_2pm": {"$sum": {"$cond": [{"$gte": ["$_id.hour", 14]}, "$expr_count", 0]}}, "count_all": {"$sum": "$expr_count"} } }, { "$sort": { "count_all": -1, } } ] result = yield self.async_fetch(redirect_aggregation(pipeline=pipeline)) content = result.content # 从这里拿到所有的商户id creator_ids = [] for c in content: creator_id = c['_id']['creator_id'] tel = c['tel'] name = c['name'] expense = c['expense'] # 10点之前下单数量 count0 = c['count_before_10am'] # 10-14点下单数量 count1 = c['count_10am_to_2pm'] # 14点之后下单数量 count2 = c['count_after_2pm'] # 当日总计下单量 _count_all = c['count_all'] # print("[%s] %s+%s+%s=%s 消費:%s" % (name, count0, count1, count2, _count_all, expense)) creator_ids.append(creator_id) middle[creator_id] = dict(name=name, tel=tel, expense=expense, count_before_10am=count0, count_10am_to_2pm=count1, count_after_2pm=count2, count_all=_count_all) # 2. 当日待取件, 当日待妥投 pipeline = [ # 取今天在<creator_ids>里面的所有运单 { "$match": { "create_time": { "$gt": start_time, "$lt": end_time }, "creator.id": { "$in": creator_ids } } }, # 按照[商户,状态条件]分组 { "$group": { "_id": { "creator_id": "$creator.id", }, "count_created": {"$sum": {"$cond": [{"$eq": ["$status.status", "PRE_CREATED"]}, 1, 0]}}, "count_sending": {"$sum": {"$cond": [{"$eq": ["$status.status", "SENDING"]}, 1, 0]}}, "count_all": {"$sum": 1} } }, { "$sort": { "count_all": -1, } } ] result = yield self.async_fetch(redirect_aggregation(pipeline=pipeline)) for c in result.content: creator_id = c['_id']['creator_id'] # 待取貨 count0 = c['count_created'] # 派件中 count1 = c['count_sending'] # 当日总计下单量 _count_all = c['count_all'] # print("[%s] 待取貨:%s 派件中:%s 總計:%s" % (name, count0, count1, _count_all)) middle[creator_id]['count_created'] = count0 middle[creator_id]['count_sending'] = count1 # 3. 拿余额 balances = yield multi_shop_balance(creator_ids) # 4. 拼结果 fin = [] for cid in creator_ids: middle[cid]['id'] = cid middle[cid]['balance'] = balances[cid] fin.append(middle[cid]) self.resp(fin)
def api_retrieve_man_info(what): what = str(what).upper().strip() request = ctx.request.input() # 如果传入what,by不是允许的值,直接报错 if what not in WHATS: raise ValueError("WHAT[%s] should be in WHATS%s." % (what, list(WHATS.keys()))) params = set([str(k).lower().strip() for k in request]) bys = set(BYS.keys()) by = params.intersection(bys) if not by: raise ValueError("BY%s should be in BYS%s." % (list(params), list(bys))) by_key = next(iter(by)) by_val = request[by_key] if by_key == 'id' and by_val and len(by_val) != 24: raise ValueError('find man with id=%s, id should be of length 24.' % by_val) # 判断是要什么类型的返回 if what == WHATS.BASIC: excludes = ('accounts', 'create_time', 'my_man') man = Man.objects(**{by_key: by_val}).exclude(*excludes).first() if not man: raise ValueError("Can't find man with[%s]=[%s]." % (by_key, by_val)) packed = ManLogic.pack_man(man, excludes=excludes) ret_cnt = ('familiars', 'pick_up_locations') for k in ret_cnt: if k in packed: packed[k] = len(packed[k]) if packed[k] else 0 return packed elif what == WHATS.ACCOUNT_LIST: man = Man.objects(**{by_key: by_val}).only('accounts').first() return man.accounts elif what == WHATS.FAMILIAR_LIST: man = Man.objects(**{by_key: by_val}).only('familiars').first() return man.familiars elif what == WHATS.STATUS: man = Man.objects(**{by_key: by_val}).only('status').first() return man.status elif what == WHATS.MAN_LIST: man = Man.objects(**{by_key: by_val}).only('my_man').first() if man and man.my_man: only = ('status', 'id', 'name', 'tel', 'avatar') my_man = {m['id']: m['bind_time'] for m in man.my_man} mans = Man.objects(id__in=list(my_man.keys())).only(*only) ret = [] for m in mans: packed_man = ManLogic.pack_man(m, only=only) packed_man['bind_time'] = my_man[str(m.pk)] ret.append(packed_man) return ret else: return [] elif what == WHATS.CODE: # 取header里面的app-name, 没给的话就给man app_name = ctx.request.header('app-name', 'man') man_id = by_val code = shortuuid.ShortUUID().random(length=8) # role是区域经理app端header里面的app-name key = key_man_code.format(role=app_name, content=code) # 存放: 二维码(360秒): get <app-name>:code:fe11ad907e2fa779ed2f363ef589d3f9 => 56f1028b2d50c07c80914393 redis_client.setex(key, man_id, 360) logging.info('Setting Code [%s] => [%s].' % (key, man_id)) return key elif what == WHATS.PICKUP_LIST: man = Man.objects(**{by_key: by_val}).only('pick_up_locations').first() return man.pick_up_locations elif what == WHATS.SIGN_IN_COUNT: # 获取人员名字 man = Man.objects(id=by_val).only('name').first() name = man.name if man.name else '' # 获取今天凌晨以后的签到记录次数 now = TimeZone.local_now() start_time, _end_time = TimeZone.day_range(value=now) start_time = TimeZone.datetime_to_str(start_time) sign_in_count = SignIn.objects(**{ by_key: by_val, 'create_time__gte': start_time }).count() return dict(name=name, sign_in_count=sign_in_count, server_time=TimeZone.datetime_to_str( now, pattern='%Y-%m-%dT%H:%M:%S'))
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('操作失败')
for data_record in data: try: baidu_push_v3(channel_id=data_record['channel_id'], msg=json.dumps(data_record.get('msg', ''), ensure_ascii=False), device_type=PLATFORM_ANDROID) except: pass except: print((traceback.format_exc())) finally: pass if __name__ == '__main__': print(('[{current_time}] starting server ...'.format( current_time=TimeZone.local_now()))) connection = pika.BlockingConnection( pika.ConnectionParameters(host='localhost')) channel = connection.channel() channel.exchange_declare(exchange=EXCHANGE_PUSH_MSG, type=TYPE_FANOUT) result = channel.queue_declare(exclusive=True) queue_name = result.method.queue channel.queue_bind(exchange=EXCHANGE_PUSH_MSG, queue=queue_name) channel.basic_consume(callback, queue=queue_name, no_ack=True) channel.start_consuming()
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 op_data(): logging.info("op_data start...") man_conn = mongodb_client['profile']['man'] shop_conn = mongodb_client['profile']['shop'] express = mongodb_client['aeolus']['express'] opdata = OpData.objects.order_by("-create_time").first() start_date = date(2016, 5, 20) if opdata: start_date = TimeZone.increment_days( TimeZone.utc_to_local(opdata.create_time), 1).date() end_date = TimeZone.local_now().date() for day in TimeZone.date_xrange(start_date, end_date): start_time, end_time = TimeZone.day_range(value=day) logging.info("op data %s", day) data = {} # ============= 资金 ============== data['zj_top_up'], data['zj_pay'] = get_zj_statistics( day, TimeZone.increment_days(day)) # ============= 订单 ============== data['dd_count'] = express.find({ "create_time": { "$gte": start_time, "$lte": end_time } }).count() data['dd_sj_count'] = express.find({ "times.zj_time": { "$gte": start_time, "$lte": end_time } }).count() data['dd_tt_count'] = express.find({ "times.parttime_tt_time": { "$gte": start_time, "$lte": end_time } }).count() data['dd_error_count'] = express.find({ "times.yc_time": { "$gte": start_time, "$lte": end_time } }).count() # ============= 客户 ============== data['sh_register'] = shop_conn.find({ "create_time": { "$gte": start_time, "$lte": end_time } }).count() data['sh_order'] = 0 result = express.aggregate([{ "$match": { "create_time": { "$gte": start_time, "$lte": end_time } } }, { "$group": { "_id": "$creator.id", } }, { "$group": { "_id": "sum", "count": { "$sum": 1 } } }]) for doc in result: data['sh_order'] += doc['count'] # ============== 人力 =============== data['hr_on_job'] = man_conn.find({ "job_description": "parttime", "status": "STATUS_WORKING" }).count() data['hr_active'] = 0 # 在规定时间内收件的人 result = express.aggregate([{ "$match": { "times.sj_time": { "$gte": start_time, "$lte": end_time } } }, { "$project": { "man": { "$arrayElemAt": ["$watchers", 0] } } }, { "$group": { "_id": "$man.id" } }]) active_list = [_['_id'] for _ in result] result = express.aggregate([{ "$match": { "times.parttime_tt_time": { "$gte": start_time, "$lte": end_time } } }, { "$group": { "_id": "$assignee.id", } }]) # 在规定时间内妥投的人 active_list2 = [_['_id'] for _ in result] temp = set(active_list + active_list2) data['hr_active'] = len(temp) # 司机出勤 man_list = man_conn.find({"tel": {"$in": driver_list}}) node_conn = psycopg2.connect(cursor_factory=psycopg2.extras.DictCursor, database="tlbs", **CONFIG_POSTGRESQL) cursor = node_conn.cursor() data['cl_depart'] = 0 man_id_list = [str(_['_id']) for _ in man_list] for man_id in man_id_list: local = arrow.get(day, "local") cursor.execute( """SELECT count(*) from trans.bs_trans_deliver_sign_record where deliver_id = %s and create_time >= %s and create_time <= %s """, (man_id, local.floor("day").strftime(TIME_PATTERN), local.ceil("day").strftime(TIME_PATTERN))) doc = cursor.fetchone() if doc and int(doc[0]) > 0: data['cl_depart'] += 1 cursor.execute( """ SELECT count(*) FROM trans.bs_trans_bind_node_info WHERE deliver_id = ANY(%s) """, (man_id_list, )) doc = cursor.fetchone() if not doc: data['cl_shift'] = 0 else: data['cl_shift'] = int(doc[0]) # ======================================= create_time = TimeZone.datetime_to_utc( TimeZone.naive_to_aware(datetime(day.year, day.month, day.day, 1))) data["create_time"] = create_time OpData(**data).save() logging.info("op_data end...")
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
if k != 'sj_time': times.append(t) times = sorted(times) for t in times: _times.append(TimeZone.datetime_to_str(t, pattern='%H:%M')) sj_time = min(times) result = mc.update_one({'_id': doc['_id']}, {'$set': { 'times.sj_time': sj_time }}) print(('%s, %s, min%s => [%s], %s, %s' % (i, doc['number'], _times, TimeZone.datetime_to_str(sj_time, pattern='%H:%M'), result.matched_count, result.modified_count))) if __name__ == '__main__': pool = Pool(4) cursor = mc.find({ 'times.sj_time': { '$exists': True }, 'create_time': { '$gte': TimeZone.str_to_datetime("2016-05-01T00:00:00.000+0800") } }) modify_sj_time(expr_cursor=cursor) # pool.map(modify_sj_time, [cursor])
def get(self): now = TimeZone.utc_now() self.write_response(content=TimeZone.datetime_to_str(now))
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): """ @api {get} /express/yun/op_data 风云 - 运营数据 @apiName yun_op_data @apiGroup app_fe @apiVersion 0.0.1 @apiParam (query param) {string} date 一个月中的某一天 @apiSuccessExample 成功返回示例 HTTP/1.1 200 OK [ { "hr_break": 0, "zj_pay": 0, "create_time": "2016-05-19T17:00:00Z", "cl_shift": 0, "dd_error_count": 1, "sh_valid": 0, "hr_invite": 0, "sh_register": 0, "sh_order": 0, "zj_cash_back": 0, "dd_count": 0, "hr_interview": 0, "zj_top_up": 0, "sh_complain": 0, "hr_consulting": 0, "hr_entry": 0, "hr_active": 0, "dd_tt_count": 0, "hr_leave": 0, "cl_late": 0, "dd_sj_count": 0, "hr_on_job": 2, "cl_depart": 0, "sh_visit": 0 }, ... ] @apiUse bad_response """ try: data = Schema({ "date": schema_date }).validate(self.get_query_args()) except: self.resp_args_error() return start, end = TimeZone.month_range(value=data['date']) query = { "create_time__gte": start, "create_time__lte": end, "excludes": ["id"] } resp = yield self.async_fetch(bl_data.redirect_op_data_search(query)) content = resp.content total = dict() for _ in content: for (k, v) in list(_.items()): if k in total: total[k] += v else: total[k] = v total['create_time'] = "总计" content.insert(0, total) self.resp(content=content)