Files
gsfdc/server/app/commands/seed_party_building_sample.py
T

183 lines
6.5 KiB
Python

"""写入行业党建演示数据:支部介绍单篇 + 党建活动列表。
重复执行会清掉 party_activities 并重写 party_branch。口令只从环境变量读取。
"""
from __future__ import annotations
from html import escape, unescape
from pathlib import Path
from sqlalchemy import delete, select
from app.db import Base, SessionLocal, get_engine
from app.models.about import save_about_page
from app.models.content import AdminFile
from app.models.home import HomeArticle, HomeArticleAttachment, create_article
from app.services.storage import ensure_buckets, make_object_key, upload_object
ROOT = Path(__file__).resolve().parents[3]
SOURCE = ROOT / "docs" / "参考" / "现站" / "基础数据"
NEWS = SOURCE / "新闻动态"
CAROUSEL = SOURCE / "首页轮播"
PARTY_CATEGORY = "party_activities"
def _paragraphs(path: Path) -> str:
text = unescape(path.read_text(encoding="utf-8"))
parts = []
for line in text.splitlines():
line = line.strip()
if not line:
continue
parts.append(f"<p>{escape(line)}</p>")
return "".join(parts)
def _paragraphs_from_lines(lines: list[str]) -> str:
return "".join(f"<p>{escape(line)}</p>" for line in lines if line.strip())
def _content_type(path: Path) -> str:
suffix = path.suffix.lower()
if suffix == ".png":
return "image/png"
if suffix == ".webp":
return "image/webp"
if suffix == ".gif":
return "image/gif"
return "image/jpeg"
def _store_public(db, path: Path, filename: str | None = None) -> AdminFile | None:
if not path.is_file():
return None
name = filename or f"party-sample-{path.name}"
row = db.scalar(
select(AdminFile).where(AdminFile.bucket == "public", AdminFile.filename == name)
)
if row is not None:
return row
data = path.read_bytes()
key = make_object_key(name)
upload_object("public", key, data, _content_type(path))
row = AdminFile(
bucket="public",
object_key=key,
filename=name,
content_type=_content_type(path),
size=len(data),
created_by=None,
)
db.add(row)
db.commit()
db.refresh(row)
return row
def _clear_party(db) -> None:
article_ids = list(
db.scalars(select(HomeArticle.id).where(HomeArticle.category == PARTY_CATEGORY)).all()
)
if article_ids:
db.execute(
delete(HomeArticleAttachment).where(HomeArticleAttachment.article_id.in_(article_ids))
)
db.execute(delete(HomeArticle).where(HomeArticle.id.in_(article_ids)))
db.commit()
def seed() -> None:
import app.models.about # noqa: F401
import app.models.content # noqa: F401
import app.models.home # noqa: F401
ensure_buckets()
engine = get_engine()
Base.metadata.create_all(bind=engine)
SessionLocal.configure(bind=engine)
db = SessionLocal()
try:
_clear_party(db)
save_about_page(
db,
"party_branch",
{
"published": True,
"bodyHtml": _paragraphs_from_lines(
[
"甘肃省房地产价格评估行业协会党支部坚持以党建引领行业发展,团结引导广大会员机构与估价师坚定理想信念、依法依规执业。",
"职能定位:宣传贯彻党的路线方针政策,落实上级党组织部署;加强支部自身建设与党员教育管理;推动党建与估价行业自律、继续教育、技术交流等工作同向发力。",
"组织生活:定期开展主题党日、集中学习与谈心谈话;组织党员参加志愿服务、公益估价与行业文化建设;指导、展示会员机构党建活动成果。",
"正式章程、成员名单与近期活动由工作人员在管理端维护。本条为演示库样例。",
]
),
"attachmentFileIds": [],
},
)
cover_a = _store_public(db, CAROUSEL / "58612080.jpg", "party-cover-a.jpg")
cover_b = _store_public(db, CAROUSEL / "50933127.jpg", "party-cover-b.jpg")
council = NEWS / "文章" / "8560786"
award = NEWS / "文章" / "7911765"
create_article(
db,
{
"category": PARTY_CATEGORY,
"title": "主题党日:学习估价行业诚信自律要求(兰州中信估价党支部)",
"publishedAt": "2025-10-12T08:00:00",
"published": True,
"bodyHtml": (
_paragraphs(council / "content.txt")
if (council / "content.txt").is_file()
else "<p>围绕行业诚信与执业风险提示开展主题党日学习。</p>"
)
+ "<p>整理自现站公开报道,属会员机构党建活动公示示意。</p>",
"imageFileId": cover_a.id if cover_a else None,
"attachmentFileIds": [],
},
)
create_article(
db,
{
"category": PARTY_CATEGORY,
"title": "走访慰问与公益估价服务日(兰州中瑞估价党支部)",
"publishedAt": "2025-07-01T08:00:00",
"published": True,
"bodyHtml": (
_paragraphs(award / "content.txt")
if (award / "content.txt").is_file()
else "<p>结合纪念日开展走访慰问与公益估价咨询。</p>"
)
+ "<p>示意会员机构党建与业务融合活动。</p>",
"imageFileId": cover_b.id if cover_b else None,
"attachmentFileIds": [],
},
)
create_article(
db,
{
"category": PARTY_CATEGORY,
"title": "支部联建:估价报告质量交叉评阅(示意,无封面)",
"publishedAt": "2025-05-18T08:00:00",
"published": True,
"bodyHtml": "<p>本条无封面,示意无配图时列表仅显示标题。联建双方交叉评阅典型报告。</p>",
"imageFileId": None,
"attachmentFileIds": [],
},
)
print(
"行业党建测试数据已写入:支部介绍 1 篇,党建活动 3 条。"
" 执行:python -m app.commands.seed_party_building_sample"
)
finally:
db.close()
if __name__ == "__main__":
seed()