From 0ecda7e966fb30958b110d2006f5a2944fa2cdde Mon Sep 17 00:00:00 2001 From: Alex Dudescu Date: Sat, 4 Nov 2023 20:39:44 +0200 Subject: [PATCH 1/4] Fixed tags and participants params for create activity endpoint --- backend/controller/activity_controller.py | 25 ++++++++++- backend/controller/login.py | 55 +++++++++++++++++++++++ backend/models/user.py | 14 +++--- backend/repository/user_repository.py | 9 +++- backend/services/user_service.py | 44 +++++++++++------- 5 files changed, 122 insertions(+), 25 deletions(-) create mode 100644 backend/controller/login.py diff --git a/backend/controller/activity_controller.py b/backend/controller/activity_controller.py index 605fdab..f624f1a 100644 --- a/backend/controller/activity_controller.py +++ b/backend/controller/activity_controller.py @@ -5,6 +5,7 @@ from services.activity_service import * from backend.services.activity_service import ActivityService from backend.services.location_service import LocationService +from backend.services.user_service import UserService from config import app import logging @@ -59,22 +60,42 @@ def get_activity_by_id(): @app.route('/activity', methods=['POST']) def create_activity(): + # TODO: fix tags and participants params (make them a list) print("Working") activity_service = ActivityService() location_service = LocationService() + user_service = UserService() try: data = json.loads(request.data) + location = data['location'] location_x = location.get('latitude') location_y = location.get('longitude') created_location = location_service.add_location(location_x, location_y) + + tags = data['tags'] + string_of_tags = "" + for tag in tags: + string_of_tags += tag + string_of_tags += ", " + string_of_tags = string_of_tags[:len(string_of_tags) - 2] + + participants = data['participants'] + string_of_participants = "" + for participant in participants: + user = user_service.get_user(participant) + if user is not None: + string_of_participants += user.display_name + string_of_participants += ", " + string_of_participants = string_of_participants[:len(string_of_participants) - 2] + created_activity = activity_service.add_activity(id=data['id'], name=data['title'], category=data['category'], description=data['description'], location_id=created_location.id, max_participants=data['maxParticipants'], start_date=data['date'], end_date=data['endDate'], - time=data['time'], tags=data['tags'], address=data['address'], - author=data['author'], participants=data['participants']) + time=data['time'], tags=string_of_tags, address=data['address'], + author=data['author'], participants=string_of_participants) return str(created_activity.id), 201 except Exception as error: diff --git a/backend/controller/login.py b/backend/controller/login.py new file mode 100644 index 0000000..41ef4e1 --- /dev/null +++ b/backend/controller/login.py @@ -0,0 +1,55 @@ +from flask import render_template, request, redirect, url_for, session +from backend.config import app +# from backend.repository.user_repo import get_account_by_username_and_password, get_account_by_username +from backend.services.user_service import UserService +from backend.models.user import User +import random +import string + +source = string.ascii_letters + string.digits + + +@app.route('/login', methods=['GET', 'POST']) +def login(): + service = UserService() + msg = '' + if request.method == 'POST' and 'username' in request.form and 'password' in request.form: + username = request.form['username'] + password = request.form['password'] + account = service.login(username, password) + if account: + session['loggedin'] = True + session['username'] = account.username + session['token'] = ''.join((random.choice(source) for i in range(8))) + msg = 'Logged in successfully! Token:' + session['token'] + else: + msg = 'Incorrect username / password !' + return render_template('login.html', msg=msg) + + +@app.route('/logout') +def logout(): + session.pop('loggedin', None) + session.pop('id', None) + session.pop('username', None) + return redirect(url_for('login')) + + +@app.route('/register', methods=['GET', 'POST']) +def register(): + service = UserService() + msg = '' + if request.method == 'POST' and 'username' in request.form and 'password' in request.form: + username = request.form['username'] + password = request.form['password'] + account = service.regiser(username) + if account: + msg = 'Account already exists!' + elif not username or not password: + msg = 'Please fill out the form!' + else: + service_add_user(User(username=username, password=password)) + msg = 'You have successfully registered !' + elif request.method == 'POST': + msg = 'Please fill out the form!' + return render_template('register.html', msg=msg) \ No newline at end of file diff --git a/backend/models/user.py b/backend/models/user.py index 8285b29..90bd8b1 100644 --- a/backend/models/user.py +++ b/backend/models/user.py @@ -10,22 +10,22 @@ class User(db.Model): # Functional Variables username: Mapped[str] = db.mapped_column(primary_key=True) - age: Mapped[int] = db.mapped_column() - display_name: Mapped[str] = db.mapped_column() + age: Mapped[int] = db.mapped_column(default=0) + display_name: Mapped[str] = db.mapped_column(default="") password: Mapped[str] = db.mapped_column() - profile_picture: Mapped[Optional[str]] = db.mapped_column + profile_picture: Mapped[Optional[str]] = db.mapped_column(default="") about: Mapped[str] = db.mapped_column() interests: Mapped[str] = db.mapped_column tags: Mapped[str] = db.mapped_column - activities_created: Mapped[str] = db.mapped_column(default=0) - activities_enrolled: Mapped[str] = db.mapped_column(default=0) - friends: Mapped[str] = db.mapped_column(default=0) + activities_created: Mapped[str] = db.mapped_column(default="") + activities_enrolled: Mapped[str] = db.mapped_column(default="") + activities_completed: Mapped[str] = db.mapped_column(default="") + friends: Mapped[str] = db.mapped_column(default="") # Other data rating: Mapped[Optional[float]] = db.mapped_column() - completed_activity_count: Mapped[int] = db.mapped_column(default=0) # favorite_category: Mapped[] diff --git a/backend/repository/user_repository.py b/backend/repository/user_repository.py index dc893b7..eb33269 100644 --- a/backend/repository/user_repository.py +++ b/backend/repository/user_repository.py @@ -4,4 +4,11 @@ class UserRepository(BaseRepository): def __init__(self): - self._model = User + self._model = User + + def get_user_by_username_and_password(self, username, password): + return User.query.filter_by(username=username, password=password) + + + def get_by_username(self, username): + return User.query.get(username) \ No newline at end of file diff --git a/backend/services/user_service.py b/backend/services/user_service.py index cf722c3..85edd4b 100644 --- a/backend/services/user_service.py +++ b/backend/services/user_service.py @@ -2,6 +2,7 @@ from repository.user_repository import UserRepository from backend.services.base_service import BaseService + # from backend.models.user import User # from backend.repository.user_repository import UserRepository @@ -10,25 +11,38 @@ class UserService(BaseService): _repo = UserRepository() - def add_user(self, username: str, age: int, display_name: str, password: str, completed_activity_count: int = 0, profile_picture: str = '', rating: float = None): - user = parse_user(username, age, display_name, password, completed_activity_count) + def add_user(self, username: str, age: int, display_name: str, password: str, profile_picture: str, rating: float, + about: str, interests: str, tags: str, activities_created: str, activities_enrolled: str, + activities_completed: str, friends: str): + user = self.parse_user(username, age, display_name, password, profile_picture, rating, about, interests, tags, + activities_created, activities_enrolled, activities_completed, friends) return self._repo.add(user) - + def remove_user(self, column, value): return self._repo.remove(column, value) - + def update_user(self, column, value, **kwargs): return self._repo.update(column, value, **kwargs) - - def get_user(self, user_id): - return self._repo.get_with_key(user_id) - - def get_all_users(self, ): + + def get_user(self, username): + return self._repo.get_by_username(username) + + def login(self, username, password): + return self._repo.get_user_by_username_and_password(username, password) + + def regiser(self, username): + return self._repo.get_user_by_username(username) + + def get_all_users(self): return self._repo.get_all() - - def rollback(self, ): + + def rollback(self): self._repo.rollback() - - - def parse_user(username: str, age: int, display_name: str, password: str, completed_activity_count: float, profile_picture: str = '', rating: float = None): - return User(username=username, age=age, display_name=display_name, password=password, completed_activity_count=completed_activity_count, profile_picture=profile_picture, rating=rating) \ No newline at end of file + + def parse_user(self, username: str, age: int, display_name: str, password: str, profile_picture: str, rating: float, + about: str, interests: str, tags: str, activities_created: str, activities_enrolled: str, + activities_completed: str, friends: str): + return User(username=username, age=age, display_name=display_name, password=password, + profile_picture=profile_picture, rating=rating, about=about, interests=interests, tags=tags, + activities_created=activities_created, activities_enrolled=activities_enrolled, + activities_completed=activities_completed, friends=friends) From 036123ce792a103e05e4bc7c1fa4858186f81210 Mon Sep 17 00:00:00 2001 From: Alex Dudescu Date: Fri, 10 Nov 2023 22:29:48 +0200 Subject: [PATCH 2/4] Create user and get all users endpoints now fully support tags and interests parameters --- backend/controller/activity_controller.py | 4 ++ backend/controller/user_controller.py | 82 +++++++++++++++++++---- backend/models/user.py | 6 +- backend/repository/user_repository.py | 8 ++- backend/services/user_service.py | 27 +++++--- 5 files changed, 100 insertions(+), 27 deletions(-) diff --git a/backend/controller/activity_controller.py b/backend/controller/activity_controller.py index f624f1a..f13d08d 100644 --- a/backend/controller/activity_controller.py +++ b/backend/controller/activity_controller.py @@ -102,3 +102,7 @@ def create_activity(): logging.error(error) activity_service.rollback() return jsonify(error.__str__(), 400) + + + + diff --git a/backend/controller/user_controller.py b/backend/controller/user_controller.py index 6f0d4e7..6d5ef86 100644 --- a/backend/controller/user_controller.py +++ b/backend/controller/user_controller.py @@ -1,33 +1,60 @@ import json -from flask import jsonify, request +from flask import jsonify, request -from services.user_service import UserService +from backend.services.user_service import UserService from config import app -from models.user import User +from backend.models.user import User import logging -@app.route('/users') + +@app.route('/users', methods=['GET']) def get_users(): - service = UserService() + service = UserService() try: users = service.get_all_users() - user_data = [{'username': user.username, 'age': user.age, 'display_name': user.display_name, - 'password': user.password} for user in users] + user_data = [ + {'username': user.username, + 'age': user.age, + 'display_name': user.display_name, + 'password': user.password, + 'about': user.about, + 'tags': user.tags, + 'interests': user.interests + } + for user in users] + return jsonify(user_data) - + except Exception as error: logging.error(error) - # return jsonify(error), 400 - return jsonify(400) + service.rollback() + return jsonify(error.__str__(), 400) @app.route('/user', methods=['POST']) def create_user(): - service = UserService() + service = UserService() try: data = json.loads(request.data) - created_user = service.add_user(username=data['username'], age=data['age'], display_name=data['name'], password="20john05") + + tags = data['tags'] + string_of_tags = "" + for tag in tags: + string_of_tags += tag + string_of_tags += "," + string_of_tags = string_of_tags[:len(string_of_tags) - 2] + + interests = data['interests'] + string_of_interests = "" + for interest in interests: + string_of_interests += interest + string_of_interests += "," + string_of_interests = string_of_interests[:len(string_of_interests) - 2] + + created_user = service.add_user(username=data['username'], age=data['age'], display_name=data['name'], + password="20john05", tags=string_of_tags, interests=string_of_interests, + about=data['about']) return created_user.username, 200 except Exception as error: @@ -35,3 +62,34 @@ def create_user(): service.rollback() return jsonify(error.__str__(), 400) +# TODO: finsih this endpoint +# @app.route('/edit_user', methods=['POST']) +# def edit_user(): +# user_service = UserService() +# try: +# data = json.loads(request.data) +# +# tags = data['tags'] +# string_of_tags = "" +# for tag in tags: +# string_of_tags += tag +# string_of_tags += ", " +# string_of_tags = string_of_tags[:len(string_of_tags) - 2] +# +# interests = data['interests'] +# string_of_interests = "" +# for interest in interests: +# string_of_interests += interest +# string_of_interests += ", " +# string_of_interests = string_of_interests[:len(string_of_interests) - 2] +# +# user_service.update_user_by_username(username=data['username'], new_display_name=data['name'], +# new_age=data['age'], new_rating=data['rating'], +# new_about=data['about'], new_tags=string_of_tags, +# new_interests=string_of_interests) +# return str(200) +# +# except Exception as error: +# logging.error(error) +# user_service.rollback() +# return jsonify(error.__str__(), 400) diff --git a/backend/models/user.py b/backend/models/user.py index 90bd8b1..b0ac05b 100644 --- a/backend/models/user.py +++ b/backend/models/user.py @@ -14,9 +14,9 @@ class User(db.Model): display_name: Mapped[str] = db.mapped_column(default="") password: Mapped[str] = db.mapped_column() profile_picture: Mapped[Optional[str]] = db.mapped_column(default="") - about: Mapped[str] = db.mapped_column() - interests: Mapped[str] = db.mapped_column - tags: Mapped[str] = db.mapped_column + about: Mapped[str] = db.mapped_column(default="") + interests: Mapped[str] = db.mapped_column(default="") + tags: Mapped[str] = db.mapped_column(default="") activities_created: Mapped[str] = db.mapped_column(default="") activities_enrolled: Mapped[str] = db.mapped_column(default="") activities_completed: Mapped[str] = db.mapped_column(default="") diff --git a/backend/repository/user_repository.py b/backend/repository/user_repository.py index eb33269..a9a3c07 100644 --- a/backend/repository/user_repository.py +++ b/backend/repository/user_repository.py @@ -1,5 +1,6 @@ from repository.base_repository import BaseRepository from models.user import User +from sqlalchemy import update class UserRepository(BaseRepository): @@ -9,6 +10,9 @@ def __init__(self): def get_user_by_username_and_password(self, username, password): return User.query.filter_by(username=username, password=password) - def get_by_username(self, username): - return User.query.get(username) \ No newline at end of file + return User.query.get(username) + + # def update_user(self, username, new_display_name, new_age, new_rating, new_about, new_interests, new_tags): + # return update(User).where(User.username == username).values( + # {"age": new_age}) diff --git a/backend/services/user_service.py b/backend/services/user_service.py index 85edd4b..d9c62ea 100644 --- a/backend/services/user_service.py +++ b/backend/services/user_service.py @@ -11,11 +11,13 @@ class UserService(BaseService): _repo = UserRepository() - def add_user(self, username: str, age: int, display_name: str, password: str, profile_picture: str, rating: float, - about: str, interests: str, tags: str, activities_created: str, activities_enrolled: str, - activities_completed: str, friends: str): - user = self.parse_user(username, age, display_name, password, profile_picture, rating, about, interests, tags, - activities_created, activities_enrolled, activities_completed, friends) + def add_user(self, username, age, display_name, password, about, interests, tags, activities_created: str = "", + activities_enrolled: str = "", activities_completed: str = "", friends: str = "", rating: int = 0, + profile_picture: str = ""): + user = self.parse_user(username=username, age=age, display_name=display_name, password=password, + about=about, interests=interests, tags=tags, + activities_created=activities_created, activities_enrolled=activities_enrolled, + activities_completed=activities_completed, friends=friends, rating=rating) return self._repo.add(user) def remove_user(self, column, value): @@ -24,6 +26,11 @@ def remove_user(self, column, value): def update_user(self, column, value, **kwargs): return self._repo.update(column, value, **kwargs) + # def update_user_by_username(self, username, new_display_name, new_age, new_rating, new_about, new_interests, + # new_tags): + # return self._repo.update_user(username, new_display_name, new_age, new_rating, new_about, new_interests, + # new_tags) + def get_user(self, username): return self._repo.get_by_username(username) @@ -39,10 +46,10 @@ def get_all_users(self): def rollback(self): self._repo.rollback() - def parse_user(self, username: str, age: int, display_name: str, password: str, profile_picture: str, rating: float, - about: str, interests: str, tags: str, activities_created: str, activities_enrolled: str, - activities_completed: str, friends: str): + def parse_user(self, username, age, display_name, password, about, interests, tags, activities_created: str = "", + activities_enrolled: str = "", activities_completed: str = "", friends: str = "", rating: int = 0, + profile_picture: str = ""): return User(username=username, age=age, display_name=display_name, password=password, - profile_picture=profile_picture, rating=rating, about=about, interests=interests, tags=tags, + about=about, interests=interests, tags=tags, activities_created=activities_created, activities_enrolled=activities_enrolled, - activities_completed=activities_completed, friends=friends) + activities_completed=activities_completed, friends=friends, rating=rating) From 08a680044f5f7ff1bb7ee286c0702262f60f6fe0 Mon Sep 17 00:00:00 2001 From: Alex Dudescu Date: Sun, 12 Nov 2023 18:37:16 +0200 Subject: [PATCH 3/4] Created edit_user endpoint --- backend/controller/user_controller.py | 60 +++++++++++++-------------- backend/repository/user_repository.py | 11 +++-- backend/services/user_service.py | 8 ++-- 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/backend/controller/user_controller.py b/backend/controller/user_controller.py index 6d5ef86..0303dac 100644 --- a/backend/controller/user_controller.py +++ b/backend/controller/user_controller.py @@ -61,35 +61,33 @@ def create_user(): logging.error(error) service.rollback() return jsonify(error.__str__(), 400) +@app.route('/edit_user', methods=['POST']) +def edit_user(): + user_service = UserService() + try: + data = json.loads(request.data) + + tags = data['tags'] + string_of_tags = "" + for tag in tags: + string_of_tags += tag + string_of_tags += "," + string_of_tags = string_of_tags[:len(string_of_tags) - 2] + + interests = data['interests'] + string_of_interests = "" + for interest in interests: + string_of_interests += interest + string_of_interests += "," + string_of_interests = string_of_interests[:len(string_of_interests) - 2] + + updated_user = user_service.update_user_by_username(username=data['username'], new_display_name=data['name'], + new_age=data['age'], new_rating=data['rating'], + new_about=data['about'], new_tags=string_of_tags, + new_interests=string_of_interests) + return jsonify(str(updated_user.username), 200) -# TODO: finsih this endpoint -# @app.route('/edit_user', methods=['POST']) -# def edit_user(): -# user_service = UserService() -# try: -# data = json.loads(request.data) -# -# tags = data['tags'] -# string_of_tags = "" -# for tag in tags: -# string_of_tags += tag -# string_of_tags += ", " -# string_of_tags = string_of_tags[:len(string_of_tags) - 2] -# -# interests = data['interests'] -# string_of_interests = "" -# for interest in interests: -# string_of_interests += interest -# string_of_interests += ", " -# string_of_interests = string_of_interests[:len(string_of_interests) - 2] -# -# user_service.update_user_by_username(username=data['username'], new_display_name=data['name'], -# new_age=data['age'], new_rating=data['rating'], -# new_about=data['about'], new_tags=string_of_tags, -# new_interests=string_of_interests) -# return str(200) -# -# except Exception as error: -# logging.error(error) -# user_service.rollback() -# return jsonify(error.__str__(), 400) + except Exception as error: + logging.error(error) + user_service.rollback() + return jsonify(error.__str__(), 400) diff --git a/backend/repository/user_repository.py b/backend/repository/user_repository.py index a9a3c07..727ff44 100644 --- a/backend/repository/user_repository.py +++ b/backend/repository/user_repository.py @@ -1,6 +1,6 @@ from repository.base_repository import BaseRepository from models.user import User -from sqlalchemy import update +from sqlalchemy import update, select class UserRepository(BaseRepository): @@ -13,6 +13,9 @@ def get_user_by_username_and_password(self, username, password): def get_by_username(self, username): return User.query.get(username) - # def update_user(self, username, new_display_name, new_age, new_rating, new_about, new_interests, new_tags): - # return update(User).where(User.username == username).values( - # {"age": new_age}) + def update_user(self, username, new_display_name, new_age, new_rating, new_about, new_interests, new_tags): + BaseRepository(User)._session.execute(update(self._model).where(self._model.username == username).values( + {'display_name': new_display_name, 'age': new_age, 'rating': new_rating, 'about': new_about, + 'interests': new_interests, 'tags': new_tags})) + BaseRepository(User)._session.commit() + return User.query.get(username) diff --git a/backend/services/user_service.py b/backend/services/user_service.py index d9c62ea..9479bc6 100644 --- a/backend/services/user_service.py +++ b/backend/services/user_service.py @@ -26,10 +26,10 @@ def remove_user(self, column, value): def update_user(self, column, value, **kwargs): return self._repo.update(column, value, **kwargs) - # def update_user_by_username(self, username, new_display_name, new_age, new_rating, new_about, new_interests, - # new_tags): - # return self._repo.update_user(username, new_display_name, new_age, new_rating, new_about, new_interests, - # new_tags) + def update_user_by_username(self, username, new_display_name, new_age, new_rating, new_about, new_interests, + new_tags): + return self._repo.update_user(username, new_display_name, new_age, new_rating, new_about, new_interests, + new_tags) def get_user(self, username): return self._repo.get_by_username(username) From fa4ea5eefd61538c11878d2e90c33cbe797ba850 Mon Sep 17 00:00:00 2001 From: Alex Dudescu Date: Sun, 12 Nov 2023 19:00:42 +0200 Subject: [PATCH 4/4] Created delete activity endpoint --- backend/controller/activity_controller.py | 15 +++++++++++++++ backend/repository/activity_repository.py | 6 ++++++ backend/services/activity_service.py | 2 ++ 3 files changed, 23 insertions(+) diff --git a/backend/controller/activity_controller.py b/backend/controller/activity_controller.py index f13d08d..dcaa94a 100644 --- a/backend/controller/activity_controller.py +++ b/backend/controller/activity_controller.py @@ -103,6 +103,21 @@ def create_activity(): activity_service.rollback() return jsonify(error.__str__(), 400) +@app.route('/delete_activity', methods=['DELETE']) +def delete_activity(): + activity_service = ActivityService() + try: + deleted_activity = activity_service.delete_activity(int(request.args.get('id'))) + return jsonify(str(deleted_activity.id), 200) + + except Exception as error: + logging.error(error) + # return jsonify(error), 400 + return "Not found", 404 + + + + diff --git a/backend/repository/activity_repository.py b/backend/repository/activity_repository.py index aec38e8..4c8a361 100644 --- a/backend/repository/activity_repository.py +++ b/backend/repository/activity_repository.py @@ -1,5 +1,6 @@ from repository.base_repository import BaseRepository from models.activity import Activity +from sqlalchemy import delete class ActivityRepository(BaseRepository): @@ -8,3 +9,8 @@ def __init__(self): def get_by_id(self, activity_id): return Activity.query.get(int(activity_id)) + def remove_activity(self, activity_id): + target = self.get_by_id(activity_id) + BaseRepository(Activity)._session.execute(delete(self._model).where(self._model.id == int(activity_id))) + BaseRepository(Activity)._session.commit() + return target diff --git a/backend/services/activity_service.py b/backend/services/activity_service.py index 8d3771d..078a3a4 100644 --- a/backend/services/activity_service.py +++ b/backend/services/activity_service.py @@ -25,6 +25,8 @@ def add_activity(self, id: int, name: str, category: str, description: str, loca def remove_activity(self, column, value): return self._repo.remove(column, value) + def delete_activity(self, activity_id): + return self._repo.remove_activity(activity_id) def update_activity(self, column, value, **kwargs): return self._repo.update(column, value, **kwargs)