Spaces:
Sleeping
Sleeping
| import os | |
| from sqlalchemy import create_engine, Column, Integer, String, Text, DateTime, Enum, ForeignKey, JSON, Boolean | |
| from sqlalchemy.orm import sessionmaker, declarative_base, relationship | |
| from sqlalchemy.sql import func | |
| import enum | |
| def _sqlite_url() -> str: | |
| # HF Spaces: /data が永続、次に /tmp | |
| for path in ("/data/app.db", "/tmp/app.db", "./app.db"): | |
| try: | |
| d = os.path.dirname(path) or "." | |
| os.makedirs(d, exist_ok=True) | |
| test = path + ".touch" | |
| with open(test, "w") as f: f.write("ok") | |
| os.remove(test) | |
| return f"sqlite+pysqlite:///{path}" | |
| except Exception: | |
| continue | |
| return "sqlite+pysqlite:///./app.db" | |
| DATABASE_URL = os.getenv("DATABASE_URL", _sqlite_url()) | |
| IS_SQLITE = DATABASE_URL.startswith("sqlite+") | |
| engine = create_engine( | |
| DATABASE_URL, | |
| pool_pre_ping=not IS_SQLITE, | |
| future=True, | |
| connect_args={"check_same_thread": False} if IS_SQLITE else {}, | |
| ) | |
| SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine, future=True) | |
| Base = declarative_base() | |
| class Tone(str, enum.Enum): | |
| neutral = "neutral" | |
| formal = "formal" | |
| friendly = "friendly" | |
| investor = "investor" | |
| pr_bold = "pr_bold" | |
| class ContentType(str, enum.Enum): | |
| press_release = "press_release" | |
| ir_letter = "ir_letter" | |
| investor_summary = "investor_summary" | |
| class DraftStatus(str, enum.Enum): | |
| draft = "draft" | |
| pending = "pending" | |
| approved = "approved" | |
| scheduled = "scheduled" | |
| sent = "sent" | |
| class Draft(Base): | |
| __tablename__ = "drafts" | |
| id = Column(Integer, primary_key=True, index=True) | |
| source_type = Column(String(20)) | |
| source_ref = Column(Text) | |
| raw_text = Column(Text) | |
| content_type = Column(Enum(ContentType), nullable=False) | |
| tone = Column(Enum(Tone), nullable=False, default=Tone.neutral) | |
| title = Column(String(300)) | |
| body_md = Column(Text) | |
| status = Column(Enum(DraftStatus), nullable=False, default=DraftStatus.draft) | |
| created_at = Column(DateTime(timezone=True), server_default=func.now()) | |
| updated_at = Column(DateTime(timezone=True), onupdate=func.now()) | |
| subject_a = Column(String(300)) | |
| subject_b = Column(String(300)) | |
| deliver_email_list = Column(Text) | |
| deliver_x = Column(Boolean, default=False) | |
| deliver_note = Column(Boolean, default=False) | |
| deliveries = relationship("Delivery", back_populates="draft") | |
| class Delivery(Base): | |
| __tablename__ = "deliveries" | |
| id = Column(Integer, primary_key=True) | |
| draft_id = Column(Integer, ForeignKey("drafts.id")) | |
| channel = Column(String(10), nullable=False) # email/x/note | |
| payload = Column(JSON) | |
| result = Column(JSON) | |
| created_at = Column(DateTime(timezone=True), server_default=func.now()) | |
| draft = relationship("Draft", back_populates="deliveries") | |
| def init_db(): | |
| Base.metadata.create_all(bind=engine) | |