# -*- coding: utf-8 -*-
# Akvo Reporting is covered by the GNU Affero General Public License.
# See more details in the license.txt file located at the root folder of the Akvo RSR module.
# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.
from argparse import ArgumentParser
from typing import TextIO, Type
from django.apps import apps
from django.core.management.base import BaseCommand
from django.db import transaction
from akvo.rsr.models import Project, RelatedProject
[docs]class Command(BaseCommand):
help = "Move Project contributors from RelatedProject to .contributes_to_project " \
"and external_parent_iati_activity_id"
[docs] def add_arguments(self, parser: ArgumentParser):
parser.add_argument(
"--apply", action="store_true",
help="Actually apply the changes"
)
[docs] def handle(self, *args, **options):
migrator = Migrator(
self.stdout, self.stderr,
apps.get_model("rsr", "Project"),
apps.get_model("rsr", "RelatedProject"),
options.get("apply", False),
)
migrator.run()
[docs]class Migrator:
def __init__(
self,
stdout: TextIO,
stderr: TextIO,
project_model: Type[Project],
related_project_model: Type[RelatedProject],
apply: bool = False
):
self.stdout = stdout
self.stderr = stderr
self.project_model = project_model
self.related_project_model = related_project_model
self.apply = apply
[docs] def run(self):
try:
self.migrate()
except InterruptedError:
self.out("Changes not applied")
else:
self.out("Changes applied")
self.out("DONE!")
[docs] def out(self, msg: str):
self._write_to_stream(self.stdout, msg)
[docs] def err(self, msg: str):
self._write_to_stream(self.stderr, msg)
def _write_to_stream(self, stream: TextIO, msg: str):
ending = "" if msg.endswith("\n") else "\n"
stream.write(msg + ending)
stream.flush()
[docs] @transaction.atomic
def migrate(self):
self.out("===Migrating contributing projects from RelatedProject")
apply = self.apply
self.migrate_related_parents()
self.migrate_external_related_parents()
if not apply:
raise InterruptedError()