Skip to content

Commit

Permalink
The great restructuring 2
Browse files Browse the repository at this point in the history
  • Loading branch information
jake158 committed Apr 4, 2024
1 parent 90ca437 commit 46940ba
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 148 deletions.
37 changes: 1 addition & 36 deletions pomodorodiscord/run.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,7 @@
import customtkinter as ctk
from src.pomodoro_frame import PomodoroFrame
from src.settings_frame import SettingsFrame
from src.stats_frame import StatsFrame
from src.app import PomodoroApp
from src.utils import load_config


class TabView(ctk.CTkTabview):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)

self.add("Main")
self.add("Settings")
self.add("Stats")

self.main_frame = PomodoroFrame(self.tab("Main"))
self.main_frame.pack(expand=True, fill='both')

self.settings_frame = SettingsFrame(self.tab("Settings"))
self.settings_frame.pack(expand=True, fill='both')

self.stats_frame = StatsFrame(self.tab("Stats"))
self.stats_frame.pack(expand=True, fill='both')


class PomodoroApp(ctk.CTk):
WIDTH = 350
HEIGHT = 400

def __init__(self):
super().__init__()

self.title("Pomodoro Tracker")
self.geometry(f"{PomodoroApp.WIDTH}x{PomodoroApp.HEIGHT}")

self.tabview = TabView(master=self)
self.tabview.pack(pady=(15, 30), expand=True, fill='y')


if __name__ == "__main__":
config = load_config()
ctk.set_default_color_theme(f"themes/{config['theme']}.json")
Expand Down
Empty file removed pomodorodiscord/src/__init__.py
Empty file.
34 changes: 34 additions & 0 deletions pomodorodiscord/src/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import customtkinter as ctk
from src.frames.pomodoro_frame import PomodoroFrame
from src.frames.settings_frame import SettingsFrame
from src.frames.stats_frame import StatsFrame


class TabView(ctk.CTkTabview):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
self.add("Main")
self.add("Settings")
self.add("Stats")

self.main_frame = PomodoroFrame(self.tab("Main"))
self.main_frame.pack(expand=True, fill='both')

self.settings_frame = SettingsFrame(self.tab("Settings"))
self.settings_frame.pack(expand=True, fill='both')

self.stats_frame = StatsFrame(self.tab("Stats"))
self.stats_frame.pack(expand=True, fill='both')


class PomodoroApp(ctk.CTk):
WIDTH = 350
HEIGHT = 400

def __init__(self):
super().__init__()
self.title("Pomodoro Tracker")
self.geometry(f"{PomodoroApp.WIDTH}x{PomodoroApp.HEIGHT}")

self.tabview = TabView(master=self)
self.tabview.pack(pady=(15, 30), expand=True, fill='y')
22 changes: 22 additions & 0 deletions pomodorodiscord/src/components/entry_frame.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import customtkinter as ctk


class EntryFrame(ctk.CTkFrame):
def __init__(self, master, text, config, config_attr, defvalue, command):
super().__init__(master)

self.label = ctk.CTkLabel(self, text=text)
self.label.pack(pady=(10, 10), padx=(10, 10))

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.set_button = ctk.CTkButton(self.controls_frame, width=120, text="Set", command=command)
self.set_button.pack(side=ctk.RIGHT)

def get(self):
return self.entry_var.get()
17 changes: 17 additions & 0 deletions pomodorodiscord/src/components/statistic_display.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import customtkinter as ctk


class StatisticDisplay(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.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_label.pack(pady=(5, 0), fill="x")

def set_value(self, value):
self.value_var.set(value)
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
import threading
import customtkinter as ctk
from datetime import datetime, timedelta
from src.utils import load_config, load_data, save_data, DEF_POMODORO_MINS, DEF_SB_MINS, DEF_LB_MINS, DEF_SB_BEFORE_L, beep
from src.richpresence import RichPresence
from src.utils import load_config, load_data, save_data, beep, DEF_POMODORO_MINS, DEF_SB_MINS, DEF_LB_MINS, DEF_SB_BEFORE_L
from src.logic.richpresence import RichPresence

BREAK_BTN_COLOR = "#9a9a9a"
BREAK_HOVER = "#adaaaa"
RESET_BTN_COLOR = "#cca508"
RESET_HOVER = "#e3b707"

# TODO: clean everything

class PomodoroFrame(ctk.CTkFrame):
def __init__(self, master):
Expand All @@ -22,7 +21,6 @@ def __init__(self, master):
threading.Thread(target=self.initialize_rpc, daemon=True).start()

def initialize_ui(self, config):
"""Set up the UI components for the Pomodoro timer"""
# Helper text that appears when a break is running
self.break_text = ctk.StringVar(value="")
self.break_label = ctk.CTkLabel(self, textvariable=self.break_text, font=("Roboto", 15))
Expand All @@ -49,8 +47,6 @@ def initialize_ui(self, config):
self.reset_button.pack()

def initialize_state(self, config):
"""Initialize the state variables"""
# Main
self.running = False
self.break_running = False
self.next_timer_update = None
Expand All @@ -72,7 +68,6 @@ def initialize_state(self, config):
self.seconds_studied = 0

def initialize_rpc(self):
"""Start the rich presence in a separate thread"""
self.rpc = RichPresence()
self.rpc_thread = threading.Thread(target=self.update_rpc, daemon=True)
self.rpc_thread.start()
Expand All @@ -84,7 +79,7 @@ def update_rpc(self):
elif self.running:
self.rpc.running_state(self.session_counter + 1, self.start_time_timestamp, self.end_time_timestamp)
else:
self.rpc.default_state(self.end_time_timestamp)
self.rpc.default_state()

# Discord-imposed rate limit
time.sleep(15)
Expand Down Expand Up @@ -138,7 +133,6 @@ def reset(self, to:str="pomodoro_time", default:int=DEF_POMODORO_MINS):
self.next_timer_update = None

config = load_config()
# TODO: Make cleaner?
self.pomodoro_time = int(config.get(to, default) * 60)
self.auto_break_cycling = config.get("auto_break_cycling", False)
self.short_break_counter = 0 if not self.auto_break_cycling else self.short_break_counter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,79 +1,47 @@
import os
import customtkinter as ctk
from src.utils import load_config, save_config, reload_app, DEF_POMODORO_MINS, DEF_SB_MINS, DEF_LB_MINS, DEF_SB_BEFORE_L, beep


class EntryFrame(ctk.CTkFrame):
def __init__(self, master, text, config, config_attr, defvalue, command):
super().__init__(master)

self.label = ctk.CTkLabel(self, text=text)
self.label.pack(pady=(10, 10), padx=(10, 10))

# Inner frame to hold the entry and button
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.set_button = ctk.CTkButton(self.controls_frame, width=120, text="Set", command=command)
self.set_button.pack(side=ctk.RIGHT)

def get(self):
return self.entry_var.get()
from src.components.entry_frame import EntryFrame
from src.utils import load_config, save_config, reload_app, beep, DEF_POMODORO_MINS, DEF_SB_MINS, DEF_LB_MINS, DEF_SB_BEFORE_L


class SettingsFrame(ctk.CTkScrollableFrame):
def __init__(self, master):
super().__init__(master)
self.themes_dir = 'themes'
config = load_config()

# Automatic Break Cycling

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, 0))

# Short Breaks Before Long Break

self.sb_before_l_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.sb_before_l_entry.pack(pady=(10, 0))

# Pomodoro Duration

self.pomodoro_entry = EntryFrame(self, "Pomodoro Duration (mins):", config, "pomodoro_time", DEF_POMODORO_MINS, self.change_pomodoro_time)
self.pomodoro_entry.pack(pady=(5, 0))

# Short Break Duration

self.sb_entry = EntryFrame(self, "Short Break Duration (mins):", config, "short_break_time", DEF_SB_MINS, self.change_sb_time)
self.sb_entry.pack(pady=(5, 0))

# Long Break Duration

self.lb_entry = EntryFrame(self, "Long Break Duration (mins):", config, "long_break_time", DEF_LB_MINS, self.change_lb_time)
self.lb_entry.pack(pady=(5, 0))

# Selecting theme
self.theme_label = ctk.CTkLabel(self, text="Select Theme:")

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(self.themes_dir) if theme.endswith('.json')]

selected = ctk.StringVar(value=config.get('theme', 'Default'))
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))

# Volume Slider
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))

# Set the slider to the current volume
self.volume_slider.set(config.get('volume', 10)) # Default volume to 10% if not set

self.volume_slider.set(config.get('volume', 10))
self.change_volume(config.get('volume', 10))

# Play Beep button

self.beep_button = ctk.CTkButton(self, text="Play", width=70, command=beep.play)
self.beep_button.pack(pady=(15, 0))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,91 +1,62 @@
import customtkinter as ctk
from datetime import datetime
from src.components.statistic_display import StatisticDisplay
from src.utils import load_data
from src.graphs import graph_pomodoro_sessions, graph_hours_studied


class StatisticDisplay(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")

# Title Label
self.title_label = ctk.CTkLabel(self, text=title, font=("Helvetica", title_font), anchor="n")
self.title_label.pack(fill="x")

# Value Label
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_label.pack(pady=(5, 0), fill="x")

def set_value(self, value):
self.value_var.set(value)
from src.logic.graphs import graph_pomodoro_sessions, graph_hours_studied


class StatsFrame(ctk.CTkScrollableFrame):
def __init__(self, master):
super().__init__(master)

# Time Studied Today

self.time_today = StatisticDisplay(self, "Time Studied Today:")

# Pomodoros Today
self.pomodoros_today = StatisticDisplay(self, "Pomodoros Today:")

# Total Hours Studied
self.total_hours = StatisticDisplay(self, "Total Time Studied:")

# Total Pomodoros
self.total_pomodoros = StatisticDisplay(self, "Total Pomodoros:")

# Update Button

self.update_stats = ctk.CTkButton(self, text="Update", width=90, font=("Roboto", 16), command=self.load_stats)
self.update_stats.pack(pady=(10, 0))

# Graphs

self.graph_label_1 = ctk.CTkLabel(self, text="Pomodoro Sessions Graph", font=("Helvetica", 18))
self.graph_label_1.pack(pady=(32, 8))
self.graph_button_1 = ctk.CTkButton(self, text="Show", width=90, font=("Roboto", 16), command=self.show_sessions_graph)
self.graph_button_1.pack()

self.graph_label_2 = ctk.CTkLabel(self, text="Hours Studied Graph", font=("Helvetica", 18))
self.graph_label_2.pack(pady=(20, 8))
self.graph_button_2 = ctk.CTkButton(self, text="Show", width=90, font=("Roboto", 16), command=self.show_hours_graph)
self.graph_button_2.pack()

self.load_stats()

def load_stats(self):
data = load_data()
if not data:
return

current_date = datetime.now().strftime("%Y-%m-%d")
total_today_seconds = data.get('seconds_by_date', {}).get(current_date, 0)

total_today_hours = total_today_seconds / 3600

if total_today_hours < 1:
self.time_today.set_value(f"{total_today_seconds // 60} minute{'s' if total_today_seconds // 60 != 1 else ''}")
else:
self.time_today.set_value(f"{total_today_hours:.1f} hours")

total_today_pomodoros = data.get('sessions_by_date', {}).get(current_date, 0)
self.pomodoros_today.set_value(f"{total_today_pomodoros} session{'s' if total_today_pomodoros != 1 else ''}")

total_seconds = data.get('total_seconds_studed', 0)
total_seconds = data.get('total_seconds_studied', 0)
total_hours = data.get('total_seconds_studied', 0) / 3600

if total_hours < 1:
self.total_hours.set_value(f"{total_seconds // 60} minute{'s' if total_seconds // 60 != 1 else ''}")
else:
self.total_hours.set_value(f"{total_hours:.1f} hours")

total_pomodoros = data.get('total_pomodoro_sessions', 0)
self.total_pomodoros.set_value(f"{total_pomodoros} session{'s' if total_pomodoros != 1 else ''}")

def show_sessions_graph(self):
graph_pomodoro_sessions(load_data())

def show_hours_graph(self):
graph_hours_studied(load_data())
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import matplotlib.dates as mdates
from datetime import datetime, timedelta

# Making sure you can run `python3 src/graphs.py`
# Making sure you can run `python3 src/logic/graphs.py`
current_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(current_dir)
sys.path.append(parent_dir)
src = os.path.dirname(os.path.dirname(current_dir))
sys.path.append(src)

from src.utils import load_data

Expand Down
Loading

0 comments on commit 46940ba

Please sign in to comment.