import os, sys, django sys.path.append("../") os.environ['PG_PORT_5432_TCP_ADDR'] = '127.0.0.1' os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.settings") django.setup() from management.models import Comment from django.contrib.contenttypes.models import ContentType from courses.models import Vertex, Lesson from access.models import ActiveObject from journals.models import Thread, HomeworkTry, ExamTry, Journal, Action, \ LessonJ, CourseThemeJ, TeacherJ, HomeworkJ, ExamJ from library.models import Article from django.contrib.auth import get_user_model from django.db import transaction def transaction_decorator(function_to_decorate): def wrap(*args, **kwargs): transaction.set_autocommit(False) try: result = function_to_decorate(*args, **kwargs) except Exception as ex: transaction.rollback() raise ex else: transaction.commit() return result finally: transaction.set_autocommit(True) return wrap @transaction_decorator def start_end_object(instance, pref, student, course, start_th_user, end_th_user): for thj in instance.objects.filter(date__isnull=False, student=student, material__course__in=course): obj_id = pref + str(thj.material.id) vertex = Vertex.manager.get(old_id=obj_id) Journal.objects.get_or_create( thread=start_th_user, user=student, content_type=vertex_type, date=thj.date, object_id=vertex.id, action_type=start_action, ) if thj.f_date: Journal.objects.get_or_create( thread=end_th_user, user=student, content_type=vertex_type, date=thj.f_date, object_id=vertex.id, action_type=end_action, ) def task_obj_try(instance, pref, teacher, task_thread): for obj_try in instance.objects.filter(teacher=teacher): vt_id = Vertex.manager.get(old_id=pref + str(obj_try.material.id)).id s_t_thread, _is_create = Thread.objects.get_or_create( key='task_%d__student_%d__teacher_%d' % (vt_id, obj_try.student.id, obj_try.teacher.id), is_staff=False, ) s_t_thread.parent.add(task_thread) s_t_thread.subscribers.add(obj_try.student) s_t_thread.subscribers.add(obj_try.teacher) user = obj_try.teacher action = Action.objects.get(name='no') if obj_try.success: action = Action.objects.get(name='yes') if obj_try.f_date is None: user = obj_try.student action = Action.objects.get(name='try') Journal.objects.get_or_create( thread=s_t_thread, user=user, content_type=vertex_type, date=obj_try.date, object_id=vt_id, action_type=action ) # # Выше - хелперы, ниже - основная часть программы # @transaction_decorator def main_threads(): print("Инициализация основных тредов") res = {} support_list = [ 'kate.gazukina@skillbox.ru', 'katerina.ragozina@skillbox.ru', ] admin_list = [ 'andrey.korolev@skillbox.ru', 'pavel.matveev@skillbox.ru', 'anton.kopylov@skillbox.ru', ] admin_thread, _is_create = Thread.objects.get_or_create( key='Admin', text='Тред для админов, сюда падают все журналируемые сообщения в системе', is_staff=True, ) for i in get_user_model().objects.filter(email__in=admin_list): admin_thread.subscribers.add(i) management_thread, _is_create = Thread.objects.get_or_create( key='Project_management', text='Тред для проджект-менеджеров, сюда падает статистика разного рода', is_staff=True, ) management_thread.parent.add(admin_thread) res['library_thread'], _is_create = Thread.objects.get_or_create( key='Library', text='Тред <<Библиотека>> сюда прилетает вся инфа по статьям', is_staff=True, ) res['library_thread'].parent.add(management_thread) start_and_end_thread, _is_create = Thread.objects.get_or_create( key='Start_and_end', text='Тред начала и завершения прохождения какого-либо этапа обучения', is_staff=True, ) start_and_end_thread.parent.add(management_thread) res['start_thread'], _is_create = Thread.objects.get_or_create( key='Start', text='Тред начала прохождения какого-либо этапа обучения', is_staff=True, ) res['start_thread'].parent.add(start_and_end_thread) res['end_thread'], _is_create = Thread.objects.get_or_create( key='End', text='Тред окончания прохождения какого-либо этапа обучения', is_staff=True, ) res['end_thread'].parent.add(start_and_end_thread) support_thread, _is_create = Thread.objects.get_or_create( key='Support', text='Тред сапортов, занимаются поддержкой клиента', is_staff=True, ) support_thread.parent.add(admin_thread) for i in get_user_model().objects.filter(email__in=support_list): support_thread.subscribers.add(i) res['task_thread'], _is_create = Thread.objects.get_or_create( key='Tasks', text='Сюда пободают все переписки студентов и преподов', is_staff=True, ) res['task_thread'].parent.add(support_thread) res['comment_thread'], _is_create = Thread.objects.get_or_create( key='Comments', text='Сюда пободают все лайки дизлайки и так далее по коментам', is_staff=True, ) res['comment_thread'].parent.add(support_thread) return res @transaction_decorator def create_article_journals(library_thread): print("Создание журналов для статей") for article in Article.objects.all(): article_kwarg = { 'content_type': article_type, 'object_id': article.id, 'thread': library_thread, } for author in article.favorite.all(): Journal.objects.get_or_create( user=author, action_type=Action.objects.get(name='favorite'), **article_kwarg, ) for author in article.likes.all(): Journal.objects.get_or_create( user=author, action_type=Action.objects.get(name='like'), **article_kwarg, ) for author in article.views.all(): Journal.objects.get_or_create( user=author, action_type=Action.objects.get(name='watch'), **article_kwarg, ) def start_end_journals(start_thread, end_thread): print("Создание журналов начала и завершения какого-либо этапа") for ao in ActiveObject.objects.all(): try: start_th_user, _is_create = Thread.objects.get_or_create( is_staff=False, key='start_thread_course_%d__user_%d' % (ao.course.id, ao.user.id), ) end_th_user, _is_create = Thread.objects.get_or_create( is_staff=False, key='end_thread_course_%d__user_%d' % (ao.course.id, ao.user.id), ) tj = TeacherJ.objects.get(course=ao.course, student=ao.user) Journal.objects.get_or_create( thread=start_th_user, user=ao.user, content_type=course_type, date=tj.start_date, object_id=ao.course.id, action_type=start_action, ) start_th_user.parent.add(start_thread) end_th_user.parent.add(end_thread) kwarg = { 'student': ao.user, 'course': ao.course, 'start_th_user': start_th_user, 'end_th_user': end_th_user, } start_end_object( instance=CourseThemeJ, pref='t_', **kwarg, ) start_end_object( instance=LessonJ, pref='l_', **kwarg, ) start_end_object( instance=HomeworkJ, pref='h_', **kwarg, ) start_end_object( instance=ExamJ, pref='e_', **kwarg, ) except TeacherJ.DoesNotExist: pass @transaction_decorator def task_try(task_tread): print("Журналы попыток домашек") for teacher in get_user_model().objects.filter(in_role='T'): task_obj_try( instance=HomeworkTry, pref='h_', teacher=teacher, task_thread=task_tread ) task_obj_try( instance=ExamTry, pref='e_', teacher=teacher, task_thread=task_tread ) @transaction_decorator def init_comment(comment_thread): comment_type = ContentType.objects.get(app_label='management', model='comment') for comment in Comment.objects.all(): comment_kwarg = { "content_type": course_type, "thread": comment_thread, "object_id": comment.id, } for user in comment.minus_rating.all(): Journal.objects.get_or_create( user=user, action_type=Action.objects.get(name="dislike"), **comment_kwarg, ) for user in comment.plus_rating.all(): Journal.objects.get_or_create( user=user, action_type=Action.objects.get(name="like"), **comment_kwarg, ) for user in comment.saw.all(): Journal.objects.get_or_create( user=user, action_type=Action.objects.get(name="watch"), **comment_kwarg, ) if __name__ == '__main__': if not "help" in sys.argv: vertex_type = ContentType.objects.get(app_label='courses', model='vertex') article_type = ContentType.objects.get(app_label='library', model='article') course_type = ContentType.objects.get(app_label='courses', model='course') start_action = Action.objects.get(name='start') end_action = Action.objects.get(name='end') boot_list = ['article', 'start_end', 'task_try', 'comment'] if len(sys.argv) == 1 else sys.argv[1:] main_threads_info = main_threads() if 'article' in boot_list: create_article_journals(main_threads_info['library_thread']) if 'start_end' in boot_list: start_end_journals(main_threads_info['start_thread'], main_threads_info['end_thread']) if 'task_try' in boot_list: task_try(main_threads_info['task_thread']) if 'comment' in boot_list: init_comment(main_threads_info['lesson_thread']) else: print(""" Это скрипт миграции в новую систему данных условно его можно разделить на несколько частей:\n 1 Инициализация основных тредов,\n 2 Создание журналов для статей,\n 3 Создание журналов начала и завершения какого-либо этапа,\n 4 Журналы попыток домашек,\n 5 Создание журналов для коментов,\n При запуске без флагов выполняются все этапы, но можно указать какой-то конкретный или несколько, article, start_end, task_try, comment (инициализация является обязательной) """)