Exemple #1
0
    def testRevertDeleteNestedInline(self):
        reversion.register(TestModel, follow=("testmodelinline_set", ))
        reversion.register(TestModelInline,
                           follow=("testmodelnestedinline_set", ))
        reversion.register(TestModelNestedInline)
        with reversion.create_revision():
            parent = TestModel.objects.create()
            child_a = TestModelInline.objects.create(test_model=parent)
            grandchild_a = TestModelNestedInline.objects.create(
                test_model_inline=child_a)

        with reversion.create_revision():
            child_b = TestModelInline.objects.create(test_model=parent)
            grandchild_b = TestModelNestedInline.objects.create(
                test_model_inline=child_b)
            reversion.add_to_revision(parent)

        Version.objects.get_for_object(parent)[1].revision.revert(delete=True)
        parent.refresh_from_db()
        self.assertRaises(TestModelInline.DoesNotExist,
                          lambda: child_b.refresh_from_db())

        self.assertRaises(TestModelNestedInline.DoesNotExist,
                          lambda: grandchild_b.refresh_from_db())
        self.assertEqual(list(parent.testmodelinline_set.all()), [child_a])
        self.assertEqual(list(child_a.testmodelnestedinline_set.all()),
                         [grandchild_a])
Exemple #2
0
def edit_installer(request, slug):
    installer = get_object_or_404(Installer, slug=slug)
    if 'delete' in request.POST:
        return redirect(
            reverse('delete_installer', kwargs={'slug': installer.slug}))
    if 'revision' in request.GET:
        try:
            revision_id = int(request.GET['revision'])
        except ValueError:
            revision_id = None
    else:
        revision_id = None
    versions = Version.objects.get_for_object(installer)
    initial_data = None
    for version in versions:
        if revision_id:
            if version.id == revision_id:
                initial_data = version.field_dict
                break
        else:
            if (version.revision.user == request.user
                    and version.revision.date_created > installer.updated_at):
                initial_data = version.field_dict
                revision_id = version.id
                break

    if initial_data:
        messages.info(
            request, "You are viewing a draft of the installer which does not "
            "reflect the currently available installer. Changes will be "
            "published once it goes through moderation.")
        if 'runner_id' in initial_data:
            initial_data['runner'] = initial_data['runner_id']

    form = InstallerForm(request.POST or None,
                         instance=installer,
                         initial=initial_data)
    if request.method == 'POST' and form.is_valid():
        with reversion.create_revision():
            installer = form.save(commit=False)
            reversion.set_user(request.user)
            reversion.set_comment("[{}] {} by {} on {}".format(
                'draft' if installer.draft else 'submission', slug,
                request.user.username, timezone.now()))
            reversion.add_to_revision(installer)
        return redirect("installer_complete", slug=installer.game.slug)
    return render(
        request, 'installers/form.html', {
            'form': form,
            'game': installer.game,
            'new': False,
            'installer': installer,
            'versions': versions,
            'revision_id': revision_id
        })
Exemple #3
0
    def form_valid(self, form):
        self.form = form
        source = Source.objects.get(uuid=self.kwargs['source_id'])

        reversion.set_comment(self.request.POST['comment'])
        reversion.add_to_revision(source)

        self.form.instance.source = source
        self.form.instance.user = self.request.user

        return super().form_valid(form)
    def form_valid(self, form):
        self.form = form
        source = Source.objects.get(uuid=self.kwargs['source_id'])

        reversion.set_comment(self.request.POST['comment'])
        reversion.add_to_revision(source)

        self.form.instance.source = source
        self.form.instance.user = self.request.user

        return super().form_valid(form)
Exemple #5
0
    def process_entity(self, entity, most_recent_version):
        # force revision date to be same as that of the most recent version
        # so status change is archived at the correct date

        reversion.set_date_created(most_recent_version.revision.date_created)

        # note in comment why this revision was created

        reversion.set_comment("Fixing status in object archives (script, #558)")

        # add entity to revision

        reversion.add_to_revision(entity)
def test_recover(admin_user, client):
    concurrentmodel = ReversionConcurrentModel.objects.create(username='******')
    with revisions.create_revision():
        set_comment("Initial revision")
        add_to_revision(concurrentmodel)

    ver = Version.objects.get_for_model(concurrentmodel).first()
    url = reverse('admin:demo_reversionconcurrentmodel_recover',
                  args=[concurrentmodel.pk])
    res = client.get(url, user=admin_user.username)
    res.form.submit().follow()

    concurrentmodel2 = ReversionConcurrentModel.objects.get(pk=concurrentmodel.pk)
    assert concurrentmodel2.username == ver.field_dict['username']
    assert concurrentmodel2.version > ver.field_dict['version']
Exemple #7
0
 def _create_revision(self):
     post_revision_commit.connect(self._handle_revision_commit, dispatch_uid='handle_revision_commit')
     with reversion.create_revision():
         reversion.set_comment(self.comment)
         reversion.set_user(self.user)
         # revision plugins and title for given language
         for plugin_instance in self.get_plugin_instances():
             reversion.add_to_revision(plugin_instance)
         reversion.add_to_revision(self.get_page_title())
     post_revision_commit.disconnect(dispatch_uid='handle_revision_commit')
     try:
         assert self._revision is not None
     except AssertionError:
         raise PageRevisionError(_(u'Revision creation failed'))
     return self._revision
Exemple #8
0
def forward_code(apps, schema_editor):
    MigrationModel = apps.get_model('reversion_compare_tests',
                                    'MigrationModel')
    with reversion.create_revision(manage_manually=True):
        info = 'Migration state 1 - version 1'
        item = MigrationModel.objects.create(info=info,
                                             number_then_text='Not a number 1',
                                             text=LOREM_IPSUM)
        reversion.set_comment(f'Reversion comment: {item.info}')
        reversion.add_to_revision(item)

    with reversion.create_revision(manage_manually=True):
        item.info = 'Migration state 1 - version 2'
        item.number_then_text = 'Not a number 2'
        item.text = LOREM_IPSUM
        reversion.set_comment(f'Reversion comment: {item.info}')
        reversion.add_to_revision(item)
Exemple #9
0
def create(req, tool):
    """Create a ToolInfo record."""
    if not member_or_admin(tool, req.user):
        messages.error(
            req, _('You are not a member of {tool}').format(tool=tool.name))
        return shortcuts.redirect(tool.get_absolute_url())

    initial_values = {
        'name': tool.name,
        'author': req.user,
    }
    if ToolInfo.objects.filter(tool=tool.name).count():
        initial_values['name'] = '{}-'.format(tool.name)
    form = ToolInfoForm(
        req.POST or None, req.FILES or None, initial=initial_values)
    if req.method == 'POST':
        if form.is_valid():
            try:
                with reversion.create_revision():
                    reversion.set_user(req.user)
                    reversion.set_comment(form.cleaned_data['comment'])
                    toolinfo = form.save(commit=False)
                    toolinfo.tool = tool.name
                    toolinfo.save()
                    form.save_m2m()
                    reversion.add_to_revision(toolinfo)
                messages.info(
                    req, _("Toolinfo {} created".format(toolinfo.title)))
                return shortcuts.redirect(
                    urls.reverse('tools:tool', kwargs={
                        'tool': tool.name,
                    }))
            except DatabaseError:
                logger.exception('ToolInfo.save failed')
                messages.error(
                    req,
                    _("Error updating database. [req id: {id}]").format(
                        id=req.id))
    ctx = {
        'tool': tool,
        'form': form,
    }
    return shortcuts.render(req, 'tools/info/create.html', ctx)
def forward_code(apps, schema_editor):
    MigrationModel = apps.get_model('reversion_compare_tests',
                                    'MigrationModel')
    item = MigrationModel.objects.first()

    with reversion.create_revision(manage_manually=True):
        item.info = 'Migration state 2 - version 3'
        item.number_then_text = 789
        item.text = 'Now this is a short text.'
        item.save()
        reversion.set_comment(f'Reversion comment: {item.info}')
        reversion.add_to_revision(item)

    with reversion.create_revision(manage_manually=True):
        item.info = 'Migration state 2 - version 4'
        item.number_then_text = 111
        item.text = 'Now this is a short text!!!'
        item.save()
        reversion.set_comment(f'Reversion comment: {item.info}')
        reversion.add_to_revision(item)
    def testRevertDeleteNestedInline(self):
        reversion.register(TestModel, follow=("testmodelinline_set",))
        reversion.register(
            TestModelInline, follow=("testmodelnestedinline_set",))
        reversion.register(TestModelNestedInline)
        with reversion.create_revision():
            parent = TestModel.objects.create()
            child_a = TestModelInline.objects.create(
                test_model=parent)
            grandchild_a = TestModelNestedInline.objects.create(
                test_model_inline=child_a)

        with reversion.create_revision():
            child_b = TestModelInline.objects.create(
                test_model=parent)
            grandchild_b = TestModelNestedInline.objects.create(
                test_model_inline=child_b)
            reversion.add_to_revision(parent)

        Version.objects.get_for_object(parent)[1].revision.revert(delete=True)
        parent.refresh_from_db()
        self.assertRaises(
            TestModelInline.DoesNotExist,
            lambda: child_b.refresh_from_db()
        )

        self.assertRaises(
            TestModelNestedInline.DoesNotExist,
            lambda: grandchild_b.refresh_from_db()
        )
        self.assertEqual(
            list(parent.testmodelinline_set.all()), [child_a]
        )
        self.assertEqual(
            list(child_a.testmodelnestedinline_set.all()), [grandchild_a]
        )
Exemple #12
0
def edit(req, tool, info_id):
    """Create a ToolInfo record."""
    toolinfo = shortcuts.get_object_or_404(ToolInfo, pk=info_id, tool=tool)
    if member_or_admin(tool, req.user):
        form = ToolInfoForm(
            req.POST or None, req.FILES or None, instance=toolinfo)
    else:
        form = ToolInfoPublicForm(
            req.POST or None, req.FILES or None, instance=toolinfo)

    if req.method == 'POST':
        if form.is_valid():
            try:
                with reversion.create_revision():
                    reversion.set_user(req.user)
                    reversion.set_comment(form.cleaned_data['comment'])
                    toolinfo = form.save()
                    reversion.add_to_revision(toolinfo)
                messages.info(
                    req, _("Toolinfo {} updated".format(toolinfo.title)))
                return shortcuts.redirect(
                    urls.reverse('tools:tool', kwargs={
                        'tool': tool.name,
                    }))
            except DatabaseError:
                logger.exception('ToolInfo.save failed')
                messages.error(
                    req,
                    _("Error updating database. [req id: {id}]").format(
                        id=req.id))
    ctx = {
        'tool': tool,
        'toolinfo': toolinfo,
        'form': form,
    }
    return shortcuts.render(req, 'tools/info/update.html', ctx)
Exemple #13
0
    def migrate_ixlan_id(self, ixlan, ixlans, trigger=None, tmp_id=False):

        """
        Migrate an ixlan id so it matches the parent exchange id
        """

        # ids already match, nothind to do here

        if ixlan.id == ixlan.ix.id:
            return

        ix = ixlan.ix
        new_id = ix.id
        old_id = ixlan.id

        # indicates that we want to migrate this ixlan to a temporary
        # id for now, so we override new_id with a temporary id

        if tmp_id:
            new_id = self.tmp_id

        # targeted ixlan id currently claimed by another ixlan (that is not this ixlan)

        if ixlans.get(new_id) and ixlans.get(new_id) != ixlan:

            # migrate conflicting ixlan id

            if not trigger or trigger.id != new_id:
                self.migrate_ixlan_id(ixlans[new_id], ixlans, trigger=ixlan)
            else:

                # this ixlan id migration was triggered by the same ixlan
                # we are trying to resolve the conflict for, so to avoid
                # and endless loop we migrate to a temporary id

                self.migrate_ixlan_id(
                    ixlans[new_id], ixlans, trigger=ixlan, tmp_id=True
                )

        # migrate ixlan id (in memory)

        ixlan.id = new_id

        if not tmp_id:
            ixlans[new_id] = ixlan

        if ixlans.get(old_id) == ixlan:
            del ixlans[old_id]

        # if ixlan was migrated to a temporary id during conflict
        # resolving above: old_id needs to be updated to temporary id

        if hasattr(ixlan, "tmp_id"):
            old_id = ixlan.tmp_id
        elif tmp_id:
            ixlan.tmp_id = new_id

        # update migration report

        if not tmp_id:
            self.report_migration(old_id, new_id, ixlan)

        self.log(
            "Migrated [{}] ixlan id {} -> {} - Exchange: {}".format(
                ixlan.status, old_id, new_id, ix.name
            )
        )

        # migrate ixlan id (database)

        self.migrate_ixlan_id_sql(old_id, ixlan.id)

        # create reversion revision for all updated entities

        if self.commit:

            # on deleted exchanges we also need to save the ix
            # and the org so it will be available in the api's incrememental
            # update response

            if ixlan.ix.status == "deleted":
                ixlan.ix.save()
                ixlan.ix.org.save()

            with reversion.create_revision():
                reversion.set_comment(
                    "Migrated to new ixlan id: {} -> {} (script, #21)".format(
                        old_id, ixlan.id
                    )
                )
                reversion.add_to_revision(ixlan)
                for netixlan in ixlan.netixlan_set.all():
                    reversion.add_to_revision(netixlan)

                    # on deleted netixlan networks
                    # we also need to save the netixlan's network and org
                    # so they will be available in api's incremental update
                    # responses

                    if netixlan.network.status == "deleted":
                        netixlan.network.save()
                        netixlan.network.org.save()
                for ixpfx in ixlan.ixpfx_set.all():
                    reversion.add_to_revision(ixpfx)

        # if old_id still points to this ixlan in our ixlans collection
        # delete it so we know the old id is now available

        if ixlans.get(old_id) == ixlan:
            del ixlans[old_id]

        # update migration stats

        self.stats[f"migrated_{ixlan.status}"] += 1
Exemple #14
0
def edit_installer(request, slug):
    """Display an edit form for install scripts

    Args:
        request: Django request object
        slug (str): installer slug

    Returns:
        Django response
    """

    installer = get_object_or_404(Installer, slug=slug)

    # Handle installer deletion in a separate view
    if "delete" in request.POST:
        return redirect(
            reverse("delete_installer", kwargs={"slug": installer.slug}))
    # Extract optional revision ID from parameters
    revision_id = request.GET.get("revision")
    try:
        revision_id = int(revision_id)
    except (ValueError, TypeError):
        revision_id = None

    draft_data = None
    versions = Version.objects.get_for_object(installer)

    # Reset reason when the installer is edited.
    installer.reason = ""

    for version in versions:
        if revision_id:
            # Display the revision given in the GET parameters
            if version.revision.id == revision_id:
                draft_data = version.field_dict
                break
        else:
            # Display the latest revision created by the current logged in user
            if (version.revision.user == request.user or request.user.is_staff
                ) and version.revision.date_created > installer.updated_at:
                draft_data = version.field_dict
                revision_id = version.revision.id
                break
    if draft_data:
        draft_data["reason"] = ""
        if "runner_id" in draft_data:
            draft_data["runner"] = draft_data["runner_id"]

    form = InstallerEditForm(request.POST or None,
                             instance=installer,
                             initial=draft_data)
    if request.method == "POST" and form.is_valid():
        # Force the creation of a revision instead of creating a new installer
        with reversion.create_revision():
            installer = form.save(commit=False)
            reversion.set_user(request.user)
            reversion.set_comment("[{}] {} by {} on {}".format(
                "draft" if installer.draft else "submission",
                slug,
                request.user.username,
                timezone.now(),
            ))
            reversion.add_to_revision(installer)

        if "save" in request.POST:
            messages.info(request, "Draft saved")
            return redirect("edit_installer", slug=installer.slug)
        messages.info(request, "Submission sent to moderation")
        return redirect("installer_complete", slug=installer.game.slug)

    if draft_data:
        messages.info(
            request,
            "You are viewing a draft of the installer which does not "
            "reflect the currently available installer. Changes will be "
            "published once it goes through moderation.",
        )
    return render(
        request, "installers/form.html", {
            "form": form,
            "game": installer.game,
            "new": False,
            "installer": installer,
            "versions": versions,
            "revision_id": revision_id,
        })
Exemple #15
0
def edit_installer(request, slug):
    """Display an edit form for install scripts

    Args:
        request: Django request object
        slug (str): installer slug

    Returns:
        Django response
    """

    installer = get_object_or_404(Installer, slug=slug)

    # Handle installer deletion in a separate view
    if 'delete' in request.POST:
        return redirect(
            reverse('delete_installer', kwargs={'slug': installer.slug}))

    # Extract optional revision ID from parameters
    revision_id = request.GET.get('revision')
    try:
        revision_id = int(revision_id)
    except (ValueError, TypeError):
        revision_id = None

    draft_data = None
    versions = Version.objects.get_for_object(installer)
    for version in versions:
        if revision_id:
            # Display the revision given in the GET parameters
            if version.id == revision_id:
                draft_data = version.field_dict
                break
        else:
            # Display the latest revision created by the current logged in user
            if (version.revision.user == request.user
                    and version.revision.date_created > installer.updated_at):
                draft_data = version.field_dict
                revision_id = version.id
                break

    if draft_data:
        messages.info(
            request, "You are viewing a draft of the installer which does not "
            "reflect the currently available installer. Changes will be "
            "published once it goes through moderation.")
        if 'runner_id' in draft_data:
            draft_data['runner'] = draft_data['runner_id']

    form = InstallerEditForm(request.POST or None,
                             instance=installer,
                             initial=draft_data)
    if request.method == 'POST' and form.is_valid():
        # Force the creation of a revision instead of creating a new installer
        with reversion.create_revision():
            installer = form.save(commit=False)
            reversion.set_user(request.user)
            reversion.set_comment("[{}] {} by {} on {}".format(
                'draft' if installer.draft else 'submission', slug,
                request.user.username, timezone.now()))
            reversion.add_to_revision(installer)
        return redirect("installer_complete", slug=installer.game.slug)
    return render(
        request, 'installers/form.html', {
            'form': form,
            'game': installer.game,
            'new': False,
            'installer': installer,
            'versions': versions,
            'revision_id': revision_id
        })
Exemple #16
0
def edit_installer(request, slug):
    """Display an edit form for install scripts

    Args:
        request: Django request object
        slug (str): installer slug

    Returns:
        Django response
    """

    installer = get_object_or_404(Installer, slug=slug)

    # Handle installer deletion in a separate view
    if "delete" in request.POST:
        return redirect(reverse("delete_installer", kwargs={"slug": installer.slug}))
    # Extract optional revision ID from parameters
    revision_id = request.GET.get("revision")
    try:
        revision_id = int(revision_id)
    except (ValueError, TypeError):
        revision_id = None

    draft_data = None
    versions = Version.objects.get_for_object(installer)

    # Reset reason when the installer is edited.
    installer.reason = ""

    for version in versions:
        if revision_id:
            # Display the revision given in the GET parameters
            if version.revision.id == revision_id:
                draft_data = version.field_dict
                break
        else:
            # Display the latest revision created by the current logged in user
            if (
                    version.revision.user == request.user or request.user.is_staff
            ) and version.revision.date_created > installer.updated_at:
                draft_data = version.field_dict
                revision_id = version.revision.id
                break
    if draft_data:
        draft_data["reason"] = ""
        if "runner_id" in draft_data:
            draft_data["runner"] = draft_data["runner_id"]

    form = InstallerEditForm(
        request.POST or None, instance=installer, initial=draft_data
    )
    if request.method == "POST" and form.is_valid():
        # Force the creation of a revision instead of creating a new installer
        with reversion.create_revision():
            installer = form.save(commit=False)
            reversion.set_user(request.user)
            reversion.set_comment(
                "[{}] {} by {} on {}".format(
                    "draft" if installer.draft else "submission",
                    slug,
                    request.user.username,
                    timezone.now(),
                )
            )
            reversion.add_to_revision(installer)

        if "save" in request.POST:
            messages.info(request, "Draft saved")
            return redirect("edit_installer", slug=installer.slug)
        messages.info(request, "Submission sent to moderation")
        return redirect("installer_complete", slug=installer.game.slug)

    if draft_data:
        messages.info(
            request,
            "You are viewing a draft of the installer which does not "
            "reflect the currently available installer. Changes will be "
            "published once it goes through moderation.",
        )
    return render(
        request,
        "installers/form.html",
        {
            "form": form,
            "game": installer.game,
            "new": False,
            "installer": installer,
            "versions": versions,
            "revision_id": revision_id,
        }
    )