def unregister(uuid, password): u = users.find_one({"_id": ObjectId(uuid), "password": passwd_hash(uuid, password)}) if u: users.remove(ObjectId(uuid)) return {"success": 1} else: return error.user_not_found(raw=True)
def stream(uuid, olderThan=None, newerThan=None, uid=None, list_id=None, type='normal'): ''' olderThan, newerThan: time since epoch (in milliseconds). uid: if exist, return uid's public messages. type: normal: the home timeline for uuid. mentions: messages mentioning uuid. unique: only one message specified by msg_uuid. user: messages published by uid. list: message published by users in list_id. ''' # setup basic query if type == 'unique': query = {'_id': ObjectId(msg_uuid)} elif type == 'normal': # uuid's home timeline u = get_user(uuid) following = u['following'] following_query = {'owner': {'$in': following + [u['_id']]}} mention_query = {'entities.mentions.mention': '@' + u['uid']} query = {'$or': [following_query, mention_query]} elif type == 'mentions': u = get_user(uuid) query = {'entities.mentions.mention': '@' + u['uid']} elif type == 'user': # get uid's public tweets target = find_user(uid) if target: query = {'owner': target['_id']} else: return error.user_not_found(raw=True) elif type == 'list': l = lists.find_one(ObjectId(list_id)) if l: query = {'owner': {'$in': l['people']}} else: return error.list_not_found(raw=True) else: return error.stream_type_not_supported(raw=True) # setup time constraints if olderThan or newerThan: query['timestamp'] = {} if olderThan: query['timestamp']['$lt'] = olderThan if newerThan: query['timestamp']['$gt'] = newerThan # then execute the query c = messages.find(query) \ .sort('timestamp', pymongo.DESCENDING) \ .batch_size(conf.stream_item_max) return _process_messages(uuid, c)
def remove_from_list(uuid, list_id, uid): u = find_user(uid) if not u: return error.user_not_found(raw=True) if not lists.find_one(ObjectId(list_id)): return error.list_not_found(raw=True) lists.update({'_id': ObjectId(list_id)}, {'$pull': {'people': u['_id']}}) return {'success': 1}
def remove_from_list(uuid, list_id, uid): u = find_user(uid) if not u: return error.user_not_found(raw=True) if not lists.find_one(ObjectId(list_id)): return error.list_not_found(raw=True) lists.update({"_id": ObjectId(list_id)}, {"$pull": {"people": u["_id"]}}) return {"success": 1}
def recommend_user(uuid): """ naive user recommendation. """ # TODO more reasonable recommendation u = get_user(uuid) if u: return list(users.find({"_id": {"$nin": u["following"] + [u["_id"]]}}).limit(conf.stream_item_max)) else: return error.user_not_found(raw=True)
def unfollow(uuid, target): # TODO check result u = find_user(target) if u: users.update({"_id": ObjectId(uuid)}, {"$pull": {"following": u["_id"]}}) users.update({"_id": u["_id"]}, {"$pull": {"follower": ObjectId(uuid)}}) return {"success": 1} else: return error.user_not_found(raw=True)
def get_follower(uuid, uid, skip=0): u = find_user(uid) if not u: return error.user_not_found(raw=True) max_index = skip + conf.stream_item_max ret = {"has_more": max_index < len(u["following"]), "items": [get_user(x) for x in u["follower"][skip:max_index]]} for user in ret["items"]: user["isfollowing"] = ObjectId(uuid) in user["follower"] return ret
def unregister(uuid, password): u = users.find_one({ '_id': ObjectId(uuid), 'password': passwd_hash(uuid, password) }) if u: users.remove(ObjectId(uuid)) return {'success': 1} else: return error.user_not_found(raw=True)
def follow(uuid, target): """ make uid follow target """ u = find_user(target) if u: # TODO check result users.update({"_id": ObjectId(uuid)}, {"$addToSet": {"following": u["_id"]}}) users.update({"_id": u["_id"]}, {"$addToSet": {"follower": ObjectId(uuid)}}) return {"success": 1} else: return error.user_not_found(raw=True)
def get_follower(uuid, uid, skip=0): u = find_user(uid) if not u: return error.user_not_found(raw=True) max_index = skip + conf.stream_item_max ret = { 'has_more': max_index < len(u['following']), 'items': [get_user(x) for x in u['follower'][skip:max_index]] } for user in ret['items']: user['isfollowing'] = ObjectId(uuid) in user['follower'] return ret
def stream(uuid, olderThan=None, newerThan=None, uid=None, list_id=None, type="normal"): """ olderThan, newerThan: time since epoch (in milliseconds). uid: if exist, return uid's public messages. type: normal: the home timeline for uuid. mentions: messages mentioning uuid. unique: only one message specified by msg_uuid. user: messages published by uid. list: message published by users in list_id. """ # setup basic query if type == "unique": query = {"_id": ObjectId(msg_uuid)} elif type == "normal": # uuid's home timeline u = get_user(uuid) following = u["following"] following_query = {"owner": {"$in": following + [u["_id"]]}} mention_query = {"entities.mentions.mention": "@" + u["uid"]} query = {"$or": [following_query, mention_query]} elif type == "mentions": u = get_user(uuid) query = {"entities.mentions.mention": "@" + u["uid"]} elif type == "user": # get uid's public tweets target = find_user(uid) if target: query = {"owner": target["_id"]} else: return error.user_not_found(raw=True) elif type == "list": l = lists.find_one(ObjectId(list_id)) if l: query = {"owner": {"$in": l["people"]}} else: return error.list_not_found(raw=True) else: return error.stream_type_not_supported(raw=True) # setup time constraints if olderThan or newerThan: query["timestamp"] = {} if olderThan: query["timestamp"]["$lt"] = olderThan if newerThan: query["timestamp"]["$gt"] = newerThan # then execute the query c = messages.find(query).sort("timestamp", pymongo.DESCENDING).batch_size(conf.stream_item_max) return _process_messages(uuid, c)
def recommend_user(uuid): ''' naive user recommendation. ''' # TODO more reasonable recommendation u = get_user(uuid) if u: return list( users.find({ '_id': { '$nin': u['following'] + [u['_id']] } }).limit(conf.stream_item_max)) else: return error.user_not_found(raw=True)
def unfollow(uuid, target): # TODO check result u = find_user(target) if u: users.update({'_id': ObjectId(uuid)}, {'$pull': { 'following': u['_id'] }}) users.update({'_id': u['_id']}, {'$pull': { 'follower': ObjectId(uuid) }}) return {'success': 1} else: return error.user_not_found(raw=True)
def get_lists(uuid, uid=None): target = ObjectId(uuid) if uid: u = find_user(uid) if u: target = u['_id'] else: return error.user_not_found(raw=True) ret = list(lists.find({'curator': target})) for item in ret: item['id'] = str(item['_id']) u = get_user(item['curator']) item['curator'] = u and u['uid'] or '!invalid' return ret
def get_lists(uuid, uid=None): target = ObjectId(uuid) if uid: u = find_user(uid) if u: target = u["_id"] else: return error.user_not_found(raw=True) ret = list(lists.find({"curator": target})) for item in ret: item["id"] = str(item["_id"]) u = get_user(item["curator"]) item["curator"] = u and u["uid"] or "!invalid" return ret
def follow(uuid, target): ''' make uid follow target ''' u = find_user(target) if u: # TODO check result users.update({'_id': ObjectId(uuid)}, {'$addToSet': { 'following': u['_id'] }}) users.update({'_id': u['_id']}, {'$addToSet': { 'follower': ObjectId(uuid) }}) return {'success': 1} else: return error.user_not_found(raw=True)
def GET(self, action): web.header("Content-Type", "application/json") set_no_cache() # check if we have the action if action not in self.GET_ACTIONS: return error.wrong_action() # get the input data if we have the spec if action in self.VALIDATE_SPECS: d = get_input(self.VALIDATE_SPECS[action]) uuid = session.get("uuid", None) if not uuid: return error.not_logged_in() if action == "stream": param = spec.extract(self.EXTRACT_SPECS["stream_request"], d) if param["type"] == "user": if not param["uid"]: raise web.badrequest() elif param["type"] == "list": if not param["list_id"]: raise web.badrequest() ret = db.stream(uuid, **param) if "error" in ret: return jsond(ret) else: return jsond(spec.extract(self.EXTRACT_SPECS["stream_response"], ret)) elif action == "current_user": u = db.get_user(uuid) return jsond(spec.extract(self.EXTRACT_SPECS["current_user"], u)) elif action == "userinfo": u = db.find_user(d.uid) if not u: return error.user_not_found() u["isfollowing"] = bson.objectid.ObjectId(uuid) in u["follower"] return jsond(spec.extract(self.EXTRACT_SPECS["userinfo"], u)) elif action == "get_following": param = spec.extract(self.EXTRACT_SPECS["userlist_request"], d) ret = db.get_following(uuid, **param) new_items = [spec.extract(self.EXTRACT_SPECS["userinfo"], u) for u in ret["items"]] ret["items"] = new_items return jsond(ret) elif action == "get_follower": param = spec.extract(self.EXTRACT_SPECS["userlist_request"], d) ret = db.get_follower(uuid, **param) new_items = [spec.extract(self.EXTRACT_SPECS["userinfo"], u) for u in ret["items"]] ret["items"] = new_items return jsond(ret) elif action == "get_message": ret = db.get_message(uuid, d.msg_id) if "error" in ret: return jsond(ret) else: return jsond(spec.extract(self.EXTRACT_SPECS["stream_response"], ret)) elif action == "validate": act = d.action if act in self.VALIDATE_SPECS: errors = spec.validate(self.VALIDATE_SPECS[act], web.input()) if errors: return jsond(errors) else: return jsond({"success": 1}) else: return error.wrong_action() elif action == "recommend_user": return jsond({"users": [spec.extract(self.EXTRACT_SPECS["userinfo"], u) for u in db.recommend_user(uuid)]}) elif action == "get_lists": ret = db.get_lists(uuid, d.get("uid")) if "error" in ret: return jsond(ret) else: return jsond({"items": [spec.extract(self.EXTRACT_SPECS["listinfo"], l) for l in ret]}) elif action == "get_list_info": ret = db.get_list_info(uuid, d["id"]) if "error" in ret: return jsond(ret) else: return jsond(spec.extract(self.EXTRACT_SPECS["listinfo"], ret)) elif action == "get_list_users": param = spec.extract(self.EXTRACT_SPECS["list_userlist_request"], d) ret = db.get_list_users(uuid, param["id"], param["skip"]) new_items = [spec.extract(self.EXTRACT_SPECS["userinfo"], u) for u in ret["items"]] ret["items"] = new_items return jsond(ret) elif action == "search": req = spec.extract(self.EXTRACT_SPECS["search_request"], d) ret = db.search(uuid, **req) if "error" in ret: return jsond(ret) else: return jsond(spec.extract(self.EXTRACT_SPECS["stream_response"], ret)) return error.not_implemented()
def GET(self, action): web.header('Content-Type', 'application/json') set_no_cache() # check if we have the action if action not in self.GET_ACTIONS: return error.wrong_action() # get the input data if we have the spec if action in self.VALIDATE_SPECS: d = get_input(self.VALIDATE_SPECS[action]) uuid = session.get('uuid', None) if not uuid: return error.not_logged_in() if action == 'stream': param = spec.extract(self.EXTRACT_SPECS['stream_request'], d) if param['type'] == 'user': if not param['uid']: raise web.badrequest() elif param['type'] == 'list': if not param['list_id']: raise web.badrequest() ret = db.stream(uuid, **param) if 'error' in ret: return jsond(ret) else: return jsond( spec.extract(self.EXTRACT_SPECS['stream_response'], ret)) elif action == 'current_user': u = db.get_user(uuid) return jsond(spec.extract(self.EXTRACT_SPECS['current_user'], u)) elif action == 'userinfo': u = db.find_user(d.uid) if not u: return error.user_not_found() u['isfollowing'] = bson.objectid.ObjectId(uuid) in u['follower'] return jsond(spec.extract(self.EXTRACT_SPECS['userinfo'], u)) elif action == 'get_following': param = spec.extract(self.EXTRACT_SPECS['userlist_request'], d) ret = db.get_following(uuid, **param) new_items = [ spec.extract(self.EXTRACT_SPECS['userinfo'], u) for u in ret['items'] ] ret['items'] = new_items return jsond(ret) elif action == 'get_follower': param = spec.extract(self.EXTRACT_SPECS['userlist_request'], d) ret = db.get_follower(uuid, **param) new_items = [ spec.extract(self.EXTRACT_SPECS['userinfo'], u) for u in ret['items'] ] ret['items'] = new_items return jsond(ret) elif action == 'get_message': ret = db.get_message(uuid, d.msg_id) if 'error' in ret: return jsond(ret) else: return jsond( spec.extract(self.EXTRACT_SPECS['stream_response'], ret)) elif action == 'validate': act = d.action if act in self.VALIDATE_SPECS: errors = spec.validate(self.VALIDATE_SPECS[act], web.input()) if errors: return jsond(errors) else: return jsond({'success': 1}) else: return error.wrong_action() elif action == 'recommend_user': return jsond({ 'users': [ spec.extract(self.EXTRACT_SPECS['userinfo'], u) for u in db.recommend_user(uuid) ] }) elif action == 'get_lists': ret = db.get_lists(uuid, d.get('uid')) if 'error' in ret: return jsond(ret) else: return jsond({ 'items': [ spec.extract(self.EXTRACT_SPECS['listinfo'], l) for l in ret ] }) elif action == 'get_list_info': ret = db.get_list_info(uuid, d['id']) if 'error' in ret: return jsond(ret) else: return jsond(spec.extract(self.EXTRACT_SPECS['listinfo'], ret)) elif action == 'get_list_users': param = spec.extract(self.EXTRACT_SPECS['list_userlist_request'], d) ret = db.get_list_users(uuid, param['id'], param['skip']) new_items = [ spec.extract(self.EXTRACT_SPECS['userinfo'], u) for u in ret['items'] ] ret['items'] = new_items return jsond(ret) elif action == 'search': req = spec.extract(self.EXTRACT_SPECS['search_request'], d) ret = db.search(uuid, **req) if 'error' in ret: return jsond(ret) else: return jsond( spec.extract(self.EXTRACT_SPECS['stream_response'], ret)) return error.not_implemented()