From 7729b3d884a42f8ae1bf290c1c03752695096afe Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 22:34:07 +0300 Subject: [PATCH 1/7] taskComponents --- models/TaskComponent.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 models/TaskComponent.py diff --git a/models/TaskComponent.py b/models/TaskComponent.py new file mode 100644 index 0000000..f2130b2 --- /dev/null +++ b/models/TaskComponent.py @@ -0,0 +1,32 @@ +__author__ = 'Aran' + + +import json +from google.appengine.ext import db + + +class TaskComponent(db.Model): + taskId = db.StringProperty(required=True) + courseName = db.StringProperty(required=True) + description = db.StringProperty(required=True,default=" ") + dueDate = db.DateProperty(required=True) + #isProject = db.BooleanProperty(required=False) + isClose = db.BooleanProperty(required=True, default=False) + isDone = db.BooleanProperty(required=True, default=False) + taskGrade = db.IntegerProperty(required=True, default=0) + + def to_JSON(self): + data = {'title' : self.title, + 'courseName' : self.courseName, + 'description' : self.description, + 'dueDate' : { + 'year': self.dueDate.year, + 'month': self.dueDate.month, + 'day': self.dueDate.day + }, + #'isProject' : self.isProject, + 'isClose' : self.isClose, + 'isDone' : self.isDone, + 'taskGrade' : self.taskGrade, + } + return json.dumps(data) From cd0fb3cf4fc76835077f30fc607ee3027a9f7ca6 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 23:53:39 +0300 Subject: [PATCH 2/7] Task Rework - chaged parameters added components module and creation in create task added getTaskComponents function --- SE_API/TaskRoutes.py | 262 +++++++++++++++++++++++++++------------- models/Task.py | 10 +- models/TaskComponent.py | 32 ++--- 3 files changed, 190 insertions(+), 114 deletions(-) diff --git a/SE_API/TaskRoutes.py b/SE_API/TaskRoutes.py index de1ebff..4c50468 100644 --- a/SE_API/TaskRoutes.py +++ b/SE_API/TaskRoutes.py @@ -18,6 +18,7 @@ from flask.ext.autodoc import Autodoc # DB Models from models.Task import Task from models.Course import Course +from models.TaskComponent import TaskComponent #Validation Utils Libs from SE_API.Validation_Utils import * @@ -42,14 +43,35 @@ def create_task(token): Payload
- JSON Object, Example:
{
- 'title' : self.title,
- 'courseName' : self.course,
- 'description' : self.description,
- 'dueDate' : self.dueDate,
- 'isClose' : self.membersId,
- 'isDone' : self.isDone,
- 'taskGrade' : self.taskGrade
- }
+ "title":"task1",
+ "courseName":"aran",
+ "description":"pls fddfsdfdsk",
+ "dueDate":{"year":2010,
+ "month":2,
+ "day":4
+ }, + "isPersonal":true,
+ "components":[
+ {
+ "type" : "should be type1",
+ "label" : "should be label1",
+ "isMandatory" : true,
+ "order" : 1
+ },
+ {
+ "type" : "should be type2",
+ "label" : "should be label2",
+ "isMandatory" : true,
+ "order" : 2
+ },
+ {
+ "type" : "should be type3",
+ "label" : "should be label3",
+ "isMandatory" : false,
+ "order" : 3
+ }
+ ]
+}

Response @@ -90,89 +112,37 @@ def create_task(token): date = datetime.date(payload['dueDate']['year'],payload['dueDate']['month'],payload['dueDate']['day']) except Exception: return bad_request("invalid dueDate format") - #TODO: add time. now, its only date task = Task(title=payload['title'], courseName=payload['courseName'], description=payload['description'], dueDate=date) - #parse isClose + # print "id: ",task.key().id() + #parse isPersonal try: - task.isClose = payload['isClose'] + task.isPersonal = payload['isPersonal'] except Exception: pass - - #parse isDone - try: - task.isDone = payload['isDone'] - except Exception: - pass - - #parse taskGrade - try: - task.taskGrade = payload['taskGrade'] - except Exception: - pass - except Exception as e: print e return bad_request() - db.put(task) db.save + + #create components + for c in payload['components']: + try: + component = TaskComponent(taskId=task.key().id(), userId=-1, type=c['type'], label=c['label'], isMandatory=c['isMandatory'], order=c['order']) + except Exception as e: + print e + return bad_request("Bad component") + db.put(component) + db.save + + + return created() -@task_routes.route('/api/tasks/getClosestTask/', methods=["GET"]) -@auto.doc() -def getClosestTask(courseName): - """ - >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']
- } -
-
- """ - #get all tasks for a specific course - arr = [] - query = Task.all() - query.filter("courseName =", courseName) - index = -1 - count = -1 - closestDate = datetime.date(3000,1,1) - for t in query.run(): - count+=1 - if t.dueDate < closestDate: - closestDate = t.dueDate - index = count - arr.append(dict(json.loads(t.to_JSON()))) - - print arr - if len(arr) != 0: - return Response(response=json.dumps(arr[index]), - status=200, - mimetype="application/json") - else: - return no_content("no Tasks") - @@ -180,7 +150,7 @@ def getClosestTask(courseName): @auto.doc() def getAllTasks(courseName): """ - >This Call will return an array of all projects in a given course + >This Call will return an array of all Tasks in a course by date
Route Parameters
- name: 'course name' @@ -195,13 +165,17 @@ def getAllTasks(courseName): 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']
- } + 'title' : 'Task1',
+ 'courseName' : 'advance Math',
+ 'description' : 'prepare by sunday',
+ 'dueDate' : { + 'year' : 2015, + 'month' : 12, + 'day' : 23 + }
+ 'isPersonal' : true,
+ 'task_id' : 589689456894
+ }

""" @@ -227,12 +201,128 @@ def getAllTasks(courseName): status=200, mimetype="application/json") else: - return Response(response=[], + return no_content() + + +@task_routes.route('/api/tasks/getTaskComponents/', methods=["GET"]) +@auto.doc() +def getTaskComponents(taskId): + """ + >This Call will return an array of all components for a given task +
+ Route Parameters
+ - taskId: integer +
+
+ Payload
+ - NONE +
+
+ Response +
+ 200 - JSON Example:
+ + [ + {
+ 'taskId' : 7589454894, + 'userId' : -1, + 'type' : 'kindOfType', + 'label' : 'kindOfLabel', + 'isMandatory' : true, + 'order' : 2 + }
+ {
+ 'taskId' : 7589454894, + 'userId' : yossi, + 'type' : 'otherKindOfType', + 'label' : 'otherKindOfLabel', + 'isMandatory' : false, + 'order' : 4 + }
+ ] +
+
+ """ + + arr = [] + query = TaskComponent.all() + query.filter("taskId = ", taskId) + + for tc in query.run(): + arr.append(dict(json.loads(tc.to_JSON()))) + + #sort array by order, and remove added key + arr = sorted(arr, key=itemgetter('order'), reverse=False) + + if len(arr) != 0: + return Response(response=json.dumps(arr), status=200, mimetype="application/json") + else: + return no_content() @task_routes.route('/api/tasks/help') def documentation(): - return auto.html() \ No newline at end of file + return auto.html() + + + +@task_routes.route('/api/tasks/help') +def documentation(): + return auto.html() + + + + + + +# @task_routes.route('/api/tasks/getClosestTask/', methods=["GET"]) +# @auto.doc() +# def getClosestTask(courseName): +# """ +# >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']
+# } +#
+#
+# """ +# #get all tasks for a specific course +# arr = [] +# query = Task.all() +# query.filter("courseName =", courseName) +# for t in query.run(): +# count+=1 +# if t.dueDate < closestDate: +# closestDate = t.dueDate +# index = count +# arr.append(dict(json.loads(t.to_JSON()))) +# +# print arr +# if len(arr) != 0: +# return Response(response=json.dumps(arr[index]), +# status=200, +# mimetype="application/json") +# else: +# return no_content("no Tasks") +# diff --git a/models/Task.py b/models/Task.py index e51ac40..292ac0d 100644 --- a/models/Task.py +++ b/models/Task.py @@ -9,10 +9,7 @@ class Task(db.Model): courseName = db.StringProperty(required=True) description = db.StringProperty(required=True,default=" ") dueDate = db.DateProperty(required=True) - #isProject = db.BooleanProperty(required=False) - isClose = db.BooleanProperty(required=True, default=False) - isDone = db.BooleanProperty(required=True, default=False) - taskGrade = db.IntegerProperty(required=True, default=0) + isPersonal = db.BooleanProperty(required=True, default=True) def to_JSON(self): data = {'title' : self.title, @@ -23,10 +20,7 @@ class Task(db.Model): 'month': self.dueDate.month, 'day': self.dueDate.day }, - #'isProject' : self.isProject, - 'isClose' : self.isClose, - 'isDone' : self.isDone, - 'taskGrade' : self.taskGrade, + 'isPersonal' : self.isPersonal, } return json.dumps(data) diff --git a/models/TaskComponent.py b/models/TaskComponent.py index f2130b2..db84efb 100644 --- a/models/TaskComponent.py +++ b/models/TaskComponent.py @@ -6,27 +6,19 @@ from google.appengine.ext import db class TaskComponent(db.Model): - taskId = db.StringProperty(required=True) - courseName = db.StringProperty(required=True) - description = db.StringProperty(required=True,default=" ") - dueDate = db.DateProperty(required=True) - #isProject = db.BooleanProperty(required=False) - isClose = db.BooleanProperty(required=True, default=False) - isDone = db.BooleanProperty(required=True, default=False) - taskGrade = db.IntegerProperty(required=True, default=0) + taskId = db.IntegerProperty(required=True) + userId = db.IntegerProperty(required=True, default = -1) + type = db.StringProperty(required=True,default=" ") + label = db.StringProperty(required=True,default=" ") + isMandatory = db.BooleanProperty(required=True, default=True) + order = db.IntegerProperty(required=True) def to_JSON(self): - data = {'title' : self.title, - 'courseName' : self.courseName, - 'description' : self.description, - 'dueDate' : { - 'year': self.dueDate.year, - 'month': self.dueDate.month, - 'day': self.dueDate.day - }, - #'isProject' : self.isProject, - 'isClose' : self.isClose, - 'isDone' : self.isDone, - 'taskGrade' : self.taskGrade, + data = {'taskId' : self.taskId, + 'userId' : self.userId, + 'type' : self.type, + 'label' : self.label, + 'isMandatory' : self.isMandatory, + 'order' : self.order } return json.dumps(data) From c6c175ca294cfd055d48283d6c1205ff2fcb32bd Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Sun, 21 Jun 2015 23:56:49 +0300 Subject: [PATCH 3/7] #52 bug fix. change in documentation --- SE_API/CampusRoutes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py index 67dd8b2..e6a2781 100644 --- a/SE_API/CampusRoutes.py +++ b/SE_API/CampusRoutes.py @@ -48,7 +48,7 @@ def create_campus(token):
Response
- 201 - Created + 200 - OK
403 - Invalid Token/Forbidden """ From 431a36760d65f77dd0ecdd5fe5c0c0ca92a148cd Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Mon, 22 Jun 2015 01:25:35 +0300 Subject: [PATCH 4/7] fix auto.doc bug --- SE_API/TaskRoutes.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SE_API/TaskRoutes.py b/SE_API/TaskRoutes.py index 4c50468..769e25b 100644 --- a/SE_API/TaskRoutes.py +++ b/SE_API/TaskRoutes.py @@ -269,10 +269,6 @@ def documentation(): -@task_routes.route('/api/tasks/help') -def documentation(): - return auto.html() - From e9e10bd980c9ea194fcf24d991e63cff92528332 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Mon, 22 Jun 2015 01:26:23 +0300 Subject: [PATCH 5/7] added delete functions + doc to campus, course, project --- SE_API/CampusRoutes.py | 32 +++++++++++----------------- SE_API/CourseRoutes.py | 38 ++++++++++++++++----------------- SE_API/ProjectRoutes.py | 47 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 40 deletions(-) diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py index e6a2781..66a262a 100644 --- a/SE_API/CampusRoutes.py +++ b/SE_API/CampusRoutes.py @@ -140,15 +140,16 @@ def get_campuses(token): return forbidden("Invalid Token") -@campus_routes.route('/api/campuses/deleteCampus//', methods=['DELETE']) + +@campus_routes.route('/api/campuses/deleteCampus//', methods=['DELETE']) @auto.doc() -def deleteCampus(token,campusName): +def deleteCampus(token,campusid): """ This Call will delete a specific campus
Route Parameters
- seToken: 'seToken' - - title: 'campusName' + - campusid: 'campusid'

Payload
@@ -159,42 +160,33 @@ def deleteCampus(token,campusName):
202 - Deleted campus
- 204 - No Matching Campus Found -
....
{
...
}req
]
- 400 - Bad Request + 400 - no such campus
- 403 - Invalid token or not a lecturer!
+ 403 - Invalid token or not a lecturer or lecturer is not owner of campus!
""" if not is_lecturer(token): #todo: change to lecturer id return forbidden("Invalid token or not a lecturer!") - user = get_user_by_token(token) - query = Campus.all() - query.filter('master_user_id =',user.key().id()) + camp = Campus.get_by_id(int(campusid)) - try: - query.filter('title =', campusName) - except Exception as e: - print e - return bad_request("invalid campus title attribute") + if camp is None: + return bad_request("no such campus") - for c in query.run(): - db.delete(c) + if camp.master_user_id == user.key().id(): + db.delete(camp) db.save return accepted("campus deleted") - - return bad_request("no such campus found") - + return forbidden("lecturer is not owner of campus") diff --git a/SE_API/CourseRoutes.py b/SE_API/CourseRoutes.py index 93c2db6..fe27f61 100644 --- a/SE_API/CourseRoutes.py +++ b/SE_API/CourseRoutes.py @@ -272,15 +272,21 @@ def getMessagesByCourseName(name): #---------------------------------------------------------- # DELETE #---------------------------------------------------------- -@course_routes.route('/api/courses/deleteCourse//', methods=['DELETE']) + + + + + + +@course_routes.route('/api/courses/deleteCourse//', methods=['DELETE']) @auto.doc() -def deleteCourse(token,courseName): +def deleteCourse(token,courseid): """ - This Call will delete a specific course + This Call will delete a specific Course
Route Parameters
- seToken: 'seToken' - - title: 'courseName' + - courseid: 'courseid'

Payload
@@ -289,9 +295,7 @@ def deleteCourse(token,courseName):
Response
- 202 - Deleted campus -
- 204 - No Matching Campus Found + 202 - Deleted Course
....
{
@@ -299,33 +303,27 @@ def deleteCourse(token,courseName): }req
]
- 400 - Bad Request + 400 - no such Course
- 403 - Invalid token or not a lecturer!
+ 403 - Invalid token or not a lecturer or lecturer is not owner of Course!
""" if not is_lecturer(token): #todo: change to lecturer id return forbidden("Invalid token or not a lecturer!") - user = get_user_by_token(token) - query = Course.all() - query.filter('master_id =',user.key().id()) + c = Course.get_by_id(int(courseid)) - try: - query.filter('courseName =', courseName) - except Exception as e: - print e - return bad_request("invalid course title attribute") + if c is None: + return bad_request("no such course") - for c in query.run(): + if c.master_id == user.key().id(): db.delete(c) db.save return accepted("course deleted") - - return bad_request("no such course or not owner of course") + return forbidden("lecturer is not owner of course") @course_routes.route('/api/courses/deleteCoursesByCampus//', methods=['DELETE']) diff --git a/SE_API/ProjectRoutes.py b/SE_API/ProjectRoutes.py index 57afe8d..1bd3c23 100644 --- a/SE_API/ProjectRoutes.py +++ b/SE_API/ProjectRoutes.py @@ -130,6 +130,53 @@ def getProjectsByCourseName(name): +@project_routes.route('/api/projects/deleteProject//', methods=['DELETE']) +@auto.doc() +def deleteProject(token,projectid): + """ + This Call will delete a specific Project +
+ Route Parameters
+ - seToken: 'seToken' + - courseid: 'projectid' +
+
+ Payload
+ - NONE
+
+
+ Response +
+ 202 - Deleted Project +
+ ....
+ {
+ ...
+ }req
+ + ]
+ 400 - no such Project +
+ 403 - Invalid token or not the owner of Project!
+ """ + + # if not is_lecturer(token): #todo: change to lecturer id + # return forbidden("Invalid token or not a lecturer!") + + user = get_user_by_token(token) + p = Project.get_by_id(int(projectid)) + + if p is None: + return bad_request("no such Project") + + if p.master_id == user.key().id(): + db.delete(p) + db.save + return accepted("Project deleted") + + return forbidden("user is not owner of Project") + + @project_routes.route('/api/projects/help') def documentation(): From 346d5b4aaae10f81cb45c67330a2f52a2292a762 Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Mon, 22 Jun 2015 01:38:01 +0300 Subject: [PATCH 6/7] added 'id' key in JSON response --- models/Campus.py | 3 ++- models/Course.py | 5 +++-- models/Message.py | 3 ++- models/Project.py | 1 + models/Task.py | 1 + models/TaskComponent.py | 3 ++- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/models/Campus.py b/models/Campus.py index f4e9cef..dd910de 100644 --- a/models/Campus.py +++ b/models/Campus.py @@ -14,7 +14,8 @@ class Campus(db.Model): data = {'title': self.title, 'email_ending': self.email_ending, 'master_user_id': self.master_user_id, - 'avatar_url': self.avatar_url + 'avatar_url': self.avatar_url, + 'id' : self.key().id() } return json.dumps(data) diff --git a/models/Course.py b/models/Course.py index fd2dc08..e2a6b7c 100644 --- a/models/Course.py +++ b/models/Course.py @@ -25,6 +25,7 @@ class Course(db.Model): 'year': self.endDate.year, 'month': self.endDate.month, 'day': self.endDate.day, - } - } + }, + 'id' : self.key().id() + } return json.dumps(data) diff --git a/models/Message.py b/models/Message.py index fa1a456..a5dc29f 100644 --- a/models/Message.py +++ b/models/Message.py @@ -18,6 +18,7 @@ class Message(db.Model): 'day': self.msgDate.day, 'hour': self.msgDate.hour, 'minute': self.msgDate.minute - } + }, + 'id' : self.key().id() } return json.dumps(data) diff --git a/models/Project.py b/models/Project.py index 579ecdd..4e6cacb 100644 --- a/models/Project.py +++ b/models/Project.py @@ -20,5 +20,6 @@ class Project(db.Model): 'logo_url' : self.logo_url, 'gitRepository' : self.gitRepository, 'membersId' : self.membersId, + 'id' : self.key().id() } return json.dumps(data) diff --git a/models/Task.py b/models/Task.py index 292ac0d..cdbaae9 100644 --- a/models/Task.py +++ b/models/Task.py @@ -21,6 +21,7 @@ class Task(db.Model): 'day': self.dueDate.day }, 'isPersonal' : self.isPersonal, + 'id' : self.key().id() } return json.dumps(data) diff --git a/models/TaskComponent.py b/models/TaskComponent.py index db84efb..161cfcc 100644 --- a/models/TaskComponent.py +++ b/models/TaskComponent.py @@ -19,6 +19,7 @@ class TaskComponent(db.Model): 'type' : self.type, 'label' : self.label, 'isMandatory' : self.isMandatory, - 'order' : self.order + 'order' : self.order, + 'id' : self.key().id() } return json.dumps(data) From f1d73aab644b7946654377af90ac782640dbddaf Mon Sep 17 00:00:00 2001 From: aranzaiger Date: Mon, 22 Jun 2015 01:38:14 +0300 Subject: [PATCH 7/7] some doc --- SE_API/CampusRoutes.py | 3 ++- SE_API/CourseRoutes.py | 6 +++++- SE_API/ProjectRoutes.py | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/SE_API/CampusRoutes.py b/SE_API/CampusRoutes.py index 66a262a..ebfa72a 100644 --- a/SE_API/CampusRoutes.py +++ b/SE_API/CampusRoutes.py @@ -108,7 +108,8 @@ def get_campuses(token): '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'
+ 'avatar_url': 'http://some.domain.com/imagefile.jpg',
+ 'id' : 1234567890
},
....
{
diff --git a/SE_API/CourseRoutes.py b/SE_API/CourseRoutes.py index fe27f61..b7af470 100644 --- a/SE_API/CourseRoutes.py +++ b/SE_API/CourseRoutes.py @@ -189,6 +189,8 @@ def getCourseByCampusName(name): 'startDate': '2015-14-3'
'endDate': '2015-29-6'
'taskFlag': 'False'
+ 'id' : 1234567890
+ }
@@ -232,7 +234,9 @@ def getMessagesByCourseName(name): 'campusName': 'JCE',
'startDate': '2015-14-3'
'endDate': '2015-29-6'
- 'taskFlag': 'False'
+ 'taskFlag': false,
+ 'id' : 1234567890
+ }
diff --git a/SE_API/ProjectRoutes.py b/SE_API/ProjectRoutes.py index 1bd3c23..175a3a7 100644 --- a/SE_API/ProjectRoutes.py +++ b/SE_API/ProjectRoutes.py @@ -106,7 +106,8 @@ def getProjectsByCourseName(name): 'grade': 98,
'logo_url': 'http://location.domain.com/image.jpg',
'gitRepository': 'http://location.git.com/somthing',
- 'membersId': ['bob', 'dylan', 'quentin', 'terentino']
+ 'membersId': ['bob', 'dylan', 'quentin', 'terentino'],
+ 'id' : 1234567890
}