]> apps.delaporte.us Git - matrix-goal-bot.git/blob - matrix_goal_bot/db.py
97ea2c05b623038dffefdc2d6e36999a78f3fccc
[matrix-goal-bot.git] / matrix_goal_bot / db.py
1 import logging
2 import os
3 from datetime import datetime as dt
4
5 from sqlmodel import Field, Session, SQLModel, create_engine, select, text, Relationship
6
7
8 DATE_FORMAT = '%Y-%m-%d'
9
10 def today():
11 return dt.now().strftime(DATE_FORMAT)
12
13
14 logger = logging.getLogger(__name__)
15 logging.basicConfig(filename='goals.log', encoding='utf-8', level=logging.DEBUG)
16
17
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")
23 def __str__(self):
24 return f'{self.name} (Vision {self.id})'
25
26
27 class Goal(SQLModel, table=True):
28 id: int | None = Field(default=None, primary_key=True)
29 name: str = Field(default=None, unique=True)
30 complete_date: dt | None = Field(default=None)
31 vision_id: int | None = Field(default=None, foreign_key="vision.id")
32 notes: str | None = Field(default=None)
33 tasks: list["Task"] = Relationship(back_populates="goal")
34 vision: Vision = Relationship(back_populates="goals")
35 def __str__(self):
36 if not self.complete_date:
37 return f'{self.name} (Goal {self.id})'
38 else:
39 completed = self.complete_date.strftime(DATE_FORMAT)
40 return f'(Done {completed}) {self.name} (Goal {self.id})'
41
42 class Task(SQLModel, table=True):
43 id: int | None = Field(default=None, primary_key=True)
44 name: str = Field(default=None, unique=True)
45 goal_id: int | None = Field(default=None, foreign_key="goal.id")
46 complete_date: dt | None = Field(default=None)
47 goal: Goal = Relationship(back_populates="tasks")
48 def __str__(self):
49 return f'{self.name} ({self.id})'
50
51
52 def pretty_print(goal, tasks):
53 results = []
54 results.append(f' ## {goal}')
55 if not tasks:
56 results.append('-- Nothing to list --')
57
58 for task in tasks:
59 if(task.complete_date):
60 results.append(f' - [x] {task}')
61 else:
62 results.append(f' - [ ] {task}')
63 return results
64
65
66 class Data():
67 def __init__(self, db_file=None):
68 if not db_file:
69 db_file = os.path.join(os.environ.get('MATRIX_DATA_DIR', ''), 'goals.db')
70
71 self.file = db_file
72 self.engine = self.get_engine()
73
74
75 def get_engine(self):
76 return create_engine(f"sqlite:///{self.file}")
77
78 def setup(self):
79 SQLModel.metadata.create_all(self.engine)
80 return 'Success'
81
82
83 def get_all_visions(self):
84 with Session(self.engine) as session:
85 cmd = select(Vision).where(Vision.complete_date == None)
86 return session.exec(cmd).all()
87
88 def print_ophan_tasks(self):
89 pass
90
91 def get_all_goals(self):
92 '''List all goals'''
93 with Session(self.engine) as session:
94 cmd = select(Goal).where(Goal.complete_date == None)
95 return session.exec(cmd).all()
96
97
98 def get_done_goals(self):
99 '''List completed goals'''
100 with Session(self.engine) as session:
101 cmd = select(Goal).where(Goal.complete_date != None)
102 return session.exec(cmd).all()
103
104
105 def get_goal(self, id):
106 with Session(self.engine) as session:
107 cmd = select(Goal).where(Goal.id == id)
108 goal = session.exec(cmd).first()
109 return (goal, goal.tasks)
110
111 def get_vision(self, id):
112 with Session(self.engine) as session:
113 cmd = select(Vision).where(Vision.id == id)
114 vision = session.exec(cmd).first()
115 if vision:
116 return (vision, vision.goals)
117 else:
118 return ('Not found', [])
119
120
121 def complete_vision(self, id):
122 with Session(self.engine) as session:
123 cmd = select(Vision).where(Vision.id == id)
124 vision = session.exec(cmd).first()
125 vision.complete_date = dt.today()
126 session.commit()
127
128
129 def complete_goal(self, id):
130 vision_id = -1
131 with Session(self.engine) as session:
132 cmd = select(Goal).where(Goal.id == id)
133 goal = session.exec(cmd).first()
134 goal.complete_date = dt.today()
135 vision_id = goal.vision_id
136 session.commit()
137 return vision_id
138
139 def complete_task(self, id):
140 with Session(self.engine) as session:
141 cmd = select(Task).where(Task.id == id)
142 task = session.exec(cmd).first()
143 task.complete_date = dt.today()
144 goal_id = task.goal_id
145 session.commit()
146 return goal_id
147
148 def add_with_name(self, cls, name):
149 id = -1
150 with Session(self.engine) as session:
151 new = cls(name=name)
152 session.add(new)
153 session.commit()
154 id = new.id
155 return id
156
157 def add_vision(self, name):
158 return self.add_with_name(Vision, name)
159
160 def add_goal(self, name):
161 return self.add_with_name(Goal, name)
162
163 def add_task(self, goal_id, name):
164 result = self.add_with_name(Task, name)
165 with Session(self.engine) as session:
166 cmd = select(Task).where(Task.name == name)
167 new = session.exec(cmd).first()
168 new.goal_id = goal_id
169 session.commit()
170 return result
171
172 def assign_vision(self, goal_id, vision_id):
173 '''Goals may move between visions'''
174 with Session(self.engine) as session:
175 cmd = select(Goal).where(Goal.id == goal_id)
176 goal = session.exec(cmd).first()
177 goal.vision_id = vision_id
178 session.commit()
179
180 def visionless(self):
181 '''Get goals with no vision'''
182 with Session(self.engine) as session:
183 cmd = select(Goal).where(Goal.vision_id == None)
184 return session.exec(cmd).all()
185
186
187 def add_note(self, note, goal):
188 '''Notes print with the goal.'''
189 pass
190
191 # Someday: Notes on each
192