Skip to content

Commit 22c6fba

Browse files
authored
Merge branch 'main' into pre-commit-ci-update-config
2 parents 05df3ba + bbf3007 commit 22c6fba

File tree

10 files changed

+123
-45
lines changed

10 files changed

+123
-45
lines changed

.github/workflows/analysis-coverage.yml

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ jobs:
106106
uses: actions/checkout@v4
107107
with:
108108
path: apps/app_api
109-
repository: cloud-py-api/app_api
109+
repository: nextcloud/app_api
110+
ref: stable29
110111

111112
- name: Install AppAPI
112113
run: |
@@ -248,7 +249,8 @@ jobs:
248249
uses: actions/checkout@v4
249250
with:
250251
path: apps/app_api
251-
repository: cloud-py-api/app_api
252+
repository: nextcloud/app_api
253+
ref: stable29
252254

253255
- name: Install AppAPI
254256
run: |
@@ -390,7 +392,8 @@ jobs:
390392
uses: actions/checkout@v4
391393
with:
392394
path: apps/app_api
393-
repository: cloud-py-api/app_api
395+
repository: nextcloud/app_api
396+
ref: stable29
394397

395398
- name: Install AppAPI
396399
run: |
@@ -525,10 +528,19 @@ jobs:
525528
run: python3 -m pip -v install ".[dev]"
526529

527530
- name: Checkout AppAPI
531+
if: ${{ matrix.nextcloud != 'master' }}
528532
uses: actions/checkout@v4
529533
with:
530534
path: apps/app_api
531-
repository: cloud-py-api/app_api
535+
repository: nextcloud/app_api
536+
ref: stable29
537+
538+
- name: Checkout AppAPI
539+
if: ${{ matrix.nextcloud == 'master' }}
540+
uses: actions/checkout@v4
541+
with:
542+
path: apps/app_api
543+
repository: nextcloud/app_api
532544

533545
- name: Install AppAPI
534546
run: |
@@ -692,10 +704,19 @@ jobs:
692704
run: python3 -m pip -v install ".[dev]"
693705

694706
- name: Checkout AppAPI
707+
if: ${{ matrix.nextcloud != 'master' }}
708+
uses: actions/checkout@v4
709+
with:
710+
path: apps/app_api
711+
repository: nextcloud/app_api
712+
ref: stable29
713+
714+
- name: Checkout AppAPI
715+
if: ${{ matrix.nextcloud == 'master' }}
695716
uses: actions/checkout@v4
696717
with:
697718
path: apps/app_api
698-
repository: cloud-py-api/app_api
719+
repository: nextcloud/app_api
699720

700721
- name: Install AppAPI
701722
run: |

examples/as_app/to_gif/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.11-bookworm
1+
FROM python:3-bookworm
22

33
COPY requirements.txt /
44

examples/as_app/to_gif/Makefile

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,82 @@
11
.DEFAULT_GOAL := help
22

3+
GITHUB_USERNAME := cloud-py-api
4+
5+
APP_ID := to_gif
6+
APP_NAME := ToGif
7+
APP_VERSION := 1.0.0
8+
APP_SECRET := 12345
9+
APP_PORT := 9031
10+
11+
JSON_INFO := "{\"id\":\"$(APP_ID)\",\"name\":\"$(APP_NAME)\",\"daemon_config_name\":\"manual_install\",\"version\":\"$(APP_VERSION)\",\"secret\":\"$(APP_SECRET)\",\"port\":$(APP_PORT),\"routes\":[{\"url\":\".*\",\"verb\":\"GET, POST, PUT, DELETE\",\"access_level\":1,\"headers_to_exclude\":[]}]}"
12+
313
.PHONY: help
414
help:
5-
@echo "Welcome to ToGif example. Please use \`make <target>\` where <target> is one of"
15+
@echo "Welcome to $(APP_NAME). Please use \`make <target>\` where <target> is one of"
616
@echo " "
717
@echo " Next commands are only for dev environment with nextcloud-docker-dev!"
818
@echo " They should run from the host you are developing on(with activated venv) and not in the container with Nextcloud!"
919
@echo " "
1020
@echo " build-push build image and upload to ghcr.io"
1121
@echo " "
12-
@echo " run28 install ToGif for Nextcloud 28"
13-
@echo " run install ToGif for Nextcloud Last"
22+
@echo " run28 install $(APP_NAME) for Nextcloud 28"
23+
@echo " run29 install $(APP_NAME) for Nextcloud 29"
24+
@echo " run30 install $(APP_NAME) for Nextcloud 30"
25+
@echo " run install $(APP_NAME) for Nextcloud Latest"
1426
@echo " "
15-
@echo " For development of this example use PyCharm run configurations. Development is always set for last Nextcloud."
16-
@echo " First run 'ToGif' and then 'make registerXX', after that you can use/debug/develop it and easy test."
27+
@echo " For development of this example use PyCharm run configurations. Development is always set to the latest version of Nextcloud."
28+
@echo " First run '$(APP_NAME)' and then 'make registerXX', after that you can use/debug/develop it and easy test."
1729
@echo " "
18-
@echo " register28 perform registration of running 'to_gif' into the 'manual_install' deploy daemon."
19-
@echo " register perform registration of running 'to_gif' into the 'manual_install' deploy daemon."
30+
@echo " register28 perform registration of running '$(APP_ID)' into the 'manual_install' deploy daemon."
31+
@echo " register29 perform registration of running '$(APP_ID)' into the 'manual_install' deploy daemon."
32+
@echo " register30 perform registration of running '$(APP_ID)' into the 'manual_install' deploy daemon."
33+
@echo " register perform registration of running '$(APP_ID)' into the 'manual_install' deploy daemon."
2034

2135
.PHONY: build-push
2236
build-push:
2337
docker login ghcr.io
24-
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag ghcr.io/cloud-py-api/to_gif:latest .
38+
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag ghcr.io/$(GITHUB_USERNAME)/$(APP_ID):latest .
2539

2640
.PHONY: run28
2741
run28:
28-
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:unregister to_gif --silent --force || true
29-
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:register to_gif --force-scopes \
30-
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/to_gif/appinfo/info.xml
42+
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:unregister $(APP_ID) --silent --force || true
43+
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:register $(APP_ID) --force-scopes \
44+
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/$(APP_ID)/appinfo/info.xml
45+
46+
.PHONY: run29
47+
run29:
48+
docker exec master-stable29-1 sudo -u www-data php occ app_api:app:unregister $(APP_ID) --silent --force || true
49+
docker exec master-stable29-1 sudo -u www-data php occ app_api:app:register $(APP_ID) --force-scopes \
50+
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/$(APP_ID)/appinfo/info.xml
51+
52+
.PHONY: run30
53+
run30:
54+
docker exec master-stable30-1 sudo -u www-data php occ app_api:app:unregister $(APP_ID) --silent --force || true
55+
docker exec master-stable30-1 sudo -u www-data php occ app_api:app:register $(APP_ID) --force-scopes \
56+
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/$(APP_ID)/appinfo/info.xml
3157

3258
.PHONY: run
3359
run:
34-
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:unregister to_gif --silent --force || true
35-
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:register to_gif --force-scopes \
36-
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/to_gif/appinfo/info.xml
60+
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:unregister $(APP_ID) --silent --force || true
61+
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:register $(APP_ID) --force-scopes \
62+
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/$(APP_ID)/appinfo/info.xml
3763

3864
.PHONY: register28
3965
register28:
40-
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:unregister to_gif --silent --force || true
41-
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:register to_gif manual_install --json-info \
42-
"{\"id\":\"to_gif\",\"name\":\"to_gif\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":9031,\"scopes\":[\"FILES\", \"NOTIFICATIONS\"]}" \
43-
--force-scopes --wait-finish
66+
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:unregister $(APP_ID) --silent --force || true
67+
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:register $(APP_ID) manual_install --json-info $(JSON_INFO) --force-scopes --wait-finish
68+
69+
.PHONY: register29
70+
register29:
71+
docker exec master-stable29-1 sudo -u www-data php occ app_api:app:unregister $(APP_ID) --silent --force || true
72+
docker exec master-stable29-1 sudo -u www-data php occ app_api:app:register $(APP_ID) manual_install --json-info $(JSON_INFO) --force-scopes --wait-finish
73+
74+
.PHONY: register30
75+
register30:
76+
docker exec master-stable30-1 sudo -u www-data php occ app_api:app:unregister $(APP_ID) --silent --force || true
77+
docker exec master-stable30-1 sudo -u www-data php occ app_api:app:register $(APP_ID) manual_install --json-info $(JSON_INFO) --force-scopes --wait-finish
4478

4579
.PHONY: register
4680
register:
47-
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:unregister to_gif --silent --force || true
48-
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:register to_gif manual_install --json-info \
49-
"{\"id\":\"to_gif\",\"name\":\"to_gif\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":9031,\"scopes\":[\"FILES\", \"NOTIFICATIONS\"]}" \
50-
--force-scopes --wait-finish
81+
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:unregister $(APP_ID) --silent --force || true
82+
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:register $(APP_ID) manual_install --json-info $(JSON_INFO) --force-scopes --wait-finish

examples/as_app/to_gif/appinfo/info.xml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<name>ToGif</name>
55
<summary>Nextcloud To Gif Example</summary>
66
<description>
7-
<![CDATA[Example of the Nextcloud application written in python]]>
7+
<![CDATA[Example of a Nextcloud application written in Python]]>
88
</description>
99
<version>1.0.0</version>
1010
<licence>MIT</licence>
@@ -16,17 +16,21 @@
1616
<bugs>https://github.com/cloud-py-api/nc_py_api/issues</bugs>
1717
<repository type="git">https://github.com/cloud-py-api/nc_py_api</repository>
1818
<dependencies>
19-
<nextcloud min-version="28" max-version="30"/>
19+
<nextcloud min-version="28" max-version="31"/>
2020
</dependencies>
2121
<external-app>
2222
<docker-install>
2323
<registry>ghcr.io</registry>
2424
<image>cloud-py-api/to_gif</image>
2525
<image-tag>latest</image-tag>
2626
</docker-install>
27-
<scopes>
28-
<value>FILES</value>
29-
<value>NOTIFICATIONS</value>
30-
</scopes>
27+
<routes>
28+
<route>
29+
<url>.*</url>
30+
<verb>GET,POST,PUT,DELETE</verb>
31+
<access_level>USER</access_level>
32+
<headers_to_exclude>[]</headers_to_exclude>
33+
</route>
34+
</routes>
3135
</external-app>
3236
</info>

examples/as_app/to_gif/lib/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
8585
if enabled:
8686
nc.ui.files_dropdown_menu.register_ex(
8787
"to_gif",
88-
"TO GIF",
88+
"To GIF",
8989
"/video_to_gif",
9090
mime="video",
9191
icon="img/icon.svg",

nc_py_api/_session.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def _response_event(self, response: Response) -> None:
301301

302302
def download2fp(self, url_path: str, fp, dav: bool, params=None, **kwargs):
303303
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", None)) as response:
305305
check_error(response)
306306
for data_chunk in response.iter_raw(chunk_size=kwargs.get("chunk_size", 5 * 1024 * 1024)):
307307
fp.write(data_chunk)
@@ -425,7 +425,7 @@ async def _response_event(self, response: Response) -> None:
425425

426426
async def download2fp(self, url_path: str, fp, dav: bool, params=None, **kwargs):
427427
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", None)) as response:
429429
check_error(response)
430430
async for data_chunk in response.aiter_raw(chunk_size=kwargs.get("chunk_size", 5 * 1024 * 1024)):
431431
fp.write(data_chunk)

nc_py_api/files/files.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,14 @@ def download_directory_as_zip(self, path: str | FsNode, local_path: str | Path |
115115
path = path.user_path if isinstance(path, FsNode) else path
116116
result_path = local_path if local_path else os.path.basename(path)
117117
with open(result_path, "wb") as fp:
118-
self._session.download2fp(
119-
"/index.php/apps/files/ajax/download.php", fp, dav=False, params={"dir": path}, **kwargs
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+
)
121126
return Path(result_path)
122127

123128
def upload(self, path: str | FsNode, content: bytes | str) -> FsNode:

nc_py_api/files/files_async.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,14 @@ async def download_directory_as_zip(
119119
path = path.user_path if isinstance(path, FsNode) else path
120120
result_path = local_path if local_path else os.path.basename(path)
121121
with open(result_path, "wb") as fp:
122-
await self._session.download2fp(
123-
"/index.php/apps/files/ajax/download.php", fp, dav=False, params={"dir": path}, **kwargs
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+
)
125130
return Path(result_path)
126131

127132
async def upload(self, path: str | FsNode, content: bytes | str) -> FsNode:

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ messages_control.disable = [
207207
"too-few-public-methods",
208208
"too-many-public-methods",
209209
"too-many-instance-attributes",
210+
"too-many-positional-arguments",
210211
]
211212

212213
[tool.pytest.ini_options]

tests/actual_tests/weather_status_test.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ async def test_available_async(anc):
1313

1414

1515
def test_get_set_location(nc_any):
16-
nc_any.weather_status.set_location(longitude=0.0, latitude=0.0)
16+
try:
17+
nc_any.weather_status.set_location(longitude=0.0, latitude=0.0)
18+
except NextcloudException as e:
19+
if e.status_code in (408, 500, 996):
20+
pytest.skip("Some network problem on the host")
21+
raise e from None
1722
loc = nc_any.weather_status.get_location()
1823
assert loc.latitude == 0.0
1924
assert loc.longitude == 0.0
@@ -42,7 +47,12 @@ def test_get_set_location(nc_any):
4247

4348
@pytest.mark.asyncio(scope="session")
4449
async def test_get_set_location_async(anc_any):
45-
await anc_any.weather_status.set_location(longitude=0.0, latitude=0.0)
50+
try:
51+
await anc_any.weather_status.set_location(longitude=0.0, latitude=0.0)
52+
except NextcloudException as e:
53+
if e.status_code in (408, 500, 996):
54+
pytest.skip("Some network problem on the host")
55+
raise e from None
4656
loc = await anc_any.weather_status.get_location()
4757
assert loc.latitude == 0.0
4858
assert loc.longitude == 0.0

0 commit comments

Comments
 (0)