def transform_file_path(cls, raw: object, include_data: bool = False) -> dict: """ 把一个实例或者doc对象的转化为适合前端呈现的格式,包括: 1. 全部是都是字符串和数字 2. files部分转化为合适的路径. 这个函数一般在返回数据给前端的时候调用. :param raw: 实例/doc :param include_data: 是否在返回对象中包含数据? 默认不包含数据只包含url_path :return: 符合1.2要求的字典 """ if isinstance(raw, cls): raw = raw.get_dict() files = raw.pop("files", list()) if len(files) == 0: r = list() else: r = list() for file in files: f = {"_id": file.id} d = AccidentData.find_one_cls(filter_dict=f) temp = AccidentData.transform(d, include_data=include_data) r.append(temp) raw = mongo_db.to_flat_dict(raw) raw['files'] = r return raw
def page(cls, _id: str = None, begin_date: (str, datetime.datetime) = None, end_date: (str, datetime.datetime) = None, index: int = 1, num: int = 20, can_json: bool = True, reverse: bool = True) -> dict: """ 分页注册客户记录 :param _id: 客户id,为空表示所有 :param begin_date: 开始时间 :param end_date: 截至时间 :param index: 页码 :param can_json: 是否进行can json转换 :param num: 每页多少条记录 :param reverse: 是否倒序排列? :return: 事件记录的列表和统计组成的dict """ filter_dict = dict() if _id is not None: filter_dict['_id'] = mongo_db.get_obj_id(_id) end_date = datetime.datetime.now() if mongo_db.get_datetime_from_str(end_date) is None else \ mongo_db.get_datetime_from_str(end_date) begin_date = mongo_db.get_datetime_from_str("2010-1-1 0:0:0") if \ mongo_db.get_datetime_from_str(begin_date) is None else mongo_db.get_datetime_from_str(begin_date) filter_dict['time'] = {"$lte": end_date, "$gte": begin_date} index = 1 if index is None else index skip = (index - 1) * num sort_dict = {"time": -1 if reverse else 1} count = cls.count(filter_dict=filter_dict) res = cls.find_plus(filter_dict=filter_dict, sort_dict=sort_dict, skip=skip, limit=num, to_dict=True) if can_json: res = [mongo_db.to_flat_dict(x) for x in res] data = {"count": count, "data": res} return data
def encode(cls, payload: dict, secret: str = None, algorithm: str = "HS256") -> (bytes, None): """ 加密.注意返回的类型是bytes. :param payload: 需要加密的对象,必须是字典类型,字段都是可json序列化的数字或者字符串 :param secret: 签名 :param algorithm: 加密算法 :return: bytes """ if isinstance(payload, dict): algorithm_list = [ "HS256", "HS384", "HS512", "ES256", "ES384", "ES512", "RS256", "RS384", "RS512", "PS256", "PS384", "PS512" ] secret = secret if secret is not None else cls.get_signature().get("signature") print({"signature": secret}) if algorithm not in algorithm_list: ms = "不支持的算法:{}".format(algorithm) raise ValueError(ms) else: payload = mongo_db.to_flat_dict(payload) res = None try: res = jwt.encode(payload=payload, key=secret, algorithm=algorithm) except Exception as e: print(e) logger.exception(e) finally: return res else: ms = "待加密对象必须是dict类型" raise TypeError(ms)
def login(cls, user_name: str, user_password: str, can_json: bool = False) -> dict: """ 公司用户的登录 :param user_name: :param user_password: :param can_json: :return: """ mes = {"message": "success"} f = {"user_name": user_name} projection = [ '_id', 'user_name', 'user_password', 'full_name', 'short_name', 'desc' ] one = cls.find_one_plus(filter_dict=f, projection=projection, instance=False) if one: pw = one.get('user_password', "") if isinstance(user_password, str) and user_password.lower() == pw.lower(): one.pop("user_password", "") one = mongo_db.to_flat_dict(one) if can_json else one mes['data'] = one else: mes['message'] = "密码错误" else: mes['message'] = "用户名不存在" return mes
def gps_push(user_id): """接收设备发来的实时gps信息""" args = get_args(request) log_type = "data_view.gps_push" info_dict = args.copy() message = {"message": "success"} token = '' try: token = args.pop('auth_token') except KeyError as e: pass finally: pass # calculated_user_id = AppLoginToken.get_id_by_token(token) if user_id: args['user_id'] = DBRef(collection="user_info", database="platform_db", id=user_id) info_dict = args.copy() info_dict['result'] = 'before begin' info_dict['result'] = 'unknown error' """发送给socketio服务器""" celery_module.send_last_pio_celery.delay(to_flat_dict(args)) try: args['real_time'] = 1 result = item_module.GPS.insert_queue(args) if result: info_dict['result'] = 'success' else: message = error_module.pack_message(message, 3004, **args) except ValueError as e: logger.exception("Error: ") error_col, error_val = e.args[0].split(" ")[-1].split(":") message = error_module.pack_message(message, 6001, **args) message['message'] = "{}的值 {} 重复".format(error_col, error_val) info_dict['result'] = message['message'] except Exception as e: logger.exception("Error: {}".format(e), exc_info=True, stack_info=True) print(e) message = error_module.pack_message(message, 5000, **args) info_dict['result'] = str(e) finally: return json.dumps(message) else: message = pack_message(message, 3009, auth_token=token, user_id=args.get('user_id')) info_dict['result'] = message['message'] return json.dumps(message)
def send_io_message(cls, init_list: list, event: str, io: SocketIO) -> None: """ 使用socketio,向所有的客户端发送报价. :param init_list: 类初始化字典的数组(报价是一批一批来的) :param event: 事件名 :param io: socketio实例 :return: """ mes = [ mongo_db.to_flat_dict(transform_product(x)) for x in init_list if transform_product(x) is not None ] data = json.dumps(mes) io.emit(event=event, data=data)
def page(cls, driver_name: str = None, status: int = None, plate_number: str = None, city: str = None, begin_date: datetime.datetime = None, end_date: datetime.datetime = None, index: int = 1, num: int = 20, can_json: bool = True, reverse: bool = True) -> dict: """ 分页查询行车记录 :param driver_name: 司机真实姓名,为空表示所有司机 :param status: int 处理状态 0未处理,1已处理 :param plate_number: 车牌 :param city: 城市 :param begin_date: 开始时间 :param end_date: 截至时间 :param index: 页码 :param can_json: 是否进行can json转换 :param num: 每页多少条记录 :param reverse: 是否倒序排列? :return: 事件记录的列表和统计组成的dict """ filter_dict = dict() if driver_name is not None: filter_dict['driver_name'] = driver_name if status is not None: filter_dict['status'] = status if plate_number is not None: filter_dict['plate_number'] = plate_number if city is not None: filter_dict['city'] = city filter_dict['time'] = {"$lte": end_date, "$gte": begin_date} skip = (index - 1) * num sort_dict = {"time": -1 if reverse else 1} count = cls.count(filter_dict=filter_dict) res = cls.find_plus(filter_dict=filter_dict, sort_dict=sort_dict, skip=skip, limit=num, to_dict=True) if can_json: res = [mongo_db.to_flat_dict(x) for x in res] data = {"count": count, "data": res} return data
def get_online_report(): """获取在线报告""" ses = get_conn("gps_info") now = datetime.datetime.now() year = now.year month = now.month begin = get_datetime_from_str("{}-{}-1 0:0:0".format(year, month)) # begin = now - datetime.timedelta(days=30) query = {"time": {"$gte": begin}} s = {"time": -1} out = "online_report_result" # 保存数据的表,每次map_reduce都会提前清空这个表 map_func = Code(""" function(){ emit(this.user_id.$id, 1); } """) reduce_func = Code(""" function(key, values){ return Array.sum(values); } """) result_conn = ses.map_reduce(map=map_func, reduce=reduce_func, query=query, sort=s, out=out, full_response=False) res = result_conn.find(filter=dict()) count_dict = {x['_id']: int(x['value']) for x in res} ids = list(count_dict.keys()) ses = get_conn("user_info") f = {"_id": {"$in": ids}} s = [("last_update", -1)] users = ses.find(filter=f, sort=s) res = list() for user in users: user_id = user['_id'] temp = to_flat_dict(user) temp['count'] = count_dict[user_id] res.append(temp) res.sort(key=lambda obj: obj['count'], reverse=True) return res
def trade_history(cls, t_id: ObjectId, filter_dict: dict, page_size: int = 50, can_json: bool = False) -> list: """ 分页查询喊单历史(已离场的) :param t_id: 老师id :param filter_dict: 查询条件字典, :param page_size: 一页有多少条记录? :param can_json: :return: """ filter_dict["teacher_id"] = t_id filter_dict["case_type"] = "exit" sort_list = [("exit_time", -1)] projection = [ '_id', 'exit_time', 'product', 'direction', 'enter_price', 'exit_price', 'lots', 'each_profit' ] ses = mongo_db.get_conn(table_name="trade") args = { "filter": filter_dict, "sort": sort_list, # 可能是None,但是没问题. "projection": projection, "limit": page_size } args = {k: v for k, v in args.items() if v is not None} """开始查询页面""" res = list() r = ses.find(**args) if r is None: pass else: if r.count() > 0: if can_json: res = [mongo_db.to_flat_dict(x) for x in r] else: res = [x for x in r] else: pass return res
def __get_signature(cls, return_type: str = "dict") -> (object, dict): """ 获取全局加密的数字签名,这是个内部方法,除了类本身外,不应该被其他对象调用. :param return_type: 返回的类型.可以选3个值object/dict/can_json,分表代表返回 实例/字典/可json序列化的字典 :return: 取决于return_type参数. """ """目前没有过期时间""" f = dict() s = [("time", -1)] one = cls.find_one(filter_dict=f, sort=s) """表为空或者没有有效的signature,重新生成一个signature""" if one is None: one = cls.__add_signature() else: pass if return_type == "object": one = cls(**one) elif return_type == "can_json": one = mongo_db.to_flat_dict(one) else: pass return one
def __get_signature(cls, return_type: str = "dict") -> (object, dict): """ 获取全局加密的数字签名,这是个内部方法,除了类本身外,不应该被其他对象调用. :param return_type: 返回的类型.可以选3个值object/dict/can_json,分表代表返回 实例/字典/可json序列化的字典 :return: 取决于return_type参数. """ f = dict() now = datetime.datetime.now() f['time'] = {"$gte": now - datetime.timedelta(seconds=6900)} s = {"time": -1} one = cls.find_one_plus(filter_dict=f, sort_dict=s, instance=False) """表为空或者没有有效的signature,重新生成一个signature""" if one is None: one = cls.__add_signature() else: pass if return_type == "object": one = cls(**one) elif return_type == "can_json": one = mongo_db.to_flat_dict(one) else: pass return one
def find_chart_info(cls, year: int, month: int) -> dict: """ 查询月活记录数据 :param year: :param month: :return: """ f = {"year": year, "month": month} one = cls.find_one_plus(filter_dict=f, instance=False) flag = False # 是否需要生成数据的标志位 if one is None: flag = True else: now = datetime.datetime.now() update_time = one['update_time'] if update_time.year == now.year and update_time.month == now.month and ( now - update_time).total_seconds() > 3600: """是本月的数据,并且更新时间已经是一月之前了,那就重新生成一个""" flag = True else: pass if flag: """生成一个""" d = get_online_report_by_map_reduce(year=year, month=month) d['year'] = year d['month'] = month if "update_time" not in d: d['update_time'] = datetime.datetime.now() r = cls.find_one_and_update_plus(filter_dict=f, update_dict={"$set": d}, upsert=True) print(r) res = d else: res = one return to_flat_dict(res)
def page(cls, driver_id: ObjectId = None, writer: (str, ObjectId, DBRef) = None, status: int = None, plate_number: str = None, city: str = None, begin_date: datetime.datetime = None, end_date: datetime.datetime = None, index: int = 1, num: int = 20, can_json: bool = True, reverse: bool = True) -> dict: """ 分页查询行车记录 :param driver_id: 司机id,为空表示所有司机,注意这里为了和违章记录保持一致,是ObjectId对象而不是常见的DBRef :param writer: 录入者id,默认指向user_info的_id :param status: int 处理状态 0未处理,1已处理, -1和None表示不做筛选 :param plate_number: 车牌 :param city: 城市 :param begin_date: 开始时间 :param end_date: 截至时间 :param index: 页码 :param can_json: 是否进行can json转换 :param num: 每页多少条记录 :param reverse: 是否倒序排列? :return: 事件记录的列表和统计组成的dict """ filter_dict = dict() if driver_id is not None: filter_dict['driver_id'] = driver_id if writer is not None: if isinstance(writer, DBRef): filter_dict['writer'] = writer elif isinstance(writer, ObjectId): writer = DBRef(database=mongo_db.db_name, collection=User.get_table_name(), id=writer) filter_dict['writer'] = writer elif isinstance(writer, str) and len(writer) == 24: writer = DBRef(database=mongo_db.db_name, collection=User.get_table_name(), id=ObjectId(writer)) filter_dict['writer'] = writer else: ms = "身份验证失败" raise ValueError(ms) if status is not None and status != -1: filter_dict['status'] = status if plate_number is not None: filter_dict['plate_number'] = plate_number if city is not None: filter_dict['city'] = city if isinstance(begin_date, datetime.datetime) and isinstance( end_date, datetime.datetime): filter_dict['time'] = {"$lte": end_date, "$gte": begin_date} elif isinstance(begin_date, datetime.datetime): filter_dict['time'] = {"$gte": begin_date} elif isinstance(end_date, datetime.datetime): filter_dict['time'] = {"$lte": end_date} else: pass skip = (index - 1) * num sort_dict = {"time": -1 if reverse else 1} count = cls.count(filter_dict=filter_dict) res = cls.find_plus(filter_dict=filter_dict, sort_dict=sort_dict, skip=skip, limit=num, to_dict=True) if can_json: res = [mongo_db.to_flat_dict(x) for x in res] data = {"count": count, "data": res} return data
def get_tasks(cls, o_id: (str, ObjectId), task_type: str = None, task_status: (str, list) = None, can_json: bool = True) -> (None, list): """ 获取模块的所有任务,返回的是doc的list :param o_id: 模块的_id, ObjectId :param task_type: 任务类型, 任务有feature和debug两种。None表示查询全部类型的任务 :param task_status: 任务状态。任务的状态有: normal/complete/fail/drop/suspend/delay normal: 正常状态,一般新建任务都处于这个状态。默认值 complete: 任务已完成 fail: 任务失败 drop: 任务已被放弃 suspend: 任务暂停 delay: 任务超期 None表示查询所有状态的任务 str 表示查询某一种状态的任务 list 是类型的数组,可以查询多种状态的任务 :param can_json: doc对象是否可以直接转为json? :return: Task类的doc的list """ module = cls.find_by_id(o_id) if isinstance(module, cls): m_dbref = module.get_dbref() type_list = [] if task_type is None: type_list = ['feature', 'debug'] else: type_list.append(task_type) status_list = [] if task_status is None: status_list = [ 'normal', 'complete', 'fail', 'drop', 'suspend', 'delay' ] elif isinstance(task_status, str): status_list.append(task_status) elif isinstance(task_status, list): status_list = task_status else: ms = "task_status参数类型错误,{}".format(type(task_status)) logger.exception(ms) raise ValueError(ms) f = { "module_id": m_dbref, "status": { "$in": status_list }, "type": { "$in": type_list } } s = {"begin_date": 1} records = cls.find_plus(filter_dict=f, sort_dict=s, to_dict=True, can_json=False) rs = list() delay_id_list = list() now = datetime.datetime.now() for record in records: """把超期的任务滤出来""" end_date = record['end_date'] status = record['status'] if end_date >= now and status == "normal": """超期的任务""" record['status'] = "delay" delay_id_list.append(record['_id']) else: pass if can_json: record = mongo_db.to_flat_dict(record) else: pass rs.append(record) if len(delay_id_list) > 0: f = {"_id": {"$in": delay_id_list}} u = {"$set": {"status": "delay"}} cls.find_one_and_update_plus(filter_dict=f, update_dict=u, upsert=False) else: pass else: rs = None return rs
def common_view_func(user: dict = None, html_name: str = ''): """ 通用页面视图 param user: 用户字典 param html_name: html文件名,包含目录路径 :return: """ # user = WXUser.find_by_id("5b56be217b3128ec21daa50a", to_dict=True) user2 = { "_id": ObjectId("5b56bdba7b3128ec21daa4c7"), "openid": "oBBcR1T5r6FCqOo2WNxMqPUqvK_I", "access_token": "12_ypF7a9ujmbnNYnbtZF8eyLyy23H9YmST6pMPYAuYefQizi4CrFOupAlLXKMe2dfRGa2Ezt0ApdHHTz-LdX8qtYVS8qTq2OQtnW5ZXtvUCGQ", "city": "闵行", "country": "中国", "expires_in": 7200, "groupid": 0, "head_img_url": "http://thirdwx.qlogo.cn/mmopen/dUtvxcibjGMKAzSRePkx3ZGZnRMsDyzU6f8fNjxtrS2nXCcwMPQUbZM4YYfS1vhWoObUHQaErCDEjNrStKszkiaA/132", "language": "zh_CN", "nick_name": "徐立杰", "province": "上海", "qr_scene": 0, "qr_scene_str": "", "refresh_token": "12_7h-zJ5RYfKWjYp7AQOiIe7VdFaZxw7gPFe3xxVVx4eEGdtuaYYK4st9HgSADdvJo_QpSLkF2JLP4Royzd_NfLde291LetISRV32TjtRweMQ", "remark": "", "scope": "snsapi_userinfo", "sex": 1, "subscribe": 1, "subscribe_scene": "ADD_SCENE_SEARCH", "tagid_list": [], "relate_img": "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQF78DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyQm9HVjAxNG5jaGwxMDAwME0wN2QAAgQmRFhbAwQAAAAA", "phone": "15618317376", "resume_id": ObjectId("5b5a96d9bede684e68049f01") } user = user2 if user is None else user template_dir = os.path.join(__project_dir__, 'templates') file_names = os.listdir(template_dir) ver = get_version() kwargs = dict() # 页面传参数 kwargs['version'] = ver kwargs['user'] = to_flat_dict(user) if html_name in file_names: """页面存在""" resume_pages = [ # 需要传递简历信息的页面 "resume.html", "register_info.html", "resume_detail.html", "additional.html", "driver_two.html", "part_time.html", 'safety_health.html', "update_id.html", ] resume_id = user.get("resume_id", "") if html_name in resume_pages: """简历的简要信息""" if resume_id == "": resume = dict() else: resume = DriverResume.find_by_id(o_id=resume_id, to_dict=True) # kwargs['work'] = dict() if html_name in ["resume.html", "resume_detail.html"]: """这个页面是显示简历全部信息的地方,需要额外详细的简历信息""" page_title = "我的简历" kwargs['page_title'] = page_title info = DriverResume.get_full_info(resume_id=resume_id) message = info['message'] if message == "success": resume = info['data'] else: ms = "获取简历详细信息错误,错误原因:{}".format(message) logger.exception(msg=ms) else: pass # set_trace() kwargs['resume'] = resume elif html_name == "driver_three.html": # 车辆信息 page_title = "自有车辆" kwargs['page_title'] = page_title v_id = get_arg(request, "v_id", "") if isinstance(v_id, str) and len(v_id) == 24: vehicle = Vehicle.find_by_id(o_id=v_id, to_dict=True) else: vehicle = dict() kwargs['vehicle'] = vehicle elif html_name == "add_info_jilu.html": # 添加荣誉 page_title = "曾获荣誉" kwargs['page_title'] = page_title if resume_id == "": return abort(403) else: h_id = get_arg(request, "h_id", "") if isinstance(h_id, str) and len(h_id) == 24: honor = Honor.find_by_id(o_id=h_id, can_json=True) else: honor = dict() kwargs['honor'] = honor elif html_name == "resume_info.html": # 添加工作经验 page_title = "工作履历" kwargs['page_title'] = page_title if resume_id == "": return abort(403) else: w_id = get_arg(request, "w_id", "") if isinstance(w_id, str) and len(w_id) == 24: work = WorkHistory.find_by_id(o_id=w_id, can_json=True) else: work = dict() kwargs['work'] = work elif html_name == "educational_experience.html": # 添加教育经历 page_title = "教育经历" kwargs['page_title'] = page_title if resume_id == "": return abort(403) else: e_id = get_arg(request, "e_id", "") if isinstance(e_id, str) and len(e_id) == 24: education = Education.find_by_id(o_id=e_id, can_json=True) else: education = dict() kwargs['education'] = education elif html_name == "intermediary.html": """ 上传营业执照等申请中介审核的页面 1. 如果审核尚未通过.允许访问本页面. 1. 未申请的,允许发起申请. 2. 申请中的,锁定输入.不允许编辑.但是可以撤回. 3. 申请驳回的,允许编辑再次申请 2. 审核通过,跳转到help_job.html页面 """ page_title = "申请认证" kwargs['page_title'] = page_title if user.get("authenticity") == 1: return redirect("/wx/html/help_job.html?u_id={}".format( user['_id'])) elif html_name == "my_resource.html": # 中介/销售/黄牛 查看自己的推荐的资源 u_id = get_arg(request, "u_id", "") user = None if isinstance(u_id, str) and len(u_id) == 24: user = WXUser.find_by_id(o_id=u_id, to_dict=True, can_json=True) else: pass # 测试时为了获取资源,生产环境请注销 # if user is None: # user = WXUser.find_by_id(o_id=ObjectId("5b56c0f87b3128ec21daa693"), to_dict=True, can_json=False) if user is None: """没有合法的u_id参数就重定向""" referrer = request.referrer if referrer is None or referrer == "": return abort(404) else: return redirect(referrer) else: kwargs['user'] = user now = datetime.datetime.now() y = get_arg(request, "y", now.year) m = get_arg(request, "m", now.month) b = mongo_db.get_datetime_from_str("{}-{}-1 0:0:0".format( y, m)) f = {"relate_time": {"$gte": b, "$lte": now}} page_index = get_arg(request, "index", 1) res = WXUser.page_resource(u_id=kwargs['user']['_id'], filter_dict=f, page_index=page_index) total_record = res.get("total_record", 0) total_page = res.get("total_page", 0) data = res.get("data", list()) current_page = res.get("current_page", 1) pages = res.get("pages", list()) page_title = "我的资源" # pages = [1, 2, 3, 4] # 生产环境注销 # total_record = 50 # 生产环境注销 # total_page = 5 # 生产环境注销 # page_index = 2 # 生产环境注销 kwargs['data'] = data kwargs['current_page'] = current_page kwargs['pages'] = pages kwargs['page_index'] = page_index kwargs['page_title'] = page_title kwargs['total_record'] = total_record kwargs['total_page'] = total_page kwargs['y'] = y kwargs['m'] = m elif html_name == "help_job.html": """ u_id = "5b56c0f87b3128ec21daa693" 展示关联二维码二维码页面, 中介/销售/黄牛专属页面,任何人访问这个页面的时候,必须带上u_id参数. 否则原路导向回去或者403 用户访问此页面时,检测用户是否已绑定 """ page_title = "委托求职" kwargs['page_title'] = page_title s_id = get_arg(request, "s_id", "") s_id = s_id if s_id != "" else get_arg(request, "u_id", "") if isinstance(s_id, str) and len(s_id) == 24: sales = WXUser.find_by_id(o_id=s_id, to_dict=True, can_json=True) if isinstance(sales, dict): """ 带s_id参数 1. 验证过,允许访问 2. 尚未通过审核,允许跳转到页面,但提示未审核,立即跳转. """ kwargs['sales'] = sales else: """不合法的u_id参数""" return abort(403) else: """无u_id参数""" return abort(403) """访问页面之前,可能需要加载一些参数""" else: pass print(kwargs) # 打印参数 print("html_name is {}".format(html_name)) return render_template(html_name, **kwargs) else: return abort(404)