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: diff --git a/project_amber/handlers/task.py b/project_amber/handlers/task.py index 65ab0e6..14286d2 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 } ] } @@ -48,14 +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 - }) - if not task.parent_id is None: - tasksList[len(tasksList) - 1]["parent_id"] = task.parent_id + tasksList.append(task.toDict()) if task.last_mod_time > lastMod: lastMod = task.last_mod_time return dumps({ "last_mod": lastMod, @@ -63,14 +58,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 +79,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,27 +90,25 @@ 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 } ``` """ 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 + response = task.toDict() 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..79269a2 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,8 @@ from project_amber.helpers import time from project_amber.models.task import Task -def addTask(text: str, status: int, parent_id: int) -> int: +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 +25,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 +42,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) -> 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 @@ -86,6 +90,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 92f086f..2206bad 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. @@ -20,6 +22,19 @@ 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 + 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