easyclone 0.2.0__tar.gz → 1.0.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 (33) hide show
  1. {easyclone-0.2.0/src/easyclone.egg-info → easyclone-1.0.0}/PKG-INFO +21 -12
  2. {easyclone-0.2.0 → easyclone-1.0.0}/README.md +15 -11
  3. {easyclone-0.2.0 → easyclone-1.0.0}/pyproject.toml +10 -1
  4. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/config.py +7 -20
  5. easyclone-1.0.0/src/easyclone/ipc/__init__.py +2 -0
  6. easyclone-1.0.0/src/easyclone/main.py +155 -0
  7. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/utils/path_manipulation.py +3 -2
  8. easyclone-1.0.0/src/easyclone/utypes/config.py +26 -0
  9. {easyclone-0.2.0 → easyclone-1.0.0/src/easyclone.egg-info}/PKG-INFO +21 -12
  10. easyclone-0.2.0/src/easyclone/ipc/__init__.py +0 -2
  11. easyclone-0.2.0/src/easyclone/main.py +0 -70
  12. easyclone-0.2.0/src/easyclone/utypes/config.py +0 -16
  13. {easyclone-0.2.0 → easyclone-1.0.0}/LICENSE +0 -0
  14. {easyclone-0.2.0 → easyclone-1.0.0}/setup.cfg +0 -0
  15. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/__main__.py +0 -0
  16. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/ipc/client.py +0 -0
  17. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/ipc/server.py +0 -0
  18. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/rclone/__init__.py +0 -0
  19. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/rclone/backup.py +0 -0
  20. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/rclone/create_dirs.py +0 -0
  21. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/rclone/operations.py +0 -0
  22. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/shared/__init__.py +0 -0
  23. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/shared/sync_status.py +0 -0
  24. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/utils/__init__.py +0 -0
  25. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/utils/essentials.py +0 -0
  26. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/utypes/__init__.py +0 -0
  27. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/utypes/enums.py +0 -0
  28. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone/utypes/models.py +0 -0
  29. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone.egg-info/SOURCES.txt +0 -0
  30. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone.egg-info/dependency_links.txt +0 -0
  31. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone.egg-info/entry_points.txt +0 -0
  32. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone.egg-info/requires.txt +0 -0
  33. {easyclone-0.2.0 → easyclone-1.0.0}/src/easyclone.egg-info/top_level.txt +0 -0
@@ -1,10 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easyclone
3
- Version: 0.2.0
3
+ Version: 1.0.0
4
4
  Summary: Very convenient Rclone bulk backup wrapper
5
+ Author-email: Ahmet Arda Kavakcı <ahmetardakavakci@gmail.com>
6
+ Maintainer-email: Ahmet Arda Kavakcı <ahmetardakavakci@gmail.com>
7
+ License-Expression: GPL-3.0-or-later
5
8
  Project-URL: Repository, https://github.com/dybdeskarphet/easyclone
6
9
  Project-URL: Documentation, https://github.com/dybdeskarphet/easyclone
7
10
  Project-URL: Issues, https://github.com/dybdeskarphet/easyclone/issues
11
+ Project-URL: Changelog, https://github.com/dybdeskarphet/easyclone/blob/main/CHANGELOG.md
12
+ Keywords: backup,sync,google,drive,easyclone
8
13
  Requires-Python: >=3.13
9
14
  Description-Content-Type: text/markdown
10
15
  License-File: LICENSE
@@ -19,13 +24,13 @@ Dynamic: license-file
19
24
 
20
25
  You define what to back up, where to back it up, and EasyClone handles the syncs and copies — clean, fast, and reliable.
21
26
 
22
- ## 🚀 Features
27
+ ## Features
23
28
 
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
+ * Sync & Copy support per-path
30
+ * Backup multiple paths at once
31
+ * Human-friendly TOML config
32
+ * IPC-ready architecture for future GUI or monitoring tools
33
+ * Optional verbose logging
29
34
 
30
35
  ## Installation
31
36
 
@@ -36,7 +41,11 @@ pip install easyclone
36
41
  pipx install easyclone
37
42
  ```
38
43
 
39
- ## 🛠️ Requirements
44
+ ## Configuration
45
+
46
+ The config file is at `~/.config/easyclone/config.toml`
47
+
48
+ ## Requirements
40
49
 
41
50
  * Python **3.13+**
42
51
  * [`rclone`](https://rclone.org/) installed and accessible in your `$PATH`
@@ -44,7 +53,7 @@ pipx install easyclone
44
53
  * `toml>=0.10.2`
45
54
  * `typer>=0.16.0`
46
55
 
47
- ## 🧪 Example Usage
56
+ ## Example Usage
48
57
 
49
58
  ```bash
50
59
  easyclone start-backup
@@ -56,16 +65,16 @@ It will:
56
65
  * Copy the paths in `copy_paths`
57
66
  * Use the `remote_name` and `root_dir` to target your cloud storage
58
67
 
59
- ## 🙋‍♀️ Contributing
68
+ ## Contributing
60
69
 
61
70
  PRs welcome. Bug reports even more welcome.
62
71
 
63
- ## FAQ
72
+ ## FAQ
64
73
 
65
74
  Why does it create the folders first?
66
75
  > 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
76
 
68
- ## 📄 License
77
+ ## License
69
78
 
70
79
  GPLv3 — do whatever you want, just don't blame me if you sync your `/` folder to the cloud :)
71
80
 
@@ -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,8 +1,16 @@
1
1
  [project]
2
2
  name = "easyclone"
3
- version = "0.2.0"
3
+ version = "1.0.0"
4
4
  description = "Very convenient Rclone bulk backup wrapper"
5
+ keywords = ["backup", "sync", "google", "drive", "easyclone"]
6
+ authors = [
7
+ {name = "Ahmet Arda Kavakcı", email = "ahmetardakavakci@gmail.com"},
8
+ ]
9
+ maintainers = [
10
+ {name = "Ahmet Arda Kavakcı", email = "ahmetardakavakci@gmail.com"},
11
+ ]
5
12
  readme = "README.md"
13
+ license = "GPL-3.0-or-later"
6
14
  requires-python = ">=3.13"
7
15
  dependencies = [
8
16
  "pydantic>=2.11.5",
@@ -17,6 +25,7 @@ easyclone = "easyclone.main:app"
17
25
  Repository = "https://github.com/dybdeskarphet/easyclone"
18
26
  Documentation = "https://github.com/dybdeskarphet/easyclone"
19
27
  Issues = "https://github.com/dybdeskarphet/easyclone/issues"
28
+ Changelog = "https://github.com/dybdeskarphet/easyclone/blob/main/CHANGELOG.md"
20
29
 
21
30
  [tool.basedpyright]
22
31
  reportAny = false
@@ -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)
@@ -0,0 +1,2 @@
1
+ from .server import start_status_server, SOCKET_PATH
2
+ from .client import listen_ipc
@@ -0,0 +1,155 @@
1
+ import asyncio
2
+ import sys
3
+ from typing import Annotated, Any
4
+ from easyclone.config import cfg
5
+ from easyclone.ipc.client import listen_ipc
6
+ from easyclone.ipc.server import start_status_server
7
+ from easyclone.rclone.operations import make_backup_operation
8
+ import typer
9
+ import json
10
+ from easyclone.shared import sync_status
11
+ from easyclone.utils.essentials import exit_if_currently_running, exit_if_no_rclone
12
+ from easyclone.utypes.enums import CommandType
13
+
14
+
15
+ app = typer.Typer(
16
+ help="Very convenient Rclone bulk backup wrapper",
17
+ context_settings={"help_option_names": ["-h", "--help"]},
18
+ )
19
+
20
+
21
+ async def ipc():
22
+ server = await start_status_server()
23
+ async with server:
24
+ await server.serve_forever()
25
+
26
+
27
+ @app.command(help="Starts the backup process using the details in the config file.")
28
+ def start_backup(
29
+ verbose: Annotated[
30
+ bool,
31
+ typer.Option(
32
+ "--verbose", "-v", help="Enables the rclone logging (overrides config)."
33
+ ),
34
+ ] = False,
35
+ ):
36
+
37
+ import atexit
38
+ from os import path, remove
39
+ import signal
40
+ from types import FrameType
41
+ from easyclone.ipc.client import SOCKET_PATH
42
+ from easyclone.utils.essentials import log
43
+ from easyclone.utypes.enums import LogLevel
44
+
45
+ def cleanup():
46
+ if path.exists(SOCKET_PATH):
47
+ log("Cleaning up socket file...", LogLevel.WARN)
48
+ remove(SOCKET_PATH)
49
+
50
+ _ = atexit.register(cleanup)
51
+
52
+ def handle_signal(_signum: int, _frame: FrameType | None):
53
+ cleanup()
54
+ sys.exit(0)
55
+
56
+ _ = signal.signal(signal.SIGINT, handle_signal)
57
+ _ = signal.signal(signal.SIGTERM, handle_signal)
58
+
59
+ async def start():
60
+
61
+ exit_if_no_rclone()
62
+ exit_if_currently_running()
63
+ await sync_status.set_total_path_count(
64
+ len(cfg.backup.sync_paths) + len(cfg.backup.copy_paths)
65
+ )
66
+
67
+ _ipc_task = asyncio.create_task(ipc())
68
+
69
+ verbose_state = verbose or cfg.backup.verbose_log
70
+
71
+ await make_backup_operation(
72
+ CommandType.COPY, cfg.backup.copy_paths, verbose_state
73
+ )()
74
+ await make_backup_operation(
75
+ CommandType.SYNC, cfg.backup.sync_paths, verbose_state
76
+ )()
77
+
78
+ asyncio.run(start())
79
+
80
+
81
+ @app.command(help="Gets status information about the backup process.")
82
+ def get_status(
83
+ all_args: Annotated[
84
+ bool,
85
+ typer.Option("--all", "-a", help="Show all the backup status information."),
86
+ ] = False,
87
+ show_total: Annotated[
88
+ bool, typer.Option("--show-total", "-t", help="Show the total amount of paths.")
89
+ ] = False,
90
+ show_current: Annotated[
91
+ bool,
92
+ typer.Option(
93
+ "--show-current", "-c", help="Show the total amount of pending paths."
94
+ ),
95
+ ] = False,
96
+ show_operations: Annotated[
97
+ bool,
98
+ typer.Option(
99
+ "--show-operations", "-o", help="Show currently running operations."
100
+ ),
101
+ ] = False,
102
+ show_finished_path_count: Annotated[
103
+ bool,
104
+ typer.Option(
105
+ "--show-finished", "-f", help="Show the total amount of finished paths."
106
+ ),
107
+ ] = False,
108
+ show_operation_count: Annotated[
109
+ bool,
110
+ typer.Option(
111
+ "--get-operation-count",
112
+ "-O",
113
+ help="Show the total amount of running operations.",
114
+ ),
115
+ ] = False,
116
+ show_empty_paths: Annotated[
117
+ bool, typer.Option("--show-empty-paths", "-e", help="Show all the empty paths.")
118
+ ] = False,
119
+ ):
120
+ data: Any = asyncio.run(listen_ipc())
121
+
122
+ args = [
123
+ show_total,
124
+ show_current,
125
+ show_operations,
126
+ show_operation_count,
127
+ show_finished_path_count,
128
+ show_empty_paths,
129
+ ]
130
+
131
+ if not any(args) or all_args:
132
+ print(json.dumps(data, indent=2))
133
+ return
134
+
135
+ if show_total:
136
+ print(data["total_path_count"])
137
+
138
+ if show_current:
139
+ print(data["operation_count"])
140
+
141
+ if show_operations:
142
+ print(json.dumps(data["operations"], indent=2))
143
+
144
+ if show_operation_count:
145
+ print(data["operation_count"])
146
+
147
+ if show_finished_path_count:
148
+ print(data["finished_path_count"])
149
+
150
+ if show_empty_paths:
151
+ print(data["empty_paths"])
152
+
153
+
154
+ if __name__ == "__main__":
155
+ app()
@@ -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,10 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easyclone
3
- Version: 0.2.0
3
+ Version: 1.0.0
4
4
  Summary: Very convenient Rclone bulk backup wrapper
5
+ Author-email: Ahmet Arda Kavakcı <ahmetardakavakci@gmail.com>
6
+ Maintainer-email: Ahmet Arda Kavakcı <ahmetardakavakci@gmail.com>
7
+ License-Expression: GPL-3.0-or-later
5
8
  Project-URL: Repository, https://github.com/dybdeskarphet/easyclone
6
9
  Project-URL: Documentation, https://github.com/dybdeskarphet/easyclone
7
10
  Project-URL: Issues, https://github.com/dybdeskarphet/easyclone/issues
11
+ Project-URL: Changelog, https://github.com/dybdeskarphet/easyclone/blob/main/CHANGELOG.md
12
+ Keywords: backup,sync,google,drive,easyclone
8
13
  Requires-Python: >=3.13
9
14
  Description-Content-Type: text/markdown
10
15
  License-File: LICENSE
@@ -19,13 +24,13 @@ Dynamic: license-file
19
24
 
20
25
  You define what to back up, where to back it up, and EasyClone handles the syncs and copies — clean, fast, and reliable.
21
26
 
22
- ## 🚀 Features
27
+ ## Features
23
28
 
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
+ * Sync & Copy support per-path
30
+ * Backup multiple paths at once
31
+ * Human-friendly TOML config
32
+ * IPC-ready architecture for future GUI or monitoring tools
33
+ * Optional verbose logging
29
34
 
30
35
  ## Installation
31
36
 
@@ -36,7 +41,11 @@ pip install easyclone
36
41
  pipx install easyclone
37
42
  ```
38
43
 
39
- ## 🛠️ Requirements
44
+ ## Configuration
45
+
46
+ The config file is at `~/.config/easyclone/config.toml`
47
+
48
+ ## Requirements
40
49
 
41
50
  * Python **3.13+**
42
51
  * [`rclone`](https://rclone.org/) installed and accessible in your `$PATH`
@@ -44,7 +53,7 @@ pipx install easyclone
44
53
  * `toml>=0.10.2`
45
54
  * `typer>=0.16.0`
46
55
 
47
- ## 🧪 Example Usage
56
+ ## Example Usage
48
57
 
49
58
  ```bash
50
59
  easyclone start-backup
@@ -56,16 +65,16 @@ It will:
56
65
  * Copy the paths in `copy_paths`
57
66
  * Use the `remote_name` and `root_dir` to target your cloud storage
58
67
 
59
- ## 🙋‍♀️ Contributing
68
+ ## Contributing
60
69
 
61
70
  PRs welcome. Bug reports even more welcome.
62
71
 
63
- ## FAQ
72
+ ## FAQ
64
73
 
65
74
  Why does it create the folders first?
66
75
  > 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
76
 
68
- ## 📄 License
77
+ ## License
69
78
 
70
79
  GPLv3 — do whatever you want, just don't blame me if you sync your `/` folder to the cloud :)
71
80
 
@@ -1,2 +0,0 @@
1
- from .server import start_status_server
2
- from .client import listen_ipc
@@ -1,70 +0,0 @@
1
- import asyncio
2
- from typing import Annotated, Any
3
- from easyclone.config import cfg
4
- from easyclone.ipc.client import listen_ipc
5
- from easyclone.ipc.server import start_status_server
6
- from easyclone.rclone.operations import make_backup_operation
7
- import typer
8
- import json
9
- from easyclone.shared import sync_status
10
- from easyclone.utils.essentials import exit_if_currently_running, exit_if_no_rclone
11
- from easyclone.utypes.enums import CommandType
12
-
13
- app = typer.Typer(
14
- help="Very convenient Rclone bulk backup wrapper",
15
- context_settings={"help_option_names": ["-h", "--help"]}
16
- )
17
-
18
- async def ipc():
19
- server = await start_status_server()
20
- async with server:
21
- await server.serve_forever()
22
-
23
- @app.command(help="Starts the backup process using the details in the config file.")
24
- def start_backup(verbose: Annotated[bool, typer.Option("--verbose", "-v", help="Enables the rclone logging (overrides config).")] = False):
25
- async def start():
26
- exit_if_no_rclone()
27
- exit_if_currently_running()
28
- await sync_status.set_total_path_count(len(cfg.backup.sync_paths) + len(cfg.backup.copy_paths))
29
-
30
- _ipc_task = asyncio.create_task(ipc())
31
-
32
- verbose_state = verbose or cfg.backup.verbose_log
33
-
34
- await make_backup_operation(CommandType.COPY, cfg.backup.copy_paths, verbose_state)()
35
- await make_backup_operation(CommandType.SYNC, cfg.backup.sync_paths, verbose_state)()
36
-
37
- asyncio.run(start())
38
-
39
- @app.command(help="Gets status information about the backup process.")
40
- def get_status(
41
- all: Annotated[bool, typer.Option("--all", "-a", help="Show all the backup status information.")] = False,
42
- show_total: Annotated[bool, typer.Option("--show-total", "-t", help="Show the total amount of paths.")] = False,
43
- show_current: Annotated[bool, typer.Option("--show-current", "-c", help="Show the total amount of pending paths.")] = False,
44
- show_operations: Annotated[bool, typer.Option("--show-operations", "-o", help="Show currently running operations.")] = False,
45
- show_operation_count: Annotated[bool, typer.Option("--get-operation-count", "-O", help="Show the total amount of running operations.")] = False,
46
- show_empty_paths: Annotated[bool, typer.Option("--show-empty-paths", "-e", help="Show all the empty paths.")] = False
47
- ):
48
- data: Any = asyncio.run(listen_ipc())
49
-
50
- if (not show_total and not show_current and not show_operations and not show_operation_count and not show_empty_paths or all) or (show_total and show_current and show_operations and show_operation_count and show_empty_paths):
51
- print(json.dumps(data, indent=2))
52
- return
53
-
54
- if show_total:
55
- print(data["total_path_count"])
56
-
57
- if show_current:
58
- print(data["operation_count"])
59
-
60
- if show_operations:
61
- print(json.dumps(data["operations"], indent=2))
62
-
63
- if show_operation_count:
64
- print(json.dumps(data["operation_count"], indent=2))
65
-
66
- if show_empty_paths:
67
- print(json.dumps(data["empty_paths"], indent=2))
68
-
69
- if __name__ == "__main__":
70
- app()
@@ -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