80 lines
3.3 KiB
Python
80 lines
3.3 KiB
Python
"""
|
|
اصلاحِ سوالهای شکلدارِ از قبل منتشرشده (seed هیچوقت حذف یا بازنویسی نمیکند، پس اصلاح یک ابزارِ جدا میخواهد).
|
|
|
|
python tools/figures/apply_fixups.py fixups.json # فقط فایلهای seed محلی
|
|
venv/bin/python tools/figures/apply_fixups.py --db fixups.json # دیتابیسِ همین ماشین (روی سرور، پس از pg_dump)
|
|
|
|
fixups.json: {"delete": [[path, prompt], ...], "blank_title": [[path, prompt], ...]}
|
|
delete سوال را کامل پاک میکند (پاسخهای ثبتشدهاش هم میرود؛ فقط برای سوالِ تازهمنتشرشده)
|
|
blank_title عنوانِ زیرِ شکل را خالی میکند (عنوان گاهی جوابِ سوال را لو میداد)
|
|
سوال با (path, prompt) شناخته میشود؛ هر کدام پیدا نشود فهرست میشود، بیصدا رد نمیشود.
|
|
"""
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
sys.path.insert(0, ROOT)
|
|
|
|
|
|
def key(path, prompt):
|
|
return (tuple(path), prompt.strip())
|
|
|
|
|
|
def apply_seed(fx):
|
|
p = os.path.join(ROOT, 'content', 'seed', 'questions.json')
|
|
data = json.load(open(p))
|
|
dele = {key(*x) for x in fx.get('delete', [])}
|
|
blank = {key(*x) for x in fx.get('blank_title', [])}
|
|
seen_d, seen_b, out = set(), set(), []
|
|
for q in data['questions']:
|
|
k = key(q['path'], q['prompt'])
|
|
if k in dele:
|
|
seen_d.add(k)
|
|
continue
|
|
if k in blank and q.get('figure'):
|
|
q['figure']['title'] = ''
|
|
seen_b.add(k)
|
|
out.append(q)
|
|
data['questions'] = out
|
|
json.dump(data, open(p, 'w'), ensure_ascii=False, indent=1)
|
|
return dele - seen_d, blank - seen_b
|
|
|
|
|
|
def apply_db(fx):
|
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
|
|
import django
|
|
django.setup()
|
|
from content.models import Question
|
|
lessons = {}
|
|
from content.models import Lesson
|
|
for l in Lesson.objects.select_related('node__unit__grade'):
|
|
lessons[(l.node.unit.grade.title, l.node.unit.title, l.node.title, l.title)] = l.pk
|
|
miss_d, miss_b = set(), set()
|
|
for path, prompt in fx.get('delete', []):
|
|
lid = lessons.get(tuple(path))
|
|
qs = Question.objects.filter(lesson_id=lid, prompt=prompt.strip()) if lid else Question.objects.none()
|
|
if not qs.exists():
|
|
miss_d.add(key(path, prompt))
|
|
else:
|
|
qs.delete()
|
|
for path, prompt in fx.get('blank_title', []):
|
|
lid = lessons.get(tuple(path))
|
|
qs = list(Question.objects.filter(lesson_id=lid, prompt=prompt.strip())) if lid else []
|
|
if not qs:
|
|
miss_b.add(key(path, prompt))
|
|
for q in qs:
|
|
if q.figure:
|
|
q.figure = {**q.figure, 'title': ''}
|
|
q.save(update_fields=['figure'])
|
|
return miss_d, miss_b
|
|
|
|
|
|
if __name__ == '__main__':
|
|
args = [a for a in sys.argv[1:] if a != '--db']
|
|
fx = json.load(open(args[0]))
|
|
miss_d, miss_b = (apply_db if '--db' in sys.argv else apply_seed)(fx)
|
|
print(f'deleted/blanked ok; not found: delete={len(miss_d)} blank_title={len(miss_b)}')
|
|
for k in list(miss_d)[:5] + list(miss_b)[:5]:
|
|
print(' missing:', k[1][:60])
|