def SaveNaturopathy(self): code = 201 status = False message = "" responseData = {} # todayDate = datetime.now().strftime('%Y-%m-%d %H:%M:%S') todayDate = datetime.now().strftime('%Y-%m-%d %H:%M:%S') ip_address = socket.gethostbyname(socket.gethostname()) requestData = dict(request.json) # converting price in integer and id in objctect id # if requestData['accomodations'] != None: # price = requestData['accomodations'] # for key in price: # price[key] = int(price[key]) # requestData['accomodations'] = price # sys.exit(); find_outlet = DB.find_one(tbl_v004_outlets, {"_id": ObjectId(requestData['outlet_id'])}) # print(requestData) if find_outlet: if requestData['naturopathy_id'] == "": del requestData['naturopathy_id'] requestData["vendor_id"] = ObjectId(requestData["vendor_id"]) requestData["outlet_id"] = ObjectId(requestData["outlet_id"]) requestData["category_id"] = ObjectId(requestData["category_id"]) requestData["business_type"] = "naturopathy" if requestData["sub_category_id"] == "other": requestData["sub_category_id"] == "other" else: requestData["sub_category_id"] = ObjectId( requestData["sub_category_id"]) requestData["recurring"] = False requestData['total_days'] = "" requestData["status"] = 1 requestData["is_delete"] = 0 requestData["created_by"] = ObjectId(requestData["user_id"]) requestData["created_date"] = todayDate requestData["insert_ip"] = ip_address del requestData['user_id'] act = DB.insert(tbl_v028_meditation_naturopathy, requestData) update_tour_steps = DB.update_one( tbl_v026_tour_steps, {"setup_service": True}, {"vendor_id": ObjectId(requestData["vendor_id"])}) responseData['naturopathy_id'] = act if act: code = 200 status = True message = MSG_CONST.NATUROPATHY_INSERTED_SUCCESS else: code = 201 status = False message = MSG_CONST.NATUROPATHY_INSERTED_FAILED else: requestData["vendor_id"] = ObjectId(requestData["vendor_id"]) requestData["outlet_id"] = ObjectId(requestData["outlet_id"]) requestData["category_id"] = ObjectId(requestData["category_id"]) if requestData["sub_category_id"] == "other": requestData["sub_category_id"] == "other" else: requestData["sub_category_id"] = ObjectId( requestData["sub_category_id"]) # requestData["sub_category_id"] = ObjectId(requestData["sub_category_id"]) requestData['naturopathy_id'] = ObjectId( requestData['naturopathy_id']) requestData["updated_by"] = ObjectId(requestData["user_id"]) if requestData["type"] == "hourly": requestData["accomodations"] = [] if requestData["type"] == "flexible": requestData["times"] = [] if requestData["accomodations"] != []: requestData['price'] = "" requestData["updated_date"] = todayDate requestData["updated_ip"] = ip_address del requestData['user_id'] # del requestData['service_id'] act = DB.update_one(tbl_v028_meditation_naturopathy, requestData, {"_id": requestData["naturopathy_id"]}) if act: code = 200 status = True message = MSG_CONST.NATUROPATHY_UPDATED_SUCCESS else: code = 201 status = False message = MSG_CONST.NATUROPATHY_UPDATED_FAILED response = output_json(responseData, message, status, code) logging.debug('SaveNaturopathy: {}'.format(response)) return response
} userdb.insert(new_user_info) user_object_id = userdb.find_one({"email": email}) user_object_id = user_object_id["_id"] print(user_object_id) else: user_object_id = userdb.find_one({"email": email}) user_object_id = user_object_id["_id"] print(user_object_id) # Company ID: default_id = companydb.find_one({"name": "Unknown_Company"}) default_id = default_id["_id"] new_job_info = { "user_id": ObjectId(f"{user_object_id}"), "job_details": { "url": url, "title": position, "country_id": "GE", "city": location_id, "industry": category, "views": views, "employment_type": stack,
def buscar_gabarito(self, id_prova): gabarito = self.provas.find_one({"_id": ObjectId(id_prova)}) return gabarito['questoes']
def test_get_tour_experiences(self): tour_id = ObjectId("5ec573d6fabc70e713595a94") result = self.app.get(f'/api/v1/tours/{tour_id}/experiences') self.assertIsNotNone(result)
def post_add(): ''' status: 0:草稿 1:发布 2:待审核 3:审核未通过 4:已删除 5:自动审核通过 :return: ''' view_data = { 'title': u'发表-{}'.format(config['title'].TITLE), 'hint': '写点东西' } view_data['permission'] = Permission.ECP view_data['help'] = mdb_cont.db.posts.find_one({ 'type': u'帮助', 'title': u'文章编辑帮助' }) subject = request.args.get('subject') if subject == "tech": view_data['hint'] = '科技有趣' elif subject == "ART": view_data['hint'] = '音乐|艺术' elif subject == "sys": if not current_user.can( Permission.ADMINISTER) and not current_user.is_role( Permission.ECP): abort(404) view_data['hint'] = '系统告示' if not subject in config['post'].SUBJECT: abort(404) else: form = EditPost(subject) if form.issue.data: if not form.title.data: flash({'type': 'w', 'msg': u'标题不能为空哦!'}) form.s_type.data = form.s_type.data form.body.data = form.body.data return render_template('post/posts/edit.html', form=form, view_data=view_data) # if current_user.can(Permission.ECP): # status = 1 # else: # status = 2 status = 1 # 封面图片 img_url = post_img(form.body.data, form.s_type.data) form.body.data = edit_img_log_claer(form.body.data, None) tag_list = request.form.getlist("boolean_l") post = { 'user_id': current_user.id, 'title': form.title.data.strip(), 'body': form.body.data, 'tag': tag_list, 'type': form.s_type.data, 'img_url': img_url, 'praise': 0, 'praise_id': [], 'pv': 0, 'pv_id': [], 'status': status, 'time': time.time(), 'update_time': time.time(), 'is_been': 1, 'subject': subject, } post_id = mdb_cont.db.posts.insert(post) post_cnt_update(current_user.id) if status == 1: flash({ 'msg': u'发表成功!首页|专栏可能延迟{}秒推出.'.format(config['cache_timeout'].POSTS), "type": 's' }) return redirect(url_for('post.show', post_id=post_id)) else: return redirect(url_for('post.preview', post_id=post_id)) elif form.draft.data: if not form.title.data: flash({'type': 'w', 'msg': u'标题不能为空哦!'}) form.s_type.data = form.s_type.data form.body.data = form.body.data return render_template('post/posts/edit.html', form=form, view_data=view_data) tag_list = request.form.getlist("boolean_l") # 封面图片 img_url = post_img(form.body.data, form.s_type.data) form.body.data = edit_img_log_claer(form.body.data, None) post = { 'user_id': current_user.id, 'title': form.title.data.strip(), 'body': form.body.data, 'tag': tag_list, 'type': form.s_type.data, 'img_url': img_url, 'praise': 0, 'praise_id': [], 'pv': 0, 'pv_id': [], 'status': 0, 'time': time.time(), 'update_time': time.time(), 'is_been': 0, 'subject': subject, } post_id = mdb_cont.db.posts.insert(post) post_cnt_update(current_user.id, ) return redirect(url_for('post.preview', post_id=post_id)) # view_data view_data['tag_s'] = [] tags = mdb_sys.db.type.find_one({'project': "post-tag", "subject": "tag"}) if tags: view_data['tag_s'] = tags["type"] view_data['tag_u'] = [] tags = mdb_cont.db.tag.find_one({'user_id': ObjectId(current_user.id)}) if tags: view_data['tag_u'] = tags['tag'] view_data['post'] = {'img_url': 'images/post_img/未分类_default.png'} return render_template('{}/post/edit.html'.format(Theme.THEME_NAME), form=form, view_data=view_data)
def bind_toy(): """ :return: """ user_list = [] device_key = request.form.get("device_key") user_id = request.form.get("user_id") toy_name = request.form.get("toy_name") baby_name = request.form.get("baby_name") remark = request.form.get("remark") gender = request.form.get("gender") # 1.创建玩具的基本信息 chat_id = MONGO_DB.chat.insert_one({}) # 没主儿的chat user_info = MONGO_DB.users.find_one({"_id": ObjectId(user_id)}) # 查询用户基本信息 user_list.append(str(user_info.get("_id"))) # 2.绑定用户与玩具关系 toy_info = { "device_key": device_key, "bind_user": user_id, "toy_name": toy_name, "avatar": "toy.jpg", "baby_name": baby_name, "gender": gender, "friend_list": [] } # 3.成为玩具的第一个好友 frist_friend = { "friend_nickname": user_info.get("nickname"), # 徐中一不不知道前不强 "friend_avatar": user_info.get("avatar"), "friend_remark": remark, # 强强 "friend_chat": str(chat_id.inserted_id) } toy_info["friend_list"].append(frist_friend) toy_id = MONGO_DB.toys.insert_one(toy_info) user_list.append(toy_id.inserted_id) MONGO_DB.chat.update_one( {"_id": chat_id.inserted_id}, {"$set": {"user_list": user_list, "chat_list": []}} ) user_info["bind_toys"].append(str(toy_id.inserted_id)) user_info["friend_list"].append( { "friend_nickname": toy_info.get("baby_name"), "friend_avatar": toy_info.get("avatar"), "friend_remark": toy_info.get("baby_name"), "friend_chat": str(chat_id.inserted_id) } ) MONGO_DB.users.update_one({"_id": ObjectId(user_id)}, {"$set": user_info}) RET["code"] = 0 RET["msg"] = "绑定成功" RET["data"] = {} return jsonify(RET)
def test_get_landmark_from_api(self): tour_id = ObjectId('5eeb86c96d5f80c5f2fdbb00') result = self.app.get(f'/api/v1/tours/{tour_id}/tourview') self.assertIsNotNone(result)
print('Getting all resources older than {:%Y-%m-%d %H:%M}...'.format(time)) rsrcs = db.clarin.resources.find({'modified': {'$lt': time}}) ids = set() for res in rsrcs: ids.add(res['_id']) print('Discarding anything that can be used in EMU projects...') projs = db.clarin.emu.find({}) for proj in projs: for name, bndl in proj['bundles'].items(): if 'audio' in bndl: ids.discard(ObjectId(bndl['audio'])) if 'trans' in bndl: ids.discard(ObjectId(bndl['trans'])) if 'seg' in bndl: ids.discard(ObjectId(bndl['seg'])) print(f'Deleting {len(ids)} resources...') for id in ids: db.clarin.resources.remove({'_id': id}) print('Making a list of files in databse...') rsrcs = db.clarin.resources.find({}) db_files = set()
def get(id, step_id): return mongo.db.projects.find_one( { '_id': ObjectId(id), 'steps._id': ObjectId(step_id) }, {'steps.$': 1})
def testgetResult(self): urls = [ { "_id": 1, "r_id": ObjectId('4e4c7b9f5bc89412ec000004'), "url": "http://www.chinacache.com/a.jpg", "status": "PROGRESS", "isdir": False, "finish_time": '20110624142700', "action": "purge", "is_multilayer": False, "channel_code": "0005", "created_time": "" }, { "_id": 2, "r_id": ObjectId('4e4c7b9f5bc89412ec000004'), "url": "http://www.chinacache.com/u.jpg", "status": "PROGRESS", "isdir": False, "finish_time": '20110624142700', "action": "expire", "is_multilayer": False, "channel_code": "0005", "created_time": "" }, ] result = mock() when(self.db_session.request).find({ "username": '******', "created_time": { "$gte": datetime.strptime('20110624142500', '%Y%m%d%H%M%S'), "$lte": datetime.strptime('20110624142800', '%Y%m%d%H%M%S') } }).thenReturn(result) when(result).limit(1000).thenReturn([{ 'created_time': '2012-01-01 01:01:01', 'remote_addr': '0.0.0.1', 'serial_num': '123456', '_id': ObjectId('4e4c7b9f5bc89412ec000004') }]) when(self.db_session.url).find({ 'r_id': ObjectId('4e4c7b9f5bc89412ec000004') }).thenReturn(urls) when(result_tencent).getStatus({ "_id": 1, "r_id": ObjectId('4e4c7b9f5bc89412ec000004'), "url": "http://www.chinacache.com/a.jpg", "status": "PROGRESS", "isdir": False, "finish_time": '20110624142700', "action": "purge", "is_multilayer": False, "channel_code": "0005", "created_time": "" }).thenReturn(0) when(result_tencent).getStatus({ "_id": 2, "r_id": ObjectId('4e4c7b9f5bc89412ec000004'), "url": "http://www.chinacache.com/u.jpg", "status": "PROGRESS", "isdir": False, "finish_time": '20110624142700', "action": "expire", "is_multilayer": False, "channel_code": "0005", "created_time": "" }).thenReturn(0) result_str = u'{"ret":"0","msg":"下列是URL 更新状态列表"}\n2012-01-01 01:01:01\t123456\t0.0.0.1\thttp://www.chinacache.com/a.jpg\t20110624142700\t0\t完成\n2012-01-01 01:01:01\t123456\t0.0.0.1\thttp://www.chinacache.com/u.jpg\t20110624142700\t0\t完成\n' self.assertEquals( result_tencent.get_result(self.db_session, '20110624142500', '20110624142800', 'test'), result_str)
# projectionFields = {'_id':False} # 用字典指定 # queryArgs = {"total_zone_name":"pudong"} # # searcher = db_coll.find({}) # # while True: # try: # dict = searcher.next() # print(len(dict)) # except StopIteration: # break bulid_time = time.strftime('%m/%d/%Y %H:%M:%S', time.localtime()) base_date = {'bulid_time': bulid_time} db_coll.insert(base_date) l = len(db_coll.find(base_date).next()) print(l) id = db_coll.find(base_date).next()['_id'] from bson import ObjectId for i in range(100): l = len(db_coll.find({'_id': ObjectId(id)}).next()) if l < 10: db_coll.update({'_id': ObjectId(id)}, {'$set': {str(i): i}}) else: bulid_time = time.strftime('%m/%d/%Y %H:%M:%S', time.localtime()) base_date = {'bulid_time': bulid_time} db_coll.insert(base_date) id = db_coll.find(base_date).next()['_id']
def delete_by_id(id: str) -> TrainingJob: document: dict = _collection.find_one_and_delete( filter={'_id': ObjectId(id)}) return TrainingJob(**document)
def exists_by_id(id: str) -> bool: count = _collection.count_documents(filter={'_id': ObjectId(id)}, limit=1) return bool(count)
def getNaturopathyByVendor(self): code = 200 status = False message = "" responseData = {} serData = [] where = {} if request.args.get("vendor_id") and request.args.get("vendor_id") != "": where["vendor_id"] = ObjectId(request.args.get("vendor_id")) where["is_delete"] = 0 where["status"] = 1 if request.args.get("outlet_id"): where["outlet_id"] = ObjectId(request.args.get("outlet_id")) serData = DB.find_by_key(tbl_v028_meditation_naturopathy, where) if serData: getCat = DB.find_all(tbl_v006_service_category, { "category_name": 1, "_id": 1 }) catData = {} if getCat: for c in getCat: if "category_name" in c and c["category_name"] != "": catData[c["_id"]["$oid"]] = c["category_name"] getOut = DB.find_all(tbl_v004_outlets, {"name": 1, "_id": 1}) outData = {} if getOut: for c in getOut: outData[c["_id"]["$oid"]] = c["name"] resData = [] for x in serData: x["_id"] = str(x["_id"]["$oid"]) if "$oid" in x["user_id"]: x["user_id"] = str(x["user_id"]["$oid"]) x["vendor_id"] = str(x["vendor_id"]["$oid"]) x["outlet_id"] = str(x["outlet_id"]["$oid"]) if "service_master_id" in x: if isinstance(x["service_master_id"], list): for sm in range(len(x["service_master_id"])): x["service_master_id"][ sm] = x["service_master_id"][sm][ "$oid"] if "$oid" in x["service_master_id"][ sm] else x["service_master_id"][sm] else: x["service_master_id"] = [ x["service_master_id"]["$oid"] if "$oid" in x["service_master_id"] else x["service_master_id"] ] if x["outlet_id"] in outData: x["outlet_name"] = outData[x["outlet_id"]] catId = [] if isinstance(x["category_id"], list): for ci in range(len(x["category_id"])): x["category_id"][ci] = x["category_id"][ci]["$oid"] if x["category_id"][ci] in catData: catId.append({ "category_id": x["category_id"][ci], "name": catData[x["category_id"][ci]].title() }) x["category_id"] = catId else: x["category_id"] = x["category_id"]["$oid"] if "$oid" in x[ "category_id"] else "" if x["category_id"] in catData: x["category_id"] = [{ "category_id": x["category_id"], "name": catData[x["category_id"]].title() }] resData.append(x) responseData = list(reversed(resData)) code = 200 status = True message = MSG_CONST.VENDOR_SERVICES_SUCCESS else: code = 201 status = False message = MSG_CONST.VENDOR_OUTLET_NOT_FOUND else: code = 201 status = False message = MSG_CONST.VENDOR_EMPTY_ID response = output_json(responseData, message, status, code) logging.debug('vendor_services_list: {}'.format(response)) return response
def test_api_onplat(self): mdl = RootUserModel(OnPlatOids=[ObjectId()], ApiOid=ObjectId()) self.assertTrue(mdl.has_api_data) self.assertTrue(mdl.has_onplat_data)
def get(id): return mongo.db.projects.find_one({'_id': ObjectId(id)})
def get_url(uid): obj_url = query_db_session.url.find_one({"_id": ObjectId(uid)}) if obj_url: return obj_url else: return None
def listFailedPosts(user, page = 0, page_size = 100000) : uid = ObjectId(user['_id']) result = tagdb.db.failed_posts.find({'uid': uid}) result = result.skip(page * page_size).limit(page_size) return result, result.count()
def test_cannot_get_inexistent_tour(self): # We need create a random a value empty = ObjectId("000000000000000000000000") result = self.app.get(f'/api/v1/tours/{empty}') self.assertTrue(result.status_code == 404)
def validate(cls, v): if not ObjectId.is_valid(v): raise ValueError('Invalid objectid') return ObjectId(v)
def test_cannot_get_inexistent_landmark_from_api(self): empty = ObjectId('000000000000000000000000') result = self.app.get(f'/api/v1/tours/{empty}/tourview') self.assertTrue(result.status_code == 404)
def edit_role(): rid = request.argget.all('id').strip() name = request.argget.all('name').strip() instructions = request.argget.all('instructions').strip() default = int(request.argget.all('default', 0)) temp_permissions = json_to_pyseq(request.argget.all('permissions', [])) permissions = 0x0 for i in temp_permissions: permissions = permissions | int(i) s, r = arg_verify(reqargs=[(gettext("name"), name)], required=True) if not s: return r data = { "msg": gettext( "The current user permissions are lower than the permissions you want to modify," " without permission to modify"), "msg_type": "w", "custom_status": 401 } user_role = mdbs["user"].db.role.find_one( {"_id": ObjectId(current_user.role_id)}) # 如果当前用户的权限最高位 小于 要修改成的这个角色权重的最高位,是不可以的 if get_num_digits(user_role["permissions"]) < get_num_digits(permissions): return data elif get_num_digits( user_role["permissions"]) == get_num_digits(permissions): role = { "name": name, "instructions": instructions, } r = mdbs["user"].db.role.update_one({"_id": ObjectId(rid)}, {"$set": role}) if not r.modified_count: data = { 'msg': gettext("No changes"), 'msg_type': "w", "custom_status": 201 } else: data = { "msg": gettext( "The highest permission of the current user is equal to that of the selected permission." " You can only modify the name and profile."), "msg_type": "s", "custom_status": 201 } return data old_role = mdbs["user"].db.role.find_one({"_id": ObjectId(rid)}) # 如果当前用户的权限最高位 小于 要修改角色的权限,也是不可以 if old_role and get_num_digits(old_role["permissions"]) >= get_num_digits( user_role["permissions"]): return data elif old_role and get_num_digits( old_role["permissions"]) == get_num_digits( user_role["permissions"]): role = { "name": name, "instructions": instructions, } r = mdbs["user"].db.role.update_one({"_id": ObjectId(rid)}, {"$set": role}) if not r.modified_count: data = { 'msg': gettext("No changes"), 'msg_type': "w", "custom_status": 201 } else: data = { "msg": gettext( "The highest permission of the current user is equal to that of the role to be modified." "Only the name and introduction can be modified."), "msg_type": "s", "custom_status": 201 } return data else: role = { "name": name, "instructions": instructions, 'permissions': permissions, "default": default } data = { 'msg': gettext("Save success"), 'msg_type': "s", "custom_status": 201 } if not mdbs["user"].db.role.find_one({ "name": name, "_id": { "$ne": ObjectId(rid) } }): if default: if not mdbs["user"].db.role.find_one({ "default": { "$in": [1, True] }, "_id": { "$ne": ObjectId(rid) } }): r = mdbs["user"].db.role.update_one({"_id": ObjectId(rid)}, {"$set": role}) if not r.modified_count: data = { 'msg': gettext("No changes"), 'msg_type': "w", "custom_status": 201 } else: data = { 'msg': gettext("Existing default role"), 'msg_type': "w", "custom_status": 403 } else: r = mdbs["user"].db.role.update_one({"_id": ObjectId(rid)}, {"$set": role}) if not r.modified_count: data = { 'msg': gettext("No changes"), 'msg_type': "w", "custom_status": 201 } else: data = { 'msg': gettext("Role name already exists"), 'msg_type': "w", "custom_status": 403 } return data
def post_edit(post_id): view_data = { 'title': u'编辑-{}'.format(config['title'].TITLE), 'hint': '正在编辑' } view_data['permission'] = Permission.ECP view_data['help'] = mdb_cont.db.posts.find_one({ 'type': u'帮助', 'title': u'文章编辑帮助' }) post = mdb_cont.db.posts.find_one_or_404({ '_id': ObjectId(post_id), 'user_id': current_user.id }) if post['subject'] == "tech": view_data['hint'] = '科技有趣' elif post['subject'] == "art": view_data['hint'] = '音乐|艺术' elif post['subject'] == "sys": if not current_user.is_role(Permission.ECP): abort(404) view_data['hint'] = '系统告示' form = EditPost(post['subject']) if form.issue.data: # if current_user.can(Permission.ECP): # status = 1 # else: # status = 2 status = 1 tag_list = request.form.getlist("boolean_l") # 封面图片 img_url = post_img(form.body.data, form.s_type.data) if current_user.can(Permission.ECP): form.body.data = sys_edit_img_log_claer( form.body.data, post_title=form.title.data.strip()) else: form.body.data = edit_img_log_claer(form.body.data, post_id) # tag if post['is_been']: _time = post['time'] _is_been = post['is_been'] else: _time = time.time() _is_been = 1 post = { 'title': form.title.data.strip(), 'body': form.body.data, 'status': status, 'type': form.s_type.data, 'img_url': img_url, 'time': _time, 'is_been': _is_been, 'update_time': time.time(), } if tag_list: post['tag'] = tag_list mdb_cont.db.posts.update( { '_id': ObjectId(post_id), 'user_id': current_user.id }, {'$set': post}) if status == 1: post_cnt_update(current_user.id) flash({ 'msg': u'更新成功!首页|专栏可能延迟{}秒更新.'.format(config['cache_timeout'].POSTS), "type": 's' }) return redirect(url_for('post.show', post_id=post_id)) else: return redirect(url_for('post.preview', post_id=post_id)) elif form.draft.data: status = 0 tag_list = request.form.getlist("boolean_l") # 图片 img_url = post_img(form.body.data, form.s_type.data) form.body.data = edit_img_log_claer(form.body.data, post_id) post = { 'title': form.title.data.strip(), 'body': form.body.data, 'type': form.s_type.data, 'img_url': img_url, 'status': status, 'update_time': time.time() } if tag_list: post['tag'] = tag_list post_cnt_update(current_user.id) mdb_cont.db.posts.update( { '_id': ObjectId(post_id), 'user_id': current_user.id }, {'$set': post}) return redirect(url_for('post.preview', post_id=post_id)) # view_data view_data['tag_s'] = [] tags = mdb_cont.db.tag.find_one({'user_id': 0}) if tags: view_data['tag_s'] = tags['tag'] view_data['tag_u'] = [] tags = mdb_cont.db.tag.find_one({'user_id': current_user.id}) if tags: view_data['tag_u'] = tags['tag'] #post form.title.data = post['title'] form.body.data = post['body'] form.s_type.data = post['type'] view_data['edit'] = True view_data['post'] = post # 记录图片url post_img_statis(post['body'], post['_id']) return render_template('post/posts/edit.html', form=form, view_data=view_data)
def add_role(): name = request.argget.all('name').strip() instructions = request.argget.all('instructions').strip() default = int(request.argget.all('default', False).strip()) temp_permissions = json_to_pyseq(request.argget.all('permissions', [])) data = { 'msg': gettext("Add a success"), 'msg_type': "s", "custom_status": 201 } permissions = 0x0 for i in temp_permissions: permissions = permissions | int(i) s, r = arg_verify(reqargs=[(gettext("name"), name)], required=True) if not s: return r elif not mdbs["user"].db.role.find_one({gettext("name"): name}): # 权限检查 user_role = mdbs["user"].db.role.find_one( {"_id": ObjectId(current_user.role_id)}) if get_num_digits( user_role["permissions"]) <= get_num_digits(permissions): data = { "msg": gettext( "The current user permissions are lower than the permissions that you want to add," " without permission to add"), "msg_type": "w", "custom_status": 401 } return data if default: if not mdbs["user"].db.role.find_one( {"default": { "$in": [1, True] }}): mdbs["user"].db.role.insert_one({ "name": name, "instructions": instructions, 'permissions': permissions, "default": default }) else: data = { 'msg': gettext("Existing default role"), 'msg_type': "w", "custom_status": 403 } else: mdbs["user"].db.role.insert_one({ "name": name, "instructions": instructions, 'permissions': permissions, "default": default }) else: data = { 'msg': gettext("Role name already exists"), 'msg_type': "w", "custom_status": 403 } return data
def remove(restaurant): return db_clustering_map.restaurants.delete_one( {"_id": ObjectId(restaurant)})
def test_api_only(self): mdl = RootUserModel(ApiOid=ObjectId()) self.assertTrue(mdl.has_api_data) self.assertFalse(mdl.has_onplat_data)
def buscar_prova(self, id_prova: int): return self.provas.find({'_id': ObjectId(id_prova)})
def test_onplat_only(self): mdl = RootUserModel(OnPlatOids=[ObjectId()]) self.assertFalse(mdl.has_api_data) self.assertTrue(mdl.has_onplat_data)
def delete(self, index, id): self.cols[index].delete_one({'_id': ObjectId(id)})
class Mongo(DataLayer): """ MongoDB data access layer for Eve REST API. .. versionchanged:: 0.5 Properly serialize nullable float and integers. #469. Return 400 if unsupported query operators are used. #387. .. versionchanged:: 0.4 Don't serialize to objectid if value is null. #341. .. versionchanged:: 0.2 Provide the specialized json serializer class as ``json_encoder_class``. .. versionchanged:: 0.1.1 'serializers' added. """ serializers = { "objectid": lambda value: ObjectId(value) if value else None, "datetime": str_to_date, "integer": lambda value: int(value) if value is not None else None, "float": lambda value: float(value) if value is not None else None, "number": lambda val: json.loads(val) if val is not None else None, "boolean": lambda v: {"1": True, "true": True, "0": False, "false": False}[ str(v).lower() ], "dbref": lambda value: DBRef( value["$col"] if "$col" in value else value["$ref"], value["$id"], value["$db"] if "$db" in value else None, ) if value is not None else None, "decimal": lambda value: decimal128.Decimal128(decimal.Decimal(str(value))) if value is not None else None, } # JSON serializer is a class attribute. Allows extensions to replace it # with their own implementation. json_encoder_class = MongoJSONEncoder operators = set( ["$gt", "$gte", "$in", "$lt", "$lte", "$ne", "$nin", "$eq"] + ["$or", "$and", "$not", "$nor"] + ["$mod", "$regex", "$text", "$where"] + ["$options", "$search", "$language", "$caseSensitive"] + ["$diacriticSensitive", "$exists", "$type"] + ["$geoWithin", "$geoIntersects", "$near", "$nearSphere", "$centerSphere"] + ["$geometry", "$maxDistance", "$minDistance", "$box"] + ["$all", "$elemMatch", "$size"] + ["$bitsAllClear", "$bitsAllSet", "$bitsAnyClear", "$bitsAnySet"] + ["$center", "$expr"] ) def init_app(self, app): """ Initialize PyMongo. .. versionchanged:: 0.6 Use mongo_prefix for multidb support. .. versionchanged:: 0.0.9 Support for Python 3.3. """ # mongod must be running or this will raise an exception self.driver = PyMongos(self) self.mongo_prefix = None def find(self, resource, req, sub_resource_lookup, perform_count=True): """ Retrieves a set of documents matching a given request. Queries can be expressed in two different formats: the mongo query syntax, and the python syntax. The first kind of query would look like: :: ?where={"name": "john doe"} while the second would look like: :: ?where=name=="john doe" The resultset if paginated. :param resource: resource name. :param req: a :class:`ParsedRequest`instance. :param sub_resource_lookup: sub-resource lookup from the endpoint url. .. versionchanged:: 0.6 Support for multiple databases. Filter soft deleted documents by default .. versionchanged:: 0.5 Support for comma delimited sort syntax. Addresses #443. Return the error if a blacklisted MongoDB operator is used in query. Abort with 400 if unsupported query operator is used. #387. Abort with 400 in case of invalid sort syntax. #387. .. versionchanged:: 0.4 'allowed_filters' is now checked before adding 'sub_resource_lookup' to the query, as it is considered safe. Refactored to use self._client_projection since projection is now honored by getitem() as well. .. versionchanged:: 0.3 Support for new _mongotize() signature. .. versionchanged:: 0.2 Support for sub-resources. Support for 'default_sort'. .. versionchanged:: 0.1.1 Better query handling. We're now properly casting objectid-like strings to ObjectIds. Also, we're casting both datetimes and objectids even when the query was originally in python syntax. .. versionchanged:: 0.0.9 More informative error messages. .. versionchanged:: 0.0.7 Abort with a 400 if the query includes blacklisted operators. .. versionchanged:: 0.0.6 Only retrieve fields in the resource schema Support for projection queries ('?projection={"name": 1}') .. versionchanged:: 0.0.5 handles the case where req.max_results is None because pagination has been disabled. .. versionchanged:: 0.0.4 retrieves the target collection via the new config.SOURCES helper. """ args = dict() if req and req.max_results: args["limit"] = req.max_results if req and req.page > 1: args["skip"] = (req.page - 1) * req.max_results # TODO sort syntax should probably be coherent with 'where': either # mongo-like # or python-like. Currently accepts only mongo-like sort # syntax. # TODO should validate on unknown sort fields (mongo driver doesn't # return an error) client_sort = self._convert_sort_request_to_dict(req) spec = self._convert_where_request_to_dict(resource, req) bad_filter = validate_filters(spec, resource) if bad_filter: abort(400, bad_filter) if sub_resource_lookup: spec = self.combine_queries(spec, sub_resource_lookup) if ( config.DOMAIN[resource]["soft_delete"] and not (req and req.show_deleted) and not self.query_contains_field(spec, config.DELETED) ): # Soft delete filtering applied after validate_filters call as # querying against the DELETED field must always be allowed when # soft_delete is enabled spec = self.combine_queries(spec, {config.DELETED: {"$ne": True}}) spec = self._mongotize(spec, resource) client_projection = self._client_projection(req) datasource, spec, projection, sort = self._datasource_ex( resource, spec, client_projection, client_sort ) if req and req.if_modified_since: spec[config.LAST_UPDATED] = {"$gt": req.if_modified_since} if len(spec) > 0: args["filter"] = spec if sort is not None: args["sort"] = sort if projection: args["projection"] = projection target = self.pymongo(resource).db[datasource] try: result = target.find(**args) except TypeError as e: # pymongo raises ValueError when invalid query paramenters are # included. We do our best to catch them beforehand but, especially # with key/value sort syntax, invalid ones might still slip in. self.app.logger.exception(e) abort(400, description=debug_error_message(str(e))) if perform_count: try: count = target.count_documents(spec) except: # fallback to deprecated method. this might happen when the query # includes operators not supported by count_documents(). one # documented use-case is when we're running on mongo 3.4 and below, # which does not support $expr ($expr must replace $where # in # count_documents()). # 1. Mongo 3.6+; $expr: pass # 2. Mongo 3.6+; $where: pass (via fallback) # 3. Mongo 3.4; $where: pass (via fallback) # 4. Mongo 3.4; $expr: fail (operator not supported by db) # See: http://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.count count = target.count() else: count = None return result, count def find_one( self, resource, req, check_auth_value=True, force_auth_field_projection=False, **lookup ): """ Retrieves a single document. :param resource: resource name. :param req: a :class:`ParsedRequest` instance. :param **lookup: lookup query. .. versionchanged:: 0.6 Support for multiple databases. Filter soft deleted documents by default .. versionchanged:: 0.4 Honor client projection requests. .. versionchanged:: 0.3.0 Support for new _mongotize() signature. Custom ID_FIELD lookups would raise an exception. See #203. .. versionchanged:: 0.1.0 ID_FIELD to ObjectID conversion is done before `_datasource_ex` is called. .. versionchanged:: 0.0.6 Only retrieve fields in the resource schema .. versionchanged:: 0.0.4 retrieves the target collection via the new config.SOURCES helper. """ self._mongotize(lookup, resource) client_projection = self._client_projection(req) datasource, filter_, projection, _ = self._datasource_ex( resource, lookup, client_projection, check_auth_value=check_auth_value, force_auth_field_projection=force_auth_field_projection, ) if ( (config.DOMAIN[resource]["soft_delete"]) and (not req or not req.show_deleted) and (not self.query_contains_field(lookup, config.DELETED)) ): filter_ = self.combine_queries(filter_, {config.DELETED: {"$ne": True}}) # Here, we feed pymongo with `None` if projection is empty. return ( self.pymongo(resource).db[datasource].find_one(filter_, projection or None) ) def find_one_raw(self, resource, **lookup): """ Retrieves a single raw document. :param resource: resource name. :param **lookup: lookup query. .. versionchanged:: 0.6 Support for multiple databases. .. versionadded:: 0.4 """ id_field = config.DOMAIN[resource]["id_field"] _id = lookup.get(id_field) datasource, filter_, _, _ = self._datasource_ex(resource, {id_field: _id}, None) lookup = self._mongotize(lookup, resource) return self.pymongo(resource).db[datasource].find_one(lookup) def find_list_of_ids(self, resource, ids, client_projection=None): """ Retrieves a list of documents from the collection given by `resource`, matching the given list of ids. This query is generated to *preserve the order* of the elements in the `ids` list. An alternative would be to use the `$in` operator and accept non-dependable ordering for a slight performance boost see <https://jira.mongodb.org/browse/SERVER-7528?focusedCommentId= 181518&page=com.atlassian.jira.plugin.system.issuetabpanels:comment -tabpanel#comment-181518> To preserve order, we use a query of the form db.collection.find( { $or:[ { _id:ObjectId(...) }, { _id:ObjectId(...) }...] } ) Instead of the simpler {'_id': {'$in': ids}} -- via http://stackoverflow.com/a/13185509/1161906 :param resource: resource name. :param ids: a list of ObjectIds corresponding to the documents to retrieve :param client_projection: a specific projection to use :return: a list of documents matching the ids in `ids` from the collection specified in `resource` .. versionchanged:: 0.6 Support for multiple databases. .. versionchanged:: 0.1.1 Using config.ID_FIELD instead of hard coded '_id'. .. versionadded:: 0.1.0 """ id_field = config.DOMAIN[resource]["id_field"] query = {"$or": [{id_field: id_} for id_ in ids]} datasource, spec, projection, _ = self._datasource_ex( resource, query=query, client_projection=client_projection ) # projection of {} return all fields in MongoDB, but # pymongo will only return `_id`. It's a design flaw upstream. # Here, we feed pymongo with `None` if projection is empty. documents = ( self.pymongo(resource) .db[datasource] .find(filter=spec, projection=(projection or None)) ) return documents def aggregate(self, resource, pipeline, options): """ .. versionadded:: 0.7 """ datasource, _, _, _ = self.datasource(resource) challenge = self._mongotize({"key": pipeline}, resource)["key"] return self.pymongo(resource).db[datasource].aggregate(challenge, **options) def insert(self, resource, doc_or_docs): """ Inserts a document into a resource collection. .. versionchanged:: 0.6.1 Support for PyMongo 3.0. .. versionchanged:: 0.6 Support for multiple databases. .. versionchanged:: 0.0.9 More informative error messages. .. versionchanged:: 0.0.8 'write_concern' support. .. versionchanged:: 0.0.6 projection queries ('?projection={"name": 1}') 'document' param renamed to 'doc_or_docs', making support for bulk inserts apparent. .. versionchanged:: 0.0.4 retrieves the target collection via the new config.SOURCES helper. """ datasource, _, _, _ = self._datasource_ex(resource) coll = self.get_collection_with_write_concern(datasource, resource) if isinstance(doc_or_docs, dict): doc_or_docs = [doc_or_docs] try: return coll.insert_many(doc_or_docs, ordered=True).inserted_ids except pymongo.errors.BulkWriteError as e: self.app.logger.exception(e) # since this is an ordered bulk operation, all remaining inserts # are aborted. Be aware that if BULK_ENABLED is True and more than # one document is included with the payload, some documents might # have been successfully inserted, even if the operation was # aborted. # report a duplicate key error since this can probably be # handled by the client. for error in e.details["writeErrors"]: # amazingly enough, pymongo does not appear to be exposing # error codes as constants. if error["code"] == 11000: abort( 409, description=debug_error_message( "Duplicate key error at index: %s, message: %s" % (error["index"], error["errmsg"]) ), ) abort( 500, description=debug_error_message( "pymongo.errors.BulkWriteError: %s" % e ), ) def _change_request(self, resource, id_, changes, original, replace=False): """ Performs a change, be it a replace or update. .. versionchanged:: 0.8.2 Return 400 if update/replace with malformed DBRef field. See #1257. .. versionchanged:: 0.6.1 Support for PyMongo 3.0. .. versionchanged:: 0.6 Return 400 if an attempt is made to update/replace an immutable field. """ id_field = config.DOMAIN[resource]["id_field"] query = {id_field: id_} if config.ETAG in original: query[config.ETAG] = original[config.ETAG] datasource, filter_, _, _ = self._datasource_ex(resource, query) coll = self.get_collection_with_write_concern(datasource, resource) try: result = ( coll.replace_one(filter_, changes) if replace else coll.update_one(filter_, changes) ) if ( config.ETAG in original and result and result.acknowledged and result.modified_count == 0 ): raise self.OriginalChangedError() except pymongo.errors.DuplicateKeyError as e: abort( 400, description=debug_error_message( "pymongo.errors.DuplicateKeyError: %s" % e ), ) except (pymongo.errors.WriteError, pymongo.errors.OperationFailure) as e: # server error codes and messages changed between 2.4 and 2.6/3.0. server_version = self.driver.db.client.server_info()["version"][:3] if (server_version == "2.4" and e.code in (13596, 10148)) or e.code in ( 66, 16837, ): # attempt to update an immutable field. this usually # happens when a PATCH or PUT includes a mismatching ID_FIELD. self.app.logger.warning(e) description = ( debug_error_message("pymongo.errors.OperationFailure: %s" % e) or "Attempt to update an immutable field. Usually happens " "when PATCH or PUT include a '%s' field, " "which is immutable (PUT can include it as long as " "it is unchanged)." % id_field ) abort(400, description=description) else: # see comment in :func:`insert()`. self.app.logger.exception(e) abort( 500, description=debug_error_message( "pymongo.errors.OperationFailure: %s" % e ), ) def update(self, resource, id_, updates, original): """ Updates a collection document. .. versionchanged:: 0.6 Support for multiple databases. .. versionchanged:: 5.2 Raise OriginalChangedError if document is changed from the specified original. .. versionchanged:: 0.4 Return a 400 on pymongo DuplicateKeyError. .. versionchanged:: 0.3.0 Custom ID_FIELD lookups would fail. See #203. .. versionchanged:: 0.2 Don't explicitly convert ID_FIELD to ObjectId anymore, so we can also process different types (UUIDs etc). .. versionchanged:: 0.0.9 More informative error messages. .. versionchanged:: 0.0.8 'write_concern' support. .. versionchanged:: 0.0.6 projection queries ('?projection={"name": 1}') .. versionchanged:: 0.0.4 retrieves the target collection via the new config.SOURCES helper. """ return self._change_request(resource, id_, {"$set": updates}, original) def replace(self, resource, id_, document, original): """ Replaces an existing document. .. versionchanged:: 0.6 Support for multiple databases. .. versionchanged:: 5.2 Raise OriginalChangedError if document is changed from the specified original. .. versionchanged:: 0.3.0 Custom ID_FIELD lookups would fail. See #203. .. versionchanged:: 0.2 Don't explicitly convert ID_FIELD to ObjectId anymore, so we can also process different types (UUIDs etc). .. versionadded:: 0.1.0 """ return self._change_request(resource, id_, document, original, replace=True) def remove(self, resource, lookup): """ Removes a document or the entire set of documents from a collection. .. versionchanged:: 0.6.1 Support for PyMongo 3.0. .. versionchanged:: 0.6 Support for multiple databases. .. versionchanged:: 0.3 Support lookup arg, which allows to properly delete sub-resources (only delete documents that meet a certain constraint). .. versionchanged:: 0.2 Don't explicitly converto ID_FIELD to ObjectId anymore, so we can also process different types (UUIDs etc). .. versionchanged:: 0.0.9 More informative error messages. .. versionchanged:: 0.0.8 'write_concern' support. .. versionchanged:: 0.0.6 projection queries ('?projection={"name": 1}') .. versionchanged:: 0.0.4 retrieves the target collection via the new config.SOURCES helper. .. versionadded:: 0.0.2 Support for deletion of entire documents collection. :returns A document (dict) describing the effect of the remove or None if write acknowledgement is disabled. """ lookup = self._mongotize(lookup, resource) datasource, filter_, _, _ = self._datasource_ex(resource, lookup) coll = self.get_collection_with_write_concern(datasource, resource) try: coll.delete_many(filter_) except pymongo.errors.OperationFailure as e: # see comment in :func:`insert()`. self.app.logger.exception(e) abort( 500, description=debug_error_message( "pymongo.errors.OperationFailure: %s" % e ), ) # TODO: The next three methods could be pulled out to form the basis # of a separate MonqoQuery class def combine_queries(self, query_a, query_b): """ Takes two db queries and applies db-specific syntax to produce the intersection. This is used because we can't just dump one set of query operators into another. Consider for example if the dataset contains a custom datasource pattern like -- 'filter': {'username': {'$exists': True}} If we simultaneously try to filter on the field `username`, then doing query_a.update(query_b) would lose information. This implementation of the function just combines everything in the two dicts using the `$and` operator. Note that this is exactly same as performing dict.update() except when multiple operators are operating on the /same field/. Example: combine_queries({'username': {'$exists': True}}, {'username': '******'}) {'$and': [{'username': {'$exists': True}}, {'username': '******'}]} .. versionadded: 0.1.0 Support for intelligent combination of db queries """ # Chain the operations with the $and operator return { "$and": [ {k: v} for k, v in itertools.chain(query_a.items(), query_b.items()) ] } def get_value_from_query(self, query, field_name): """ For the specified field name, parses the query and returns the value being assigned in the query. For example, get_value_from_query({'_id': 123}, '_id') 123 This mainly exists to deal with more complicated compound queries get_value_from_query( {'$and': [{'_id': 123}, {'firstname': 'mike'}], '_id' ) 123 .. versionadded: 0.1.0 Support for parsing values embedded in compound db queries """ if field_name in query: return query[field_name] elif "$and" in query: for condition in query["$and"]: if field_name in condition: return condition[field_name] raise KeyError def query_contains_field(self, query, field_name): """ For the specified field name, does the query contain it? Used know whether we need to parse a compound query. .. versionadded: 0.1.0 Support for parsing values embedded in compound db queries """ try: self.get_value_from_query(query, field_name) except KeyError: return False return True def is_empty(self, resource): """ Returns True if resource is empty; False otherwise. If there is no predefined filter on the resource we're relying on the db.collection.count_documents. However, if we do have a predefined filter we have to fallback on the find() method, which can be much slower. .. versionchanged:: 0.6 Support for multiple databases. .. versionadded:: 0.3 """ datasource, filter_, _, _ = self.datasource(resource) coll = self.pymongo(resource).db[datasource] try: if not filter_: # faster, but we can only afford it if there's now predefined # filter on the datasource. return coll.count_documents({}) == 0 else: # fallback on find() since we have a filter to apply. try: # need to check if the whole resultset is missing, no # matter the IMS header. del filter_[config.LAST_UPDATED] except: pass return coll.count_documents(filter_) == 0 except pymongo.errors.OperationFailure as e: # see comment in :func:`insert()`. self.app.logger.exception(e) abort( 500, description=debug_error_message( "pymongo.errors.OperationFailure: %s" % e ), ) def _mongotize(self, source, resource, parse_objectid=False): """ Recursively iterates a JSON dictionary, turning RFC-1123 strings into datetime values and ObjectId-link strings into ObjectIds. .. versionchanged:: 0.3 'query_objectid_as_string' allows to bypass casting string types to objectids. .. versionchanged:: 0.1.1 Renamed from _jsondatetime to _mongotize, as it now handles ObjectIds too. .. versionchanged:: 0.1.0 Datetime conversion was failing on Py2, since 0.0.9 :P .. versionchanged:: 0.0.9 support for Python 3.3. .. versionadded:: 0.0.4 """ resource_def = config.DOMAIN[resource] schema = resource_def.get("schema") id_field = resource_def["id_field"] id_field_versioned = versioned_id_field(resource_def) query_objectid_as_string = resource_def.get("query_objectid_as_string", False) parse_objectid = parse_objectid or not query_objectid_as_string def try_cast(k, v, should_parse_objectid): try: return datetime.strptime(v, config.DATE_FORMAT) except: if k in (id_field, id_field_versioned) or should_parse_objectid: try: # Convert to unicode because ObjectId() interprets # 12-character strings (but not unicode) as binary # representations of ObjectId's. See # https://github.com/pyeve/eve/issues/508 try: r = ObjectId(unicode(v)) except NameError: # We're on Python 3 so it's all unicode already. r = ObjectId(v) return r except: return v else: return v def get_schema_type(keys, schema): def dict_sub_schema(base): if base.get("type") == "dict": return base.get("schema") return base if not isinstance(schema, dict): return None if not keys: return schema.get("type") k = keys[0] keys = keys[1:] schema_type = schema[k].get("type") if k in schema else None if schema_type == "list": if "items" in schema[k]: items = schema[k].get("items") or [] possible_types = [get_schema_type(keys, item) for item in items] if "objectid" in possible_types: return "objectid" else: return next((t for t in possible_types if t), None) elif "schema" in schema[k]: # recursively check the schema return get_schema_type(keys, dict_sub_schema(schema[k]["schema"])) elif schema_type == "dict": if "schema" in schema[k]: return get_schema_type(keys, dict_sub_schema(schema[k]["schema"])) else: return schema_type for k, v in source.items(): keys = k.split(".") schema_type = get_schema_type(keys, schema) is_objectid = (schema_type == "objectid") or parse_objectid if isinstance(v, dict): self._mongotize(v, resource, is_objectid) elif isinstance(v, list): for i, v1 in enumerate(v): if isinstance(v1, dict): source[k][i] = self._mongotize(v1, resource) else: source[k][i] = try_cast(k, v1, is_objectid) elif isinstance(v, str_type): source[k] = try_cast(k, v, is_objectid) return source def _sanitize(self, resource, spec): """ Makes sure that only allowed operators are included in the query, aborts with a 400 otherwise. .. versionchanged:: 1.1.0 Add mongo_query_whitelist config option to extend the list of supported operators .. versionchanged:: 0.5 Abort with 400 if unsupported query operators are used. #387. DRY. .. versionchanged:: 0.0.9 More informative error messages. Allow ``auth_username_field`` to be set to ``ID_FIELD``. .. versionadded:: 0.0.7 """ def sanitize_keys(spec): ops = set([op for op in spec.keys() if op[0] == "$"]) known = Mongo.operators | set( config.DOMAIN[resource]["mongo_query_whitelist"] ) unknown = ops - known if unknown: abort( 400, description=debug_error_message( "Query contains unknown or unsupported operators: %s" % ", ".join(unknown) ), ) if set(spec.keys()) & set(config.MONGO_QUERY_BLACKLIST): abort( 400, description=debug_error_message( "Query contains operators banned in MONGO_QUERY_BLACKLIST" ), ) if isinstance(spec, dict): sanitize_keys(spec) for value in spec.values(): self._sanitize(resource, value) if isinstance(spec, list): for value in spec: self._sanitize(resource, value) return spec def _convert_sort_request_to_dict(self, req): """ Converts the contents of a `ParsedRequest`'s `sort` property to a dict """ client_sort = {} if req and req.sort: try: # assume it's mongo syntax (ie. ?sort=[("name", 1)]) client_sort = ast.literal_eval(req.sort) except ValueError: # it's not mongo so let's see if it's a comma delimited string # instead (ie. "?sort=-age, name"). sort = [] for sort_arg in [s.strip() for s in req.sort.split(",")]: if sort_arg[0] == "-": sort.append((sort_arg[1:], -1)) else: sort.append((sort_arg, 1)) if len(sort) > 0: client_sort = sort except Exception as e: self.app.logger.exception(e) abort(400, description=debug_error_message(str(e))) return client_sort def _convert_where_request_to_dict(self, resource, req): """ Converts the contents of a `ParsedRequest`'s `where` property to a dict """ query = {} if req and req.where: try: query = self._sanitize(resource, json.loads(req.where)) except HTTPException: # _sanitize() is raising an HTTP exception; let it fire. raise except: # couldn't parse as mongo query; give the python parser a shot. try: query = parse(req.where) except ParseError: abort( 400, description=debug_error_message( "Unable to parse `where` clause" ), ) return query def _wc(self, resource): """ Syntactic sugar for the current collection write_concern setting. .. versionadded:: 0.0.8 """ return config.DOMAIN[resource]["mongo_write_concern"] def current_mongo_prefix(self, resource=None): """ Returns the active mongo_prefix that should be used to retrieve a valid PyMongo instance from the cache. If 'self.mongo_prefix' is set it has precedence over both endpoint (resource) and default drivers. This allows Auth classes (for instance) to override default settings to use a user-reserved db instance. Even a standard Flask view can set the mongo_prefix: from flask import g g.mongo_prefix = 'MONGO2' :param resource: endpoint for which a mongo prefix is needed. ..versionchanged:: 0.7 Allow standard Flask views (@app.route) to set the mongo_prefix on their own. ..versionadded:: 0.6 """ # the hack below avoids passing the resource around, which would not be # an issue within this module but would force an update to the # eve.io.media.MediaStorage interface, possibly breaking compatibility # for other database implementations. auth = None try: if resource is None and request and request.endpoint: resource = request.endpoint[: request.endpoint.index("|")] if request and request.endpoint: auth = resource_auth(resource) except ValueError: pass px = auth.get_mongo_prefix() if auth else None if px is None: px = g.get("mongo_prefix", None) if px is None: if resource: px = config.DOMAIN[resource].get("mongo_prefix", "MONGO") else: px = "MONGO" return px def pymongo(self, resource=None, prefix=None): """ Returns an active PyMongo instance. If 'prefix' is defined then it has precedence over the endpoint ('resource') and/or 'self.mongo_instance'. :param resource: endpoint for which a PyMongo instance is requested. :param prefix: PyMongo instance key. This has precedence over both 'resource' and eventual `self.mongo_prefix'. .. versionadded:: 0.6 """ px = prefix if prefix else self.current_mongo_prefix(resource=resource) if px not in self.driver: # instantiate and add to cache self.driver[px] = PyMongo(self.app, px) # important, we don't want to preserve state between requests self.mongo_prefix = None try: return self.driver[px] except Exception as e: raise ConnectionException(e) def get_collection_with_write_concern(self, datasource, resource): """ Returns a pymongo Collection with the desired write_concern setting. PyMongo 3.0+ collections are immutable, yet we still want to allow the maintainer to change the write concern setting on the fly, hence the clone. .. versionadded:: 0.6.1 """ wc = WriteConcern(config.DOMAIN[resource]["mongo_write_concern"]["w"]) return self.pymongo(resource).db[datasource].with_options(write_concern=wc)