Skip to content

Commit 2d7f227

Browse files
authored
add occ example, update pkgs and scopes, bump versions (#1)
* add occ example, update pkgs and scopes, bump versions * remove commands for nc27
1 parent de314cf commit 2d7f227

File tree

5 files changed

+1774
-1854
lines changed

5 files changed

+1774
-1854
lines changed

Makefile

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ help:
99
@echo " "
1010
@echo " build-push build image and upload to ghcr.io"
1111
@echo " "
12-
@echo " run27 install UiExample for Nextcloud 27"
1312
@echo " run28 install UiExample for Nextcloud 28"
13+
@echo " run29 install UiExample for Nextcloud 29"
1414
@echo " run install UiExample for Nextcloud Last"
1515
@echo " "
1616
@echo " For development of this example use PyCharm run configurations. Development is always set for last Nextcloud."
1717
@echo " First run 'UiExample' and then 'make registerXX', after that you can use/debug/develop it and easy test."
1818
@echo " "
19-
@echo " register27 perform registration of running UiExample into the 'manual_install' deploy daemon."
2019
@echo " register28 perform registration of running UiExample into the 'manual_install' deploy daemon."
20+
@echo " register29 perform registration of running UiExample into the 'manual_install' deploy daemon."
2121
@echo " register perform registration of running UiExample into the 'manual_install' deploy daemon."
2222
@echo " "
2323
@echo " L10N (for manual translation):"
@@ -30,46 +30,46 @@ build-push:
3030
docker login ghcr.io
3131
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag ghcr.io/cloud-py-api/ui_example:latest .
3232

33-
.PHONY: run27
34-
run27:
35-
docker exec master-stable27-1 sudo -u www-data php occ app_api:app:unregister ui_example --silent --force || true
36-
docker exec master-stable27-1 sudo -u www-data php occ app_api:app:register ui_example --force-scopes \
37-
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/ui_example/appinfo/info.xml
38-
3933
.PHONY: run28
4034
run28:
4135
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:unregister ui_example --silent --force || true
4236
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:register ui_example --force-scopes \
4337
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/ui_example/appinfo/info.xml
4438

39+
.PHONY: run29
40+
run28:
41+
docker exec master-stable29-1 sudo -u www-data php occ app_api:app:unregister ui_example --silent --force || true
42+
docker exec master-stable29-1 sudo -u www-data php occ app_api:app:register ui_example --force-scopes \
43+
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/ui_example/appinfo/info.xml
44+
4545
.PHONY: run
4646
run:
4747
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:unregister ui_example --silent --force || true
4848
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:register ui_example --force-scopes \
4949
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/ui_example/appinfo/info.xml
5050

51-
.PHONY: register27
52-
register27:
53-
docker exec master-stable27-1 sudo -u www-data php occ app_api:app:unregister ui_example --silent --force || true
54-
docker exec master-stable27-1 rm -rf /tmp/ui_example_l10n && docker cp l10n master-stable27-1:/tmp/ui_example_l10n
55-
docker exec master-stable27-1 sudo -u www-data php occ app_api:app:register ui_example manual_install --json-info \
56-
"{\"id\":\"ui_example\",\"name\":\"UI Example\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":9035,\"scopes\":[],\"system_app\":0, \"translations_folder\":\"\/tmp\/ui_example_l10n\"}" \
57-
--force-scopes --wait-finish
58-
5951
.PHONY: register28
6052
register28:
6153
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:unregister ui_example --silent --force || true
6254
docker exec master-stable28-1 rm -rf /tmp/ui_example_l10n && docker cp l10n master-stable28-1:/tmp/ui_example_l10n
6355
docker exec master-stable28-1 sudo -u www-data php occ app_api:app:register ui_example manual_install --json-info \
64-
"{\"id\":\"ui_example\",\"name\":\"UI Example\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":9035,\"scopes\":[],\"system_app\":0, \"translations_folder\":\"\/tmp\/ui_example_l10n\"}" \
56+
"{\"id\":\"ui_example\",\"name\":\"UI Example\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":9035,\"scopes\":[\"OCC_COMMAND\", \"NOTIFICATIONS\"],\"system_app\":0, \"translations_folder\":\"\/tmp\/ui_example_l10n\"}" \
57+
--force-scopes --wait-finish
58+
59+
.PHONY: register29
60+
register29:
61+
docker exec master-stable29-1 sudo -u www-data php occ app_api:app:unregister ui_example --silent --force || true
62+
docker exec master-stable29-1 rm -rf /tmp/ui_example_l10n && docker cp l10n master-stable29-1:/tmp/ui_example_l10n
63+
docker exec master-stable29-1 sudo -u www-data php occ app_api:app:register ui_example manual_install --json-info \
64+
"{\"id\":\"ui_example\",\"name\":\"UI Example\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":9035,\"scopes\":[\"OCC_COMMAND\", \"NOTIFICATIONS\"],\"system_app\":0, \"translations_folder\":\"\/tmp\/ui_example_l10n\"}" \
6565
--force-scopes --wait-finish
6666

6767
.PHONY: register
6868
register:
6969
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:unregister ui_example --silent --force || true
7070
docker exec master-nextcloud-1 rm -rf /tmp/ui_example_l10n && docker cp l10n master-nextcloud-1:/tmp/ui_example_l10n
7171
docker exec master-nextcloud-1 sudo -u www-data php occ app_api:app:register ui_example manual_install --json-info \
72-
"{\"id\":\"ui_example\",\"name\":\"UI Example\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":9035,\"scopes\":[\"NOTIFICATIONS\"],\"system_app\":0, \"translations_folder\":\"\/tmp\/ui_example_l10n\"}" \
72+
"{\"id\":\"ui_example\",\"name\":\"UI Example\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"port\":9035,\"scopes\":[\"OCC_COMMAND\", \"NOTIFICATIONS\"],\"system_app\":0, \"translations_folder\":\"\/tmp\/ui_example_l10n\"}" \
7373
--force-scopes --wait-finish
7474

7575
.PHONY: translation_templates

appinfo/info.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<bugs>https://github.com/cloud-py-api/ui_example/issues</bugs>
1717
<repository type="git">https://github.com/cloud-py-api/ui_example</repository>
1818
<dependencies>
19-
<nextcloud min-version="27" max-version="29"/>
19+
<nextcloud min-version="28" max-version="30"/>
2020
</dependencies>
2121
<external-app>
2222
<docker-install>
@@ -25,6 +25,8 @@
2525
<image-tag>latest</image-tag>
2626
</docker-install>
2727
<scopes>
28+
<value>OCC_COMMAND</value>
29+
<value>NOTIFICATIONS</value>
2830
</scopes>
2931
<system>false</system>
3032
</external-app>

lib/main.py

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import os
44
import random
5+
import time
56
from contextlib import asynccontextmanager
67
from typing import Annotated
78

89
from fastapi import FastAPI, responses, Header, Request, Depends
10+
from fastapi.responses import StreamingResponse
911
from starlette.middleware.base import BaseHTTPMiddleware
1012
from pydantic import BaseModel
1113

@@ -197,6 +199,38 @@ def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
197199
nc.ui.resources.set_script("top_menu", "first_menu", "js/ui_example-main")
198200
nc.ui.top_menu.register("first_menu", "UI example", "img/app.svg")
199201
nc.ui.files_dropdown_menu.register("test_menu", _("Test menu"), "/test_menu", mime="image/jpeg", icon="img/app-dark.svg")
202+
nc.occ_commands.register("ui_example:ping", "/occ_ping")
203+
nc.occ_commands.register(
204+
"ui_example:setup",
205+
"/occ_setup",
206+
arguments=[
207+
{
208+
"name": "test_arg",
209+
"mode": "required",
210+
"description": "Test argument",
211+
}
212+
],
213+
)
214+
nc.occ_commands.register(
215+
"ui_example:stream",
216+
"/occ_stream",
217+
arguments=[
218+
{
219+
"name": "stream_count",
220+
"mode": "required",
221+
"description": "Number of stream rows",
222+
}
223+
],
224+
options=[
225+
{
226+
"name": "double",
227+
"mode": "optional",
228+
"description": "Double the stream rows",
229+
"default": False,
230+
}
231+
],
232+
)
233+
200234

201235
if nc.srv_version["major"] >= 29:
202236
nc.ui.settings.register_form(SETTINGS_EXAMPLE)
@@ -207,6 +241,9 @@ def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
207241
nc.ui.resources.delete_script("top_menu", "first_menu", "js/ui_example-main")
208242
nc.ui.top_menu.unregister("first_menu")
209243
nc.ui.files_dropdown_menu.unregister("test_menu")
244+
nc.occ_commands.unregister("ui_example:ping")
245+
nc.occ_commands.unregister("ui_example:setup")
246+
nc.occ_commands.unregister("ui_example:stream")
210247
return ""
211248

212249

@@ -238,15 +275,46 @@ async def test_menu_handler(
238275
return responses.Response()
239276

240277

241-
class FileInfo(BaseModel):
242-
getlastmodified: str
243-
getetag: str
244-
getcontenttype: str
245-
fileid: int
246-
permissions: str
247-
size: int
248-
getcontentlength: int
249-
favorite: int
278+
class OccPayload(BaseModel):
279+
arguments: dict | None = None
280+
options: dict | None = None
281+
282+
283+
class OccData(BaseModel):
284+
occ: OccPayload
285+
286+
287+
@APP.post("/occ_ping")
288+
async def occ_ping():
289+
return responses.Response(content="<info>PONG</info>\n")
290+
291+
292+
@APP.post("/occ_setup")
293+
async def occ_setup(data: OccData):
294+
print(f"params: {data}")
295+
test_arg = data.occ.arguments['test_arg']
296+
print(f"test_arg: {test_arg}")
297+
if test_arg == "test":
298+
return responses.Response(content="<info>OK</info>\n")
299+
else:
300+
return responses.Response(content="<error>ERROR</error>\n")
301+
302+
303+
def fake_data_streamer(data: OccData):
304+
stream_count = int(data.occ.arguments['stream_count'])
305+
if not stream_count:
306+
stream_count = 1
307+
if 'double' in data.occ.options:
308+
stream_count *= 2
309+
for i in range(stream_count):
310+
yield f"<info>Test stream row {i}</info>\n"
311+
time.sleep(0.5)
312+
313+
314+
@APP.post("/occ_stream")
315+
async def occ_stream(data: OccData):
316+
print(f"params: {data}")
317+
return StreamingResponse(fake_data_streamer(data), status_code=200, media_type="text/plain")
250318

251319

252320
@APP.post("/nextcloud_file")

0 commit comments

Comments
 (0)