diff --git a/src/api/__init__.py b/src/api/__init__.py index 6c88e10..312906b 100644 --- a/src/api/__init__.py +++ b/src/api/__init__.py @@ -4,6 +4,8 @@ from flask import Flask app = Flask(__name__) +# Disable sorting of the jsonified data +app.config['JSON_SORT_KEYS'] = False from api.models import db import api.models diff --git a/src/api/controllers/projectController.py b/src/api/controllers/projectController.py index 6d4982e..cdb4a1e 100644 --- a/src/api/controllers/projectController.py +++ b/src/api/controllers/projectController.py @@ -1,4 +1,4 @@ -from api.models import db, Project +from api.models import db, Project, UserHasProject, ProjectLink class ProjectController: session = db.session() @@ -7,8 +7,48 @@ def create_project(self, **kwargs): self.session.add(project) self.session.commit() + return project + + def update_project(self, id, **kwargs): + project = Project.query.filter_by(id=id).first() + + if project == None: + return project + + for key, value in kwargs.items(): + setattr(project, key, value) + + db.session.commit() + + return project + def get_project(self, **kwargs): project = Project.query.filter_by(**kwargs).first() + + return project + + def get_all_projects(self, **kwargs): + all_projects = Project.query.all() + + return all_projects + + def delete_project(self, id): + # Remove all project's links + for link in ProjectLink.query.filter_by(project_id=id).all(): + db.session.delete(link) + + # Remove project from all users + for project in UserHasProject.query.filter_by(project_id=id).all(): + db.session.delete(project) + + project = Project.query.filter_by(id=id).first() + + if project == None: + return project + + db.session.delete(project) + db.session.commit() + return project -projectController = ProjectController() +projectController = ProjectController() \ No newline at end of file diff --git a/src/api/controllers/userController.py b/src/api/controllers/userController.py index a7806d2..fba76e8 100644 --- a/src/api/controllers/userController.py +++ b/src/api/controllers/userController.py @@ -1,4 +1,4 @@ -from api.models import db, User +from api.models import db, User, UserHasProject, UserLink class UserController: session = db.session() @@ -7,8 +7,48 @@ def create_user(self, **kwargs): self.session.add(user) self.session.commit() + return user + + def update_user(self, id, **kwargs): + user = User.query.filter_by(id=id).first() + + if user == None: + return user + + for key, value in kwargs.items(): + setattr(user, key, value) + + db.session.commit() + + return user + def get_user(self, **kwargs): user = User.query.filter_by(**kwargs).first() + + return user + + def get_all_users(self, **kwargs): + all_users = User.query.all() + + return all_users + + def delete_user(self, id): + # Remove all user's links + for link in UserLink.query.filter_by(user_id=id).all(): + db.session.delete(link) + + # Remove user from all projects + for project in UserHasProject.query.filter_by(user_id=id).all(): + db.session.delete(project) + + user = User.query.filter_by(id=id).first() + + if user == None: + return user + + db.session.delete(user) + db.session.commit() + return user userController = UserController() diff --git a/src/api/models/__init__.py b/src/api/models/__init__.py index 13a7a3c..57cc9a3 100644 --- a/src/api/models/__init__.py +++ b/src/api/models/__init__.py @@ -3,9 +3,16 @@ """ from sys import argv from datetime import datetime + from api.models.database import db, init_db -from api.models.userModel import UserHasProject, User, UserLink -from api.models.projectModel import Project, ProjectLink + +from api.models.userModel import User +from api.models.userLinkModel import UserLink +from api.models.projectModel import Project +from api.models.projectLinkModel import ProjectLink +from api.models.userHasProjectModel import UserHasProject +from api.models.userFeedbackModel import UserFeedback +from api.models.projectFeedbackModel import ProjectFeedback if '--reset-db' in argv: init_db(True) @@ -17,10 +24,12 @@ import datetime; user1 = User(name='Foe Joe') +user2 = User(name='Tommy Frich') +user3 = User(name='Limm Carter') link1 = UserLink(name='GitHub', url='https://github.com') user1.links.append(link1) -project1 = Project(name='Hello, World!', description='First project.', development_status=2, creation_date=datetime.datetime.now()) +project1 = Project(name='Hello, World!', repository="https://github.com/ProgrammingBuddies/programmingbuddies-api", description='First project.', development_status=2, creation_date=datetime.datetime.now()) link2 = ProjectLink(name='Reddit', url='https://reddit.com') project1.links.append(link2) @@ -29,6 +38,17 @@ user1.projects.append(userHasProject) +feedback1 = ProjectFeedback(rating=3, description="Cool project!", project_feed_author=user1, project=project1) +feedback2 = ProjectFeedback(rating=1, description="Not so cool!", project_feed_author=user2, project=project1) + +# project1.feedbacks.append(feedback1) +# project1.feedbacks.append(feedback2) + +feedback3 = UserFeedback(user_feed_author=user1, destination=user2, rating=5, description="Good guy!") +feedback4 = UserFeedback(user_feed_author=user3, destination=user2, rating=1, description="Poor guy!") + db.session.add(user1) +db.session.add(user2) +db.session.add(user3) db.session.commit() """ diff --git a/src/api/models/projectFeedbackModel.py b/src/api/models/projectFeedbackModel.py new file mode 100644 index 0000000..7e62061 --- /dev/null +++ b/src/api/models/projectFeedbackModel.py @@ -0,0 +1,8 @@ +from api.models import db + +class ProjectFeedback(db.Model): + id = db.Column(db.Integer, primary_key=True) + user_id = db.Column(db.Integer, db.ForeignKey('user.id')) + project_id = db.Column(db.Integer, db.ForeignKey('project.id')) + rating = db.Column(db.Integer, nullable=False) + description = db.Column(db.String(255), nullable=True) diff --git a/src/api/models/projectLinkModel.py b/src/api/models/projectLinkModel.py new file mode 100644 index 0000000..929d528 --- /dev/null +++ b/src/api/models/projectLinkModel.py @@ -0,0 +1,20 @@ +from api.models import db + +class ProjectLink(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(80), nullable=False) + url = db.Column(db.Text, nullable=False) + project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False) + + # todo: decide if this should contain project_id (it is already present in the model) + def as_dict(self): + obj_d = { + 'id': self.id, + 'name': self.name, + 'url': self.url, + 'project_id': self.project_id + } + return obj_d + + def __repr__(self): + return '' % self.name diff --git a/src/api/models/projectModel.py b/src/api/models/projectModel.py index 04be1fa..c9466ca 100644 --- a/src/api/models/projectModel.py +++ b/src/api/models/projectModel.py @@ -1,24 +1,35 @@ from api.models import db +from datetime import datetime + +from api.models.userHasProjectModel import UserHasProject +from api.models.projectLinkModel import ProjectLink class Project(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), nullable=False) description = db.Column(db.Text, nullable=False) languages = db.Column(db.Text) - development_status = db.Column(db.Integer, nullable=False) - creation_date = db.Column(db.DateTime, nullable=False) + development_status = db.Column(db.Integer, nullable=False, default=0) + creation_date = db.Column(db.DateTime, nullable=False, default=datetime.now()) release_date = db.Column(db.DateTime) + repository = db.Column(db.Text, nullable=False) users = db.relationship('UserHasProject', back_populates='project') links = db.relationship('ProjectLink', backref='project', lazy=True) + feedbacks = db.relationship('ProjectFeedback', backref='project') - def __repr__(self): - return '' % self.name - -class ProjectLink(db.Model): - id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String(80), nullable=False) - url = db.Column(db.Text, nullable=False) - project_id = db.Column(db.Integer, db.ForeignKey('project.id'), nullable=False) + def as_dict(self): + obj_d = { + 'id': self.id, + 'name': self.name, + 'description': self.description, + 'languages': self.languages, + 'development_status': self.development_status, + 'creation_date': self.creation_date, + 'release_date': self.release_date, + 'users': [ user.user_as_dict() for user in self.users ], + 'links': [ link.as_dict() for link in self.links ] + } + return obj_d def __repr__(self): - return '' % self.name \ No newline at end of file + return '' % self.name diff --git a/src/api/models/userFeedbackModel.py b/src/api/models/userFeedbackModel.py new file mode 100644 index 0000000..353111a --- /dev/null +++ b/src/api/models/userFeedbackModel.py @@ -0,0 +1,18 @@ +from api.models import db + +class UserFeedback(db.Model): + id = db.Column(db.Integer, primary_key=True) + author_id = db.Column(db.Integer, db.ForeignKey('user.id')) + user_id = db.Column(db.Integer, db.ForeignKey('user.id')) + rating = db.Column(db.Integer, nullable=False) + description = db.Column(db.String(255), nullable=True) + + def as_dict(self): + obj_d = { + 'id': self.id, + 'author': self.author_id, + 'user': self.user_id, + 'rating': self.rating, + 'description': self.description, + } + return obj_d diff --git a/src/api/models/userHasProjectModel.py b/src/api/models/userHasProjectModel.py new file mode 100644 index 0000000..5bc446e --- /dev/null +++ b/src/api/models/userHasProjectModel.py @@ -0,0 +1,14 @@ +from api.models import db + +class UserHasProject(db.Model): + user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True) + project_id = db.Column(db.Integer, db.ForeignKey('project.id'), primary_key=True) + user = db.relationship('User', back_populates='projects') + project = db.relationship('Project', back_populates='users') + role = db.Column(db.Integer, nullable=False) + + def user_as_dict(self): + return { 'user_id': self.user_id, 'role': self.role } + + def project_as_dict(self): + return { 'project_id': self.project_id, 'role': self.role } diff --git a/src/api/models/userLinkModel.py b/src/api/models/userLinkModel.py new file mode 100644 index 0000000..64fa5fa --- /dev/null +++ b/src/api/models/userLinkModel.py @@ -0,0 +1,19 @@ +from api.models import db + +class UserLink(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(80), nullable=False) + url = db.Column(db.Text, nullable=False) + user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) + + def as_dict(self): + obj_d = { + 'id': self.id, + 'name': self.name, + 'url': self.url, + 'user_id': self.user_id + } + return obj_d + + def __repr__(self): + return '' % self.name diff --git a/src/api/models/userModel.py b/src/api/models/userModel.py index 389d5e6..7084b32 100644 --- a/src/api/models/userModel.py +++ b/src/api/models/userModel.py @@ -1,11 +1,8 @@ from api.models import db -class UserHasProject(db.Model): - user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True) - project_id = db.Column(db.Integer, db.ForeignKey('project.id'), primary_key=True) - user = db.relationship('User', back_populates='projects') - project = db.relationship('Project', back_populates='users') - role = db.Column(db.Integer, nullable=False) +from api.models.userHasProjectModel import UserHasProject +from api.models.userLinkModel import UserLink +from api.models.projectFeedbackModel import ProjectFeedback class User(db.Model): id = db.Column(db.Integer, primary_key=True) @@ -17,15 +14,23 @@ class User(db.Model): occupation = db.Column(db.String(80)) projects = db.relationship('UserHasProject', back_populates='user') links = db.relationship('UserLink', backref='user', lazy=True) + project_feedbacks = db.relationship('ProjectFeedback', backref='project_feed_author') + user_feedbacks = db.relationship('UserFeedback', foreign_keys="UserFeedback.author_id", backref='user_feed_author') + received_feebacks = db.relationship('UserFeedback', foreign_keys="UserFeedback.user_id", backref='destination') - def __repr__(self): - return '' % self.name - -class UserLink(db.Model): - id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String(80), nullable=False) - url = db.Column(db.Text, nullable=False) - user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) + def as_dict(self): + obj_d = { + 'id': self.id, + 'name': self.name, + 'bio': self.bio, + 'languages': self.languages, + 'interests': self.interests, + 'location': self.location, + 'occupation': self.occupation, + 'projects': [ project.project_as_dict() for project in self.projects ], + 'links': [ link.as_dict() for link in self.links ] + } + return obj_d def __repr__(self): - return '' % self.name \ No newline at end of file + return '' % self.name diff --git a/src/api/views/__init__.py b/src/api/views/__init__.py index 82faa16..8820895 100644 --- a/src/api/views/__init__.py +++ b/src/api/views/__init__.py @@ -1,4 +1,4 @@ """ The views package """ -from api.views import userView, oauthView \ No newline at end of file +from api.views import userView, projectView, oauthView diff --git a/src/api/views/projectView.py b/src/api/views/projectView.py new file mode 100644 index 0000000..994f2dd --- /dev/null +++ b/src/api/views/projectView.py @@ -0,0 +1,43 @@ +from flask import request, jsonify +from api import app +from api.controllers import projectController + +@app.route("/projects", methods=['POST']) +def post_project(): + project = projectController.create_project(**request.get_json()) + + return jsonify(project.as_dict()), 201 + +@app.route("/projects/", methods=['POST']) +def update_project(id): + if 'id' in request.get_json(): + return "", 501 + project = projectController.update_project(id, **request.get_json()) + + return jsonify(project.as_dict()), 200 + +@app.route("/projects/", methods=['GET']) +def get_project(id): + project = projectController.get_project(id=id) + + if project: + return jsonify(project.as_dict()), 200 + else: + return "", 404 + +@app.route("/projects", methods=['GET']) +def get_all_projects(): + all_projects = projectController.get_all_projects() + + projects = [ project.as_dict() for project in all_projects ] + + return jsonify(projects), 200 + +@app.route("/projects/", methods=['DELETE']) +def delete_project(id): + project = projectController.delete_project(id) + + if project: + return "", 202 + else: + return "", 404 \ No newline at end of file diff --git a/src/api/views/userView.py b/src/api/views/userView.py index 4107d5b..b07d321 100644 --- a/src/api/views/userView.py +++ b/src/api/views/userView.py @@ -1,14 +1,43 @@ +from flask import request, jsonify from api import app - from api.controllers import userController -from flask import request -@app.route("/user/push", methods=['POST']) -def push_user(): - user = userController.create_user(**request.form) - return "200OK" +@app.route("/users", methods=['POST']) +def create_user(): + user = userController.create_user(**request.get_json()) + + return jsonify(user.as_dict()), 201 + +@app.route("/users/", methods=['POST']) +def update_user(id): + if 'id' in request.get_json(): + return "", 501 + user = userController.update_user(id, **request.get_json()) + + return jsonify(user.as_dict()), 200 + +@app.route("/users/", methods=['GET']) +def get_user(id): + user = userController.get_user(id=id) + + if user: + return jsonify(user.as_dict()), 200 + else: + return "", 404 + +@app.route("/users", methods=['GET']) +def get_all_users(): + all_users = userController.get_all_users() + + users = [ user.as_dict() for user in all_users ] + + return jsonify(users), 200 + +@app.route("/users/", methods=['DELETE']) +def delete_user(id): + user = userController.delete_user(id) -@app.route("/user/get/", methods=['GET']) -def get_user(name): - user = userController.get_user(username=name) - return user.username + if user: + return "", 200 + else: + return "", 404 \ No newline at end of file