From 5ddc8859607a6a1948fe78edce64564acd96f3ef Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Mon, 12 Aug 2019 07:31:58 +0500 Subject: [PATCH 1/5] Update CI config --- .drone.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.drone.yml b/.drone.yml index 08ac481..5e23118 100644 --- a/.drone.yml +++ b/.drone.yml @@ -8,6 +8,10 @@ steps: - pip install pylint - pip install -r requirements.txt - pylint project_amber + when: + branch: + exclude: + - master - name: push to registry image: plugins/docker settings: From f192f9f3fe00db737bd3efd65a870cd42f7c7c70 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Wed, 21 Aug 2019 11:46:09 +0500 Subject: [PATCH 2/5] Remove useless method --- project_amber/models/task.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/project_amber/models/task.py b/project_amber/models/task.py index 92f086f..f76b82e 100644 --- a/project_amber/models/task.py +++ b/project_amber/models/task.py @@ -20,6 +20,3 @@ def is_child(self) -> bool: if self.gen > 0: return True return False - def __repr__(self): - return "" \ - % self.id, self.owner, self.text, self.status, self.creation_time From fbd9362b0a3f14da2c7db2c477215855091b67f9 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Wed, 21 Aug 2019 13:50:35 +0500 Subject: [PATCH 3/5] Add API support for reminders/deadlines --- project_amber/handlers/task.py | 41 +++++++++++++++++++++++----------- project_amber/helpers/task.py | 16 ++++++++++--- project_amber/models/task.py | 4 +++- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/project_amber/handlers/task.py b/project_amber/handlers/task.py index 65ab0e6..7e402c7 100644 --- a/project_amber/handlers/task.py +++ b/project_amber/handlers/task.py @@ -21,14 +21,16 @@ def handle_task_request(): "id": 123, "text": "Some task", "status:": 1, - "last_mod": 12345 // timestamp + "last_mod": 12345, // timestamp + "deadline": 123456 }, { "id": 456, "text": "Some text", "status": 0, "last_mod": 12346, - "parent_id": 123 + "parent_id": 123, + "reminder": 123457 } ] } @@ -54,8 +56,13 @@ def handle_task_request(): "status": task.status, "last_mod": task.last_mod_time }) + currentTask = tasksList[len(tasksList) - 1] if not task.parent_id is None: - tasksList[len(tasksList) - 1]["parent_id"] = task.parent_id + currentTask["parent_id"] = task.parent_id + if not task.deadline is None: + currentTask["deadline"] = task.deadline + if not task.reminder is None: + currentTask["reminder"] = task.reminder if task.last_mod_time > lastMod: lastMod = task.last_mod_time return dumps({ "last_mod": lastMod, @@ -63,14 +70,14 @@ def handle_task_request(): }) if request.method == "POST": text = request.json.get("text") - if text is None: - raise BadRequest(MSG_TEXT_NOT_SPECIFIED) + if text is None: raise BadRequest(MSG_TEXT_NOT_SPECIFIED) status = request.json.get("status") # if only I could `get("status", d=0)` like we do that with dicts - if status is None: - status = 0 + if status is None: status = 0 + deadline = request.json.get("deadline") + reminder = request.json.get("reminder") parent_id = request.json.get("parent_id") # ok to be `None` - new_id = addTask(text, status, parent_id) + new_id = addTask(text, status, parent_id, deadline, reminder) return dumps({ "id": new_id }) def handle_task_id_request(task_id: int): @@ -84,7 +91,9 @@ def handle_task_id_request(task_id: int): "text": "Some text", "status": 1, "last_mod": 123456, // timestamp - "parent_id": 11 // if applicable + "parent_id": 11, // if applicable + "reminder": 123456, // if applicable + "deadline": 123457 // if applicable } ``` On PATCH and DELETE the user will get HTTP 200 with an empty response. On @@ -93,7 +102,9 @@ def handle_task_id_request(task_id: int): { "text": "New task text", "status": 1, // new status - "parent_id": 123 // if applicable + "parent_id": 123, // if applicable + "deadline": 123456, // if applicable + "reminder": 123457, // if applicable } ``` """ @@ -105,15 +116,19 @@ def handle_task_id_request(task_id: int): "status": task.status, "last_mod": task.last_mod_time } - if not task.parent_id is None: - response["parent_id"] = task.parent_id + if not task.parent_id is None: response["parent_id"] = task.parent_id + if not task.deadline is None: response["deadline"] = task.deadline + if not task.reminder is None: response["reminder"] = task.reminder return dumps(response) if request.method == "PATCH": text = request.json.get("text") status = request.json.get("status") parent_id = request.json.get("parent_id") + deadline = request.json.get("deadline") + reminder = request.json.get("reminder") # these are fine to be `None` - updateTask(task_id, text=text, status=status, parent_id=parent_id) + updateTask(task_id, text=text, status=status, parent_id=parent_id, \ + deadline=deadline, reminder=reminder) return EMPTY_RESP if request.method == "DELETE": removeTask(task_id) diff --git a/project_amber/helpers/task.py b/project_amber/helpers/task.py index c755e19..45e9cb2 100644 --- a/project_amber/helpers/task.py +++ b/project_amber/helpers/task.py @@ -1,3 +1,5 @@ +from typing import List + from flask import request from project_amber.const import MSG_TASK_NOT_FOUND, MSG_TASK_DANGEROUS @@ -6,7 +8,10 @@ from project_amber.helpers import time from project_amber.models.task import Task -def addTask(text: str, status: int, parent_id: int) -> int: +TaskList = List[Task] + +def addTask(text: str, status: int, parent_id: int, deadline: int = None, \ + reminder: int = None) -> int: """ Creates a new task. Returns its ID. """ @@ -22,7 +27,8 @@ def addTask(text: str, status: int, parent_id: int) -> int: raise NotFound(MSG_TASK_NOT_FOUND) gen = parent.gen + 1 task = Task(owner=request.user.id, text=text, creation_time=task_time, \ - last_mod_time=task_time, status=status, parent_id=parent_id, gen=gen) + last_mod_time=task_time, status=status, parent_id=parent_id, gen=gen, \ + deadline=deadline, reminder=reminder) db.session.add(task) db.session.commit() return task.id @@ -38,7 +44,7 @@ def getTask(task_id: int) -> Task: raise NotFound(MSG_TASK_NOT_FOUND) return task -def getTasks(text: str = None) -> list: +def getTasks(text: str = None) -> TaskList: """ Returns a list containing tasks from a certain user. If the second parameter is specified, this will return the tasks that have this text in @@ -86,6 +92,10 @@ def updateTask(task_id: int, **kwargs) -> int: raise BadRequest(MSG_TASK_DANGEROUS) task.parent_id = new_parent.id updateChildren(task.id) + if "deadline" in kwargs and not kwargs["deadline"] is None: + task.deadline = kwargs["deadline"] + if "reminder" in kwargs and not kwargs["reminder"] is None: + task.reminder = kwargs["reminder"] task.last_mod_time = time() db.session.commit() return task_id diff --git a/project_amber/models/task.py b/project_amber/models/task.py index f76b82e..a1e928b 100644 --- a/project_amber/models/task.py +++ b/project_amber/models/task.py @@ -7,12 +7,14 @@ class Task(db.Model): """ id = db.Column(db.Integer, primary_key=True) owner = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) - text = db.Column(db.String(65536)) # TODO: probably subject to increase + text = db.Column(db.String(65536)) gen = db.Column(db.Integer, nullable=False) parent_id = db.Column(db.Integer, db.ForeignKey("task.id")) status = db.Column(db.Integer, nullable=False) creation_time = db.Column(db.Integer, nullable=False) last_mod_time = db.Column(db.Integer, nullable=False) + deadline = db.Column(db.Integer) + reminder = db.Column(db.Integer) def is_child(self) -> bool: """ Helper method. Simply checks whether the task is of gen 0 or not. From 0df681a972a0125077e7bbf204c2ef2b5a2ebc34 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Wed, 21 Aug 2019 13:59:37 +0500 Subject: [PATCH 4/5] Remove an excessive line --- project_amber/helpers/task.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/project_amber/helpers/task.py b/project_amber/helpers/task.py index 45e9cb2..79269a2 100644 --- a/project_amber/helpers/task.py +++ b/project_amber/helpers/task.py @@ -8,8 +8,6 @@ from project_amber.helpers import time from project_amber.models.task import Task -TaskList = List[Task] - def addTask(text: str, status: int, parent_id: int, deadline: int = None, \ reminder: int = None) -> int: """ @@ -44,7 +42,7 @@ def getTask(task_id: int) -> Task: raise NotFound(MSG_TASK_NOT_FOUND) return task -def getTasks(text: str = None) -> TaskList: +def getTasks(text: str = None) -> List[Task]: """ Returns a list containing tasks from a certain user. If the second parameter is specified, this will return the tasks that have this text in From 254efc85e0a3004ab4999320bade37141b7269b5 Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Wed, 21 Aug 2019 14:06:30 +0500 Subject: [PATCH 5/5] Refactor task getters --- project_amber/handlers/task.py | 24 ++---------------------- project_amber/models/task.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/project_amber/handlers/task.py b/project_amber/handlers/task.py index 7e402c7..14286d2 100644 --- a/project_amber/handlers/task.py +++ b/project_amber/handlers/task.py @@ -50,19 +50,7 @@ def handle_task_request(): tasksList = [] lastMod = 0 for task in tasks: - tasksList.append({ - "id": task.id, - "text": task.text, - "status": task.status, - "last_mod": task.last_mod_time - }) - currentTask = tasksList[len(tasksList) - 1] - if not task.parent_id is None: - currentTask["parent_id"] = task.parent_id - if not task.deadline is None: - currentTask["deadline"] = task.deadline - if not task.reminder is None: - currentTask["reminder"] = task.reminder + tasksList.append(task.toDict()) if task.last_mod_time > lastMod: lastMod = task.last_mod_time return dumps({ "last_mod": lastMod, @@ -110,15 +98,7 @@ def handle_task_id_request(task_id: int): """ if request.method == "GET": task = getTask(task_id) - response = { - "id": task.id, - "text": task.text, - "status": task.status, - "last_mod": task.last_mod_time - } - if not task.parent_id is None: response["parent_id"] = task.parent_id - if not task.deadline is None: response["deadline"] = task.deadline - if not task.reminder is None: response["reminder"] = task.reminder + response = task.toDict() return dumps(response) if request.method == "PATCH": text = request.json.get("text") diff --git a/project_amber/models/task.py b/project_amber/models/task.py index a1e928b..2206bad 100644 --- a/project_amber/models/task.py +++ b/project_amber/models/task.py @@ -22,3 +22,19 @@ def is_child(self) -> bool: if self.gen > 0: return True return False + def toDict(self) -> dict: + """ + Helper method that converts public task data (ID, text, PID, status, + modtime, deadline and reminders) to a dict that can be safely used in + JSON serialization. Returns the resulting dict. + """ + result = { + "id": self.id, + "text": self.text, + "status": self.status, + "last_mod": self.last_mod_time + } + if self.parent_id: result["parent_id"] = self.parent_id + if self.deadline: result["deadline"] = self.deadline + if self.reminder: result["reminder"] = self.reminder + return result