From 7ede351b11a173b5e2ad5c7825763d77ed5eb200 Mon Sep 17 00:00:00 2001 From: Mattia Succurro Date: Mon, 4 Nov 2019 22:09:04 +0100 Subject: [PATCH] Adding profile_feed and profile_search endpoints --- CHANGELOG.md | 2 +- app/api.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1989d5..31583dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ * Added the capability to change password. * Corrected a bug into `pwdhash`: it accepted an argument, but pulled data from the form instead of processing it. Now it uses the argument. * Schema changes: added column `telegram` to `UserProfile` table. To update schema, execute the script `migrate_0_6_to_0_7.py` -* Adding public API. Each of the API endpoints take a mandatory query string argument: the access token, generated by a separate endpoint at `/get_access_token` and stored into the client. All API routes start with `/api/V1`. Added endpoints `feed`, `create` and `profile_info`. +* Adding public API. Each of the API endpoints take a mandatory query string argument: the access token, generated by a separate endpoint at `/get_access_token` and stored into the client. All API routes start with `/api/V1`. Added endpoints `feed`, `create`, `profile_info`, `profile_feed` and `profile_search`. ## 0.6.0 diff --git a/app/api.py b/app/api.py index 1393ce9..0c9abd9 100644 --- a/app/api.py +++ b/app/api.py @@ -1,7 +1,7 @@ from flask import Blueprint, jsonify, request import sys, datetime, re from functools import wraps -from .models import User, Message +from .models import User, Message, Relationship from .utils import check_access_token, Visibility bp = Blueprint('api', __name__, url_prefix='/api/V1') @@ -37,7 +37,7 @@ def validate_access(func): result = func(user, *args, **kwargs) assert isinstance(result, dict) except Exception: - sys.excepthook(*sys.exc_info()) + import traceback; traceback.print_exc() return jsonify({ 'message': str(sys.exc_info()[1]), 'status': 'fail' @@ -95,13 +95,24 @@ def create(self): except User.DoesNotExist: pass +def get_relationship_info(self, other): + if self == other: + return + return { + "following": self.is_following(other), + "followed_by": other.is_following(self) + } + @bp.route('/profile_info/', methods=['GET']) @validate_access def profile_info(self, userid): if userid == 'self': user = self elif userid.isdigit(): - user = User[id] + try: + user = User[userid] + except User.DoesNotExist: + return {'user': None} else: raise ValueError('userid should be an integer or "self"') profile = user.profile @@ -115,5 +126,50 @@ def profile_info(self, userid): "generation": profile.year, "instagram": profile.instagram, "facebook": profile.facebook, + "relationships": get_relationship_info(self, user) } } + +@bp.route('/profile_info/feed/', methods=['GET']) +@validate_access +def profile_feed(self, userid): + if userid == 'self': + user = self + elif userid.isdigit(): + user = User[userid] + else: + raise ValueError('userid should be an integer or "self"') + timeline_media = [] + date = request.args.get('offset') + if date is None: + date = datetime.datetime.now() + else: + date = datetime.datetime.fromtimestamp(date) + query = Visibility(Message + .select() + .where((Message.user == user) + & (Message.pub_date < date)) + .order_by(Message.pub_date.desc()) + .limit(20)) + for message in query: + timeline_media.append(get_message_info(message)) + return {'timeline_media': timeline_media} + +@bp.route('/profile_search', methods=['POST']) +@validate_access +def profile_search(self): + data = request.get_json(True) + query = User.select().where(User.username ** ('%' + data['q'] + '%')).limit(20) + results = [] + for result in query: + profile = result.profile + result.append({ + "id": result.id, + "username": result.username, + "full_name": result.profile.full_name, + "followers_count": len(result.followers()) + }) + return { + "users": results + } +