diff --git a/SE_API/API.py b/SE_API/API.py index bbf7921..a1ad212 100644 --- a/SE_API/API.py +++ b/SE_API/API.py @@ -6,6 +6,7 @@ from GithubAPI.GithubAPI import GitHubAPI_Keys from google.appengine.ext import db import requests import uuid +import datetime from flask import Flask, request, render_template, redirect, abort, Response @@ -19,15 +20,23 @@ from models.Course import Course from models.Project import Project from models.Campus import Campus -#Validation Utils Libs +# All API from SE_API.Validation_Utils import * from SE_API.Respones_Utils import * +from SE_API.Email_Utils import * + +from SE_API.UserRoutes import user_routes +from SE_API.CampusRoutes import campus_routes +from SE_API.CourseRoutes import course_routes +from SE_API.ProjectRoutes import project_routes app = Flask(__name__, static_folder='../templates') + + githubKeys = GitHubAPI_Keys() app.config['GITHUB_CLIENT_ID'] = githubKeys.getId() @@ -35,6 +44,12 @@ app.config['GITHUB_CLIENT_SECRET'] = githubKeys.getSecret() github = GitHub(app) cross = CORS(app) + +app.register_blueprint(user_routes) +app.register_blueprint(campus_routes) +app.register_blueprint(course_routes) +app.register_blueprint(project_routes) + auto = Autodoc(app) @app.errorhandler(404) @@ -108,29 +123,28 @@ def send_activation(token): 403 - Invalid Token
""" if not request.data: - return Response(response=json.dumps({'message': 'Bad Request'}), - status=400, - mimetype="application/json") + return bad_request() payload = json.loads(request.data) if not is_user_token_valid(token): - return Response(response=json.dumps({'message': 'Not A Valid Token!'}), - status=403, - mimetype="application/json") + return forbidden("Not A Valid Token!") + query = User.all() query.filter('seToken =', token) for u in query.run(limit=1): try: send_validation_email(token=token, name=u.username, email=payload["email"]) except Exception: - return Response(response=json.dumps({'message': 'Bad Request'}), - status=400, - mimetype="application/json") + return bad_request() return Response(status=200) @app.route('/api/help') def documentation(): - return auto.html() + return app.send_static_file('API_Doc/api_doc_index.html') + +# @app.route('/api/help/campuses') +# def documentation(): +# return auto.html() @app.route('/home') def returnHome(): @@ -141,51 +155,6 @@ def returnHome(): -@app.route('/api/getUserByToken/', methods=["GET"]) -@auto.doc() -def getUserByToken(token): - ''' - This Function is will Activate a user and add tha campus to it -
- Route Parameters
- - validation_token: 'seToken|email_suffix' -
-
- Payload
- - NONE -
-
- Response -
- 200 - JSON Example:
- - {
- 'username' : 'github_username',
- 'name' : 'Bob Dylan',
- 'email' : 'email@domain.com',
- 'isLecturer' : true,
- 'seToken' : 'dds2d-sfvvsf-qqq-fdf33-sfaa',
- 'avatar_url' : 'http://location.domain.com/image.jpg',
- 'isFirstLogin' : false,
- 'campuses_id_list': ['22314','243512',...,'356'],
- 'classes_id_list': ['22314','243512',...,'356']
- } -
-
- 403 - Invalid Token - ''' - query = User.all() - query.filter("seToken = ", token) - - for u in query.run(limit=5): - return Response(response=u.to_JSON(), - status=201, - mimetype="application/json") # Real response! - - return Response(response=json.dumps({'message' : 'No User Found'}), - status=400, - mimetype="application/json") - @app.route('/githubOAuth') @@ -229,114 +198,6 @@ def oauth(oauth_token): return cookieMonster(user.seToken) -@app.route('/api/Campuses/create/', methods=['POST']) -@auto.doc() -def create_campus(token): - """ - This call will create a new campus in the DB -
- Route Parameters
- - seToken: 'seToken' -
-
- Payload
- - JSON Object, Example:
- {
- 'title': 'Campus name',
- 'email_ending': '@campus.ac.com',
- 'avatar_url': 'http://location.domain.com/image.jpg'
- }
-
-
- Response -
- 201 - Created -
- 403 - Invalid Token/Forbidden - """ - print "1\n" - if not request.data: - return Response(response=json.dumps({'message': 'Bad Request0'}), - status=400, - mimetype="application/json") - payload = json.loads(request.data) - if not is_lecturer(token): #todo: change to lecturer id - return Response(response=json.dumps({'message': 'Invalid token or not a lecturer!'}), - status=403, - mimetype="application/json") - - user = get_user_by_token(token) - - #todo: check legality - - try: - campus = Campus(title=payload['title'], email_ending=payload['email_ending'], master_user_id=user.key().id(), avatar_url=payload['avatar_url']) - except Exception: - return Response(response=json.dumps({'message': 'Bad Request1'}), - status=400, - mimetype="application/json") - - db.put(campus) - db.save - return Response(response=json.dumps(campus.to_JSON()), - status=201, - mimetype="application/json") - - - - -@app.route('/api/Campuses/', methods=['GET']) -@auto.doc() -def get_campuses(token): - """ - This Call will return an array of all Campuses available -
- Route Parameters
- - seToken: 'seToken' -
-
- Payload
- - NONE
-
-
- Response -
- 200 - JSON Array, Example:
- [
- { - 'title': 'JCE',
- 'email_ending': '@post.jce.ac.il',
- 'master_user_id': 123453433341, (User that created the campus)
- 'avatar_url': 'http://some.domain.com/imagefile.jpg'
- },
- ....
- {
- ...
- }req
- ]
-
- 403 - Invalid Token
- 500 - Server Error - """ - if is_user_token_valid(token): - arr = [] - query = Campus.all() - for c in query.run(): - arr.append(dict(json.loads(c.to_JSON()))) - print arr - if len(arr) != 0: - return Response(response=json.dumps(arr), - status=200, - mimetype="application/json") - else: - return Response(response=[], - status=200, - mimetype="application/json") - else: - return Response(response=json.dumps({'message': 'Invalid Token'}), - status=403, - mimetype="application/json") - @app.route('/login') @@ -385,3 +246,5 @@ def cookieMonster(uid): response = app.make_response(redirect_to_home ) response.set_cookie('com.sehub.www',value=uid) return response + + diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py new file mode 100644 index 0000000..11af4b3 --- /dev/null +++ b/SE_API/CampusRoutes.py @@ -0,0 +1,144 @@ +__author__ = 'Aran' + +from flask import Blueprint +import json +from GithubAPI.GithubAPI import GitHubAPI_Keys + +from google.appengine.ext import db +import requests +import datetime + +from flask import Flask, request, render_template, redirect, abort, Response + +from flask.ext.github import GitHub +from flask.ext.cors import CORS, cross_origin +from flask.ext.autodoc import Autodoc + +# DB Models +from models.Campus import Campus + +#Validation Utils Libs +from SE_API.Validation_Utils import * +from SE_API.Respones_Utils import * +from SE_API.Email_Utils import * + + + +campus_routes = Blueprint("campus_routes", __name__) +auto = Autodoc() + +@campus_routes.route('/api/campuses/create/', methods=['POST']) +@auto.doc() +def create_campus(token): + """ + This call will create a new campus in the DB +
+ Route Parameters
+ - seToken: 'seToken' +
+
+ Payload
+ - JSON Object, Example:
+ {
+ 'title': 'Campus name',
+ 'email_ending': '@campus.ac.com',
+ 'avatar_url': 'http://location.domain.com/image.jpg'
+ }
+
+
+ Response +
+ 201 - Created +
+ 403 - Invalid Token/Forbidden + """ + if not request.data: + return bad_request() + if not is_lecturer(token): #todo: change to lecturer id + return forbidden("Invalid token or not a lecturer!") + + #try to parse payload + try: + payload = json.loads(request.data) + except Exception as e: + return bad_request(e) + + #check if name already exists + try: + query = Campus.all() + query.filter("title = ", payload['title']) + for c in query.run(limit=1): + return forbidden("Campus with same name already exists") + except Exception as e: + print e + + user = get_user_by_token(token) + + try: + campus = Campus(title=payload['title'], email_ending=payload['email_ending'], master_user_id=user.key().id(), avatar_url=payload['avatar_url']) + except Exception: + return bad_request() + + + send_create_campus_request(user.email, user.name, campus.title) + notify_se_hub_campus_request(campus, campus.title) + return ok() + + + + + +@campus_routes.route('/api/campuses/getAll/', methods=['GET']) +@auto.doc() +def get_campuses(token): + """ + This Call will return an array of all Campuses available +
+ Route Parameters
+ - seToken: 'seToken' +
+
+ Payload
+ - NONE
+
+
+ Response +
+ 200 - JSON Array, Example:
+ [
+ { + 'title': 'JCE',
+ 'email_ending': '@post.jce.ac.il',
+ 'master_user_id': 123453433341, (User that created the campus)
+ 'avatar_url': 'http://some.domain.com/imagefile.jpg'
+ },
+ ....
+ {
+ ...
+ }req
+ ]
+
+ 403 - Invalid Token
+ """ + if is_user_token_valid(token): + arr = [] + query = Campus.all() + for c in query.run(): + arr.append(dict(json.loads(c.to_JSON()))) + print arr + if len(arr) != 0: + return Response(response=json.dumps(arr), + status=200, + mimetype="application/json") + else: + return Response(response=[], + status=200, + mimetype="application/json") + else: + return forbidden("Invalid Token") + + + +@campus_routes.route('/api/campuses/help') +def documentation(): + return auto.html() diff --git a/SE_API/CourseRoutes.py b/SE_API/CourseRoutes.py new file mode 100644 index 0000000..4bae4ea --- /dev/null +++ b/SE_API/CourseRoutes.py @@ -0,0 +1,153 @@ +__author__ = 'Aran' + +from flask import Blueprint +import json +from GithubAPI.GithubAPI import GitHubAPI_Keys + +from google.appengine.ext import db +import requests +import datetime + +from flask import Flask, request, render_template, redirect, abort, Response + +from flask.ext.github import GitHub +from flask.ext.cors import CORS, cross_origin +from flask.ext.autodoc import Autodoc + +# DB Models +from models.Course import Course + +#Validation Utils Libs +from SE_API.Validation_Utils import * +from SE_API.Respones_Utils import * + + + +course_routes = Blueprint("course_routes", __name__) +auto = Autodoc() + + +@course_routes.route('/api/courses/create/', methods=['POST']) +@auto.doc() +def create_course(token): + """ + This call will create a new course in the DB +
+ Route Parameters
+ - seToken: 'seToken' +
+
+ Payload
+ - JSON Object, Example:
+ {
+ 'courseName': 'Advance Math',
+ 'campusName': 'JCE',
+ 'startDate': '2015-14-3'
+ 'endDate': '2015-29-6'
+ 'taskFlag': 'False'
+ }
+
+
+ Response +
+ 201 - Created +
+ 400 - Bad Request +
+ 403 - Invalid token or not a lecturer + """ + if not request.data: + return bad_request() + if not is_lecturer(token): #todo: change to lecturer id + return forbidden("Invalid token or not a lecturer!") + + user = get_user_by_token(token) + + #try to parse payload + try: + payload = json.loads(request.data) + except Exception as e: + return bad_request(e) + + + try: + start_date = datetime.date(payload['startDate']['year'],payload['startDate']['month'],payload['startDate']['day']) + end_date = datetime.date(payload['endDate']['year'],payload['endDate']['month'],payload['endDate']['day']) + + if end_date <= start_date: + return bad_request("end date cant be before (or same day) start date") + + course = Course(courseName=payload['courseName'], campusName=payload['campusName'], + startDate=start_date, endDate=end_date) + + #check if name already exists + try: + query = Course.all() + query.filter("courseName = ", payload['courseName']) + for c in query.run(limit=1): + return forbidden("Campus with same name already exists") + except Exception as e: + print e + + + except Exception: + return bad_request() + + + + db.put(course) + db.save + return Response(response=course.to_JSON(), + status=201, + mimetype="application/json") + + + +@course_routes.route('/api/courses/getCourseByCampusName/', methods=["GET"]) +@auto.doc() +def getCourseByCampusName(name): + """ + >This Call will return an array of all courses in a given campus +
+ Route Parameters
+ - name: 'campus name' +
+
+ Payload
+ - NONE +
+
+ Response +
+ 200 - JSON Example:
+ + {
+ 'courseName': 'Advance Math',
+ 'campusName': 'JCE',
+ 'startDate': '2015-14-3'
+ 'endDate': '2015-29-6'
+ 'taskFlag': 'False'
+ } +
+
+ """ + arr = [] + query = Course.all() + query.filter("campusName = ", name) + + for c in query.run(): + arr.append(dict(json.loads(c.to_JSON()))) + print arr + if len(arr) != 0: + return Response(response=json.dumps(arr), + status=200, + mimetype="application/json") + else: + return Response(response=[], + status=200, + mimetype="application/json") + + +@course_routes.route('/api/courses/help') +def documentation(): + return auto.html() \ No newline at end of file diff --git a/SE_API/Email_Utils.py b/SE_API/Email_Utils.py new file mode 100644 index 0000000..683f7e8 --- /dev/null +++ b/SE_API/Email_Utils.py @@ -0,0 +1,127 @@ +__author__ = 'sagi' + + +from google.appengine.api import mail + + +def send_validation_email(token, email, name): + emailSuffix = str(email).split('@')[1] + message = mail.EmailMessage(sender="SE-Hub Support ", + subject="SE-Hub Activate Account") + + message.to = email + + message.body = """ + Dear """+name+""": + + To Activate your SE-Hub Account please click on the link below:
+ http://se-hub.appspot.com/api/validation/confirm/"""+token+"""|"""+emailSuffix+""" + to get access to your Campus :) + + Please let us know if you have any questions. + + SE-Hub (c) 2015 niptop Team. + """ + + message.html = """ + +
+
+ + +
+
+
+

Hey """+name+"""- Just one More Step...

+

Dear """+name+""":

+ + To Activate your SE-Hub Account please click on the link below:
+ http://se-hub.appspot.com/api/validation/confirm/"""+token+"""|"""+emailSuffix+""" + + to access you virtual class. +
+

+ Please let us know if you have any questions. +
+ SE-Hub (c) 2015 niptop Team. + + + """ + + message.send() + +def send_create_campus_request(email, name, campus_name): + message = mail.EmailMessage(sender="SE-Hub Support ", + subject="SE-Hub: "+campus_name+" Is Being Evaluated") + + message.to = email + + message.body = """ + Dear """+name+""": + + Thank You For Choosing SE-Hub! + Your Request for creating a new Campus named """+campus_name + """ + is Being Evaluated. + You Will Receive an e-mail When We finish the process
+ + Please let us know if you have any questions. + + SE-Hub (c) 2015 niptop Team. + """ + + message.html = """ + +
+
+ + +
+
+
+

Thank You For Choosing SE-Hub!

+

Dear """+name+""":

+ + Your Request for creating a new Campus named """+campus_name + """ + is Being Evaluated. + You Will Receive an e-mail When We finish the process
+ + to access you virtual class. +
+

+ Please let us know if you have any questions. +
+ SE-Hub (c) 2015 niptop Team. + + + """ + message.send() + + +def notify_se_hub_campus_request(campus, campus_name): + message = mail.EmailMessage(sender="SE-Hub Support ", + subject="SE-Hub: "+campus_name+" Is Being Evaluated") + + message.to = 'se-hub@appspot.gserviceaccount.com' + + message.body = """ + a new Campus request + """+str(campus.to_JSON()) + + message.html = """ + +
+
+ + +
+
+
+

New Campus!

+
+ """ + str(campus.to_JSON()) + """ +
+ SE-Hub (c) 2015 niptop Team. + + + """ + message.send() diff --git a/SE_API/ProjectRoutes.py b/SE_API/ProjectRoutes.py new file mode 100644 index 0000000..18d2fb1 --- /dev/null +++ b/SE_API/ProjectRoutes.py @@ -0,0 +1,134 @@ +__author__ = 'Aran' + +from flask import Blueprint +import json +from GithubAPI.GithubAPI import GitHubAPI_Keys + +from google.appengine.ext import db +import requests +import datetime + +from flask import Flask, request, render_template, redirect, abort, Response + +from flask.ext.github import GitHub +from flask.ext.cors import CORS, cross_origin +from flask.ext.autodoc import Autodoc + +# DB Models +from models.Project import Project + +#Validation Utils Libs +from SE_API.Validation_Utils import * +from SE_API.Respones_Utils import * + + + +project_routes = Blueprint("project_routes", __name__) +auto = Autodoc() + +@project_routes.route('/api/projects/create/', methods=['POST']) +@auto.doc() +def create_project(token): + """ + This call will create a new project in the DB +
+ Route Parameters
+ - seToken: 'seToken' +
+
+ Payload
+ - JSON Object, Example:
+ {
+ 'projectName': 'Advance Math',
+ 'courseName': 'JCE',
+ 'logo_url': 'http://location.domain.com/image.jpg'
+ 'gitRepository': 'http://location.git.com/somthing'
+ }
+
+
+ Response +
+ 201 - Created +
+ 400 - Bad Request +
+ 403 - Invalid token or not a lecturer + """ + if not request.data: + return bad_request() + payload = json.loads(request.data) + if not is_lecturer(token): #todo: change to lecturer id + return forbidden("Invalid token or not a lecturer!") + + user = get_user_by_token(token) + + #todo: check legality + + try: + project = Project(projectName=payload['projectName'], courseName=payload['courseName'], masterId=user.key().id(), gitRepository=payload['gitRepository'], membersId=[token]) + except Exception as e: + print e + return bad_request() + + db.put(project) + db.save + return Response(response=project.to_JSON(), + status=201, + mimetype="application/json") + + + + + +@project_routes.route('/api/projects/getProjectsByCourseName/', methods=["GET"]) +@auto.doc() +def getProjectsByCourseName(name): + """ + >This Call will return an array of all projects in a given course +
+ Route Parameters
+ - name: 'course name' +
+
+ Payload
+ - NONE +
+
+ Response +
+ 200 - JSON Example:
+ + {
+ 'projectName': 'Advance Math',
+ 'courseName': 'JCE',
+ 'grade': 98,
+ 'logo_url': 'http://location.domain.com/image.jpg',
+ 'gitRepository': 'http://location.git.com/somthing',
+ 'membersId': ['bob', 'dylan', 'quentin', 'terentino']
+ } +
+
+ """ + + arr = [] + query = Project.all() + query.filter("courseName = ", name) + + for p in query.run(): + arr.append(dict(json.loads(p.to_JSON()))) + print arr + if len(arr) != 0: + return Response(response=json.dumps(arr), + status=200, + mimetype="application/json") + else: + return Response(response=[], + status=200, + mimetype="application/json") + + + + +@project_routes.route('/api/projects/help') +def documentation(): + return auto.html() \ No newline at end of file diff --git a/SE_API/Respones_Utils.py b/SE_API/Respones_Utils.py index b789974..3fe0e3f 100644 --- a/SE_API/Respones_Utils.py +++ b/SE_API/Respones_Utils.py @@ -3,6 +3,29 @@ __author__ = 'Aran' from flask import Response import json + +def ok(message='OK'): + return Response(response=json.dumps({'message': message}), + status=200, + mimetype="application/json") + +def created(message='Created'): + return Response(response=json.dumps({'message': message}), + status=201, + mimetype="application/json") + +def accepted(message='Accepted'): + return Response(response=json.dumps({'message': message}), + status=202, + mimetype="application/json") + + +def no_content(message='No Content'): + return Response(response=json.dumps({'message': message}), + status=204, + mimetype="application/json") + + def bad_request(message='Bad Request'): return Response(response=json.dumps({'message': message}), status=400, diff --git a/SE_API/UserRoutes.py b/SE_API/UserRoutes.py new file mode 100644 index 0000000..e487f2a --- /dev/null +++ b/SE_API/UserRoutes.py @@ -0,0 +1,75 @@ +__author__ = 'Aran' + +from flask import Blueprint +import json +from GithubAPI.GithubAPI import GitHubAPI_Keys + +from google.appengine.ext import db +import requests +import datetime + +from flask import Flask, request, render_template, redirect, abort, Response + +from flask.ext.github import GitHub +from flask.ext.cors import CORS, cross_origin +from flask.ext.autodoc import Autodoc + +# DB Models +from models.User import User + +#Validation Utils Libs +from SE_API.Validation_Utils import * +from SE_API.Respones_Utils import * + + +user_routes = Blueprint("user_routes", __name__) +auto = Autodoc() + + +@user_routes.route('/api/users/getUserByToken/', methods=["GET"]) +@auto.doc() +def getUserByToken(token): + """ + >This Call will return a user by a given token +
+ Route Parameters
+ - seToken: 'seToken' +
+
+ Payload
+ - NONE +
+
+ Response +
+ 200 - JSON Example:
+ + {
+ 'username': 'DarkLord',
+ 'name': 'Darth Vader',
+ 'email': 'darkLord@death.planet,
+ 'isLecturer': 'True',
+ 'seToken': 'xxxxxx-xxxxx-xxxxx-xxxxxx',
+ 'avatar_url': 'http://location.git.com/somthing'
+ 'isFirstLogin': False,
+ 'campuses_id_list': ['JCA','JCB','JCC'],
+ 'classes_id_list': ['a','b','c']
+ } +
+
+ 403 - No User Found + """ + query = User.all() + query.filter("seToken = ", token) + + for u in query.run(limit=5): + return Response(response=u.to_JSON(), + status=200, + mimetype="application/json") # Real response! + + return bad_request("No User Found") + + +@user_routes.route('/api/users/help') +def documentation(): + return auto.html() \ No newline at end of file diff --git a/SE_API/Validation_Utils.py b/SE_API/Validation_Utils.py index e99b2bd..90df681 100644 --- a/SE_API/Validation_Utils.py +++ b/SE_API/Validation_Utils.py @@ -2,7 +2,7 @@ __author__ = 'sagi' from google.appengine.ext import db from models.User import User from models.Campus import Campus -from google.appengine.api import mail + def get_user_by_token(token): @@ -32,50 +32,3 @@ def is_lecturer(token): if user is None: return False return user.isLecturer - - -def send_validation_email(token, email, name): - emailSuffix = str(email).split('@')[1] - message = mail.EmailMessage(sender="SE-Hub Support ", - subject="SE-Hub Activate Account") - - message.to = email - - message.body = """ - Dear """+name+""": - - To Activate your SE-Hub Account please click on the link below:
- http://se-hub.appspot.com/api/validation/confirm/"""+token+"""|"""+emailSuffix+""" - to get access to your Campus :) - - Please let us know if you have any questions. - - SE-Hub (c) 2015 niptop Team. - """ - - message.html = """ - -
-
- - -
-
-
-

Hey """+name+"""- Just one More Step...

-

Dear """+name+""":

- - To Activate your SE-Hub Account please click on the link below:
- http://se-hub.appspot.com/api/validation/confirm/"""+token+"""|"""+emailSuffix+""" - - to access you virtual class. -
-

- Please let us know if you have any questions. -
- SE-Hub (c) 2015 niptop Team. - - - """ - - message.send() diff --git a/Testing/UserAPI_Test.py b/Testing/UserAPI_Test.py index 179979e..e907400 100644 --- a/Testing/UserAPI_Test.py +++ b/Testing/UserAPI_Test.py @@ -17,20 +17,27 @@ class UserTestPlan(unittest.TestCase): print 'Initialized' def test_getUserByToken_invalid(self): - r = requests.get(self.__class__.url_+'api/getUserByToken/invalidtoken') - self.assertEquals(r.status_code, 204) - + r = requests.get(self.__class__.url_+'api/users/getUserByToken/invalidtoken') + self.assertEquals(r.status_code, 403) def test_getUserByToken_valid(self): - r = requests.get(self.__class__.url_+'api/getUserByToken/'+__CONFIG__['TOKENS']['STUDENT']) + r = requests.get(self.__class__.url_+'api/users/getUserByToken/'+__CONFIG__['TOKENS']['STUDENT']) self.assertEquals(r.status_code, 200) self.assertEquals(r.json()['username'], 'qa_student') - def test_getUserByToken_empty(self): - r = requests.get(self.__class__.url_+'api/getUserByToken/') + r = requests.get(self.__class__.url_+'api/users/getUserByToken/') self.assertEquals(r.status_code, 400) + def test_isStudent_Student(self): + r = requests.get(self.__class__.url_+'api/users/getUserByToken/'+__CONFIG__['TOKENS']['STUDENT']) + self.assertEquals(r.status_code, 200) + self.assertFalse(r.json()['isLecturer']) + + def test_isLecturer_Lecturer(self): + r = requests.get(self.__class__.url_+'api/users/getUserByToken/'+__CONFIG__['TOKENS']['LECTURER']) + self.assertEquals(r.status_code, 200) + self.assertTrue(r.json()['isLecturer']) if __name__ == '__main__': diff --git a/lib/flask_autodoc/templates/autodoc_default.html b/lib/flask_autodoc/templates/autodoc_default.html index 0d9b490..a512bd9 100644 --- a/lib/flask_autodoc/templates/autodoc_default.html +++ b/lib/flask_autodoc/templates/autodoc_default.html @@ -49,6 +49,9 @@
diff --git a/models/Course.py b/models/Course.py index 83557a7..fd2dc08 100644 --- a/models/Course.py +++ b/models/Course.py @@ -6,17 +6,25 @@ from google.appengine.ext import db class Course(db.Model): courseName = db.StringProperty(required=True) campusName = db.StringProperty(required=True) - projects = db.StringListProperty(required=True) + master_id = db.IntegerProperty(required=True) + # projects = db.StringListProperty(required=True,default=[]) startDate = db.DateProperty(required=True) - endDate = db.DateProperty(required=False) - taskFlag = db.BooleanProperty(required=True) + endDate = db.DateProperty(required=True) def to_JSON(self): data = {'courseName' : self.courseName, 'campusName' : self.campusName, - 'projects' : self.projects, - 'startDate' : self.startDate, - 'endDate' : self.endDate, - 'taskFlag' : self.taskFlag, + 'master_id' : self.master_id, + # 'projects' : self.projects, + 'startDate' : { + 'year': self.startDate.year, + 'month': self.startDate.month, + 'day': self.startDate.day, + }, + 'endDate' : { + 'year': self.endDate.year, + 'month': self.endDate.month, + 'day': self.endDate.day, + } } return json.dumps(data) diff --git a/models/Project.py b/models/Project.py index edecd83..579ecdd 100644 --- a/models/Project.py +++ b/models/Project.py @@ -5,13 +5,17 @@ from google.appengine.ext import db class Project(db.Model): projectName = db.StringProperty(required=True) - grade = db.IntegerProperty(required=True) - logo_url = db.StringProperty(required=True) + courseName = db.StringProperty(required=True) + master_id = db.IntegerProperty(required=True) + grade = db.IntegerProperty(required=True, default=0) + logo_url = db.StringProperty(required=False) gitRepository = db.StringProperty(required=True) membersId = db.StringListProperty(required=True) def to_JSON(self): data = {'projectName' : self.projectName, + 'courseName' : self.courseName, + 'master_id' : self.master_id, 'grade' : self.grade, 'logo_url' : self.logo_url, 'gitRepository' : self.gitRepository, diff --git a/templates/API_Doc/api_doc_index.html b/templates/API_Doc/api_doc_index.html new file mode 100644 index 0000000..6e88ea7 --- /dev/null +++ b/templates/API_Doc/api_doc_index.html @@ -0,0 +1,93 @@ + + + + + + + + + + + + + SE-Hub API Docs + + + + + + +

+ SE-Hub Docs Index +

+ + +
+
    +
  • Users Related API
  • +
  • Campuses Related API
  • +
  • Courses Related API
  • +
  • Validation Related API
  • +
+
+ +
+
+
+
+
Footer Content
+

You can use rows and columns here to organize your footer content.

+
+
+
Links
+ +
+
+
+ +
+ + \ No newline at end of file diff --git a/templates/css/theme.css b/templates/css/theme.css index a4067cd..a8b0155 100644 --- a/templates/css/theme.css +++ b/templates/css/theme.css @@ -15,9 +15,18 @@ md-list .md-button { width: 100%; } +.welcome-logo-banner{ + width: 100%; +} + /* Using Data-URI converted from svg until becomes available https://github.com/google/material-design-icons */ + +p { + margin-left: 2em; +} + .menuBtn { background: transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDI0IDI0IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPGcgaWQ9IkhlYWRlciI+CiAgICA8Zz4KICAgICAgICA8cmVjdCB4PSItNjE4IiB5PSItMjIzMiIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPgogICAgPC9nPgo8L2c+CjxnIGlkPSJMYWJlbCI+CjwvZz4KPGcgaWQ9Ikljb24iPgogICAgPGc+CiAgICAgICAgPHJlY3QgZmlsbD0ibm9uZSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ii8+CiAgICAgICAgPHBhdGggZD0iTTMsMThoMTh2LTJIM1YxOHogTTMsMTNoMTh2LTJIM1YxM3ogTTMsNnYyaDE4VjZIM3oiIHN0eWxlPSJmaWxsOiNmM2YzZjM7Ii8+CiAgICA8L2c+CjwvZz4KPGcgaWQ9IkdyaWQiIGRpc3BsYXk9Im5vbmUiPgogICAgPGcgZGlzcGxheT0iaW5saW5lIj4KICAgIDwvZz4KPC9nPgo8L3N2Zz4=) no-repeat center center; } @@ -54,100 +63,88 @@ body.noscroll } .avatar { - float: left; - margin-top: 1em; - margin-right: 1em; - position: relative; - + margin-top: 1em; + margin-right: 1em; + position: center; + + -webkit-border-radius: 30%; + -moz-border-radius: 30%; + border-radius: 30%; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - -webkit-box-shadow: 0 0 0 3px #fff, 0 0 0 4px #999, 0 2px 5px 4px rgba(0,0,0,.2); - -moz-box-shadow: 0 0 0 3px #fff, 0 0 0 4px #999, 0 2px 5px 4px rgba(0,0,0,.2); - box-shadow: 0 0 0 3px #fff, 0 0 0 4px #999, 0 2px 5px 4px rgba(0,0,0,.2); } /*.avatar { background: rgba(0, 0, 0, 0.2); -}*/ + }*/ -.avatar img { - border-radius: 40px; - width: 80px; - height: 80px; - margin: 6px; /* centers the image in the parent element */ -} + .avatar img { + border-radius: 40px; + position:center; + width: 80px; + height: 80px; + margin: 6px; /*centers the image in the parent element */ + -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + } -/* Added BY devMatan */ + /* Added BY devMatan */ /*.disabledSubmitButton: { /*background: #f7f7f7;*/ /*border-radius: 10000px;*/ /*text-align: center;*/ - + /*position: relative !important;* -}*/ + }*/ -.campusAvatar: -{ - float: left; + .campusAvatar img + { +/* margin-top: 1em; margin-right: 1em; - position: relative; - width:70%; - height:auto; + position: center; + */ - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; + border-radius: 40px; + position:center; + width: 80px; + height: 80px; + margin: 6px; + -webkit-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + -moz-box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + box-shadow: 2px 2px 5px 0px rgba(0,0,0,0.75); + } - -webkit-box-shadow: 0 0 0 3px #fff, 0 0 0 4px #999, 0 2px 5px 4px rgba(0,0,0,.2); - -moz-box-shadow: 0 0 0 3px #fff, 0 0 0 4px #999, 0 2px 5px 4px rgba(0,0,0,.2); - box-shadow: 0 0 0 3px #fff, 0 0 0 4px #999, 0 2px 5px 4px rgba(0,0,0,.2); -} + .spacer{ + margin-right: auto; + margin-left: auto; + } -.spacer{ - margin-right: auto; - margin-left: auto; -} + .port_spacer{ + margin-top: auto; + margin-bottom: auto; + } -.port_spacer{ - margin-top: auto; - margin-bottom: auto; -} - -.mail_suffix{ - margin-top: auto; -} + .mail_suffix{ + margin-top: auto; + } /*div.img campusAvatar { border: 1px solid #0000ff; padding-right: 10px; float:right; -}*/ + }*/ -/*.dropDown: /* TODO * +/*.dropDown /* TODO * { border-bottom: 2px black solid; border-top: 2px black solid; border-left: 2px black solid; border-right: 2px black solid; border-radius: 1px black solid; -}*/ - - -/* -h1 -{ - position:center; -} -*/ - - - - +}*/ \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index ea840eb..a94ff2e 100644 --- a/templates/index.html +++ b/templates/index.html @@ -14,7 +14,7 @@
- +

Wellcome To SE-Hub!

@@ -35,7 +35,7 @@ - + diff --git a/templates/js/app.js b/templates/js/app.js index 46b8d12..9b93421 100644 --- a/templates/js/app.js +++ b/templates/js/app.js @@ -14,8 +14,10 @@ welcome.controller('welcomeController', ['$scope', 'apiService', '$cookies', '$w console.log("Welcome Controller"); var uid = $cookies['com.sehub.www']; - if(uid) + if(uid){ + console.info("Session in Place"); $window.location.href = DEBUG ? 'http://localhost:8080/home' : 'http://se-hub.appspot.com/home'; + } @@ -26,8 +28,7 @@ app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) { $routeProvider .when('/', { - templateUrl: 'templates/views/home.html', - controller: 'mainController' + templateUrl: 'templates/views/home.html' }) .when('/register', { templateUrl: 'templates/views/register.html', diff --git a/templates/js/controllers/mainController.js b/templates/js/controllers/mainController.js index c27cf90..9da1fa1 100644 --- a/templates/js/controllers/mainController.js +++ b/templates/js/controllers/mainController.js @@ -1,19 +1,23 @@ angular.module('SeHub') .controller('mainController', ['$scope', '$rootScope', 'apiService', '$cookies', '$location', function ($scope, $rootScope, apiService, $cookies, $location) { - $rootScope.seToken = $cookies['com.sehub.www']; - var token = $rootScope.seToken; + var token = $cookies['com.sehub.www']; + $scope.loadingData = true; + $scope.isInRegisterMode = false; apiService.getUserByToken(token).success(function(data){ - console.log(data); - if(data.message == 'No User Found') + if(data.message == 'No User Found'){ console.error("No User Found!"); + } $scope.user = data; - $rootScope.user = data; - if($scope.user.isFirstLogin) + if($scope.user.isFirstLogin){ + $scope.menuObj = {}; + $scope.isInRegisterMode = true; + $scope.loadingData = false; $location.path('/register') + } }) $scope.loadingData = false; diff --git a/templates/js/controllers/registerController.js b/templates/js/controllers/registerController.js index c8cadcf..b46bc91 100644 --- a/templates/js/controllers/registerController.js +++ b/templates/js/controllers/registerController.js @@ -1,45 +1,37 @@ angular.module('SeHub') -.controller('registerController', ['$scope', '$location', '$cookies', 'apiService', '$rootScope', function ($scope, $location, $cookies, apiService ,$rootScope) { - +.controller('registerController', ['$scope', '$cookies', '$cookieStore', '$window', '$location', '$mdToast', '$mdDialog', 'apiService', '$rootScope', function ($scope, $cookies, $cookieStore, $window, $location, $mdToast, $mdDialog, apiService ,$rootScope) +{ $scope.userHasNoName = false; $scope.campusChecked = false; $scope.isEmpty = true; // if the academic email line is empty - // $scope.fullMail = $scope.academicEmail + $scope.campusObj.email_ending; // Will hold the full academic email of the user $rootScope.seToken = $cookies['com.sehub.www']; var token = $rootScope.seToken; - apiService.getUserByToken(token).success(function(data){ + apiService.getUserByToken(token).success(function(data) // Get user token + { $scope.user = data; - console.log(data); + if(data.message == 'No User Found') console.error("No User Found!"); + console.log(data); - $scope.user = data; - $rootScope.user = data; - if($scope.user.isFirstLogin) - $location.path('/register') - - - if($scope.user.name === ";"){ + if($scope.user.name === ";") + { $scope.user.name = ""; $scope.user.name = $scope.user.username $scope.userHasNoName = true; } - apiService.getAllCampuses($scope.user.seToken).success(function(data) - { - $scope.campuses = data; - }).error(function() - { - // TODO + apiService.getAllCampuses($scope.user.seToken).success(function(data) // Get all the campuses + { + $scope.campuses = data; + }).error(function() + { + // TODO + }); }); - }); - - - - $scope.dropdownClicked = function() { if($scope.campus){ @@ -51,40 +43,61 @@ angular.module('SeHub') console.log($scope.campusObj); // TODO REMOVE!! } }; + }; + }; + + $scope.submitClicked = function(ev) + { + if($scope.user.AcMail != null) + { + var fullMail = $scope.user.AcMail + $scope.campusObj.email_ending; // Holds the full academic email of the user + apiService.sendValidationMail($scope.user.seToken, fullMail).success(function(data) + { + console.log("DONE - 200"); + $mdDialog.show($mdDialog.alert().title('E-mail Verification').content('A verification e-mail has been sent to your email address.') + .ariaLabel('Email verification alert dialog').ok('Got it!').targetEvent(ev)); // Pop-up alert for e-mail verification + $cookieStore.remove("com.sehub.www"); // Removing the cookies + $window.location.href = 'http://se-hub.appspot.com'; // Reference to 'welcome' page + }).error(function() + { + $mdDialog.show($mdDialog.alert().title('Error - E-mail Verification').content('An error has occured in your e-mail address.') + .ariaLabel('Email verification error alert dialog').ok('Got it!').targetEvent(ev)); + }); + }; + }; + + $scope.lecturerPrivilege = function(data) + { + // console.log("Now " + data); + var isLecturer; + if(!data) // if i am a lecturer (when pressing -> getting last data value before pressing) = "!data" => I Am Lecturer + { + isLecturer = true; + console.log("im lecturer " + isLecturer); } - - }; - - $scope.submitClicked = function() - { - console.log($scope.user.AcMail); - $scope.mail = 'pin'; - console.log($scope.mail); - }; - - - - apiService.getAllCampuses($scope.user.seToken).success(function(data) - { - $scope.campuses = data; - }).error(function() - { - // TODO - }); - - // apiService.sendValidationMail($scope.user.seToken, $scope.fullMail).success(function(data) // TODO: Add 2nd parameter email type Email - // { - // console.log($scope.fullMail); - // console.log("200"); - - // // TODO - // }).error(function() - // { - - // }); + } - + // TODO FOR LATER - toast + // TODO FOR LATER + // $scope.getPopWindowPosition = function() + // { + // return Object.keys($scope.toastPosition).filter(function(pos) + // { + // return $scope.toastPosition[pos]; + // }).join(' '); + // }; + + // $scope.toastPosition = + // { + // bottom: false, + // top: true, + // left: false, + // right: true + // }; -}]); \ No newline at end of file + // TODO FOR LATER + // TODO FOR LATER + +}]); diff --git a/templates/js/services/apiService.js b/templates/js/services/apiService.js index e240375..108b309 100644 --- a/templates/js/services/apiService.js +++ b/templates/js/services/apiService.js @@ -7,7 +7,7 @@ service.factory('apiService', ['$http', function($http) { return { getUserByToken: function(token){ - var url = (DEBUG ? "http://localhost:8080" : "http://se-hub.appspot.com") + "/api/getUserByToken/" + token; + var url = (DEBUG ? "http://localhost:8080" : "http://se-hub.appspot.com") + "/api/users/getUserByToken/" + token; req = { method : "GET", url : url @@ -16,7 +16,7 @@ service.factory('apiService', ['$http', function($http) { return $http(req); }, getAllCampuses: function(token){ - var url = (DEBUG ? "http://localhost:8080" : "http://se-hub.appspot.com") + "/api/Campuses/" + token; + var url = (DEBUG ? "http://localhost:8080" : "http://se-hub.appspot.com") + "/api/campuses/getAll/" + token; req = { method : "GET", url : url diff --git a/templates/views/index.html b/templates/views/index.html index 816e633..fcc374d 100644 --- a/templates/views/index.html +++ b/templates/views/index.html @@ -8,8 +8,8 @@ - - + +