Habit Streak Update (2/2)

Yeah reworked the entire thing so that the checked, count and streak value is stored in the Habit Table
This commit is contained in:
Yapollon 2024-02-28 14:14:10 +01:00
parent d0c5127c92
commit e2f1402d50
6 changed files with 72 additions and 70 deletions

10
app.py
View File

@ -330,11 +330,10 @@ def password_change():
) )
def save_profile_image(image_file):
UPLOAD_FOLDER = 'static/profile_images/' # Folder to store profile images UPLOAD_FOLDER = 'static/profile_images/' # Folder to store profile images
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def save_profile_image(image_file):
filename = image_file.filename filename = image_file.filename
if '.' not in filename: if '.' not in filename:
# Ensure the filename has an extension # Ensure the filename has an extension
@ -397,7 +396,6 @@ def upload_profile_image():
@login_required @login_required
def check_habit(): def check_habit():
habit_id = request.get_json()["habitId"] habit_id = request.get_json()["habitId"]
habit = Habit.get(habit_id) habit = Habit.get(habit_id)
if habit is None: if habit is None:
@ -418,11 +416,13 @@ def check_habit():
if not delete_tracking: if not delete_tracking:
HabitTracking.create(habit_id) HabitTracking.create(habit_id)
habit.fill_statistics()
else: else:
delete_tracking.delete() delete_tracking.delete()
habit.reset_statistics()
habit.load_statistics()
# Update habit
habit.fill_statistics()
return { return {
"habitId": habit_id, "habitId": habit_id,

View File

@ -92,10 +92,10 @@ def delete_user(id: int):
### Habit ### ### 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() now = datetime.now().isoformat()
query = (f"INSERT INTO habits (list_id, name, note, times, unit, slot, created_at, updated_at) " 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}', '{now}', '{now}');") f"VALUES ('{list_id}', '{name}', '{note}', '{times}', '{unit}', '{slot}', '{checked}', '{count}', '{streak}', '{now}', '{now}');")
conn = con3() conn = con3()
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(query) cursor.execute(query)
@ -126,7 +126,6 @@ def get_habits(list_id: int):
def get_heatmap_value(user_id: int, days: int): def get_heatmap_value(user_id: int, days: int):
date = (datetime.now() - timedelta(days=days)).date() date = (datetime.now() - timedelta(days=days)).date()
print(date)
# Uses JOINs to get all Habits # Uses JOINs to get all Habits
query = (f"SELECT habits.id FROM 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 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): def delete_habit(id: int):
query = f"DELETE FROM habits WHERE id = {id};" query = f"DELETE FROM habits WHERE id = {id};"
conn = con3() conn = con3()

View File

@ -0,0 +1 @@
DROP TABLE habits;

View File

@ -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)
);

View File

@ -1,12 +1,11 @@
import json import json
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime from datetime import datetime
from datetime import date
from datetime import timedelta from datetime import timedelta
from models.HabitTracking import HabitTracking from models.HabitTracking import HabitTracking
from db.SQLiteClient import (create_habit, get_habit, update_habit, delete_habit, get_next_slot, get_slots, update_slot, 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: # unit will be represented by integers like this:
@ -24,23 +23,24 @@ class Habit:
times: int times: int
unit: int unit: int
slot: int slot: int
checked: bool = False checked: bool
count: int
streak: int
percentage: int = 0 percentage: int = 0
streak: int = 0
def __post_init__(self): def __post_init__(self):
self.fill_statistics() self.load_statistics()
@staticmethod @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) slot = get_next_slot(list_id)
id = create_habit(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) return Habit(id, list_id, name, note, times, unit, slot, checked, count, streak)
@staticmethod @staticmethod
def get(id: int): def get(id: int):
habit = get_habit(id) 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 # 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 return HabitList(raw_habitLists[0], raw_habitLists[1], raw_habitLists[2]) if raw_habitLists else None
def getStreak(self): # Loads the progress and checks if the streak is not broken
trackings = [] def load_statistics(self):
print("loading")
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):
today_date = datetime.today().date() today_date = datetime.today().date()
self.checked = False tracking_dates = [tracking.created_at.date() for tracking in self.get_habitTrackings()]
count = 0 yesterday = today_date - timedelta(days=1)
# self.streak =- 1 if not self.checked and not yesterday in tracking_dates:
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:
self.streak = 0 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): def to_json(self):
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)

View File

@ -42,7 +42,7 @@ class HabitList:
raw_habits = get_habits(self.id) raw_habits = get_habits(self.id)
habits = [] habits = []
for habit in raw_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) habits.append(habit)
return habits return habits