<commit_before># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations
from temba.flows.models import RuleSet, Flow, ActionSet, TrueTest


def fix_like_named_destinations(apps, schema_editor):

    # must have a label
    updated_rules = RuleSet.objects.filter(label=None).update(label='Response A')
    if updated_rules:
        print "%d empty labels updated" % updated_rules

    updates = 0
    for flow in Flow.objects.all():

        for ruleset in RuleSet.objects.filter(flow=flow):
            actionsets = {actionset['uuid'] for actionset in ActionSet.objects.filter(flow=flow).values('uuid')}

            category_map = {}
            new_rules = []
            rules = ruleset.get_rules()
            for rule in rules:
                category_name = rule.get_category_name(flow.base_language)

                if not category_name:
                    continue

                category_name = category_name.lower()

                # prefer first valid destination for like named categories
                if rule.destination in actionsets and category_name not in category_map:
                    category_map[category_name] = rule.destination

            changed = False
            for rule in rules:

                category_name = rule.get_category_name(flow.base_language)

                if isinstance(rule.test, TrueTest):
                    continue

                if not category_name:
                    changed = True
                    print "[%s] - %d: (No Category) (%s)" % (flow.org.name, flow.pk, flow.modified_on)
                    continue

                if rule.destination and rule.destination not in actionsets:
                    print ("*" * 8) + " Fixing missing actionset " + ("*" * 8)
                    rule.destination = None
                    changed = True

                new_destination = None
                if category_name.lower() in category_map:
                    new_destination = category_map[category_name.lower()]

                if new_destination != rule.destination:

                    if new_destination is None:
                        print ("*" * 8)+ " WARNING, clearing destination " + ("*" * 8)

                    print "%s->%s [%s] - %d: %s" % (rule.destination, new_destination, flow.org.name, flow.pk, rule.get_category_name(flow.base_language))
                    changed = True
                    rule.destination = new_destination
                new_rules.append(rule)

            if changed:

                # update our ruleset
                ruleset.set_rules(new_rules)
                ruleset.save()

                try:
                    # make sure there's nothing cached when creating our new revision
                    flow = Flow.objects.get(pk=flow.pk)
                    flow.update(flow.as_json())
                except:
                    print "Skipping backup of broken flow [%d] - %s - %s" % (flow.pk, flow.org.name, flow.name)

                updates += 1

    if updates:
        print "Updated %d rulesets" % updates


class Migration(migrations.Migration):

    dependencies = [
        ('flows', '0011_auto_20150227_1823'),
    ]

    operations = [
        migrations.RunPython(fix_like_named_destinations)
    ]<commit_msg>fail the migration if we can't save our flow<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations
from temba.flows.models import RuleSet, Flow, ActionSet, TrueTest


def fix_like_named_destinations(apps, schema_editor):

    # must have a label
    updated_rules = RuleSet.objects.filter(label=None).update(label='Response A')
    if updated_rules:
        print "%d empty labels updated" % updated_rules

    updates = 0
    for flow in Flow.objects.all():

        for ruleset in RuleSet.objects.filter(flow=flow):
            actionsets = {actionset['uuid'] for actionset in ActionSet.objects.filter(flow=flow).values('uuid')}

            category_map = {}
            new_rules = []
            rules = ruleset.get_rules()
            for rule in rules:
                category_name = rule.get_category_name(flow.base_language)

                if not category_name:
                    continue

                category_name = category_name.lower()

                # prefer first valid destination for like named categories
                if rule.destination in actionsets and category_name not in category_map:
                    category_map[category_name] = rule.destination

            changed = False
            for rule in rules:

                category_name = rule.get_category_name(flow.base_language)

                if isinstance(rule.test, TrueTest):
                    continue

                if not category_name:
                    changed = True
                    print "[%s] - %d: (No Category) (%s)" % (flow.org.name, flow.pk, flow.modified_on)
                    continue

                if rule.destination and rule.destination not in actionsets:
                    print ("*" * 8) + " Fixing missing actionset " + ("*" * 8)
                    rule.destination = None
                    changed = True

                new_destination = None
                if category_name.lower() in category_map:
                    new_destination = category_map[category_name.lower()]

                if new_destination != rule.destination:

                    if new_destination is None:
                        print ("*" * 8)+ " WARNING, clearing destination " + ("*" * 8)

                    print "%s->%s [%s] - %d: %s" % (rule.destination, new_destination, flow.org.name, flow.pk, rule.get_category_name(flow.base_language))
                    changed = True
                    rule.destination = new_destination
                new_rules.append(rule)

            if changed:

                # update our ruleset
                ruleset.set_rules(new_rules)
                ruleset.save()

                # make sure there's nothing cached when creating our new revision
                flow = Flow.objects.get(pk=flow.pk)
                flow.update(flow.as_json())

                updates += 1

    if updates:
        print "Updated %d rulesets" % updates


class Migration(migrations.Migration):

    dependencies = [
        ('flows', '0011_auto_20150227_1823'),
    ]

    operations = [
        migrations.RunPython(fix_like_named_destinations)
    ]
{'fraction_non_alphanumeric': 0.08766233766233766, 'fraction_numerical': 0.007111935683364255, 'mean_word_length': 1.7157850545759865, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6339206', 'n_tokens_mistral': 1749, 'n_tokens_neox': 1600, 'n_words': 428}