Severian commited on
Commit
8b90f94
·
verified ·
1 Parent(s): 378e4c4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +264 -57
app.py CHANGED
@@ -153,24 +153,16 @@ def load_daily_data(date_key=None):
153
  try:
154
  if file_path.exists():
155
  try:
156
- with open(file_path, 'r') as f:
157
- data = json.load(f)
158
- try:
159
- # Validate and update existing data
160
- data = validate_data_structure(data)
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
- # Return empty metrics for historical dates that don't exist
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
- return data.get("habits", get_default_habits())
 
 
 
 
 
 
364
  except Exception as e:
365
  print(f"Error loading habits: {e}")
366
- return get_default_habits()
 
 
 
 
 
 
 
 
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) # Pass summary_text as parameter
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) # Pass summary_text as parameter
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) # Pass summary_text as parameter
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=4,
927
- min_width=250
 
 
 
 
 
 
 
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. Update current daily data
 
 
 
 
 
 
 
 
 
 
 
 
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
- # 2. Update habits configuration
1020
- current_habits = load_habits()
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
- # Show notification
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
- return gr.update()
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
- with gr.Blocks(theme='Nymbo/Nymbo_Theme') as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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