Initial commit: IMAP Mail Filter Service
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import enum
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import Boolean, DateTime, Enum, ForeignKey, Integer, String, func
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.database import Base
|
||||
|
||||
|
||||
class ConditionField(str, enum.Enum):
|
||||
FROM = "from"
|
||||
TO = "to"
|
||||
SUBJECT = "subject"
|
||||
BODY = "body"
|
||||
HAS_ATTACHMENT = "has_attachment"
|
||||
|
||||
|
||||
class MatchType(str, enum.Enum):
|
||||
CONTAINS = "contains"
|
||||
REGEX = "regex"
|
||||
EXACT = "exact"
|
||||
|
||||
|
||||
class ActionType(str, enum.Enum):
|
||||
MOVE = "move"
|
||||
FORWARD = "forward"
|
||||
DELETE = "delete"
|
||||
MARK_READ = "mark_read"
|
||||
|
||||
|
||||
class Account(Base):
|
||||
__tablename__ = "accounts"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
name: Mapped[str] = mapped_column(String(100))
|
||||
imap_host: Mapped[str] = mapped_column(String(255))
|
||||
imap_port: Mapped[int] = mapped_column(Integer, default=993)
|
||||
use_ssl: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
username: Mapped[str] = mapped_column(String(255))
|
||||
password: Mapped[str] = mapped_column(String(255))
|
||||
smtp_host: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
||||
smtp_port: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
smtp_username: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
||||
smtp_password: Mapped[str | None] = mapped_column(String(255), nullable=True)
|
||||
poll_interval_seconds: Mapped[int] = mapped_column(Integer, default=120)
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
last_poll_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime, server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
|
||||
filter_rules: Mapped[list["FilterRule"]] = relationship(
|
||||
back_populates="account", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class FilterRule(Base):
|
||||
__tablename__ = "filter_rules"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
account_id: Mapped[int] = mapped_column(ForeignKey("accounts.id", ondelete="CASCADE"))
|
||||
name: Mapped[str] = mapped_column(String(200))
|
||||
priority: Mapped[int] = mapped_column(Integer, default=100)
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
|
||||
stop_processing: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
source_folder: Mapped[str] = mapped_column(String(255), default="INBOX")
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime, server_default=func.now(), onupdate=func.now()
|
||||
)
|
||||
|
||||
account: Mapped["Account"] = relationship(back_populates="filter_rules")
|
||||
conditions: Mapped[list["FilterCondition"]] = relationship(
|
||||
back_populates="rule", cascade="all, delete-orphan"
|
||||
)
|
||||
actions: Mapped[list["FilterAction"]] = relationship(
|
||||
back_populates="rule", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
|
||||
class FilterCondition(Base):
|
||||
__tablename__ = "filter_conditions"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
rule_id: Mapped[int] = mapped_column(ForeignKey("filter_rules.id", ondelete="CASCADE"))
|
||||
field: Mapped[ConditionField] = mapped_column(Enum(ConditionField))
|
||||
match_type: Mapped[MatchType] = mapped_column(Enum(MatchType))
|
||||
value: Mapped[str] = mapped_column(String(500))
|
||||
negate: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
|
||||
rule: Mapped["FilterRule"] = relationship(back_populates="conditions")
|
||||
|
||||
|
||||
class FilterAction(Base):
|
||||
__tablename__ = "filter_actions"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
rule_id: Mapped[int] = mapped_column(ForeignKey("filter_rules.id", ondelete="CASCADE"))
|
||||
action_type: Mapped[ActionType] = mapped_column(Enum(ActionType))
|
||||
parameter: Mapped[str | None] = mapped_column(String(500), nullable=True)
|
||||
|
||||
rule: Mapped["FilterRule"] = relationship(back_populates="actions")
|
||||
Reference in New Issue
Block a user