refactor(mail): address PR #935 round-1 review
- models/mail.py: lowercase `list` generics per CLAUDE.md convention. - client/mail.py: _ocs_get now inspects ocs.meta.statuscode (re-raises >=400 as HTTPStatusError carrying the OCS code so callers' 404/403 handling applies) and guards response.json() against non-JSON bodies (RequestError). - Extract the duplicated _format_addresses + content reconstruction into vector/mail_content.py, used by both processor.py and context.py (fixes the SonarCloud new_duplicated_lines_density gate). - processor.py: add the missing mail_message Qdrant payload block so the computed mail metadata (subject/from/to/cc/date_int/has_attachments/ account_id/mailbox_id) is actually stored, not dropped. - Rename the list_messages `filter` param to `search_filter` (avoid shadowing builtins.filter); still maps to the OCS `filter` query param. - Docstring notes: has_more heuristic, attachment content size. - Tests: OCS meta-failure + non-JSON client paths; initial-sync scanner tests (tests/unit/vector/test_scanner_mail.py). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
3074622455
commit
62ee3e9f32
@@ -1,7 +1,5 @@
|
||||
"""Pydantic models for Nextcloud Mail app responses (read-only)."""
|
||||
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from .base import BaseResponse
|
||||
@@ -41,7 +39,7 @@ class MailMailbox(BaseModel):
|
||||
None, alias="displayName", description="Human-readable mailbox name"
|
||||
)
|
||||
account_id: int = Field(alias="accountId", description="Parent account ID")
|
||||
special_use: List[str] = Field(
|
||||
special_use: list[str] = Field(
|
||||
default_factory=list,
|
||||
alias="specialUse",
|
||||
description="Special-use roles (e.g. inbox, sent, trash)",
|
||||
@@ -94,10 +92,10 @@ class MailMessageSummary(BaseModel):
|
||||
date_int: int | None = Field(
|
||||
None, alias="dateInt", description="Sent date as a Unix timestamp (seconds)"
|
||||
)
|
||||
from_: List[MailAddress] = Field(
|
||||
from_: list[MailAddress] = Field(
|
||||
default_factory=list, alias="from", description="Sender addresses"
|
||||
)
|
||||
to: List[MailAddress] = Field(
|
||||
to: list[MailAddress] = Field(
|
||||
default_factory=list, description="Recipient addresses"
|
||||
)
|
||||
mailbox_id: int | None = Field(
|
||||
@@ -123,14 +121,14 @@ class MailMessage(BaseModel):
|
||||
date_int: int | None = Field(
|
||||
None, alias="dateInt", description="Sent date as a Unix timestamp (seconds)"
|
||||
)
|
||||
from_: List[MailAddress] = Field(
|
||||
from_: list[MailAddress] = Field(
|
||||
default_factory=list, alias="from", description="Sender addresses"
|
||||
)
|
||||
to: List[MailAddress] = Field(
|
||||
to: list[MailAddress] = Field(
|
||||
default_factory=list, description="Recipient addresses"
|
||||
)
|
||||
cc: List[MailAddress] = Field(default_factory=list, description="CC addresses")
|
||||
bcc: List[MailAddress] = Field(default_factory=list, description="BCC addresses")
|
||||
cc: list[MailAddress] = Field(default_factory=list, description="CC addresses")
|
||||
bcc: list[MailAddress] = Field(default_factory=list, description="BCC addresses")
|
||||
has_html_body: bool = Field(
|
||||
False, alias="hasHtmlBody", description="Whether the body is HTML"
|
||||
)
|
||||
@@ -138,7 +136,7 @@ class MailMessage(BaseModel):
|
||||
None,
|
||||
description="Rendered body (sanitized HTML if hasHtmlBody, else plain text)",
|
||||
)
|
||||
attachments: List[MailAttachment] = Field(
|
||||
attachments: list[MailAttachment] = Field(
|
||||
default_factory=list, description="Message attachments"
|
||||
)
|
||||
|
||||
@@ -149,21 +147,21 @@ class MailMessage(BaseModel):
|
||||
class ListAccountsResponse(BaseResponse):
|
||||
"""Response model for listing mail accounts."""
|
||||
|
||||
results: List[MailAccount] = Field(description="List of mail accounts")
|
||||
results: list[MailAccount] = Field(description="List of mail accounts")
|
||||
total_count: int = Field(description="Total number of accounts")
|
||||
|
||||
|
||||
class ListMailboxesResponse(BaseResponse):
|
||||
"""Response model for listing mailboxes."""
|
||||
|
||||
results: List[MailMailbox] = Field(description="List of mailboxes")
|
||||
results: list[MailMailbox] = Field(description="List of mailboxes")
|
||||
total_count: int = Field(description="Total number of mailboxes")
|
||||
|
||||
|
||||
class ListMessagesResponse(BaseResponse):
|
||||
"""Response model for listing message envelopes."""
|
||||
|
||||
results: List[MailMessageSummary] = Field(description="List of message summaries")
|
||||
results: list[MailMessageSummary] = Field(description="List of message summaries")
|
||||
total_count: int = Field(description="Number of messages returned")
|
||||
has_more: bool = Field(False, description="Whether more messages may exist")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user