mirror of https://github.com/gmbrax/Pilgrim.git
				
				
				
			Compare commits
	
		
			No commits in common. "26ef00fe3e3b9117b5f228e8668fba3983c5336f" and "10135b9cdc9dd182204bc29f7c054aad0d52c3b0" have entirely different histories.
		
	
	
		
			26ef00fe3e
			...
			10135b9cdc
		
	
		| 
						 | 
					@ -20,9 +20,6 @@
 | 
				
			||||||
    dependencies = [
 | 
					    dependencies = [
 | 
				
			||||||
      "sqlalchemy",
 | 
					      "sqlalchemy",
 | 
				
			||||||
        "textual",
 | 
					        "textual",
 | 
				
			||||||
        "tomli",
 | 
					 | 
				
			||||||
        "tomli_w"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    [template.plugins.default]
 | 
					    [template.plugins.default]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,21 +1,19 @@
 | 
				
			||||||
from pilgrim.database import Database
 | 
					from pilgrim.database import Database
 | 
				
			||||||
from pilgrim.service.servicemanager import ServiceManager
 | 
					from pilgrim.service.servicemanager import ServiceManager
 | 
				
			||||||
from pilgrim.ui.ui import UIApp
 | 
					from pilgrim.ui.ui import UIApp
 | 
				
			||||||
from pilgrim.utils import ConfigManager
 | 
					from pilgrim.utils import DirectoryManager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Application:
 | 
					class Application:
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        self.config_manager = ConfigManager()
 | 
					        self.config_dir = DirectoryManager.get_config_directory()
 | 
				
			||||||
        self.config_manager.read_config()  # Chamar antes de criar o Database
 | 
					        self.database = Database()
 | 
				
			||||||
        self.database = Database(self.config_manager)
 | 
					 | 
				
			||||||
        session = self.database.session()
 | 
					        session = self.database.session()
 | 
				
			||||||
        session_manager = ServiceManager()
 | 
					        session_manager = ServiceManager()
 | 
				
			||||||
        session_manager.set_session(session)
 | 
					        session_manager.set_session(session)
 | 
				
			||||||
        self.ui = UIApp(session_manager, self.config_manager)
 | 
					        self.ui = UIApp(session_manager)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def run(self):
 | 
					    def run(self):
 | 
				
			||||||
        print(f"URL do banco: {self.config_manager.database_url}")
 | 
					 | 
				
			||||||
        self.database.create()
 | 
					        self.database.create()
 | 
				
			||||||
        self.ui.run()
 | 
					        self.ui.run()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,24 +5,38 @@ from pathlib import Path
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pilgrim.utils import ConfigManager
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Base = declarative_base()
 | 
					Base = declarative_base()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_database_path() -> Path:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Get the database file path following XDG Base Directory specification.
 | 
				
			||||||
 | 
					    Creates the directory if it doesn't exist.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    # Get home directory
 | 
				
			||||||
 | 
					    home = Path.home()
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    # Create .pilgrim directory if it doesn't exist
 | 
				
			||||||
 | 
					    pilgrim_dir = home / ".pilgrim"
 | 
				
			||||||
 | 
					    pilgrim_dir.mkdir(exist_ok=True)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Database file path
 | 
				
			||||||
 | 
					    db_path = pilgrim_dir / "database.db"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # If database doesn't exist in new location but exists in current directory,
 | 
				
			||||||
 | 
					    # migrate it
 | 
				
			||||||
 | 
					    if not db_path.exists():
 | 
				
			||||||
 | 
					        current_db = Path("database.db")
 | 
				
			||||||
 | 
					        if current_db.exists():
 | 
				
			||||||
 | 
					            shutil.copy2(current_db, db_path)
 | 
				
			||||||
 | 
					            print(f"Database migrated from {current_db} to {db_path}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return db_path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Database:
 | 
					class Database:
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
    def __init__(self, config_manager: ConfigManager):
 | 
					        db_path = get_database_path()
 | 
				
			||||||
        self.db_path = config_manager.database_url
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Garantir que o diretório existe
 | 
					 | 
				
			||||||
        db_dir = os.path.dirname(self.db_path)
 | 
					 | 
				
			||||||
        if not os.path.exists(db_dir):
 | 
					 | 
				
			||||||
            os.makedirs(db_dir, exist_ok=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.engine = create_engine(
 | 
					        self.engine = create_engine(
 | 
				
			||||||
            f"sqlite:///{self.db_path}",
 | 
					            f"sqlite:///{db_path}",
 | 
				
			||||||
            echo=False,
 | 
					            echo=False,
 | 
				
			||||||
            connect_args={"check_same_thread": False},
 | 
					            connect_args={"check_same_thread": False},
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,9 +12,9 @@ class NewDiaryModal(ModalScreen[str]):
 | 
				
			||||||
        Binding("escape", "cancel", "Cancel"),
 | 
					        Binding("escape", "cancel", "Cancel"),
 | 
				
			||||||
        Binding("enter", "create_diary", "Create",priority=True),
 | 
					        Binding("enter", "create_diary", "Create",priority=True),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self,autoopen=True):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        self.auto_open = self.app.config_manager.auto_open_new_diary
 | 
					        self.auto_open = autoopen
 | 
				
			||||||
        self.name_input = Input(id="NewDiaryModal-NameInput",classes="NewDiaryModal-NameInput") # This ID is fine, it's specific to the input
 | 
					        self.name_input = Input(id="NewDiaryModal-NameInput",classes="NewDiaryModal-NameInput") # This ID is fine, it's specific to the input
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def compose(self) -> ComposeResult:
 | 
					    def compose(self) -> ComposeResult:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,6 @@ from pilgrim.service.servicemanager import ServiceManager
 | 
				
			||||||
from pilgrim.ui.screens.about_screen import AboutScreen
 | 
					from pilgrim.ui.screens.about_screen import AboutScreen
 | 
				
			||||||
from pilgrim.ui.screens.diary_list_screen import DiaryListScreen
 | 
					from pilgrim.ui.screens.diary_list_screen import DiaryListScreen
 | 
				
			||||||
from pilgrim.ui.screens.edit_entry_screen import EditEntryScreen
 | 
					from pilgrim.ui.screens.edit_entry_screen import EditEntryScreen
 | 
				
			||||||
from pilgrim.utils import ConfigManager
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
CSS_FILE_PATH = Path(__file__).parent / "styles" / "pilgrim.css"
 | 
					CSS_FILE_PATH = Path(__file__).parent / "styles" / "pilgrim.css"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,10 +16,9 @@ CSS_FILE_PATH = Path(__file__).parent / "styles" / "pilgrim.css"
 | 
				
			||||||
class UIApp(App):
 | 
					class UIApp(App):
 | 
				
			||||||
    CSS_PATH = CSS_FILE_PATH
 | 
					    CSS_PATH = CSS_FILE_PATH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self,service_manager: ServiceManager, config_manager: ConfigManager, **kwargs):
 | 
					    def __init__(self,service_manager: ServiceManager, **kwargs):
 | 
				
			||||||
        super().__init__(**kwargs)
 | 
					        super().__init__(**kwargs)
 | 
				
			||||||
        self.service_manager = service_manager
 | 
					        self.service_manager = service_manager
 | 
				
			||||||
        self.config_manager = config_manager
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def on_mount(self) -> None:
 | 
					    def on_mount(self) -> None:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,3 @@
 | 
				
			||||||
from .directory_manager import DirectoryManager
 | 
					from .directory_manager import DirectoryManager
 | 
				
			||||||
from .config_manager import ConfigManager
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = ['DirectoryManager', 'ConfigManager']
 | 
					__all__ = ['DirectoryManager']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,107 +0,0 @@
 | 
				
			||||||
import os.path
 | 
					 | 
				
			||||||
from os import PathLike
 | 
					 | 
				
			||||||
from threading import Lock
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import tomli
 | 
					 | 
				
			||||||
import tomli_w
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from pilgrim.utils import DirectoryManager
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SingletonMeta(type):
 | 
					 | 
				
			||||||
    _instances = {}
 | 
					 | 
				
			||||||
    _lock: Lock = Lock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __call__(cls, *args, **kwargs):
 | 
					 | 
				
			||||||
        with cls._lock:
 | 
					 | 
				
			||||||
            if cls not in cls._instances:
 | 
					 | 
				
			||||||
                instance = super().__call__(*args, **kwargs)
 | 
					 | 
				
			||||||
                cls._instances[cls] = instance
 | 
					 | 
				
			||||||
        return cls._instances[cls]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ConfigManager(metaclass=SingletonMeta):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.database_url = None
 | 
					 | 
				
			||||||
        self.database_type = None
 | 
					 | 
				
			||||||
        self.auto_open_diary = None
 | 
					 | 
				
			||||||
        self.auto_open_new_diary = None
 | 
					 | 
				
			||||||
        self.config_dir = DirectoryManager.get_config_directory()
 | 
					 | 
				
			||||||
        self.__data = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def read_config(self):
 | 
					 | 
				
			||||||
        if os.path.exists(f"{DirectoryManager.get_config_directory()}/config.toml"):
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                with open(f"{DirectoryManager.get_config_directory()}/config.toml", "rb") as f:
 | 
					 | 
				
			||||||
                    data = tomli.load(f)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            except tomli.TOMLDecodeError as e:
 | 
					 | 
				
			||||||
                raise ValueError(f"Invalid TOML configuration: {e}")
 | 
					 | 
				
			||||||
            except Exception as e:
 | 
					 | 
				
			||||||
                raise RuntimeError(f"Error reading configuration: {e}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.__data = data
 | 
					 | 
				
			||||||
            self.database_url = self.__data["database"]["url"]
 | 
					 | 
				
			||||||
            self.database_type = self.__data["database"]["type"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if self.__data["settings"]["diary"]["auto_open_diary_on_startup"] == "":
 | 
					 | 
				
			||||||
                self.auto_open_diary = None
 | 
					 | 
				
			||||||
            self.auto_open_new_diary = self.__data["settings"]["diary"]["auto_open_on_creation"]
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            print("Error: config.toml not found.")
 | 
					 | 
				
			||||||
            self.create_config()
 | 
					 | 
				
			||||||
            self.read_config()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def create_config(self, config: dict = None):
 | 
					 | 
				
			||||||
        # Garantir que o diretório de configuração existe
 | 
					 | 
				
			||||||
        config_dir = DirectoryManager.get_config_directory()
 | 
					 | 
				
			||||||
        if not os.path.exists(config_dir):
 | 
					 | 
				
			||||||
            os.makedirs(config_dir, exist_ok=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        default = {
 | 
					 | 
				
			||||||
            "database": {
 | 
					 | 
				
			||||||
                "url": f"{config_dir}/database.db",
 | 
					 | 
				
			||||||
                "type": "sqlite"
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            "settings": {
 | 
					 | 
				
			||||||
                "diary": {
 | 
					 | 
				
			||||||
                    "auto_open_diary_on_startup": "",
 | 
					 | 
				
			||||||
                    "auto_open_on_creation": False
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if config is None:
 | 
					 | 
				
			||||||
            config = default
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            with open(f"{config_dir}/config.toml", "wb") as f:
 | 
					 | 
				
			||||||
                tomli_w.dump(config, f)
 | 
					 | 
				
			||||||
        except Exception as e:
 | 
					 | 
				
			||||||
            raise RuntimeError(f"Error creating configuration: {e}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def save_config(self):
 | 
					 | 
				
			||||||
        if self.__data is None:
 | 
					 | 
				
			||||||
            self.read_config()
 | 
					 | 
				
			||||||
        if self.__data is None:
 | 
					 | 
				
			||||||
            raise RuntimeError("Error reading configuration.")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.__data["database"]["url"] = self.database_url
 | 
					 | 
				
			||||||
        self.__data["database"]["type"] = self.database_type
 | 
					 | 
				
			||||||
        self.__data["settings"]["diary"]["auto_open_diary_on_startup"] = self.auto_open_diary or ""
 | 
					 | 
				
			||||||
        self.__data["settings"]["diary"]["auto_open_on_creation"] = self.auto_open_new_diary
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            self.create_config(self.__data)
 | 
					 | 
				
			||||||
        except Exception as e:
 | 
					 | 
				
			||||||
            raise RuntimeError(f"Error saving configuration: {e}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_config_dir(self, value):
 | 
					 | 
				
			||||||
        self.config_dir = value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_database_url(self, value: str):
 | 
					 | 
				
			||||||
        self.database_url = value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_auto_open_diary(self, value: str):
 | 
					 | 
				
			||||||
        self.auto_open_diary = value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_auto_open_new_diary(self, value: bool):
 | 
					 | 
				
			||||||
        self.auto_open_new_diary = value
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,4 @@
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import shutil
 | 
					 | 
				
			||||||
from pathlib import Path
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,26 +37,3 @@ class DirectoryManager:
 | 
				
			||||||
    def get_diary_images_directory(directory_name: str) -> Path:
 | 
					    def get_diary_images_directory(directory_name: str) -> Path:
 | 
				
			||||||
        """Returns the images directory path for a specific diary."""
 | 
					        """Returns the images directory path for a specific diary."""
 | 
				
			||||||
        return DirectoryManager.get_diary_data_directory(directory_name) / "images"
 | 
					        return DirectoryManager.get_diary_data_directory(directory_name) / "images"
 | 
				
			||||||
 | 
					 | 
				
			||||||
    @staticmethod
 | 
					 | 
				
			||||||
    def get_database_path() -> Path:
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        Get the database file path following XDG Base Directory specification.
 | 
					 | 
				
			||||||
        Creates the directory if it doesn't exist.
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        pilgrim_dir = DirectoryManager.get_config_directory()
 | 
					 | 
				
			||||||
        db_path = pilgrim_dir / "database.db"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # If database doesn't exist in new location but exists in current directory,
 | 
					 | 
				
			||||||
        # migrate it
 | 
					 | 
				
			||||||
        if not db_path.exists():
 | 
					 | 
				
			||||||
            current_db = Path("database.db")
 | 
					 | 
				
			||||||
            if current_db.exists():
 | 
					 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    shutil.copy2(current_db, db_path)
 | 
					 | 
				
			||||||
                    # Consider using logging instead of print
 | 
					 | 
				
			||||||
                    print(f"Database migrated from {current_db} to {db_path}")
 | 
					 | 
				
			||||||
                except (OSError, shutil.Error) as e:
 | 
					 | 
				
			||||||
                    raise RuntimeError(f"Failed to migrate database: {e}")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return db_path
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue