Skip to main content
Glama
webdav.py4.6 kB
"""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" )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/No-Smoke/nextcloud-mcp-comprehensive'

If you have feedback or need assistance with the MCP directory API, please join our Discord server