nc-py-api 0.17.1__py3-none-any.whl → 0.18.0__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.
- nc_py_api/_session.py +2 -2
- nc_py_api/_version.py +1 -1
- nc_py_api/files/__init__.py +8 -2
- nc_py_api/files/files.py +8 -3
- nc_py_api/files/files_async.py +8 -3
- nc_py_api/users.py +2 -2
- nc_py_api/webhooks.py +15 -1
- {nc_py_api-0.17.1.dist-info → nc_py_api-0.18.0.dist-info}/METADATA +3 -3
- {nc_py_api-0.17.1.dist-info → nc_py_api-0.18.0.dist-info}/RECORD +12 -12
- {nc_py_api-0.17.1.dist-info → nc_py_api-0.18.0.dist-info}/licenses/AUTHORS +1 -0
- {nc_py_api-0.17.1.dist-info → nc_py_api-0.18.0.dist-info}/WHEEL +0 -0
- {nc_py_api-0.17.1.dist-info → nc_py_api-0.18.0.dist-info}/licenses/LICENSE.txt +0 -0
nc_py_api/_session.py
CHANGED
|
@@ -301,7 +301,7 @@ class NcSessionBasic(NcSessionBase, ABC):
|
|
|
301
301
|
|
|
302
302
|
def download2fp(self, url_path: str, fp, dav: bool, params=None, **kwargs):
|
|
303
303
|
adapter = self.adapter_dav if dav else self.adapter
|
|
304
|
-
with adapter.stream("GET", url_path, params=params) as response:
|
|
304
|
+
with adapter.stream("GET", url_path, params=params, headers=kwargs.get("headers")) as response:
|
|
305
305
|
check_error(response)
|
|
306
306
|
for data_chunk in response.iter_raw(chunk_size=kwargs.get("chunk_size", 5 * 1024 * 1024)):
|
|
307
307
|
fp.write(data_chunk)
|
|
@@ -425,7 +425,7 @@ class AsyncNcSessionBasic(NcSessionBase, ABC):
|
|
|
425
425
|
|
|
426
426
|
async def download2fp(self, url_path: str, fp, dav: bool, params=None, **kwargs):
|
|
427
427
|
adapter = self.adapter_dav if dav else self.adapter
|
|
428
|
-
async with adapter.stream("GET", url_path, params=params) as response:
|
|
428
|
+
async with adapter.stream("GET", url_path, params=params, headers=kwargs.get("headers")) as response:
|
|
429
429
|
check_error(response)
|
|
430
430
|
async for data_chunk in response.aiter_raw(chunk_size=kwargs.get("chunk_size", 5 * 1024 * 1024)):
|
|
431
431
|
fp.write(data_chunk)
|
nc_py_api/_version.py
CHANGED
nc_py_api/files/__init__.py
CHANGED
|
@@ -5,12 +5,18 @@ import datetime
|
|
|
5
5
|
import email.utils
|
|
6
6
|
import enum
|
|
7
7
|
import os
|
|
8
|
+
import re
|
|
8
9
|
import warnings
|
|
9
10
|
|
|
10
11
|
from pydantic import BaseModel
|
|
11
12
|
|
|
12
13
|
from .. import _misc
|
|
13
14
|
|
|
15
|
+
user_regex = re.compile(r"(?:files|trashbin|versions)/([^/]+)/")
|
|
16
|
+
"""Regex for evaluating user from full path string; instantiated once on import."""
|
|
17
|
+
user_path_regex = re.compile(r".*?(files|trashbin|versions)/([^/]+)/")
|
|
18
|
+
"""Regex for evaluating user path from full path string; instantiated once on import."""
|
|
19
|
+
|
|
14
20
|
|
|
15
21
|
class LockType(enum.IntEnum):
|
|
16
22
|
"""Nextcloud File Locks types."""
|
|
@@ -218,12 +224,12 @@ class FsNode:
|
|
|
218
224
|
@property
|
|
219
225
|
def user(self) -> str:
|
|
220
226
|
"""Returns user ID extracted from the `full_path`."""
|
|
221
|
-
return self.full_path
|
|
227
|
+
return user_regex.findall(self.full_path)[0]
|
|
222
228
|
|
|
223
229
|
@property
|
|
224
230
|
def user_path(self) -> str:
|
|
225
231
|
"""Returns path relative to the user's root directory."""
|
|
226
|
-
return
|
|
232
|
+
return user_path_regex.sub("", self.full_path, count=1)
|
|
227
233
|
|
|
228
234
|
@property
|
|
229
235
|
def is_shared(self) -> bool:
|
nc_py_api/files/files.py
CHANGED
|
@@ -115,9 +115,14 @@ class FilesAPI:
|
|
|
115
115
|
path = path.user_path if isinstance(path, FsNode) else path
|
|
116
116
|
result_path = local_path if local_path else os.path.basename(path)
|
|
117
117
|
with open(result_path, "wb") as fp:
|
|
118
|
-
self._session.
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
if self._session.nc_version["major"] >= 31:
|
|
119
|
+
full_path = dav_get_obj_path(self._session.user, path)
|
|
120
|
+
accept_header = f"application/{kwargs.get('format', 'zip')}"
|
|
121
|
+
self._session.download2fp(quote(full_path), fp, dav=True, headers={"Accept": accept_header})
|
|
122
|
+
else:
|
|
123
|
+
self._session.download2fp(
|
|
124
|
+
"/index.php/apps/files/ajax/download.php", fp, dav=False, params={"dir": path}, **kwargs
|
|
125
|
+
)
|
|
121
126
|
return Path(result_path)
|
|
122
127
|
|
|
123
128
|
def upload(self, path: str | FsNode, content: bytes | str) -> FsNode:
|
nc_py_api/files/files_async.py
CHANGED
|
@@ -119,9 +119,14 @@ class AsyncFilesAPI:
|
|
|
119
119
|
path = path.user_path if isinstance(path, FsNode) else path
|
|
120
120
|
result_path = local_path if local_path else os.path.basename(path)
|
|
121
121
|
with open(result_path, "wb") as fp:
|
|
122
|
-
await self._session.
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
if (await self._session.nc_version)["major"] >= 31:
|
|
123
|
+
full_path = dav_get_obj_path(await self._session.user, path)
|
|
124
|
+
accept_header = f"application/{kwargs.get('format', 'zip')}"
|
|
125
|
+
await self._session.download2fp(quote(full_path), fp, dav=True, headers={"Accept": accept_header})
|
|
126
|
+
else:
|
|
127
|
+
await self._session.download2fp(
|
|
128
|
+
"/index.php/apps/files/ajax/download.php", fp, dav=False, params={"dir": path}, **kwargs
|
|
129
|
+
)
|
|
125
130
|
return Path(result_path)
|
|
126
131
|
|
|
127
132
|
async def upload(self, path: str | FsNode, content: bytes | str) -> FsNode:
|
nc_py_api/users.py
CHANGED
|
@@ -369,8 +369,8 @@ class _AsyncUsersAPI:
|
|
|
369
369
|
|
|
370
370
|
|
|
371
371
|
def _create(user_id: str, display_name: str | None, **kwargs) -> dict[str, typing.Any]:
|
|
372
|
-
password = kwargs.get("password"
|
|
373
|
-
email = kwargs.get("email"
|
|
372
|
+
password = kwargs.get("password")
|
|
373
|
+
email = kwargs.get("email")
|
|
374
374
|
if not password and not email:
|
|
375
375
|
raise ValueError("Either password or email must be set")
|
|
376
376
|
data = {"userid": user_id}
|
nc_py_api/webhooks.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import dataclasses
|
|
4
4
|
|
|
5
5
|
from ._misc import clear_from_params_empty # , require_capabilities
|
|
6
|
-
from ._session import AsyncNcSessionBasic, NcSessionBasic
|
|
6
|
+
from ._session import AppConfig, AsyncNcSessionBasic, NcSessionBasic
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
@dataclasses.dataclass
|
|
@@ -140,6 +140,13 @@ class _WebhooksAPI:
|
|
|
140
140
|
def unregister(self, webhook_id: int) -> bool:
|
|
141
141
|
return self._session.ocs("DELETE", f"{self._ep_base}/{webhook_id}")
|
|
142
142
|
|
|
143
|
+
def unregister_all(self, appid: str = "") -> int:
|
|
144
|
+
if not appid and isinstance(self._session.cfg, AppConfig):
|
|
145
|
+
appid = self._session.cfg.app_name
|
|
146
|
+
else:
|
|
147
|
+
raise ValueError("The `appid` parameter cannot be empty for non-ExApp use.")
|
|
148
|
+
return self._session.ocs("DELETE", f"{self._ep_base}/byappid/{appid}")
|
|
149
|
+
|
|
143
150
|
|
|
144
151
|
class _AsyncWebhooksAPI:
|
|
145
152
|
"""The class provides the async application management API on the Nextcloud server."""
|
|
@@ -208,3 +215,10 @@ class _AsyncWebhooksAPI:
|
|
|
208
215
|
|
|
209
216
|
async def unregister(self, webhook_id: int) -> bool:
|
|
210
217
|
return await self._session.ocs("DELETE", f"{self._ep_base}/{webhook_id}")
|
|
218
|
+
|
|
219
|
+
async def unregister_all(self, appid: str = "") -> int:
|
|
220
|
+
if not appid and isinstance(self._session.cfg, AppConfig):
|
|
221
|
+
appid = self._session.cfg.app_name
|
|
222
|
+
else:
|
|
223
|
+
raise ValueError("The `appid` parameter cannot be empty for non-ExApp use.")
|
|
224
|
+
return await self._session.ocs("DELETE", f"{self._ep_base}/byappid/{appid}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: nc-py-api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.0
|
|
4
4
|
Summary: Nextcloud Python Framework
|
|
5
5
|
Project-URL: Changelog, https://github.com/cloud-py-api/nc_py_api/blob/main/CHANGELOG.md
|
|
6
6
|
Project-URL: Documentation, https://cloud-py-api.github.io/nc_py_api/
|
|
@@ -70,8 +70,8 @@ Requires-Dist: caldav==1.3.6; extra == 'docs'
|
|
|
70
70
|
Requires-Dist: sphinx-copybutton; extra == 'docs'
|
|
71
71
|
Requires-Dist: sphinx-inline-tabs; extra == 'docs'
|
|
72
72
|
Requires-Dist: sphinx-issues>=3.0.1; extra == 'docs'
|
|
73
|
-
Requires-Dist: sphinx-rtd-theme
|
|
74
|
-
Requires-Dist: sphinx
|
|
73
|
+
Requires-Dist: sphinx-rtd-theme<3; extra == 'docs'
|
|
74
|
+
Requires-Dist: sphinx<8; extra == 'docs'
|
|
75
75
|
Requires-Dist: uvicorn[standard]>=0.23.2; extra == 'docs'
|
|
76
76
|
Description-Content-Type: text/markdown
|
|
77
77
|
|
|
@@ -4,10 +4,10 @@ nc_py_api/_exceptions.py,sha256=7vbUECaLmD7RJBCU27t4fuP6NmQK6r4508u_gS4szhI,2298
|
|
|
4
4
|
nc_py_api/_misc.py,sha256=dUzCP9VmyhtICTsn1aexlFAYUioBm40k6Zh-YE5WwCY,3333
|
|
5
5
|
nc_py_api/_preferences.py,sha256=OtovFZuGHnHYKjdDjSnUappO795tW8Oxj7qVaejHWpQ,2479
|
|
6
6
|
nc_py_api/_preferences_ex.py,sha256=tThj6U0ZZMaBZ-jUkjrbaI0xDnafWsBowQKsC6gjOQs,7179
|
|
7
|
-
nc_py_api/_session.py,sha256=
|
|
7
|
+
nc_py_api/_session.py,sha256=ZD0TKrL-tOpxYtV6AO0cwRrYzbnjBr_ylCEUirrykjU,20242
|
|
8
8
|
nc_py_api/_talk_api.py,sha256=0Uo7OduYniuuX3UQPb468RyGJJ-PWBCgJ5HoPuz5Qa0,51068
|
|
9
9
|
nc_py_api/_theming.py,sha256=hTr3nuOemSuRFZaPy9iXNmBM7rDgQHECH43tHMWGqEY,1870
|
|
10
|
-
nc_py_api/_version.py,sha256=
|
|
10
|
+
nc_py_api/_version.py,sha256=t3qny54XTwpi3rVJqMS8yB4HNF5ZcqFIKiy_TGER6lQ,52
|
|
11
11
|
nc_py_api/activity.py,sha256=t9VDSnnaXRNOvALqOSGCeXSQZ-426pCOMSfQ96JHys4,9574
|
|
12
12
|
nc_py_api/apps.py,sha256=Us2y2lszdxXlD8t6kxwd5_Nrrmazc0EvZXIH9O-ol80,9315
|
|
13
13
|
nc_py_api/calendar.py,sha256=-T6CJ8cRbJZTLtxSEDWuuYpD29DMJGCTfLONmtxZV9w,1445
|
|
@@ -19,10 +19,10 @@ nc_py_api/options.py,sha256=K5co-fIfFVbwF6r3sqWsJF3cKgAbS2CjLAXdyTOkP9s,1717
|
|
|
19
19
|
nc_py_api/talk.py,sha256=OZFemYkDOaM6o4xAK3EvQbjMFiK75E5qnsCDyihIElg,29368
|
|
20
20
|
nc_py_api/talk_bot.py,sha256=_RuImwb3jYvUKX3ywcX095ucOjECCxsuc59heIxNoTM,16725
|
|
21
21
|
nc_py_api/user_status.py,sha256=I101nwYS8X1WvC8AnLa2f3qJUCPDPHrbq-ke0h1VT4E,13282
|
|
22
|
-
nc_py_api/users.py,sha256=
|
|
22
|
+
nc_py_api/users.py,sha256=SQG8Agplaxy7XJgguK-rxV-azpc-QdktbDmLmQtJkXo,15476
|
|
23
23
|
nc_py_api/users_groups.py,sha256=IPxw-Ks5NjCm6r8_HC9xmf3IYptH00ulITbp5iazhAo,6289
|
|
24
24
|
nc_py_api/weather_status.py,sha256=wAkjuJPjxc0Rxe4za0BzfwB0XeUmkCXoisJtTH3-qdQ,7582
|
|
25
|
-
nc_py_api/webhooks.py,sha256
|
|
25
|
+
nc_py_api/webhooks.py,sha256=14nAMy-tnOvmRnJbo42zUHyjX-z6kc9OMDUVKzNmplY,7769
|
|
26
26
|
nc_py_api/ex_app/__init__.py,sha256=hFbu6wTXs-wmjs1tavm_HYLwiqgrp7_qJe-stzCiqfI,692
|
|
27
27
|
nc_py_api/ex_app/defs.py,sha256=FaQInH3jLugKxDUqpwrXdkMT-lBxmoqWmXJXc11fa6A,727
|
|
28
28
|
nc_py_api/ex_app/events_listener.py,sha256=pgQ4hSQV39NuP9F9IDWxo0Qle6oG15-Ol2FlItnIBGY,4682
|
|
@@ -41,13 +41,13 @@ nc_py_api/ex_app/ui/resources.py,sha256=Vwx69oZ93Ouh6HJtGUqaKFUr4Reo74H4vT1YCpb-
|
|
|
41
41
|
nc_py_api/ex_app/ui/settings.py,sha256=f0R17lGhBfo2JQULVw_hFxhpfoPw_CW7vBu0Rb1ABJw,6623
|
|
42
42
|
nc_py_api/ex_app/ui/top_menu.py,sha256=oCgGtIoMYbp-5iN5aXEbT7Q88HtccR7hg6IBFgbbyX4,5118
|
|
43
43
|
nc_py_api/ex_app/ui/ui.py,sha256=OqFHKn6oIZli8T1wnv6YtQ4glNfeNb90WwGCvtWI1Z4,1632
|
|
44
|
-
nc_py_api/files/__init__.py,sha256=
|
|
44
|
+
nc_py_api/files/__init__.py,sha256=uSjqZyYAq9x3xOb_yz15KNNAcPo1PhbpPLtPz_ej-Eo,17303
|
|
45
45
|
nc_py_api/files/_files.py,sha256=_s_f8xbzQPEH2F2LNwomI9CxscYHryus1pMZ_vW00C4,13666
|
|
46
|
-
nc_py_api/files/files.py,sha256=
|
|
47
|
-
nc_py_api/files/files_async.py,sha256=
|
|
46
|
+
nc_py_api/files/files.py,sha256=6G4zONjnI7oSCUf4C79xrFV4QUYquxZDCLlpkGvME0M,24912
|
|
47
|
+
nc_py_api/files/files_async.py,sha256=nyDeWiGx_8CHuVrNThSgfZy0l-WlC4El-TzJONo0TsM,25773
|
|
48
48
|
nc_py_api/files/sharing.py,sha256=VRZCl-TYK6dbu9rUHPs3_jcVozu1EO8bLGZwoRpiLsU,14439
|
|
49
|
-
nc_py_api-0.
|
|
50
|
-
nc_py_api-0.
|
|
51
|
-
nc_py_api-0.
|
|
52
|
-
nc_py_api-0.
|
|
53
|
-
nc_py_api-0.
|
|
49
|
+
nc_py_api-0.18.0.dist-info/METADATA,sha256=_cUiEBjdiSBuqx6RM9HyIMR_pjr62TanPtBpb9DFmlw,9451
|
|
50
|
+
nc_py_api-0.18.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
51
|
+
nc_py_api-0.18.0.dist-info/licenses/AUTHORS,sha256=B2Q9q9XH3PAxJp0V3GiKQc1l0z7vtGDpDHqda-ISWKM,616
|
|
52
|
+
nc_py_api-0.18.0.dist-info/licenses/LICENSE.txt,sha256=OLEMh401fAumGHfRSna365MLIfnjdTcdOHZ6QOzMjkg,1551
|
|
53
|
+
nc_py_api-0.18.0.dist-info/RECORD,,
|
|
@@ -6,6 +6,7 @@ answer newbie questions, and generally made NC-Py-API that much better:
|
|
|
6
6
|
Alexander Piskun <bigcat88@icloud.com>
|
|
7
7
|
CooperGerman <https://github.com/CooperGerman>
|
|
8
8
|
Tobias Tschech <Tobias@tschech-online.de>
|
|
9
|
+
Scott Williams <scottwilliams@ucsb.edu>
|
|
9
10
|
<Please alphabetize new entries>
|
|
10
11
|
|
|
11
12
|
A big THANK YOU goes to:
|
|
File without changes
|
|
File without changes
|