p115client 0.0.5.5.4.1__tar.gz → 0.0.5.5.5__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 (22) hide show
  1. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/PKG-INFO +1 -1
  2. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/client.py +31 -12
  3. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/download.py +1 -1
  4. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/iterdir.py +2 -119
  5. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/life.py +2 -1
  6. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/pyproject.toml +1 -1
  7. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/LICENSE +0 -0
  8. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/__init__.py +0 -0
  9. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/_upload.py +0 -0
  10. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/const.py +0 -0
  11. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/exception.py +0 -0
  12. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/py.typed +0 -0
  13. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/__init__.py +0 -0
  14. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/edit.py +0 -0
  15. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/export_dir.py +0 -0
  16. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/fs_files.py +0 -0
  17. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/pool.py +0 -0
  18. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/request.py +0 -0
  19. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/upload.py +0 -0
  20. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/tool/xys.py +0 -0
  21. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/p115client/type.py +0 -0
  22. {p115client-0.0.5.5.4.1 → p115client-0.0.5.5.5}/readme.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: p115client
3
- Version: 0.0.5.5.4.1
3
+ Version: 0.0.5.5.5
4
4
  Summary: Python 115 webdisk client.
5
5
  Home-page: https://github.com/ChenyangGao/p115client
6
6
  License: MIT
@@ -6922,13 +6922,13 @@ class P115Client:
6922
6922
 
6923
6923
  - 全部: 0
6924
6924
  - ??: 1
6925
- - ??: 2
6925
+ - 离线下载: 2
6926
6926
  - 播放视频: 3
6927
6927
  - 上传: 4
6928
6928
  - ??: 5
6929
6929
  - ??: 6
6930
6930
  - 接收: 7
6931
- - 移入: 8
6931
+ - 移动: 8
6932
6932
 
6933
6933
  - with_file: 0 | 1 = 0
6934
6934
  """
@@ -7077,13 +7077,13 @@ class P115Client:
7077
7077
 
7078
7078
  - 全部: 0
7079
7079
  - ??: 1
7080
- - ??: 2
7080
+ - 离线下载: 2
7081
7081
  - 播放视频: 3
7082
7082
  - 上传: 4
7083
7083
  - ??: 5
7084
7084
  - ??: 6
7085
7085
  - 接收: 7
7086
- - 移入: 8
7086
+ - 移动: 8
7087
7087
 
7088
7088
  - with_file: 0 | 1 = 0
7089
7089
  """
@@ -7141,9 +7141,9 @@ class P115Client:
7141
7141
  - 播放视频: 3
7142
7142
  - 上传: 4
7143
7143
  - ??: 5
7144
- - ??: 6(似乎和离线下载有关)
7144
+ - ??: 6
7145
7145
  - 接收: 7
7146
- - 移入: 8
7146
+ - 移动: 8
7147
7147
  """
7148
7148
  api = complete_webapi("/history/list", base_url=base_url)
7149
7149
  if isinstance(payload, (int, str)):
@@ -7202,9 +7202,9 @@ class P115Client:
7202
7202
  - 播放视频: 3
7203
7203
  - 上传: 4
7204
7204
  - ??: 5
7205
- - ??: 6(似乎和离线下载有关)
7205
+ - ??: 6
7206
7206
  - 接收: 7
7207
- - 移入: 8
7207
+ - 移动: 8
7208
7208
  """
7209
7209
  api = complete_proapi("/history/list", base_url, app)
7210
7210
  if isinstance(payload, (int, str)):
@@ -8382,6 +8382,13 @@ class P115Client:
8382
8382
 
8383
8383
  POST https://webapi.115.com/files/move
8384
8384
 
8385
+ .. caution::
8386
+ 你可以把文件或目录移动到其它目录 id 下,即使是不存在的 id
8387
+
8388
+ 因此,我定义了一个概念,悬空节点,此节点的 aid=1,但它有一个祖先节点,要么不存在,要么 aid != 1
8389
+
8390
+ 你可以用 `P115Client.tool_space` 方法,使用【校验空间】功能,把所有悬空节点找出来,放到根目录下的【修复文件】目录,此接口一天只能用一次
8391
+
8385
8392
  :payload:
8386
8393
  - fid: int | str 💡 文件或目录 id,只接受单个 id
8387
8394
  - fid[]: int | str
@@ -8407,8 +8414,9 @@ class P115Client:
8407
8414
  @overload
8408
8415
  def fs_move_app(
8409
8416
  self,
8410
- payload: dict,
8417
+ payload: int | str | dict | Iterable[int | str],
8411
8418
  /,
8419
+ pid: int = 0,
8412
8420
  app: str = "android",
8413
8421
  base_url: bool | str | Callable[[], str] = False,
8414
8422
  *,
@@ -8419,8 +8427,9 @@ class P115Client:
8419
8427
  @overload
8420
8428
  def fs_move_app(
8421
8429
  self,
8422
- payload: dict,
8430
+ payload: int | str | dict | Iterable[int | str],
8423
8431
  /,
8432
+ pid: int = 0,
8424
8433
  app: str = "android",
8425
8434
  base_url: bool | str | Callable[[], str] = False,
8426
8435
  *,
@@ -8430,8 +8439,9 @@ class P115Client:
8430
8439
  ...
8431
8440
  def fs_move_app(
8432
8441
  self,
8433
- payload: dict,
8442
+ payload: int | str | dict | Iterable[int | str],
8434
8443
  /,
8444
+ pid: int = 0,
8435
8445
  app: str = "android",
8436
8446
  base_url: bool | str | Callable[[], str] = False,
8437
8447
  *,
@@ -8448,7 +8458,16 @@ class P115Client:
8448
8458
  - user_id: int | str = <default> 💡 不用管
8449
8459
  """
8450
8460
  api = complete_proapi("/files/move", base_url, app)
8451
- payload = dict(payload, user_id=self.user_id)
8461
+ if isinstance(payload, (int, str)):
8462
+ payload = {"ids": payload, "user_id": self.user_id}
8463
+ elif isinstance(payload, dict):
8464
+ payload = dict(payload, user_id=self.user_id)
8465
+ else:
8466
+ payload = {f"fid[{i}]": fid for i, fid in enumerate(payload)}
8467
+ if not payload:
8468
+ return {"state": False, "message": "no op"}
8469
+ payload["user_id"] = self.user_id
8470
+ payload.setdefault("pid", pid)
8452
8471
  return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
8453
8472
 
8454
8473
  @overload
@@ -1120,7 +1120,7 @@ def iter_download_nodes(
1120
1120
  """获取一个目录内所有的文件或者目录的信息(简略)
1121
1121
 
1122
1122
  :param client: 115 客户端或 cookies
1123
- :param pickcode: 目录的提取码
1123
+ :param pickcode: 目录的 提取码 或者 id
1124
1124
  :param files: 如果为 True,则只获取文件,否则只获取目录
1125
1125
  :param max_workers: 最大并发数,如果为 None 或 <= 0,则默认为 20
1126
1126
  :param async_: 是否异步
@@ -9,8 +9,8 @@ __all__ = [
9
9
  "iter_nodes_skim", "iter_stared_dirs_raw", "iter_stared_dirs", "ensure_attr_path",
10
10
  "ensure_attr_path_by_category_get", "iterdir_raw", "iterdir", "iterdir_limited",
11
11
  "iter_files_raw", "iter_files", "traverse_files", "iter_dupfiles", "iter_image_files",
12
- "iter_dangling_files", "share_extract_payload", "share_iterdir", "share_iter_files",
13
- "iter_selected_nodes", "iter_selected_nodes_by_pickcode", "iter_selected_nodes_using_category_get",
12
+ "share_extract_payload", "share_iterdir", "share_iter_files", "iter_selected_nodes",
13
+ "iter_selected_nodes_by_pickcode", "iter_selected_nodes_using_category_get",
14
14
  "iter_selected_nodes_using_edit", "iter_selected_nodes_using_star_event",
15
15
  "iter_selected_dirs_using_star", "iter_files_with_dirname", "iter_files_with_path",
16
16
  "iter_files_with_path_by_export_dir", "iter_parents_3_level", "iter_dir_nodes",
@@ -3040,123 +3040,6 @@ def iter_image_files(
3040
3040
  return run_gen_step_iter(gen_step, async_=async_)
3041
3041
 
3042
3042
 
3043
- @overload
3044
- def iter_dangling_files(
3045
- client: str | P115Client,
3046
- cid: int = 0,
3047
- page_size: int = 0,
3048
- suffix: str = "",
3049
- type: Literal[1, 2, 3, 4, 5, 6, 7, 99] = 99,
3050
- normalize_attr: Callable[[dict], dict] = normalize_attr,
3051
- app: str = "web",
3052
- *,
3053
- async_: Literal[False] = False,
3054
- **request_kwargs,
3055
- ) -> Iterator[dict]:
3056
- ...
3057
- @overload
3058
- def iter_dangling_files(
3059
- client: str | P115Client,
3060
- cid: int = 0,
3061
- page_size: int = 0,
3062
- suffix: str = "",
3063
- type: Literal[1, 2, 3, 4, 5, 6, 7, 99] = 99,
3064
- normalize_attr: Callable[[dict], dict] = normalize_attr,
3065
- app: str = "web",
3066
- *,
3067
- async_: Literal[True],
3068
- **request_kwargs,
3069
- ) -> AsyncIterator[dict]:
3070
- ...
3071
- def iter_dangling_files(
3072
- client: str | P115Client,
3073
- cid: int = 0,
3074
- page_size: int = 0,
3075
- suffix: str = "",
3076
- type: Literal[1, 2, 3, 4, 5, 6, 7, 99] = 99,
3077
- normalize_attr: Callable[[dict], dict] = normalize_attr,
3078
- app: str = "web",
3079
- *,
3080
- async_: Literal[False, True] = False,
3081
- **request_kwargs,
3082
- ) -> Iterator[dict] | AsyncIterator[dict]:
3083
- """找出所有悬空的文件,即所在的目录 id 不为 0 且不存在
3084
-
3085
- .. todo::
3086
- 实际上,广义的悬空,包括所有这样的文件或目录,它们的祖先节点中存在一个节点,这个节点的 id 目前不存在于网盘(可能被删除或移入回收站)
3087
-
3088
- .. danger::
3089
- 你可以用 `P115Client.fs_move` 方法,把文件或目录随意移动到任何目录 id 下,即使这个 id 不存在
3090
-
3091
- .. note::
3092
- 你可以用 `P115Client.tool_space` 方法,把所有悬空文件找出来,放到专门的目录中,但这个接口一天只能用一次
3093
-
3094
- :param client: 115 客户端或 cookies
3095
- :param cid: 目录 id
3096
- :param page_size: 分页大小
3097
- :param suffix: 后缀名(优先级高于 type)
3098
- :param type: 文件类型
3099
-
3100
- - 1: 文档
3101
- - 2: 图片
3102
- - 3: 音频
3103
- - 4: 视频
3104
- - 5: 压缩包
3105
- - 6: 应用
3106
- - 7: 书籍
3107
- - 99: 仅文件
3108
-
3109
- :param normalize_attr: 把数据进行转换处理,使之便于阅读
3110
- :param app: 使用某个 app (设备)的接口
3111
- :param async_: 是否异步
3112
- :param request_kwargs: 其它请求参数
3113
-
3114
- :return: 迭代器,返回此目录内的(仅文件)文件信息
3115
- """
3116
- if not isinstance(client, P115Client):
3117
- client = P115Client(client, check_for_relogin=True)
3118
- if page_size <= 0:
3119
- page_size = 10_000
3120
- elif page_size < 16:
3121
- page_size = 16
3122
- if app in ("", "web", "desktop", "harmony"):
3123
- fs_files: Callable = client.fs_files
3124
- else:
3125
- fs_files = partial(client.fs_files_app, app=app)
3126
- def gen_step():
3127
- na_cids: set[int] = set()
3128
- ok_cids: set[int] = set()
3129
- payload = {"cid": cid, "limit": page_size, "offset": 0, "suffix": suffix, "type": type}
3130
- while True:
3131
- resp = yield fs_files(payload, async_=async_, **request_kwargs)
3132
- if cid and int(resp["path"][-1]["cid"]) != cid:
3133
- break
3134
- if resp["offset"] != payload["offset"]:
3135
- break
3136
- t = tuple(map(_overview_attr, resp["data"]))
3137
- pids = {
3138
- pid for a in t
3139
- if (pid := a.parent_id) not in na_cids
3140
- and pid not in ok_cids
3141
- }
3142
- if pids:
3143
- if async_:
3144
- na_cids.update(iter_nodes_skim(client, pids, **request_kwargs))
3145
- else:
3146
- yield async_foreach(
3147
- na_cids.add,
3148
- iter_nodes_skim(client, pids, async_=True, **request_kwargs),
3149
- )
3150
- ok_cids |= pids - na_cids
3151
- for a, info in zip(t, resp["data"]):
3152
- if a.parent_id in na_cids:
3153
- yield Yield(normalize_attr(info), identity=True)
3154
- payload["offset"] += len(resp["data"]) # type: ignore
3155
- if payload["offset"] >= resp["count"]:
3156
- break
3157
- return run_gen_step_iter(gen_step, async_=async_)
3158
-
3159
-
3160
3043
  def share_extract_payload(link: str, /) -> SharePayload:
3161
3044
  """从链接中提取 share_code 和 receive_code
3162
3045
 
@@ -11,7 +11,7 @@ __doc__ = "这个模块提供了一些和 115 生活操作事件有关的函数"
11
11
  from asyncio import sleep as async_sleep
12
12
  from collections.abc import AsyncIterator, Container, Coroutine, Iterator
13
13
  from functools import partial
14
- from itertools import count
14
+ from itertools import count, cycle
15
15
  from time import time, sleep
16
16
  from typing import overload, Any, Final, Literal
17
17
 
@@ -243,6 +243,7 @@ def iter_life_behavior_once(
243
243
  if app in ("", "web", "desktop", "harmony"):
244
244
  life_behavior_detail = partial(client.life_behavior_detail, **request_kwargs)
245
245
  else:
246
+ request_kwargs.setdefault("base_url", cycle(("http://proapi.115.com", "https://proapi.115.com")).__next__)
246
247
  life_behavior_detail = partial(client.life_behavior_detail_app, app=app, **request_kwargs)
247
248
  if first_batch_size <= 0:
248
249
  first_batch_size = 64 if from_time or from_id else 1000
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "p115client"
3
- version = "0.0.5.5.4.1"
3
+ version = "0.0.5.5.5"
4
4
  description = "Python 115 webdisk client."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"
File without changes