diff --git a/app.py b/app.py index e6fcbce..0c4bac8 100644 --- a/app.py +++ b/app.py @@ -330,11 +330,10 @@ def password_change(): ) -UPLOAD_FOLDER = 'static/profile_images/' # Folder to store profile images -app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER - - def save_profile_image(image_file): + UPLOAD_FOLDER = 'static/profile_images/' # Folder to store profile images + app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER + filename = image_file.filename if '.' not in filename: # Ensure the filename has an extension @@ -397,7 +396,6 @@ def upload_profile_image(): @login_required def check_habit(): habit_id = request.get_json()["habitId"] - habit = Habit.get(habit_id) if habit is None: @@ -418,11 +416,13 @@ def check_habit(): if not delete_tracking: HabitTracking.create(habit_id) + habit.fill_statistics() else: delete_tracking.delete() + habit.reset_statistics() + + habit.load_statistics() - # Update habit - habit.fill_statistics() return { "habitId": habit_id, diff --git a/db/SQLiteClient.py b/db/SQLiteClient.py index 28cb035..d9b811c 100644 --- a/db/SQLiteClient.py +++ b/db/SQLiteClient.py @@ -92,10 +92,10 @@ def delete_user(id: int): ### Habit ### -def create_habit(list_id: int, name: str, note: str, times: int, unit: int, slot: int): +def create_habit(list_id: int, name: str, note: str, times: int, unit: int, slot: int, checked: bool, count:int, streak: int): now = datetime.now().isoformat() - query = (f"INSERT INTO habits (list_id, name, note, times, unit, slot, created_at, updated_at) " - f"VALUES ('{list_id}', '{name}', '{note}', '{times}', '{unit}', '{slot}', '{now}', '{now}');") + query = (f"INSERT INTO habits (list_id, name, note, times, unit, slot, checked, count, streak, created_at, updated_at) " + f"VALUES ('{list_id}', '{name}', '{note}', '{times}', '{unit}', '{slot}', '{checked}', '{count}', '{streak}', '{now}', '{now}');") conn = con3() cursor = conn.cursor() cursor.execute(query) @@ -126,7 +126,6 @@ def get_habits(list_id: int): def get_heatmap_value(user_id: int, days: int): date = (datetime.now() - timedelta(days=days)).date() - print(date) # Uses JOINs to get all Habits query = (f"SELECT habits.id FROM habits " @@ -201,6 +200,18 @@ def update_habit(id: int, name: str, note: str, times: int, unit: int): return cursor.lastrowid +def update_habit_statistics(id: int, checked: bool, count: int, streak: int): + now = datetime.now().isoformat() + query = (f"UPDATE habits SET checked = {checked}, count = {count}, streak = {streak}, updated_at = '{now}' " + f"WHERE id = {id};") + conn = con3() + cursor = conn.cursor() + cursor.execute(query) + conn.commit() + conn.close() + return cursor.lastrowid + + def delete_habit(id: int): query = f"DELETE FROM habits WHERE id = {id};" conn = con3() diff --git a/db/migrations/1709118298_delete_habits_table.sql b/db/migrations/1709118298_delete_habits_table.sql new file mode 100644 index 0000000..6e0914a --- /dev/null +++ b/db/migrations/1709118298_delete_habits_table.sql @@ -0,0 +1 @@ +DROP TABLE habits; \ No newline at end of file diff --git a/db/migrations/1709118311_create_habits_table.sql b/db/migrations/1709118311_create_habits_table.sql new file mode 100644 index 0000000..61720c8 --- /dev/null +++ b/db/migrations/1709118311_create_habits_table.sql @@ -0,0 +1,16 @@ +CREATE TABLE IF NOT EXISTS habits +( + id INTEGER PRIMARY KEY AUTOINCREMENT, + list_id INTEGER NOT NULL, + name TEXT NOT NULL, + note TEXT, + times INTEGER NOT NULL, + unit INTEGER, + slot INTEGER NOT NULL, + checked BOOLEAN NOT NULL, + count INTEGER NOT NULL, + streak INTEGER NOT NULL, + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL, + FOREIGN KEY (list_id) REFERENCES habit_lists(id) +); \ No newline at end of file diff --git a/models/Habit.py b/models/Habit.py index fe515bb..d0fee6d 100644 --- a/models/Habit.py +++ b/models/Habit.py @@ -1,12 +1,11 @@ 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) + get_habitTrackings, get_habitList, update_habit_statistics) # unit will be represented by integers like this: @@ -24,23 +23,24 @@ class Habit: times: int unit: int slot: int - checked: bool = False + checked: bool + count: int + streak: int percentage: int = 0 - streak: int = 0 def __post_init__(self): - self.fill_statistics() + self.load_statistics() @staticmethod - def create(list_id: int, name: str, times: int, note: str = None, unit: int = 1): + def create(list_id: int, name: str, times: int, note: str = None, unit: int = 1, checked: bool = False, count: int = 0, streak: int = 0): 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) + id = create_habit(list_id, name, note, times, unit, slot, checked, count, streak) + return Habit(id, list_id, name, note, times, unit, slot, checked, count, streak) @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 + return Habit(habit[0], habit[1], habit[2], habit[3], habit[4], habit[5], habit[6], habit[7], habit[8], habit[9]) if habit else None # Updates: name, note, times, unit @@ -99,58 +99,32 @@ class Habit: 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 current_date == trackings[0] or yesterdate == trackings[0]: - return self.streak - else: - self.streak = 0 - return self.streak - - # Saves the progress and streak of the Habit in the attribute percentage - def fill_statistics(self): + # Loads the progress and checks if the streak is not broken + def load_statistics(self): + print("loading") today_date = datetime.today().date() - self.checked = False - count = 0 - # self.streak =- 1 - - yesterday_tracked = False - - for tracking in self.get_habitTrackings(): - tracking_date = tracking.created_at.date() - - if tracking_date == today_date - timedelta(days=1): - yesterday_tracked = True - if tracking_date == today_date: - self.checked = True - self.streak = + 1 - - # Count occurrences based on unit - if self.unit == 0 and tracking_date == today_date: - count += 1 # Daily - elif self.unit == 1 and tracking_date.isocalendar()[1] == today_date.isocalendar()[1]: - count += 1 # Weekly - elif self.unit == 2 and tracking_date.month == today_date.month: - count += 1 # Monthly - elif self.unit == 3 and tracking_date.year == today_date.year: - count += 1 # Yearly - - if not yesterday_tracked: + tracking_dates = [tracking.created_at.date() for tracking in self.get_habitTrackings()] + yesterday = today_date - timedelta(days=1) + if not self.checked and not yesterday in tracking_dates: self.streak = 0 + update_habit_statistics(self.id, self.count, self.count, self.streak) + + self.percentage = int(self.count / self.times * 100) + + # Saves the progress count and streak + def fill_statistics(self): + self.checked = True + self.streak += 1 + self.count += 1 + update_habit_statistics(self.id, self.checked, self.count, self.streak) + + # Turns the statistics back to the unchecked state + def reset_statistics(self): + self.checked = False + self.streak -= 1 + self.count -= 1 + update_habit_statistics(self.id, self.checked, self.count, self.streak) - 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) diff --git a/models/HabitList.py b/models/HabitList.py index bdff3f5..110af65 100644 --- a/models/HabitList.py +++ b/models/HabitList.py @@ -42,7 +42,7 @@ class HabitList: raw_habits = get_habits(self.id) habits = [] for habit in raw_habits: - habit = Habit(habit[0], habit[1], habit[2], habit[3], habit[4], habit[5], habit[6]) + habit = Habit(habit[0], habit[1], habit[2], habit[3], habit[4], habit[5], habit[6], habit[7], habit[8], habit[9]) habits.append(habit) return habits