-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase.py
More file actions
205 lines (169 loc) · 6.82 KB
/
database.py
File metadata and controls
205 lines (169 loc) · 6.82 KB
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
"""Database operations for Pilotage de Survie."""
import psycopg2
from psycopg2.extras import RealDictCursor
from datetime import date, datetime
from typing import Optional
from config import DATABASE_URL
def get_connection():
"""Get database connection."""
return psycopg2.connect(DATABASE_URL, cursor_factory=RealDictCursor)
# ============ TASKS ============
def add_task(title: str, category: str = "Dynamic", justification: str = "", impact: Optional[str] = None) -> dict:
"""Add a new task for today."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
INSERT INTO tasks (title, category, justification, impact, task_date)
VALUES (%s, %s, %s, %s, CURRENT_DATE)
RETURNING id, title, category, completed
""", (title, category, justification, impact))
conn.commit()
return dict(cur.fetchone())
def get_today_tasks() -> list:
"""Get all tasks for today."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
SELECT id, title, category, completed, justification, impact
FROM tasks
WHERE task_date = CURRENT_DATE
ORDER BY category, id
""")
return [dict(row) for row in cur.fetchall()]
def get_incomplete_tasks_today() -> list:
"""Get incomplete tasks for today."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
SELECT id, title, category
FROM tasks
WHERE task_date = CURRENT_DATE AND completed = FALSE
ORDER BY category, id
""")
return [dict(row) for row in cur.fetchall()]
def mark_task_done(task_id: int) -> Optional[dict]:
"""Mark a task as completed."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
UPDATE tasks
SET completed = TRUE, completed_at = NOW()
WHERE id = %s AND task_date = CURRENT_DATE
RETURNING id, title, completed
""", (task_id,))
conn.commit()
result = cur.fetchone()
return dict(result) if result else None
def mark_task_undone(task_id: int) -> Optional[dict]:
"""Mark a task as not completed."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
UPDATE tasks
SET completed = FALSE, completed_at = NULL
WHERE id = %s AND task_date = CURRENT_DATE
RETURNING id, title, completed
""", (task_id,))
conn.commit()
result = cur.fetchone()
return dict(result) if result else None
def delete_task(task_id: int) -> bool:
"""Delete a task."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
DELETE FROM tasks
WHERE id = %s AND task_date = CURRENT_DATE
RETURNING id
""", (task_id,))
conn.commit()
return cur.fetchone() is not None
# ============ DAILY NOTES ============
def set_daily_note(note: str) -> dict:
"""Set or update today's note."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
INSERT INTO daily_notes (note_date, note)
VALUES (CURRENT_DATE, %s)
ON CONFLICT (note_date)
DO UPDATE SET note = %s, updated_at = NOW()
RETURNING note_date, note
""", (note, note))
conn.commit()
return dict(cur.fetchone())
def get_daily_note() -> Optional[str]:
"""Get today's note."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
SELECT note FROM daily_notes WHERE note_date = CURRENT_DATE
""")
result = cur.fetchone()
return result["note"] if result else None
# ============ STATISTICS ============
def get_today_stats() -> dict:
"""Get statistics for today."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
SELECT
COUNT(*) as total,
COUNT(*) FILTER (WHERE completed = TRUE) as completed,
COUNT(*) FILTER (WHERE completed = FALSE) as pending
FROM tasks
WHERE task_date = CURRENT_DATE
""")
return dict(cur.fetchone())
def has_tasks_today() -> bool:
"""Check if there are any tasks today."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
SELECT EXISTS(SELECT 1 FROM tasks WHERE task_date = CURRENT_DATE)
""")
return cur.fetchone()["exists"]
def has_completed_any_today() -> bool:
"""Check if any task was completed today."""
with get_connection() as conn:
with conn.cursor() as cur:
cur.execute("""
SELECT EXISTS(
SELECT 1 FROM tasks
WHERE task_date = CURRENT_DATE AND completed = TRUE
)
""")
return cur.fetchone()["exists"]
# ============ DEFAULT TASKS ============
def create_default_tasks() -> list:
"""Create default tasks for today if none exist."""
if has_tasks_today():
return []
with get_connection() as conn:
with conn.cursor() as cur:
# Get default tasks from config
cur.execute("SELECT value FROM config WHERE key = 'default_recovery_tasks'")
recovery = cur.fetchone()
recovery_tasks = recovery["value"] if recovery else ["Sport", "Anime/Manga", "Sommeil (8h)"]
cur.execute("SELECT value FROM config WHERE key = 'default_core_tasks'")
core = cur.fetchone()
core_tasks = core["value"] if core else ["Apprentissage Rust", "Prospection Cyber"]
created = []
# Insert recovery tasks
for title in recovery_tasks:
cur.execute("""
INSERT INTO tasks (title, category, task_date)
VALUES (%s, 'Recovery', CURRENT_DATE)
RETURNING id, title, category
""", (title,))
created.append(dict(cur.fetchone()))
# Insert core tasks
for title in core_tasks:
cur.execute("""
INSERT INTO tasks (title, category, task_date)
VALUES (%s, 'Core', CURRENT_DATE)
RETURNING id, title, category
""", (title,))
created.append(dict(cur.fetchone()))
conn.commit()
return created