diff --git a/flomo/cli.py b/flomo/cli.py index a7b5bb6..abdbada 100644 --- a/flomo/cli.py +++ b/flomo/cli.py @@ -1,9 +1,10 @@ import datetime -import sqlite3 import click import click_aliases +import flomo.config as config +import flomo.errors as errors import flomo.tracker as tracker import flomo.ui as ui @@ -16,6 +17,19 @@ def flomo(): pass +@flomo.command(aliases=["i"]) +def init(): + """ + Initialize the required files for Flomo. + """ + db = tracker.Tracker(initializing=True) + db.create_table() + db.conn.close() + + conf = config.Config(initializing=True) + conf.create_config() + + @flomo.command(aliases=["s"]) @click.option("-t", "--tag", default="Default", help="Session tag name.") @click.option("-n", "--name", default="Work", help="Session Name") @@ -23,11 +37,14 @@ def start(tag: str, name: str): """ Start a Flowmodoro session. """ - db = tracker.Tracker() - db.create_table() - session_id = db.create_session(tag, name, datetime.datetime.now()) - db.conn.close() - ui.main(tag.lower(), name, session_id) + try: + db = tracker.Tracker() + db.create_table() + session_id = db.create_session(tag, name, datetime.datetime.now()) + db.conn.close() + ui.main(tag.lower(), name, session_id) + except (errors.DBFileNotFoundError, errors.NoConfigError) as e: + print(e) @flomo.command(aliases=["t"]) @@ -37,8 +54,29 @@ def tracking(): """ try: tracker.show_sessions() - except sqlite3.OperationalError: - print("No sessions were found.") + except ( + errors.DBFileNotFoundError, + errors.NoSessionsError, + errors.NoSessionError, + ) as e: + print(e) + + +@flomo.command(aliases=["d"]) +@click.argument("session_id") +def delete(session_id: str): + """ + Delete a session. + """ + try: + db = tracker.Tracker() + db.delete_session(int(session_id)) + db.conn.close() + except ( + errors.DBFileNotFoundError, + errors.NoSessionError, + ) as e: + print(e) if __name__ == "__main__": diff --git a/flomo/config.py b/flomo/config.py new file mode 100644 index 0000000..ed7c7ab --- /dev/null +++ b/flomo/config.py @@ -0,0 +1,18 @@ +import os + +import flomo.errors as errors +import flomo.helpers as helpers + + +class Config: + def __init__(self, initializing: bool = False): + self.path = helpers.get_path("config.json", in_data=True) + + if not initializing and not self._config_file_exists(): + raise errors.NoConfigError() + + def _config_file_exists(self): + return os.path.exists(self.path) # TODO: Check if file contents are proper. + + def create_config(self): + pass diff --git a/flomo/errors.py b/flomo/errors.py new file mode 100644 index 0000000..d2b4097 --- /dev/null +++ b/flomo/errors.py @@ -0,0 +1,18 @@ +class DBFileNotFoundError(Exception): + def __init__(self): + super().__init__("Database file does not exist. Please run `flomo init`.") + + +class NoConfigError(Exception): + def __init__(self): + super().__init__("No config file found. Please run `flomo init`.") + + +class NoSessionsError(Exception): + def __init__(self): + super().__init__("No sessions were found.") + + +class NoSessionError(Exception): + def __init__(self, session_id): + super().__init__(f"No session with ID {session_id} was found.") diff --git a/flomo/helpers.py b/flomo/helpers.py index 355704a..e1ae9f9 100644 --- a/flomo/helpers.py +++ b/flomo/helpers.py @@ -4,8 +4,6 @@ from playsound import playsound -import flomo.tracker as tracker - def get_path(file_name: str, in_data: bool = False): dir_path = os.path.dirname(os.path.realpath(__file__)) @@ -33,7 +31,7 @@ def play_sound(): def message_log(message: str): - path = get_path("message.log", True) + path = get_path("message.log", in_data=True) with open(path, "a") as f: f.write(message + "\n") @@ -44,9 +42,3 @@ def format_time(seconds: int) -> str: mins, secs = divmod(remainder, 60) return f"{hours:02}:{mins:02}:{secs:02}" - - -def update_session(session_id: float): - db = tracker.Tracker() - db.update_session(session_id, datetime.datetime.now()) - db.conn.close() diff --git a/flomo/tracker.py b/flomo/tracker.py index 43a7633..743614c 100644 --- a/flomo/tracker.py +++ b/flomo/tracker.py @@ -4,26 +4,32 @@ import pandas import tabulate +import flomo.errors as errors import flomo.helpers as helpers class Tracker: - def __init__(self): - path = helpers.get_path("sessions.db", True) + def __init__(self, initializing: bool = False): + path = helpers.get_path("sessions.db", in_data=True) self.conn = sqlite3.connect(path) self.cursor = self.conn.cursor() + if not initializing and not self._db_file_exists(): + raise errors.DBFileNotFoundError() + + def _db_file_exists(self): + self.cursor.execute("SELECT name FROM sqlite_master WHERE type='table';") + return bool(self.cursor.fetchall()) + def create_table(self): self.cursor.execute( "CREATE TABLE IF NOT EXISTS sessions (id FLOAT PRIMARY KEY, date_time TEXT, tag TEXT, name TEXT, total_time TEXT)" ) self.conn.commit() - def create_session( - self, tag: str, name: str, start_time: datetime.datetime - ) -> float: - session_id = start_time.timestamp() % 1000000 + def create_session(self, tag: str, name: str, start_time: datetime.datetime) -> int: + session_id = int(start_time.timestamp() % 1000000) self.cursor.execute( "INSERT INTO sessions (id, date_time, tag, name) VALUES (?, ?, ?, ?)", (session_id, start_time.strftime("%Y-%m-%d %H:%M:%S"), tag, name), @@ -31,7 +37,7 @@ def create_session( self.conn.commit() return session_id - def update_session(self, session_id: float, end_time: datetime.datetime): + def update_session(self, session_id: int, end_time: datetime.datetime): date_time = self.get_session(session_id)[1] total_time = end_time - datetime.datetime.strptime( date_time, "%Y-%m-%d %H:%M:%S" @@ -49,10 +55,22 @@ def get_sessions(self): self.cursor.execute("SELECT * FROM sessions") return self.cursor.fetchall() - def get_session(self, session_id: float): + def get_session(self, session_id: int): self.cursor.execute("SELECT * FROM sessions WHERE id = ?", (session_id,)) return self.cursor.fetchone() + def delete_session(self, session_id: int): + if not self.get_session(session_id): + raise errors.NoSessionError(session_id) + self.cursor.execute("DELETE FROM sessions WHERE id = ?", (session_id,)) + self.conn.commit() + + +def update_session(session_id: int): + db = Tracker() + db.update_session(session_id, datetime.datetime.now()) + db.conn.close() + def show_sessions(): db = Tracker() diff --git a/flomo/ui.py b/flomo/ui.py index 5aa320b..f274809 100644 --- a/flomo/ui.py +++ b/flomo/ui.py @@ -10,6 +10,7 @@ from rich.text import Text import flomo.helpers as helpers +import flomo.tracker as tracker class UI: @@ -63,7 +64,7 @@ def get_input(self): return self.terminal.inkey().lower() -def main(tag: str, name: str, session_id: float): +def main(tag: str, name: str, session_id: int): # TODO: Do something with the Terminal close issue try: while True: @@ -123,5 +124,5 @@ def main(tag: str, name: str, session_id: float): if isinstance(e, Exception): helpers.message_log(f"{datetime.datetime.now()} - Error: {e}") finally: - helpers.update_session(session_id) + tracker.update_session(session_id) sys.exit()