Resctructuralisation

This commit is contained in:
2025-09-24 06:58:13 +02:00
parent a4477ce6a2
commit 9ea2da0d7f
11 changed files with 71 additions and 151 deletions

View File

@@ -1,125 +0,0 @@
import sqlite3
from pathlib import Path
from typing import Any, List, Tuple
class SQLite3FileHandler:
def __init__(self, db_path: Path):
self.db_path = Path(db_path)
need_init = not self.db_path.exists() # zjistíme, jestli soubor existuje před connect
self.conn = sqlite3.connect(str(self.db_path))
self.cursor = self.conn.cursor()
if need_init:
self.create_tables()
def create_tables(self) -> None:
"""
Vytvoří tabulky (bez chyby pokud už existují).
"""
script = """
CREATE TABLE IF NOT EXISTS TAGS (
ID INTEGER PRIMARY KEY,
TAG_NAME TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS FILES (
ID INTEGER PRIMARY KEY,
PATH TEXT NOT NULL,
FILE_NAME TEXT NOT NULL,
HASH TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS RELATIONS (
ID INTEGER PRIMARY KEY,
IDS INTEGER NOT NULL,
TYPE TEXT NOT NULL,
IDT INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS TAG_CATEGORY (
ID INTEGER PRIMARY KEY,
TAG_CAT_NAME TEXT NOT NULL UNIQUE
);
"""
# executescript umí více příkazů najednou
self.conn.executescript(script)
self.conn.commit()
def insert_tag(self, tag_name: str) -> None:
query = "INSERT INTO TAGS (TAG_NAME) VALUES (?)"
self.cursor.execute(query, (tag_name,))
self.conn.commit()
def delete_tag(self, tag_name: str) -> None:
query = "DELETE FROM TAGS WHERE TAG_NAME = ?"
self.cursor.execute(query, (tag_name,))
self.conn.commit()
def insert_category(self, tag_cat_name: str) -> None:
query = "INSERT INTO TAG_CATEGORY (TAG_CAT_NAME) VALUES (?)"
self.cursor.execute(query, (tag_cat_name,))
self.conn.commit()
def delete_category(self, tag_cat_name: str) -> None:
"""
Smaže kategorii podle názvu.
"""
query = "DELETE FROM TAG_CATEGORY WHERE TAG_CAT_NAME = ?"
self.cursor.execute(query, (tag_cat_name,))
self.conn.commit()
def insert_relation_tag_cat(self, tag_id: int, tag_cat_id: int) -> None:
query = "INSERT INTO RELATIONS (IDS, TYPE, IDT) VALUES (?, ?, ?)"
self.cursor.execute(query, (tag_id, "Category", tag_cat_id))
self.conn.commit()
def delete_relation_tag_cat(self, tag_id: int, tag_cat_id: int) -> None:
"""
Smaže vztah mezi tagem a kategorií podle IDS a IDT.
TYPE je pevně "Category".
"""
query = "DELETE FROM RELATIONS WHERE IDS = ? AND TYPE = ? AND IDT = ?"
self.cursor.execute(query, (tag_id, "Category", tag_cat_id))
self.conn.commit()
def insert_file(self, path: str, file_name: str, hash_value: str) -> None:
"""
Vloží nový soubor do tabulky FILES.
"""
query = "INSERT INTO FILES (PATH, FILE_NAME, HASH) VALUES (?, ?, ?)"
self.cursor.execute(query, (path, file_name, hash_value))
self.conn.commit()
def delete_file(self, file_id: int) -> None:
"""
Smaže soubor podle jeho ID.
"""
query = "DELETE FROM FILES WHERE ID = ?"
self.cursor.execute(query, (file_id,))
self.conn.commit()
def insert_relation_tag_file(self, tag_id: int, file_id: int) -> None:
query = "INSERT INTO RELATIONS (IDS, TYPE, IDT) VALUES (?, ?, ?)"
self.cursor.execute(query, (tag_id, "File", file_id))
self.conn.commit()
def delete_relation_tag_file(self, tag_id: int, file_id: int) -> None:
"""
Smaže vztah mezi tagem a souborem podle IDS a IDT.
TYPE je pevně "File".
"""
query = "DELETE FROM RELATIONS WHERE IDS = ? AND TYPE = ? AND IDT = ?"
self.cursor.execute(query, (tag_id, "File", file_id))
self.conn.commit()
def fetch_all(self, table_name: str) -> List[Tuple[Any]]:
"""Vrátí všechny řádky z tabulky."""
query = f"SELECT * FROM {table_name}"
self.cursor.execute(query)
return self.cursor.fetchall()
def close(self) -> None:
"""Zavře připojení k databázi."""
self.conn.close()

View File

@@ -1,12 +0,0 @@
from pathlib import Path
class State(self):
class TagManager(self, SaveHandler, ):
self.SaveHandler = SaveHandler
class FileManager():

42
src/core/file.py Normal file
View File

@@ -0,0 +1,42 @@
from pathlib import Path
import json
class File():
def __init__(self, file_path: Path, tagmanager = None) -> None:
self.file_path = file_path
self.metadata_filename = self.get_metadata_filename(self.file_path)
self.new = True
self.ignored = False
self.tags = []
self.tagmanager = tagmanager
self.get_metadata()
def get_metadata_filename(self, file_path: Path) -> Path:
file_name = file_path.name
metadata_filename =Path(f".{file_name}.!tag")
return metadata_filename
def get_metadata(self) -> None:
if not self.metadata_filename.exists():
self.new = True
self.ignored = False
self.tags = []
else:
self.load_metadata()
def save_metadata(self) -> None:
"""Save object state into metadata file as JSON."""
data = {
"new": self.new,
"ignored": self.ignored,
"tags": self.tags,
}
with open(self.metadata_filename, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
def load_metadata(self) -> None:
with open(self.metadata_filename, "r", encoding="utf-8") as f:
data = json.load(f)
self.new = data.get("new", True)
self.ignored = data.get("ignored", False)
self.tags = data.get("tags", [])

View File

@@ -1,13 +1,21 @@
# Module header
import sys
if __name__ == "__main__":
sys.exit("This module is not intended to be executed as the main program.")
# Imports
from pathlib import Path
from .file import File
from .tag_manager import TagManager
# Functions
class FileManager():
def __init__(self, tagmanager: TagManager) -> None:
self.filelist = []
self.folders = []
self.tagmanager = tagmanager
def append(self, folder: Path) -> None:
self.folders.append(folder)
for each in list_files(folder):
file = File(each, self.tagmanager)
self.filelist.append(file)
def list_files(folder_path: str | Path) -> list[Path]:
"""
Vrátí seznam Path objektů všech souborů uvnitř složky (rekurzivně).

3
src/core/tag_manager.py Normal file
View File

@@ -0,0 +1,3 @@
class TagManager():
def __init__(self):
pass

0
src/ui/__init__.py Normal file
View File

View File

@@ -6,21 +6,23 @@ import tkinter as tk
from tkinter import ttk, simpledialog, messagebox
from src.core.image_handler import load_icon
from src.core.file_manager import FileManager
class App:
def __init__(self):
def __init__(self, filehandler: FileManager):
self.states = {} # Tree states (checkbox on/off)
self.files = {} # Path -> set(tags), napojíš na SQLite3FileHandler
self.selected_tree_item_for_context = None
self.selected_list_index_for_context = None
self.filehandler = filehandler
# ==================================================
# MAIN GUI
# ==================================================
def main(self) -> None:
root = tk.Tk()
root.title("Tag manager")
root.title("Tagger")
root.geometry("900x600")
self.root = root