def handle(self, *args, **options):
        delete_older_than_datetime = datetimeutils.from_isoformat(
            options['datetime']).replace(second=0, microsecond=0)
        delete_empty_subjects = options['delete_empty_subjects']

        now = timezone.now()
        if delete_older_than_datetime >= now:
            self.stderr.write(
                'EXITING... Given datetime {} must be earlier than now ({})'.format(
                    arrow.get(delete_older_than_datetime.astimezone(
                        timezone.get_current_timezone())).format('MMM D. YYYY HH:mm'),
                    arrow.get(
                        now.astimezone(timezone.get_current_timezone())).format('MMM D. YYYY HH:mm')
                ))
            raise SystemExit()

        if not Period.objects.filter(end_time__lt=delete_older_than_datetime).exists():
            self.stderr.write(
                'EXITING... There are no semesters that ended before {}.'.format(
                    arrow.get(delete_older_than_datetime).format('MMM D. YYYY HH:mm')))
            raise SystemExit()

        self.stdout.write('###########################################################\n'
                          '# Delete all semesters that ended before: {}\n'
                          '# Delete subjects if all semester are deleted: {}'
                          '\n###########################################################'.format(
            arrow.get(delete_older_than_datetime).format('MMM D. YYYY HH:mm'),
            'YES' if delete_empty_subjects else 'NO'
        ))

        # Instantiate period deleter
        period_deleter = PeriodDelete(
            end_time_older_than_datetime=delete_older_than_datetime,
            delete_empty_subjects=delete_empty_subjects,
            log_info=True)

        self.stdout.write(
            '\nPreview of semesters that will be deleted:\n'.format(
                arrow.get(delete_older_than_datetime).format('MMM D. YYYY HH:mm')))
        self.stdout.write('\n')
        self.stdout.write(period_deleter.get_preview())
        self.stdout.write('\n')

        # User must confirm the deletion.
        self.__confirm_delete()

        # Start deletion
        with transaction.atomic():
            call_command('ievvtasks_customsql', '--clear')

            self.stdout.write('Deleting periods...')
            period_deleter.delete()

            call_command('ievvtasks_customsql', '-i', '-r')
 def test_deletes_stored_files_for_multiple_comments(self):
     testperiod = mommy.make('core.Period', end_time=timezone.now())
     testassignment = mommy.make('core.Assignment', parentnode=testperiod)
     testgroup = mommy.make('core.AssignmentGroup',
                            parentnode=testassignment)
     testfeedbackset = mommy.make('devilry_group.FeedbackSet',
                                  group=testgroup)
     testcomment1 = mommy.make('devilry_group.GroupComment',
                               feedback_set=testfeedbackset)
     testcomment2 = mommy.make('devilry_group.GroupComment',
                               feedback_set=testfeedbackset)
     commentfile1 = mommy.make('devilry_comment.CommentFile',
                               comment=testcomment1,
                               filename='testfile1.txt')
     commentfile1.file.save('testfile1.txt', ContentFile('testcontent'))
     commentfile2 = mommy.make('devilry_comment.CommentFile',
                               comment=testcomment2,
                               filename='testfile2.txt')
     commentfile2.file.save('testfile2.txt', ContentFile('testcontent'))
     file_path1 = commentfile1.file.path
     file_path2 = commentfile2.file.path
     self.assertTrue(os.path.exists(file_path1))
     self.assertTrue(os.path.exists(file_path2))
     PeriodDelete(end_time_older_than_datetime=timezone.now() +
                  timezone.timedelta(days=10)).delete()
     self.assertFalse(os.path.exists(file_path1))
     self.assertFalse(os.path.exists(file_path2))
     self.assertEqual(GroupComment.objects.count(), 0)
     self.assertEqual(Comment.objects.count(), 0)
     self.assertEqual(CommentFile.objects.count(), 0)
    def test_does_not_delete_files_for_other_periods(self):
        testfeedbackset = mommy.make(
            'devilry_group.FeedbackSet',
            group__parentnode__parentnode__end_time=timezone.now() +
            timezone.timedelta(days=300))
        testcomment = mommy.make('devilry_group.GroupComment',
                                 feedback_set=testfeedbackset)
        commentfile = mommy.make('devilry_comment.CommentFile',
                                 comment=testcomment,
                                 filename='notdeleted.txt')
        commentfile.file.save('testfile.txt', ContentFile('testcontent'))
        file_path = commentfile.file.path

        to_delete_testfeedbackset = mommy.make(
            'devilry_group.FeedbackSet',
            group__parentnode__parentnode__end_time=timezone.now())
        to_delete_testcomment = mommy.make(
            'devilry_group.GroupComment',
            feedback_set=to_delete_testfeedbackset)
        to_delete_commentfile = mommy.make('devilry_comment.CommentFile',
                                           comment=to_delete_testcomment,
                                           filename='testfile.txt')
        to_delete_commentfile.file.save('testfile.txt',
                                        ContentFile('testcontent'))
        to_delete_file_path = to_delete_commentfile.file.path

        self.assertTrue(os.path.exists(file_path))
        self.assertTrue(os.path.exists(to_delete_file_path))

        PeriodDelete(end_time_older_than_datetime=timezone.now() +
                     timezone.timedelta(days=10)).delete()

        self.assertTrue(os.path.exists(file_path))
        self.assertFalse(os.path.exists(to_delete_file_path))
 def test_excludes_initially_empty_subjects(self):
     subject_without_period = mommy.make('core.Subject')
     mommy.make('core.Period', end_time=timezone.now())
     self.assertEqual(Subject.objects.count(), 2)
     self.assertEqual(Period.objects.count(), 1)
     PeriodDelete(end_time_older_than_datetime=timezone.now() +
                  timezone.timedelta(days=10),
                  delete_empty_subjects=True).delete()
     self.assertEqual(Subject.objects.get(), subject_without_period)
     self.assertEqual(Period.objects.count(), 0)
    def test_assignment_groups_are_deleted(self):
        testperiod = mommy.make('core.Period', end_time=timezone.now())
        mommy.make('core.PeriodTag', period=testperiod)
        testassignment = mommy.make('core.Assignment', parentnode=testperiod)
        mommy.make('core.AssignmentGroup', parentnode=testassignment)

        self.assertEqual(AssignmentGroup.objects.count(), 1)
        PeriodDelete(end_time_older_than_datetime=timezone.now() +
                     timezone.timedelta(days=10)).delete()
        self.assertEqual(AssignmentGroup.objects.count(), 0)
    def test_feedbacksets_are_deleted(self):
        testperiod = mommy.make('core.Period', end_time=timezone.now())
        mommy.make('core.PeriodTag', period=testperiod)
        testassignment = mommy.make('core.Assignment', parentnode=testperiod)
        testgroup = mommy.make('core.AssignmentGroup',
                               parentnode=testassignment)
        mommy.make('devilry_group.FeedbackSet', group=testgroup)

        self.assertEqual(FeedbackSet.objects.count(), 1)
        PeriodDelete(end_time_older_than_datetime=timezone.now() +
                     timezone.timedelta(days=10)).delete()
        self.assertEqual(FeedbackSet.objects.count(), 0)
 def testsubject_deleted_if_all_periods_are_deleted(self):
     testsubject = mommy.make('core.Subject')
     mommy.make('core.Period',
                parentnode=testsubject,
                end_time=timezone.now())
     self.assertEqual(Subject.objects.count(), 1)
     self.assertEqual(Period.objects.count(), 1)
     PeriodDelete(end_time_older_than_datetime=timezone.now() +
                  timezone.timedelta(days=10),
                  delete_empty_subjects=True).delete()
     self.assertEqual(Subject.objects.count(), 0)
     self.assertEqual(Period.objects.count(), 0)
 def test_subject_not_deleted_if_not_all_periods_are_deleted(self):
     testsubject = mommy.make('core.Subject')
     mommy.make('core.Period',
                parentnode=testsubject,
                end_time=timezone.now())
     period_not_deleted = mommy.make('core.Period',
                                     parentnode=testsubject,
                                     end_time=timezone.now() +
                                     timezone.timedelta(days=50))
     self.assertEqual(Subject.objects.count(), 1)
     self.assertEqual(Period.objects.count(), 2)
     PeriodDelete(end_time_older_than_datetime=timezone.now() +
                  timezone.timedelta(days=10)).delete()
     self.assertEqual(Subject.objects.get(), testsubject)
     self.assertEqual(Period.objects.get(), period_not_deleted)
    def test_examiners_and_related_examiners_are_deleted(self):
        testperiod = mommy.make('core.Period', end_time=timezone.now())
        mommy.make('core.PeriodTag', period=testperiod)
        testassignment = mommy.make('core.Assignment', parentnode=testperiod)
        testgroup = mommy.make('core.AssignmentGroup',
                               parentnode=testassignment)
        testrelatedexaminer = mommy.make('core.RelatedExaminer',
                                         period=testperiod)
        mommy.make('core.Examiner',
                   assignmentgroup=testgroup,
                   relatedexaminer=testrelatedexaminer)

        self.assertEqual(RelatedExaminer.objects.count(), 1)
        self.assertEqual(Examiner.objects.count(), 1)
        PeriodDelete(end_time_older_than_datetime=timezone.now() +
                     timezone.timedelta(days=10)).delete()
        self.assertEqual(RelatedExaminer.objects.count(), 0)
        self.assertEqual(Examiner.objects.count(), 0)
    def test_candidates_and_related_students_are_deleted(self):
        testperiod = mommy.make('core.Period', end_time=timezone.now())
        mommy.make('core.PeriodTag', period=testperiod)
        testassignment = mommy.make('core.Assignment', parentnode=testperiod)
        testgroup = mommy.make('core.AssignmentGroup',
                               parentnode=testassignment)
        testrelatedstudent = mommy.make('core.RelatedStudent',
                                        period=testperiod)
        mommy.make('core.Candidate',
                   assignment_group=testgroup,
                   relatedstudent=testrelatedstudent)

        self.assertEqual(RelatedStudent.objects.count(), 1)
        self.assertEqual(Candidate.objects.count(), 1)
        PeriodDelete(end_time_older_than_datetime=timezone.now() +
                     timezone.timedelta(days=10)).delete()
        self.assertEqual(RelatedStudent.objects.count(), 0)
        self.assertEqual(Candidate.objects.count(), 0)
 def test_deletes_stored_file_for_comment(self):
     testperiod = mommy.make('core.Period', end_time=timezone.now())
     testassignment = mommy.make('core.Assignment', parentnode=testperiod)
     testgroup = mommy.make('core.AssignmentGroup',
                            parentnode=testassignment)
     testfeedbackset = mommy.make('devilry_group.FeedbackSet',
                                  group=testgroup)
     testcomment = mommy.make('devilry_group.GroupComment',
                              feedback_set=testfeedbackset)
     commentfile = mommy.make('devilry_comment.CommentFile',
                              comment=testcomment,
                              filename='testfile.txt')
     commentfile.file.save('testfile.txt', ContentFile('testcontent'))
     file_path = commentfile.file.path
     self.assertTrue(os.path.exists(file_path))
     PeriodDelete(end_time_older_than_datetime=timezone.now() +
                  timezone.timedelta(days=10)).delete()
     self.assertFalse(os.path.exists(file_path))
    def test_only_deletes_periods_older_than_sanity(self):
        testperiod1 = mommy.make('core.Period',
                                 end_time=timezone.now() +
                                 timezone.timedelta(days=1))
        testperiod2 = mommy.make('core.Period',
                                 end_time=timezone.now() +
                                 timezone.timedelta(days=2))
        testperiod3 = mommy.make('core.Period',
                                 end_time=timezone.now() -
                                 timezone.timedelta(days=1))
        testperiod4 = mommy.make('core.Period',
                                 end_time=timezone.now() -
                                 timezone.timedelta(days=2))

        PeriodDelete(end_time_older_than_datetime=timezone.now()).delete()

        self.assertTrue(Period.objects.filter(id=testperiod1.id).exists())
        self.assertTrue(Period.objects.filter(id=testperiod2.id).exists())
        self.assertFalse(Period.objects.filter(id=testperiod3.id).exists())
        self.assertFalse(Period.objects.filter(id=testperiod4.id).exists())
示例#13
0
    def handle(self, *args, **options):
        delete_older_than_datetime = datetimeutils.from_isoformat(
            options['datetime']).replace(second=0, microsecond=0)
        delete_empty_subjects = options['delete_empty_subjects']

        now = timezone.now()
        if delete_older_than_datetime >= now:
            self.stderr.write(
                'EXITING... Given datetime {} must be earlier than now ({})'.
                format(
                    arrow.get(
                        delete_older_than_datetime.astimezone(
                            timezone.get_current_timezone())).format(
                                'MMM D. YYYY HH:mm'),
                    arrow.get(now.astimezone(
                        timezone.get_current_timezone())).format(
                            'MMM D. YYYY HH:mm')))
            raise SystemExit()

        if not Period.objects.filter(
                end_time__lt=delete_older_than_datetime).exists():
            self.stderr.write(
                'EXITING... There are no semesters that ended before {}.'.
                format(
                    arrow.get(delete_older_than_datetime).format(
                        'MMM D. YYYY HH:mm')))
            raise SystemExit()

        self.stdout.write(
            '###########################################################\n'
            '# Delete all semesters that ended before: {}\n'
            '# Delete subjects if all semester are deleted: {}'
            '\n###########################################################'.
            format(
                arrow.get(delete_older_than_datetime).format(
                    'MMM D. YYYY HH:mm'),
                'YES' if delete_empty_subjects else 'NO'))

        # Instantiate period deleter
        period_deleter = PeriodDelete(
            end_time_older_than_datetime=delete_older_than_datetime,
            delete_empty_subjects=delete_empty_subjects,
            log_info=True)

        self.stdout.write(
            '\nPreview of semesters that will be deleted:\n'.format(
                arrow.get(delete_older_than_datetime).format(
                    'MMM D. YYYY HH:mm')))
        self.stdout.write('\n')
        self.stdout.write(period_deleter.get_preview())
        self.stdout.write('\n')

        # User must confirm the deletion.
        self.__confirm_delete()

        # Start deletion
        with transaction.atomic():
            call_command('ievvtasks_customsql', '--clear')

            self.stdout.write('Deleting periods...')
            period_deleter.delete()

            call_command('ievvtasks_customsql', '-i', '-r')
    def test_sanity_delete_cascade(self):
        testsubject = mommy.make('core.Subject')
        subjectpermissiongroup = mommy.make(
            'devilry_account.SubjectPermissionGroup', subject=testsubject)
        mommy.make('devilry_account.PermissionGroupUser',
                   user=mommy.make(settings.AUTH_USER_MODEL),
                   permissiongroup=subjectpermissiongroup.permissiongroup)

        testperiod = mommy.make('core.Period',
                                parentnode=testsubject,
                                end_time=timezone.now())
        periodpermissiongroup = mommy.make(
            'devilry_account.PeriodPermissionGroup', period=testperiod)
        mommy.make('devilry_account.PermissionGroupUser',
                   user=mommy.make(settings.AUTH_USER_MODEL),
                   permissiongroup=periodpermissiongroup.permissiongroup)
        testrelatedexaminer = mommy.make('core.RelatedExaminer',
                                         period=testperiod)
        testrelatedstudent = mommy.make('core.RelatedStudent',
                                        period=testperiod)
        mommy.make('core.PeriodTag', period=testperiod)
        testassignment = mommy.make('core.Assignment', parentnode=testperiod)
        testgroup = mommy.make('core.AssignmentGroup',
                               parentnode=testassignment)
        mommy.make('core.Examiner',
                   assignmentgroup=testgroup,
                   relatedexaminer=testrelatedexaminer)
        mommy.make('core.Candidate',
                   assignment_group=testgroup,
                   relatedstudent=testrelatedstudent)
        testfeedbackset = mommy.make('devilry_group.FeedbackSet',
                                     group=testgroup)
        mommy.make('devilry_group.GroupComment', feedback_set=testfeedbackset)

        self.assertEqual(Subject.objects.count(), 1)
        self.assertEqual(SubjectPermissionGroup.objects.count(), 1)
        self.assertEqual(Period.objects.count(), 1)
        self.assertEqual(RelatedExaminer.objects.count(), 1)
        self.assertEqual(RelatedStudent.objects.count(), 1)
        self.assertEqual(PeriodTag.objects.count(), 1)
        self.assertEqual(PeriodPermissionGroup.objects.count(), 1)
        self.assertEqual(PermissionGroupUser.objects.count(), 2)
        self.assertEqual(Assignment.objects.count(), 1)
        self.assertEqual(AssignmentGroup.objects.count(), 1)
        self.assertEqual(Examiner.objects.count(), 1)
        self.assertEqual(Candidate.objects.count(), 1)
        self.assertEqual(FeedbackSet.objects.count(), 1)
        self.assertEqual(GroupComment.objects.count(), 1)
        self.assertEqual(Comment.objects.count(), 1)

        PeriodDelete(end_time_older_than_datetime=timezone.now() +
                     timezone.timedelta(days=10),
                     delete_empty_subjects=True).delete()

        self.assertEqual(Subject.objects.count(), 0)
        self.assertEqual(SubjectPermissionGroup.objects.count(), 0)
        self.assertEqual(Period.objects.count(), 0)
        self.assertEqual(RelatedExaminer.objects.count(), 0)
        self.assertEqual(RelatedStudent.objects.count(), 0)
        self.assertEqual(PeriodTag.objects.count(), 0)
        self.assertEqual(PeriodPermissionGroup.objects.count(), 0)
        self.assertEqual(Assignment.objects.count(), 0)
        self.assertEqual(AssignmentGroup.objects.count(), 0)
        self.assertEqual(Examiner.objects.count(), 0)
        self.assertEqual(Candidate.objects.count(), 0)
        self.assertEqual(FeedbackSet.objects.count(), 0)
        self.assertEqual(GroupComment.objects.count(), 0)
        self.assertEqual(Comment.objects.count(), 0)
        self.assertEqual(PermissionGroup.objects.count(), 2)
        self.assertEqual(PermissionGroupUser.objects.count(), 2)
 def test_end_time_not_less_than(self):
     mommy.make('core.Period',
                end_time=timezone.now() + timezone.timedelta(days=10))
     PeriodDelete(end_time_older_than_datetime=timezone.now()).delete()
     self.assertEqual(Period.objects.count(), 1)