nc-py-api 0.11.0__tar.gz → 0.18.1__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 (61) hide show
  1. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/AUTHORS +1 -0
  2. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/CHANGELOG.md +101 -0
  3. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/PKG-INFO +35 -23
  4. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/README.md +15 -16
  5. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/__init__.py +1 -1
  6. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/_session.py +27 -14
  7. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/_version.py +1 -1
  8. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/apps.py +0 -13
  9. nc_py_api-0.18.1/nc_py_api/ex_app/__init__.py +25 -0
  10. nc_py_api-0.18.1/nc_py_api/ex_app/defs.py +37 -0
  11. nc_py_api-0.18.1/nc_py_api/ex_app/events_listener.py +137 -0
  12. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/integration_fastapi.py +25 -14
  13. nc_py_api-0.18.1/nc_py_api/ex_app/logging.py +46 -0
  14. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/misc.py +6 -1
  15. nc_py_api-0.18.1/nc_py_api/ex_app/occ_commands.py +153 -0
  16. nc_py_api-0.18.1/nc_py_api/ex_app/providers/providers.py +24 -0
  17. nc_py_api-0.18.1/nc_py_api/ex_app/providers/task_processing.py +261 -0
  18. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/ui/files_actions.py +45 -61
  19. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/files/__init__.py +76 -6
  20. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/files/_files.py +12 -0
  21. nc_py_api-0.18.1/nc_py_api/files/files.py +520 -0
  22. nc_py_api-0.11.0/nc_py_api/files/files.py → nc_py_api-0.18.1/nc_py_api/files/files_async.py +23 -477
  23. nc_py_api-0.18.1/nc_py_api/loginflow_v2.py +161 -0
  24. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/nextcloud.py +77 -21
  25. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/talk_bot.py +5 -0
  26. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/users.py +3 -3
  27. nc_py_api-0.18.1/nc_py_api/webhooks.py +224 -0
  28. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/pyproject.toml +123 -68
  29. nc_py_api-0.11.0/nc_py_api/ex_app/__init__.py +0 -15
  30. nc_py_api-0.11.0/nc_py_api/ex_app/defs.py +0 -49
  31. nc_py_api-0.11.0/nc_py_api/ex_app/providers/providers.py +0 -38
  32. nc_py_api-0.11.0/nc_py_api/ex_app/providers/speech_to_text.py +0 -128
  33. nc_py_api-0.11.0/nc_py_api/ex_app/providers/text_processing.py +0 -135
  34. nc_py_api-0.11.0/nc_py_api/ex_app/providers/translations.py +0 -165
  35. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/.gitignore +0 -0
  36. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/LICENSE.txt +0 -0
  37. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/_deffered_error.py +0 -0
  38. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/_exceptions.py +0 -0
  39. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/_misc.py +0 -0
  40. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/_preferences.py +0 -0
  41. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/_preferences_ex.py +0 -0
  42. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/_talk_api.py +0 -0
  43. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/_theming.py +0 -0
  44. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/activity.py +0 -0
  45. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/calendar.py +0 -0
  46. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/persist_transformers_cache.py +0 -0
  47. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/providers/__init__.py +0 -0
  48. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/ui/__init__.py +0 -0
  49. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/ui/resources.py +0 -0
  50. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/ui/settings.py +0 -0
  51. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/ui/top_menu.py +0 -0
  52. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/ui/ui.py +0 -0
  53. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/ex_app/uvicorn_fastapi.py +0 -0
  54. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/files/sharing.py +0 -0
  55. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/notes.py +0 -0
  56. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/notifications.py +0 -0
  57. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/options.py +0 -0
  58. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/talk.py +0 -0
  59. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/user_status.py +0 -0
  60. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/users_groups.py +0 -0
  61. {nc_py_api-0.11.0 → nc_py_api-0.18.1}/nc_py_api/weather_status.py +0 -0
@@ -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:
@@ -2,6 +2,107 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.18.1 - 2025-01-14]
6
+
7
+ ### Fixed
8
+
9
+ - Chunked Upload V2 not working on Nextcloud 30 and later. #324 Thanks to @DrZoidberg09
10
+
11
+ ## [0.18.0 - 2024-10-09]
12
+
13
+ ### Added
14
+
15
+ - New `webhooks.unregister_all` method. #309
16
+
17
+ ### Fixed
18
+
19
+ - Files: `user` and `user_path` properties in `FSNode` when Nextcloud located in the sub-path. #297 Thanks to @vwbusguy
20
+ - `files.download_directory_as_zip` method now supports upcoming Nextcloud 31. #304
21
+
22
+ ## [0.17.1 - 2024-09-06]
23
+
24
+ ### Added
25
+
26
+ - NextcloudApp: `setup_nextcloud_logging` function to support transparently sending logs to Nextcloud. #294
27
+
28
+ ### Fixed
29
+
30
+ - NextcloudApp: `nc.log` now suppresses all exceptions to safe call it anywhere(for example in exception handlers). #293
31
+
32
+ ## [0.17.0 - 2024-09-05]
33
+
34
+ ### Added
35
+
36
+ - `message_type` property to TalkBotMessage. #292
37
+
38
+ ### Changed
39
+
40
+ - NextcloudApp: `TextProcessing`, `Speech2Text` and `Translation` AI Providers API was removed. #289
41
+
42
+ ## [0.16.0 - 2024-08-12]
43
+
44
+ ### Changed
45
+
46
+ - NextcloudApp: rework of TaskProcessing provider API. #284
47
+
48
+ ### Fixed
49
+
50
+ - `nc.files.makedirs` not working properly on Windows. #280 Thanks to @Wuli6
51
+
52
+ ## [0.15.1 - 2024-07-30]
53
+
54
+ ### Fixed
55
+
56
+ - Corrected behaviour of `ocs` function for `Group Folders` app routes(they are not fully OCS API). #279
57
+ - NextcloudApp: `get_computation_device` function now correctly returns result in upper_case. #278
58
+
59
+ ## [0.15.0 - 2024-07-19]
60
+
61
+ ### Added
62
+
63
+ - Initial Webhooks API support for the upcoming Nextcloud 30. #272
64
+
65
+ ### Changed
66
+
67
+ - NextcloudApp: `fetch_models_task` function now saves paths to downloaded models. #274 Thanks to @kyteinsky
68
+
69
+ ## [0.14.0 - 2024-07-09]
70
+
71
+ ### Added
72
+
73
+ - `LoginFlowV2` implementation by @blvdek #255
74
+ - `files.get_tags` function to get all tags assigned to the file or directory. #260
75
+ - NextcloudApp: `nc.ui.files_dropdown_menu.register_ex` to register new version of FileActions(AppAPI 2.6.0+) #252
76
+ - NextcloudApp: `enabled_state` property to check if the current ExApp is disabled or enabled. #268
77
+ - NextcloudApp: support for the new AI API for the Nextcloud 30. #254
78
+
79
+ ## [0.13.0 - 2024-04-28]
80
+
81
+ ### Added
82
+
83
+ - NextcloudApp: `occ` commands registration API(AppAPI 2.5.0+). #247
84
+ - NextcloudApp: `Nodes` events listener registration API(AppAPI 2.5.0+). #249
85
+
86
+ ## [0.12.1 - 2024-04-05]
87
+
88
+ ### Fixed
89
+
90
+ - Incorrect `Display name` when creating user, which led to the parameter being ignored. #239 Thanks to @derekbuckley
91
+
92
+ ## [0.12.0 - 2024-04-02]
93
+
94
+ Update with new features only for `NextcloudApp` class. #233
95
+
96
+ ### Added
97
+
98
+ - `ex_app.get_computation_device` function for retrieving GPU type(only with AppAPI `2.5.0`+).
99
+ - `ex_app.integration_fastapi.fetch_models_task` are now public function, added `progress_init_start_value` param.
100
+ - Global authentication when used now sets `request.scope["username"]` for easy use.
101
+
102
+ ### Changed
103
+
104
+ - `UiActionFileInfo` class marked as deprecated, instead `ActionFileInfo` class should be used.
105
+
5
106
  ## [0.11.0 - 2024-02-17]
6
107
 
7
108
  ### Added
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: nc-py-api
3
- Version: 0.11.0
3
+ Version: 0.18.1
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/
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3 :: Only
20
20
  Classifier: Programming Language :: Python :: 3.10
21
21
  Classifier: Programming Language :: Python :: 3.11
22
22
  Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
23
24
  Classifier: Programming Language :: Python :: Implementation :: CPython
24
25
  Classifier: Programming Language :: Python :: Implementation :: PyPy
25
26
  Classifier: Topic :: Internet :: WWW/HTTP
@@ -38,13 +39,24 @@ Provides-Extra: app
38
39
  Requires-Dist: uvicorn[standard]>=0.23.2; extra == 'app'
39
40
  Provides-Extra: bench
40
41
  Requires-Dist: matplotlib; extra == 'bench'
41
- Requires-Dist: nc-py-api[app]; extra == 'bench'
42
42
  Requires-Dist: numpy; extra == 'bench'
43
43
  Requires-Dist: py-cpuinfo; extra == 'bench'
44
+ Requires-Dist: uvicorn[standard]>=0.23.2; extra == 'bench'
44
45
  Provides-Extra: calendar
45
46
  Requires-Dist: caldav==1.3.6; extra == 'calendar'
46
47
  Provides-Extra: dev
47
- Requires-Dist: nc-py-api[bench,calendar,dev-min]; extra == 'dev'
48
+ Requires-Dist: caldav==1.3.6; extra == 'dev'
49
+ Requires-Dist: coverage; extra == 'dev'
50
+ Requires-Dist: huggingface-hub; extra == 'dev'
51
+ Requires-Dist: matplotlib; extra == 'dev'
52
+ Requires-Dist: numpy; extra == 'dev'
53
+ Requires-Dist: pillow; extra == 'dev'
54
+ Requires-Dist: pre-commit; extra == 'dev'
55
+ Requires-Dist: py-cpuinfo; extra == 'dev'
56
+ Requires-Dist: pylint; extra == 'dev'
57
+ Requires-Dist: pytest; extra == 'dev'
58
+ Requires-Dist: pytest-asyncio; extra == 'dev'
59
+ Requires-Dist: uvicorn[standard]>=0.23.2; extra == 'dev'
48
60
  Provides-Extra: dev-min
49
61
  Requires-Dist: coverage; extra == 'dev-min'
50
62
  Requires-Dist: huggingface-hub; extra == 'dev-min'
@@ -55,12 +67,13 @@ Requires-Dist: pytest; extra == 'dev-min'
55
67
  Requires-Dist: pytest-asyncio; extra == 'dev-min'
56
68
  Provides-Extra: docs
57
69
  Requires-Dist: autodoc-pydantic>=2.0.1; extra == 'docs'
58
- Requires-Dist: nc-py-api[app,calendar]; extra == 'docs'
70
+ Requires-Dist: caldav==1.3.6; extra == 'docs'
59
71
  Requires-Dist: sphinx-copybutton; extra == 'docs'
60
72
  Requires-Dist: sphinx-inline-tabs; extra == 'docs'
61
73
  Requires-Dist: sphinx-issues>=3.0.1; extra == 'docs'
62
- Requires-Dist: sphinx-rtd-theme>=1; extra == 'docs'
63
- Requires-Dist: sphinx>=6.2; extra == 'docs'
74
+ Requires-Dist: sphinx-rtd-theme<3; extra == 'docs'
75
+ Requires-Dist: sphinx<8; extra == 'docs'
76
+ Requires-Dist: uvicorn[standard]>=0.23.2; extra == 'docs'
64
77
  Description-Content-Type: text/markdown
65
78
 
66
79
  <p align="center">
@@ -73,7 +86,7 @@ Description-Content-Type: text/markdown
73
86
  [![Docs](https://github.com/cloud-py-api/nc_py_api/actions/workflows/docs.yml/badge.svg)](https://cloud-py-api.github.io/nc_py_api/)
74
87
  [![codecov](https://codecov.io/github/cloud-py-api/nc_py_api/branch/main/graph/badge.svg?token=C91PL3FYDQ)](https://codecov.io/github/cloud-py-api/nc_py_api)
75
88
 
76
- ![NextcloudVersion](https://img.shields.io/badge/Nextcloud-26%20%7C%2027%20%7C%2028-blue)
89
+ ![NextcloudVersion](https://img.shields.io/badge/Nextcloud-27%20%7C%2028%20%7C%2029%20%7C%2030-blue)
77
90
  ![PythonVersion](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)
78
91
  ![impl](https://img.shields.io/pypi/implementation/nc_py_api)
79
92
  ![pypi](https://img.shields.io/pypi/v/nc_py_api.svg)
@@ -89,23 +102,22 @@ Python library that provides a robust and well-documented API that allows develo
89
102
  * **Sync + Async**: Provides both sync and async APIs.
90
103
 
91
104
  ### Capabilities
92
- | **_Capability_** | Nextcloud 26 | Nextcloud 27 | Nextcloud 28 | Nextcloud 29 |
93
- |-----------------------|:------------:|:------------:|:------------:|:------------:|
94
- | Calendar | ✅ | ✅ | ✅ | ✅ |
95
- | File System & Tags | ✅ | ✅ | ✅ | ✅ |
96
- | Nextcloud Talk | ✅ | ✅ | ✅ | ✅ |
97
- | Notifications | ✅ | ✅ | ✅ | ✅ |
98
- | Shares | ✅ | ✅ | ✅ | ✅ |
99
- | Users & Groups | ✅ | ✅ | ✅ | ✅ |
100
- | User & Weather status | ✅ | ✅ | ✅ | ✅ |
101
- | Other APIs*** | ✅ | ✅ | ✅ | ✅ |
102
- | Talk Bot API* | N/A | ✅ | ✅ | ✅ |
103
- | Settings UI API* | N/A | N/A | N/A | ✅ |
104
- | AI Providers API** | N/A | N/A | N/A | ✅ |
105
+ | **_Capability_** | Nextcloud 27 | Nextcloud 28 | Nextcloud 29 | Nextcloud 30 |
106
+ |------------------------------|:------------:|:------------:|:------------:|:------------:|
107
+ | Calendar | ✅ | ✅ | ✅ | ✅ |
108
+ | File System & Tags | ✅ | ✅ | ✅ | ✅ |
109
+ | Nextcloud Talk | ✅ | ✅ | ✅ | ✅ |
110
+ | Notifications | ✅ | ✅ | ✅ | ✅ |
111
+ | Shares | ✅ | ✅ | ✅ | ✅ |
112
+ | Users & Groups | ✅ | ✅ | ✅ | ✅ |
113
+ | User & Weather status | ✅ | ✅ | ✅ | ✅ |
114
+ | Other APIs** | ✅ | ✅ | ✅ | ✅ |
115
+ | Talk Bot API* | | ✅ | ✅ | ✅ |
116
+ | Settings UI API* | N/A | N/A | | ✅ |
117
+ | TaskProcessing Provider API* | N/A | N/A | N/A | ✅ |
105
118
 
106
119
  &ast;_available only for **NextcloudApp**_<br>
107
- &ast;&ast;_available only for **NextcloudApp**: SpeechToText, TextProcessing, Translation_<br>
108
- &ast;&ast;&ast;_Activity, Notes_
120
+ &ast;&ast;_Activity, Notes_
109
121
 
110
122
  ### Differences between the Nextcloud and NextcloudApp classes
111
123
 
@@ -8,7 +8,7 @@
8
8
  [![Docs](https://github.com/cloud-py-api/nc_py_api/actions/workflows/docs.yml/badge.svg)](https://cloud-py-api.github.io/nc_py_api/)
9
9
  [![codecov](https://codecov.io/github/cloud-py-api/nc_py_api/branch/main/graph/badge.svg?token=C91PL3FYDQ)](https://codecov.io/github/cloud-py-api/nc_py_api)
10
10
 
11
- ![NextcloudVersion](https://img.shields.io/badge/Nextcloud-26%20%7C%2027%20%7C%2028-blue)
11
+ ![NextcloudVersion](https://img.shields.io/badge/Nextcloud-27%20%7C%2028%20%7C%2029%20%7C%2030-blue)
12
12
  ![PythonVersion](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)
13
13
  ![impl](https://img.shields.io/pypi/implementation/nc_py_api)
14
14
  ![pypi](https://img.shields.io/pypi/v/nc_py_api.svg)
@@ -24,23 +24,22 @@ Python library that provides a robust and well-documented API that allows develo
24
24
  * **Sync + Async**: Provides both sync and async APIs.
25
25
 
26
26
  ### Capabilities
27
- | **_Capability_** | Nextcloud 26 | Nextcloud 27 | Nextcloud 28 | Nextcloud 29 |
28
- |-----------------------|:------------:|:------------:|:------------:|:------------:|
29
- | Calendar | ✅ | ✅ | ✅ | ✅ |
30
- | File System & Tags | ✅ | ✅ | ✅ | ✅ |
31
- | Nextcloud Talk | ✅ | ✅ | ✅ | ✅ |
32
- | Notifications | ✅ | ✅ | ✅ | ✅ |
33
- | Shares | ✅ | ✅ | ✅ | ✅ |
34
- | Users & Groups | ✅ | ✅ | ✅ | ✅ |
35
- | User & Weather status | ✅ | ✅ | ✅ | ✅ |
36
- | Other APIs*** | ✅ | ✅ | ✅ | ✅ |
37
- | Talk Bot API* | N/A | ✅ | ✅ | ✅ |
38
- | Settings UI API* | N/A | N/A | N/A | ✅ |
39
- | AI Providers API** | N/A | N/A | N/A | ✅ |
27
+ | **_Capability_** | Nextcloud 27 | Nextcloud 28 | Nextcloud 29 | Nextcloud 30 |
28
+ |------------------------------|:------------:|:------------:|:------------:|:------------:|
29
+ | Calendar | ✅ | ✅ | ✅ | ✅ |
30
+ | File System & Tags | ✅ | ✅ | ✅ | ✅ |
31
+ | Nextcloud Talk | ✅ | ✅ | ✅ | ✅ |
32
+ | Notifications | ✅ | ✅ | ✅ | ✅ |
33
+ | Shares | ✅ | ✅ | ✅ | ✅ |
34
+ | Users & Groups | ✅ | ✅ | ✅ | ✅ |
35
+ | User & Weather status | ✅ | ✅ | ✅ | ✅ |
36
+ | Other APIs** | ✅ | ✅ | ✅ | ✅ |
37
+ | Talk Bot API* | | ✅ | ✅ | ✅ |
38
+ | Settings UI API* | N/A | N/A | | ✅ |
39
+ | TaskProcessing Provider API* | N/A | N/A | N/A | ✅ |
40
40
 
41
41
  &ast;_available only for **NextcloudApp**_<br>
42
- &ast;&ast;_available only for **NextcloudApp**: SpeechToText, TextProcessing, Translation_<br>
43
- &ast;&ast;&ast;_Activity, Notes_
42
+ &ast;&ast;_Activity, Notes_
44
43
 
45
44
  ### Differences between the Nextcloud and NextcloudApp classes
46
45
 
@@ -7,6 +7,6 @@ from ._exceptions import (
7
7
  NextcloudMissingCapabilities,
8
8
  )
9
9
  from ._version import __version__
10
- from .files import FilePermissions, FsNode, LockType
10
+ from .files import FilePermissions, FsNode, LockType, SystemTag
11
11
  from .files.sharing import ShareType
12
12
  from .nextcloud import AsyncNextcloud, AsyncNextcloudApp, Nextcloud, NextcloudApp
@@ -103,7 +103,10 @@ class Config(BasicConfig):
103
103
 
104
104
  def __init__(self, **kwargs):
105
105
  super().__init__(**kwargs)
106
- self.auth = (self._get_config_value("nc_auth_user", **kwargs), self._get_config_value("nc_auth_pass", **kwargs))
106
+ nc_auth_user = self._get_config_value("nc_auth_user", raise_not_found=False, **kwargs)
107
+ nc_auth_pass = self._get_config_value("nc_auth_pass", raise_not_found=False, **kwargs)
108
+ if nc_auth_user and nc_auth_pass:
109
+ self.auth = (nc_auth_user, nc_auth_pass)
107
110
 
108
111
 
109
112
  @dataclass
@@ -123,7 +126,7 @@ class AppConfig(BasicConfig):
123
126
  super().__init__(**kwargs)
124
127
  self.aa_version = self._get_config_value("aa_version", raise_not_found=False, **kwargs)
125
128
  if not self.aa_version:
126
- self.aa_version = "1.0.0"
129
+ self.aa_version = "2.2.0"
127
130
  self.app_name = self._get_config_value("app_id", **kwargs)
128
131
  self.app_version = self._get_config_value("app_version", **kwargs)
129
132
  self.app_secret = self._get_config_value("app_secret", **kwargs)
@@ -147,7 +150,7 @@ class NcSessionBase(ABC):
147
150
  self.init_adapter()
148
151
  self.init_adapter_dav()
149
152
  self.response_headers = Headers()
150
- self._ocs_regexp = re.compile(r"/ocs/v[12]\.php/")
153
+ self._ocs_regexp = re.compile(r"/ocs/v[12]\.php/|/apps/groupfolders/")
151
154
 
152
155
  def init_adapter(self, restart=False) -> None:
153
156
  if getattr(self, "adapter", None) is None or restart:
@@ -173,9 +176,14 @@ class NcSessionBase(ABC):
173
176
 
174
177
  @property
175
178
  def ae_url(self) -> str:
176
- """Return base url for the App Ecosystem endpoints."""
179
+ """Return base url for the AppAPI endpoints."""
177
180
  return "/ocs/v1.php/apps/app_api/api/v1"
178
181
 
182
+ @property
183
+ def ae_url_v2(self) -> str:
184
+ """Return base url for the AppAPI endpoints(version 2)."""
185
+ return "/ocs/v1.php/apps/app_api/api/v2"
186
+
179
187
 
180
188
  class NcSessionBasic(NcSessionBase, ABC):
181
189
  adapter: Client
@@ -189,13 +197,16 @@ class NcSessionBasic(NcSessionBase, ABC):
189
197
  content: bytes | str | typing.Iterable[bytes] | typing.AsyncIterable[bytes] | None = None,
190
198
  json: dict | list | None = None,
191
199
  params: dict | None = None,
200
+ files: dict | None = None,
192
201
  **kwargs,
193
202
  ):
194
203
  self.init_adapter()
195
204
  info = f"request: {method} {path}"
196
205
  nested_req = kwargs.pop("nested_req", False)
197
206
  try:
198
- response = self.adapter.request(method, path, content=content, json=json, params=params, **kwargs)
207
+ response = self.adapter.request(
208
+ method, path, content=content, json=json, params=params, files=files, **kwargs
209
+ )
199
210
  except ReadTimeout:
200
211
  raise NextcloudException(408, info=info) from None
201
212
 
@@ -278,6 +289,7 @@ class NcSessionBasic(NcSessionBase, ABC):
278
289
  str_url = str(request.url)
279
290
  if re.search(self._ocs_regexp, str_url) is not None: # this is OCS call
280
291
  request.url = request.url.copy_merge_params({"format": "json"})
292
+ request.headers["Accept"] = "application/json"
281
293
 
282
294
  def _response_event(self, response: Response) -> None:
283
295
  str_url = str(response.request.url)
@@ -289,7 +301,7 @@ class NcSessionBasic(NcSessionBase, ABC):
289
301
 
290
302
  def download2fp(self, url_path: str, fp, dav: bool, params=None, **kwargs):
291
303
  adapter = self.adapter_dav if dav else self.adapter
292
- 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:
293
305
  check_error(response)
294
306
  for data_chunk in response.iter_raw(chunk_size=kwargs.get("chunk_size", 5 * 1024 * 1024)):
295
307
  fp.write(data_chunk)
@@ -307,13 +319,16 @@ class AsyncNcSessionBasic(NcSessionBase, ABC):
307
319
  content: bytes | str | typing.Iterable[bytes] | typing.AsyncIterable[bytes] | None = None,
308
320
  json: dict | list | None = None,
309
321
  params: dict | None = None,
322
+ files: dict | None = None,
310
323
  **kwargs,
311
324
  ):
312
325
  self.init_adapter()
313
326
  info = f"request: {method} {path}"
314
327
  nested_req = kwargs.pop("nested_req", False)
315
328
  try:
316
- response = await self.adapter.request(method, path, content=content, json=json, params=params, **kwargs)
329
+ response = await self.adapter.request(
330
+ method, path, content=content, json=json, params=params, files=files, **kwargs
331
+ )
317
332
  except ReadTimeout:
318
333
  raise NextcloudException(408, info=info) from None
319
334
 
@@ -398,6 +413,7 @@ class AsyncNcSessionBasic(NcSessionBase, ABC):
398
413
  str_url = str(request.url)
399
414
  if re.search(self._ocs_regexp, str_url) is not None: # this is OCS call
400
415
  request.url = request.url.copy_merge_params({"format": "json"})
416
+ request.headers["Accept"] = "application/json"
401
417
 
402
418
  async def _response_event(self, response: Response) -> None:
403
419
  str_url = str(response.request.url)
@@ -409,7 +425,7 @@ class AsyncNcSessionBasic(NcSessionBase, ABC):
409
425
 
410
426
  async def download2fp(self, url_path: str, fp, dav: bool, params=None, **kwargs):
411
427
  adapter = self.adapter_dav if dav else self.adapter
412
- 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:
413
429
  check_error(response)
414
430
  async for data_chunk in response.aiter_raw(chunk_size=kwargs.get("chunk_size", 5 * 1024 * 1024)):
415
431
  fp.write(data_chunk)
@@ -459,7 +475,7 @@ class NcSessionAppBasic(ABC):
459
475
  self.cfg = AppConfig(**kwargs)
460
476
  super().__init__(**kwargs)
461
477
 
462
- def sign_check(self, request: HTTPConnection) -> None:
478
+ def sign_check(self, request: HTTPConnection) -> str:
463
479
  headers = {
464
480
  "AA-VERSION": request.headers.get("AA-VERSION", ""),
465
481
  "EX-APP-ID": request.headers.get("EX-APP-ID", ""),
@@ -474,13 +490,10 @@ class NcSessionAppBasic(ABC):
474
490
  if headers["EX-APP-ID"] != self.cfg.app_name:
475
491
  raise ValueError(f"Invalid EX-APP-ID:{headers['EX-APP-ID']} != {self.cfg.app_name}")
476
492
 
477
- our_version = self.adapter.headers.get("EX-APP-VERSION", "")
478
- if headers["EX-APP-VERSION"] != our_version:
479
- raise ValueError(f"Invalid EX-APP-VERSION:{headers['EX-APP-VERSION']} <=> {our_version}")
480
-
481
- app_secret = get_username_secret_from_headers(headers)[1]
493
+ username, app_secret = get_username_secret_from_headers(headers)
482
494
  if app_secret != self.cfg.app_secret:
483
495
  raise ValueError(f"Invalid App secret:{app_secret} != {self.cfg.app_secret}")
496
+ return username
484
497
 
485
498
 
486
499
  class NcSessionApp(NcSessionAppBasic, NcSessionBasic):
@@ -1,3 +1,3 @@
1
1
  """Version of nc_py_api."""
2
2
 
3
- __version__ = "0.11.0"
3
+ __version__ = "0.18.1"
@@ -1,7 +1,6 @@
1
1
  """Nextcloud API for working with applications."""
2
2
 
3
3
  import dataclasses
4
- import datetime
5
4
 
6
5
  from ._misc import require_capabilities
7
6
  from ._session import AsyncNcSessionBasic, NcSessionBasic
@@ -34,18 +33,6 @@ class ExAppInfo:
34
33
  """Flag indicating if the application enabled."""
35
34
  return bool(self._raw_data["enabled"])
36
35
 
37
- @property
38
- def last_check_time(self) -> datetime.datetime:
39
- """Time of the last successful application check."""
40
- return datetime.datetime.utcfromtimestamp(int(self._raw_data["last_check_time"])).replace(
41
- tzinfo=datetime.timezone.utc
42
- )
43
-
44
- @property
45
- def system(self) -> bool:
46
- """Flag indicating if the application is a system application."""
47
- return bool(self._raw_data["system"])
48
-
49
36
  def __repr__(self):
50
37
  return f"<{self.__class__.__name__} id={self.app_id}, ver={self.version}>"
51
38
 
@@ -0,0 +1,25 @@
1
+ """All possible ExApp stuff for NextcloudApp that can be used."""
2
+
3
+ from ..files import ActionFileInfo
4
+ from .defs import FileSystemEventNotification, LogLvl
5
+ from .integration_fastapi import (
6
+ AppAPIAuthMiddleware,
7
+ anc_app,
8
+ atalk_bot_msg,
9
+ nc_app,
10
+ set_handlers,
11
+ talk_bot_msg,
12
+ )
13
+ from .logging import setup_nextcloud_logging
14
+ from .misc import (
15
+ get_computation_device,
16
+ get_model_path,
17
+ persistent_storage,
18
+ verify_version,
19
+ )
20
+ from .ui.settings import SettingsField, SettingsFieldType, SettingsForm
21
+ from .uvicorn_fastapi import run_app
22
+
23
+
24
+ class UiActionFileInfo(ActionFileInfo):
25
+ """``Deprecated``: use :py:class:`~nc_py_api.files.ActionFileInfo` instead."""
@@ -0,0 +1,37 @@
1
+ """Additional definitions for NextcloudApp."""
2
+
3
+ import enum
4
+
5
+ from pydantic import BaseModel
6
+
7
+ from ..files import ActionFileInfo
8
+
9
+
10
+ class LogLvl(enum.IntEnum):
11
+ """Log levels."""
12
+
13
+ DEBUG = 0
14
+ """Debug log level"""
15
+ INFO = 1
16
+ """Informational log level"""
17
+ WARNING = 2
18
+ """Warning log level. ``Default``"""
19
+ ERROR = 3
20
+ """Error log level"""
21
+ FATAL = 4
22
+ """Fatal log level"""
23
+
24
+
25
+ class FileSystemEventData(BaseModel):
26
+ """FileSystem events format."""
27
+
28
+ target: ActionFileInfo
29
+ source: ActionFileInfo | None = None
30
+
31
+
32
+ class FileSystemEventNotification(BaseModel):
33
+ """AppAPI event notification common data."""
34
+
35
+ event_type: str
36
+ event_subtype: str
37
+ event_data: FileSystemEventData
@@ -0,0 +1,137 @@
1
+ """Nextcloud API for registering Events listeners for ExApps."""
2
+
3
+ import dataclasses
4
+
5
+ from .._exceptions import NextcloudExceptionNotFound
6
+ from .._misc import require_capabilities
7
+ from .._session import AsyncNcSessionApp, NcSessionApp
8
+
9
+ _EP_SUFFIX: str = "events_listener"
10
+
11
+
12
+ @dataclasses.dataclass
13
+ class EventsListener:
14
+ """EventsListener description."""
15
+
16
+ def __init__(self, raw_data: dict):
17
+ self._raw_data = raw_data
18
+
19
+ @property
20
+ def event_type(self) -> str:
21
+ """Main type of event, e.g. ``node_event``."""
22
+ return self._raw_data["event_type"]
23
+
24
+ @property
25
+ def event_subtypes(self) -> str:
26
+ """Subtypes for which fire event, e.g. ``NodeCreatedEvent``, ``NodeDeletedEvent``."""
27
+ return self._raw_data["event_subtypes"]
28
+
29
+ @property
30
+ def action_handler(self) -> str:
31
+ """Relative ExApp url which will be called by Nextcloud."""
32
+ return self._raw_data["action_handler"]
33
+
34
+ def __repr__(self):
35
+ return f"<{self.__class__.__name__} event_type={self.event_type}, handler={self.action_handler}>"
36
+
37
+
38
+ class EventsListenerAPI:
39
+ """API for registering Events listeners, avalaible as **nc.events_handler.<method>**."""
40
+
41
+ def __init__(self, session: NcSessionApp):
42
+ self._session = session
43
+
44
+ def register(
45
+ self,
46
+ event_type: str,
47
+ callback_url: str,
48
+ event_subtypes: list[str] | None = None,
49
+ ) -> None:
50
+ """Registers or edits the events listener."""
51
+ if event_subtypes is None:
52
+ event_subtypes = []
53
+ require_capabilities("app_api", self._session.capabilities)
54
+ params = {
55
+ "eventType": event_type,
56
+ "actionHandler": callback_url,
57
+ "eventSubtypes": event_subtypes,
58
+ }
59
+ self._session.ocs("POST", f"{self._session.ae_url}/{_EP_SUFFIX}", json=params)
60
+
61
+ def unregister(self, event_type: str, not_fail=True) -> None:
62
+ """Removes the events listener."""
63
+ require_capabilities("app_api", self._session.capabilities)
64
+ try:
65
+ self._session.ocs(
66
+ "DELETE",
67
+ f"{self._session.ae_url}/{_EP_SUFFIX}",
68
+ params={"eventType": event_type},
69
+ )
70
+ except NextcloudExceptionNotFound as e:
71
+ if not not_fail:
72
+ raise e from None
73
+
74
+ def get_entry(self, event_type: str) -> EventsListener | None:
75
+ """Get information about the event listener."""
76
+ require_capabilities("app_api", self._session.capabilities)
77
+ try:
78
+ return EventsListener(
79
+ self._session.ocs(
80
+ "GET",
81
+ f"{self._session.ae_url}/{_EP_SUFFIX}",
82
+ params={"eventType": event_type},
83
+ )
84
+ )
85
+ except NextcloudExceptionNotFound:
86
+ return None
87
+
88
+
89
+ class AsyncEventsListenerAPI:
90
+ """API for registering Events listeners, avalaible as **nc.events_handler.<method>**."""
91
+
92
+ def __init__(self, session: AsyncNcSessionApp):
93
+ self._session = session
94
+
95
+ async def register(
96
+ self,
97
+ event_type: str,
98
+ callback_url: str,
99
+ event_subtypes: list[str] | None = None,
100
+ ) -> None:
101
+ """Registers or edits the events listener."""
102
+ if event_subtypes is None:
103
+ event_subtypes = []
104
+ require_capabilities("app_api", await self._session.capabilities)
105
+ params = {
106
+ "eventType": event_type,
107
+ "actionHandler": callback_url,
108
+ "eventSubtypes": event_subtypes,
109
+ }
110
+ await self._session.ocs("POST", f"{self._session.ae_url}/{_EP_SUFFIX}", json=params)
111
+
112
+ async def unregister(self, event_type: str, not_fail=True) -> None:
113
+ """Removes the events listener."""
114
+ require_capabilities("app_api", await self._session.capabilities)
115
+ try:
116
+ await self._session.ocs(
117
+ "DELETE",
118
+ f"{self._session.ae_url}/{_EP_SUFFIX}",
119
+ params={"eventType": event_type},
120
+ )
121
+ except NextcloudExceptionNotFound as e:
122
+ if not not_fail:
123
+ raise e from None
124
+
125
+ async def get_entry(self, event_type: str) -> EventsListener | None:
126
+ """Get information about the event listener."""
127
+ require_capabilities("app_api", await self._session.capabilities)
128
+ try:
129
+ return EventsListener(
130
+ await self._session.ocs(
131
+ "GET",
132
+ f"{self._session.ae_url}/{_EP_SUFFIX}",
133
+ params={"eventType": event_type},
134
+ )
135
+ )
136
+ except NextcloudExceptionNotFound:
137
+ return None