Compare commits

..

7 Commits

Author SHA1 Message Date
f40a5c9276 Merge branch 'abstract_defaults'
Abstract the defaults into a seperate file
2026-01-03 17:20:18 +01:00
0e80ba0b0d config : use the defaults from defaults.py
Remove the defaults from the dataclasses as they are redundent with the
fallbacks of configparser.
Use the values in defaults.py as the fallbacks instead of hardcoded
values.
2026-01-03 17:18:19 +01:00
a223f04909 config : take cache_dir_path into account
cache_dir_path and all of the OtherConfig was ignored and the default
value was loaded, read its value from the config file instead.
2026-01-03 17:15:22 +01:00
e42ae71862 defaults : Create defaults.py
Creates the file defaults.py this is used to store the defaults and
easily include them into the config.
Changing defaults is thus possible without touching the code leaving
less room for errors.
2026-01-03 17:10:06 +01:00
58c7f7d1be Add main as a script with poetry 2026-01-03 16:39:00 +01:00
eefb21faff Mark local imports as such.
Prefix local imports with "unisync." so they are not mistaken with
external modules imports
2026-01-03 16:24:58 +01:00
941c467fc2 Bump copyright year and add missing file headers 2026-01-02 10:58:27 +01:00
9 changed files with 62 additions and 28 deletions

View File

@@ -10,6 +10,9 @@ requires-python = ">=3.13"
dependencies = [ dependencies = [
] ]
[project.scripts]
unisync = "unisync.main:main"
[tool.poetry] [tool.poetry]
packages = [{include = "unisync", from = "src"}] packages = [{include = "unisync", from = "src"}]

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2025 Paul Retourné # Copyright (C) 2025-2026 Paul Retourné
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import argparse import argparse
@@ -11,7 +11,7 @@ def create_argparser(sync_function, add_function, mount_function) -> argparse.Ar
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
prog='unisync', prog='unisync',
description='File synchronisation application', description='File synchronisation application',
epilog="Copyright © 2025 Paul Retourné.\n" epilog="Copyright © 2025-2026 Paul Retourné.\n"
"License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.", "License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.",
formatter_class=argparse.RawDescriptionHelpFormatter formatter_class=argparse.RawDescriptionHelpFormatter
) )

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2025 Paul Retourné # Copyright (C) 2025-2026 Paul Retourné
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from configparser import UNNAMED_SECTION from configparser import UNNAMED_SECTION
@@ -7,16 +7,18 @@ from pathlib import Path
import ipaddress import ipaddress
import configparser import configparser
from unisync.defaults import *
@dataclass @dataclass
class ServerConfig: class ServerConfig:
""" """
Dataclass keeping the config for connecting to the server Dataclass keeping the config for connecting to the server
""" """
user: str user: str
sshargs: str = "" sshargs: str
hostname: str = "" hostname: str
ip: str = "" ip: str
port: int = 22 port: int
def __post_init__(self): def __post_init__(self):
""" """
@@ -44,15 +46,15 @@ class UnisonConfig:
""" """
Dataclass keeping unison specific configurations Dataclass keeping unison specific configurations
""" """
bools: list = field(default_factory=list) bools: list
values: dict = field(default_factory=dict) values: dict
@dataclass @dataclass
class OtherConfig: class OtherConfig:
""" """
Dataclass keeping miscellanous configuration options Dataclass keeping miscellanous configuration options
""" """
cache_dir_path: Path = Path("~/.unisync").expanduser() cache_dir_path: Path
@dataclass @dataclass
class Config: class Config:
@@ -62,7 +64,7 @@ class Config:
server: ServerConfig server: ServerConfig
roots: RootsConfig roots: RootsConfig
unison: UnisonConfig unison: UnisonConfig
other: OtherConfig = field(default_factory=OtherConfig) other: OtherConfig
def load_config(config_path:str) -> Config: def load_config(config_path:str) -> Config:
@@ -79,18 +81,22 @@ def load_config(config_path:str) -> Config:
# Check if sections are provided # Check if sections are provided
server_section = "Server" if "Server" in config.sections() else UNNAMED_SECTION server_section = "Server" if "Server" in config.sections() else UNNAMED_SECTION
roots_section = "Roots" if "Roots" in config.sections() else UNNAMED_SECTION roots_section = "Roots" if "Roots" in config.sections() else UNNAMED_SECTION
other_section = "Other" if "Other" in config.sections() else UNNAMED_SECTION
server_config = ServerConfig( server_config = ServerConfig(
config.get(server_section, "user"), config.get(server_section, "user"),
config.get(server_section, "sshargs", fallback=""), config.get(server_section, "sshargs", fallback=DEFAULT_SERVER_SSHARGS),
config.get(server_section, "hostname", fallback=""), config.get(server_section, "hostname", fallback=DEFAULT_SERVER_HOSTNAME),
config.get(server_section, "ip", fallback=""), config.get(server_section, "ip", fallback=DEFAULT_SERVER_IP),
config.getint(server_section, "port", fallback=22) config.getint(server_section, "port", fallback=DEFAULT_SERVER_PORT)
) )
roots_config = RootsConfig( roots_config = RootsConfig(
config.get(roots_section, "local"), config.get(roots_section, "local", fallback=DEFAULT_ROOTS_LOCAL),
config.get(roots_section, "remote") config.get(roots_section, "remote")
) )
other_config = OtherConfig(
config.get(other_section, "cache_dir_path", fallback=DEFAULT_MISC_CACHE_DIR_PATH)
)
args_bool = list() args_bool = list()
args_val = dict() args_val = dict()
@@ -104,4 +110,4 @@ def load_config(config_path:str) -> Config:
args_val[key] = val args_val[key] = val
unison_config = UnisonConfig(args_bool, args_val) unison_config = UnisonConfig(args_bool, args_val)
return Config(server_config, roots_config, unison_config) return Config(server_config, roots_config, unison_config, other_config)

18
src/unisync/defaults.py Normal file
View File

@@ -0,0 +1,18 @@
# copyright (c) 2026 paul retourné
# spdx-license-identifier: gpl-3.0-or-later
from pathlib import Path
# Commented out values are part of the config but are required so there is no defaults.
# This allows this file to be a list of all the config options.
# DEFAULT_SERVER_USER: str = ""
DEFAULT_SERVER_SSHARGS: str = ""
DEFAULT_SERVER_HOSTNAME: str = ""
DEFAULT_SERVER_IP: str = ""
DEFAULT_SERVER_PORT: int = 22
DEFAULT_ROOTS_LOCAL: str = str(Path("~/files").expanduser())
# DEFAULT_ROOTS_REMOTE: str = ""
DEFAULT_MISC_CACHE_DIR_PATH: Path = Path("~/.unisync").expanduser()

View File

@@ -1,3 +1,6 @@
# Copyright (C) 2025-2026 Paul Retourné
# SPDX-License-Identifier: GPL-3.0-or-later
class RemoteMountedError(BaseException): class RemoteMountedError(BaseException):
pass pass

View File

@@ -1,13 +1,14 @@
# Copyright (C) 2025 Paul Retourné # Copyright (C) 2025-2026 Paul Retourné
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import os import os
from argparser import create_argparser
from runners import unisync_sync, unisync_add, unisync_mount
from config import load_config
from synchroniser import Synchroniser
from pathlib import Path from pathlib import Path
from paths import *
from unisync.argparser import create_argparser
from unisync.runners import unisync_sync, unisync_add, unisync_mount
from unisync.config import load_config
from unisync.synchroniser import Synchroniser
from unisync.paths import *
def main(): def main():
parser = create_argparser(unisync_sync, unisync_add, unisync_mount) parser = create_argparser(unisync_sync, unisync_add, unisync_mount)

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2025 Paul Retourné # Copyright (C) 2025-2026 Paul Retourné
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later

View File

@@ -1,5 +1,8 @@
from synchroniser import Synchroniser # Copyright (C) 2025-2026 Paul Retourné
from paths import PathsManager # SPDX-License-Identifier: GPL-3.0-or-later
from unisync.synchroniser import Synchroniser
from unisync.paths import PathsManager
def unisync_sync(synchroniser:Synchroniser, paths_manager:PathsManager): def unisync_sync(synchroniser:Synchroniser, paths_manager:PathsManager):

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2025 Paul Retourné # Copyright (C) 2025-2026 Paul Retourné
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import subprocess import subprocess
@@ -9,7 +9,7 @@ import logging
from pathlib import Path from pathlib import Path
from errors import RemoteMountedError, InvalidMountError from unisync.errors import RemoteMountedError, InvalidMountError
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)