122 lines
4.5 KiB
Python
122 lines
4.5 KiB
Python
"""Pydantic models for WebDAV responses."""
|
|
|
|
from datetime import datetime
|
|
from typing import List, Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from .base import BaseResponse, StatusResponse
|
|
|
|
|
|
class FileInfo(BaseModel):
|
|
"""Model for file/directory information."""
|
|
|
|
name: str = Field(description="File/directory name")
|
|
path: str = Field(description="Full path")
|
|
is_directory: bool = Field(description="Whether this is a directory")
|
|
size: Optional[int] = Field(
|
|
None, description="File size in bytes (None for directories)"
|
|
)
|
|
content_type: Optional[str] = Field(None, description="MIME content type")
|
|
last_modified: Optional[str] = Field(
|
|
None, description="Last modification time (ISO format)"
|
|
)
|
|
etag: Optional[str] = Field(None, description="ETag for versioning")
|
|
file_id: Optional[int] = Field(None, description="Nextcloud file ID")
|
|
is_favorite: Optional[bool] = Field(None, description="Whether file is favorited")
|
|
|
|
@property
|
|
def last_modified_datetime(self) -> Optional[datetime]:
|
|
"""Convert last modified string to datetime."""
|
|
if not self.last_modified:
|
|
return None
|
|
try:
|
|
return datetime.fromisoformat(self.last_modified.replace("Z", "+00:00"))
|
|
except (ValueError, AttributeError):
|
|
return None
|
|
|
|
|
|
class DirectoryListing(BaseResponse):
|
|
"""Response model for directory listings."""
|
|
|
|
path: str = Field(description="Directory path")
|
|
files: List[FileInfo] = Field(description="Files and directories in the path")
|
|
total_count: int = Field(description="Total number of items")
|
|
directories_count: int = Field(description="Number of directories")
|
|
files_count: int = Field(description="Number of files")
|
|
total_size: int = Field(default=0, description="Total size of all files in bytes")
|
|
|
|
|
|
class ReadFileResponse(BaseResponse):
|
|
"""Response model for reading file contents."""
|
|
|
|
path: str = Field(description="File path")
|
|
content: str = Field(description="File content (text or base64 for binary)")
|
|
content_type: str = Field(description="MIME content type")
|
|
size: int = Field(description="File size in bytes")
|
|
encoding: Optional[str] = Field(
|
|
None, description="Encoding used (e.g., 'base64' for binary files)"
|
|
)
|
|
etag: Optional[str] = Field(None, description="ETag for versioning")
|
|
last_modified: Optional[str] = Field(None, description="Last modification time")
|
|
|
|
|
|
class WriteFileResponse(StatusResponse):
|
|
"""Response model for writing files."""
|
|
|
|
path: str = Field(description="File path that was written")
|
|
size: Optional[int] = Field(None, description="Size of the written file")
|
|
created: bool = Field(description="Whether a new file was created (vs overwritten)")
|
|
|
|
|
|
class CreateDirectoryResponse(StatusResponse):
|
|
"""Response model for directory creation."""
|
|
|
|
path: str = Field(description="Directory path that was created")
|
|
created: bool = Field(
|
|
description="Whether directory was created or already existed"
|
|
)
|
|
|
|
|
|
class DeleteResourceResponse(StatusResponse):
|
|
"""Response model for resource deletion."""
|
|
|
|
path: str = Field(description="Path that was deleted")
|
|
was_directory: bool = Field(
|
|
description="Whether the deleted resource was a directory"
|
|
)
|
|
items_deleted: Optional[int] = Field(
|
|
None, description="Number of items deleted (for directories)"
|
|
)
|
|
|
|
|
|
class MoveResourceResponse(StatusResponse):
|
|
"""Response model for resource move/rename operations."""
|
|
|
|
source_path: str = Field(description="Original path of the resource")
|
|
destination_path: str = Field(description="New path of the resource")
|
|
overwrite: bool = Field(
|
|
description="Whether the destination was overwritten if it existed"
|
|
)
|
|
|
|
|
|
class CopyResourceResponse(StatusResponse):
|
|
"""Response model for resource copy operations."""
|
|
|
|
source_path: str = Field(description="Original path of the resource")
|
|
destination_path: str = Field(description="Destination path for the copy")
|
|
overwrite: bool = Field(
|
|
description="Whether the destination was overwritten if it existed"
|
|
)
|
|
|
|
|
|
class SearchFilesResponse(BaseResponse):
|
|
"""Response model for WebDAV search operations."""
|
|
|
|
results: List[FileInfo] = Field(description="Search results")
|
|
total_found: int = Field(description="Total number of files found")
|
|
scope: str = Field(description="The scope/path that was searched")
|
|
filters_applied: Optional[dict] = Field(
|
|
None, description="Filters that were applied to the search"
|
|
)
|