Skip to content

Commit

Permalink
v0.12.0 [publish]
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
  • Loading branch information
bigcat88 committed Apr 2, 2024
1 parent ee702ad commit 8ad89cb
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 69 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

All notable changes to this project will be documented in this file.

## [0.12.0 - 2024-02-28]
## [0.12.0 - 2024-04-02]

Update with new features only for `NextcloudApp` class. #233

Expand All @@ -12,6 +12,10 @@ Update with new features only for `NextcloudApp` class. #233
- `ex_app.integration_fastapi.fetch_models_task` are now public function, added `progress_init_start_value` param.
- Global authentication when used now sets `request.scope["username"]` for easy use.

### Changed

- `UiActionFileInfo` class marked as deprecated, instead `ActionFileInfo` class should be used.

## [0.11.0 - 2024-02-17]

### Added
Expand Down
6 changes: 3 additions & 3 deletions docs/NextcloudApp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ an empty response (which will be a status of 200) and in the background already
The last parameter is a structure describing the action and the file on which it needs to be performed,
which is passed by the AppAPI when clicking on the drop-down context menu of the file.

We use the built method :py:meth:`~nc_py_api.ex_app.ui.files_actions.UiActionFileInfo.to_fs_node` into the structure to convert it
into a standard :py:class:`~nc_py_api.files.FsNode` class that describes the file and pass the FsNode class instance to the background task.
We use the built-in ``to_fs_node`` method of :py:class:`~nc_py_api.files.ActionFileInfo` to get a standard
:py:class:`~nc_py_api.files.FsNode` class that describes the file and pass the FsNode class instance to the background task.

In the **convert_video_to_gif** function, a standard conversion using ``OpenCV`` from a video file to a GIF image occurs,
and since this is not directly related to working with NextCloud, we will skip this for now.
Expand All @@ -261,7 +261,7 @@ This is a modified endpoint from ``to_gif`` example:
@APP.post("/video_to_gif")
async def video_to_gif(
file: UiFileActionHandlerInfo,
file: ActionFileInfo,
nc: Annotated[NextcloudApp, Depends(nc_app)],
background_tasks: BackgroundTasks,
):
Expand Down
2 changes: 2 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
(r"py:class", r"starlette\.requests\.Request"),
(r"py:class", r"starlette\.requests\.HTTPConnection"),
(r"py:class", r"ComputedFieldInfo"),
(r"py:class", r"FieldInfo"),
(r"py:class", r"ConfigDict"),
(r"py:.*", r"httpx.*"),
]

Expand Down
3 changes: 3 additions & 0 deletions docs/reference/Files/Files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ All File APIs are designed to work relative to the current user.

.. autoclass:: nc_py_api.files.FsNodeLockInfo
:members:

.. autoclass:: nc_py_api.files.ActionFileInfo
:members: fileId, name, directory, etag, mime, fileType, size, favorite, permissions, mtime, userId, instanceId, to_fs_node
4 changes: 2 additions & 2 deletions examples/as_app/to_gif/lib/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

from nc_py_api import FsNode, NextcloudApp
from nc_py_api.ex_app import (
ActionFileInfo,
AppAPIAuthMiddleware,
LogLvl,
UiActionFileInfo,
nc_app,
run_app,
set_handlers,
Expand Down Expand Up @@ -77,7 +77,7 @@ def convert_video_to_gif(input_file: FsNode, nc: NextcloudApp):

@APP.post("/video_to_gif")
async def video_to_gif(
file: UiActionFileInfo,
file: ActionFileInfo,
nc: Annotated[NextcloudApp, Depends(nc_app)],
background_tasks: BackgroundTasks,
):
Expand Down
2 changes: 1 addition & 1 deletion nc_py_api/_version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Version of nc_py_api."""

__version__ = "0.12.0.dev0"
__version__ = "0.12.0"
8 changes: 6 additions & 2 deletions nc_py_api/ex_app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""All possible ExApp stuff for NextcloudApp that can be used."""

from .defs import LogLvl
from ..files import ActionFileInfo
from .defs import FileSystemEventNotification, LogLvl
from .integration_fastapi import (
AppAPIAuthMiddleware,
anc_app,
Expand All @@ -15,6 +16,9 @@
persistent_storage,
verify_version,
)
from .ui.files_actions import UiActionFileInfo
from .ui.settings import SettingsField, SettingsFieldType, SettingsForm
from .uvicorn_fastapi import run_app


class UiActionFileInfo(ActionFileInfo):
"""``Deprecated``: use :py:class:`~nc_py_api.ex_app.ActionFileInfo` instead."""
19 changes: 19 additions & 0 deletions nc_py_api/ex_app/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import enum

from pydantic import BaseModel

from ..files import ActionFileInfo


class LogLvl(enum.IntEnum):
"""Log levels."""
Expand All @@ -16,3 +20,18 @@ class LogLvl(enum.IntEnum):
"""Error log level"""
FATAL = 4
"""Fatal log level"""


class FileSystemEventData(BaseModel):
"""FileSystem events format."""

target: ActionFileInfo
source: ActionFileInfo | None = None


class FileSystemEventNotification(BaseModel):
"""AppAPI event notification common data."""

event_type: str
event_subtype: str
event_data: FileSystemEventData
60 changes: 0 additions & 60 deletions nc_py_api/ex_app/ui/files_actions.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
"""Nextcloud API for working with drop-down file's menu."""

import dataclasses
import datetime
import os

from pydantic import BaseModel

from ..._exceptions import NextcloudExceptionNotFound
from ..._misc import require_capabilities
from ..._session import AsyncNcSessionApp, NcSessionApp
from ...files import FsNode, permissions_to_str


@dataclasses.dataclass
Expand Down Expand Up @@ -63,61 +58,6 @@ def __repr__(self):
return f"<{self.__class__.__name__} name={self.name}, mime={self.mime}, handler={self.action_handler}>"


class UiActionFileInfo(BaseModel):
"""File Information Nextcloud sends to the External Application."""

fileId: int
"""FileID without Nextcloud instance ID"""
name: str
"""Name of the file/directory"""
directory: str
"""Directory relative to the user's home directory"""
etag: str
mime: str
fileType: str
"""**file** or **dir**"""
size: int
"""size of file/directory"""
favorite: str
"""**true** or **false**"""
permissions: int
"""Combination of :py:class:`~nc_py_api.files.FilePermissions` values"""
mtime: int
"""Last modified time"""
userId: str
"""The ID of the user performing the action."""
shareOwner: str | None
"""If the object is shared, this is a display name of the share owner."""
shareOwnerId: str | None
"""If the object is shared, this is the owner ID of the share."""
instanceId: str | None
"""Nextcloud instance ID."""

def to_fs_node(self) -> FsNode:
"""Returns usual :py:class:`~nc_py_api.files.FsNode` created from this class."""
user_path = os.path.join(self.directory, self.name).rstrip("/")
is_dir = bool(self.fileType.lower() == "dir")
if is_dir:
user_path += "/"
full_path = os.path.join(f"files/{self.userId}", user_path.lstrip("/"))
file_id = str(self.fileId).rjust(8, "0")

permissions = "S" if self.shareOwnerId else ""
permissions += permissions_to_str(self.permissions, is_dir)
return FsNode(
full_path,
etag=self.etag,
size=self.size,
content_length=0 if is_dir else self.size,
permissions=permissions,
favorite=bool(self.favorite.lower() == "true"),
file_id=file_id + self.instanceId if self.instanceId else file_id,
fileid=self.fileId,
last_modified=datetime.datetime.utcfromtimestamp(self.mtime).replace(tzinfo=datetime.timezone.utc),
mimetype=self.mime,
)


class _UiFilesActionsAPI:
"""API for the drop-down menu in Nextcloud **Files app**, avalaible as **nc.ui.files_dropdown_menu.<method>**."""

Expand Down
58 changes: 58 additions & 0 deletions nc_py_api/files/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
import datetime
import email.utils
import enum
import os
import warnings

from pydantic import BaseModel

from .. import _misc


Expand Down Expand Up @@ -461,3 +464,58 @@ def __str__(self):
f"{self.share_type.name}: `{self.path}` with id={self.share_id}"
f" from {self.share_owner} to {self.share_with}"
)


class ActionFileInfo(BaseModel):
"""Information Nextcloud sends to the External Application about File Nodes affected in action."""

fileId: int
"""FileID without Nextcloud instance ID"""
name: str
"""Name of the file/directory"""
directory: str
"""Directory relative to the user's home directory"""
etag: str
mime: str
fileType: str
"""**file** or **dir**"""
size: int
"""size of file/directory"""
favorite: str
"""**true** or **false**"""
permissions: int
"""Combination of :py:class:`~nc_py_api.files.FilePermissions` values"""
mtime: int
"""Last modified time"""
userId: str
"""The ID of the user performing the action."""
shareOwner: str | None = None
"""If the object is shared, this is a display name of the share owner."""
shareOwnerId: str | None = None
"""If the object is shared, this is the owner ID of the share."""
instanceId: str | None = None
"""Nextcloud instance ID."""

def to_fs_node(self) -> FsNode:
"""Returns usual :py:class:`~nc_py_api.files.FsNode` created from this class."""
user_path = os.path.join(self.directory, self.name).rstrip("/")
is_dir = bool(self.fileType.lower() == "dir")
if is_dir:
user_path += "/"
full_path = os.path.join(f"files/{self.userId}", user_path.lstrip("/"))
file_id = str(self.fileId).rjust(8, "0")

permissions = "S" if self.shareOwnerId else ""
permissions += permissions_to_str(self.permissions, is_dir)
return FsNode(
full_path,
etag=self.etag,
size=self.size,
content_length=0 if is_dir else self.size,
permissions=permissions,
favorite=bool(self.favorite.lower() == "true"),
file_id=file_id + self.instanceId if self.instanceId else file_id,
fileid=self.fileId,
last_modified=datetime.datetime.utcfromtimestamp(self.mtime).replace(tzinfo=datetime.timezone.utc),
mimetype=self.mime,
)

0 comments on commit 8ad89cb

Please sign in to comment.