]>
us-delaporte.pagekite.me Git - matrix-goal-bot.git/blob - matrix_goal_bot/db.py
3 from datetime
import datetime
as dt
5 from sqlmodel
import Field
, Session
, SQLModel
, create_engine
, select
, text
, Relationship
7 logger
= logging
.getLogger(__name__
)
9 DATE_FORMAT
= '%Y-%m-%d'
12 return dt
.now().strftime(DATE_FORMAT
)
15 class Vision(SQLModel
, table
=True):
16 id: int |
None = Field(default
=None, primary_key
=True)
17 name
: str = Field(default
=None, unique
=True)
18 complete_date
: dt |
None = Field(default
=None)
19 goals
: list["Goal"] = Relationship(back_populates
="vision")
21 return f
'{self.name} (Vision {self.id})'
24 class PreferGoal(SQLModel
, table
=True):
25 goal_id
: int |
None = Field(default
=None, foreign_key
="goal.id", primary_key
=True)
28 class Goal(SQLModel
, table
=True):
29 id: int |
None = Field(default
=None, primary_key
=True)
30 name
: str = Field(default
=None, unique
=True)
31 start_date
: dt |
None = Field(default
=dt
.today())
32 complete_date
: dt |
None = Field(default
=None)
33 vision_id
: int |
None = Field(default
=None, foreign_key
="vision.id")
34 notes
: str |
None = Field(default
=None)
35 tasks
: list["Task"] = Relationship(back_populates
="goal")
36 vision
: Vision
= Relationship(back_populates
="goals")
38 if not self
.complete_date
:
39 return f
'{self.name} (Goal {self.id})'
41 completed
= self
.complete_date
.strftime(DATE_FORMAT
)
42 return f
'(Done {completed}) {self.name} (Goal {self.id})'
44 class Task(SQLModel
, table
=True):
45 id: int |
None = Field(default
=None, primary_key
=True)
46 name
: str = Field(default
=None, unique
=True)
47 goal_id
: int |
None = Field(default
=None, foreign_key
="goal.id")
48 complete_date
: dt |
None = Field(default
=None)
49 goal
: Goal
= Relationship(back_populates
="tasks")
51 return f
'{self.name} ({self.id})'
54 def pretty_print(goal
, tasks
):
56 results
.append(f
' ## {goal}')
58 results
.append('-- Nothing to list --')
61 if(task
.complete_date
):
62 results
.append(f
' - [x] {task}')
64 results
.append(f
' - [ ] {task}')
68 def _get_with_id(cls
, item_id
):
69 return select(cls
).where(cls
.id == item_id
)
71 def _get_with_name(cls
, name
):
72 return select(cls
).where(func
.lower(cls
.name
) == func
.lower(name
))
76 def __init__(self
, db_file
=None):
78 db_file
= os
.path
.join(os
.environ
.get('MATRIX_DATA_DIR', ''), 'goal.db')
81 self
.engine
= self
.get_engine()
85 return create_engine(f
"sqlite:///{self.file}")
88 SQLModel
.metadata
.create_all(self
.engine
)
92 with Session(self
.engine
) as session
:
93 session
.exec(text(''' alter table goal add start_date DATETIME; '''))
98 def _set_pref_goal_id(self
, goal_id
):
99 with Session(self
.engine
) as session
:
100 prefs
= session
.exec(select(PreferGoal
)).all()
105 pref
.goal_id
= goal_id
109 def _get_pref_goal_id(self
):
110 with Session(self
.engine
) as session
:
111 pref
= session
.exec(select(PreferGoal
)).one()
115 def clear(self
, goal_id
, clear_all
=False):
116 with Session(self
.engine
) as session
:
117 goal
= session
.exec(_get_with_id(Goal
, goal_id
)).first()
118 for item
in goal
.tasks
:
119 if clear_all
or item
.complete_date
:
123 def get_all_visions(self
):
124 with Session(self
.engine
) as session
:
125 cmd
= select(Vision
).where(Vision
.complete_date
== None)
126 return session
.exec(cmd
).all()
128 def get_all_goals(self
):
130 with Session(self
.engine
) as session
:
131 cmd
= select(Goal
).where(Goal
.complete_date
== None)
132 return session
.exec(cmd
).all()
134 def get_current_goals(self
):
135 '''List current goals'''
136 with Session(self
.engine
) as session
:
137 cmd
= select(Goal
).where(Goal
.complete_date
== None).where(Goal
.start_date
<= dt
.today())
138 results
= session
.exec(cmd
).all()
139 logger
.debug(f
'Current goals: {results}')
142 def get_done_goals(self
):
143 '''List completed goals'''
144 with Session(self
.engine
) as session
:
145 cmd
= select(Goal
).where(Goal
.complete_date
!= None)
146 return session
.exec(cmd
).all()
149 def get_goal(self
, goal_id
):
150 self
._set
_pref
_goal
_id
(goal_id
)
151 with Session(self
.engine
) as session
:
152 cmd
= select(Goal
).where(Goal
.id == goal_id
)
153 goal
= session
.exec(cmd
).first()
154 return (goal
, goal
.tasks
)
156 def get_vision(self
, id):
157 with Session(self
.engine
) as session
:
158 cmd
= select(Vision
).where(Vision
.id == id)
159 vision
= session
.exec(cmd
).first()
161 return (vision
, vision
.goals
)
163 return ('Not found', [])
166 def complete_vision(self
, id):
167 with Session(self
.engine
) as session
:
168 cmd
= select(Vision
).where(Vision
.id == id)
169 vision
= session
.exec(cmd
).first()
170 vision
.complete_date
= dt
.today()
174 def complete_goal(self
, goal_id
):
176 with Session(self
.engine
) as session
:
177 cmd
= select(Goal
).where(Goal
.id == goal_id
)
178 goal
= session
.exec(cmd
).first()
179 goal
.complete_date
= dt
.today()
180 vision_id
= goal
.vision_id
185 def put_off_goal(self
, goal_id
):
187 with Session(self
.engine
) as session
:
188 cmd
= select(Goal
).where(Goal
.id == goal_id
)
189 goal
= session
.exec(cmd
).first()
190 goal
.start_date
= dt
.today() + timedelta(days
=14)
191 vision_id
= goal
.vision_id
195 def start_goal(self
, goal_id
):
197 with Session(self
.engine
) as session
:
198 cmd
= select(Goal
).where(Goal
.id == goal_id
)
199 goal
= session
.exec(cmd
).first()
200 goal
.start_date
= dt
.today()
201 vision_id
= goal
.vision_id
204 return (vision
, vision
.goals
)
206 return ('No Vision Assigned', [])
209 def rename_goal(self
, goal_id
, name
):
210 self
._set
_pref
_goal
_id
(goal_id
)
212 with Session(self
.engine
) as session
:
213 cmd
= select(Goal
).where(Goal
.id == goal_id
)
214 goal
= session
.exec(cmd
).first()
216 vision_id
= goal
.vision_id
221 def complete_task(self
, id):
222 with Session(self
.engine
) as session
:
223 cmd
= select(Task
).where(Task
.id == id)
224 task
= session
.exec(cmd
).first()
225 task
.complete_date
= dt
.today()
226 goal_id
= task
.goal_id
228 self
._set
_pref
_goal
_id
(goal_id
)
231 def add_with_name(self
, cls
, name
):
233 with Session(self
.engine
) as session
:
240 def add_vision(self
, name
):
241 return self
.add_with_name(Vision
, name
)
243 def add_goal(self
, name
):
244 goal_id
= self
.add_with_name(Goal
, name
)
245 self
._set
_pref
_goal
_id
(goal_id
)
248 def quick_add_task(self
, name
):
249 goal_id
= self
._get
_pref
_goal
_id
()
250 task_id
= self
.add_with_name(Task
, name
)
251 with Session(self
.engine
) as session
:
252 cmd
= select(Task
).where(Task
.id == task_id
)
253 new
= session
.exec(cmd
).first()
254 new
.goal_id
= goal_id
258 def remove_task(self
, task_id
):
260 logger
.debug(f
'Removing task with id {task_id}')
261 with Session(self
.engine
) as session
:
262 cmd
= select(Task
).where(Task
.id == int(task_id
))
263 to_remove
= session
.exec(cmd
).first()
265 return f
'Unable to find task with id {task_id}'
267 logger
.debug(f
'Removing task with name {to_remove.name}')
268 task_name
= to_remove
.name
269 session
.delete(to_remove
)
271 return f
'Removed task "{task_name}"'
273 def assign_vision(self
, goal_id
, vision_id
):
274 '''Goals may move between visions'''
275 self
._set
_pref
_goal
_id
(goal_id
)
276 with Session(self
.engine
) as session
:
277 cmd
= select(Goal
).where(Goal
.id == goal_id
)
278 goal
= session
.exec(cmd
).first()
279 goal
.vision_id
= vision_id
282 def visionless(self
):
283 '''Get goals with no vision'''
284 with Session(self
.engine
) as session
:
285 cmd
= select(Goal
).where(Goal
.vision_id
== None)
286 return session
.exec(cmd
).all()
289 def add_note(self
, note
, goal
):
290 '''Notes print with the goal.'''
293 # Someday: Notes on each