File size: 4,965 Bytes
2f88c81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
from copy import deepcopy
import models
from psql_database import engine, Base, SessionLocal
import sqlalchemy as sa
import schemas as schemas
import passlib.hash as pwd_hash
import re
from fastapi import HTTPException, Depends, security
import jwt


OAUTH2_SCHEME = security.OAuth2PasswordBearer(tokenUrl="/api/token")

JWT_SECRET = 'myjwtsecret'


def validate_email(email):
    pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
    return bool(re.match(pattern, email))


def create_database_tables():
    return Base.metadata.create_all(bind=engine)


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


async def get_user_by_email(email: str, db: sa.orm.Session):
    return db.query(models.User).filter(models.User.email == email).first()


async def create_user(user: schemas.userCreate, db: sa.orm.Session):

    if not validate_email(user.email):
        raise HTTPException(status_code=400, detail="Invalid email")

    user_obj = models.User(
        first_name=user.first_name,
        last_name=user.last_name,
        email=user.email,
        password=pwd_hash.bcrypt.hash(user.password)
    )

    db.add(user_obj)
    db.commit()  # commit operation
    db.refresh(user_obj)  # Await the refresh operation
    return user_obj


async def authenticate_user(email, password, db: sa.orm.Session):
    user = await get_user_by_email(email=email, db=db)

    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user if user.verify_password(password) else False


async def create_token(user: models.User):
    user_dict = {
        "first_name": user.first_name,
        "last_name": user.last_name,
        "email": user.email,
    }
    token = jwt.encode(user_dict, JWT_SECRET)

    return dict(access_token=token, token_type='bearer', status='success')


async def get_current_user(db: sa.orm.Session = Depends(get_db), token: str = Depends(OAUTH2_SCHEME)):
    try:
        payload = jwt.decode(token, JWT_SECRET, algorithms=['HS256'])
        print(payload)
        user = db.query(models.User).filter(
            models.User.email == payload['email']).first()
        if not user:
            raise HTTPException(status_code=404, detail="User not found")
        return schemas.User(**user.__dict__)
    except Exception as e:
        raise HTTPException(status_code=401, detail="Invalid token") from e


async def create_todo(user: schemas.User, todo: schemas.TodoCreate, db: sa.orm.Session = Depends(get_db)):
    print(todo.dict())

    todo_obj = models.Todo(
        task_name=todo.task_name,
        task_description=todo.task_description,
        priority=todo.priority,
        category=todo.category,
        due_date=todo.due_date,
        status=todo.status,
        user_id=user.user_id,
    )

    db.add(todo_obj)
    db.commit()
    db.refresh(todo_obj)
    return todo_obj


async def get_todos(user: schemas.User, db: sa.orm.Session = Depends(get_db)):
    return db.query(models.Todo).filter(models.Todo.user_id == user.user_id).all()


async def delete_todo(todo_id: int, user: schemas.User, db: sa.orm.Session = Depends(get_db)):
    todo = db.query(models.Todo).filter(models.Todo.user_id ==
                                        user.user_id, models.Todo.todo_id == todo_id).first()
    if not todo:
        raise HTTPException(status_code=404, detail="Todo not found")
    db.delete(todo)
    db.commit()
    return todo


async def update_todo(todo_id: int, user: schemas.User, todo: schemas.TodoCreate, db: sa.orm.Session = Depends(get_db)):
    todo_db = db.query(models.Todo).filter(
        models.Todo.user_id == user.user_id, models.Todo.todo_id == todo_id).first()
    if not todo_db:
        raise HTTPException(status_code=404, detail="Todo not found")
    todo_db.task_name = todo.task_name
    todo_db.task_description = todo.task_description or todo.task_description
    todo_db.priority = todo.priority
    todo_db.category = todo.category
    todo_db.due_date = todo.due_date
    todo_db.status = todo.status

    db.commit()
    db.refresh(todo_db)
    return todo_db


async def get_today_todos(user: schemas.User, db: sa.orm.Session = Depends(get_db)):
    return db.query(models.Todo).filter(models.Todo.user_id == user.user_id, sa.func.date(models.Todo.due_date) == sa.func.date(sa.func.now())).all()


async def get_overdue_todos(user: schemas.User, db: sa.orm.Session = Depends(get_db)):
    return db.query(models.Todo).filter(models.Todo.user_id == user.user_id, models.Todo.due_date < sa.func.now()).all()


async def get_upcoming_todos(user: schemas.User, db: sa.orm.Session = Depends(get_db)):
    return db.query(models.Todo).filter(models.Todo.user_id == user.user_id, models.Todo.due_date > sa.func.now()).all()


async def get_completed_todos(user: schemas.User, db: sa.orm.Session = Depends(get_db)):
    return db.query(models.Todo).filter(models.Todo.user_id == user.user_id, models.Todo.status == True).all()