Files
guilan-ace-backend/apps/content/management/commands/seed_mock_content.py

204 lines
9.9 KiB
Python

from django.contrib.admin.models import CHANGE, LogEntry
from django.contrib.contenttypes.models import ContentType
from django.core.management.base import BaseCommand
from django.db import DEFAULT_DB_ALIAS, connections, transaction
from apps.content.current import AboutContent, AboutItem, HomeContent, ListingContent, SiteContent
SITE_MOCK = {
"official_name": "نام انجمن نمونه",
"short_name": "انجمن نمونه",
"faculty_subline": "دانشکده نمونه",
"description": "این متن نمونه است و پس از ورود محتوای اصلی از پنل مدیریت جایگزین می‌شود.",
"logo": "",
"logo_alt": "",
"nav_home": "خانه",
"nav_about": "درباره ما",
"nav_events": "رویدادها",
"nav_blog": "بلاگ",
"email": "contact@example.invalid",
"phone": "0000000000",
"telegram_url": "https://example.invalid/telegram",
"instagram_url": "https://example.invalid/instagram",
"website_url": "https://example.invalid",
"address": "نشانی نمونه",
"footer_copy": "متن نمونه پابرگ؛ محتوای نهایی را از پنل مدیریت وارد کنید.",
"enamad_image": "",
"enamad_image_alt": "",
"enamad_url": "",
"seo_title": "عنوان نمونه سایت",
"seo_description": "توضیحات نمونه برای موتورهای جست‌وجو.",
"seo_image": "",
"seo_image_alt": "",
}
HOME_MOCK = {
"title": "عنوان نمونه صفحه اصلی",
"intro": "این متن نمونه صفحه اصلی است و پس از ورود محتوای اصلی جایگزین می‌شود.",
"hero_heading": "عنوان نمونه صفحه اصلی",
"hero_body": "توضیحات نمونه برای معرفی انجمن و فعالیت‌های آن.",
"hero_image": "",
"hero_image_alt": "",
"hero_action_label": "مشاهده رویدادها",
"hero_action_url": "/events",
"hero_secondary_action_label": "مطالب بلاگ",
"hero_secondary_action_url": "/blog",
"featured_events_heading": "رویدادهای نمونه",
"featured_events_intro": "توضیحات نمونه برای بخش رویدادها.",
"featured_events_link_label": "همه رویدادها",
"featured_events_url": "/events",
"featured_event_action_label": "مشاهده رویداد",
"featured_posts_heading": "نوشته‌های نمونه",
"featured_posts_intro": "توضیحات نمونه برای بخش نوشته‌ها.",
"featured_posts_link_label": "همه نوشته‌ها",
"featured_posts_url": "/blog",
"featured_post_action_label": "خواندن مطلب",
"participation_heading": "به ما بپیوندید",
"participation_body": "این متن نمونه راه‌های مشارکت را توضیح می‌دهد.",
"participation_image": "",
"participation_image_alt": "",
"participation_action_label": "اطلاعات بیشتر",
"participation_action_url": "/auth",
"participation_secondary_action_label": "درباره انجمن",
"participation_secondary_action_url": "/about",
"seo_title": "عنوان نمونه صفحه اصلی",
"seo_description": "توضیحات نمونه صفحه اصلی برای موتورهای جست‌وجو.",
"seo_image": "",
"seo_image_alt": "",
}
ABOUT_MOCK = {
"title": "عنوان نمونه صفحه درباره ما",
"intro": "این متن نمونه معرفی انجمن است و بعداً از پنل مدیریت قابل ویرایش است.",
"identity_heading": "معرفی نمونه",
"identity_body": "اطلاعات نمونه درباره هویت انجمن.",
"mission_heading": "ماموریت نمونه",
"mission_body": "توضیحات نمونه درباره ماموریت انجمن.",
"vision_heading": "چشم‌انداز نمونه",
"vision_body": "جامعه‌ای برای یادگیری، تجربه‌کردن و رشد در کنار یکدیگر.",
"activities_heading": "فعالیت‌های نمونه",
"activities_body": "توضیحات نمونه درباره فعالیت‌ها.",
"values_heading": "ارزش‌های نمونه",
"values_body": "یادگیری، همکاری و مسئولیت‌پذیری نمونه.",
"faq_heading": "پرسش‌های نمونه",
"contact_heading": "راه‌های ارتباطی نمونه",
"members_heading": "اعضای انجمن",
"members_intro": "با اعضایی آشنا شوید که برای ساختن تجربه‌های بهتر در انجمن همکاری می‌کنند.",
"gallery_heading": "خاطرات انجمن",
"gallery_intro": "تصاویری از گردهمایی‌ها، برنامه‌ها و لحظه‌هایی که کنار هم ساخته‌ایم.",
"past_events_heading": "رویدادهای برگزار شده",
"history_heading": "مسیر انجمن",
"audience_heading": "برای چه کسانی؟",
"year_events_heading": "لحظه‌های هر سال",
"cta_heading": "به جمع ما بپیوندید",
"cta_body": "اگر دوست دارید یاد بگیرید و در ساختن تجربه‌های تازه سهیم شوید، با ما همراه باشید.",
"cta_action_label": "راه‌های پیوستن",
"cta_action_url": "",
"seo_title": "عنوان نمونه صفحه درباره ما",
"seo_description": "توضیحات نمونه صفحه درباره ما برای موتورهای جست‌وجو.",
"seo_image": "",
"seo_image_alt": "",
}
LISTING_MOCKS = {
"events": {
"title": "عنوان نمونه رویدادها",
"intro": "این متن نمونه برای معرفی فهرست رویدادهاست.",
"seo_title": "عنوان نمونه رویدادها",
"seo_description": "توضیحات نمونه صفحه رویدادها برای موتورهای جست‌وجو.",
"seo_image": "",
"seo_image_alt": "",
},
"blog": {
"title": "عنوان نمونه بلاگ",
"intro": "این متن نمونه برای معرفی نوشته‌های بلاگ است.",
"seo_title": "عنوان نمونه بلاگ",
"seo_description": "توضیحات نمونه صفحه بلاگ برای موتورهای جست‌وجو.",
"seo_image": "",
"seo_image_alt": "",
},
}
ABOUT_ITEM_MOCKS = (
("mission", "ماموریت نمونه", "این متن نمونه برای توضیح ماموریت انجمن است."),
("activities", "فعالیت نمونه", "این متن نمونه یکی از فعالیت‌های انجمن را معرفی می‌کند."),
("values", "ارزش نمونه", "این متن نمونه یکی از ارزش‌های انجمن را توضیح می‌دهد."),
("faq", "پرسش نمونه", "پاسخ نمونه؛ اطلاعات نهایی را از پنل مدیریت وارد کنید."),
)
RECORDS = (
("site", SiteContent, {"pk": 1}, SITE_MOCK),
("home", HomeContent, {"pk": 1}, HOME_MOCK),
("about", AboutContent, {"pk": 1}, ABOUT_MOCK),
("events", ListingContent, {"pk": "events"}, LISTING_MOCKS["events"]),
("blog", ListingContent, {"pk": "blog"}, LISTING_MOCKS["blog"]),
)
def has_admin_change(model, object_id, using):
content_type = ContentType.objects.db_manager(using).get_for_model(model)
return LogEntry.objects.using(using).filter(
content_type=content_type,
object_id=str(object_id),
action_flag=CHANGE,
).exists()
class Command(BaseCommand):
help = "Fill untouched site content records with obvious sample copy."
def add_arguments(self, parser):
parser.add_argument(
"--database",
default=DEFAULT_DB_ALIAS,
choices=tuple(connections),
help="Database alias to update.",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Report intended changes without writing to the database.",
)
def handle(self, *args, database, dry_run, **options):
updated = 0
skipped = 0
prefix = "Dry run: " if dry_run else ""
with transaction.atomic(using=database):
for label, model, lookup, values in RECORDS:
record = model.objects.using(database).select_for_update().filter(**lookup).first()
object_id = lookup["pk"]
if record is not None and has_admin_change(model, object_id, database):
self.stdout.write(f"Skipped {label}: it has a Django admin change entry.")
skipped += 1
continue
if dry_run:
action = "create" if record is None else "replace"
self.stdout.write(f"Dry run: would {action} {label} with mock content.")
updated += 1
continue
if record is None:
record = model(**lookup)
for field, value in values.items():
setattr(record, field, value)
record.save(using=database)
updated += 1
self.stdout.write(f"Loaded mock content for {label}.")
if label == "about":
AboutItem.objects.using(database).filter(about_id=record.pk).delete()
AboutItem.objects.using(database).bulk_create(
[
AboutItem(about_id=record.pk, kind=kind, title=title, text=text, position=position)
for position, (kind, title, text) in enumerate(ABOUT_ITEM_MOCKS)
]
)
action = "would be updated" if dry_run else "updated"
summary = f"{updated} content records {action}; {skipped} admin-edited records skipped."
self.stdout.write(f"{prefix}{summary}")