diff --git a/kitsune/products/migrations/0010_auto_20240624_0616.py b/kitsune/products/migrations/0010_auto_20240624_0616.py new file mode 100644 index 000000000..3815d1dd4 --- /dev/null +++ b/kitsune/products/migrations/0010_auto_20240624_0616.py @@ -0,0 +1,175 @@ +# Generated by Django 4.2.11 on 2024-06-24 06:16 +# Data migration to move KB articles to different topics + +from django.db import migrations + +from kitsune.questions.config import products as PRODUCTS_CONFIG + +# The key is the topic slug to migrate to and the value is the list +# of topic slugs to migrate from, +# If the topic for each product does not exist, it will be created +# If it exists, the articles will be moved to the existing topic for each product. +# If the topics is created, a redirect will be added to the old topic. +TOPICS_TO_MIGRATE = { + "install-and-update:": [ + "install-and-update-firefox", + "install-and-update-firefox-ios", + "download-and-install", + "download-setup", + "deploy-firefox-for-enterprise", + "installation-enterprise", + "deploy-firefox-enterprise-mac", + "deploy-firefox-enterprise-windows", + "deploy-firefox-enterprise-linux", + "install-migrate-and-update", + "download-install-and-migration", + "install-lockwise", + ], + "troubleshooting": [ + "fix-problems", + "fix-problems-firefox", + "crashes-errors-and-other-issues", + "firefox-ios-not-working-expected", + "fix-slowness-crashing-error-messages-and-other-problems", + "troubleshoot", + "troubleshoot-issues", + "fix-problems-lockwise", + "troubleshooting-reality", + ], + "protect-your-privacy": [ + "stay-private-and-secure", + "privacy-and-security", + "privacy-and-security-settings", + "passwords-forms-and-search", + "security-privacy", + "protect-your-privacy-firefox-android", + "privacy-settings-firefox-ios", + ], + "emails": [ + "emails-thunderbird", + "set-up-email-thunderbird", + ], + "customize-settings-and-preferences": [ + "manage-preferences-and-add-ons-firefox", + "firefox-settings", + "personalize-firefox", + "personalize-firefox-settings", + "customize", + "controls", + "tab-settings", + "firefox-options-preferences-and-settings", + "bookmark-options", + "personalize-your-experience", + "firefox-android-settings", + "customize-settings-firefox-android", + "customize-preferences-ios", + "customization-firefox-enterprise-environment", + "policies-customization-enterprise", + "manage-certificates-firefox-enterprise", + "policies-overview-enterprise", + "manage-settings-policy", + "autoconfiguration-enterprise", + "hubs-permissions-settings", + "thunderbird-controls-and-buttons", + "tab-settings", + "thunderbird-options-preferences-and-settings", + "update-account-settings", + "customize-controls-options-and-add-ons", + ], + "install-and-manage-add-ons": [ + "install-and-manage-add-ons-firefox", + "use-extensions-and-add-ons", + "add-ons", + "manage-add-ons-enterprise", + "customize-thunderbird-add-ons-plugins-and-extensions", + ], +} + + +def move_kb_articles(apps, schema_editor): + Topic = apps.get_model("products", "Topic") + TopicSlugHistory = apps.get_model("products", "TopicSlugHistory") + title = "" + for target_slug in TOPICS_TO_MIGRATE.keys(): + + match target_slug: + case "install-and-update": + title = "Install and Update" + case "troubleshooting": + title = "Troubleshooting" + case "protect-your-privacy": + title = "Protect your privacy" + case "emails": + title = "Emails" + case "customize-settings-and-preferences": + title = "Customize settings and preferences" + case "install-and-manage-add-ons": + title = "Install and manage add-ons" + case _: + pass + + source_topics = Topic.objects.filter(slug__in=TOPICS_TO_MIGRATE.get(target_slug, [])) + for source_topic in source_topics: + product = source_topic.product + created = False + + try: + target_topic = Topic.objects.get(slug=target_slug, product=product) + except Topic.DoesNotExist: + created = True + target_topic = Topic.objects.create( + title=title, + slug=target_slug, + product=product, + display_order=source_topic.display_order, + visible=True, + description=title, + ) + + # Make sure that target topics are not sub-topics + if target_topic.parent: + target_topic.parent = None + + # make sure the target topic is visible and it has the correct title + if not created: + target_topic.title = title + target_topic.description = title + target_topic.visible = True + target_topic.save() + + # Migrate KB articles to new topics + documents = source_topic.document_set.all() + for document in documents: + document.topics.add(target_topic) + document.topics.remove(source_topic) + + # Migrate questions to the new topic + if source_topic.questions.exists(): + for question in source_topic.questions.all(): + question.topic = target_topic + question.save() + + # handle redirects for the old topics + if ( + not TopicSlugHistory.objects.filter(slug=source_topic.slug).exists() + and product.visible + ): + TopicSlugHistory.objects.create(slug=source_topic.slug, topic=target_topic) + + # Finally let's make the source topic invisible + source_topic.visible = False + source_topic.save() + + +def backwards(apps, schema_editor): + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ("products", "0009_topicslughistory"), + ] + + operations = [move_kb_articles, backwards] + operations = [migrations.RunPython(move_kb_articles, backwards)]