HabitTracker/models/Habit.py
Yapollon bcfb7aaec6 Update Habit.py
Streak for Daylies was added.
2024-02-20 10:57:45 +01:00

158 lines
5.1 KiB
Python

import json
from dataclasses import dataclass
from datetime import datetime
from datetime import date
from datetime import timedelta
from models.HabitTracking import HabitTracking
from db.SQLiteClient import (create_habit, get_habit, update_habit, delete_habit, get_next_slot, get_slots, update_slot,
get_habitTrackings, get_habitList)
# unit will be represented by integers like this:
# 0: day
# 1: week (default)
# 2: month
# 3: year
@dataclass
class Habit:
id: int
list_id: int
name: str
note: str
times: int
unit: int
slot: int
percentage: int = 0
streak: int = 0
def __post_init__(self):
self.fill_statistics()
@staticmethod
def create(list_id: int, name: str, times: int, note: str = None, unit: int = 1):
slot = get_next_slot(list_id)
id = create_habit(list_id, name, note, times, unit, slot)
return Habit(id, list_id, name, note, times, unit, slot)
@staticmethod
def get(id: int):
habit = get_habit(id)
return Habit(habit[0], habit[1], habit[2], habit[3], habit[4], habit[5], habit[6]) if habit else None
# Updates: name, note, times, unit
def update(self):
update_habit(self.id, self.name, self.note, self.times, self.unit)
# Updates the slot and reorders the HabitList accordingly
def update_slot(self, new_slot: int):
# Fetches a list with the following structure [(id, slot), (id, slot), ...]
slots = get_slots(self.list_id)
# Splits the list depending on whether the new slot is higher or lower than the current one
if new_slot > self.slot: # Example self.slot=1 new_slot=4
slots = slots[self.slot:new_slot] # Expected list: [(id, 2), (id, 3), (id, 4)]
for slot in slots:
update_slot(slot[0], slot[1]-1)
if new_slot < self.slot: # Example self.slot=4 new_slot=1
slots = slots[new_slot-1:self.slot-1] # Expected list: [(id, 1), (id, 2), (id, 3)]
for slot in slots:
update_slot(slot[0], slot[1]+1)
# Update the slot of the current habit
update_slot(self.id, new_slot)
# Deletes the Habit
def delete(self):
# Reorders the slots
slots = get_slots(self.list_id)[self.slot+1:]
for slot in slots:
update_slot(slot[0], slot[1] - 1)
# Deletes all track-records associated with the Habit
trackings = self.get_habitTrackings()
for tracking in trackings:
tracking.delete()
# Deletes the current Habit
delete_habit(self.id)
# Returns all track-records for a Habit
def get_habitTrackings(self) -> list:
trackings = []
for rawTracking in get_habitTrackings(self.id):
trackings.append(HabitTracking(rawTracking[0], rawTracking[1],
datetime.strptime(rawTracking[2], "%Y-%m-%dT%H:%M:%S.%f")))
return trackings
# Returns the HabitList in which the Habit is located
def habit_list(self) -> list:
from models.HabitList import HabitList
raw_habitLists = get_habitList(self.list_id)
return HabitList(raw_habitLists[0], raw_habitLists[1], raw_habitLists[2]) if raw_habitLists else None
def getStreak(self):
trackings = []
for rawTracking in get_habitTrackings(self.id):
trackings.append(datetime.strptime(rawTracking[2], "%Y-%m-%d"))
trackings.sort(reverse=True)
current_date = date.today()
yesterdate = date.today() - timedelta(days=1)
if not trackings:
return self.streak
# bisherige streak zurückgeben, falls nicht vorhanden bei null starten
if self.streak != 0 and (current_date == trackings[0] or yesterdate == trackings[0]):
return self.streak
else:
self.streak = 0
return self.streak
def removeStreak(self):
self.streak -= 1
return
def addStreak(self):
self.streak += 1
return
# Saves the progress of the Habit in the attribute percentage
def fill_statistics(self):
count = 0
self.checked = False
for tracking in self.get_habitTrackings():
if tracking.created_at.date() == datetime.today().date():
self.checked = True
# day
if self.unit == 0:
if tracking.created_at.date() == datetime.today().date():
count += 1
# week
elif self.unit == 1:
if tracking.created_at.isocalendar()[1] == datetime.today().isocalendar()[1]:
count += 1
# month
elif self.unit == 2:
if tracking.created_at.month == datetime.today().month:
count += 1
# year
elif self.unit == 3:
if tracking.created_at.year == datetime.today().year:
count += 1
self.percentage = int(count / self.times * 100)
def to_json(self):
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)