rclone-api 1.0.21__tar.gz → 1.0.23__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. {rclone_api-1.0.21 → rclone_api-1.0.23}/PKG-INFO +1 -1
  2. {rclone_api-1.0.21 → rclone_api-1.0.23}/pyproject.toml +4 -1
  3. rclone_api-1.0.23/src/rclone_api/cmd/list_files.py +27 -0
  4. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/rclone.py +3 -8
  5. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/util.py +15 -0
  6. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api.egg-info/PKG-INFO +1 -1
  7. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api.egg-info/SOURCES.txt +3 -0
  8. rclone_api-1.0.23/src/rclone_api.egg-info/entry_points.txt +2 -0
  9. rclone_api-1.0.23/tests/test_cmd_list_files.py +83 -0
  10. {rclone_api-1.0.21 → rclone_api-1.0.23}/.aiderignore +0 -0
  11. {rclone_api-1.0.21 → rclone_api-1.0.23}/.github/workflows/lint.yml +0 -0
  12. {rclone_api-1.0.21 → rclone_api-1.0.23}/.github/workflows/push_macos.yml +0 -0
  13. {rclone_api-1.0.21 → rclone_api-1.0.23}/.github/workflows/push_ubuntu.yml +0 -0
  14. {rclone_api-1.0.21 → rclone_api-1.0.23}/.github/workflows/push_win.yml +0 -0
  15. {rclone_api-1.0.21 → rclone_api-1.0.23}/.gitignore +0 -0
  16. {rclone_api-1.0.21 → rclone_api-1.0.23}/.pylintrc +0 -0
  17. {rclone_api-1.0.21 → rclone_api-1.0.23}/.vscode/launch.json +0 -0
  18. {rclone_api-1.0.21 → rclone_api-1.0.23}/.vscode/settings.json +0 -0
  19. {rclone_api-1.0.21 → rclone_api-1.0.23}/.vscode/tasks.json +0 -0
  20. {rclone_api-1.0.21 → rclone_api-1.0.23}/LICENSE +0 -0
  21. {rclone_api-1.0.21 → rclone_api-1.0.23}/MANIFEST.in +0 -0
  22. {rclone_api-1.0.21 → rclone_api-1.0.23}/README.md +0 -0
  23. {rclone_api-1.0.21 → rclone_api-1.0.23}/clean +0 -0
  24. {rclone_api-1.0.21 → rclone_api-1.0.23}/install +0 -0
  25. {rclone_api-1.0.21 → rclone_api-1.0.23}/lint +0 -0
  26. {rclone_api-1.0.21 → rclone_api-1.0.23}/requirements.testing.txt +0 -0
  27. {rclone_api-1.0.21 → rclone_api-1.0.23}/setup.cfg +0 -0
  28. {rclone_api-1.0.21 → rclone_api-1.0.23}/setup.py +0 -0
  29. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/__init__.py +0 -0
  30. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/assets/example.txt +0 -0
  31. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/cli.py +0 -0
  32. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/config.py +0 -0
  33. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/convert.py +0 -0
  34. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/dir.py +0 -0
  35. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/dir_listing.py +0 -0
  36. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/exec.py +0 -0
  37. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/file.py +0 -0
  38. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/filelist.py +0 -0
  39. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/process.py +0 -0
  40. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/remote.py +0 -0
  41. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/rpath.py +0 -0
  42. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api/walk.py +0 -0
  43. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api.egg-info/dependency_links.txt +0 -0
  44. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api.egg-info/requires.txt +0 -0
  45. {rclone_api-1.0.21 → rclone_api-1.0.23}/src/rclone_api.egg-info/top_level.txt +0 -0
  46. {rclone_api-1.0.21 → rclone_api-1.0.23}/test +0 -0
  47. {rclone_api-1.0.21 → rclone_api-1.0.23}/tests/test_copy.py +0 -0
  48. {rclone_api-1.0.21 → rclone_api-1.0.23}/tests/test_is_synced.py +0 -0
  49. {rclone_api-1.0.21 → rclone_api-1.0.23}/tests/test_ls.py +0 -0
  50. {rclone_api-1.0.21 → rclone_api-1.0.23}/tests/test_mount.py +0 -0
  51. {rclone_api-1.0.21 → rclone_api-1.0.23}/tests/test_mount_webdav.py +0 -0
  52. {rclone_api-1.0.21 → rclone_api-1.0.23}/tests/test_obscure.py +0 -0
  53. {rclone_api-1.0.21 → rclone_api-1.0.23}/tests/test_remotes.py +0 -0
  54. {rclone_api-1.0.21 → rclone_api-1.0.23}/tests/test_serve_webdav.py +0 -0
  55. {rclone_api-1.0.21 → rclone_api-1.0.23}/tests/test_walk.py +0 -0
  56. {rclone_api-1.0.21 → rclone_api-1.0.23}/tox.ini +0 -0
  57. {rclone_api-1.0.21 → rclone_api-1.0.23}/upload_package.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.21
3
+ Version: 1.0.23
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.21"
18
+ version = "1.0.23"
19
19
 
20
20
  [tool.setuptools]
21
21
  package-dir = {"" = "src"}
@@ -43,3 +43,6 @@ profile = "black"
43
43
  [tool.mypy]
44
44
  ignore_missing_imports = true
45
45
  disable_error_code = ["import-untyped"]
46
+
47
+ [project.scripts]
48
+ rclone-api-listfiles = "rclone_api.cmd.list_files:main"
@@ -0,0 +1,27 @@
1
+ import argparse
2
+ from pathlib import Path
3
+
4
+ from rclone_api import Rclone
5
+
6
+
7
+ def list_files(rclone: Rclone, path: str):
8
+ """List files in a remote path."""
9
+ for dirlisting in rclone.walk(path):
10
+ for file in dirlisting.files:
11
+ print(file.path)
12
+
13
+
14
+ def _parse_args() -> argparse.Namespace:
15
+ parser = argparse.ArgumentParser(description="List files in a remote path.")
16
+ parser.add_argument("--config", help="Path to rclone config file", required=True)
17
+ parser.add_argument("path", help="Remote path to list")
18
+ return parser.parse_args()
19
+
20
+
21
+ def main() -> int:
22
+ """Main entry point."""
23
+ args = _parse_args()
24
+ path = args.path
25
+ rclone = Rclone(Path(args.config))
26
+ list_files(rclone, path)
27
+ return 0
@@ -19,7 +19,7 @@ from rclone_api.file import File
19
19
  from rclone_api.process import Process
20
20
  from rclone_api.remote import Remote
21
21
  from rclone_api.rpath import RPath
22
- from rclone_api.util import get_rclone_exe, to_path
22
+ from rclone_api.util import get_rclone_exe, to_path, wait_for_mount
23
23
  from rclone_api.walk import walk
24
24
 
25
25
 
@@ -291,9 +291,7 @@ class Rclone:
291
291
  if other_cmds:
292
292
  cmd_list += other_cmds
293
293
  proc = self._launch_process(cmd_list)
294
- time.sleep(2) # give it a moment to mount
295
- if proc.poll() is not None:
296
- raise ValueError("Mount process failed to start")
294
+ wait_for_mount(outdir, proc)
297
295
  return proc
298
296
 
299
297
  def mount_webdav(
@@ -330,10 +328,7 @@ class Rclone:
330
328
  if other_cmds:
331
329
  cmd_list += other_cmds
332
330
  proc = self._launch_process(cmd_list)
333
- # proc = rclone_exec.launch_process(cmd_list)
334
- time.sleep(2)
335
- if proc.poll() is not None:
336
- raise ValueError("Mount process failed to start")
331
+ wait_for_mount(outdir, proc)
337
332
  return proc
338
333
 
339
334
  def serve_webdav(
@@ -1,6 +1,7 @@
1
1
  import os
2
2
  import shutil
3
3
  import subprocess
4
+ import time
4
5
  from pathlib import Path
5
6
  from tempfile import TemporaryDirectory
6
7
  from typing import Any
@@ -112,3 +113,17 @@ def rclone_execute(
112
113
  tempdir.cleanup()
113
114
  except Exception as e:
114
115
  print(f"Error cleaning up tempdir: {e}")
116
+
117
+
118
+ def wait_for_mount(path: Path, mount_process: Any, timeout: int = 60) -> None:
119
+ from rclone_api.process import Process
120
+
121
+ assert isinstance(mount_process, Process)
122
+ expire_time = time.time() + timeout
123
+ while time.time() < expire_time:
124
+ rtn = mount_process.poll()
125
+ if rtn is not None:
126
+ raise subprocess.CalledProcessError(rtn, mount_process.cmd)
127
+ if path.exists():
128
+ return
129
+ raise TimeoutError(f"Path {path} did not exist after {timeout} seconds")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: rclone_api
3
- Version: 1.0.21
3
+ Version: 1.0.23
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  Maintainer: Zachary Vorhies
@@ -38,9 +38,12 @@ src/rclone_api/walk.py
38
38
  src/rclone_api.egg-info/PKG-INFO
39
39
  src/rclone_api.egg-info/SOURCES.txt
40
40
  src/rclone_api.egg-info/dependency_links.txt
41
+ src/rclone_api.egg-info/entry_points.txt
41
42
  src/rclone_api.egg-info/requires.txt
42
43
  src/rclone_api.egg-info/top_level.txt
43
44
  src/rclone_api/assets/example.txt
45
+ src/rclone_api/cmd/list_files.py
46
+ tests/test_cmd_list_files.py
44
47
  tests/test_copy.py
45
48
  tests/test_is_synced.py
46
49
  tests/test_ls.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ rclone-api-listfiles = rclone_api.cmd.list_files:main
@@ -0,0 +1,83 @@
1
+ """
2
+ Unit test file.
3
+ """
4
+
5
+ import os
6
+ import unittest
7
+
8
+ from dotenv import load_dotenv
9
+
10
+ from rclone_api import Config, Rclone, Remote
11
+ from rclone_api.cmd.list_files import list_files
12
+
13
+ load_dotenv()
14
+
15
+ BUCKET_NAME = os.getenv("BUCKET_NAME") # Default if not in .env
16
+
17
+
18
+ def _generate_rclone_config() -> Config:
19
+
20
+ # BUCKET_NAME = os.getenv("BUCKET_NAME", "TorrentBooks") # Default if not in .env
21
+
22
+ # Load additional environment variables
23
+ BUCKET_KEY_SECRET = os.getenv("BUCKET_KEY_SECRET")
24
+ BUCKET_KEY_PUBLIC = os.getenv("BUCKET_KEY_PUBLIC")
25
+ # BUCKET_URL = os.getenv("BUCKET_URL")
26
+ BUCKET_URL = "sfo3.digitaloceanspaces.com"
27
+
28
+ config_text = f"""
29
+ [dst]
30
+ type = s3
31
+ provider = DigitalOcean
32
+ access_key_id = {BUCKET_KEY_PUBLIC}
33
+ secret_access_key = {BUCKET_KEY_SECRET}
34
+ endpoint = {BUCKET_URL}
35
+ bucket = {BUCKET_NAME}
36
+ """
37
+
38
+ out = Config(config_text)
39
+ return out
40
+
41
+
42
+ class RcloneLsTests(unittest.TestCase):
43
+ """Test rclone functionality."""
44
+
45
+ def setUp(self) -> None:
46
+ """Check if all required environment variables are set before running tests."""
47
+ required_vars = [
48
+ "BUCKET_NAME",
49
+ "BUCKET_KEY_SECRET",
50
+ "BUCKET_KEY_PUBLIC",
51
+ "BUCKET_URL",
52
+ ]
53
+ missing = [var for var in required_vars if not os.getenv(var)]
54
+ if missing:
55
+ self.skipTest(
56
+ f"Missing required environment variables: {', '.join(missing)}"
57
+ )
58
+ os.environ["RCLONE_API_VERBOSE"] = "1"
59
+
60
+ def test_list_remotes(self) -> None:
61
+ rclone = Rclone(_generate_rclone_config())
62
+
63
+ remotes: list[Remote] = rclone.listremotes()
64
+ self.assertGreater(len(remotes), 0)
65
+ for remote in remotes:
66
+ self.assertIsInstance(remote, Remote)
67
+ print(remote)
68
+ print("done")
69
+
70
+ def test_cmd_list_files(self) -> None:
71
+ """Test listing the root directory of the bucket.
72
+
73
+ Verifies that we can:
74
+ 1. Connect to the bucket
75
+ 2. List its contents
76
+ 3. Get both directories and files as proper types
77
+ """
78
+ rclone = Rclone(_generate_rclone_config())
79
+ list_files(rclone, f"dst:{BUCKET_NAME}")
80
+
81
+
82
+ if __name__ == "__main__":
83
+ unittest.main()
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