]>
apps.delaporte.us 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
8 DATE_FORMAT
= '%Y-%m-%d'
11 return dt
.now().strftime(DATE_FORMAT
)
14 logger
= logging
.getLogger(__name__
)
15 logging
.basicConfig(filename
='goals.log', encoding
='utf-8', level
=logging
.DEBUG
)
18 class Vision(SQLModel
, table
=True):
19 id: int |
None = Field(default
=None, primary_key
=True)
20 name
: str = Field(default
=None, unique
=True)
21 complete_date
: dt |
None = Field(default
=None)
22 goals
: list["Goal"] = Relationship(back_populates
="vision")
24 return f
'{self.name} (Vision {self.id})'
27 class PreferGoal(SQLModel
, table
=True):
28 goal_id
: int |
None = Field(default
=None, foreign_key
="goal.id", primary_key
=True)
31 class Goal(SQLModel
, table
=True):
32 id: int |
None = Field(default
=None, primary_key
=True)
33 name
: str = Field(default
=None, unique
=True)
34 complete_date
: dt |
None = Field(default
=None)
35 vision_id
: int |
None = Field(default
=None, foreign_key
="vision.id")
36 notes
: str |
None = Field(default
=None)
37 tasks
: list["Task"] = Relationship(back_populates
="goal")
38 vision
: Vision
= Relationship(back_populates
="goals")
40 if not self
.complete_date
:
41 return f
'{self.name} (Goal {self.id})'
43 completed
= self
.complete_date
.strftime(DATE_FORMAT
)
44 return f
'(Done {completed}) {self.name} (Goal {self.id})'
46 class Task(SQLModel
, table
=True):
47 id: int |
None = Field(default
=None, primary_key
=True)
48 name
: str = Field(default
=None, unique
=True)
49 goal_id
: int |
None = Field(default
=None, foreign_key
="goal.id")
50 complete_date
: dt |
None = Field(default
=None)
51 goal
: Goal
= Relationship(back_populates
="tasks")
53 return f
'{self.name} ({self.id})'
56 def pretty_print(goal
, tasks
):
58 results
.append(f
' ## {goal}')
60 results
.append('-- Nothing to list --')
63 if(task
.complete_date
):
64 results
.append(f
' - [x] {task}')
66 results
.append(f
' - [ ] {task}')
71 def __init__(self
, db_file
=None):
73 db_file
= os
.path
.join(os
.environ
.get('MATRIX_DATA_DIR', ''), 'goals.db')
76 self
.engine
= self
.get_engine()
80 return create_engine(f
"sqlite:///{self.file}")
83 SQLModel
.metadata
.create_all(self
.engine
)
87 def _set_pref_goal_id(self
, goal_id
):
88 with Session(self
.engine
) as session
:
89 prefs
= session
.exec(select(PreferGoal
)).all()
93 pref
.goal_id
= goal_id
97 def _get_pref_goal_id(self
):
98 with Session(self
.engine
) as session
:
99 pref
= session
.exec(select(PreferGoal
)).one()
104 def get_all_visions(self
):
105 with Session(self
.engine
) as session
:
106 cmd
= select(Vision
).where(Vision
.complete_date
== None)
107 return session
.exec(cmd
).all()
109 def get_all_goals(self
):
111 with Session(self
.engine
) as session
:
112 cmd
= select(Goal
).where(Goal
.complete_date
== None)
113 return session
.exec(cmd
).all()
116 def get_done_goals(self
):
117 '''List completed goals'''
118 with Session(self
.engine
) as session
:
119 cmd
= select(Goal
).where(Goal
.complete_date
!= None)
120 return session
.exec(cmd
).all()
123 def get_goal(self
, goal_id
):
124 self
._set
_pref
_goal
_id
(goal_id
)
125 with Session(self
.engine
) as session
:
126 cmd
= select(Goal
).where(Goal
.id == goal_id
)
127 goal
= session
.exec(cmd
).first()
128 return (goal
, goal
.tasks
)
130 def get_vision(self
, id):
131 with Session(self
.engine
) as session
:
132 cmd
= select(Vision
).where(Vision
.id == id)
133 vision
= session
.exec(cmd
).first()
135 return (vision
, vision
.goals
)
137 return ('Not found', [])
140 def complete_vision(self
, id):
141 with Session(self
.engine
) as session
:
142 cmd
= select(Vision
).where(Vision
.id == id)
143 vision
= session
.exec(cmd
).first()
144 vision
.complete_date
= dt
.today()
148 def complete_goal(self
, goal_id
):
149 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 goal
.complete_date
= dt
.today()
155 vision_id
= goal
.vision_id
159 def rename_goal(self
, goal_id
, name
):
160 self
._set
_pref
_goal
_id
(goal_id
)
162 with Session(self
.engine
) as session
:
163 cmd
= select(Goal
).where(Goal
.id == goal_id
)
164 goal
= session
.exec(cmd
).first()
166 vision_id
= goal
.vision_id
171 def complete_task(self
, id):
172 with Session(self
.engine
) as session
:
173 cmd
= select(Task
).where(Task
.id == id)
174 task
= session
.exec(cmd
).first()
175 task
.complete_date
= dt
.today()
176 goal_id
= task
.goal_id
178 self
._set
_pref
_goal
_id
(goal_id
)
181 def add_with_name(self
, cls
, name
):
183 with Session(self
.engine
) as session
:
190 def add_vision(self
, name
):
191 return self
.add_with_name(Vision
, name
)
193 def add_goal(self
, name
):
194 goal_id
= self
.add_with_name(Goal
, name
)
195 self
._set
_pref
_goal
_id
(goal_id
)
198 def quick_add_task(self
, name
):
199 goal_id
= self
._get
_pref
_goal
_id
()
200 task_id
= self
.add_with_name(Task
, name
)
201 with Session(self
.engine
) as session
:
202 cmd
= select(Task
).where(Task
.id == task_id
)
203 new
= session
.exec(cmd
).first()
204 new
.goal_id
= goal_id
208 def remove_task(self
, task_id
):
210 with Session(self
.engine
) as session
:
211 cmd
= select(Task
).where(Task
.id == task_id
)
212 to_remove
= session
.exec(cmd
).first()
213 task_name
= to_remove
.name
214 session
.delete(to_remove
)
216 return f
'Removed task "{task_name}"'
218 def assign_vision(self
, goal_id
, vision_id
):
219 '''Goals may move between visions'''
220 self
._set
_pref
_goal
_id
(goal_id
)
221 with Session(self
.engine
) as session
:
222 cmd
= select(Goal
).where(Goal
.id == goal_id
)
223 goal
= session
.exec(cmd
).first()
224 goal
.vision_id
= vision_id
227 def visionless(self
):
228 '''Get goals with no vision'''
229 with Session(self
.engine
) as session
:
230 cmd
= select(Goal
).where(Goal
.vision_id
== None)
231 return session
.exec(cmd
).all()
234 def add_note(self
, note
, goal
):
235 '''Notes print with the goal.'''
238 # Someday: Notes on each