Skip to content
This repository has been archived by the owner on Jan 20, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop' at v0.0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
tdemin committed Apr 28, 2020
2 parents b5cb76b + cb2c31d commit dd49068
Show file tree
Hide file tree
Showing 14 changed files with 200 additions and 114 deletions.
3 changes: 1 addition & 2 deletions .drone.yml
Expand Up @@ -3,9 +3,8 @@ name: Python linting

steps:
- name: pylint
image: python:3.7-stretch
image: python:3.8
commands:
- pip install pylint
- pip install -r requirements.txt
- pylint --rcfile .pylintrc project_amber project_amber/handlers project_amber/controllers project_amber/models
when:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
@@ -1,4 +1,4 @@
FROM python:3.7-alpine
FROM python:3.8-alpine
LABEL maintainer "Timur Demin <me@tdem.in>"
WORKDIR /app
ENV UWSGI_PORT 8080
Expand Down
1 change: 1 addition & 0 deletions Pipfile
Expand Up @@ -7,6 +7,7 @@ verify_ssl = true
pylint = "*"
yapf = "*"
rope = "*"
mypy = "*"

[packages]
bcrypt = "==3.1.7"
Expand Down
237 changes: 157 additions & 80 deletions Pipfile.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions project_amber/app.py
@@ -1,6 +1,7 @@
from json import dumps

from flask import Flask
from flask.wrappers import Response
from flask_cors import CORS

from project_amber.config import config
Expand All @@ -13,8 +14,13 @@
from project_amber.handlers.task import task_handlers as task
from project_amber.handlers.users import user_handlers as user

class JsonResponse(Response):
default_mimetype = "application/json"
charset = "utf-8"

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = config.database
app.response_class = JsonResponse
db.init_app(app)
CORS(app, resources={r"/*": {"origins": config.domain}})

Expand Down
4 changes: 2 additions & 2 deletions project_amber/config.py
Expand Up @@ -34,8 +34,8 @@ class Config:
print(ioerr.strerror)
sys.exit(1)

for entry in vars(config):
if entry in loadedConfig:
for entry in dir(config):
if entry in loadedConfig and not entry.startswith("__"):
setattr(config, entry, loadedConfig[entry])


Expand Down
2 changes: 1 addition & 1 deletion project_amber/const.py
Expand Up @@ -23,4 +23,4 @@
MSG_TEXT_NOT_SPECIFIED = "No text specified"
MSG_TASK_DANGEROUS = "Potentially dangerous operation"

VERSION = "0.0.4"
VERSION = "0.0.5"
2 changes: 1 addition & 1 deletion project_amber/controllers/auth.py
Expand Up @@ -37,7 +37,7 @@ def gen_token() -> str:


class UserController:
user: LoginUser = None
user: LoginUser

def __init__(self, user: LoginUser):
self.user = user
Expand Down
12 changes: 6 additions & 6 deletions project_amber/controllers/task.py
@@ -1,4 +1,4 @@
from typing import List
from typing import List, Optional, cast

from project_amber.const import MSG_TASK_NOT_FOUND, MSG_TASK_DANGEROUS, \
MSG_TEXT_NOT_SPECIFIED
Expand All @@ -10,7 +10,7 @@


class TaskController:
user: LoginUser = None
user: LoginUser

def __init__(self, user: LoginUser):
self.user = user
Expand Down Expand Up @@ -63,11 +63,11 @@ def update_children(self, task_id: int):
task = self.get_task(task_id)
if task.parent_id:
parent = self.get_task(task.parent_id)
parent_list = parent.getParents()
parent_list = parent.get_parents()
parent_list.append(parent.id)
task.setParents(parent_list)
task.set_parents(parent_list)
else:
task.setParents(list())
task.set_parents(list())
children = db.session.query(Task).filter_by(parent_id=task_id).all()
for child in children:
self.update_children(child.id)
Expand All @@ -86,7 +86,7 @@ def update_task(self, task_id: int, data: dict) -> int:
self.update_children(task.id)
else:
new_parent = self.get_task(new_details.parent_id)
if task.id in new_parent.getParents() or task.id == new_parent.id:
if task.id in new_parent.get_parents() or task.id == new_parent.id:
raise BadRequest(MSG_TASK_DANGEROUS)
task.parent_id = new_parent.id
self.update_children(task.id)
Expand Down
4 changes: 2 additions & 2 deletions project_amber/handlers/task.py
Expand Up @@ -55,7 +55,7 @@ def task_request():
tasks = tc.get_tasks(query)
tasksList = list()
for task in tasks:
tasksList.append(task.toDict())
tasksList.append(task.to_dict())
return dumps(tasksList)
if request.method == "POST":
new_id = tc.add_task(request.json)
Expand Down Expand Up @@ -97,7 +97,7 @@ def task_id_request(task_id: int):
tc = TaskController(request.user)
if request.method == "GET":
task = tc.get_task(task_id)
response = task.toDict()
response = task.to_dict()
return dumps(response)
if request.method == "PATCH":
tc.update_task(task_id, request.json)
Expand Down
23 changes: 7 additions & 16 deletions project_amber/models/task.py
Expand Up @@ -17,22 +17,15 @@ 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))
parent_id = db.Column(db.Integer, db.ForeignKey("task.id"))
parent_id = db.Column(db.Integer)
status = db.Column(db.Integer, nullable=False)
creation_time = db.Column(db.BigInteger, nullable=False)
last_mod_time = db.Column(db.BigInteger, nullable=False)
deadline = db.Column(db.BigInteger)
reminder = db.Column(db.BigInteger)
parents = db.Column(db.String(2048), nullable=False)

def isChild(self) -> bool:
"""
Helper method. Simply checks whether the task is of gen 0 or not.
"""
if self.gen > 0: return True
return False

def toDict(self) -> dict:
def to_dict(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
Expand All @@ -52,24 +45,22 @@ def toDict(self) -> dict:
def merge(self, task: "Task"):
"""
Copies public data from another task.
Does not update task generations; this has to be done manually.
"""
for i in ("parent_id", "text", "status", "reminder", "deadline"):
new_value = getattr(task, i)
if new_value is not None:
setattr(self, i, new_value)

def __init__(self, owner: int, data: dict = None):
# TODO: should't throw HTTP errors from model code
# TODO: ideally this dictionary should be a TypedDict; we've bumped our
# Python requirements to 3.8 already
if not isinstance(data, dict): raise BadRequest
self.text = data.get(API_TEXT)
self.status = data.get(API_STATUS)
self.creation_time = time()
self.last_mod_time = self.creation_time
self.parent_id = data.get(API_PID)
# SQLite is fine with 0 in foreign key, Postgres isn't,
# and this needs a workaround
if self.parent_id == 0: self.parent_id = None
self.deadline = data.get(API_DEADLINE)
self.reminder = data.get(API_REMINDER)
self.parents = ""
Expand All @@ -87,7 +78,7 @@ def delete(self):
"""
db.session.delete(self)

def getParents(self) -> List[int]:
def get_parents(self) -> List[int]:
"""
Retrieves a list of connected parent IDs that have a higher tree level.
The list is deserialized from a string contained in the database.
Expand All @@ -96,7 +87,7 @@ def getParents(self) -> List[int]:
return list()
return list(map(lambda x: int(x), self.parents.split(SEPARATOR)))

def setParents(self, pids: List[int]) -> str:
def set_parents(self, pids: List[int]) -> str:
"""
Serializes the provided list of connected parent IDs that have a higher
tree level into a string. Returns the resulting string.
Expand Down
Binary file modified requirements.txt
Binary file not shown.
13 changes: 13 additions & 0 deletions setup.cfg
Expand Up @@ -11,3 +11,16 @@ indent_closing_brackets = false
indent_width = 4
use_tabs = false
column_limit = 100

[mypy]
files = project_amber
namespace_packages = true

[mypy-bcrypt.*]
ignore_missing_imports = true

[mypy-flask_sqlalchemy.*]
ignore_missing_imports = true

[mypy-flask_cors.*]
ignore_missing_imports = true
5 changes: 2 additions & 3 deletions setup.py
Expand Up @@ -4,21 +4,20 @@

setup(
name="project_amber",
version="0.0.4",
version="0.0.5",
description="The backend app of a note-taking app, Project Amber",
url="https://git.tdem.in/tdemin/amber",
author="Timur Demin",
author_email="me@tdem.in",
license="MIT",
classifiers=[
"Development Status :: 3 - Alpha", "License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8"
"Programming Language :: Python :: 3"
],
keywords="tasks backend flask",
project_urls={"Homepage": "https://git.tdem.in/tdemin/amber"},
packages=["project_amber"],
install_requires=["flask", "flask-cors", "flask-sqlalchemy", "bcrypt"],
python_requires=">=3.6"
python_requires=">=3.8"
)

0 comments on commit dd49068

Please sign in to comment.