Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -153,24 +153,16 @@ def load_daily_data(date_key=None):
|
|
| 153 |
try:
|
| 154 |
if file_path.exists():
|
| 155 |
try:
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
# Only save if the file already existed and needed updates
|
| 163 |
-
save_daily_data(data, date_key)
|
| 164 |
-
|
| 165 |
-
return data
|
| 166 |
-
except Exception as e:
|
| 167 |
-
print(f"Error validating data: {e}")
|
| 168 |
-
return create_empty_daily_data()
|
| 169 |
-
except json.JSONDecodeError as e:
|
| 170 |
-
print(f"Error loading data: {e}")
|
| 171 |
-
# Try to clean up the corrupted file
|
| 172 |
-
data = clean_daily_data_file(date_key)
|
| 173 |
return data
|
|
|
|
|
|
|
|
|
|
| 174 |
else:
|
| 175 |
# Only create new file if it's today's date
|
| 176 |
if date_key == get_date_key():
|
|
@@ -178,16 +170,7 @@ def load_daily_data(date_key=None):
|
|
| 178 |
save_daily_data(data, date_key)
|
| 179 |
return data
|
| 180 |
else:
|
| 181 |
-
|
| 182 |
-
return {
|
| 183 |
-
"tracking_metrics": {
|
| 184 |
-
"productivity": 0,
|
| 185 |
-
"energy": 0,
|
| 186 |
-
"mood": 0,
|
| 187 |
-
"sleep_quality": 0,
|
| 188 |
-
"exercise_intensity": 0
|
| 189 |
-
}
|
| 190 |
-
}
|
| 191 |
except Exception as e:
|
| 192 |
print(f"Error loading data: {e}")
|
| 193 |
return create_empty_daily_data()
|
|
@@ -219,14 +202,18 @@ def create_empty_daily_data():
|
|
| 219 |
"habits": {habit: [False] * 7 for habit in current_habits},
|
| 220 |
"focus": {
|
| 221 |
"priorities": [
|
| 222 |
-
[],
|
| 223 |
-
[],
|
| 224 |
-
[]
|
|
|
|
|
|
|
| 225 |
],
|
| 226 |
"later": [
|
| 227 |
-
[],
|
| 228 |
-
[],
|
| 229 |
-
[]
|
|
|
|
|
|
|
| 230 |
],
|
| 231 |
"priority_reward": "",
|
| 232 |
"later_reward": ""
|
|
@@ -247,7 +234,7 @@ def create_empty_daily_data():
|
|
| 247 |
}
|
| 248 |
}
|
| 249 |
|
| 250 |
-
# Add journal section
|
| 251 |
data["journal"] = {
|
| 252 |
question: "" for question in JOURNAL_QUESTIONS
|
| 253 |
}
|
|
@@ -347,10 +334,20 @@ def get_default_habits():
|
|
| 347 |
"""Get the default habits list if no custom list exists"""
|
| 348 |
return [
|
| 349 |
# Morning Routine (Essential)
|
|
|
|
|
|
|
|
|
|
| 350 |
|
| 351 |
# After Work Activities
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
|
| 353 |
# Flexible Throughout Day
|
|
|
|
|
|
|
|
|
|
| 354 |
]
|
| 355 |
|
| 356 |
def load_habits():
|
|
@@ -360,10 +357,24 @@ def load_habits():
|
|
| 360 |
try:
|
| 361 |
with open(config_path, 'r') as f:
|
| 362 |
data = json.load(f)
|
| 363 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 364 |
except Exception as e:
|
| 365 |
print(f"Error loading habits: {e}")
|
| 366 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 367 |
|
| 368 |
def save_habits(habits_list):
|
| 369 |
"""Save the current habits list to configuration"""
|
|
@@ -393,7 +404,7 @@ def save_habits(habits_list):
|
|
| 393 |
|
| 394 |
# Remove redundant constants
|
| 395 |
DEFAULT_SELF_CARE_ITEMS = [
|
| 396 |
-
"Yoga (AM)", "Vitamins", "Outside",
|
| 397 |
"Stretch (PM)", "Reading", "Learning", "Journal",
|
| 398 |
"Tapping", "Meditate", "Brain Train"
|
| 399 |
]
|
|
@@ -859,6 +870,43 @@ def load_user_config():
|
|
| 859 |
|
| 860 |
return default_config
|
| 861 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 862 |
def create_habit_section():
|
| 863 |
"""Create the habit tracking section with better layout"""
|
| 864 |
# Load current habits
|
|
@@ -878,6 +926,9 @@ def create_habit_section():
|
|
| 878 |
summary_text = gr.Markdown()
|
| 879 |
refresh_btn = gr.Button("🔄 Refresh")
|
| 880 |
|
|
|
|
|
|
|
|
|
|
| 881 |
# Connect refresh button to update summary
|
| 882 |
refresh_btn.click(
|
| 883 |
fn=update_summary,
|
|
@@ -900,21 +951,21 @@ def create_habit_section():
|
|
| 900 |
# Morning Section
|
| 901 |
with gr.Group():
|
| 902 |
gr.Markdown("#### 🌅 Morning Routine")
|
| 903 |
-
create_habit_group(morning_habits, summary_text)
|
| 904 |
|
| 905 |
gr.Markdown("---")
|
| 906 |
|
| 907 |
# Evening Section
|
| 908 |
with gr.Group():
|
| 909 |
gr.Markdown("#### 🌙 Evening Activities")
|
| 910 |
-
create_habit_group(evening_habits, summary_text)
|
| 911 |
|
| 912 |
gr.Markdown("---")
|
| 913 |
|
| 914 |
# Flexible Section
|
| 915 |
with gr.Group():
|
| 916 |
gr.Markdown("#### ⭐ Flexible Activities")
|
| 917 |
-
create_habit_group(flexible_habits, summary_text)
|
| 918 |
|
| 919 |
gr.Markdown("---")
|
| 920 |
|
|
@@ -923,8 +974,15 @@ def create_habit_section():
|
|
| 923 |
new_habit = gr.Textbox(
|
| 924 |
label="New Habit/Task",
|
| 925 |
placeholder="Enter a new habit or task to track",
|
| 926 |
-
scale=
|
| 927 |
-
min_width=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 928 |
)
|
| 929 |
duration = gr.Dropdown(
|
| 930 |
choices=["", "15min", "20min", "30min", "45min", "60min"],
|
|
@@ -933,6 +991,95 @@ def create_habit_section():
|
|
| 933 |
min_width=100
|
| 934 |
)
|
| 935 |
add_btn = gr.Button("Add Habit", scale=1, min_width=100)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 936 |
|
| 937 |
def create_habit_group(habits, summary_text):
|
| 938 |
"""Create a group of habit tracking rows with better scaling"""
|
|
@@ -1010,28 +1157,52 @@ def create_habit_group(habits, summary_text):
|
|
| 1010 |
def delete_habit_fn(habit_name=habit):
|
| 1011 |
"""Delete a habit and update the UI"""
|
| 1012 |
try:
|
| 1013 |
-
# 1.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1014 |
current_data = load_daily_data()
|
| 1015 |
-
if habit_name in current_data["habits"]:
|
| 1016 |
del current_data["habits"][habit_name]
|
| 1017 |
save_daily_data(current_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1018 |
|
| 1019 |
-
#
|
| 1020 |
-
|
| 1021 |
-
if habit_name in current_habits:
|
| 1022 |
-
current_habits.remove(habit_name)
|
| 1023 |
-
save_habits(current_habits)
|
| 1024 |
-
|
| 1025 |
-
# 3. Update all existing daily data files to remove this habit
|
| 1026 |
-
update_all_daily_files(habit_to_remove=habit_name)
|
| 1027 |
|
| 1028 |
-
#
|
| 1029 |
-
gr.Info(f"Deleted: {habit_name}")
|
| 1030 |
return gr.update(visible=False)
|
|
|
|
| 1031 |
except Exception as e:
|
| 1032 |
print(f"Error deleting habit: {e}")
|
| 1033 |
gr.Warning(f"Failed to delete {habit_name}")
|
| 1034 |
-
|
| 1035 |
|
| 1036 |
# Connect delete button with proper output
|
| 1037 |
delete_btn.click(
|
|
@@ -1320,7 +1491,43 @@ def manual_save():
|
|
| 1320 |
print(f"Error saving data: {e}")
|
| 1321 |
return "❌ Error saving data"
|
| 1322 |
|
| 1323 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1324 |
# Load initial data
|
| 1325 |
current_data = load_daily_data()
|
| 1326 |
current_data = check_and_refresh_day(current_data)
|
|
@@ -1331,7 +1538,7 @@ with gr.Blocks(theme='Nymbo/Nymbo_Theme') as demo:
|
|
| 1331 |
with gr.Column(scale=2):
|
| 1332 |
pass # Empty column for spacing
|
| 1333 |
with gr.Column(scale=1):
|
| 1334 |
-
gr.Image("./logo.png", show_label=False, container=False, width=250, show_download_button=False)
|
| 1335 |
with gr.Column(scale=2):
|
| 1336 |
pass # Empty column for spacing
|
| 1337 |
|
|
|
|
| 153 |
try:
|
| 154 |
if file_path.exists():
|
| 155 |
try:
|
| 156 |
+
# Try to load and clean the file
|
| 157 |
+
data = clean_json_file(file_path)
|
| 158 |
+
|
| 159 |
+
# Validate and update the data structure
|
| 160 |
+
data = validate_data_structure(data)
|
| 161 |
+
save_daily_data(data, date_key)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
return data
|
| 163 |
+
except Exception as e:
|
| 164 |
+
print(f"Error loading data: {e}")
|
| 165 |
+
return create_empty_daily_data()
|
| 166 |
else:
|
| 167 |
# Only create new file if it's today's date
|
| 168 |
if date_key == get_date_key():
|
|
|
|
| 170 |
save_daily_data(data, date_key)
|
| 171 |
return data
|
| 172 |
else:
|
| 173 |
+
return create_empty_daily_data()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
except Exception as e:
|
| 175 |
print(f"Error loading data: {e}")
|
| 176 |
return create_empty_daily_data()
|
|
|
|
| 202 |
"habits": {habit: [False] * 7 for habit in current_habits},
|
| 203 |
"focus": {
|
| 204 |
"priorities": [
|
| 205 |
+
["", ""], # Empty task and status
|
| 206 |
+
["", ""],
|
| 207 |
+
["", ""],
|
| 208 |
+
["", ""],
|
| 209 |
+
["", ""]
|
| 210 |
],
|
| 211 |
"later": [
|
| 212 |
+
["", ""], # Empty task and status
|
| 213 |
+
["", ""],
|
| 214 |
+
["", ""],
|
| 215 |
+
["", ""],
|
| 216 |
+
["", ""]
|
| 217 |
],
|
| 218 |
"priority_reward": "",
|
| 219 |
"later_reward": ""
|
|
|
|
| 234 |
}
|
| 235 |
}
|
| 236 |
|
| 237 |
+
# Add journal section with empty entries
|
| 238 |
data["journal"] = {
|
| 239 |
question: "" for question in JOURNAL_QUESTIONS
|
| 240 |
}
|
|
|
|
| 334 |
"""Get the default habits list if no custom list exists"""
|
| 335 |
return [
|
| 336 |
# Morning Routine (Essential)
|
| 337 |
+
"Morning Exercise/Yoga",
|
| 338 |
+
"Meditation (20min)",
|
| 339 |
+
|
| 340 |
|
| 341 |
# After Work Activities
|
| 342 |
+
"Evening Stretch (20min)",
|
| 343 |
+
"Active Learning (20min)",
|
| 344 |
+
"Journal",
|
| 345 |
+
|
| 346 |
|
| 347 |
# Flexible Throughout Day
|
| 348 |
+
"Reading (20min)",
|
| 349 |
+
"Take a photo",
|
| 350 |
+
"Future Planning"
|
| 351 |
]
|
| 352 |
|
| 353 |
def load_habits():
|
|
|
|
| 357 |
try:
|
| 358 |
with open(config_path, 'r') as f:
|
| 359 |
data = json.load(f)
|
| 360 |
+
if "habits" in data and isinstance(data["habits"], list):
|
| 361 |
+
return data["habits"]
|
| 362 |
+
else:
|
| 363 |
+
# If the file exists but is invalid, create a new one with defaults
|
| 364 |
+
default_habits = get_default_habits()
|
| 365 |
+
save_habits(default_habits)
|
| 366 |
+
return default_habits
|
| 367 |
except Exception as e:
|
| 368 |
print(f"Error loading habits: {e}")
|
| 369 |
+
# If there's an error reading the file, create a new one with defaults
|
| 370 |
+
default_habits = get_default_habits()
|
| 371 |
+
save_habits(default_habits)
|
| 372 |
+
return default_habits
|
| 373 |
+
else:
|
| 374 |
+
# If the file doesn't exist, create it with defaults
|
| 375 |
+
default_habits = get_default_habits()
|
| 376 |
+
save_habits(default_habits)
|
| 377 |
+
return default_habits
|
| 378 |
|
| 379 |
def save_habits(habits_list):
|
| 380 |
"""Save the current habits list to configuration"""
|
|
|
|
| 404 |
|
| 405 |
# Remove redundant constants
|
| 406 |
DEFAULT_SELF_CARE_ITEMS = [
|
| 407 |
+
"Yoga (AM)", "Vitamins", "Outside",
|
| 408 |
"Stretch (PM)", "Reading", "Learning", "Journal",
|
| 409 |
"Tapping", "Meditate", "Brain Train"
|
| 410 |
]
|
|
|
|
| 870 |
|
| 871 |
return default_config
|
| 872 |
|
| 873 |
+
def add_new_habit(habit_name, duration, category):
|
| 874 |
+
"""Add a new habit to the tracking system"""
|
| 875 |
+
try:
|
| 876 |
+
if not habit_name.strip():
|
| 877 |
+
return "⚠️ Please enter a habit name", None, None, None
|
| 878 |
+
|
| 879 |
+
# Format the habit name with duration if provided
|
| 880 |
+
formatted_habit = habit_name.strip()
|
| 881 |
+
if duration:
|
| 882 |
+
formatted_habit = f"{formatted_habit} ({duration})"
|
| 883 |
+
|
| 884 |
+
# Add category prefix for sorting
|
| 885 |
+
if category == "Morning":
|
| 886 |
+
formatted_habit = f"Morning {formatted_habit}"
|
| 887 |
+
elif category == "Evening":
|
| 888 |
+
formatted_habit = f"Evening {formatted_habit}"
|
| 889 |
+
|
| 890 |
+
# Load current habits
|
| 891 |
+
current_habits = load_habits()
|
| 892 |
+
|
| 893 |
+
# Check if habit already exists
|
| 894 |
+
if formatted_habit in current_habits:
|
| 895 |
+
return "⚠️ This habit already exists", None, None, None
|
| 896 |
+
|
| 897 |
+
# Add new habit to list
|
| 898 |
+
current_habits.append(formatted_habit)
|
| 899 |
+
|
| 900 |
+
# Save updated habits list
|
| 901 |
+
save_habits(current_habits)
|
| 902 |
+
|
| 903 |
+
# Return success message and clear inputs
|
| 904 |
+
return "✅ Habit added successfully!", "", "", ""
|
| 905 |
+
|
| 906 |
+
except Exception as e:
|
| 907 |
+
print(f"Error adding habit: {e}")
|
| 908 |
+
return f"❌ Error adding habit: {str(e)}", None, None, None
|
| 909 |
+
|
| 910 |
def create_habit_section():
|
| 911 |
"""Create the habit tracking section with better layout"""
|
| 912 |
# Load current habits
|
|
|
|
| 926 |
summary_text = gr.Markdown()
|
| 927 |
refresh_btn = gr.Button("🔄 Refresh")
|
| 928 |
|
| 929 |
+
# Add status message component
|
| 930 |
+
status_message = gr.Markdown(visible=False)
|
| 931 |
+
|
| 932 |
# Connect refresh button to update summary
|
| 933 |
refresh_btn.click(
|
| 934 |
fn=update_summary,
|
|
|
|
| 951 |
# Morning Section
|
| 952 |
with gr.Group():
|
| 953 |
gr.Markdown("#### 🌅 Morning Routine")
|
| 954 |
+
create_habit_group(morning_habits, summary_text)
|
| 955 |
|
| 956 |
gr.Markdown("---")
|
| 957 |
|
| 958 |
# Evening Section
|
| 959 |
with gr.Group():
|
| 960 |
gr.Markdown("#### 🌙 Evening Activities")
|
| 961 |
+
create_habit_group(evening_habits, summary_text)
|
| 962 |
|
| 963 |
gr.Markdown("---")
|
| 964 |
|
| 965 |
# Flexible Section
|
| 966 |
with gr.Group():
|
| 967 |
gr.Markdown("#### ⭐ Flexible Activities")
|
| 968 |
+
create_habit_group(flexible_habits, summary_text)
|
| 969 |
|
| 970 |
gr.Markdown("---")
|
| 971 |
|
|
|
|
| 974 |
new_habit = gr.Textbox(
|
| 975 |
label="New Habit/Task",
|
| 976 |
placeholder="Enter a new habit or task to track",
|
| 977 |
+
scale=3,
|
| 978 |
+
min_width=200
|
| 979 |
+
)
|
| 980 |
+
category = gr.Dropdown(
|
| 981 |
+
choices=["Morning", "Evening", "Flexible"],
|
| 982 |
+
label="Category",
|
| 983 |
+
value="Flexible",
|
| 984 |
+
scale=2,
|
| 985 |
+
min_width=100
|
| 986 |
)
|
| 987 |
duration = gr.Dropdown(
|
| 988 |
choices=["", "15min", "20min", "30min", "45min", "60min"],
|
|
|
|
| 991 |
min_width=100
|
| 992 |
)
|
| 993 |
add_btn = gr.Button("Add Habit", scale=1, min_width=100)
|
| 994 |
+
|
| 995 |
+
# Add status message component
|
| 996 |
+
status_message = gr.Markdown(visible=False)
|
| 997 |
+
|
| 998 |
+
def add_and_refresh(habit_name, category, duration):
|
| 999 |
+
message, _, _, _ = add_new_habit(habit_name, duration, category)
|
| 1000 |
+
|
| 1001 |
+
# Reload habits and recreate sections
|
| 1002 |
+
current_habits = load_habits()
|
| 1003 |
+
morning_habits = [h for h in current_habits if any(x in h.lower() for x in ["wake", "morning", "meditation", "brain", "walk"])]
|
| 1004 |
+
evening_habits = [h for h in current_habits if any(x in h.lower() for x in ["evening", "massage", "learning", "journal", "guitar"])]
|
| 1005 |
+
flexible_habits = [h for h in current_habits if h not in morning_habits + evening_habits]
|
| 1006 |
+
|
| 1007 |
+
# Update summary
|
| 1008 |
+
summary = update_summary()
|
| 1009 |
+
|
| 1010 |
+
# Create updated habit groups
|
| 1011 |
+
create_habit_group(morning_habits, summary_text)
|
| 1012 |
+
create_habit_group(evening_habits, summary_text)
|
| 1013 |
+
create_habit_group(flexible_habits, summary_text)
|
| 1014 |
+
|
| 1015 |
+
return [
|
| 1016 |
+
message, # Status message
|
| 1017 |
+
"", # Clear habit input
|
| 1018 |
+
category, # Keep category selection
|
| 1019 |
+
"", # Clear duration input
|
| 1020 |
+
gr.update(visible=True), # Show status message
|
| 1021 |
+
gr.update(value=summary) # Update summary text
|
| 1022 |
+
]
|
| 1023 |
+
|
| 1024 |
+
# Connect the add button event
|
| 1025 |
+
add_btn.click(
|
| 1026 |
+
fn=add_and_refresh,
|
| 1027 |
+
inputs=[new_habit, category, duration],
|
| 1028 |
+
outputs=[
|
| 1029 |
+
status_message,
|
| 1030 |
+
new_habit,
|
| 1031 |
+
category,
|
| 1032 |
+
duration,
|
| 1033 |
+
status_message,
|
| 1034 |
+
summary_text
|
| 1035 |
+
]
|
| 1036 |
+
)
|
| 1037 |
+
|
| 1038 |
+
# Create a refresh button that will be clicked programmatically
|
| 1039 |
+
refresh_habits_btn = gr.Button("Refresh", visible=False)
|
| 1040 |
+
|
| 1041 |
+
def add_and_refresh(habit_name, duration):
|
| 1042 |
+
message, _, _ = add_new_habit(habit_name, duration)
|
| 1043 |
+
return [
|
| 1044 |
+
message, # Status message
|
| 1045 |
+
"", # Clear habit input
|
| 1046 |
+
"", # Clear duration input
|
| 1047 |
+
gr.update(visible=True), # Show status message
|
| 1048 |
+
True # Trigger refresh button
|
| 1049 |
+
]
|
| 1050 |
+
|
| 1051 |
+
# Connect the add button event
|
| 1052 |
+
add_btn.click(
|
| 1053 |
+
fn=add_and_refresh,
|
| 1054 |
+
inputs=[new_habit, duration],
|
| 1055 |
+
outputs=[
|
| 1056 |
+
status_message,
|
| 1057 |
+
new_habit,
|
| 1058 |
+
duration,
|
| 1059 |
+
status_message,
|
| 1060 |
+
refresh_habits_btn
|
| 1061 |
+
]
|
| 1062 |
+
)
|
| 1063 |
+
|
| 1064 |
+
# Connect refresh button to reload habits
|
| 1065 |
+
def reload_habits():
|
| 1066 |
+
current_habits = load_habits()
|
| 1067 |
+
morning_habits = [h for h in current_habits if any(x in h.lower() for x in ["wake", "morning", "meditation", "brain", "walk"])]
|
| 1068 |
+
evening_habits = [h for h in current_habits if any(x in h.lower() for x in ["evening", "massage", "learning", "journal", "guitar"])]
|
| 1069 |
+
flexible_habits = [h for h in current_habits if h not in morning_habits + evening_habits]
|
| 1070 |
+
|
| 1071 |
+
return [
|
| 1072 |
+
gr.update(value=update_summary()), # Update summary
|
| 1073 |
+
gr.update(visible=False) # Hide status message
|
| 1074 |
+
]
|
| 1075 |
+
|
| 1076 |
+
refresh_habits_btn.click(
|
| 1077 |
+
fn=reload_habits,
|
| 1078 |
+
outputs=[
|
| 1079 |
+
summary_text,
|
| 1080 |
+
status_message
|
| 1081 |
+
]
|
| 1082 |
+
)
|
| 1083 |
|
| 1084 |
def create_habit_group(habits, summary_text):
|
| 1085 |
"""Create a group of habit tracking rows with better scaling"""
|
|
|
|
| 1157 |
def delete_habit_fn(habit_name=habit):
|
| 1158 |
"""Delete a habit and update the UI"""
|
| 1159 |
try:
|
| 1160 |
+
# 1. Delete from habits_config.json first
|
| 1161 |
+
config_path = Path("habits_config.json")
|
| 1162 |
+
if config_path.exists():
|
| 1163 |
+
with open(config_path, 'r') as f:
|
| 1164 |
+
config_data = json.load(f)
|
| 1165 |
+
if "habits" in config_data:
|
| 1166 |
+
if habit_name in config_data["habits"]:
|
| 1167 |
+
config_data["habits"].remove(habit_name)
|
| 1168 |
+
with open(config_path, 'w') as f:
|
| 1169 |
+
json.dump(config_data, f, indent=2)
|
| 1170 |
+
print(f"Removed {habit_name} from habits_config.json")
|
| 1171 |
+
|
| 1172 |
+
# 2. Update current daily data
|
| 1173 |
current_data = load_daily_data()
|
| 1174 |
+
if "habits" in current_data and habit_name in current_data["habits"]:
|
| 1175 |
del current_data["habits"][habit_name]
|
| 1176 |
save_daily_data(current_data)
|
| 1177 |
+
print(f"Removed {habit_name} from current daily data")
|
| 1178 |
+
|
| 1179 |
+
# 3. Clean up historical data
|
| 1180 |
+
json_files = list(DATA_DIR.glob("*.json"))
|
| 1181 |
+
for file_path in json_files:
|
| 1182 |
+
try:
|
| 1183 |
+
with open(file_path, 'r') as f:
|
| 1184 |
+
day_data = json.load(f)
|
| 1185 |
+
if "habits" in day_data and habit_name in day_data["habits"]:
|
| 1186 |
+
del day_data["habits"][habit_name]
|
| 1187 |
+
with open(file_path, 'w') as f:
|
| 1188 |
+
json.dump(day_data, f, indent=2)
|
| 1189 |
+
print(f"Removed {habit_name} from {file_path}")
|
| 1190 |
+
except Exception as e:
|
| 1191 |
+
print(f"Error updating file {file_path}: {e}")
|
| 1192 |
+
|
| 1193 |
+
# Show success notification
|
| 1194 |
+
gr.Info(f"Deleted: {habit_name}")
|
| 1195 |
|
| 1196 |
+
# Force reload habits from config
|
| 1197 |
+
load_habits() # Reload habits to ensure sync
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1198 |
|
| 1199 |
+
# Hide the row in UI
|
|
|
|
| 1200 |
return gr.update(visible=False)
|
| 1201 |
+
|
| 1202 |
except Exception as e:
|
| 1203 |
print(f"Error deleting habit: {e}")
|
| 1204 |
gr.Warning(f"Failed to delete {habit_name}")
|
| 1205 |
+
return gr.update()
|
| 1206 |
|
| 1207 |
# Connect delete button with proper output
|
| 1208 |
delete_btn.click(
|
|
|
|
| 1491 |
print(f"Error saving data: {e}")
|
| 1492 |
return "❌ Error saving data"
|
| 1493 |
|
| 1494 |
+
def clean_json_file(file_path):
|
| 1495 |
+
"""Clean up potentially corrupted JSON file"""
|
| 1496 |
+
try:
|
| 1497 |
+
with open(file_path, 'r') as f:
|
| 1498 |
+
content = f.read().strip()
|
| 1499 |
+
|
| 1500 |
+
# Try to find the last valid JSON structure
|
| 1501 |
+
try:
|
| 1502 |
+
# First try to parse as-is
|
| 1503 |
+
data = json.loads(content)
|
| 1504 |
+
return data
|
| 1505 |
+
except json.JSONDecodeError:
|
| 1506 |
+
# If that fails, try to clean up the content
|
| 1507 |
+
# Find the last closing brace
|
| 1508 |
+
last_brace = content.rfind('}')
|
| 1509 |
+
if last_brace != -1:
|
| 1510 |
+
content = content[:last_brace + 1]
|
| 1511 |
+
try:
|
| 1512 |
+
data = json.loads(content)
|
| 1513 |
+
# Save the cleaned data back to file
|
| 1514 |
+
with open(file_path, 'w') as f:
|
| 1515 |
+
json.dump(data, f, indent=2)
|
| 1516 |
+
return data
|
| 1517 |
+
except json.JSONDecodeError:
|
| 1518 |
+
pass
|
| 1519 |
+
|
| 1520 |
+
# If all cleanup attempts fail, create new data
|
| 1521 |
+
data = create_empty_daily_data()
|
| 1522 |
+
with open(file_path, 'w') as f:
|
| 1523 |
+
json.dump(data, f, indent=2)
|
| 1524 |
+
return data
|
| 1525 |
+
|
| 1526 |
+
except Exception as e:
|
| 1527 |
+
print(f"Error cleaning JSON file {file_path}: {e}")
|
| 1528 |
+
return create_empty_daily_data()
|
| 1529 |
+
|
| 1530 |
+
with gr.Blocks() as demo:
|
| 1531 |
# Load initial data
|
| 1532 |
current_data = load_daily_data()
|
| 1533 |
current_data = check_and_refresh_day(current_data)
|
|
|
|
| 1538 |
with gr.Column(scale=2):
|
| 1539 |
pass # Empty column for spacing
|
| 1540 |
with gr.Column(scale=1):
|
| 1541 |
+
gr.Image("./logo.png", show_label=False, container=False, width=250, show_download_button=False, )
|
| 1542 |
with gr.Column(scale=2):
|
| 1543 |
pass # Empty column for spacing
|
| 1544 |
|