easyclone 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {easyclone-0.2.0/src/easyclone.egg-info → easyclone-0.3.0}/PKG-INFO +16 -12
  2. {easyclone-0.2.0 → easyclone-0.3.0}/README.md +15 -11
  3. {easyclone-0.2.0 → easyclone-0.3.0}/pyproject.toml +1 -1
  4. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/config.py +7 -20
  5. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/utils/path_manipulation.py +3 -2
  6. easyclone-0.3.0/src/easyclone/utypes/config.py +26 -0
  7. {easyclone-0.2.0 → easyclone-0.3.0/src/easyclone.egg-info}/PKG-INFO +16 -12
  8. easyclone-0.2.0/src/easyclone/utypes/config.py +0 -16
  9. {easyclone-0.2.0 → easyclone-0.3.0}/LICENSE +0 -0
  10. {easyclone-0.2.0 → easyclone-0.3.0}/setup.cfg +0 -0
  11. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/__main__.py +0 -0
  12. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/ipc/__init__.py +0 -0
  13. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/ipc/client.py +0 -0
  14. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/ipc/server.py +0 -0
  15. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/main.py +0 -0
  16. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/rclone/__init__.py +0 -0
  17. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/rclone/backup.py +0 -0
  18. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/rclone/create_dirs.py +0 -0
  19. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/rclone/operations.py +0 -0
  20. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/shared/__init__.py +0 -0
  21. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/shared/sync_status.py +0 -0
  22. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/utils/__init__.py +0 -0
  23. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/utils/essentials.py +0 -0
  24. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/utypes/__init__.py +0 -0
  25. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/utypes/enums.py +0 -0
  26. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone/utypes/models.py +0 -0
  27. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone.egg-info/SOURCES.txt +0 -0
  28. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone.egg-info/dependency_links.txt +0 -0
  29. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone.egg-info/entry_points.txt +0 -0
  30. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone.egg-info/requires.txt +0 -0
  31. {easyclone-0.2.0 → easyclone-0.3.0}/src/easyclone.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easyclone
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Very convenient Rclone bulk backup wrapper
5
5
  Project-URL: Repository, https://github.com/dybdeskarphet/easyclone
6
6
  Project-URL: Documentation, https://github.com/dybdeskarphet/easyclone
@@ -19,13 +19,13 @@ Dynamic: license-file
19
19
 
20
20
  You define what to back up, where to back it up, and EasyClone handles the syncs and copies — clean, fast, and reliable.
21
21
 
22
- ## 🚀 Features
22
+ ## Features
23
23
 
24
- * 🔁 Sync & Copy support per-path
25
- * 📁 Backup multiple paths at once
26
- * 🧠 Human-friendly TOML config
27
- * 🛠️ IPC-ready architecture for future GUI or monitoring tools
28
- * 🔊 Optional verbose logging
24
+ * Sync & Copy support per-path
25
+ * Backup multiple paths at once
26
+ * Human-friendly TOML config
27
+ * IPC-ready architecture for future GUI or monitoring tools
28
+ * Optional verbose logging
29
29
 
30
30
  ## Installation
31
31
 
@@ -36,7 +36,11 @@ pip install easyclone
36
36
  pipx install easyclone
37
37
  ```
38
38
 
39
- ## 🛠️ Requirements
39
+ ## Configuration
40
+
41
+ The config file is at `~/.config/easyclone/config.toml`
42
+
43
+ ## Requirements
40
44
 
41
45
  * Python **3.13+**
42
46
  * [`rclone`](https://rclone.org/) installed and accessible in your `$PATH`
@@ -44,7 +48,7 @@ pipx install easyclone
44
48
  * `toml>=0.10.2`
45
49
  * `typer>=0.16.0`
46
50
 
47
- ## 🧪 Example Usage
51
+ ## Example Usage
48
52
 
49
53
  ```bash
50
54
  easyclone start-backup
@@ -56,16 +60,16 @@ It will:
56
60
  * Copy the paths in `copy_paths`
57
61
  * Use the `remote_name` and `root_dir` to target your cloud storage
58
62
 
59
- ## 🙋‍♀️ Contributing
63
+ ## Contributing
60
64
 
61
65
  PRs welcome. Bug reports even more welcome.
62
66
 
63
- ## FAQ
67
+ ## FAQ
64
68
 
65
69
  Why does it create the folders first?
66
70
  > Because services like Google Drive support multiple folders with the same name in the same directory. So when you try to concurrently backup paths from the same directory, it will create the parent directory more than once, and we don't want that.
67
71
 
68
- ## 📄 License
72
+ ## License
69
73
 
70
74
  GPLv3 — do whatever you want, just don't blame me if you sync your `/` folder to the cloud :)
71
75
 
@@ -4,13 +4,13 @@
4
4
 
5
5
  You define what to back up, where to back it up, and EasyClone handles the syncs and copies — clean, fast, and reliable.
6
6
 
7
- ## 🚀 Features
7
+ ## Features
8
8
 
9
- * 🔁 Sync & Copy support per-path
10
- * 📁 Backup multiple paths at once
11
- * 🧠 Human-friendly TOML config
12
- * 🛠️ IPC-ready architecture for future GUI or monitoring tools
13
- * 🔊 Optional verbose logging
9
+ * Sync & Copy support per-path
10
+ * Backup multiple paths at once
11
+ * Human-friendly TOML config
12
+ * IPC-ready architecture for future GUI or monitoring tools
13
+ * Optional verbose logging
14
14
 
15
15
  ## Installation
16
16
 
@@ -21,7 +21,11 @@ pip install easyclone
21
21
  pipx install easyclone
22
22
  ```
23
23
 
24
- ## 🛠️ Requirements
24
+ ## Configuration
25
+
26
+ The config file is at `~/.config/easyclone/config.toml`
27
+
28
+ ## Requirements
25
29
 
26
30
  * Python **3.13+**
27
31
  * [`rclone`](https://rclone.org/) installed and accessible in your `$PATH`
@@ -29,7 +33,7 @@ pipx install easyclone
29
33
  * `toml>=0.10.2`
30
34
  * `typer>=0.16.0`
31
35
 
32
- ## 🧪 Example Usage
36
+ ## Example Usage
33
37
 
34
38
  ```bash
35
39
  easyclone start-backup
@@ -41,16 +45,16 @@ It will:
41
45
  * Copy the paths in `copy_paths`
42
46
  * Use the `remote_name` and `root_dir` to target your cloud storage
43
47
 
44
- ## 🙋‍♀️ Contributing
48
+ ## Contributing
45
49
 
46
50
  PRs welcome. Bug reports even more welcome.
47
51
 
48
- ## FAQ
52
+ ## FAQ
49
53
 
50
54
  Why does it create the folders first?
51
55
  > Because services like Google Drive support multiple folders with the same name in the same directory. So when you try to concurrently backup paths from the same directory, it will create the parent directory more than once, and we don't want that.
52
56
 
53
- ## 📄 License
57
+ ## License
54
58
 
55
59
  GPLv3 — do whatever you want, just don't blame me if you sync your `/` folder to the cloud :)
56
60
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "easyclone"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "Very convenient Rclone bulk backup wrapper"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -1,9 +1,10 @@
1
1
  from __future__ import annotations
2
+ import json
2
3
  from threading import Lock
3
4
  from os import getenv
4
5
  from pathlib import Path
5
6
  from easyclone.utypes.enums import LogLevel
6
- from easyclone.utypes.config import BackupConfigModel, ConfigModel, RcloneConfigModel
7
+ from easyclone.utypes.config import BackupConfigModel, ConfigModel
7
8
  import toml
8
9
 
9
10
  class Config:
@@ -31,21 +32,6 @@ class Config:
31
32
  copy_paths=[],
32
33
  remote_name="GoogleDrive",
33
34
  root_dir="Backups/PC",
34
- verbose_log=False
35
- ),
36
- rclone=RcloneConfigModel(
37
- args=[
38
- "--update",
39
- "--verbose",
40
- "--transfers 30",
41
- "--checkers 8",
42
- "--contimeout 60s",
43
- "--timeout 300s",
44
- "--retries 3",
45
- "--low-level-retries 10",
46
- "--stats 1s"
47
- ],
48
- concurrent_limit=50
49
35
  )
50
36
  )
51
37
 
@@ -66,6 +52,10 @@ class Config:
66
52
 
67
53
  self._path = config_file
68
54
 
55
+ def _config_normalize(self, config: ConfigModel):
56
+ config.backup.root_dir = config.backup.root_dir.strip("/")
57
+ return config
58
+
69
59
  def _load_config(self):
70
60
  from easyclone.utils.essentials import log
71
61
  self._get_config_path()
@@ -83,10 +73,7 @@ class Config:
83
73
  try:
84
74
  parsed_toml = toml.loads(parsed_string)
85
75
  validated_config = ConfigModel.model_validate(parsed_toml)
86
-
87
- # Normalize config
88
- validated_config.backup.root_dir = validated_config.backup.root_dir.strip("/")
89
-
76
+ validated_config = self._config_normalize(validated_config)
90
77
  return validated_config
91
78
  except Exception as e:
92
79
  log(f"Invalid config: {e}", LogLevel.ERROR)
@@ -1,3 +1,4 @@
1
+ import json
1
2
  from pathlib import Path
2
3
  import os
3
4
  from easyclone.utypes.enums import PathType
@@ -10,7 +11,7 @@ def organize_paths(paths: list[str], remote_name: str) -> OrganizedPaths:
10
11
  root_dir = cfg.backup.root_dir
11
12
 
12
13
  for path in paths:
13
- p = Path(path).expanduser()
14
+ p = Path(os.path.expandvars(os.path.expanduser(path)))
14
15
 
15
16
  if not os.path.exists(p):
16
17
  empty_paths.append(path)
@@ -28,7 +29,7 @@ def organize_paths(paths: list[str], remote_name: str) -> OrganizedPaths:
28
29
  "dest": f"{remote_name}:{root_dir}{dest_dir}",
29
30
  "path_type": PathType.FILE.value
30
31
  })
31
-
32
+
32
33
  return {
33
34
  "valid_paths": source_dest_array,
34
35
  "empty_paths": empty_paths
@@ -0,0 +1,26 @@
1
+ from pydantic import BaseModel
2
+
3
+ class BackupConfigModel(BaseModel):
4
+ sync_paths: list[str]
5
+ copy_paths: list[str]
6
+ remote_name: str
7
+ root_dir: str
8
+ verbose_log: bool = False
9
+
10
+ class RcloneConfigModel(BaseModel):
11
+ args: list[str] = [
12
+ "--update",
13
+ "--verbose",
14
+ "--transfers 30",
15
+ "--checkers 8",
16
+ "--contimeout 60s",
17
+ "--timeout 300s",
18
+ "--retries 3",
19
+ "--low-level-retries 10",
20
+ "--stats 1s"
21
+ ]
22
+ concurrent_limit: int = 50
23
+
24
+ class ConfigModel(BaseModel):
25
+ backup: BackupConfigModel
26
+ rclone: RcloneConfigModel = RcloneConfigModel()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easyclone
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Very convenient Rclone bulk backup wrapper
5
5
  Project-URL: Repository, https://github.com/dybdeskarphet/easyclone
6
6
  Project-URL: Documentation, https://github.com/dybdeskarphet/easyclone
@@ -19,13 +19,13 @@ Dynamic: license-file
19
19
 
20
20
  You define what to back up, where to back it up, and EasyClone handles the syncs and copies — clean, fast, and reliable.
21
21
 
22
- ## 🚀 Features
22
+ ## Features
23
23
 
24
- * 🔁 Sync & Copy support per-path
25
- * 📁 Backup multiple paths at once
26
- * 🧠 Human-friendly TOML config
27
- * 🛠️ IPC-ready architecture for future GUI or monitoring tools
28
- * 🔊 Optional verbose logging
24
+ * Sync & Copy support per-path
25
+ * Backup multiple paths at once
26
+ * Human-friendly TOML config
27
+ * IPC-ready architecture for future GUI or monitoring tools
28
+ * Optional verbose logging
29
29
 
30
30
  ## Installation
31
31
 
@@ -36,7 +36,11 @@ pip install easyclone
36
36
  pipx install easyclone
37
37
  ```
38
38
 
39
- ## 🛠️ Requirements
39
+ ## Configuration
40
+
41
+ The config file is at `~/.config/easyclone/config.toml`
42
+
43
+ ## Requirements
40
44
 
41
45
  * Python **3.13+**
42
46
  * [`rclone`](https://rclone.org/) installed and accessible in your `$PATH`
@@ -44,7 +48,7 @@ pipx install easyclone
44
48
  * `toml>=0.10.2`
45
49
  * `typer>=0.16.0`
46
50
 
47
- ## 🧪 Example Usage
51
+ ## Example Usage
48
52
 
49
53
  ```bash
50
54
  easyclone start-backup
@@ -56,16 +60,16 @@ It will:
56
60
  * Copy the paths in `copy_paths`
57
61
  * Use the `remote_name` and `root_dir` to target your cloud storage
58
62
 
59
- ## 🙋‍♀️ Contributing
63
+ ## Contributing
60
64
 
61
65
  PRs welcome. Bug reports even more welcome.
62
66
 
63
- ## FAQ
67
+ ## FAQ
64
68
 
65
69
  Why does it create the folders first?
66
70
  > Because services like Google Drive support multiple folders with the same name in the same directory. So when you try to concurrently backup paths from the same directory, it will create the parent directory more than once, and we don't want that.
67
71
 
68
- ## 📄 License
72
+ ## License
69
73
 
70
74
  GPLv3 — do whatever you want, just don't blame me if you sync your `/` folder to the cloud :)
71
75
 
@@ -1,16 +0,0 @@
1
- from pydantic import BaseModel
2
-
3
- class BackupConfigModel(BaseModel):
4
- sync_paths: list[str]
5
- copy_paths: list[str]
6
- remote_name: str
7
- root_dir: str
8
- verbose_log: bool
9
-
10
- class RcloneConfigModel(BaseModel):
11
- args: list[str]
12
- concurrent_limit: int
13
-
14
- class ConfigModel(BaseModel):
15
- backup: BackupConfigModel
16
- rclone: RcloneConfigModel
File without changes
File without changes