Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/todo list #285

Merged
merged 26 commits into from Feb 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b385f73
created templates of forms and the list, started with database models…
liaarbel Feb 6, 2021
73d9f37
created to do list functions, templates an routers
liaarbel Feb 7, 2021
892f168
added create, edit and delete functions. little changes with the fronted
liaarbel Feb 10, 2021
f97a148
added if tasks done and added tests
liaarbel Feb 12, 2021
7e1a2da
fixed test of creating task
liaarbel Feb 13, 2021
568c8d6
changed test_if_task_has_done data parameters
liaarbel Feb 13, 2021
4b1855f
merged
liaarbel Feb 13, 2021
b1442a4
fixed tests - if task has done, and fixed models examples
liaarbel Feb 14, 2021
916db78
merged
liaarbel Feb 14, 2021
36ed683
added newline
liaarbel Feb 14, 2021
3e7c4a3
removed imports and changed parameters name
liaarbel Feb 14, 2021
28f9f95
added newline and changed parameter name
liaarbel Feb 14, 2021
c1a902b
deleted spaces
liaarbel Feb 14, 2021
8891aca
changed data parameter name
liaarbel Feb 14, 2021
b7287f1
moved js to new file
liaarbel Feb 16, 2021
4d7e29d
merged
liaarbel Feb 23, 2021
b4134d1
changed modals names, change functions in js from jquery, reformatted…
liaarbel Feb 23, 2021
bf946d7
merged
liaarbel Feb 23, 2021
ab20f1b
add ','
liaarbel Feb 23, 2021
aaa25aa
splited modal to each template, first try changing from jQuery, chang…
liaarbel Feb 25, 2021
39b12f9
splited modal to each template
liaarbel Feb 25, 2021
8aa8efd
merged
liaarbel Feb 25, 2021
d5c15d6
changed js from jQuery, fixed edit task test and added attributes to …
liaarbel Feb 25, 2021
9bf753e
removed todo, fixed typing, checked about owner in delete_task() and …
liaarbel Feb 25, 2021
cc67d8e
removed commented code, changed url to url_for, removed console.log a…
liaarbel Feb 26, 2021
b37f6a0
fixed dayview momentary change
liaarbel Feb 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions app/database/models.py
Expand Up @@ -9,6 +9,7 @@
JSON,
Boolean,
Column,
Date,
DateTime,
Enum,
Float,
Expand Down Expand Up @@ -68,6 +69,8 @@ class User(Base):
back_populates="user",
)
comments = relationship("Comment", back_populates="user")
tasks = relationship(
"Task", cascade="all, delete", back_populates="owner")

oauth_credentials = relationship(
"OAuthCredentials",
Expand Down Expand Up @@ -550,6 +553,21 @@ class InternationalDays(Base):
international_day = Column(String, nullable=False)


class Task(Base):
__tablename__ = "tasks"

id = Column(Integer, primary_key=True, index=True)
title = Column(String, nullable=False)
description = Column(String, nullable=False)
is_done = Column(Boolean, default=False)
is_important = Column(Boolean, nullable=False)
date = Column(Date, nullable=False)
time = Column(Time, nullable=False)
owner_id = Column(Integer, ForeignKey("users.id"))

owner = relationship("User", back_populates="tasks")


# insert language data


Expand Down
35 changes: 35 additions & 0 deletions app/internal/todo_list.py
@@ -0,0 +1,35 @@
from datetime import date, time

from sqlalchemy.orm import Session

from app.database.models import Task
from app.internal.utils import create_model


def create_task(
db: Session,
title: str,
description: str,
date_str: date,
time_str: time,
owner_id: int,
is_important: bool,
) -> Task:
"""Creates and saves a new task."""
task = create_model(
db,
Task,
title=title,
description=description,
date=date_str,
time=time_str,
owner_id=owner_id,
is_important=is_important,
is_done=False,
)
return task


def by_id(db: Session, task_id: int) -> Task:
task = db.query(Task).filter_by(id=task_id).one()
return task
2 changes: 2 additions & 0 deletions app/main.py
Expand Up @@ -80,6 +80,7 @@ def create_tables(engine, psql_environment):
search,
settings,
telegram,
todo_list,
user,
weekview,
weight,
Expand Down Expand Up @@ -133,6 +134,7 @@ async def swagger_ui_redirect():
search.router,
settings.router,
telegram.router,
todo_list.router,
liaarbel marked this conversation as resolved.
Show resolved Hide resolved
user.router,
weekview.router,
weight.router,
Expand Down
52 changes: 29 additions & 23 deletions app/routers/dayview.py
Expand Up @@ -4,12 +4,10 @@

from fastapi import APIRouter, Depends, HTTPException, Request

from app.database.models import Event, User
from app.database.models import Event, Task, User
from app.dependencies import get_db, templates
from app.internal import international_days, zodiac
from app.internal.security.dependencies import current_user

# from app.internal.security.schema import CurrentUser
from app.routers.user import get_all_user_events

router = APIRouter()
Expand Down Expand Up @@ -74,9 +72,9 @@ def _date_is_today(self) -> bool:

class EventsAttributes(DivAttributes):
def __init__(
self,
event: Event,
day: Union[bool, datetime] = False,
self,
event: Event,
day: Union[bool, datetime] = False,
) -> None:
self.start_time = event.start
self.end_time = event.end
Expand Down Expand Up @@ -136,9 +134,9 @@ def _check_multiday_event(self) -> Tuple[bool, bool]:


def is_specific_time_event_in_day(
event: Event,
day: datetime,
day_end: datetime,
event: Event,
day: datetime,
day_end: datetime,
) -> bool:
if event.all_day:
return False
Expand All @@ -150,9 +148,9 @@ def is_specific_time_event_in_day(


def is_all_day_event_in_day(
event: Event,
day: datetime,
day_end: datetime,
event: Event,
day: datetime,
day_end: datetime,
) -> bool:
if not event.all_day:
return False
Expand All @@ -164,9 +162,9 @@ def is_all_day_event_in_day(


def get_events_and_attributes(
day: datetime,
session,
user_id: int,
day: datetime,
session,
user_id: int,
) -> Iterator[Tuple[Event, EventsAttributes]]:
events = get_all_user_events(session, user_id)
day_end = day + timedelta(hours=24)
Expand All @@ -176,9 +174,9 @@ def get_events_and_attributes(


def get_all_day_events(
day: datetime,
session,
user_id: int,
day: datetime,
session,
user_id: int,
) -> Iterator[Event]:
events = get_all_user_events(session, user_id)
day_end = day + timedelta(hours=24)
Expand All @@ -189,11 +187,11 @@ def get_all_day_events(

@router.get("/day/{date}", include_in_schema=False)
async def dayview(
request: Request,
date: str,
view="day",
session=Depends(get_db),
user: User = Depends(current_user),
request: Request,
date: str,
view="day",
session=Depends(get_db),
user: User = Depends(current_user),
):
try:
day = datetime.strptime(date, "%Y-%m-%d")
Expand All @@ -212,6 +210,12 @@ async def dayview(
)
current_time_with_attrs = CurrentTimeAttributes(date=day)
inter_day = international_days.get_international_day_per_day(session, day)
tasks = (
session.query(Task)
.filter(Task.owner_id == user.user_id)
.filter(Task.date == day.date())
.order_by(Task.time)
)
month = day.strftime("%B").upper()
return templates.TemplateResponse(
"calendar_day_view.html",
Expand All @@ -221,9 +225,11 @@ async def dayview(
"all_day_events": all_day_events,
"month": month,
"day": day.day,
"date_str": date,
"international_day": inter_day,
"zodiac": zodiac_obj,
"view": view,
"current_time": current_time_with_attrs,
"tasks": tasks,
},
)
143 changes: 143 additions & 0 deletions app/routers/todo_list.py
@@ -0,0 +1,143 @@
from datetime import datetime

from fastapi import APIRouter, Depends, Form, status
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse, RedirectResponse
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from starlette.requests import Request

from app.config import templates
from app.dependencies import get_db
from app.internal.todo_list import by_id, create_task
from app.internal.utils import get_current_user

router = APIRouter(
prefix="/task",
tags=["task"],
responses={status.HTTP_404_NOT_FOUND: {"description": "Not found"}},
)


@router.post("/delete")
def delete_task(
request: Request,
task_id: int = Form(...),
db: Session = Depends(get_db),
) -> RedirectResponse:
user = get_current_user(db)
task = by_id(db, task_id)
if task.owner_id != user.id:
return templates.TemplateResponse(
"calendar_day_view.html",
{"task_id": task_id},
status_code=status.HTTP_403_FORBIDDEN,
)

date_str = task.date.strftime('%Y-%m-%d')
try:
# Delete task
db.delete(task)

db.commit()

except (SQLAlchemyError, TypeError):
return templates.TemplateResponse(
"calendar_day_view.html",
{"task_id": task_id},
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
return RedirectResponse(
request.url_for("dayview", date=date_str),
status_code=status.HTTP_302_FOUND,
)


@router.post("/add")
async def add_task(
request: Request,
title: str = Form(...),
description: str = Form(...),
date_str: str = Form(...),
time_str: str = Form(...),
is_important: bool = Form(False),
session: Session = Depends(get_db),
) -> RedirectResponse:
user = get_current_user(session)
create_task(
session,
title,
description,
datetime.strptime(date_str, '%Y-%m-%d').date(),
datetime.strptime(time_str, '%H:%M').time(),
user.id,
is_important,
)
return RedirectResponse(
request.url_for("dayview", date=date_str),
status_code=status.HTTP_303_SEE_OTHER,
)


@router.post("/edit")
async def edit_task(
request: Request,
task_id: int = Form(...),
title: str = Form(...),
description: str = Form(...),
date_str: str = Form(...),
time_str: str = Form(...),
is_important: bool = Form(False),
session: Session = Depends(get_db),
) -> RedirectResponse:
task = by_id(session, task_id)
task.title = title
task.description = description
task.date = datetime.strptime(date_str, '%Y-%m-%d').date()
task.time = datetime.strptime(time_str, '%H:%M:%S').time()
task.is_important = is_important
session.commit()
return RedirectResponse(
request.url_for("dayview", date=date_str),
status_code=status.HTTP_303_SEE_OTHER,
)


@router.post("/done/{task_id}")
async def set_task_done(
request: Request,
task_id: int,
session: Session = Depends(get_db),
) -> RedirectResponse:
task = by_id(session, task_id)
task.is_done = True
session.commit()
return RedirectResponse(
request.url_for("dayview", date=task.date.strftime('%Y-%m-%d')),
status_code=status.HTTP_303_SEE_OTHER,
)


@router.post("/undone/{task_id}")
async def set_task_undone(
request: Request,
task_id: int,
session: Session = Depends(get_db),
) -> RedirectResponse:
task = by_id(session, task_id)
task.is_done = False
session.commit()
return RedirectResponse(
request.url_for("dayview", date=task.date.strftime('%Y-%m-%d')),
status_code=status.HTTP_303_SEE_OTHER,
)


@router.get("/{task_id}")
async def get_task(
task_id: int,
session: Session = Depends(get_db),
) -> JSONResponse:
task = by_id(session, task_id)
data = jsonable_encoder(task)
return JSONResponse(content=data)