From 7cf1cb73602096d2619543b9d10796a8edcef1a5 Mon Sep 17 00:00:00 2001 From: ldeluigi <44567586+ldeluigi@users.noreply.github.com> Date: Thu, 23 Mar 2023 16:12:50 +0100 Subject: [PATCH] Reset migrations --- backend/spellbook/migrations/0001_initial.py | 186 +++++++++++++++--- ..._state_alter_combo_description_and_more.py | 64 ------ ...card_identity_variant_identity_and_more.py | 29 --- ...plate_template_card_template_name_index.py | 33 ---- ...emplate_options_combo_requires_and_more.py | 27 --- .../0006_alter_template_scryfall_query.py | 19 -- .../0007_alter_template_scryfall_query.py | 19 -- ...emove_job_variants_variant_generated_by.py | 23 --- .../0009_alter_template_scryfall_query.py | 19 -- .../0010_card_legal_variant_legal.py | 23 --- ...te_remove_combo_zone_locations_and_more.py | 151 -------------- ...0012_alter_cardincombo_options_and_more.py | 45 ----- ...lter_cardincombo_zone_location_and_more.py | 33 ---- ...iant_templateinvariant_variant_and_more.py | 105 ---------- ...ler_variant_spoiler_alter_variant_legal.py | 29 --- .../migrations/0017_alter_job_message.py | 18 -- 16 files changed, 158 insertions(+), 665 deletions(-) delete mode 100644 backend/spellbook/migrations/0002_alter_combo_cards_state_alter_combo_description_and_more.py delete mode 100644 backend/spellbook/migrations/0003_card_identity_variant_identity_and_more.py delete mode 100644 backend/spellbook/migrations/0004_template_template_card_template_name_index.py delete mode 100644 backend/spellbook/migrations/0005_alter_template_options_combo_requires_and_more.py delete mode 100644 backend/spellbook/migrations/0006_alter_template_scryfall_query.py delete mode 100644 backend/spellbook/migrations/0007_alter_template_scryfall_query.py delete mode 100644 backend/spellbook/migrations/0008_remove_job_variants_variant_generated_by.py delete mode 100644 backend/spellbook/migrations/0009_alter_template_scryfall_query.py delete mode 100644 backend/spellbook/migrations/0010_card_legal_variant_legal.py delete mode 100644 backend/spellbook/migrations/0011_remove_combo_cards_state_remove_combo_zone_locations_and_more.py delete mode 100644 backend/spellbook/migrations/0012_alter_cardincombo_options_and_more.py delete mode 100644 backend/spellbook/migrations/0013_alter_cardincombo_zone_location_and_more.py delete mode 100644 backend/spellbook/migrations/0014_delete_variants_squashed_0015_cardinvariant_templateinvariant_variant_and_more.py delete mode 100644 backend/spellbook/migrations/0016_card_spoiler_variant_spoiler_alter_variant_legal.py delete mode 100644 backend/spellbook/migrations/0017_alter_job_message.py diff --git a/backend/spellbook/migrations/0001_initial.py b/backend/spellbook/migrations/0001_initial.py index 51f8bd7b..fc167a8f 100644 --- a/backend/spellbook/migrations/0001_initial.py +++ b/backend/spellbook/migrations/0001_initial.py @@ -1,10 +1,11 @@ -# Generated by Django 4.1 on 2022-09-29 09:05 +# Generated by Django 4.1.5 on 2023-03-23 15:12 from django.conf import settings import django.core.validators from django.db import migrations, models import django.db.models.deletion import sortedm2m.fields +import spellbook.models.mixins class Migration(migrations.Migration): @@ -22,6 +23,9 @@ class Migration(migrations.Migration): ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(help_text='Card name', max_length=255, unique=True, verbose_name='name of card')), ('oracle_id', models.UUIDField(blank=True, help_text='Scryfall Oracle ID', null=True, unique=True, verbose_name='Scryfall Oracle ID of card')), + ('identity', models.CharField(blank=True, help_text='Card mana identity', max_length=5, validators=[django.core.validators.RegexValidator(message='Can be any combination of zero or more letters in [W,U,B,R,G], in order.', regex='^W?U?B?R?G?$')], verbose_name='mana identity of card')), + ('legal', models.BooleanField(default=True, help_text='Is this card legal in Commander?', verbose_name='is legal')), + ('spoiler', models.BooleanField(default=False, help_text='Is this card from an upcoming set?', verbose_name='is spoiler')), ('added', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), ], @@ -30,16 +34,41 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'cards', 'ordering': ['name'], }, + bases=(models.Model, spellbook.models.mixins.ScryfallLinkMixin), + ), + migrations.CreateModel( + name='CardInCombo', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), + ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), + ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), + ], + options={ + 'ordering': ['order', 'id'], + 'abstract': False, + }, + ), + migrations.CreateModel( + name='CardInVariant', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), + ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), + ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), + ], + options={ + 'ordering': ['order', 'id'], + 'abstract': False, + }, ), migrations.CreateModel( name='Combo', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('zone_locations', models.TextField(blank=True, default='', help_text='Starting locations for cards.')), - ('cards_state', models.TextField(blank=True, default='', help_text='State of cards in their starting locations.')), - ('mana_needed', models.CharField(blank=True, default='', help_text='Mana needed for this combo. Use the {1}{W}{U}{B}{R}{G}{B/P}... format.', max_length=200, validators=[django.core.validators.RegexValidator(message='Mana needed must be in the {1}{W}{U}{B}{R}{G}{B/P}... format.', regex='^(\\{(?:[0-9WUBRGCXS]|[1-9][0-9]|([2WUBRG])(?:\\/(?!\\2)[WUBRG])?(?:\\/P)?)\\} *)*$')])), - ('other_prerequisites', models.TextField(blank=True, default='', help_text='Other prerequisites for this combo.')), - ('description', models.TextField(blank=True, help_text='Long description of the combo, in steps')), + ('mana_needed', models.CharField(blank=True, default='', help_text='Mana needed for this combo. Use the {1}{W}{U}{B}{R}{G}{B/P}... format.', max_length=200, validators=[django.core.validators.RegexValidator(message='Mana needed must be in the {1}{W}{U}{B}{R}{G}{B/P}... format.', regex='^(\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\} *)*$')])), + ('other_prerequisites', models.TextField(blank=True, default='', help_text='Other prerequisites for this combo.', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')])), + ('description', models.TextField(blank=True, help_text='Long description of the combo, in steps', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')])), ('generator', models.BooleanField(default=True, help_text='Is this combo a generator for variants?', verbose_name='is generator')), ('created', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), @@ -49,6 +78,7 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'combos', 'ordering': ['created'], }, + bases=(models.Model, spellbook.models.mixins.ScryfallLinkMixin), ), migrations.CreateModel( name='Feature', @@ -67,49 +97,108 @@ class Migration(migrations.Migration): }, ), migrations.CreateModel( - name='Variant', + name='Job', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='name of job')), + ('created', models.DateTimeField(auto_now_add=True)), + ('expected_termination', models.DateTimeField()), + ('termination', models.DateTimeField(blank=True, null=True)), + ('status', models.CharField(choices=[('S', 'Success'), ('F', 'Failure'), ('P', 'Pending')], default='P', max_length=2)), + ('message', models.TextField(blank=True, default='')), + ], + options={ + 'verbose_name': 'job', + 'verbose_name_plural': 'jobs', + 'ordering': ['-created', 'name'], + }, + ), + migrations.CreateModel( + name='Template', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(help_text='short description of the template in natural language', max_length=255, verbose_name='template name')), + ('scryfall_query', models.CharField(help_text='Variables supported: manavalue, mv, power, pow, toughness, tou, powtou, pt, loyalty, loy, color, c, identity, id, has, type, t, keyword, is, mana, m, devotion, produces. Operators supported: =, !=, <, >, <=, >=, :. You can compose a "and"/"or" expression made of "and"/"or" expressions, like "(c:W or c:U) and (t:creature or t:artifact)". You can also omit parentheses when not necessary, like "(c:W or c:U) t:creature". More info at: https://scryfall.com/docs/syntax.', max_length=255, validators=[django.core.validators.RegexValidator(message='Invalid Scryfall query syntax.', regex='^(?:(?:\\((?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)|(?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*))(?: (?:and |or )?(?:\\((?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)|(?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)))*)$')], verbose_name='Scryfall query')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'card template', + 'verbose_name_plural': 'templates', + 'ordering': ['name'], + }, + ), + migrations.CreateModel( + name='TemplateInVariant', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), + ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), + ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), + ('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.template')), + ], + options={ + 'ordering': ['order', 'id'], + 'abstract': False, + }, + ), + migrations.CreateModel( + name='Variant', + fields=[ + ('id', models.CharField(editable=False, help_text='Unique ID for this variant', max_length=128, primary_key=True, serialize=False, unique=True)), ('status', models.CharField(choices=[('N', 'New'), ('D', 'Draft'), ('NW', 'Not Working'), ('OK', 'Ok'), ('R', 'Restore')], default='N', help_text='Variant status for editors', max_length=2)), - ('zone_locations', models.TextField(blank=True, default='', help_text='Starting locations for cards.')), - ('cards_state', models.TextField(blank=True, default='', help_text='State of cards in their starting locations.')), - ('mana_needed', models.CharField(blank=True, default='', help_text='Mana needed for this combo. Use the {1}{W}{U}{B}{R}{G}{B/P}... format.', max_length=200, validators=[django.core.validators.RegexValidator(message='Mana needed must be in the {1}{W}{U}{B}{R}{G}{B/P}... format.', regex='^(\\{(?:[0-9WUBRGCXS]|[1-9][0-9]|([2WUBRG])(?:\\/(?!\\2)[WUBRG])?(?:\\/P)?)\\} *)*$')])), - ('other_prerequisites', models.TextField(blank=True, default='', help_text='Other prerequisites for this variant.')), - ('description', models.TextField(blank=True, help_text='Long description of the variant, in steps')), + ('mana_needed', models.CharField(blank=True, default='', help_text='Mana needed for this combo. Use the {1}{W}{U}{B}{R}{G}{B/P}... format.', max_length=200, validators=[django.core.validators.RegexValidator(message='Mana needed must be in the {1}{W}{U}{B}{R}{G}{B/P}... format.', regex='^(\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\} *)*$')])), + ('other_prerequisites', models.TextField(blank=True, default='', help_text='Other prerequisites for this variant.', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')])), + ('description', models.TextField(blank=True, help_text='Long description, in steps', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')])), ('created', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), - ('unique_id', models.CharField(editable=False, help_text='Unique ID for this variant', max_length=128, unique=True)), ('frozen', models.BooleanField(default=False, help_text='Is this variant undeletable?', verbose_name='is frozen')), + ('identity', models.CharField(blank=True, editable=False, help_text='Mana identity', max_length=5, validators=[django.core.validators.RegexValidator(message='Can be any combination of zero or more letters in [W,U,B,R,G], in order.', regex='^W?U?B?R?G?$')], verbose_name='mana identity')), + ('legal', models.BooleanField(help_text='Is this variant legal in Commander?', verbose_name='is legal')), + ('spoiler', models.BooleanField(help_text='Is this variant a spoiler?', verbose_name='is spoiler')), + ('generated_by', models.ForeignKey(blank=True, editable=False, help_text='Job that generated this variant', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='variants', to='spellbook.job')), ('includes', models.ManyToManyField(editable=False, help_text='Combo that this variant includes', related_name='included_in_variants', to='spellbook.combo')), ('of', models.ManyToManyField(editable=False, help_text='Combo that this variant is an instance of', related_name='variants', to='spellbook.combo')), ('produces', sortedm2m.fields.SortedManyToManyField(editable=False, help_text='Features that this variant produces', related_name='produced_by_variants', to='spellbook.feature')), - ('uses', sortedm2m.fields.SortedManyToManyField(editable=False, help_text='Cards that this variant uses', related_name='used_in_variants', to='spellbook.card')), + ('requires', models.ManyToManyField(blank=True, help_text='Templates that this variant requires', related_name='required_by_variants', through='spellbook.TemplateInVariant', to='spellbook.template', verbose_name='required templates')), + ('uses', models.ManyToManyField(editable=False, help_text='Cards that this variant uses', related_name='used_in_variants', through='spellbook.CardInVariant', to='spellbook.card')), ], options={ 'verbose_name': 'variant', 'verbose_name_plural': 'variants', 'ordering': ['-status', '-created'], }, + bases=(models.Model, spellbook.models.mixins.ScryfallLinkMixin), + ), + migrations.AddField( + model_name='templateinvariant', + name='variant', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.variant'), ), migrations.CreateModel( - name='Job', + name='TemplateInCombo', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255, verbose_name='name of job')), - ('created', models.DateTimeField(auto_now_add=True)), - ('expected_termination', models.DateTimeField()), - ('termination', models.DateTimeField(blank=True, null=True)), - ('status', models.CharField(choices=[('S', 'Success'), ('F', 'Failure'), ('P', 'Pending')], default='P', max_length=2)), - ('message', models.TextField(blank=True)), - ('started_by', models.ForeignKey(blank=True, help_text='User that started this job', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='started_jobs', to=settings.AUTH_USER_MODEL)), - ('variants', models.ManyToManyField(blank=True, editable=False, help_text='Variants that this job added or updated', related_name='jobs', to='spellbook.variant', verbose_name='variants updated')), + ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), + ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), + ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), + ('combo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.combo')), + ('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.template')), ], options={ - 'verbose_name': 'job', - 'verbose_name_plural': 'jobs', - 'ordering': ['-created', 'name'], + 'ordering': ['order', 'id'], + 'abstract': False, }, ), + migrations.AddIndex( + model_name='template', + index=models.Index(fields=['name'], name='card_template_name_index'), + ), + migrations.AddField( + model_name='job', + name='started_by', + field=models.ForeignKey(blank=True, help_text='User that started this job', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='started_jobs', to=settings.AUTH_USER_MODEL), + ), migrations.AddField( model_name='combo', name='needs', @@ -125,10 +214,35 @@ class Migration(migrations.Migration): name='removes', field=models.ManyToManyField(blank=True, help_text='Features that this combo removes', related_name='removed_by_combos', to='spellbook.feature', verbose_name='removed features'), ), + migrations.AddField( + model_name='combo', + name='requires', + field=models.ManyToManyField(blank=True, help_text='Templates that this combo requires', related_name='required_by_combos', through='spellbook.TemplateInCombo', to='spellbook.template', verbose_name='required templates'), + ), migrations.AddField( model_name='combo', name='uses', - field=models.ManyToManyField(blank=True, help_text='Cards that this combo uses', related_name='used_in_combos', to='spellbook.card', verbose_name='used cards'), + field=models.ManyToManyField(blank=True, help_text='Cards that this combo uses', related_name='used_in_combos', through='spellbook.CardInCombo', to='spellbook.card', verbose_name='used cards'), + ), + migrations.AddField( + model_name='cardinvariant', + name='card', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.card'), + ), + migrations.AddField( + model_name='cardinvariant', + name='variant', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.variant'), + ), + migrations.AddField( + model_name='cardincombo', + name='card', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.card'), + ), + migrations.AddField( + model_name='cardincombo', + name='combo', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.combo'), ), migrations.AddField( model_name='card', @@ -137,7 +251,15 @@ class Migration(migrations.Migration): ), migrations.AddIndex( model_name='variant', - index=models.Index(fields=['unique_id'], name='unique_variant_index'), + index=models.Index(fields=['id'], name='unique_variant_index'), + ), + migrations.AlterUniqueTogether( + name='templateinvariant', + unique_together={('template', 'variant')}, + ), + migrations.AlterUniqueTogether( + name='templateincombo', + unique_together={('template', 'combo')}, ), migrations.AddIndex( model_name='job', @@ -147,4 +269,12 @@ class Migration(migrations.Migration): model_name='job', constraint=models.CheckConstraint(check=models.Q(('expected_termination__gte', models.F('created'))), name='job_expected_termination_gte_created'), ), + migrations.AlterUniqueTogether( + name='cardinvariant', + unique_together={('card', 'variant')}, + ), + migrations.AlterUniqueTogether( + name='cardincombo', + unique_together={('card', 'combo')}, + ), ] diff --git a/backend/spellbook/migrations/0002_alter_combo_cards_state_alter_combo_description_and_more.py b/backend/spellbook/migrations/0002_alter_combo_cards_state_alter_combo_description_and_more.py deleted file mode 100644 index 5afeb537..00000000 --- a/backend/spellbook/migrations/0002_alter_combo_cards_state_alter_combo_description_and_more.py +++ /dev/null @@ -1,64 +0,0 @@ -# Generated by Django 4.1 on 2022-09-30 17:52 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='combo', - name='cards_state', - field=models.TextField(blank=True, default='', help_text='State of cards in their starting locations.', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting cards state'), - ), - migrations.AlterField( - model_name='combo', - name='description', - field=models.TextField(blank=True, help_text='Long description of the combo, in steps', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')]), - ), - migrations.AlterField( - model_name='combo', - name='mana_needed', - field=models.CharField(blank=True, default='', help_text='Mana needed for this combo. Use the {1}{W}{U}{B}{R}{G}{B/P}... format.', max_length=200, validators=[django.core.validators.RegexValidator(message='Mana needed must be in the {1}{W}{U}{B}{R}{G}{B/P}... format.', regex='^(\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\} *)*$')]), - ), - migrations.AlterField( - model_name='combo', - name='other_prerequisites', - field=models.TextField(blank=True, default='', help_text='Other prerequisites for this combo.', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')]), - ), - migrations.AlterField( - model_name='combo', - name='zone_locations', - field=models.TextField(blank=True, default='', help_text='Starting locations for cards.', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting locations'), - ), - migrations.AlterField( - model_name='variant', - name='cards_state', - field=models.TextField(blank=True, default='', help_text='State of cards in their starting locations.', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting cards state'), - ), - migrations.AlterField( - model_name='variant', - name='description', - field=models.TextField(blank=True, help_text='Long description of the variant, in steps', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')]), - ), - migrations.AlterField( - model_name='variant', - name='mana_needed', - field=models.CharField(blank=True, default='', help_text='Mana needed for this combo. Use the {1}{W}{U}{B}{R}{G}{B/P}... format.', max_length=200, validators=[django.core.validators.RegexValidator(message='Mana needed must be in the {1}{W}{U}{B}{R}{G}{B/P}... format.', regex='^(\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\} *)*$')]), - ), - migrations.AlterField( - model_name='variant', - name='other_prerequisites', - field=models.TextField(blank=True, default='', help_text='Other prerequisites for this variant.', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')]), - ), - migrations.AlterField( - model_name='variant', - name='zone_locations', - field=models.TextField(blank=True, default='', help_text='Starting locations for cards.', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting locations'), - ), - ] diff --git a/backend/spellbook/migrations/0003_card_identity_variant_identity_and_more.py b/backend/spellbook/migrations/0003_card_identity_variant_identity_and_more.py deleted file mode 100644 index 1889e955..00000000 --- a/backend/spellbook/migrations/0003_card_identity_variant_identity_and_more.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 4.1 on 2022-10-01 22:24 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0002_alter_combo_cards_state_alter_combo_description_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='card', - name='identity', - field=models.CharField(blank=True, help_text='Card mana identity', max_length=5, validators=[django.core.validators.RegexValidator(message='Can be any combination of zero or more letters in [W,U,B,R,G], in order.', regex='^W?U?B?R?G?$')], verbose_name='mana identity of card'), - ), - migrations.AddField( - model_name='variant', - name='identity', - field=models.CharField(blank=True, editable=False, help_text='Mana identity', max_length=5, validators=[django.core.validators.RegexValidator(message='Can be any combination of zero or more letters in [W,U,B,R,G], in order.', regex='^W?U?B?R?G?$')], verbose_name='mana identity'), - ), - migrations.AlterField( - model_name='variant', - name='description', - field=models.TextField(blank=True, help_text='Long description, in steps', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')]), - ), - ] diff --git a/backend/spellbook/migrations/0004_template_template_card_template_name_index.py b/backend/spellbook/migrations/0004_template_template_card_template_name_index.py deleted file mode 100644 index 2bcd0993..00000000 --- a/backend/spellbook/migrations/0004_template_template_card_template_name_index.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 4.1 on 2022-10-03 22:04 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0003_card_identity_variant_identity_and_more'), - ] - - operations = [ - migrations.CreateModel( - name='Template', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(help_text='short description of the template in natural language', max_length=255, verbose_name='template name')), - ('scryfall_query', models.CharField(help_text='Variables supported: mv, manavalue, power, pow, toughness, tou, pt, powtou, loyalty, loyalty, c, color, id, identity, has, t, type, keyword, is, m, mana, devotion, produces. Operators supported: =, !=, <, >, <=, >=, :. You can compose a "and" expression made of "or" expression, like "(c:W or c:U) and (t:creature or t:artifact)". You can also omit parentheses when not necessary, like "(c:W or c:U) t:creature". More info at https://scryfall.com/docs/syntax.', max_length=255, validators=[django.core.validators.RegexValidator(message='Invalid Scryfall query syntax.', regex='^(?:(?:(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!=]+|"[^"]")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: or (?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!=]+|"[^"]")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)|\\((?:(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!=]+|"[^"]")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: or (?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!=]+|"[^"]")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)(?: (?:and )(?:(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!=]+|"[^"]")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))|\\((?:(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!=]+|"[^"]")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: or (?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!=]+|"[^"]")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)))*)$')], verbose_name='Scryfall query')), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ], - options={ - 'verbose_name': 'card template', - 'verbose_name_plural': 'card templates', - 'ordering': ['name'], - }, - ), - migrations.AddIndex( - model_name='template', - index=models.Index(fields=['name'], name='card_template_name_index'), - ), - ] diff --git a/backend/spellbook/migrations/0005_alter_template_options_combo_requires_and_more.py b/backend/spellbook/migrations/0005_alter_template_options_combo_requires_and_more.py deleted file mode 100644 index fd940406..00000000 --- a/backend/spellbook/migrations/0005_alter_template_options_combo_requires_and_more.py +++ /dev/null @@ -1,27 +0,0 @@ -# Generated by Django 4.1 on 2022-10-03 23:35 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0004_template_template_card_template_name_index'), - ] - - operations = [ - migrations.AlterModelOptions( - name='template', - options={'ordering': ['name'], 'verbose_name': 'card template', 'verbose_name_plural': 'templates'}, - ), - migrations.AddField( - model_name='combo', - name='requires', - field=models.ManyToManyField(blank=True, help_text='Templates that this combo requires', related_name='required_by_combos', to='spellbook.template', verbose_name='required templates'), - ), - migrations.AddField( - model_name='variant', - name='requires', - field=models.ManyToManyField(blank=True, help_text='Templates that this variant requires', related_name='required_by_variants', to='spellbook.template', verbose_name='required templates'), - ), - ] diff --git a/backend/spellbook/migrations/0006_alter_template_scryfall_query.py b/backend/spellbook/migrations/0006_alter_template_scryfall_query.py deleted file mode 100644 index 760e8023..00000000 --- a/backend/spellbook/migrations/0006_alter_template_scryfall_query.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.1 on 2022-10-04 19:05 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0005_alter_template_options_combo_requires_and_more'), - ] - - operations = [ - migrations.AlterField( - model_name='template', - name='scryfall_query', - field=models.CharField(help_text='Variables supported: mv, manavalue, power, pow, toughness, tou, pt, powtou, loyalty, loyalty, c, color, id, identity, has, t, type, keyword, is, m, mana, devotion, produces. Operators supported: =, !=, <, >, <=, >=, :. You can compose a "and" expression made of "or" expression, like "(c:W or c:U) and (t:creature or t:artifact)". You can also omit parentheses when not necessary, like "(c:W or c:U) t:creature". More info at https://scryfall.com/docs/syntax.', max_length=255, validators=[django.core.validators.RegexValidator(message='Invalid Scryfall query syntax.', regex='^(?:(?:\\((?:(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)|(?:(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*))(?: (?:and |or )?(?:\\((?:(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)|(?:(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion|produces)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)))*)$')], verbose_name='Scryfall query'), - ), - ] diff --git a/backend/spellbook/migrations/0007_alter_template_scryfall_query.py b/backend/spellbook/migrations/0007_alter_template_scryfall_query.py deleted file mode 100644 index b1618151..00000000 --- a/backend/spellbook/migrations/0007_alter_template_scryfall_query.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.1 on 2022-10-05 23:49 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0006_alter_template_scryfall_query'), - ] - - operations = [ - migrations.AlterField( - model_name='template', - name='scryfall_query', - field=models.CharField(help_text='Variables supported: manavalue, mv, power, pow, toughness, tou, powtou, pt, loyalty, loy, color, c, identity, id, has, type, t, keyword, is, mana, m, devotion, produces. Operators supported: =, !=, <, >, <=, >=, :. You can compose a "and" expression made of "or" expression, like "(c:W or c:U) and (t:creature or t:artifact)". You can also omit parentheses when not necessary, like "(c:W or c:U) t:creature". More info at https://scryfall.com/docs/syntax.', max_length=255, validators=[django.core.validators.RegexValidator(message='Invalid Scryfall query syntax.', regex='^(?:(?:\\((?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)|(?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*))(?: (?:and |or )?(?:\\((?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)|(?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)))*)$')], verbose_name='Scryfall query'), - ), - ] diff --git a/backend/spellbook/migrations/0008_remove_job_variants_variant_generated_by.py b/backend/spellbook/migrations/0008_remove_job_variants_variant_generated_by.py deleted file mode 100644 index 7a9b1a03..00000000 --- a/backend/spellbook/migrations/0008_remove_job_variants_variant_generated_by.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 4.1.2 on 2022-11-27 11:00 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0007_alter_template_scryfall_query'), - ] - - operations = [ - migrations.RemoveField( - model_name='job', - name='variants', - ), - migrations.AddField( - model_name='variant', - name='generated_by', - field=models.ForeignKey(blank=True, editable=False, help_text='Job that generated this variant', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='variants', to='spellbook.job'), - ), - ] diff --git a/backend/spellbook/migrations/0009_alter_template_scryfall_query.py b/backend/spellbook/migrations/0009_alter_template_scryfall_query.py deleted file mode 100644 index 41666bf5..00000000 --- a/backend/spellbook/migrations/0009_alter_template_scryfall_query.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 4.1.3 on 2023-01-01 16:42 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0008_remove_job_variants_variant_generated_by'), - ] - - operations = [ - migrations.AlterField( - model_name='template', - name='scryfall_query', - field=models.CharField(help_text='Variables supported: manavalue, mv, power, pow, toughness, tou, powtou, pt, loyalty, loy, color, c, identity, id, has, type, t, keyword, is, mana, m, devotion, produces. Operators supported: =, !=, <, >, <=, >=, :. You can compose a "and"/"or" expression made of "and"/"or" expressions, like "(c:W or c:U) and (t:creature or t:artifact)". You can also omit parentheses when not necessary, like "(c:W or c:U) t:creature". More info at: https://scryfall.com/docs/syntax.', max_length=255, validators=[django.core.validators.RegexValidator(message='Invalid Scryfall query syntax.', regex='^(?:(?:\\((?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)|(?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*))(?: (?:and |or )?(?:\\((?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)\\)|(?:(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy))))(?: (?:and |or )?(?:-?(?:(?:(?:c|color|id|identity|produces)(?::|[<>]=?|!=|=)|(?:has|t|type|keyword|is):)(?:[^\\s:<>!="]+|"[^"]+")|(?:m|mana|devotion)(?::|[<>]=?|!=|=)(?:\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)(?::|[<>]=?|!=|=)(?:\\d+|(?:mv|manavalue|power|pow|toughness|tou|pt|powtou|loyalty|loy)))))*)))*)$')], verbose_name='Scryfall query'), - ), - ] diff --git a/backend/spellbook/migrations/0010_card_legal_variant_legal.py b/backend/spellbook/migrations/0010_card_legal_variant_legal.py deleted file mode 100644 index cff35a71..00000000 --- a/backend/spellbook/migrations/0010_card_legal_variant_legal.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 4.1.5 on 2023-02-07 16:37 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0009_alter_template_scryfall_query'), - ] - - operations = [ - migrations.AddField( - model_name='card', - name='legal', - field=models.BooleanField(default=True, help_text='Is this card legal in Commander?', verbose_name='is legal'), - ), - migrations.AddField( - model_name='variant', - name='legal', - field=models.BooleanField(default=True, help_text='Is this variant legal in Commander?', verbose_name='is legal'), - ), - ] diff --git a/backend/spellbook/migrations/0011_remove_combo_cards_state_remove_combo_zone_locations_and_more.py b/backend/spellbook/migrations/0011_remove_combo_cards_state_remove_combo_zone_locations_and_more.py deleted file mode 100644 index e704bb4d..00000000 --- a/backend/spellbook/migrations/0011_remove_combo_cards_state_remove_combo_zone_locations_and_more.py +++ /dev/null @@ -1,151 +0,0 @@ -# Generated by Django 4.1.5 on 2023-02-08 14:08 - -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion - - -def create_through_relation(apps, schema_editor): - Combo = apps.get_model('spellbook', 'Combo') - CardInCombo = apps.get_model('spellbook', 'CardInCombo') - TemplateInCombo = apps.get_model('spellbook', 'TemplateInCombo') - for combo in Combo.objects.all(): - for order, card in enumerate(combo.uses.all()): - CardInCombo(combo=combo, card=card, order=order).save() - for order, template in enumerate(combo.requires.all()): - TemplateInCombo(combo=combo, template=template, order=order).save() - Variant = apps.get_model('spellbook', 'Variant') - CardInVariant = apps.get_model('spellbook', 'CardInVariant') - TemplateInVariant = apps.get_model('spellbook', 'TemplateInVariant') - for variant in Variant.objects.all(): - for order, card in enumerate(variant.uses.all()): - CardInVariant(variant=variant, card=card, order=order).save() - for order, template in enumerate(variant.requires.all()): - TemplateInVariant(variant=variant, template=template, order=order).save() - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0010_card_legal_variant_legal'), - ] - - operations = [ - migrations.RemoveField( - model_name='combo', - name='cards_state', - ), - migrations.RemoveField( - model_name='combo', - name='zone_locations', - ), - migrations.RemoveField( - model_name='variant', - name='cards_state', - ), - migrations.RemoveField( - model_name='variant', - name='zone_locations', - ), - migrations.CreateModel( - name='TemplateInVariant', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), - ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), - ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), - ('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.template')), - ('variant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.variant')), - ], - options={ - 'ordering': ['order'], - 'abstract': False, - 'unique_together': {('template', 'variant'), ('order', 'variant')}, - }, - ), - migrations.CreateModel( - name='TemplateInCombo', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), - ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), - ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), - ('combo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.combo')), - ('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.template')), - ], - options={ - 'ordering': ['order'], - 'abstract': False, - 'unique_together': {('order', 'combo'), ('template', 'combo')}, - }, - ), - migrations.CreateModel( - name='CardInVariant', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), - ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), - ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), - ('card', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.card')), - ('variant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.variant')), - ], - options={ - 'ordering': ['order'], - 'abstract': False, - 'unique_together': {('card', 'variant'), ('order', 'variant')}, - }, - ), - migrations.CreateModel( - name='CardInCombo', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), - ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), - ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), - ('card', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.card')), - ('combo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.combo')), - ], - options={ - 'ordering': ['order'], - 'abstract': False, - 'unique_together': {('order', 'combo'), ('card', 'combo')}, - }, - ), - migrations.RunPython(create_through_relation, reverse_code=migrations.RunPython.noop), - migrations.RemoveField( - model_name='combo', - name='requires', - ), - migrations.RemoveField( - model_name='combo', - name='uses', - ), - migrations.RemoveField( - model_name='variant', - name='requires', - ), - migrations.RemoveField( - model_name='variant', - name='uses', - ), - migrations.AddField( - model_name='combo', - name='requires', - field=models.ManyToManyField(blank=True, help_text='Templates that this combo requires', related_name='required_by_combos', through='spellbook.TemplateInCombo', to='spellbook.template', verbose_name='required templates'), - ), - migrations.AddField( - model_name='combo', - name='uses', - field=models.ManyToManyField(blank=True, help_text='Cards that this combo uses', related_name='used_in_combos', through='spellbook.CardInCombo', to='spellbook.card', verbose_name='used cards'), - ), - migrations.AddField( - model_name='variant', - name='requires', - field=models.ManyToManyField(blank=True, help_text='Templates that this variant requires', related_name='required_by_variants', through='spellbook.TemplateInVariant', to='spellbook.template', verbose_name='required templates'), - ), - migrations.AddField( - model_name='variant', - name='uses', - field=models.ManyToManyField(editable=False, help_text='Cards that this variant uses', related_name='used_in_variants', through='spellbook.CardInVariant', to='spellbook.card'), - ), - ] diff --git a/backend/spellbook/migrations/0012_alter_cardincombo_options_and_more.py b/backend/spellbook/migrations/0012_alter_cardincombo_options_and_more.py deleted file mode 100644 index c62924d0..00000000 --- a/backend/spellbook/migrations/0012_alter_cardincombo_options_and_more.py +++ /dev/null @@ -1,45 +0,0 @@ -# Generated by Django 4.1.5 on 2023-02-10 15:45 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0011_remove_combo_cards_state_remove_combo_zone_locations_and_more'), - ] - - operations = [ - migrations.AlterModelOptions( - name='cardincombo', - options={'ordering': ['order', 'id']}, - ), - migrations.AlterModelOptions( - name='cardinvariant', - options={'ordering': ['order', 'id']}, - ), - migrations.AlterModelOptions( - name='templateincombo', - options={'ordering': ['order', 'id']}, - ), - migrations.AlterModelOptions( - name='templateinvariant', - options={'ordering': ['order', 'id']}, - ), - migrations.AlterUniqueTogether( - name='cardincombo', - unique_together={('card', 'combo')}, - ), - migrations.AlterUniqueTogether( - name='cardinvariant', - unique_together={('card', 'variant')}, - ), - migrations.AlterUniqueTogether( - name='templateincombo', - unique_together={('template', 'combo')}, - ), - migrations.AlterUniqueTogether( - name='templateinvariant', - unique_together={('template', 'variant')}, - ), - ] diff --git a/backend/spellbook/migrations/0013_alter_cardincombo_zone_location_and_more.py b/backend/spellbook/migrations/0013_alter_cardincombo_zone_location_and_more.py deleted file mode 100644 index b6448357..00000000 --- a/backend/spellbook/migrations/0013_alter_cardincombo_zone_location_and_more.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 4.1.5 on 2023-02-12 23:03 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0012_alter_cardincombo_options_and_more'), - ] - - operations = [ - migrations.AlterField( - model_name='cardincombo', - name='zone_location', - field=models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location'), - ), - migrations.AlterField( - model_name='cardinvariant', - name='zone_location', - field=models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location'), - ), - migrations.AlterField( - model_name='templateincombo', - name='zone_location', - field=models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location'), - ), - migrations.AlterField( - model_name='templateinvariant', - name='zone_location', - field=models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location'), - ), - ] diff --git a/backend/spellbook/migrations/0014_delete_variants_squashed_0015_cardinvariant_templateinvariant_variant_and_more.py b/backend/spellbook/migrations/0014_delete_variants_squashed_0015_cardinvariant_templateinvariant_variant_and_more.py deleted file mode 100644 index 8ea2e0c0..00000000 --- a/backend/spellbook/migrations/0014_delete_variants_squashed_0015_cardinvariant_templateinvariant_variant_and_more.py +++ /dev/null @@ -1,105 +0,0 @@ -# Generated by Django 4.1.5 on 2023-03-10 10:39 - -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion -import sortedm2m.fields -import spellbook.models - - -class Migration(migrations.Migration): - - replaces = [('spellbook', '0014_delete_variants'), ('spellbook', '0015_cardinvariant_templateinvariant_variant_and_more')] - - dependencies = [ - ('spellbook', '0013_alter_cardincombo_zone_location_and_more'), - ] - - operations = [ - migrations.DeleteModel( - name='CardInVariant', - ), - migrations.DeleteModel( - name='TemplateInVariant', - ), - migrations.DeleteModel( - name='Variant', - ), - migrations.CreateModel( - name='CardInVariant', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), - ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), - ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), - ('card', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.card')), - ], - options={ - 'ordering': ['order', 'id'], - 'abstract': False, - }, - ), - migrations.CreateModel( - name='TemplateInVariant', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('order', models.IntegerField(help_text='Order of the card in the combo.', verbose_name='order')), - ('zone_location', models.CharField(choices=[('H', 'Hand'), ('B', 'Battlefield'), ('C', 'Command Zone'), ('G', 'Graveyard'), ('L', 'Library'), ('E', 'Exile'), ('A', 'Any')], default='H', help_text='Starting location for the card.', max_length=2, verbose_name='starting location')), - ('card_state', models.CharField(blank=True, default='', help_text='State of the card in its starting location.', max_length=200, validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')], verbose_name='starting card state')), - ('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.template')), - ], - options={ - 'ordering': ['order', 'id'], - 'abstract': False, - }, - ), - migrations.CreateModel( - name='Variant', - fields=[ - ('id', models.CharField(editable=False, help_text='Unique ID for this variant', max_length=128, primary_key=True, serialize=False, unique=True)), - ('status', models.CharField(choices=[('N', 'New'), ('D', 'Draft'), ('NW', 'Not Working'), ('OK', 'Ok'), ('R', 'Restore')], default='N', help_text='Variant status for editors', max_length=2)), - ('mana_needed', models.CharField(blank=True, default='', help_text='Mana needed for this combo. Use the {1}{W}{U}{B}{R}{G}{B/P}... format.', max_length=200, validators=[django.core.validators.RegexValidator(message='Mana needed must be in the {1}{W}{U}{B}{R}{G}{B/P}... format.', regex='^(\\{(?:[0-9WUBRGCPXYZS∞]|[1-9][0-9]{1,2}|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\} *)*$')])), - ('other_prerequisites', models.TextField(blank=True, default='', help_text='Other prerequisites for this variant.', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')])), - ('description', models.TextField(blank=True, help_text='Long description, in steps', validators=[django.core.validators.RegexValidator(message='Unpaired double square brackets are not allowed.', regex='^(?:[^\\[]*(?:\\[(?!\\[)|\\[{2}[^\\[]+\\]{2}|\\[{3,}))*[^\\[]*$'), django.core.validators.RegexValidator(message='Symbols must be in the {1}{W}{U}{B}{R}{G}{B/P}{A}{E}{T}{Q}... format.', regex='^(?:[^\\{]*\\{(?:[0-9WUBRGCPXYZSTQEA½∞]|PW|CHAOS|TK|[1-9][0-9]{1,2}|H[WUBRG]|(?:2\\/[WUBRG]|W\\/U|W\\/B|B\\/R|B\\/G|U\\/B|U\\/R|R\\/G|R\\/W|G\\/W|G\\/U)(?:\\/P)?)\\})*[^\\{]*$')])), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('frozen', models.BooleanField(default=False, help_text='Is this variant undeletable?', verbose_name='is frozen')), - ('legal', models.BooleanField(default=True, help_text='Is this variant legal in Commander?', verbose_name='is legal')), - ('identity', models.CharField(blank=True, editable=False, help_text='Mana identity', max_length=5, validators=[django.core.validators.RegexValidator(message='Can be any combination of zero or more letters in [W,U,B,R,G], in order.', regex='^W?U?B?R?G?$')], verbose_name='mana identity')), - ('generated_by', models.ForeignKey(blank=True, editable=False, help_text='Job that generated this variant', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='variants', to='spellbook.job')), - ('includes', models.ManyToManyField(editable=False, help_text='Combo that this variant includes', related_name='included_in_variants', to='spellbook.combo')), - ('of', models.ManyToManyField(editable=False, help_text='Combo that this variant is an instance of', related_name='variants', to='spellbook.combo')), - ('produces', sortedm2m.fields.SortedManyToManyField(editable=False, help_text='Features that this variant produces', related_name='produced_by_variants', to='spellbook.feature')), - ('requires', models.ManyToManyField(blank=True, help_text='Templates that this variant requires', related_name='required_by_variants', through='spellbook.TemplateInVariant', to='spellbook.template', verbose_name='required templates')), - ('uses', models.ManyToManyField(editable=False, help_text='Cards that this variant uses', related_name='used_in_variants', through='spellbook.CardInVariant', to='spellbook.card')), - ], - options={ - 'verbose_name': 'variant', - 'verbose_name_plural': 'variants', - 'ordering': ['-status', '-created'], - }, - bases=(models.Model, spellbook.models.mixins.ScryfallLinkMixin), - ), - migrations.AddField( - model_name='templateinvariant', - name='variant', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.variant'), - ), - migrations.AddField( - model_name='cardinvariant', - name='variant', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spellbook.variant'), - ), - migrations.AddIndex( - model_name='variant', - index=models.Index(fields=['id'], name='unique_variant_index'), - ), - migrations.AlterUniqueTogether( - name='templateinvariant', - unique_together={('template', 'variant')}, - ), - migrations.AlterUniqueTogether( - name='cardinvariant', - unique_together={('card', 'variant')}, - ), - ] diff --git a/backend/spellbook/migrations/0016_card_spoiler_variant_spoiler_alter_variant_legal.py b/backend/spellbook/migrations/0016_card_spoiler_variant_spoiler_alter_variant_legal.py deleted file mode 100644 index 9f02dce2..00000000 --- a/backend/spellbook/migrations/0016_card_spoiler_variant_spoiler_alter_variant_legal.py +++ /dev/null @@ -1,29 +0,0 @@ -# Generated by Django 4.1.5 on 2023-03-15 20:33 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0014_delete_variants_squashed_0015_cardinvariant_templateinvariant_variant_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='card', - name='spoiler', - field=models.BooleanField(default=False, help_text='Is this card from an upcoming set?', verbose_name='is spoiler'), - ), - migrations.AddField( - model_name='variant', - name='spoiler', - field=models.BooleanField(default=False, help_text='Is this variant a spoiler?', verbose_name='is spoiler'), - preserve_default=False, - ), - migrations.AlterField( - model_name='variant', - name='legal', - field=models.BooleanField(help_text='Is this variant legal in Commander?', verbose_name='is legal'), - ), - ] diff --git a/backend/spellbook/migrations/0017_alter_job_message.py b/backend/spellbook/migrations/0017_alter_job_message.py deleted file mode 100644 index e54b4036..00000000 --- a/backend/spellbook/migrations/0017_alter_job_message.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.1.5 on 2023-03-16 19:05 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('spellbook', '0016_card_spoiler_variant_spoiler_alter_variant_legal'), - ] - - operations = [ - migrations.AlterField( - model_name='job', - name='message', - field=models.TextField(blank=True, default=''), - ), - ]