inital commit
This commit is contained in:
139
server/app/mailer/messages/models.py
Normal file
139
server/app/mailer/messages/models.py
Normal file
@@ -0,0 +1,139 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import StrEnum
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from app.mailer.campaign.models import BuildStatus, SendStatus
|
||||
|
||||
|
||||
class MessageValidationStatus(StrEnum):
|
||||
READY = "ready"
|
||||
WARNING = "warning"
|
||||
NEEDS_REVIEW = "needs_review"
|
||||
BLOCKED = "blocked"
|
||||
EXCLUDED = "excluded"
|
||||
INACTIVE = "inactive"
|
||||
|
||||
|
||||
class ImapStatus(StrEnum):
|
||||
NOT_REQUESTED = "not_requested"
|
||||
PENDING = "pending"
|
||||
APPENDED = "appended"
|
||||
FAILED = "failed"
|
||||
SKIPPED = "skipped"
|
||||
|
||||
|
||||
class MessageIssue(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
severity: Literal["info", "warning", "error"]
|
||||
code: str
|
||||
message: str
|
||||
behavior: str | None = None
|
||||
source: str | None = None
|
||||
|
||||
|
||||
class MessageAddress(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
email: str
|
||||
name: str | None = None
|
||||
|
||||
|
||||
class MessageAttachmentSummary(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
attachment_id: str | None = None
|
||||
label: str | None = None
|
||||
status: str
|
||||
behavior: str | None = None
|
||||
required: bool
|
||||
allow_multiple: bool
|
||||
zip_enabled: bool
|
||||
file_filter: str
|
||||
directory: str
|
||||
matches: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class MessageDraft(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid", populate_by_name=True)
|
||||
|
||||
entry_index: int
|
||||
entry_id: str | None = None
|
||||
active: bool
|
||||
|
||||
build_status: BuildStatus
|
||||
validation_status: MessageValidationStatus
|
||||
send_status: SendStatus
|
||||
imap_status: ImapStatus
|
||||
|
||||
subject: str | None = None
|
||||
from_: MessageAddress | None = Field(default=None, alias="from")
|
||||
to: list[MessageAddress] = Field(default_factory=list)
|
||||
cc: list[MessageAddress] = Field(default_factory=list)
|
||||
bcc: list[MessageAddress] = Field(default_factory=list)
|
||||
reply_to: list[MessageAddress] = Field(default_factory=list)
|
||||
bounce_to: list[MessageAddress] = Field(default_factory=list)
|
||||
disposition_notification_to: list[MessageAddress] = Field(default_factory=list)
|
||||
|
||||
attachment_count: int = 0
|
||||
attachments: list[MessageAttachmentSummary] = Field(default_factory=list)
|
||||
issues: list[MessageIssue] = Field(default_factory=list)
|
||||
|
||||
eml_path: str | None = None
|
||||
eml_size_bytes: int | None = None
|
||||
|
||||
@property
|
||||
def is_queueable(self) -> bool:
|
||||
return self.active and self.build_status == BuildStatus.BUILT and self.validation_status in {
|
||||
MessageValidationStatus.READY,
|
||||
MessageValidationStatus.WARNING,
|
||||
}
|
||||
|
||||
|
||||
class CampaignBuildReport(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
campaign_id: str
|
||||
campaign_name: str
|
||||
campaign_file: str
|
||||
entries_count: int
|
||||
messages: list[MessageDraft] = Field(default_factory=list)
|
||||
|
||||
@property
|
||||
def built_count(self) -> int:
|
||||
return sum(1 for message in self.messages if message.build_status == BuildStatus.BUILT)
|
||||
|
||||
@property
|
||||
def build_failed_count(self) -> int:
|
||||
return sum(1 for message in self.messages if message.build_status == BuildStatus.BUILD_FAILED)
|
||||
|
||||
@property
|
||||
def ready_count(self) -> int:
|
||||
return sum(1 for message in self.messages if message.validation_status == MessageValidationStatus.READY)
|
||||
|
||||
@property
|
||||
def warning_count(self) -> int:
|
||||
return sum(1 for message in self.messages if message.validation_status == MessageValidationStatus.WARNING)
|
||||
|
||||
@property
|
||||
def needs_review_count(self) -> int:
|
||||
return sum(1 for message in self.messages if message.validation_status == MessageValidationStatus.NEEDS_REVIEW)
|
||||
|
||||
@property
|
||||
def blocked_count(self) -> int:
|
||||
return sum(1 for message in self.messages if message.validation_status == MessageValidationStatus.BLOCKED)
|
||||
|
||||
@property
|
||||
def excluded_count(self) -> int:
|
||||
return sum(1 for message in self.messages if message.validation_status == MessageValidationStatus.EXCLUDED)
|
||||
|
||||
@property
|
||||
def inactive_count(self) -> int:
|
||||
return sum(1 for message in self.messages if message.validation_status == MessageValidationStatus.INACTIVE)
|
||||
|
||||
@property
|
||||
def queueable_count(self) -> int:
|
||||
return sum(1 for message in self.messages if message.is_queueable)
|
||||
Reference in New Issue
Block a user