Skip to content

Commit

Permalink
reworked app-scopes definition (#83)
Browse files Browse the repository at this point in the history
CI will fail, waiting for AppEcosystem update

Signed-off-by: Alexander Piskun <[email protected]>
  • Loading branch information
bigcat88 authored Aug 15, 2023
1 parent 8ee8d64 commit e514f26
Show file tree
Hide file tree
Showing 21 changed files with 213 additions and 107 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/analysis-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ jobs:
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[2, 10, 11],\"optional\":[30, 31, 32, 33]},\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
-e --force-scopes
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down Expand Up @@ -290,7 +290,7 @@ jobs:
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[2, 10, 11],\"optional\":[30, 31, 32, 33]},\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
-e --force-scopes
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down Expand Up @@ -429,7 +429,7 @@ jobs:
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[2, 10, 11],\"optional\":[30, 31, 32, 33]},\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
-e --force-scopes
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down Expand Up @@ -549,7 +549,7 @@ jobs:
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[2, 10, 11],\"optional\":[30, 31, 32, 33]},\"port\":$APP_PORT,\"protocol\":\"http\",\"system_app\":1}" \
-e --force-scopes
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down Expand Up @@ -794,7 +794,7 @@ jobs:
cd ..
php occ app_ecosystem_v2:daemon:register manual_install "Manual Install" manual-install 0 0 0
php occ app_ecosystem_v2:app:register $APP_ID manual_install --json-info \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"protocol\":\"http\",\"port\":$APP_PORT,\"system_app\":1}" \
"{\"appid\":\"$APP_ID\",\"name\":\"$APP_ID\",\"daemon_config_name\":\"manual_install\",\"version\":\"$APP_VERSION\",\"secret\":\"$APP_SECRET\",\"host\":\"localhost\",\"scopes\":{\"required\":[2, 10, 11],\"optional\":[30, 31, 32, 33]},\"protocol\":\"http\",\"port\":$APP_PORT,\"system_app\":1}" \
-e --force-scopes
kill -15 $(cat /tmp/_install.pid)
timeout 3m tail --pid=$(cat /tmp/_install.pid) -f /dev/null
Expand Down
4 changes: 2 additions & 2 deletions .run/to_gif.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
<env name="APP_ID" value="to_gif" />
<env name="APP_PORT" value="9029" />
<env name="APP_SECRET" value="12345" />
<env name="APP_VERSION" value="1.0.0" />
<env name="NEXTCLOUD_URL" value="http://nextcloud.local/index.php" />
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/examples/as_app/to_gif/main.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/examples/as_app/to_gif/src/main.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ All notable changes to this project will be documented in this file.
### Added

- `Nextcloud.response_headers` property, to get headers from last response.
### Changed

- Reworked `External API` declarations, skeleton made much simpler.

## [0.0.29 - 2023-08-13]

Expand Down
20 changes: 20 additions & 0 deletions examples/COPYING
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
10 changes: 10 additions & 0 deletions examples/as_app/skeleton/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM python:3.11.4-slim-bookworm

COPY requirements.txt /
ADD /src/ /app/

RUN \
python3 -m pip install -r requirements.txt && rm -rf ~/.cache && rm requirements.txt

WORKDIR /app
ENTRYPOINT ["python3", "main.py"]
46 changes: 46 additions & 0 deletions examples/as_app/skeleton/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.DEFAULT_GOAL := help

.PHONY: help
help:
@echo "Welcome to app_python_skeleton example. Please use \`make <target>\` where <target> is one of"
@echo " "
@echo " Next commands are only for dev environment with nextcloud-docker-dev!"
@echo " They should run from the host you are developing on(with activated venv) and not in the container with Nextcloud!"
@echo " "
@echo " build-push build image and upload to ghcr.io"
@echo " "
@echo " deploy deploy example to registered 'docker_dev'"
@echo " "
@echo " run28 install app_python_skeleton for Nextcloud 28"
@echo " run27 install app_python_skeleton for Nextcloud 27"
@echo " "
@echo " For development of this example use PyCharm run configurations. Development is always set for last Nextcloud."
@echo " First run 'app_python_skeleton' and then 'make manual_register', after that you can use/debug/develop it and easy test."
@echo " "
@echo " manual_register perform registration of running 'app_python_skeleton' into 'manual_install' deploy daemon."

.PHONY: build-push
build-push:
docker login ghcr.io
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag ghcr.io/cloud-py-api/py_app_v2-skeleton:latest .

.PHONY: deploy
deploy:
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:deploy app_python_skeleton docker_dev \
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/skeleton/appinfo/info.xml

.PHONY: run28
run28:
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:unregister app_python_skeleton --silent || true
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:register app_python_skeleton docker_dev -e --force-scopes

.PHONY: run27
run27:
docker exec master-stable27-1 sudo -u www-data php occ app_ecosystem_v2:app:unregister app_python_skeleton --silent || true
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:register app_python_skeleton docker_dev -e --force-scopes

.PHONY: manual_register
manual_register:
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:register app_python_skeleton manual_install --json-info \
"{\"appid\":\"app_python_skeleton\",\"name\":\"App Python Skeleton\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"host\":\"host.docker.internal\",\"port\":9029,\"scopes\":{\"required\":[],\"optional\":[]},\"protocol\":\"http\",\"system_app\":0}" \
-e --force-scopes
36 changes: 36 additions & 0 deletions examples/as_app/skeleton/appinfo/info.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0"?>
<info>
<id>app_python_skeleton</id>
<name>App Python Skeleton</name>
<summary>Nextcloud Python Application Skeleton</summary>
<description>
<![CDATA[Example of the Nextcloud application written in python]]>
</description>
<version>1.0.0</version>
<licence>MIT</licence>
<author mail="[email protected]" homepage="https://github.com/andrey18106">Andrey Borysenko</author>
<author mail="[email protected]" homepage="https://github.com/bigcat88">Alexander Piskun</author>
<namespace>PyAppV2_skeleton</namespace>
<category>tools</category>
<website>https://github.com/cloud-py-api/nc_py_api</website>
<bugs>https://github.com/cloud-py-api/nc_py_api/issues</bugs>
<repository type="git">https://github.com/cloud-py-api/nc_py_api</repository>
<dependencies>
<nextcloud min-version="27" max-version="28"/>
</dependencies>
<ex-app>
<docker-install>
<registry>ghcr.io</registry>
<image>cloud-py-api/py_app_v2-skeleton</image>
<image-tag>latest</image-tag>
</docker-install>
<scopes>
<required>
</required>
<optional>
</optional>
</scopes>
<protocol>http</protocol>
<system>0</system>
</ex-app>
</info>
1 change: 1 addition & 0 deletions examples/as_app/skeleton/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nc_py_api[app]
27 changes: 27 additions & 0 deletions examples/as_app/skeleton/src/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""
Simplest example.
"""

from fastapi import FastAPI

from nc_py_api import NextcloudApp
from nc_py_api.ex_app import LogLvl, run_app

APP = FastAPI()


def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
# This will be called each time application is `enabled` or `disabled`
# All scopes that application required already granted before this step.
# NOTE: `user` is unavailable on this step, so all NC API calls that require it will fail as unauthorized.
print(f"enabled={enabled}")
if enabled:
nc.log(LogLvl.WARNING, f"Hello from {nc.app_cfg.app_name} :)")
else:
nc.log(LogLvl.WARNING, f"Bye bye from {nc.app_cfg.app_name} :(")
# In case of an error, a non-empty short string should be returned, which will be shown to the NC administrator.
return ""


if __name__ == "__main__":
run_app(APP, enabled_handler, "main:APP", log_level="trace")
4 changes: 2 additions & 2 deletions examples/as_app/to_gif/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
FROM python:3.11.4-bookworm

COPY requirements.txt /
ADD main.py /app/
ADD /src/ /app/

RUN \
apt-get update && \
apt-get install -y \
ffmpeg libsm6 libxext6 gifsicle

RUN \
python3 -m pip install -r requirements.txt
python3 -m pip install -r requirements.txt && rm -rf ~/.cache && rm requirements.txt

WORKDIR /app
ENTRYPOINT ["python3", "main.py"]
4 changes: 2 additions & 2 deletions examples/as_app/to_gif/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ build-push:
.PHONY: deploy
deploy:
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:deploy to_gif docker_dev \
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/to_gif/info.xml
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/to_gif/appinfo/info.xml

.PHONY: run28
run28:
Expand All @@ -42,5 +42,5 @@ run27:
.PHONY: manual_register
manual_register:
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:register to_gif manual_install --json-info \
"{\"appid\":\"to_gif\",\"name\":\"to_gif\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"host\":\"host.docker.internal\",\"port\":9029,\"protocol\":\"http\",\"system_app\":0}" \
"{\"appid\":\"to_gif\",\"name\":\"to_gif\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"host\":\"host.docker.internal\",\"port\":9029,\"scopes\":{\"required\":[10],\"optional\":[32]},\"protocol\":\"http\",\"system_app\":0}" \
-e --force-scopes
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
<version>1.0.0</version>
<licence>MIT</licence>
<author mail="[email protected]" homepage="https://github.com/andrey18106">Andrey Borysenko</author>
<author mail="[email protected]" homepage="https://github.com/bigcat88">Alexander Piskun</author>
<namespace>ToGifExample</namespace>
<category>tools</category>
<website>https://github.com/cloud-py-api/nc_py_apy</website>
<bugs>https://github.com/cloud-py-api/nc_py_apy/issues</bugs>
<repository type="git">https://github.com/cloud-py-api/nc_py_apy</repository>
<website>https://github.com/cloud-py-api/nc_py_api</website>
<bugs>https://github.com/cloud-py-api/nc_py_api/issues</bugs>
<repository type="git">https://github.com/cloud-py-api/nc_py_api</repository>
<dependencies>
<nextcloud min-version="27" max-version="28"/>
</dependencies>
Expand All @@ -23,6 +24,14 @@
<image>cloud-py-api/to_gif</image>
<image-tag>latest</image-tag>
</docker-install>
<scopes>
<required>
<value>2</value>
</required>
<optional>
<value>32</value>
</optional>
</scopes>
<protocol>http</protocol>
<system>0</system>
</ex-app>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
"""Simplest example of files_dropdown_menu + notification."""

import tempfile
from os import environ, path
from os import path
from typing import Annotated

import cv2
import imageio
import numpy
import urllib3
import uvicorn
from fastapi import BackgroundTasks, Depends, FastAPI
from pygifsicle import optimize
from requests import Response

from nc_py_api import NextcloudApp
from nc_py_api.ex_app import (
ApiScope,
LogLvl,
UiActionFileInfo,
UiFileActionHandlerInfo,
enable_heartbeat,
nc_app,
set_enabled_handler,
set_scopes,
run_app,
)

APP = FastAPI()
Expand Down Expand Up @@ -93,13 +88,10 @@ def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
return ""


@APP.on_event("startup")
def initialization():
set_enabled_handler(APP, enabled_handler)
set_scopes(APP, {"required": [ApiScope.DAV], "optional": [ApiScope.NOTIFICATIONS]})
enable_heartbeat(APP)


if __name__ == "__main__":
urllib3.disable_warnings()
uvicorn.run("main:APP", host=environ.get("APP_HOST", "127.0.0.1"), port=int(environ["APP_PORT"]), log_level="trace")
run_app(
APP,
enabled_handler,
"main:APP",
log_level="trace",
)
8 changes: 2 additions & 6 deletions nc_py_api/ex_app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
"""All possible ExApp stuff for NextcloudApp that can be used."""
from .defs import ApiScope, LogLvl
from .integration_fastapi import (
enable_heartbeat,
nc_app,
set_enabled_handler,
set_scopes,
)
from .integration_fastapi import nc_app
from .ui.files import UiActionFileInfo, UiFileActionHandlerInfo
from .uvicorn_fastapi import run_app
22 changes: 7 additions & 15 deletions nc_py_api/ex_app/defs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Additional definitions for NextcloudApp."""

import enum
import typing


class LogLvl(enum.IntEnum):
Expand All @@ -24,22 +23,15 @@ class ApiScope(enum.IntEnum):

SYSTEM = 2
"""Allows access to the System APIs."""
DAV = 3
FILES = 10
"""Allows access to the Nextcloud file base."""
USER_INFO = 10
FILES_SHARING = 11
"""Allows access to APIs that provide File Sharing."""
USER_INFO = 30
"""Allows access to APIs that work with users."""
USER_STATUS = 11
USER_STATUS = 31
"""Allows access to APIs that work with users statuses."""
NOTIFICATIONS = 12
NOTIFICATIONS = 32
"""Allows access to APIs that provide Notifications."""
WEATHER_STATUS = 13
WEATHER_STATUS = 33
"""Allows access to APIs that provide Weather status."""
FILES_SHARING = 14
"""Allows access to APIs that provide File Sharing."""


class ApiScopesStruct(typing.TypedDict):
"""Reply of the Nextcloud App with the desired scopes."""

required: list[int]
optional: list[int]
Loading

0 comments on commit e514f26

Please sign in to comment.