Skip to content

Commit 8ad89cb

Browse files
committed
v0.12.0 [publish]
Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
1 parent ee702ad commit 8ad89cb

File tree

10 files changed

+99
-69
lines changed

10 files changed

+99
-69
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

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

5-
## [0.12.0 - 2024-02-28]
5+
## [0.12.0 - 2024-04-02]
66

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

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

15+
### Changed
16+
17+
- `UiActionFileInfo` class marked as deprecated, instead `ActionFileInfo` class should be used.
18+
1519
## [0.11.0 - 2024-02-17]
1620

1721
### Added

docs/NextcloudApp.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ an empty response (which will be a status of 200) and in the background already
242242
The last parameter is a structure describing the action and the file on which it needs to be performed,
243243
which is passed by the AppAPI when clicking on the drop-down context menu of the file.
244244

245-
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
246-
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.
245+
We use the built-in ``to_fs_node`` method of :py:class:`~nc_py_api.files.ActionFileInfo` to get a standard
246+
:py:class:`~nc_py_api.files.FsNode` class that describes the file and pass the FsNode class instance to the background task.
247247

248248
In the **convert_video_to_gif** function, a standard conversion using ``OpenCV`` from a video file to a GIF image occurs,
249249
and since this is not directly related to working with NextCloud, we will skip this for now.
@@ -261,7 +261,7 @@ This is a modified endpoint from ``to_gif`` example:
261261
262262
@APP.post("/video_to_gif")
263263
async def video_to_gif(
264-
file: UiFileActionHandlerInfo,
264+
file: ActionFileInfo,
265265
nc: Annotated[NextcloudApp, Depends(nc_app)],
266266
background_tasks: BackgroundTasks,
267267
):

docs/conf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
(r"py:class", r"starlette\.requests\.Request"),
6969
(r"py:class", r"starlette\.requests\.HTTPConnection"),
7070
(r"py:class", r"ComputedFieldInfo"),
71+
(r"py:class", r"FieldInfo"),
72+
(r"py:class", r"ConfigDict"),
7173
(r"py:.*", r"httpx.*"),
7274
]
7375

docs/reference/Files/Files.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ All File APIs are designed to work relative to the current user.
2626

2727
.. autoclass:: nc_py_api.files.FsNodeLockInfo
2828
:members:
29+
30+
.. autoclass:: nc_py_api.files.ActionFileInfo
31+
:members: fileId, name, directory, etag, mime, fileType, size, favorite, permissions, mtime, userId, instanceId, to_fs_node

examples/as_app/to_gif/lib/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414

1515
from nc_py_api import FsNode, NextcloudApp
1616
from nc_py_api.ex_app import (
17+
ActionFileInfo,
1718
AppAPIAuthMiddleware,
1819
LogLvl,
19-
UiActionFileInfo,
2020
nc_app,
2121
run_app,
2222
set_handlers,
@@ -77,7 +77,7 @@ def convert_video_to_gif(input_file: FsNode, nc: NextcloudApp):
7777

7878
@APP.post("/video_to_gif")
7979
async def video_to_gif(
80-
file: UiActionFileInfo,
80+
file: ActionFileInfo,
8181
nc: Annotated[NextcloudApp, Depends(nc_app)],
8282
background_tasks: BackgroundTasks,
8383
):

nc_py_api/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Version of nc_py_api."""
22

3-
__version__ = "0.12.0.dev0"
3+
__version__ = "0.12.0"

nc_py_api/ex_app/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""All possible ExApp stuff for NextcloudApp that can be used."""
22

3-
from .defs import LogLvl
3+
from ..files import ActionFileInfo
4+
from .defs import FileSystemEventNotification, LogLvl
45
from .integration_fastapi import (
56
AppAPIAuthMiddleware,
67
anc_app,
@@ -15,6 +16,9 @@
1516
persistent_storage,
1617
verify_version,
1718
)
18-
from .ui.files_actions import UiActionFileInfo
1919
from .ui.settings import SettingsField, SettingsFieldType, SettingsForm
2020
from .uvicorn_fastapi import run_app
21+
22+
23+
class UiActionFileInfo(ActionFileInfo):
24+
"""``Deprecated``: use :py:class:`~nc_py_api.ex_app.ActionFileInfo` instead."""

nc_py_api/ex_app/defs.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
import enum
44

5+
from pydantic import BaseModel
6+
7+
from ..files import ActionFileInfo
8+
59

610
class LogLvl(enum.IntEnum):
711
"""Log levels."""
@@ -16,3 +20,18 @@ class LogLvl(enum.IntEnum):
1620
"""Error log level"""
1721
FATAL = 4
1822
"""Fatal log level"""
23+
24+
25+
class FileSystemEventData(BaseModel):
26+
"""FileSystem events format."""
27+
28+
target: ActionFileInfo
29+
source: ActionFileInfo | None = None
30+
31+
32+
class FileSystemEventNotification(BaseModel):
33+
"""AppAPI event notification common data."""
34+
35+
event_type: str
36+
event_subtype: str
37+
event_data: FileSystemEventData

nc_py_api/ex_app/ui/files_actions.py

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
"""Nextcloud API for working with drop-down file's menu."""
22

33
import dataclasses
4-
import datetime
5-
import os
6-
7-
from pydantic import BaseModel
84

95
from ..._exceptions import NextcloudExceptionNotFound
106
from ..._misc import require_capabilities
117
from ..._session import AsyncNcSessionApp, NcSessionApp
12-
from ...files import FsNode, permissions_to_str
138

149

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

6560

66-
class UiActionFileInfo(BaseModel):
67-
"""File Information Nextcloud sends to the External Application."""
68-
69-
fileId: int
70-
"""FileID without Nextcloud instance ID"""
71-
name: str
72-
"""Name of the file/directory"""
73-
directory: str
74-
"""Directory relative to the user's home directory"""
75-
etag: str
76-
mime: str
77-
fileType: str
78-
"""**file** or **dir**"""
79-
size: int
80-
"""size of file/directory"""
81-
favorite: str
82-
"""**true** or **false**"""
83-
permissions: int
84-
"""Combination of :py:class:`~nc_py_api.files.FilePermissions` values"""
85-
mtime: int
86-
"""Last modified time"""
87-
userId: str
88-
"""The ID of the user performing the action."""
89-
shareOwner: str | None
90-
"""If the object is shared, this is a display name of the share owner."""
91-
shareOwnerId: str | None
92-
"""If the object is shared, this is the owner ID of the share."""
93-
instanceId: str | None
94-
"""Nextcloud instance ID."""
95-
96-
def to_fs_node(self) -> FsNode:
97-
"""Returns usual :py:class:`~nc_py_api.files.FsNode` created from this class."""
98-
user_path = os.path.join(self.directory, self.name).rstrip("/")
99-
is_dir = bool(self.fileType.lower() == "dir")
100-
if is_dir:
101-
user_path += "/"
102-
full_path = os.path.join(f"files/{self.userId}", user_path.lstrip("/"))
103-
file_id = str(self.fileId).rjust(8, "0")
104-
105-
permissions = "S" if self.shareOwnerId else ""
106-
permissions += permissions_to_str(self.permissions, is_dir)
107-
return FsNode(
108-
full_path,
109-
etag=self.etag,
110-
size=self.size,
111-
content_length=0 if is_dir else self.size,
112-
permissions=permissions,
113-
favorite=bool(self.favorite.lower() == "true"),
114-
file_id=file_id + self.instanceId if self.instanceId else file_id,
115-
fileid=self.fileId,
116-
last_modified=datetime.datetime.utcfromtimestamp(self.mtime).replace(tzinfo=datetime.timezone.utc),
117-
mimetype=self.mime,
118-
)
119-
120-
12161
class _UiFilesActionsAPI:
12262
"""API for the drop-down menu in Nextcloud **Files app**, avalaible as **nc.ui.files_dropdown_menu.<method>**."""
12363

nc_py_api/files/__init__.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
import datetime
55
import email.utils
66
import enum
7+
import os
78
import warnings
89

10+
from pydantic import BaseModel
11+
912
from .. import _misc
1013

1114

@@ -461,3 +464,58 @@ def __str__(self):
461464
f"{self.share_type.name}: `{self.path}` with id={self.share_id}"
462465
f" from {self.share_owner} to {self.share_with}"
463466
)
467+
468+
469+
class ActionFileInfo(BaseModel):
470+
"""Information Nextcloud sends to the External Application about File Nodes affected in action."""
471+
472+
fileId: int
473+
"""FileID without Nextcloud instance ID"""
474+
name: str
475+
"""Name of the file/directory"""
476+
directory: str
477+
"""Directory relative to the user's home directory"""
478+
etag: str
479+
mime: str
480+
fileType: str
481+
"""**file** or **dir**"""
482+
size: int
483+
"""size of file/directory"""
484+
favorite: str
485+
"""**true** or **false**"""
486+
permissions: int
487+
"""Combination of :py:class:`~nc_py_api.files.FilePermissions` values"""
488+
mtime: int
489+
"""Last modified time"""
490+
userId: str
491+
"""The ID of the user performing the action."""
492+
shareOwner: str | None = None
493+
"""If the object is shared, this is a display name of the share owner."""
494+
shareOwnerId: str | None = None
495+
"""If the object is shared, this is the owner ID of the share."""
496+
instanceId: str | None = None
497+
"""Nextcloud instance ID."""
498+
499+
def to_fs_node(self) -> FsNode:
500+
"""Returns usual :py:class:`~nc_py_api.files.FsNode` created from this class."""
501+
user_path = os.path.join(self.directory, self.name).rstrip("/")
502+
is_dir = bool(self.fileType.lower() == "dir")
503+
if is_dir:
504+
user_path += "/"
505+
full_path = os.path.join(f"files/{self.userId}", user_path.lstrip("/"))
506+
file_id = str(self.fileId).rjust(8, "0")
507+
508+
permissions = "S" if self.shareOwnerId else ""
509+
permissions += permissions_to_str(self.permissions, is_dir)
510+
return FsNode(
511+
full_path,
512+
etag=self.etag,
513+
size=self.size,
514+
content_length=0 if is_dir else self.size,
515+
permissions=permissions,
516+
favorite=bool(self.favorite.lower() == "true"),
517+
file_id=file_id + self.instanceId if self.instanceId else file_id,
518+
fileid=self.fileId,
519+
last_modified=datetime.datetime.utcfromtimestamp(self.mtime).replace(tzinfo=datetime.timezone.utc),
520+
mimetype=self.mime,
521+
)

0 commit comments

Comments
 (0)