Skip to content

Commit

Permalink
made UiActionFileInfo.to_fs_node more consistent (#105)
Browse files Browse the repository at this point in the history
Now created `FsNode` has the same `file_id` as from WebDAV request with
type `str`.

Was not able to do it earlier, as only recent AppEcosystem version start
providing Nextcloud Instance ID.

Signed-off-by: Alexander Piskun <[email protected]>
  • Loading branch information
bigcat88 authored Aug 29, 2023
1 parent cdbac4e commit 9ac433b
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

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

## [0.0.42 - 2023-08-30]

### Fixed

- Created `FsNode` from `UiActionFileInfo` now have the `file_id` with the NC instance ID as from the DAV requests.

## [0.0.41 - 2023-08-26]

### Added
Expand Down
19 changes: 9 additions & 10 deletions nc_py_api/ex_app/ui/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
from ..._session import NcSessionApp
from ...files import FilePermissions, FsNode

ENDPOINT_SUFFIX = "files/actions/menu"


class UiActionFileInfo(BaseModel):
"""File Information Nextcloud sends to the External Application."""
Expand Down Expand Up @@ -40,18 +38,17 @@ class UiActionFileInfo(BaseModel):
"""If the object is shared, this is a display name of the share owner."""
shareOwnerId: typing.Optional[str]
"""If the object is shared, this is the owner ID of the share."""
instanceId: typing.Optional[str]
"""Nextcloud instance ID."""

def to_fs_node(self) -> FsNode:
"""Returns created ``FsNode`` from the file info given.
.. note:: :py:attr:`~nc_py_api.files.FsNode.file_id` in this case is ``without`` **instance_id**
and equal to :py:attr:`~nc_py_api.files.FsNodeInfo.fileid`.
"""
"""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 ""
if self.permissions & FilePermissions.PERMISSION_SHARE:
Expand All @@ -71,7 +68,7 @@ def to_fs_node(self) -> FsNode:
content_length=0 if is_dir else self.size,
permissions=permissions,
favorite=bool(self.favorite.lower() == "true"),
file_id=self.fileId,
file_id=file_id + self.instanceId if self.instanceId else file_id,
fileid=self.fileId,
last_modified=datetime.utcfromtimestamp(self.mtime).replace(tzinfo=timezone.utc),
)
Expand All @@ -91,6 +88,8 @@ class UiFileActionHandlerInfo(BaseModel):
class _UiFilesActionsAPI:
"""API for the drop-down menu in Nextcloud **Files app**."""

_ep_suffix: str = "files/actions/menu"

def __init__(self, session: NcSessionApp):
self._session = session

Expand All @@ -109,14 +108,14 @@ def register(self, name: str, display_name: str, callback_url: str, **kwargs) ->
"action_handler": callback_url,
},
}
self._session.ocs(method="POST", path=f"{self._session.ae_url}/{ENDPOINT_SUFFIX}", json=params)
self._session.ocs(method="POST", path=f"{self._session.ae_url}/{self._ep_suffix}", json=params)

def unregister(self, name: str, not_fail=True) -> None:
"""Removes files dropdown menu element."""
require_capabilities("app_ecosystem_v2", self._session.capabilities)
params = {"fileActionMenuName": name}
try:
self._session.ocs(method="DELETE", path=f"{self._session.ae_url}/{ENDPOINT_SUFFIX}", json=params)
self._session.ocs(method="DELETE", path=f"{self._session.ae_url}/{self._ep_suffix}", json=params)
except NextcloudExceptionNotFound as e:
if not not_fail:
raise e from None
5 changes: 4 additions & 1 deletion tests/ui_files_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ def ui_action_check(directory: str, fs_object: FsNode):
permissions += FilePermissions.PERMISSION_DELETE
if fs_object.is_shareable:
permissions += FilePermissions.PERMISSION_SHARE
fileid_str = str(fs_object.info.fileid)
i = fs_object.file_id.find(fileid_str)
file_info = ex_app.UiActionFileInfo(
fileId=fs_object.info.fileid,
name=fs_object.name,
Expand All @@ -102,14 +104,15 @@ def ui_action_check(directory: str, fs_object: FsNode):
userId=fs_object.user,
shareOwner="some_user" if fs_object.is_shared else None,
shareOwnerId="some_user_id" if fs_object.is_shared else None,
instanceId=fs_object.file_id[i + len(fileid_str) :],
)
fs_node = file_info.to_fs_node()
assert isinstance(fs_node, FsNode)
assert fs_node.etag == fs_object.etag
assert fs_node.name == fs_object.name
assert fs_node.user_path == fs_object.user_path
assert fs_node.full_path == fs_object.full_path
assert fs_node.file_id == fs_object.info.fileid
assert fs_node.file_id == fs_object.file_id
assert fs_node.is_dir == fs_object.is_dir
# assert fs_node.mime == fs_object.mime
assert fs_node.info.permissions == fs_object.info.permissions
Expand Down

0 comments on commit 9ac433b

Please sign in to comment.