except Exception: pass def _publish_control(campaign_id, action, reason=""): if rdb is None: return try: rdb.publish(f"campaign:{campaign_id}:control", f"{action}|{reason}") except Exception: pass def _publish_progress(campaign_id): if rdb is None: return try: rdb.publish(f"campaign:{campaign_id}:progress", "tick") except Exception: pass 115: _publish_control(campaign.id, "pause", 414:def _publish_control(campaign_id, action, reason=""): 418: rdb.publish(f"campaign:{campaign_id}:control", f"{action}|{reason}") ===RECIPIENT LIST MODEL=== class RecipientList(Base, TimestampMixin): __tablename__ = "recipient_lists" id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True) name = Column(String(200), nullable=False) description = Column(Text, default="") source = Column(String(30), default="manual") # manual|csv|txt row_count = Column(Integer, default=0) recipients = relationship("Recipient", back_populates="list", cascade="all, delete-orphan") class Recipient(Base, TimestampMixin): __tablename__ = "recipients" id = Column(Integer, primary_key=True) list_id = Column(Integer, ForeignKey("recipient_lists.id", ondelete="CASCADE"), nullable=False, index=True) email = Column(String(320), nullable=False, index=True) first_name = Column(String(150), default="") last_name = Column(String(150), default="") company_name = Column(String(250), default="") company_phone = Column(String(60), default="") customer_email = Column(String(320), default="") custom_fields = Column(JSON, default=dict) # validation / status status = Column(String(30), default="valid") # valid|invalid|duplicate|suppressed|bounced validation_error = Column(Text, default="") is_valid = Column(Boolean, default=True, nullable=False) # unsubscribe token (unique secret per recipient) unsub_token = Column(String(64), unique=True, nullable=False) list = relationship("RecipientList", back_populates="recipients") __table_args__ = (Index("ix_recipient_list_email", "list_id", "email"),)