From 562d46ac58e39ad76effa4e7f2275b2b9aa19e10 Mon Sep 17 00:00:00 2001 From: Shiv Date: Fri, 29 Aug 2025 15:30:13 +0530 Subject: [PATCH] Implement dashboard and CLI features --- backend/__init__.py | 0 backend/scripts/__init__.py | 0 backend/scripts/productivity/__init__.py | 0 backend/scripts/productivity/dashboard.py | 106 ++++++++++++++++++ .../scripts/productivity/pomodoro_timer.py | 50 +++++++-- .../scripts/productivity/reminder_system.py | 69 ++++++------ backend/scripts/productivity/time_tracker.py | 70 ++++++------ backend/scripts/productivity/todo_manager.py | 85 +++++++------- reminders.json | 18 +++ todo_list.json | 16 +++ 10 files changed, 293 insertions(+), 121 deletions(-) create mode 100644 backend/__init__.py create mode 100644 backend/scripts/__init__.py create mode 100644 backend/scripts/productivity/__init__.py create mode 100644 backend/scripts/productivity/dashboard.py create mode 100644 reminders.json create mode 100644 todo_list.json diff --git a/backend/__init__.py b/backend/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/scripts/__init__.py b/backend/scripts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/scripts/productivity/__init__.py b/backend/scripts/productivity/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/scripts/productivity/dashboard.py b/backend/scripts/productivity/dashboard.py new file mode 100644 index 00000000..73d5c1e7 --- /dev/null +++ b/backend/scripts/productivity/dashboard.py @@ -0,0 +1,106 @@ +""" +PyEveryday Daily Dashboard + +This script provides a centralized dashboard for productivity tools: + - Todos + - Reminders + - Pomodoro Timer + - Time Tracking + - Weather + - Motivational Quote + - Configurable section toggles +""" + +import os +import json +try: + from quote_fetcher import QuoteFetcher +except ImportError: + try: + from productivity.quote_fetcher import QuoteFetcher + except ImportError: + try: + from backend.scripts.productivity.quote_fetcher import QuoteFetcher + except ImportError: + QuoteFetcher = None +from datetime import datetime +import requests + +CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'dashboard_config.json') +DEFAULT_CONFIG = { + "show_todos": True, + "show_reminders": True, + "show_pomodoro": True, + "show_time_tracking": True, + "show_quote": True, + # Weather removed +} + +def load_config(): + if os.path.exists(CONFIG_PATH): + try: + with open(CONFIG_PATH, 'r') as f: + return json.load(f) + except Exception: + pass + return DEFAULT_CONFIG.copy() + +config = load_config() + +def section_header(title): + return f"\n--- {title} ---" + + + +# --- Motivational Quote --- +def get_motivational_quote(): + if QuoteFetcher is None: + return "Quote: (not available)" + try: + fetcher = QuoteFetcher() + return fetcher.get_local_quote() + except Exception as e: + return f"Quote: ERROR: {type(e).__name__}: {e}" + +# --- Dynamic Section Loader --- +def try_import_and_run(module_name, func_name, section_title): + try: + import importlib + mod = importlib.import_module(module_name) + func = getattr(mod, func_name) + result = func() + if result: + return section_header(section_title) + f"\n{result}" + except Exception as e: + return section_header(section_title) + f"\nERROR: {type(e).__name__}: {e}" + return "" + +def main(): + print("\n=== PyEveryday Daily Dashboard ===\n") + print(f"Date: {datetime.now().strftime('%Y-%m-%d %H:%M')}") + + # Todos + if config.get("show_todos", True): + print(try_import_and_run('todo_manager', 'dashboard_summary', 'Todos')) + + # Reminders + if config.get("show_reminders", True): + print(try_import_and_run('reminder_system', 'dashboard_summary', 'Reminders')) + + # Pomodoro + if config.get("show_pomodoro", True): + print(try_import_and_run('pomodoro_timer', 'dashboard_summary', 'Pomodoro Timer')) + + # Time Tracking + if config.get("show_time_tracking", True): + print(try_import_and_run('time_tracker', 'dashboard_summary', 'Time Tracking')) + + + + # Motivational Quote + if config.get("show_quote", True): + print(section_header('Motivational Quote')) + print(get_motivational_quote()) + +if __name__ == "__main__": + main() diff --git a/backend/scripts/productivity/pomodoro_timer.py b/backend/scripts/productivity/pomodoro_timer.py index 544243f6..4c62de53 100644 --- a/backend/scripts/productivity/pomodoro_timer.py +++ b/backend/scripts/productivity/pomodoro_timer.py @@ -1,8 +1,24 @@ +def dashboard_summary(): + # Show completed sessions today + try: + stats_file = "pomodoro_stats.json" + import json, datetime + today = datetime.date.today().isoformat() + if not os.path.exists(stats_file): + return "No pomodoro sessions yet." + with open(stats_file, 'r') as f: + data = json.load(f) + today_sessions = [s for s in data if s.get('date') == today] + return f"Sessions today: {len(today_sessions)}" + except Exception: + return "No pomodoro stats available." + import time import datetime import sys import threading import os +import argparse class PomodoroTimer: def __init__(self, work_duration=25, break_duration=5, long_break_duration=15): @@ -146,28 +162,42 @@ def interactive_mode(): else: print("Unknown command") + if __name__ == "__main__": - if len(sys.argv) > 1: - command = sys.argv[1].lower() - timer = PomodoroTimer() - - if command == "work": + parser = argparse.ArgumentParser(description="Pomodoro Timer") + parser.add_argument('--work', type=int, help='Work session duration in minutes') + parser.add_argument('--break', dest='break_', type=int, help='Short break duration in minutes') + parser.add_argument('--long-break', type=int, help='Long break duration in minutes') + parser.add_argument('--session', choices=['work', 'break'], help='Start a work or break session immediately') + parser.add_argument('--stats', action='store_true', help='Show Pomodoro statistics') + parser.add_argument('--reset', action='store_true', help='Reset session count') + parser.add_argument('--interactive', action='store_true', help='Start in interactive mode') + args = parser.parse_args() + + # If any CLI flag is used, run in CLI mode + if any([args.work, args.break_, args.long_break, args.session, args.stats, args.reset]) and not args.interactive: + timer = PomodoroTimer( + work_duration=args.work if args.work else 25, + break_duration=args.break_ if args.break_ else 5, + long_break_duration=args.long_break if args.long_break else 15 + ) + if args.session == 'work': thread = timer.start_work_session() if thread: try: thread.join() except KeyboardInterrupt: timer.stop() - - elif command == "break": + elif args.session == 'break': thread = timer.start_break() if thread: try: thread.join() except KeyboardInterrupt: timer.stop() - - else: - print("Usage: python pomodoro_timer.py [work|break]") + if args.stats: + timer.get_stats() + if args.reset: + timer.reset_sessions() else: interactive_mode() diff --git a/backend/scripts/productivity/reminder_system.py b/backend/scripts/productivity/reminder_system.py index b94d336a..dfc3ea43 100644 --- a/backend/scripts/productivity/reminder_system.py +++ b/backend/scripts/productivity/reminder_system.py @@ -1,3 +1,13 @@ +def dashboard_summary(): + mgr = ReminderManager() + active = [r for r in mgr.reminders if r.active] + if not active: + return "No active reminders." + msg = f"Active reminders: {len(active)}" + next_rem = min(active, key=lambda r: r.reminder_time, default=None) + if next_rem: + msg += f"\nNext: {next_rem.message} at {next_rem.reminder_time.strftime('%Y-%m-%d %H:%M')}" + return msg import datetime import time import json @@ -167,51 +177,38 @@ def create_quick_reminders(): print("Quick reminders created!") + if __name__ == "__main__": + import argparse import sys - + parser = argparse.ArgumentParser(description="Reminder System") + parser.add_argument('--add', nargs=2, metavar=('MESSAGE', 'TIME'), help='Add a new reminder. TIME format: HH:MM or YYYY-MM-DDTHH:MM') + parser.add_argument('--repeat', help='Repeat interval for the reminder (e.g., 30m, 1h)') + parser.add_argument('--list', action='store_true', help='List all reminders') + parser.add_argument('--remove', metavar='REMINDER_ID', help='Remove a reminder by ID') + parser.add_argument('--monitor', action='store_true', help='Start monitoring reminders') + parser.add_argument('--quick', action='store_true', help='Create quick reminders') + parser.add_argument('--interactive', action='store_true', help='Start in interactive mode') + args = parser.parse_args() + manager = ReminderManager() - - if len(sys.argv) < 2: - print("Usage: python reminder_system.py [args]") - print("Commands: add, list, remove, monitor, quick") - sys.exit(1) - - command = sys.argv[1] - - if command == "add": - if len(sys.argv) < 4: - print("Usage: add