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.
- {lfss-0.12.1 → lfss-0.12.3}/PKG-INFO +10 -11
- {lfss-0.12.1 → lfss-0.12.3}/Readme.md +1 -1
- {lfss-0.12.1 → lfss-0.12.3}/docs/Client.md +1 -2
- {lfss-0.12.1 → lfss-0.12.3}/docs/changelog.md +9 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/cli.py +30 -20
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/utils.py +5 -1
- {lfss-0.12.1 → lfss-0.12.3}/pyproject.toml +11 -10
- {lfss-0.12.1 → lfss-0.12.3}/docs/Enviroment_variables.md +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/docs/Known_issues.md +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/docs/Permission.md +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/docs/Webdav.md +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/api.js +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/index.html +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/info.css +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/info.js +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/login.css +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/login.js +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/popup.css +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/popup.js +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/scripts.js +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/state.js +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/styles.css +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/thumb.css +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/thumb.js +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/frontend/utils.js +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/api/__init__.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/api/connector.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/__init__.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/balance.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/cli_lib.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/log.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/panel.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/serve.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/user.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/cli/vacuum.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/__init__.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/bounded_pool.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/config.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/connection_pool.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/database.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/datatype.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/error.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/log.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/eng/thumb.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/sql/init.sql +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/sql/pragma.sql +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/app.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/app_base.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/app_dav.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/app_native.py +0 -0
- {lfss-0.12.1 → lfss-0.12.3}/lfss/svc/common_impl.py +0 -0
- {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.
|
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
|
-
|
14
|
-
Requires-Dist:
|
15
|
-
Requires-Dist:
|
16
|
-
Requires-Dist:
|
17
|
-
Requires-Dist:
|
18
|
-
Requires-Dist:
|
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
|
```
|
@@ -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
|
-
|
59
|
-
if detailed:
|
60
|
-
if isinstance(r,
|
61
|
-
|
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
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
File without changes
|