Skip to content

Commit

Permalink
updating to_gif example (#65)
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
  • Loading branch information
bigcat88 authored Aug 7, 2023
1 parent c2967fc commit 4b1370e
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 78 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/analysis-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -750,8 +750,7 @@ jobs:
permissions:
contents: none
runs-on: ubuntu-22.04
needs: [tests-maria, tests-pgsql, tests-oci, tests-latest-maria-full]
# needs: [tests-maria, tests-pgsql, tests-oci, tests-sqlite, tests-latest-maria-full, test-latest-pgsql-client]
needs: [tests-maria, tests-pgsql, tests-oci, tests-sqlite, tests-latest-maria-full, test-latest-pgsql-client]
name: Tests-OK
steps:
- run: echo "Tests passed successfully"
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ vendor
/out
/dev/
local
.run/
tmp
.phpdoc
clover.unit.xml
Expand Down
29 changes: 29 additions & 0 deletions .run/to_gif.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="to_gif" type="PythonConfigurationType" factoryName="Python">
<module name="nc_py_api" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<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="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>
1 change: 0 additions & 1 deletion examples/as_app/to_gif/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ FROM python:3.11.4-bookworm

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

RUN \
apt-get update && \
Expand Down
60 changes: 32 additions & 28 deletions examples/as_app/to_gif/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,44 @@
.PHONY: help
help:
@echo "Welcome to ToGif example. Please use \`make <target>\` where <target> is one of"
@echo " docs make HTML docs"
@echo " html make HTML docs"
@echo " "
@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 " register28 register nc_py_api for Nextcloud 28"
@echo " register27 register nc_py_api for Nextcloud 27"
@echo " register26 register nc_py_api for Nextcloud 26"
@echo " build-push build image and upload to ghcr.io"
@echo " "
@echo " tests28 run nc_py_api tests for Nextcloud 28"
@echo " tests27 run nc_py_api tests for Nextcloud 27"
@echo " tests26 run nc_py_api tests for Nextcloud 26"

.PHONY: register28
register28:
/bin/sh scripts/dev_register.sh master-nextcloud-1 nextcloud.local
@echo " deploy deploy example to registered 'docker_dev'"
@echo " "
@echo " run28 install ToGif for Nextcloud 28"
@echo " run27 install ToGif for Nextcloud 27"
@echo " "
@echo " For development of this example use PyCharm run configurations. Development is always set for last Nextcloud."
@echo " First run 'to_gif' and then 'make manual_register', after that you can use/debug/develop it and easy test."
@echo " "
@echo " manual_register perform registration of running 'to_gif' into 'manual_install' deploy daemon."

.PHONY: register27
register27:
/bin/sh scripts/dev_register.sh master-stable27-1 stable27.local
.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/to_gif:latest .

.PHONY: register26
register26:
/bin/sh scripts/dev_register.sh master-stable26-1 stable26.local
.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

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

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

.PHONY: tests26
tests26:
NEXTCLOUD_URL=http://stable26.local python3 -m pytest
.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}" \
-e --force-scopes
95 changes: 50 additions & 45 deletions examples/as_app/to_gif/main.py
Original file line number Diff line number Diff line change
@@ -1,73 +1,93 @@
"""
Simplest example.
"""
"""Simplest example of files_dropdown_menu + notification."""

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

import uvicorn
from fastapi import FastAPI, Depends
from requests import Response
import urllib3

import tempfile
from pygifsicle import optimize
import imageio
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 UiFileActionHandlerInfo, LogLvl, NextcloudApp, nc_app, set_enabled_handler, ApiScope, set_scopes
from nc_py_api import (
ApiScope,
GuiActionFileInfo,
GuiFileActionHandlerInfo,
LogLvl,
NextcloudApp,
enable_heartbeat,
nc_app,
set_enabled_handler,
set_scopes,
)

APP = FastAPI()


@APP.post("/video_to_gif")
async def video_to_gif(
file: UiFileActionHandlerInfo,
nc: Annotated[NextcloudApp, Depends(nc_app)],
):
source_path = path.join(file.actionFile.dir, file.actionFile.name)
def convert_video_to_gif(input_params: GuiActionFileInfo, nc: NextcloudApp):
source_path = path.join(input_params.directory, input_params.name)
save_path = path.splitext(source_path)[0] + ".gif"
nc.log(LogLvl.WARNING, f"Processing:{source_path} -> {save_path}")
source_file = nc.files.download(source_path)
nc.log(LogLvl.WARNING, "File downloaded")
try:
with tempfile.NamedTemporaryFile(mode="w+b") as tmp_in:
tmp_in.write(source_file)
nc.files.download2stream(source_path, tmp_in)
nc.log(LogLvl.WARNING, "File downloaded")
tmp_in.flush()
cap = cv2.VideoCapture(tmp_in.name)
with tempfile.NamedTemporaryFile(mode="w+b", suffix=".gif") as tmp_out:
image_lst = []
previous_frame = None
skip = 0
while True:
skip += 1
ret, frame = cap.read()
if frame is None:
break
if skip == 2:
skip = 0
continue
if previous_frame is not None:
diff = numpy.mean(previous_frame != frame)
if diff < 0.91:
continue
if frame is None:
break
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image_lst.append(frame_rgb)
previous_frame = frame
if len(image_lst) > 60:
break
cap.release()
imageio.mimsave(tmp_out.name, image_lst)
optimize(tmp_out.name)
nc.log(LogLvl.WARNING, "GIF is ready")
nc.files.upload(save_path, content=tmp_out.read())
nc.files.upload_stream(save_path, tmp_out)
nc.log(LogLvl.WARNING, "Result uploaded")
nc.users.notifications.create(f"{input_params.name} finished!", f"{save_path} is waiting for you!")
except Exception as e:
nc.log(LogLvl.ERROR, str(e))
nc.users.notifications.create("Error occurred", "Error information was written to log file")


@APP.post("/video_to_gif")
async def video_to_gif(
file: GuiFileActionHandlerInfo,
nc: Annotated[NextcloudApp, Depends(nc_app)],
background_tasks: BackgroundTasks,
):
background_tasks.add_task(convert_video_to_gif, file.actionFile, nc)
return Response()


def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
print(f"enabled={enabled}")
try:
if enabled:
nc.ui_files_actions.register("to_gif", "TO GIF", "/video_to_gif", mime="video")
nc.gui.files_dropdown_menu.register("to_gif", "TO GIF", "/video_to_gif", mime="video")
else:
nc.ui_files_actions.unregister("to_gif")
nc.gui.files_dropdown_menu.unregister("to_gif")
except Exception as e:
return str(e)
return ""
Expand All @@ -76,25 +96,10 @@ def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
@APP.on_event("startup")
def initialization():
set_enabled_handler(APP, enabled_handler)
set_scopes(APP, {
"required": [ApiScope.DAV],
"optional": [ApiScope.NOTIFICATIONS]
})
set_scopes(APP, {"required": [ApiScope.DAV], "optional": [ApiScope.NOTIFICATIONS]})
enable_heartbeat(APP)


if __name__ == "__main__":
# This should be set by packaging step
secret = "tC6vkwPhcppjMykD1r0n9NlI95uJMBYjs5blpIcA1PAdoPDmc5qoAjaBAkyocZ6E" \
"X1T8Pi+T5papEolTLxz3fJSPS8ffC4204YmggxPsbJdCkXHWNPHKWS9B+vTj2SIV"
if "app_name" not in environ:
environ["app_name"] = "nc_py_api"
if "app_version" not in environ:
environ["app_version"] = "1.0.0"
if "app_secret" not in environ:
environ["app_secret"] = secret
if "nextcloud_url" not in environ:
environ["nextcloud_url"] = "http://nextcloud.local/index.php"
# environ["app_name"] = "test_app"
# ---------
urllib3.disable_warnings()
uvicorn.run("main:APP", host="0.0.0.0", port=9001, log_level="trace", reload=True)
uvicorn.run("main:APP", host=environ.get("APP_HOST", "127.0.0.1"), port=int(environ["APP_PORT"]), log_level="trace")
2 changes: 1 addition & 1 deletion scripts/dev_register.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ NEXTCLOUD_URL="http://$2" APP_PORT=9009 APP_ID="nc_py_api" APP_SECRET="12345" AP
echo $! > /tmp/_install.pid
python3 tests/_install_wait.py "http://localhost:9009/heartbeat" "\"status\":\"ok\"" 15 0.5
docker exec "$1" sudo -u www-data php occ app_ecosystem_v2:app:register nc_py_api manual_install --json-info \
"{\"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}" \
"{\"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}" \
-e --force-scopes
cat /tmp/_install.pid
kill -15 "$(cat /tmp/_install.pid)"
Expand Down

0 comments on commit 4b1370e

Please sign in to comment.