Skip to content

Commit 4b1370e

Browse files
authoredAug 7, 2023
updating to_gif example (#65)
Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
·
v0.20.2v0.0.28
1 parent c2967fc commit 4b1370e

File tree

7 files changed

+113
-78
lines changed

7 files changed

+113
-78
lines changed
 

‎.github/workflows/analysis-coverage.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,8 +750,7 @@ jobs:
750750
permissions:
751751
contents: none
752752
runs-on: ubuntu-22.04
753-
needs: [tests-maria, tests-pgsql, tests-oci, tests-latest-maria-full]
754-
# needs: [tests-maria, tests-pgsql, tests-oci, tests-sqlite, tests-latest-maria-full, test-latest-pgsql-client]
753+
needs: [tests-maria, tests-pgsql, tests-oci, tests-sqlite, tests-latest-maria-full, test-latest-pgsql-client]
755754
name: Tests-OK
756755
steps:
757756
- run: echo "Tests passed successfully"

‎.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ vendor
2424
/out
2525
/dev/
2626
local
27-
.run/
2827
tmp
2928
.phpdoc
3029
clover.unit.xml

‎.run/to_gif.run.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="to_gif" type="PythonConfigurationType" factoryName="Python">
3+
<module name="nc_py_api" />
4+
<option name="INTERPRETER_OPTIONS" value="" />
5+
<option name="PARENT_ENVS" value="true" />
6+
<envs>
7+
<env name="APP_ID" value="to_gif" />
8+
<env name="APP_PORT" value="9029" />
9+
<env name="APP_SECRET" value="12345" />
10+
<env name="APP_VERSION" value="1.0.0" />
11+
<env name="NEXTCLOUD_URL" value="http://nextcloud.local/index.php" />
12+
<env name="PYTHONUNBUFFERED" value="1" />
13+
</envs>
14+
<option name="SDK_HOME" value="" />
15+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
16+
<option name="IS_MODULE_SDK" value="true" />
17+
<option name="ADD_CONTENT_ROOTS" value="true" />
18+
<option name="ADD_SOURCE_ROOTS" value="true" />
19+
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
20+
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/examples/as_app/to_gif/main.py" />
21+
<option name="PARAMETERS" value="" />
22+
<option name="SHOW_COMMAND_LINE" value="false" />
23+
<option name="EMULATE_TERMINAL" value="false" />
24+
<option name="MODULE_MODE" value="false" />
25+
<option name="REDIRECT_INPUT" value="false" />
26+
<option name="INPUT_FILE" value="" />
27+
<method v="2" />
28+
</configuration>
29+
</component>

‎examples/as_app/to_gif/Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ FROM python:3.11.4-bookworm
22

33
COPY requirements.txt /
44
ADD main.py /app/
5-
ADD nc_py_api /app/nc_py_api
65

76
RUN \
87
apt-get update && \

‎examples/as_app/to_gif/Makefile

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,44 @@
33
.PHONY: help
44
help:
55
@echo "Welcome to ToGif example. Please use \`make <target>\` where <target> is one of"
6-
@echo " docs make HTML docs"
7-
@echo " html make HTML docs"
8-
@echo " "
6+
@echo " "
97
@echo " Next commands are only for dev environment with nextcloud-docker-dev!"
108
@echo " They should run from the host you are developing on(with activated venv) and not in the container with Nextcloud!"
119
@echo " "
12-
@echo " register28 register nc_py_api for Nextcloud 28"
13-
@echo " register27 register nc_py_api for Nextcloud 27"
14-
@echo " register26 register nc_py_api for Nextcloud 26"
10+
@echo " build-push build image and upload to ghcr.io"
1511
@echo " "
16-
@echo " tests28 run nc_py_api tests for Nextcloud 28"
17-
@echo " tests27 run nc_py_api tests for Nextcloud 27"
18-
@echo " tests26 run nc_py_api tests for Nextcloud 26"
19-
20-
.PHONY: register28
21-
register28:
22-
/bin/sh scripts/dev_register.sh master-nextcloud-1 nextcloud.local
12+
@echo " deploy deploy example to registered 'docker_dev'"
13+
@echo " "
14+
@echo " run28 install ToGif for Nextcloud 28"
15+
@echo " run27 install ToGif for Nextcloud 27"
16+
@echo " "
17+
@echo " For development of this example use PyCharm run configurations. Development is always set for last Nextcloud."
18+
@echo " First run 'to_gif' and then 'make manual_register', after that you can use/debug/develop it and easy test."
19+
@echo " "
20+
@echo " manual_register perform registration of running 'to_gif' into 'manual_install' deploy daemon."
2321

24-
.PHONY: register27
25-
register27:
26-
/bin/sh scripts/dev_register.sh master-stable27-1 stable27.local
22+
.PHONY: build-push
23+
build-push:
24+
docker login ghcr.io
25+
docker buildx build --push --platform linux/arm64/v8,linux/amd64 --tag ghcr.io/cloud-py-api/to_gif:latest .
2726

28-
.PHONY: register26
29-
register26:
30-
/bin/sh scripts/dev_register.sh master-stable26-1 stable26.local
27+
.PHONY: deploy
28+
deploy:
29+
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:deploy to_gif docker_dev \
30+
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/to_gif/info.xml
3131

32-
.PHONY: tests28
33-
tests28:
34-
NEXTCLOUD_URL=http://nextcloud.local python3 -m pytest
32+
.PHONY: run28
33+
run28:
34+
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:unregister to_gif --silent || true
35+
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:register to_gif docker_dev -e --force-scopes
3536

36-
.PHONY: tests27
37-
tests27:
38-
NEXTCLOUD_URL=http://stable27.local python3 -m pytest
37+
.PHONY: run27
38+
run27:
39+
docker exec master-stable27-1 sudo -u www-data php occ app_ecosystem_v2:app:unregister to_gif --silent || true
40+
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:register to_gif docker_dev -e --force-scopes
3941

40-
.PHONY: tests26
41-
tests26:
42-
NEXTCLOUD_URL=http://stable26.local python3 -m pytest
42+
.PHONY: manual_register
43+
manual_register:
44+
docker exec master-nextcloud-1 sudo -u www-data php occ app_ecosystem_v2:app:register to_gif manual_install --json-info \
45+
"{\"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}" \
46+
-e --force-scopes

‎examples/as_app/to_gif/main.py

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,93 @@
1-
"""
2-
Simplest example.
3-
"""
1+
"""Simplest example of files_dropdown_menu + notification."""
42

5-
from os import path, environ
3+
import tempfile
4+
from os import environ, path
65
from typing import Annotated
76

8-
import uvicorn
9-
from fastapi import FastAPI, Depends
10-
from requests import Response
11-
import urllib3
12-
13-
import tempfile
14-
from pygifsicle import optimize
15-
import imageio
167
import cv2
8+
import imageio
179
import numpy
10+
import urllib3
11+
import uvicorn
12+
from fastapi import BackgroundTasks, Depends, FastAPI
13+
from pygifsicle import optimize
14+
from requests import Response
1815

19-
from nc_py_api import UiFileActionHandlerInfo, LogLvl, NextcloudApp, nc_app, set_enabled_handler, ApiScope, set_scopes
16+
from nc_py_api import (
17+
ApiScope,
18+
GuiActionFileInfo,
19+
GuiFileActionHandlerInfo,
20+
LogLvl,
21+
NextcloudApp,
22+
enable_heartbeat,
23+
nc_app,
24+
set_enabled_handler,
25+
set_scopes,
26+
)
2027

2128
APP = FastAPI()
2229

2330

24-
@APP.post("/video_to_gif")
25-
async def video_to_gif(
26-
file: UiFileActionHandlerInfo,
27-
nc: Annotated[NextcloudApp, Depends(nc_app)],
28-
):
29-
source_path = path.join(file.actionFile.dir, file.actionFile.name)
31+
def convert_video_to_gif(input_params: GuiActionFileInfo, nc: NextcloudApp):
32+
source_path = path.join(input_params.directory, input_params.name)
3033
save_path = path.splitext(source_path)[0] + ".gif"
3134
nc.log(LogLvl.WARNING, f"Processing:{source_path} -> {save_path}")
32-
source_file = nc.files.download(source_path)
33-
nc.log(LogLvl.WARNING, "File downloaded")
3435
try:
3536
with tempfile.NamedTemporaryFile(mode="w+b") as tmp_in:
36-
tmp_in.write(source_file)
37+
nc.files.download2stream(source_path, tmp_in)
38+
nc.log(LogLvl.WARNING, "File downloaded")
3739
tmp_in.flush()
3840
cap = cv2.VideoCapture(tmp_in.name)
3941
with tempfile.NamedTemporaryFile(mode="w+b", suffix=".gif") as tmp_out:
4042
image_lst = []
4143
previous_frame = None
44+
skip = 0
4245
while True:
46+
skip += 1
4347
ret, frame = cap.read()
48+
if frame is None:
49+
break
50+
if skip == 2:
51+
skip = 0
52+
continue
4453
if previous_frame is not None:
4554
diff = numpy.mean(previous_frame != frame)
4655
if diff < 0.91:
4756
continue
48-
if frame is None:
49-
break
5057
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
5158
image_lst.append(frame_rgb)
5259
previous_frame = frame
60+
if len(image_lst) > 60:
61+
break
5362
cap.release()
5463
imageio.mimsave(tmp_out.name, image_lst)
5564
optimize(tmp_out.name)
5665
nc.log(LogLvl.WARNING, "GIF is ready")
57-
nc.files.upload(save_path, content=tmp_out.read())
66+
nc.files.upload_stream(save_path, tmp_out)
5867
nc.log(LogLvl.WARNING, "Result uploaded")
68+
nc.users.notifications.create(f"{input_params.name} finished!", f"{save_path} is waiting for you!")
5969
except Exception as e:
6070
nc.log(LogLvl.ERROR, str(e))
71+
nc.users.notifications.create("Error occurred", "Error information was written to log file")
72+
73+
74+
@APP.post("/video_to_gif")
75+
async def video_to_gif(
76+
file: GuiFileActionHandlerInfo,
77+
nc: Annotated[NextcloudApp, Depends(nc_app)],
78+
background_tasks: BackgroundTasks,
79+
):
80+
background_tasks.add_task(convert_video_to_gif, file.actionFile, nc)
6181
return Response()
6282

6383

6484
def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
6585
print(f"enabled={enabled}")
6686
try:
6787
if enabled:
68-
nc.ui_files_actions.register("to_gif", "TO GIF", "/video_to_gif", mime="video")
88+
nc.gui.files_dropdown_menu.register("to_gif", "TO GIF", "/video_to_gif", mime="video")
6989
else:
70-
nc.ui_files_actions.unregister("to_gif")
90+
nc.gui.files_dropdown_menu.unregister("to_gif")
7191
except Exception as e:
7292
return str(e)
7393
return ""
@@ -76,25 +96,10 @@ def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
7696
@APP.on_event("startup")
7797
def initialization():
7898
set_enabled_handler(APP, enabled_handler)
79-
set_scopes(APP, {
80-
"required": [ApiScope.DAV],
81-
"optional": [ApiScope.NOTIFICATIONS]
82-
})
99+
set_scopes(APP, {"required": [ApiScope.DAV], "optional": [ApiScope.NOTIFICATIONS]})
100+
enable_heartbeat(APP)
83101

84102

85103
if __name__ == "__main__":
86-
# This should be set by packaging step
87-
secret = "tC6vkwPhcppjMykD1r0n9NlI95uJMBYjs5blpIcA1PAdoPDmc5qoAjaBAkyocZ6E" \
88-
"X1T8Pi+T5papEolTLxz3fJSPS8ffC4204YmggxPsbJdCkXHWNPHKWS9B+vTj2SIV"
89-
if "app_name" not in environ:
90-
environ["app_name"] = "nc_py_api"
91-
if "app_version" not in environ:
92-
environ["app_version"] = "1.0.0"
93-
if "app_secret" not in environ:
94-
environ["app_secret"] = secret
95-
if "nextcloud_url" not in environ:
96-
environ["nextcloud_url"] = "http://nextcloud.local/index.php"
97-
# environ["app_name"] = "test_app"
98-
# ---------
99104
urllib3.disable_warnings()
100-
uvicorn.run("main:APP", host="0.0.0.0", port=9001, log_level="trace", reload=True)
105+
uvicorn.run("main:APP", host=environ.get("APP_HOST", "127.0.0.1"), port=int(environ["APP_PORT"]), log_level="trace")

‎scripts/dev_register.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ NEXTCLOUD_URL="http://$2" APP_PORT=9009 APP_ID="nc_py_api" APP_SECRET="12345" AP
1313
echo $! > /tmp/_install.pid
1414
python3 tests/_install_wait.py "http://localhost:9009/heartbeat" "\"status\":\"ok\"" 15 0.5
1515
docker exec "$1" sudo -u www-data php occ app_ecosystem_v2:app:register nc_py_api manual_install --json-info \
16-
"{\"appid\":\"nc_py_api\",\"name\":\"NC_Py_API\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"host\":\"host.docker.internal\",\"port\":9009,\"protocol\":\"http\",\"system_app\":1}" \
16+
"{\"appid\":\"nc_py_api\",\"name\":\"nc_py_api\",\"daemon_config_name\":\"manual_install\",\"version\":\"1.0.0\",\"secret\":\"12345\",\"host\":\"host.docker.internal\",\"port\":9009,\"protocol\":\"http\",\"system_app\":1}" \
1717
-e --force-scopes
1818
cat /tmp/_install.pid
1919
kill -15 "$(cat /tmp/_install.pid)"

0 commit comments

Comments
 (0)
Please sign in to comment.