""" متنِ درس‌هایی که LaTeX خام داشتند (`\( \vec{a} \)`، `^{n}`) به متنِ ساده‌ی یونیکد برمی‌گردد. فرانت LaTeX رندر نمی‌کند، پس دانش‌آموز بک‌اسلش و آکولاد می‌دید (درس‌های بردارِ دوازدهم). فایل‌های seed همین تبدیل را گرفته‌اند، ولی `seed_content` متنِ مثال/قدم‌های درسِ موجود را عوض نمی‌کند (فقط خانه‌ی خالی را پر می‌کند)، پس سرور بی‌این migration همان متنِ خراب را نگه می‌داشت. تبدیل در `content/plain_math.py` است و idempotent: بار دوم هیچ‌چیز عوض نمی‌شود. معکوس ندارد (متنِ قدیم بی‌فایده بود). نمودارها: فقط `FIGURE_TEXT_KEYS`، نه `expr`. """ import hashlib from django.db import migrations from content.plain_math import convert, convert_figures def _h(text): return hashlib.sha1((text or '').encode('utf-8')).hexdigest() def _key(*parts): return hashlib.sha1('\x1f'.join(('intro', *map(str, parts))).encode('utf-8')).hexdigest() def forwards(apps, schema_editor): Lesson = apps.get_model('content', 'Lesson') SeedRecord = apps.get_model('content', 'SeedRecord') qs = Lesson.objects.select_related('node__unit__grade') for lesson in qs.iterator(chunk_size=500): new = { 'intro_text': convert(lesson.intro_text), 'example': convert(lesson.example), 'steps': [convert(s) for s in (lesson.steps or [])], 'figures': convert_figures(lesson.figures or []), } changed = [f for f, v in new.items() if v != getattr(lesson, f)] if not changed: continue old_intro = lesson.intro_text for f in changed: setattr(lesson, f, new[f]) lesson.save(update_fields=changed) if 'intro_text' in changed: # دفترِ seed «آخرین متنی که خودمان نوشتیم» را با هش نگه می‌دارد؛ هشِ قدیم بماند # متنِ تازه «کارِ ادمین» حساب می‌شود و دیگر از فایل تازه نمی‌شود. n = lesson.node key = _key(n.unit.grade.title, n.unit.title, n.title, lesson.title) SeedRecord.objects.filter(key=key, value=_h(old_intro)).update(value=_h(new['intro_text'])) class Migration(migrations.Migration): dependencies = [('content', '0019_question_figure')] operations = [migrations.RunPython(forwards, migrations.RunPython.noop)]