lfss 0.12.1__tar.gz → 0.12.3__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 (52) hide show
  1. {lfss-0.12.1 → lfss-0.12.3}/PKG-INFO +10 -11
  2. {lfss-0.12.1 → lfss-0.12.3}/Readme.md +1 -1
  3. {lfss-0.12.1 → lfss-0.12.3}/docs/Client.md +1 -2
  4. {lfss-0.12.1 → lfss-0.12.3}/docs/changelog.md +9 -0
  5. {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/cli.py +30 -20
  6. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/utils.py +5 -1
  7. {lfss-0.12.1 → lfss-0.12.3}/pyproject.toml +11 -10
  8. {lfss-0.12.1 → lfss-0.12.3}/docs/Enviroment_variables.md +0 -0
  9. {lfss-0.12.1 → lfss-0.12.3}/docs/Known_issues.md +0 -0
  10. {lfss-0.12.1 → lfss-0.12.3}/docs/Permission.md +0 -0
  11. {lfss-0.12.1 → lfss-0.12.3}/docs/Webdav.md +0 -0
  12. {lfss-0.12.1 → lfss-0.12.3}/frontend/api.js +0 -0
  13. {lfss-0.12.1 → lfss-0.12.3}/frontend/index.html +0 -0
  14. {lfss-0.12.1 → lfss-0.12.3}/frontend/info.css +0 -0
  15. {lfss-0.12.1 → lfss-0.12.3}/frontend/info.js +0 -0
  16. {lfss-0.12.1 → lfss-0.12.3}/frontend/login.css +0 -0
  17. {lfss-0.12.1 → lfss-0.12.3}/frontend/login.js +0 -0
  18. {lfss-0.12.1 → lfss-0.12.3}/frontend/popup.css +0 -0
  19. {lfss-0.12.1 → lfss-0.12.3}/frontend/popup.js +0 -0
  20. {lfss-0.12.1 → lfss-0.12.3}/frontend/scripts.js +0 -0
  21. {lfss-0.12.1 → lfss-0.12.3}/frontend/state.js +0 -0
  22. {lfss-0.12.1 → lfss-0.12.3}/frontend/styles.css +0 -0
  23. {lfss-0.12.1 → lfss-0.12.3}/frontend/thumb.css +0 -0
  24. {lfss-0.12.1 → lfss-0.12.3}/frontend/thumb.js +0 -0
  25. {lfss-0.12.1 → lfss-0.12.3}/frontend/utils.js +0 -0
  26. {lfss-0.12.1 → lfss-0.12.3}/lfss/api/__init__.py +0 -0
  27. {lfss-0.12.1 → lfss-0.12.3}/lfss/api/connector.py +0 -0
  28. {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/__init__.py +0 -0
  29. {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/balance.py +0 -0
  30. {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/cli_lib.py +0 -0
  31. {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/log.py +0 -0
  32. {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/panel.py +0 -0
  33. {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/serve.py +0 -0
  34. {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/user.py +0 -0
  35. {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/vacuum.py +0 -0
  36. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/__init__.py +0 -0
  37. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/bounded_pool.py +0 -0
  38. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/config.py +0 -0
  39. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/connection_pool.py +0 -0
  40. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/database.py +0 -0
  41. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/datatype.py +0 -0
  42. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/error.py +0 -0
  43. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/log.py +0 -0
  44. {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/thumb.py +0 -0
  45. {lfss-0.12.1 → lfss-0.12.3}/lfss/sql/init.sql +0 -0
  46. {lfss-0.12.1 → lfss-0.12.3}/lfss/sql/pragma.sql +0 -0
  47. {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/app.py +0 -0
  48. {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/app_base.py +0 -0
  49. {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/app_dav.py +0 -0
  50. {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/app_native.py +0 -0
  51. {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/common_impl.py +0 -0
  52. {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/request_log.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lfss
3
- Version: 0.12.1
3
+ Version: 0.12.3
4
4
  Summary: Lite file storage service
5
5
  Home-page: https://github.com/MenxLi/lfss
6
6
  Author: Li, Mengxun
@@ -10,16 +10,15 @@ Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Programming Language :: Python :: 3.10
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
- Requires-Dist: aiofiles (==24.*)
14
- Requires-Dist: aiosqlite (==0.*)
15
- Requires-Dist: fastapi (==0.*)
16
- Requires-Dist: mimesniff (==1.*)
17
- Requires-Dist: pillow
18
- Requires-Dist: python-multipart
13
+ Provides-Extra: all
14
+ Requires-Dist: aiofiles (==24.*) ; extra == "all"
15
+ Requires-Dist: aiosqlite (==0.*) ; extra == "all"
16
+ Requires-Dist: fastapi[standard] (==0.*) ; extra == "all"
17
+ Requires-Dist: mimesniff (==1.*) ; extra == "all"
18
+ Requires-Dist: pillow ; extra == "all"
19
19
  Requires-Dist: requests (==2.*)
20
- Requires-Dist: rich
21
- Requires-Dist: stream-zip (==0.*)
22
- Requires-Dist: uvicorn (==0.*)
20
+ Requires-Dist: rich ; extra == "all"
21
+ Requires-Dist: stream-zip (==0.*) ; extra == "all"
23
22
  Project-URL: Repository, https://github.com/MenxLi/lfss
24
23
  Description-Content-Type: text/markdown
25
24
 
@@ -41,7 +40,7 @@ Tested on 2 million files, and it is still fast.
41
40
 
42
41
  Usage:
43
42
  ```sh
44
- pip install lfss
43
+ pip install "lfss[all]"
45
44
  lfss-user add <username> <password>
46
45
  lfss-serve
47
46
  ```
@@ -16,7 +16,7 @@ Tested on 2 million files, and it is still fast.
16
16
 
17
17
  Usage:
18
18
  ```sh
19
- pip install lfss
19
+ pip install "lfss[all]"
20
20
  lfss-user add <username> <password>
21
21
  lfss-serve
22
22
  ```
@@ -3,8 +3,7 @@
3
3
 
4
4
  To install python CLI tools without dependencies (to avoid conflicts with your existing packages):
5
5
  ```sh
6
- pip install requests
7
- pip install lfss --no-deps
6
+ pip install lfss
8
7
  ```
9
8
 
10
9
  Then set the `LFSS_ENDPOINT`, `LFSS_TOKEN` environment variables,
@@ -1,5 +1,14 @@
1
1
  ## 0.12
2
2
 
3
+ ### 0.12.3
4
+ - Show partial list hint
5
+ - Delete command alias `rm`
6
+ - Fix download single file with overwrite option
7
+
8
+ ### 0.12.2
9
+ - Setup optional dependencies
10
+ - Present only the name by default for CLI list command
11
+
3
12
  ### 0.12.1
4
13
  - Add `cat` command
5
14
  - Use unicode icons for CLI list command
@@ -55,14 +55,18 @@ def print_path_list(
55
55
  print("[F]", end=" ")
56
56
  case _:
57
57
  print("[?]", end=" ")
58
- print(decode_uri_components(r.url), end="")
59
- if detailed:
60
- if isinstance(r, FileRecord):
61
- print(f" | {fmt_storage_size(r.file_size)}, permission={r.permission.name}, created={r.create_time}, accessed={r.access_time}")
58
+ # if not detailed, only print name
59
+ if not detailed:
60
+ if isinstance(r, DirectoryRecord):
61
+ assert r.url.endswith("/")
62
+ print(decode_uri_components(r.url).rstrip("/").split("/")[-1], end="/")
62
63
  else:
63
- print()
64
+ print(decode_uri_components(r.url).split("/")[-1], end="")
64
65
  else:
65
- print()
66
+ print(decode_uri_components(r.url), end="")
67
+ if isinstance(r, FileRecord):
68
+ print(f" :: {fmt_storage_size(r.file_size)} {r.permission.name}", end="")
69
+ print()
66
70
 
67
71
  for d in line_sep(dirs, end=False):
68
72
  print_ln(d)
@@ -108,7 +112,7 @@ def parse_arguments():
108
112
  sp_query.add_argument("path", help="Path to query", nargs="+", type=str)
109
113
 
110
114
  # delete
111
- sp_delete = sp.add_parser("delete", help="Delete files or directories", aliases=["del"])
115
+ sp_delete = sp.add_parser("delete", help="Delete files or directories", aliases=["del", "rm"])
112
116
  sp_delete.add_argument("path", help="Path to delete", nargs="+", type=str)
113
117
  sp_delete.add_argument("-y", "--yes", action="store_true", help="Confirm deletion without prompt")
114
118
 
@@ -117,7 +121,7 @@ def parse_arguments():
117
121
  sp_list.add_argument("path", help="Path to list", type=str)
118
122
  sp_list.add_argument("--offset", type=int, default=0, help="Offset of the list")
119
123
  sp_list.add_argument("--limit", type=int, default=100, help="Limit of the list")
120
- sp_list.add_argument("-l", "--long", action="store_true", help="Detailed list, including all metadata")
124
+ sp_list.add_argument("-l", "--long", action="store_true", help="Detailed list")
121
125
  sp_list.add_argument("--order", "--order-by", type=str, help="Order of the list", default="", choices=typing.get_args(FileSortKey))
122
126
  sp_list.add_argument("--reverse", "--order-desc", action="store_true", help="Reverse the list order")
123
127
 
@@ -126,7 +130,7 @@ def parse_arguments():
126
130
  sp_list_d.add_argument("path", help="Path to list", type=str)
127
131
  sp_list_d.add_argument("--offset", type=int, default=0, help="Offset of the list")
128
132
  sp_list_d.add_argument("--limit", type=int, default=100, help="Limit of the list")
129
- sp_list_d.add_argument("-l", "--long", action="store_true", help="Detailed list, including all metadata")
133
+ sp_list_d.add_argument("-l", "--long", action="store_true", help="Detailed list")
130
134
  sp_list_d.add_argument("--order", "--order-by", type=str, help="Order of the list", default="", choices=typing.get_args(DirSortKey))
131
135
  sp_list_d.add_argument("--reverse", "--order-desc", action="store_true", help="Reverse the list order")
132
136
 
@@ -136,7 +140,7 @@ def parse_arguments():
136
140
  sp_list_f.add_argument("--offset", type=int, default=0, help="Offset of the list")
137
141
  sp_list_f.add_argument("--limit", type=int, default=100, help="Limit of the list")
138
142
  sp_list_f.add_argument("-r", "--recursive", "--flat", action="store_true", help="List files recursively")
139
- sp_list_f.add_argument("-l", "--long", action="store_true", help="Detailed list, including all metadata")
143
+ sp_list_f.add_argument("-l", "--long", action="store_true", help="Detailed list")
140
144
  sp_list_f.add_argument("--order", "--order-by", type=str, help="Order of the list", default="", choices=typing.get_args(FileSortKey))
141
145
  sp_list_f.add_argument("--reverse", "--order-desc", action="store_true", help="Reverse the list order")
142
146
 
@@ -223,12 +227,12 @@ def main():
223
227
  verbose=not args.quiet,
224
228
  n_retries=args.retries,
225
229
  interval=args.interval,
226
- overwrite=args.overwrite
230
+ overwrite=args.conflict == "overwrite"
227
231
  )
228
232
  if not success:
229
233
  print("\033[91mFailed to download: \033[0m", msg, file=sys.stderr)
230
-
231
- elif args.command in ["delete", "del"]:
234
+
235
+ elif args.command in ["delete", "del", "rm"]:
232
236
  if not args.yes:
233
237
  print("You are about to delete the following paths:")
234
238
  for path in args.path:
@@ -261,9 +265,10 @@ def main():
261
265
  order_desc=args.reverse,
262
266
  )
263
267
  print_path_list(res, detailed=args.long)
264
- if len(res.dirs) + len(res.files) == args.limit:
265
- print(f"\033[33m[Warning] List limit reached, use --offset and --limit to list more items.\033[0m")
266
-
268
+ if args.path != "/" and len(res.dirs) + len(res.files) == args.limit:
269
+ _len_str = f"{args.offset + 1}-{args.offset + len(res.dirs) + len(res.files)}/{connector.count_dirs(args.path) + connector.count_files(args.path)}"
270
+ print(f"{_len_str} items listed.")
271
+
267
272
  elif args.command in ["lsf", "list-f"]:
268
273
  with catch_request_error(default_error_handler_dict(args.path)):
269
274
  res = connector.list_files(
@@ -275,8 +280,12 @@ def main():
275
280
  order_desc=args.reverse,
276
281
  )
277
282
  print_path_list(res, detailed=args.long)
278
- if len(res) == args.limit:
279
- print(f"\033[33m[Warning] List limit reached, use --offset and --limit to list more files.\033[0m")
283
+ if args.path != "/" and len(res) == args.limit:
284
+ if args.recursive:
285
+ _len_str = f"{args.offset + 1}-{args.offset + len(res)}/{connector.count_files(args.path, flat=True)}"
286
+ else:
287
+ _len_str = f"{args.offset + 1}-{args.offset + len(res)}/{connector.count_files(args.path)}"
288
+ print(f"{_len_str} files listed.")
280
289
 
281
290
  elif args.command in ["lsd", "list-d"]:
282
291
  with catch_request_error(default_error_handler_dict(args.path)):
@@ -289,8 +298,9 @@ def main():
289
298
  order_desc=args.reverse,
290
299
  )
291
300
  print_path_list(res, detailed=args.long)
292
- if len(res) == args.limit:
293
- print(f"\033[33m[Warning] List limit reached, use --offset and --limit to list more directories.\033[0m")
301
+ if args.path != "/" and len(res) == args.limit:
302
+ _len_str = f"{args.offset + 1}-{args.offset + len(res)}/{connector.count_dirs(args.path)}"
303
+ print(f"{_len_str} items listed.")
294
304
 
295
305
  elif args.command in ["cat", "concatenate"]:
296
306
  for _p in args.path:
@@ -3,7 +3,6 @@ import urllib.parse
3
3
  import pathlib
4
4
  import functools
5
5
  import hashlib
6
- import aiofiles
7
6
  import asyncio
8
7
  from asyncio import Lock
9
8
  from collections import OrderedDict
@@ -11,6 +10,11 @@ from concurrent.futures import ThreadPoolExecutor
11
10
  from typing import TypeVar, Callable, Awaitable
12
11
  from functools import wraps, partial
13
12
  from uuid import uuid4
13
+ try:
14
+ # optional dependency for client-side
15
+ import aiofiles
16
+ except ImportError:
17
+ pass
14
18
 
15
19
  async def copy_file(source: str|pathlib.Path, destination: str|pathlib.Path):
16
20
  async with aiofiles.open(source, mode='rb') as src:
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "lfss"
3
- version = "0.12.1"
3
+ version = "0.12.3"
4
4
  description = "Lite file storage service"
5
5
  authors = ["Li, Mengxun <mengxunli@whu.edu.cn>"]
6
6
  readme = "Readme.md"
@@ -11,15 +11,16 @@ include = ["Readme.md", "docs/*", "frontend/*", "lfss/sql/*"]
11
11
  [tool.poetry.dependencies]
12
12
  python = ">=3.10" # PEP-622
13
13
  requests = "2.*"
14
- aiosqlite = "0.*"
15
- aiofiles = "24.*"
16
- mimesniff = "1.*"
17
- fastapi = "0.*"
18
- uvicorn = "0.*"
19
- stream-zip = "0.*"
20
- python-multipart = "*"
21
- pillow = "*"
22
- rich = "*"
14
+ aiosqlite = {"version" = "0.*", "optional" = true}
15
+ aiofiles = {"version" = "24.*", "optional" = true}
16
+ mimesniff = {"version" = "1.*", "optional" = true}
17
+ stream-zip = {"version" = "0.*", "optional" = true}
18
+ pillow = {"version" = "*", "optional" = true}
19
+ rich = {"version" = "*", "optional" = true}
20
+ fastapi = {"version" = "0.*", "optional" = true, "extras" = ["standard"]}
21
+
22
+ [tool.poetry.extras]
23
+ all = ["aiosqlite", "aiofiles", "mimesniff", "fastapi", "stream-zip", "pillow", "rich"]
23
24
 
24
25
  [tool.poetry.dev-dependencies]
25
26
  pytest = "*"
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
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
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
File without changes
File without changes
File without changes
File without changes
File without changes