nc-py-api 0.10.0__py3-none-any.whl → 0.18.1__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.
@@ -0,0 +1,161 @@
1
+ """Login flow v2 API wrapper."""
2
+
3
+ import asyncio
4
+ import json
5
+ import time
6
+ from dataclasses import dataclass
7
+
8
+ import httpx
9
+
10
+ from ._exceptions import check_error
11
+ from ._session import AsyncNcSession, NcSession
12
+
13
+ MAX_TIMEOUT = 60 * 20
14
+
15
+
16
+ @dataclass
17
+ class LoginFlow:
18
+ """The Nextcloud Login flow v2 initialization response representation."""
19
+
20
+ def __init__(self, raw_data: dict) -> None:
21
+ self.raw_data = raw_data
22
+
23
+ @property
24
+ def login(self) -> str:
25
+ """The URL for user authorization.
26
+
27
+ Should be opened by the user in the default browser to authorize in Nextcloud.
28
+ """
29
+ return self.raw_data["login"]
30
+
31
+ @property
32
+ def token(self) -> str:
33
+ """Token for a polling for confirmation of user authorization."""
34
+ return self.raw_data["poll"]["token"]
35
+
36
+ @property
37
+ def endpoint(self) -> str:
38
+ """Endpoint for polling."""
39
+ return self.raw_data["poll"]["endpoint"]
40
+
41
+ def __repr__(self) -> str:
42
+ return f"<{self.__class__.__name__} login_url={self.login}>"
43
+
44
+
45
+ @dataclass
46
+ class Credentials:
47
+ """The Nextcloud Login flow v2 response with app credentials representation."""
48
+
49
+ def __init__(self, raw_data: dict) -> None:
50
+ self.raw_data = raw_data
51
+
52
+ @property
53
+ def server(self) -> str:
54
+ """The address of Nextcloud to connect to.
55
+
56
+ The server may specify a protocol (http or https). If no protocol is specified https will be used.
57
+ """
58
+ return self.raw_data["server"]
59
+
60
+ @property
61
+ def login_name(self) -> str:
62
+ """The username for authenticating with Nextcloud."""
63
+ return self.raw_data["loginName"]
64
+
65
+ @property
66
+ def app_password(self) -> str:
67
+ """The application password generated for authenticating with Nextcloud."""
68
+ return self.raw_data["appPassword"]
69
+
70
+ def __repr__(self) -> str:
71
+ return f"<{self.__class__.__name__} login={self.login_name} app_password={self.app_password}>"
72
+
73
+
74
+ class _LoginFlowV2API:
75
+ """Class implementing Nextcloud Login flow v2."""
76
+
77
+ _ep_init: str = "/index.php/login/v2"
78
+ _ep_poll: str = "/index.php/login/v2/poll"
79
+
80
+ def __init__(self, session: NcSession) -> None:
81
+ self._session = session
82
+
83
+ def init(self, user_agent: str = "nc_py_api") -> LoginFlow:
84
+ """Init a Login flow v2.
85
+
86
+ :param user_agent: Application name. Application password will be associated with this name.
87
+ """
88
+ r = self._session.adapter.post(self._ep_init, headers={"user-agent": user_agent})
89
+ return LoginFlow(_res_to_json(r))
90
+
91
+ def poll(self, token: str, timeout: int = MAX_TIMEOUT, step: int = 1, overwrite_auth: bool = True) -> Credentials:
92
+ """Poll the Login flow v2 credentials.
93
+
94
+ :param token: Token for a polling for confirmation of user authorization.
95
+ :param timeout: Maximum time to wait for polling in seconds, defaults to MAX_TIMEOUT.
96
+ :param step: Interval for polling in seconds, defaults to 1.
97
+ :param overwrite_auth: If True current session will be overwritten with new credentials, defaults to True.
98
+ :raises ValueError: If timeout more than 20 minutes.
99
+ """
100
+ if timeout > MAX_TIMEOUT:
101
+ msg = "Timeout can't be more than 20 minutes."
102
+ raise ValueError(msg)
103
+ for _ in range(timeout // step):
104
+ r = self._session.adapter.post(self._ep_poll, data={"token": token})
105
+ if r.status_code == 200:
106
+ break
107
+ time.sleep(step)
108
+ r_model = Credentials(_res_to_json(r))
109
+ if overwrite_auth:
110
+ self._session.cfg.auth = (r_model.login_name, r_model.app_password)
111
+ self._session.init_adapter(restart=True)
112
+ self._session.init_adapter_dav(restart=True)
113
+ return r_model
114
+
115
+
116
+ class _AsyncLoginFlowV2API:
117
+ """Class implementing Async Nextcloud Login flow v2."""
118
+
119
+ _ep_init: str = "/index.php/login/v2"
120
+ _ep_poll: str = "/index.php/login/v2/poll"
121
+
122
+ def __init__(self, session: AsyncNcSession) -> None:
123
+ self._session = session
124
+
125
+ async def init(self, user_agent: str = "nc_py_api") -> LoginFlow:
126
+ """Init a Login flow v2.
127
+
128
+ :param user_agent: Application name. Application password will be associated with this name.
129
+ """
130
+ r = await self._session.adapter.post(self._ep_init, headers={"user-agent": user_agent})
131
+ return LoginFlow(_res_to_json(r))
132
+
133
+ async def poll(
134
+ self, token: str, timeout: int = MAX_TIMEOUT, step: int = 1, overwrite_auth: bool = True
135
+ ) -> Credentials:
136
+ """Poll the Login flow v2 credentials.
137
+
138
+ :param token: Token for a polling for confirmation of user authorization.
139
+ :param timeout: Maximum time to wait for polling in seconds, defaults to MAX_TIMEOUT.
140
+ :param step: Interval for polling in seconds, defaults to 1.
141
+ :param overwrite_auth: If True current session will be overwritten with new credentials, defaults to True.
142
+ :raises ValueError: If timeout more than 20 minutes.
143
+ """
144
+ if timeout > MAX_TIMEOUT:
145
+ raise ValueError("Timeout can't be more than 20 minutes.")
146
+ for _ in range(timeout // step):
147
+ r = await self._session.adapter.post(self._ep_poll, data={"token": token})
148
+ if r.status_code == 200:
149
+ break
150
+ await asyncio.sleep(step)
151
+ r_model = Credentials(_res_to_json(r))
152
+ if overwrite_auth:
153
+ self._session.cfg.auth = (r_model.login_name, r_model.app_password)
154
+ self._session.init_adapter(restart=True)
155
+ self._session.init_adapter_dav(restart=True)
156
+ return r_model
157
+
158
+
159
+ def _res_to_json(response: httpx.Response) -> dict:
160
+ check_error(response)
161
+ return json.loads(response.text)
nc_py_api/nextcloud.py CHANGED
@@ -1,5 +1,6 @@
1
1
  """Nextcloud class providing access to all API endpoints."""
2
2
 
3
+ import contextlib
3
4
  import typing
4
5
  from abc import ABC
5
6
 
@@ -30,15 +31,20 @@ from .activity import _ActivityAPI, _AsyncActivityAPI
30
31
  from .apps import _AppsAPI, _AsyncAppsAPI
31
32
  from .calendar import _CalendarAPI
32
33
  from .ex_app.defs import LogLvl
34
+ from .ex_app.events_listener import AsyncEventsListenerAPI, EventsListenerAPI
35
+ from .ex_app.occ_commands import AsyncOccCommandsAPI, OccCommandsAPI
33
36
  from .ex_app.providers.providers import AsyncProvidersApi, ProvidersApi
34
37
  from .ex_app.ui.ui import AsyncUiApi, UiApi
35
- from .files.files import AsyncFilesAPI, FilesAPI
38
+ from .files.files import FilesAPI
39
+ from .files.files_async import AsyncFilesAPI
40
+ from .loginflow_v2 import _AsyncLoginFlowV2API, _LoginFlowV2API
36
41
  from .notes import _AsyncNotesAPI, _NotesAPI
37
42
  from .notifications import _AsyncNotificationsAPI, _NotificationsAPI
38
43
  from .user_status import _AsyncUserStatusAPI, _UserStatusAPI
39
44
  from .users import _AsyncUsersAPI, _UsersAPI
40
45
  from .users_groups import _AsyncUsersGroupsAPI, _UsersGroupsAPI
41
46
  from .weather_status import _AsyncWeatherStatusAPI, _WeatherStatusAPI
47
+ from .webhooks import _AsyncWebhooksAPI, _WebhooksAPI
42
48
 
43
49
 
44
50
  class _NextcloudBasic(ABC): # pylint: disable=too-many-instance-attributes
@@ -66,6 +72,8 @@ class _NextcloudBasic(ABC): # pylint: disable=too-many-instance-attributes
66
72
  """Nextcloud API for managing users statuses"""
67
73
  weather_status: _WeatherStatusAPI
68
74
  """Nextcloud API for managing user weather statuses"""
75
+ webhooks: _WebhooksAPI
76
+ """Nextcloud API for managing webhooks"""
69
77
  _session: NcSessionBasic
70
78
 
71
79
  def __init__(self, session: NcSessionBasic):
@@ -81,6 +89,7 @@ class _NextcloudBasic(ABC): # pylint: disable=too-many-instance-attributes
81
89
  self.users_groups = _UsersGroupsAPI(session)
82
90
  self.user_status = _UserStatusAPI(session)
83
91
  self.weather_status = _WeatherStatusAPI(session)
92
+ self.webhooks = _WebhooksAPI(session)
84
93
 
85
94
  @property
86
95
  def capabilities(self) -> dict:
@@ -164,6 +173,8 @@ class _AsyncNextcloudBasic(ABC): # pylint: disable=too-many-instance-attributes
164
173
  """Nextcloud API for managing users statuses"""
165
174
  weather_status: _AsyncWeatherStatusAPI
166
175
  """Nextcloud API for managing user weather statuses"""
176
+ webhooks: _AsyncWebhooksAPI
177
+ """Nextcloud API for managing webhooks"""
167
178
  _session: AsyncNcSessionBasic
168
179
 
169
180
  def __init__(self, session: AsyncNcSessionBasic):
@@ -179,6 +190,7 @@ class _AsyncNextcloudBasic(ABC): # pylint: disable=too-many-instance-attributes
179
190
  self.users_groups = _AsyncUsersGroupsAPI(session)
180
191
  self.user_status = _AsyncUserStatusAPI(session)
181
192
  self.weather_status = _AsyncWeatherStatusAPI(session)
193
+ self.webhooks = _AsyncWebhooksAPI(session)
182
194
 
183
195
  @property
184
196
  async def capabilities(self) -> dict:
@@ -244,15 +256,18 @@ class Nextcloud(_NextcloudBasic):
244
256
  """
245
257
 
246
258
  _session: NcSession
259
+ loginflow_v2: _LoginFlowV2API
260
+ """Nextcloud Login flow v2."""
247
261
 
248
262
  def __init__(self, **kwargs):
249
263
  """If the parameters are not specified, they will be taken from the environment.
250
264
 
251
265
  :param nextcloud_url: url of the nextcloud instance.
252
- :param nc_auth_user: login username.
253
- :param nc_auth_pass: password or app-password for the username.
266
+ :param nc_auth_user: login username. Optional.
267
+ :param nc_auth_pass: password or app-password for the username. Optional.
254
268
  """
255
269
  self._session = NcSession(**kwargs)
270
+ self.loginflow_v2 = _LoginFlowV2API(self._session)
256
271
  super().__init__(self._session)
257
272
 
258
273
  @property
@@ -268,15 +283,18 @@ class AsyncNextcloud(_AsyncNextcloudBasic):
268
283
  """
269
284
 
270
285
  _session: AsyncNcSession
286
+ loginflow_v2: _AsyncLoginFlowV2API
287
+ """Nextcloud Login flow v2."""
271
288
 
272
289
  def __init__(self, **kwargs):
273
290
  """If the parameters are not specified, they will be taken from the environment.
274
291
 
275
292
  :param nextcloud_url: url of the nextcloud instance.
276
- :param nc_auth_user: login username.
277
- :param nc_auth_pass: password or app-password for the username.
293
+ :param nc_auth_user: login username. Optional.
294
+ :param nc_auth_pass: password or app-password for the username. Optional.
278
295
  """
279
296
  self._session = AsyncNcSession(**kwargs)
297
+ self.loginflow_v2 = _AsyncLoginFlowV2API(self._session)
280
298
  super().__init__(self._session)
281
299
 
282
300
  @property
@@ -304,6 +322,10 @@ class NextcloudApp(_NextcloudBasic):
304
322
  """Nextcloud UI API for ExApps"""
305
323
  providers: ProvidersApi
306
324
  """API for registering providers for Nextcloud"""
325
+ events_listener: EventsListenerAPI
326
+ """API for registering Events listeners for ExApps"""
327
+ occ_commands: OccCommandsAPI
328
+ """API for registering OCC command for ExApps"""
307
329
 
308
330
  def __init__(self, **kwargs):
309
331
  """The parameters will be taken from the environment.
@@ -316,24 +338,38 @@ class NextcloudApp(_NextcloudBasic):
316
338
  self.preferences_ex = PreferencesExAPI(self._session)
317
339
  self.ui = UiApi(self._session)
318
340
  self.providers = ProvidersApi(self._session)
341
+ self.events_listener = EventsListenerAPI(self._session)
342
+ self.occ_commands = OccCommandsAPI(self._session)
319
343
 
320
- def log(self, log_lvl: LogLvl, content: str) -> None:
344
+ @property
345
+ def enabled_state(self) -> bool:
346
+ """Returns ``True`` if ExApp is enabled, ``False`` otherwise."""
347
+ with contextlib.suppress(Exception):
348
+ return bool(self._session.ocs("GET", "/ocs/v1.php/apps/app_api/ex-app/state"))
349
+ return False
350
+
351
+ def log(self, log_lvl: LogLvl, content: str, fast_send: bool = False) -> None:
321
352
  """Writes log to the Nextcloud log file."""
322
- if self.check_capabilities("app_api"):
323
- return
324
- if int(log_lvl) < self.capabilities["app_api"].get("loglevel", 0):
325
- return
326
- self._session.ocs("POST", f"{self._session.ae_url}/log", json={"level": int(log_lvl), "message": content})
353
+ int_log_lvl = int(log_lvl)
354
+ if int_log_lvl < 0 or int_log_lvl > 4:
355
+ raise ValueError("Invalid `log_lvl` value")
356
+ if not fast_send:
357
+ if self.check_capabilities("app_api"):
358
+ return
359
+ if int_log_lvl < self.capabilities["app_api"].get("loglevel", 0):
360
+ return
361
+ with contextlib.suppress(Exception):
362
+ self._session.ocs("POST", f"{self._session.ae_url}/log", json={"level": int_log_lvl, "message": content})
327
363
 
328
364
  def users_list(self) -> list[str]:
329
- """Returns list of users on the Nextcloud instance. **Available** only for ``System`` applications."""
365
+ """Returns list of users on the Nextcloud instance."""
330
366
  return self._session.ocs("GET", f"{self._session.ae_url}/users")
331
367
 
332
368
  @property
333
369
  def user(self) -> str:
334
370
  """Property containing the current user ID.
335
371
 
336
- **System Applications** can change user ID they impersonate with **set_user** method.
372
+ **ExApps** can change user ID they impersonate with **set_user** method.
337
373
  """
338
374
  return self._session.user
339
375
 
@@ -421,6 +457,10 @@ class AsyncNextcloudApp(_AsyncNextcloudBasic):
421
457
  """Nextcloud UI API for ExApps"""
422
458
  providers: AsyncProvidersApi
423
459
  """API for registering providers for Nextcloud"""
460
+ events_listener: AsyncEventsListenerAPI
461
+ """API for registering Events listeners for ExApps"""
462
+ occ_commands: AsyncOccCommandsAPI
463
+ """API for registering OCC command for ExApps"""
424
464
 
425
465
  def __init__(self, **kwargs):
426
466
  """The parameters will be taken from the environment.
@@ -433,24 +473,40 @@ class AsyncNextcloudApp(_AsyncNextcloudBasic):
433
473
  self.preferences_ex = AsyncPreferencesExAPI(self._session)
434
474
  self.ui = AsyncUiApi(self._session)
435
475
  self.providers = AsyncProvidersApi(self._session)
476
+ self.events_listener = AsyncEventsListenerAPI(self._session)
477
+ self.occ_commands = AsyncOccCommandsAPI(self._session)
478
+
479
+ @property
480
+ async def enabled_state(self) -> bool:
481
+ """Returns ``True`` if ExApp is enabled, ``False`` otherwise."""
482
+ with contextlib.suppress(Exception):
483
+ return bool(await self._session.ocs("GET", "/ocs/v1.php/apps/app_api/ex-app/state"))
484
+ return False
436
485
 
437
- async def log(self, log_lvl: LogLvl, content: str) -> None:
486
+ async def log(self, log_lvl: LogLvl, content: str, fast_send: bool = False) -> None:
438
487
  """Writes log to the Nextcloud log file."""
439
- if await self.check_capabilities("app_api"):
440
- return
441
- if int(log_lvl) < (await self.capabilities)["app_api"].get("loglevel", 0):
442
- return
443
- await self._session.ocs("POST", f"{self._session.ae_url}/log", json={"level": int(log_lvl), "message": content})
488
+ int_log_lvl = int(log_lvl)
489
+ if int_log_lvl < 0 or int_log_lvl > 4:
490
+ raise ValueError("Invalid `log_lvl` value")
491
+ if not fast_send:
492
+ if await self.check_capabilities("app_api"):
493
+ return
494
+ if int_log_lvl < (await self.capabilities)["app_api"].get("loglevel", 0):
495
+ return
496
+ with contextlib.suppress(Exception):
497
+ await self._session.ocs(
498
+ "POST", f"{self._session.ae_url}/log", json={"level": int_log_lvl, "message": content}
499
+ )
444
500
 
445
501
  async def users_list(self) -> list[str]:
446
- """Returns list of users on the Nextcloud instance. **Available** only for ``System`` applications."""
502
+ """Returns list of users on the Nextcloud instance."""
447
503
  return await self._session.ocs("GET", f"{self._session.ae_url}/users")
448
504
 
449
505
  @property
450
506
  async def user(self) -> str:
451
507
  """Property containing the current user ID.
452
508
 
453
- **System Applications** can change user ID they impersonate with **set_user** method.
509
+ **ExApps** can change user ID they impersonate with **set_user** method.
454
510
  """
455
511
  return await self._session.user
456
512
 
nc_py_api/talk_bot.py CHANGED
@@ -29,6 +29,11 @@ class TalkBotMessage:
29
29
  def __init__(self, raw_data: dict):
30
30
  self._raw_data = raw_data
31
31
 
32
+ @property
33
+ def message_type(self) -> str:
34
+ """The type of message like Join, Leave, Create, Activity, etc."""
35
+ return self._raw_data["type"]
36
+
32
37
  @property
33
38
  def actor_id(self) -> str:
34
39
  """One of the attendee types followed by the ``/`` character and a unique identifier within the given type.
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", None)
373
- email = kwargs.get("email", None)
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}
@@ -378,5 +378,5 @@ def _create(user_id: str, display_name: str | None, **kwargs) -> dict[str, typin
378
378
  if k in kwargs:
379
379
  data[k] = kwargs[k]
380
380
  if display_name is not None:
381
- data["displayname"] = display_name
381
+ data["displayName"] = display_name
382
382
  return data
nc_py_api/webhooks.py ADDED
@@ -0,0 +1,224 @@
1
+ """Nextcloud Webhooks API."""
2
+
3
+ import dataclasses
4
+
5
+ from ._misc import clear_from_params_empty # , require_capabilities
6
+ from ._session import AppConfig, AsyncNcSessionBasic, NcSessionBasic
7
+
8
+
9
+ @dataclasses.dataclass
10
+ class WebhookInfo:
11
+ """Information about the Webhook."""
12
+
13
+ def __init__(self, raw_data: dict):
14
+ self._raw_data = raw_data
15
+
16
+ @property
17
+ def webhook_id(self) -> int:
18
+ """`ID` of the webhook."""
19
+ return self._raw_data["id"]
20
+
21
+ @property
22
+ def app_id(self) -> str:
23
+ """`ID` of the ExApp that registered webhook."""
24
+ return self._raw_data["appId"] if self._raw_data["appId"] else ""
25
+
26
+ @property
27
+ def user_id(self) -> str:
28
+ """`UserID` if webhook was registered in user context."""
29
+ return self._raw_data["userId"] if self._raw_data["userId"] else ""
30
+
31
+ @property
32
+ def http_method(self) -> str:
33
+ """HTTP method used to call webhook."""
34
+ return self._raw_data["httpMethod"]
35
+
36
+ @property
37
+ def uri(self) -> str:
38
+ """URL address that will be called for this webhook."""
39
+ return self._raw_data["uri"]
40
+
41
+ @property
42
+ def event(self) -> str:
43
+ """Nextcloud PHP event that triggers this webhook."""
44
+ return self._raw_data["event"]
45
+
46
+ @property
47
+ def event_filter(self):
48
+ """Mongo filter to apply to the serialized data to decide if firing."""
49
+ return self._raw_data["eventFilter"]
50
+
51
+ @property
52
+ def user_id_filter(self) -> str:
53
+ """Currently unknown."""
54
+ return self._raw_data["userIdFilter"]
55
+
56
+ @property
57
+ def headers(self) -> dict:
58
+ """Headers that should be added to request when calling webhook."""
59
+ return self._raw_data["headers"] if self._raw_data["headers"] else {}
60
+
61
+ @property
62
+ def auth_method(self) -> str:
63
+ """Currently unknown."""
64
+ return self._raw_data["authMethod"]
65
+
66
+ @property
67
+ def auth_data(self) -> dict:
68
+ """Currently unknown."""
69
+ return self._raw_data["authData"] if self._raw_data["authData"] else {}
70
+
71
+ def __repr__(self):
72
+ return f"<{self.__class__.__name__} id={self.webhook_id}, event={self.event}>"
73
+
74
+
75
+ class _WebhooksAPI:
76
+ """The class provides the application management API on the Nextcloud server."""
77
+
78
+ _ep_base: str = "/ocs/v1.php/apps/webhook_listeners/api/v1/webhooks"
79
+
80
+ def __init__(self, session: NcSessionBasic):
81
+ self._session = session
82
+
83
+ def get_list(self, uri_filter: str = "") -> list[WebhookInfo]:
84
+ params = {"uri": uri_filter} if uri_filter else {}
85
+ return [WebhookInfo(i) for i in self._session.ocs("GET", f"{self._ep_base}", params=params)]
86
+
87
+ def get_entry(self, webhook_id: int) -> WebhookInfo:
88
+ return WebhookInfo(self._session.ocs("GET", f"{self._ep_base}/{webhook_id}"))
89
+
90
+ def register(
91
+ self,
92
+ http_method: str,
93
+ uri: str,
94
+ event: str,
95
+ event_filter: dict | None = None,
96
+ user_id_filter: str = "",
97
+ headers: dict | None = None,
98
+ auth_method: str = "none",
99
+ auth_data: dict | None = None,
100
+ ):
101
+ params = {
102
+ "httpMethod": http_method,
103
+ "uri": uri,
104
+ "event": event,
105
+ "eventFilter": event_filter,
106
+ "userIdFilter": user_id_filter,
107
+ "headers": headers,
108
+ "authMethod": auth_method,
109
+ "authData": auth_data,
110
+ }
111
+ clear_from_params_empty(["eventFilter", "userIdFilter", "headers", "authMethod", "authData"], params)
112
+ return WebhookInfo(self._session.ocs("POST", f"{self._ep_base}", json=params))
113
+
114
+ def update(
115
+ self,
116
+ webhook_id: int,
117
+ http_method: str,
118
+ uri: str,
119
+ event: str,
120
+ event_filter: dict | None = None,
121
+ user_id_filter: str = "",
122
+ headers: dict | None = None,
123
+ auth_method: str = "none",
124
+ auth_data: dict | None = None,
125
+ ):
126
+ params = {
127
+ "id": webhook_id,
128
+ "httpMethod": http_method,
129
+ "uri": uri,
130
+ "event": event,
131
+ "eventFilter": event_filter,
132
+ "userIdFilter": user_id_filter,
133
+ "headers": headers,
134
+ "authMethod": auth_method,
135
+ "authData": auth_data,
136
+ }
137
+ clear_from_params_empty(["eventFilter", "userIdFilter", "headers", "authMethod", "authData"], params)
138
+ return WebhookInfo(self._session.ocs("POST", f"{self._ep_base}/{webhook_id}", json=params))
139
+
140
+ def unregister(self, webhook_id: int) -> bool:
141
+ return self._session.ocs("DELETE", f"{self._ep_base}/{webhook_id}")
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
+
150
+
151
+ class _AsyncWebhooksAPI:
152
+ """The class provides the async application management API on the Nextcloud server."""
153
+
154
+ _ep_base: str = "/ocs/v1.php/webhooks"
155
+
156
+ def __init__(self, session: AsyncNcSessionBasic):
157
+ self._session = session
158
+
159
+ async def get_list(self, uri_filter: str = "") -> list[WebhookInfo]:
160
+ params = {"uri": uri_filter} if uri_filter else {}
161
+ return [WebhookInfo(i) for i in await self._session.ocs("GET", f"{self._ep_base}", params=params)]
162
+
163
+ async def get_entry(self, webhook_id: int) -> WebhookInfo:
164
+ return WebhookInfo(await self._session.ocs("GET", f"{self._ep_base}/{webhook_id}"))
165
+
166
+ async def register(
167
+ self,
168
+ http_method: str,
169
+ uri: str,
170
+ event: str,
171
+ event_filter: dict | None = None,
172
+ user_id_filter: str = "",
173
+ headers: dict | None = None,
174
+ auth_method: str = "none",
175
+ auth_data: dict | None = None,
176
+ ):
177
+ params = {
178
+ "httpMethod": http_method,
179
+ "uri": uri,
180
+ "event": event,
181
+ "eventFilter": event_filter,
182
+ "userIdFilter": user_id_filter,
183
+ "headers": headers,
184
+ "authMethod": auth_method,
185
+ "authData": auth_data,
186
+ }
187
+ clear_from_params_empty(["eventFilter", "userIdFilter", "headers", "authMethod", "authData"], params)
188
+ return WebhookInfo(await self._session.ocs("POST", f"{self._ep_base}", json=params))
189
+
190
+ async def update(
191
+ self,
192
+ webhook_id: int,
193
+ http_method: str,
194
+ uri: str,
195
+ event: str,
196
+ event_filter: dict | None = None,
197
+ user_id_filter: str = "",
198
+ headers: dict | None = None,
199
+ auth_method: str = "none",
200
+ auth_data: dict | None = None,
201
+ ):
202
+ params = {
203
+ "id": webhook_id,
204
+ "httpMethod": http_method,
205
+ "uri": uri,
206
+ "event": event,
207
+ "eventFilter": event_filter,
208
+ "userIdFilter": user_id_filter,
209
+ "headers": headers,
210
+ "authMethod": auth_method,
211
+ "authData": auth_data,
212
+ }
213
+ clear_from_params_empty(["eventFilter", "userIdFilter", "headers", "authMethod", "authData"], params)
214
+ return WebhookInfo(await self._session.ocs("POST", f"{self._ep_base}/{webhook_id}", json=params))
215
+
216
+ async def unregister(self, webhook_id: int) -> bool:
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}")