From 5ba2e862d9dec8996ab0dcaf2f3c0f2d97cd9562 Mon Sep 17 00:00:00 2001 From: freeram Date: Tue, 7 May 2024 13:36:24 -0600 Subject: [PATCH] Clean --- src/frames/settings_frame.py | 85 ++++++++++++++++++++++++------- src/frames/stats_frame.py | 13 ++--- src/logic/richpresence.py | 26 +++++++--- src/reusable/settings_reusable.py | 24 +++++---- src/reusable/stats_reusable.py | 25 ++++++--- src/utils.py | 15 +++++- 6 files changed, 137 insertions(+), 51 deletions(-) diff --git a/src/frames/settings_frame.py b/src/frames/settings_frame.py index 0bd595f..9c3ef80 100644 --- a/src/frames/settings_frame.py +++ b/src/frames/settings_frame.py @@ -8,32 +8,79 @@ class SettingsFrame(ctk.CTkScrollableFrame): def __init__(self, master): super().__init__(master) config = load_config() - - self.abcycling_var = ctk.IntVar(value=config.get("auto_break_cycling", 0)) - self.abcycling_switch = ctk.CTkCheckBox(self, text=" Automatic break cycling", border_width=2, variable=self.abcycling_var, onvalue=1, offvalue=0, command=self.change_abcycling) + self.initialize_ui(config) + + def initialize_ui(self, config): + # ABC + self.abcycling_var = ctk.IntVar(value=config.get("auto_break_cycling", 0)) + self.abcycling_switch= ctk.CTkCheckBox(self, + text=" Automatic break cycling", + border_width=2, + variable=self.abcycling_var, + onvalue=1, + offvalue=0, + command=self.change_abcycling) self.abcycling_switch.pack(pady=(10, 5)) - self.sbl_entry = EntryFrame(self, "Short breaks before\nlong break (if auto cycling):", config, "short_breaks_before_long", DEF_SB_BEFORE_L, self.change_sb_before_l) - self.pomodoro_entry = EntryFrame(self, "Pomodoro Duration (mins):", config, "pomodoro_time", DEF_POMODORO_MINS, self.change_pomodoro_time) - self.sb_entry = EntryFrame(self, "Short Break Duration (mins):", config, "short_break_time", DEF_SB_MINS, self.change_sb_time) - self.lb_entry = EntryFrame(self, "Long Break Duration (mins):", config, "long_break_time", DEF_LB_MINS, self.change_lb_time) + # Enter a number frames + self.sbl_entry = EntryFrame(self, + text="Short breaks before\nlong break (if auto cycling):", + config=config, + config_attr="short_breaks_before_long", + defvalue=DEF_SB_BEFORE_L, + command=self.change_sb_before_l) + self.pomodoro_entry = EntryFrame(self, + text="Pomodoro Duration (mins):", + config=config, + config_attr="pomodoro_time", + defvalue=DEF_POMODORO_MINS, + command=self.change_pomodoro_time) + self.sb_entry = EntryFrame(self, + text="Short Break Duration (mins):", + config=config, + config_attr="short_break_time", + defvalue=DEF_SB_MINS, + command=self.change_sb_time) + self.lb_entry = EntryFrame(self, + text="Long Break Duration (mins):", + config=config, + config_attr="long_break_time", + defvalue=DEF_LB_MINS, + command=self.change_lb_time) - self.theme_label = ctk.CTkLabel(self, text="Select Theme (RESTARTS APP):") - self.theme_label.pack(pady=(20, 0)) - self.theme_options = [os.path.splitext(theme)[0] for theme in os.listdir(THEMES_DIR) if theme.endswith('.json')] - selected = ctk.StringVar(value=config.get('theme', 'Default')) - self.theme_menu = ctk.CTkOptionMenu(self, variable=selected, values=self.theme_options, anchor="n", command=self.change_theme) - self.theme_menu.pack(pady=(10, 0)) + # Theme selection + self.theme_label = ctk.CTkLabel(self, + text="Select Theme (RESTARTS APP):") - self.volume_label = ctk.CTkLabel(self, text="Adjust Beep Volume:") - self.volume_label.pack(pady=(20, 0)) - self.volume_slider = ctk.CTkSlider(self, from_=0, to=100, number_of_steps=100, command=self.change_volume) - self.volume_slider.pack(pady=(10, 0)) - + self.theme_options = [os.path.splitext(theme)[0] for theme in os.listdir(THEMES_DIR) if theme.endswith('.json')] + selected = ctk.StringVar(value=config.get('theme', 'Default')) + + self.theme_menu =ctk.CTkOptionMenu(self, + variable=selected, + values=self.theme_options, + anchor="n", + command=self.change_theme) + + # Volume controls + self.volume_label = ctk.CTkLabel(self, + text="Adjust Beep Volume:") + self.volume_slider = ctk.CTkSlider(self, + from_=0, + to=100, + number_of_steps=100, + command=self.change_volume) self.volume_slider.set(config.get('volume', 10)) self.change_volume(config.get('volume', 10)) - self.beep_button = ctk.CTkButton(self, text="Play", width=70, command=beep.play) + self.beep_button = ctk.CTkButton(self, + text="Play", + width=70, + command=beep.play) + + self.theme_label.pack(pady=(20, 0)) + self.theme_menu.pack(pady=(10, 0)) + self.volume_label.pack(pady=(20, 0)) + self.volume_slider.pack(pady=(10, 0)) self.beep_button.pack(pady=(15, 0)) def change_abcycling(self): diff --git a/src/frames/stats_frame.py b/src/frames/stats_frame.py index 4f57578..4649c1c 100644 --- a/src/frames/stats_frame.py +++ b/src/frames/stats_frame.py @@ -1,27 +1,24 @@ import customtkinter as ctk from datetime import datetime from CTkMessagebox import CTkMessagebox -from src.reusable.stats_reusable import StatisticFrame, ButtonFrame from src.utils import load_data +from src.reusable.stats_reusable import StatisticFrame, ButtonFrame from src.logic.graphs import graph_pomodoro_sessions, graph_hours_studied class StatsFrame(ctk.CTkScrollableFrame): def __init__(self, master): super().__init__(master) - self.time_today = StatisticFrame(self, "Time Studied Today:") + self.time_today = StatisticFrame(self, "Time Studied Today:") self.pomodoros_today = StatisticFrame(self, "Pomodoros Today:") - self.total_hours = StatisticFrame(self, "Total Time Studied:") + self.total_hours = StatisticFrame(self, "Total Time Studied:") self.total_pomodoros = StatisticFrame(self, "Total Pomodoros:") - self.graph_btn_1 = ButtonFrame(self, "Pomodoro Sessions Graph", "Show", self.show_sessions_graph) - self.graph_btn_2 = ButtonFrame(self, "Hours Studied Graph", "Show", self.show_hours_graph) + self.graph_btn_1 = ButtonFrame(self, "Pomodoro Sessions Graph", "Show", self.show_sessions_graph) + self.graph_btn_2 = ButtonFrame(self, "Hours Studied Graph", "Show", self.show_hours_graph) self.load_stats() def load_stats(self): data = load_data() - if not data: - return - current_date = datetime.now().strftime("%Y-%m-%d") self.update_time_today(data, current_date) self.update_pomodoros_today(data, current_date) diff --git a/src/logic/richpresence.py b/src/logic/richpresence.py index 1a1e688..32fda7f 100644 --- a/src/logic/richpresence.py +++ b/src/logic/richpresence.py @@ -57,19 +57,33 @@ def format_time(self, seconds_studied): @_handle_exceptions def idling_state(self, seconds_studied=0): self.update(state=f"Total time studied: {self.format_time(self.total_seconds_studied + seconds_studied)}", - details="Idling", start=self.launch_time, large_image="graytomato", large_text="github.com/jake158/pomodoro-discord") + details="Idling", + start=self.launch_time, + large_image="graytomato", + large_text="github.com/jake158/pomodoro-discord") @_handle_exceptions def running_state(self, session, start_time, end_time): - self.update(state=f"Session {session}", details="Studying", start=start_time, - end=end_time, large_image="tomato", large_text="github.com/jake158/pomodoro-discord") + self.update(state=f"Session {session}", + details="Studying", + start=start_time, + end=end_time, + large_image="tomato", + large_text="github.com/jake158/pomodoro-discord") @_handle_exceptions def paused_state(self, start_time): - self.update(state="Paused", details=None, start=start_time, large_image="graytomato", + self.update(state="Paused", + details=None, + start=start_time, + large_image="graytomato", large_text="github.com/jake158/pomodoro-discord") @_handle_exceptions def break_state(self, seconds_studied, start_time, end_time): - self.update(state=f"Time studied: {self.format_time(seconds_studied)}", details="On break", start=start_time, - end=end_time, large_image="greentomato", large_text="github.com/jake158/pomodoro-discord") + self.update(state=f"Time studied: {self.format_time(seconds_studied)}", + details="On break", + start=start_time, + end=end_time, + large_image="greentomato", + large_text="github.com/jake158/pomodoro-discord") diff --git a/src/reusable/settings_reusable.py b/src/reusable/settings_reusable.py index c1f7413..0025983 100644 --- a/src/reusable/settings_reusable.py +++ b/src/reusable/settings_reusable.py @@ -4,19 +4,25 @@ class EntryFrame(ctk.CTkFrame): def __init__(self, master, text, config, config_attr, defvalue, command): super().__init__(master) - self.pack(pady=(5, 0)) - - self.label = ctk.CTkLabel(self, text=text) - self.label.pack(pady=(10, 10), padx=(10, 10)) + self.label = ctk.CTkLabel(self, + text=text) self.controls_frame = ctk.CTkFrame(self) - self.controls_frame.pack(fill=ctk.X, expand=True, padx=10) - self.entry_var = ctk.IntVar(value=config.get(config_attr, defvalue)) - self.entry = ctk.CTkEntry(self.controls_frame, width=35, textvariable=self.entry_var) - self.entry.pack(side=ctk.LEFT, fill=ctk.X, expand=True, padx=(0, 10)) + self.entry_var = ctk.IntVar(value=config.get(config_attr, defvalue)) + self.entry = ctk.CTkEntry(self.controls_frame, + width=35, + textvariable=self.entry_var) - self.set_button = ctk.CTkButton(self.controls_frame, width=120, text="Set", command=command) + self.set_button =ctk.CTkButton(self.controls_frame, + width=120, + text="Set", + command=command) + + self.pack(pady=(5, 0)) + self.label.pack(pady=(10, 10), padx=(10, 10)) + self.controls_frame.pack(fill=ctk.X, expand=True, padx=10) + self.entry.pack(side=ctk.LEFT, fill=ctk.X, expand=True, padx=(0, 10)) self.set_button.pack(side=ctk.RIGHT) def get(self): diff --git a/src/reusable/stats_reusable.py b/src/reusable/stats_reusable.py index 3e9b99a..ba5cedc 100644 --- a/src/reusable/stats_reusable.py +++ b/src/reusable/stats_reusable.py @@ -4,13 +4,17 @@ class StatisticFrame(ctk.CTkFrame): def __init__(self, master, title, initial_value="0", title_font=18, val_font=24, **kwargs): super().__init__(master, **kwargs) - self.pack(pady=(10, 15), fill="x") + self.title_label = ctk.CTkLabel(self, + text=title, + font=("Helvetica", title_font), anchor="n") - self.title_label = ctk.CTkLabel(self, text=title, font=("Helvetica", title_font), anchor="n") - self.title_label.pack(fill="x") + self.value_var =ctk.StringVar(value=initial_value) + self.value_label = ctk.CTkLabel(self, + textvariable=self.value_var, + font=("Helvetica", val_font), anchor="center") - self.value_var = ctk.StringVar(value=initial_value) - self.value_label = ctk.CTkLabel(self, textvariable=self.value_var, font=("Helvetica", val_font), anchor="center") + self.pack(pady=(10, 15), fill="x") + self.title_label.pack(fill="x") self.value_label.pack(pady=(5, 0), fill="x") def set_value(self, value): @@ -20,8 +24,15 @@ def set_value(self, value): class ButtonFrame(ctk.CTkFrame): def __init__(self, master, title, btntext, callback, **kwargs): super().__init__(master, **kwargs) + self.label = ctk.CTkLabel(self, + text=title, + font=("Helvetica", 18)) + self.button =ctk.CTkButton(self, + text=btntext, + width=90, + font=("Roboto", 16), + command=callback) + self.pack() - self.label = ctk.CTkLabel(self, text=title, font=("Helvetica", 18)) self.label.pack(pady=(20, 8)) - self.button = ctk.CTkButton(self, text=btntext, width=90, font=("Roboto", 16), command=callback) self.button.pack() diff --git a/src/utils.py b/src/utils.py index a7f2df0..724b18e 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,13 +1,12 @@ -import json import os import sys +import json from pygame import mixer mixer.init() beep = mixer.Sound(os.path.join('src', 'assets', 'sounds', 'beep.mp3')) - DEF_POMODORO_MINS = 25 DEF_SB_MINS = 5 DEF_LB_MINS = 15 @@ -28,6 +27,9 @@ def load_file(filename, on_no_file=None): def load_data(): + """ + Load the timer data from a JSON file, returning a default dictionary if the file is not found. + """ return load_file(DATA_FILE, {'total_seconds_studied': 0, 'total_pomodoro_sessions': 0, 'seconds_by_date': {}, @@ -35,16 +37,25 @@ def load_data(): def save_data(data): + """ + Save the provided data to a JSON file. + """ with open(DATA_FILE, 'w') as data_file: json.dump(data, data_file, indent=4) def load_config(): + """ + Load the timer config from a JSON file, returning a default config if the file is not found. + """ return load_file(CONFIG_FILE, {'theme': 'Default', 'sound': 'beep.mp3'}) def save_config(config): + """ + Save the provided config to a JSON file. + """ with open(CONFIG_FILE, 'w') as config_file: json.dump(config, config_file, indent=4)