rclone-api 1.0.69__tar.gz → 1.0.70__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. {rclone_api-1.0.69 → rclone_api-1.0.70}/PKG-INFO +1 -1
  2. {rclone_api-1.0.69 → rclone_api-1.0.70}/pyproject.toml +1 -1
  3. rclone_api-1.0.70/src/rclone_api/diff_walk.py +123 -0
  4. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/dir.py +1 -1
  5. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api.egg-info/PKG-INFO +1 -1
  6. rclone_api-1.0.69/src/rclone_api/diff_walk.py +0 -143
  7. {rclone_api-1.0.69 → rclone_api-1.0.70}/.aiderignore +0 -0
  8. {rclone_api-1.0.69 → rclone_api-1.0.70}/.github/workflows/lint.yml +0 -0
  9. {rclone_api-1.0.69 → rclone_api-1.0.70}/.github/workflows/push_macos.yml +0 -0
  10. {rclone_api-1.0.69 → rclone_api-1.0.70}/.github/workflows/push_ubuntu.yml +0 -0
  11. {rclone_api-1.0.69 → rclone_api-1.0.70}/.github/workflows/push_win.yml +0 -0
  12. {rclone_api-1.0.69 → rclone_api-1.0.70}/.gitignore +0 -0
  13. {rclone_api-1.0.69 → rclone_api-1.0.70}/.pylintrc +0 -0
  14. {rclone_api-1.0.69 → rclone_api-1.0.70}/.vscode/launch.json +0 -0
  15. {rclone_api-1.0.69 → rclone_api-1.0.70}/.vscode/settings.json +0 -0
  16. {rclone_api-1.0.69 → rclone_api-1.0.70}/.vscode/tasks.json +0 -0
  17. {rclone_api-1.0.69 → rclone_api-1.0.70}/LICENSE +0 -0
  18. {rclone_api-1.0.69 → rclone_api-1.0.70}/MANIFEST.in +0 -0
  19. {rclone_api-1.0.69 → rclone_api-1.0.70}/README.md +0 -0
  20. {rclone_api-1.0.69 → rclone_api-1.0.70}/clean +0 -0
  21. {rclone_api-1.0.69 → rclone_api-1.0.70}/install +0 -0
  22. {rclone_api-1.0.69 → rclone_api-1.0.70}/lint +0 -0
  23. {rclone_api-1.0.69 → rclone_api-1.0.70}/requirements.testing.txt +0 -0
  24. {rclone_api-1.0.69 → rclone_api-1.0.70}/setup.cfg +0 -0
  25. {rclone_api-1.0.69 → rclone_api-1.0.70}/setup.py +0 -0
  26. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/__init__.py +0 -0
  27. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/assets/example.txt +0 -0
  28. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/cli.py +0 -0
  29. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/cmd/list_files.py +0 -0
  30. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/completed_process.py +0 -0
  31. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/config.py +0 -0
  32. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/convert.py +0 -0
  33. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/deprecated.py +0 -0
  34. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/diff.py +0 -0
  35. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/dir_listing.py +0 -0
  36. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/exec.py +0 -0
  37. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/file.py +0 -0
  38. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/filelist.py +0 -0
  39. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/group_files.py +0 -0
  40. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/process.py +0 -0
  41. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/rclone.py +0 -0
  42. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/remote.py +0 -0
  43. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/rpath.py +0 -0
  44. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/types.py +0 -0
  45. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/util.py +0 -0
  46. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api/walk.py +0 -0
  47. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api.egg-info/SOURCES.txt +0 -0
  48. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  49. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api.egg-info/entry_points.txt +0 -0
  50. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api.egg-info/requires.txt +0 -0
  51. {rclone_api-1.0.69 → rclone_api-1.0.70}/src/rclone_api.egg-info/top_level.txt +0 -0
  52. {rclone_api-1.0.69 → rclone_api-1.0.70}/test +0 -0
  53. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_cmd_list_files.py +0 -0
  54. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_copy.py +0 -0
  55. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_copy_files.py +0 -0
  56. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_diff.py +0 -0
  57. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_diff_walk.py +0 -0
  58. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_group_files.py +0 -0
  59. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_is_synced.py +0 -0
  60. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_ls.py +0 -0
  61. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_mount.py +0 -0
  62. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_mount_s3.py +0 -0
  63. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_mount_webdav.py +0 -0
  64. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_obscure.py +0 -0
  65. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_remote_control.py +0 -0
  66. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_remotes.py +0 -0
  67. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_serve_webdav.py +0 -0
  68. {rclone_api-1.0.69 → rclone_api-1.0.70}/tests/test_walk.py +0 -0
  69. {rclone_api-1.0.69 → rclone_api-1.0.70}/tox.ini +0 -0
  70. {rclone_api-1.0.69 → rclone_api-1.0.70}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.69
3
+ Version: 1.0.70
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  Maintainer: Zachary Vorhies
@@ -15,7 +15,7 @@ dependencies = [
15
15
  "python-dotenv>=1.0.0",
16
16
  ]
17
17
  # Change this with the version number bump.
18
- version = "1.0.69"
18
+ version = "1.0.70"
19
19
 
20
20
  [tool.setuptools]
21
21
  package-dir = {"" = "src"}
@@ -0,0 +1,123 @@
1
+ import time
2
+ from concurrent.futures import ThreadPoolExecutor
3
+ from queue import Empty, Queue
4
+ from threading import Thread
5
+ from typing import Generator
6
+
7
+ from rclone_api import Dir
8
+ from rclone_api.dir_listing import DirListing
9
+ from rclone_api.types import ListingOption
10
+ from rclone_api.walk import walk_runner_depth_first
11
+
12
+ _MAX_OUT_QUEUE_SIZE = 50
13
+
14
+
15
+ # ONLY Works from src -> dst diffing.
16
+ def _async_diff_dir_walk_task(
17
+ src: Dir, dst: Dir, max_depth: int, out_queue: Queue[Dir | None], reverse
18
+ ) -> None:
19
+ curr_src, curr_dst = src, dst
20
+ with ThreadPoolExecutor(max_workers=2) as executor:
21
+ # src_dir_listing = src.ls(listing_option=ListingOption.DIRS_ONLY)
22
+ # dst_dir_listing = dst.ls(listing_option=ListingOption.DIRS_ONLY)
23
+ t1 = executor.submit(
24
+ src.ls, listing_option=ListingOption.DIRS_ONLY, reverse=reverse
25
+ )
26
+ t2 = executor.submit(
27
+ dst.ls, listing_option=ListingOption.DIRS_ONLY, reverse=reverse
28
+ )
29
+ src_dir_listing: DirListing = t1.result()
30
+ dst_dir_listing: DirListing = t2.result()
31
+ next_depth = max_depth - 1 if max_depth > 0 else max_depth
32
+ dst_files: list[str] = [d.name for d in dst_dir_listing.dirs]
33
+ src_files: list[str] = [d.name for d in src_dir_listing.dirs]
34
+ dst_files_set: set[str] = set(dst_files)
35
+ matching_dirs: list[str] = []
36
+ for file in src_files:
37
+ if file not in dst_files_set:
38
+ # print(f"missing dir on src: {file}")
39
+ queue_dir_listing: Queue[DirListing | None] = Queue()
40
+ if next_depth > 0 or next_depth == -1:
41
+ walk_runner_depth_first(
42
+ dir=curr_src,
43
+ out_queue=queue_dir_listing,
44
+ reverse=reverse,
45
+ max_depth=next_depth,
46
+ )
47
+ while dirlisting := queue_dir_listing.get():
48
+ if dirlisting is None:
49
+ break
50
+ # print(f"dirlisting: {dirlisting}")
51
+ for d in dirlisting.dirs:
52
+ out_queue.put(d)
53
+ else:
54
+ matching_dirs.append(file)
55
+
56
+ for matching_dir in matching_dirs:
57
+ # print(f"matching dir: {matching_dir}")
58
+ if next_depth > 0 or next_depth == -1:
59
+ src_next = curr_src / matching_dir
60
+ dst_next = curr_dst / matching_dir
61
+ _async_diff_dir_walk_task(
62
+ src=src_next,
63
+ dst=dst_next,
64
+ max_depth=next_depth,
65
+ out_queue=out_queue,
66
+ reverse=reverse,
67
+ )
68
+
69
+
70
+ def async_diff_dir_walk_task(
71
+ src: Dir, dst: Dir, max_depth: int, out_queue: Queue[Dir | None], reverse=False
72
+ ) -> None:
73
+ try:
74
+ _async_diff_dir_walk_task(src, dst, max_depth, out_queue, reverse)
75
+ except Exception:
76
+ import _thread
77
+
78
+ _thread.interrupt_main()
79
+ raise
80
+ finally:
81
+ out_queue.put(None)
82
+
83
+
84
+ def diff_walk(
85
+ src: Dir,
86
+ dst: Dir,
87
+ max_depth: int = -1,
88
+ reverse: bool = False,
89
+ ) -> Generator[Dir, None, None]:
90
+ """Walk through the given directory recursively.
91
+
92
+ Args:
93
+ dir: Directory or Remote to walk through
94
+ max_depth: Maximum depth to traverse (-1 for unlimited)
95
+
96
+ Yields:
97
+ DirListing: Directory listing for each directory encountered
98
+ """
99
+
100
+ try:
101
+ out_queue: Queue[Dir | None] = Queue(maxsize=_MAX_OUT_QUEUE_SIZE)
102
+
103
+ def task() -> None:
104
+ async_diff_dir_walk_task(src, dst, max_depth, out_queue, reverse=reverse)
105
+
106
+ worker = Thread(
107
+ target=task,
108
+ daemon=True,
109
+ )
110
+ worker.start()
111
+
112
+ while True:
113
+ try:
114
+ dirlisting = out_queue.get_nowait()
115
+ if dirlisting is None:
116
+ break
117
+ yield dirlisting
118
+ except Empty:
119
+ time.sleep(0.1)
120
+
121
+ worker.join()
122
+ except KeyboardInterrupt:
123
+ pass
@@ -102,7 +102,7 @@ class Dir:
102
102
  path = Path(self.path.path) / other
103
103
  rpath = RPath(
104
104
  self.path.remote,
105
- str(path),
105
+ str(path.as_posix()),
106
106
  name=other,
107
107
  size=0,
108
108
  mime_type="inode/directory",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.69
3
+ Version: 1.0.70
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  Maintainer: Zachary Vorhies
@@ -1,143 +0,0 @@
1
- from concurrent.futures import ThreadPoolExecutor
2
- from queue import Queue
3
- from threading import Thread
4
- from typing import Generator
5
-
6
- from rclone_api import Dir
7
- from rclone_api.dir_listing import DirListing
8
- from rclone_api.types import ListingOption
9
- from rclone_api.walk import walk_runner_depth_first
10
-
11
- _MAX_OUT_QUEUE_SIZE = 50
12
-
13
-
14
- # ONLY Works from src -> dst diffing.
15
- def _async_diff_dir_walk_task(
16
- src: Dir, dst: Dir, max_depth: int, out_queue: Queue[Dir | None], reverse=False
17
- ) -> None:
18
-
19
- try:
20
- stack = [(src, dst)]
21
- while stack:
22
- curr_src, curr_dst = stack.pop()
23
- curr_src = curr_src
24
- curr_dst = curr_dst
25
-
26
- with ThreadPoolExecutor(max_workers=2) as executor:
27
- # src_dir_listing = src.ls(listing_option=ListingOption.DIRS_ONLY)
28
- # dst_dir_listing = dst.ls(listing_option=ListingOption.DIRS_ONLY)
29
- t1 = executor.submit(
30
- src.ls, listing_option=ListingOption.DIRS_ONLY, reverse=reverse
31
- )
32
- t2 = executor.submit(
33
- dst.ls, listing_option=ListingOption.DIRS_ONLY, reverse=reverse
34
- )
35
- src_dir_listing: DirListing = t1.result()
36
- dst_dir_listing: DirListing = t2.result()
37
-
38
- # dirlisting = current_dir.ls()
39
- # if reverse:
40
- # dirlisting.dirs.reverse()
41
- # if depth != 0:
42
- # for subdir in dirlisting.dirs: # Process deeper directories first
43
- # # stack.append((child, depth - 1 if depth > 0 else depth))
44
- # next_depth = depth - 1 if depth > 0 else depth
45
- # _walk_runner_depth_first(
46
- # subdir, next_depth, out_queue, reverse=reverse
47
- # )
48
- # out_queue.put(dirlisting)
49
-
50
- # for subdir in dst_dir_listing.dirs:
51
- # subdir.to_string(include_remote=False)
52
- # walk_runner_depth_first()
53
-
54
- # find elements missing on dst
55
- # missing_on_dst: set[Dir] = set(src_dir_listing.dirs) - set(
56
- # dst_dir_listing.dirs
57
- # )
58
- # exists_on_dst: set[Dir] = set(src_dir_listing.dirs) - missing_on_dst
59
-
60
- dst_files: list[str] = [d.name for d in dst_dir_listing.dirs]
61
- src_files: list[str] = [d.name for d in src_dir_listing.dirs]
62
-
63
- dst_files_set: set[str] = set(dst_files)
64
- # src_files_set: set[str] = set(src_files)
65
-
66
- # print(f"src_files: {src_files}")
67
- # print(f"dst_files: {dst_files}")
68
-
69
- matching_dirs: list[str] = []
70
-
71
- for file in src_files:
72
- if file not in dst_files_set:
73
- # print(f"missing dir on src: {file}")
74
- queue_dir_listing: Queue[DirListing | None] = Queue()
75
- walk_runner_depth_first(
76
- dir=curr_src,
77
- max_depth=max_depth,
78
- out_queue=queue_dir_listing,
79
- reverse=reverse,
80
- )
81
- while dirlisting := queue_dir_listing.get():
82
- if dirlisting is None:
83
- break
84
- # print(f"dirlisting: {dirlisting}")
85
- for d in dirlisting.dirs:
86
- out_queue.put(d)
87
- else:
88
- matching_dirs.append(file)
89
-
90
- for matching_dir in matching_dirs:
91
- # print(f"matching dir: {matching_dir}")
92
- _async_diff_dir_walk_task(
93
- src=curr_src / matching_dir,
94
- dst=curr_dst / matching_dir,
95
- max_depth=max_depth,
96
- out_queue=out_queue,
97
- reverse=reverse,
98
- )
99
-
100
- out_queue.put(None)
101
- except KeyboardInterrupt:
102
- import _thread
103
-
104
- out_queue.put(None)
105
- _thread.interrupt_main()
106
-
107
-
108
- def diff_walk(
109
- src: Dir,
110
- dst: Dir,
111
- max_depth: int = -1,
112
- reverse: bool = False,
113
- ) -> Generator[Dir, None, None]:
114
- """Walk through the given directory recursively.
115
-
116
- Args:
117
- dir: Directory or Remote to walk through
118
- max_depth: Maximum depth to traverse (-1 for unlimited)
119
-
120
- Yields:
121
- DirListing: Directory listing for each directory encountered
122
- """
123
-
124
- try:
125
- out_queue: Queue[Dir | None] = Queue(maxsize=_MAX_OUT_QUEUE_SIZE)
126
-
127
- def task() -> None:
128
- _async_diff_dir_walk_task(src, dst, max_depth, out_queue, reverse=reverse)
129
-
130
- worker = Thread(
131
- target=task,
132
- daemon=True,
133
- )
134
- worker.start()
135
-
136
- while dirlisting := out_queue.get():
137
- if dirlisting is None:
138
- break
139
- yield dirlisting
140
-
141
- worker.join()
142
- except KeyboardInterrupt:
143
- pass
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes