rclone-api 1.5.36__py3-none-any.whl → 1.5.37__py3-none-any.whl

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.
rclone_api/fs.py CHANGED
@@ -31,7 +31,8 @@ class FS(abc.ABC):
31
31
  pass
32
32
 
33
33
  @abc.abstractmethod
34
- def ls(self, path: Path | str) -> list[str]:
34
+ def ls(self, path: Path | str) -> tuple[list[str], list[str]]:
35
+ """First is files and second is directories."""
35
36
  pass
36
37
 
37
38
  @abc.abstractmethod
@@ -57,8 +58,11 @@ class RealFS(FS):
57
58
  def __init__(self) -> None:
58
59
  super().__init__()
59
60
 
60
- def ls(self, path: Path | str) -> list[str]:
61
- return [str(p) for p in Path(path).iterdir()]
61
+ def ls(self, path: Path | str) -> tuple[list[str], list[str]]:
62
+ files_and_dirs = [str(p) for p in Path(path).iterdir()]
63
+ files = [f for f in files_and_dirs if Path(f).is_file()]
64
+ dirs = [d for d in files_and_dirs if Path(d).is_dir()]
65
+ return files, dirs
62
66
 
63
67
  def cwd(self) -> "FSPath":
64
68
  return RealFS.from_path(Path.cwd())
@@ -176,7 +180,7 @@ class RemoteFS(FS):
176
180
  # Make faster.
177
181
  return isinstance(err, Exception) and self.exists(path)
178
182
 
179
- def ls(self, path: Path | str) -> list[str]:
183
+ def ls(self, path: Path | str) -> tuple[list[str], list[str]]:
180
184
  from rclone_api.http_server import HttpServer
181
185
 
182
186
  assert isinstance(self.server, HttpServer)
@@ -259,13 +263,17 @@ class FSPath:
259
263
  assert isinstance(self.fs, RealFS)
260
264
  shutil.rmtree(self.path, ignore_errors=ignore_errors)
261
265
 
262
- def lspaths(self) -> "list[FSPath]":
263
- names: list[str] = self.ls()
264
- return [self / name for name in names]
265
-
266
- def ls(self) -> list[str]:
267
- names: list[str] = self.fs.ls(self.path)
268
- return names
266
+ def lspaths(self) -> "tuple[list[FSPath], list[FSPath]]":
267
+ filenames, dirnames = self.ls()
268
+ fpaths: list[FSPath] = [self / name for name in filenames]
269
+ dpaths: list[FSPath] = [self / name for name in dirnames]
270
+ return fpaths, dpaths
271
+
272
+ def ls(self) -> tuple[list[str], list[str]]:
273
+ filenames: list[str]
274
+ dirnames: list[str]
275
+ filenames, dirnames = self.fs.ls(self.path)
276
+ return filenames, dirnames
269
277
 
270
278
  @property
271
279
  def name(self) -> str:
rclone_api/http_server.py CHANGED
@@ -6,6 +6,7 @@ import tempfile
6
6
  import time
7
7
  import warnings
8
8
  from concurrent.futures import Future, ThreadPoolExecutor
9
+ from dataclasses import dataclass
9
10
  from pathlib import Path
10
11
  from threading import Semaphore
11
12
  from typing import Any
@@ -24,9 +25,16 @@ _PUT_WARNED = False
24
25
  _range = range
25
26
 
26
27
 
27
- def _parse_files(html: str) -> list[str]:
28
+ @dataclass
29
+ class FileList:
30
+ dirs: list[str]
31
+ files: list[str]
32
+
33
+
34
+ def _parse_files_and_dirs(html: str) -> FileList:
28
35
  soup = BeautifulSoup(html, "html.parser")
29
36
  files = []
37
+ dirs = []
30
38
  # Find each table row with class "file"
31
39
  for tr in soup.find_all("tr", class_="file"):
32
40
  name_span = tr.find("span", class_="name") # type: ignore
@@ -38,9 +46,14 @@ def _parse_files(html: str) -> list[str]:
38
46
  # Get the text from the <a> tag
39
47
  file_name = a_tag.get_text(strip=True) # type: ignore
40
48
  # Skip directories (they end with a slash)
41
- if not file_name.endswith("/"):
49
+ # if not file_name.endswith("/"):
50
+ # files.append(file_name)
51
+ # files.append(file_name)
52
+ if file_name.endswith("/"):
53
+ dirs.append(file_name)
54
+ else:
42
55
  files.append(file_name)
43
- return files
56
+ return FileList(dirs=dirs, files=files)
44
57
 
45
58
 
46
59
  class HttpServer:
@@ -125,7 +138,7 @@ class HttpServer:
125
138
 
126
139
  # curl "http://localhost:5572/?list"
127
140
 
128
- def list(self, path: str) -> list[str] | Exception:
141
+ def list(self, path: str) -> tuple[list[str], list[str]] | Exception:
129
142
  """List files on the server."""
130
143
 
131
144
  try:
@@ -136,7 +149,8 @@ class HttpServer:
136
149
  url += "/?list"
137
150
  response = httpx.get(url, timeout=_TIMEOUT)
138
151
  response.raise_for_status()
139
- return _parse_files(response.content.decode())
152
+ files_and_dirs = _parse_files_and_dirs(response.content.decode())
153
+ return files_and_dirs.dirs, files_and_dirs.files
140
154
  except Exception as e:
141
155
  warnings.warn(f"Failed to list files on {self.url}: {e}")
142
156
  return e
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rclone_api
3
- Version: 1.5.36
3
+ Version: 1.5.37
4
4
  Summary: rclone api in python
5
5
  Home-page: https://github.com/zackees/rclone-api
6
6
  License: BSD 3-Clause License
@@ -13,9 +13,9 @@ rclone_api/file_item.py,sha256=cH-AQYsxedhNPp4c8NHY1ad4Z7St4yf_VGbmiGD59no,1770
13
13
  rclone_api/file_part.py,sha256=i6ByS5_sae8Eba-4imBVTxd-xKC8ExWy7NR8QGr0ors,6155
14
14
  rclone_api/file_stream.py,sha256=_W3qnwCuigqA0hzXl2q5pAxSZDRaUSwet4BkT0lpnzs,1431
15
15
  rclone_api/filelist.py,sha256=xbiusvNgaB_b_kQOZoHMJJxn6TWGtPrWd2J042BI28o,767
16
- rclone_api/fs.py,sha256=eCiY6Jw8tVC1Kcfr0334Mj29BpeBNF7OtebAPLZdY-0,8386
16
+ rclone_api/fs.py,sha256=ldXOBsPg5I36FFUrEwFN1KbpVge5C4OywtoRTgBUfVw,8893
17
17
  rclone_api/group_files.py,sha256=H92xPW9lQnbNw5KbtZCl00bD6iRh9yRbCuxku4j_3dg,8036
18
- rclone_api/http_server.py,sha256=P7HQFneQ8f6i4H3_dgYVFS8DJca_GYaxVSBmz7lYC9Y,11704
18
+ rclone_api/http_server.py,sha256=F5_hwvcU8duU8u9oaHOiXpfDrEyOFvk311179UseVh8,12113
19
19
  rclone_api/install.py,sha256=Xb1BRn8rQcSpSd4dzmvIOELP2zM2DytUeIZ6jzv738A,2893
20
20
  rclone_api/log.py,sha256=VZHM7pNSXip2ZLBKMP7M1u-rp_F7zoafFDuR8CPUoKI,1271
21
21
  rclone_api/mount.py,sha256=LZqEhuKZunbWVqmsOIqkkCotaxWJpdFRS1InXveoU5E,1428
@@ -54,9 +54,9 @@ rclone_api/s3/multipart/upload_parts_inline.py,sha256=V7syKjFyVIe4U9Ahl5XgqVTzt9
54
54
  rclone_api/s3/multipart/upload_parts_resumable.py,sha256=6-nlMclS8jyVvMvFbQDcZOX9MY1WbCcKA_s9bwuYxnk,9793
55
55
  rclone_api/s3/multipart/upload_parts_server_side_merge.py,sha256=Fp2pdrs5dONQI9LkfNolgAGj1-Z2V1SsRd0r0sreuXI,18040
56
56
  rclone_api/s3/multipart/upload_state.py,sha256=f-Aq2NqtAaMUMhYitlICSNIxCKurWAl2gDEUVizLIqw,6019
57
- rclone_api-1.5.36.dist-info/licenses/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
58
- rclone_api-1.5.36.dist-info/METADATA,sha256=o7YKGtRzxdve9F1m3Y4CXoAsO52zKyk1KWbdw03IGYg,37155
59
- rclone_api-1.5.36.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
60
- rclone_api-1.5.36.dist-info/entry_points.txt,sha256=fJteOlYVwgX3UbNuL9jJ0zUTuX2O79JFAeNgK7Sw7EQ,255
61
- rclone_api-1.5.36.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
62
- rclone_api-1.5.36.dist-info/RECORD,,
57
+ rclone_api-1.5.37.dist-info/licenses/LICENSE,sha256=b6pOoifSXiUaz_lDS84vWlG3fr4yUKwB8fzkrH9R8bQ,1064
58
+ rclone_api-1.5.37.dist-info/METADATA,sha256=ICLEVml9U93fTILo5VC6P1CtM5qm7CMri1y3uFrbRTw,37155
59
+ rclone_api-1.5.37.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
60
+ rclone_api-1.5.37.dist-info/entry_points.txt,sha256=fJteOlYVwgX3UbNuL9jJ0zUTuX2O79JFAeNgK7Sw7EQ,255
61
+ rclone_api-1.5.37.dist-info/top_level.txt,sha256=EvZ7uuruUpe9RiUyEp25d1Keq7PWYNT0O_-mr8FCG5g,11
62
+ rclone_api-1.5.37.dist-info/RECORD,,