From b1c943fa4485ebb4a58a7940e92530cc3c07bfc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Hells=C3=A9n?= Date: Sun, 24 Dec 2023 18:54:15 +0100 Subject: [PATCH] Add models --- .../migrations/0001_initial.py | 767 ++++++++++++++++++ twitch_drop_notifier/models.py | 238 +++++- 2 files changed, 1004 insertions(+), 1 deletion(-) create mode 100644 twitch_drop_notifier/migrations/0001_initial.py diff --git a/twitch_drop_notifier/migrations/0001_initial.py b/twitch_drop_notifier/migrations/0001_initial.py new file mode 100644 index 0000000..6f8c9d1 --- /dev/null +++ b/twitch_drop_notifier/migrations/0001_initial.py @@ -0,0 +1,767 @@ +# Generated by Django 5.0 on 2023-12-24 17:53 + +import django.db.models.deletion +import simple_history.models +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="Game", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "game_id", + models.TextField( + help_text="The ID of the game.", + verbose_name="Game ID", + ), + ), + ( + "display_name", + models.TextField( + help_text="The display name of the game.", + verbose_name="Game Name", + ), + ), + ( + "slug", + models.TextField( + help_text="The slug of the game.", + verbose_name="Game Slug", + ), + ), + ("image", models.ImageField(blank=True, upload_to="images/")), + ("model_created", models.DateTimeField(auto_now_add=True)), + ("model_updated", models.DateTimeField(auto_now=True)), + ], + options={ + "verbose_name": "Game", + "db_table": "game", + "db_table_comment": "A game.", + "ordering": ["display_name"], + }, + ), + migrations.CreateModel( + name="Owner", + fields=[ + ( + "owner_id", + models.UUIDField( + editable=False, + help_text="The ID of the owner.", + primary_key=True, + serialize=False, + verbose_name="Owner ID", + ), + ), + ( + "name", + models.TextField( + help_text="The name of the owner.", + verbose_name="Developer Name", + ), + ), + ("image", models.ImageField(blank=True, upload_to="images/")), + ("model_created", models.DateTimeField(auto_now_add=True)), + ("model_updated", models.DateTimeField(auto_now=True)), + ], + options={ + "verbose_name": "Owner", + "db_table": "owner", + "db_table_comment": "An owner.", + "ordering": ["name"], + }, + ), + migrations.CreateModel( + name="Reward", + fields=[ + ( + "reward_id", + models.UUIDField( + editable=False, + help_text="The ID of the reward.", + primary_key=True, + serialize=False, + verbose_name="Reward ID", + ), + ), + ( + "name", + models.TextField( + help_text="The name of the reward.", + verbose_name="Reward Name", + ), + ), + ( + "required_minutes_watched", + models.IntegerField( + help_text="The required minutes watched to earn the reward.", + verbose_name="Required Minutes Watched", + ), + ), + ( + "is_available_on_ios", + models.BooleanField( + default=False, + help_text="If the reward is available on iOS.", + verbose_name="Available on iOS", + ), + ), + ("image", models.ImageField(blank=True, upload_to="images/")), + ( + "start_at", + models.DateTimeField( + help_text="The date and time the reward starts.", + verbose_name="Start At", + ), + ), + ( + "end_at", + models.DateTimeField( + help_text="The date and time the reward ends.", + verbose_name="End At", + ), + ), + ( + "created", + models.DateTimeField( + help_text="The date and time the reward was model_created. From Twitch JSON.", + ), + ), + ( + "model_created", + models.DateTimeField( + auto_now_add=True, + help_text="The date and time the reward was model_created in the database.", + ), + ), + ("model_model_updated", models.DateTimeField(auto_now=True)), + ], + options={ + "verbose_name": "Reward", + "db_table": "reward", + "db_table_comment": "A reward.", + "ordering": ["name"], + }, + ), + migrations.CreateModel( + name="TwitchChannel", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.TextField( + help_text="The name of the Twitch channel.", + verbose_name="Twitch Channel Name", + ), + ), + ("image", models.ImageField(blank=True, upload_to="images/")), + ("is_live", models.BooleanField(default=False)), + ("model_created", models.DateTimeField(auto_now_add=True)), + ("model_updated", models.DateTimeField(auto_now=True)), + ], + options={ + "verbose_name": "Twitch Channel", + "db_table": "twitch_channel", + "db_table_comment": "A Twitch channel.", + "ordering": ["name"], + }, + ), + migrations.CreateModel( + name="HistoricalGame", + fields=[ + ( + "id", + models.BigIntegerField( + auto_created=True, + blank=True, + db_index=True, + verbose_name="ID", + ), + ), + ( + "game_id", + models.TextField( + help_text="The ID of the game.", + verbose_name="Game ID", + ), + ), + ( + "display_name", + models.TextField( + help_text="The display name of the game.", + verbose_name="Game Name", + ), + ), + ( + "slug", + models.TextField( + help_text="The slug of the game.", + verbose_name="Game Slug", + ), + ), + ("image", models.TextField(blank=True, max_length=100)), + ("history_id", models.AutoField(primary_key=True, serialize=False)), + ("history_date", models.DateTimeField(db_index=True)), + ("history_change_reason", models.CharField(max_length=100, null=True)), + ( + "history_type", + models.CharField( + choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], + max_length=1, + ), + ), + ( + "history_user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name": "historical Game", + "verbose_name_plural": "historical Games", + "db_table": "game_history", + "ordering": ("-history_date", "-history_id"), + "get_latest_by": ("history_date", "history_id"), + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + migrations.CreateModel( + name="HistoricalOwner", + fields=[ + ( + "owner_id", + models.UUIDField( + db_index=True, + editable=False, + help_text="The ID of the owner.", + verbose_name="Owner ID", + ), + ), + ( + "name", + models.TextField( + help_text="The name of the owner.", + verbose_name="Developer Name", + ), + ), + ("image", models.TextField(blank=True, max_length=100)), + ("history_id", models.AutoField(primary_key=True, serialize=False)), + ("history_date", models.DateTimeField(db_index=True)), + ("history_change_reason", models.CharField(max_length=100, null=True)), + ( + "history_type", + models.CharField( + choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], + max_length=1, + ), + ), + ( + "history_user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name": "historical Owner", + "verbose_name_plural": "historical Owners", + "db_table": "owner_history", + "ordering": ("-history_date", "-history_id"), + "get_latest_by": ("history_date", "history_id"), + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + migrations.CreateModel( + name="HistoricalReward", + fields=[ + ( + "reward_id", + models.UUIDField( + db_index=True, + editable=False, + help_text="The ID of the reward.", + verbose_name="Reward ID", + ), + ), + ( + "name", + models.TextField( + help_text="The name of the reward.", + verbose_name="Reward Name", + ), + ), + ( + "required_minutes_watched", + models.IntegerField( + help_text="The required minutes watched to earn the reward.", + verbose_name="Required Minutes Watched", + ), + ), + ( + "is_available_on_ios", + models.BooleanField( + default=False, + help_text="If the reward is available on iOS.", + verbose_name="Available on iOS", + ), + ), + ("image", models.TextField(blank=True, max_length=100)), + ( + "start_at", + models.DateTimeField( + help_text="The date and time the reward starts.", + verbose_name="Start At", + ), + ), + ( + "end_at", + models.DateTimeField( + help_text="The date and time the reward ends.", + verbose_name="End At", + ), + ), + ( + "created", + models.DateTimeField( + help_text="The date and time the reward was model_created. From Twitch JSON.", + ), + ), + ( + "model_created", + models.DateTimeField( + blank=True, + editable=False, + help_text="The date and time the reward was model_created in the database.", + ), + ), + ( + "model_model_updated", + models.DateTimeField(blank=True, editable=False), + ), + ("history_id", models.AutoField(primary_key=True, serialize=False)), + ("history_date", models.DateTimeField(db_index=True)), + ("history_change_reason", models.CharField(max_length=100, null=True)), + ( + "history_type", + models.CharField( + choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], + max_length=1, + ), + ), + ( + "history_user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name": "historical Reward", + "verbose_name_plural": "historical Rewards", + "db_table": "reward_history", + "ordering": ("-history_date", "-history_id"), + "get_latest_by": ("history_date", "history_id"), + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + migrations.CreateModel( + name="HistoricalTwitchChannel", + fields=[ + ( + "id", + models.BigIntegerField( + auto_created=True, + blank=True, + db_index=True, + verbose_name="ID", + ), + ), + ( + "name", + models.TextField( + help_text="The name of the Twitch channel.", + verbose_name="Twitch Channel Name", + ), + ), + ("image", models.TextField(blank=True, max_length=100)), + ("is_live", models.BooleanField(default=False)), + ("history_id", models.AutoField(primary_key=True, serialize=False)), + ("history_date", models.DateTimeField(db_index=True)), + ("history_change_reason", models.CharField(max_length=100, null=True)), + ( + "history_type", + models.CharField( + choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], + max_length=1, + ), + ), + ( + "history_user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name": "historical Twitch Channel", + "verbose_name_plural": "historical Twitch Channels", + "db_table": "twitch_channel_history", + "ordering": ("-history_date", "-history_id"), + "get_latest_by": ("history_date", "history_id"), + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + migrations.CreateModel( + name="HistoricalTwitchDrop", + fields=[ + ( + "id", + models.BigIntegerField( + auto_created=True, + blank=True, + db_index=True, + verbose_name="ID", + ), + ), + ( + "drop_id", + models.TextField( + help_text="The ID of the drop.", + verbose_name="Drop ID", + ), + ), + ( + "name", + models.TextField( + help_text="The name of the drop.", + verbose_name="Drop Name", + ), + ), + ( + "description", + models.TextField( + help_text="The description of the drop.", + verbose_name="Description", + ), + ), + ( + "details_url", + models.URLField( + help_text="The URL to the drop details.", + verbose_name="Details URL", + ), + ), + ( + "how_to_earn", + models.TextField( + help_text="How to earn the drop.", + verbose_name="How to Earn", + ), + ), + ("image", models.TextField(blank=True, max_length=100)), + ( + "start_date", + models.DateTimeField( + help_text="The date and time the drop starts.", + verbose_name="Start Date", + ), + ), + ( + "end_date", + models.DateTimeField( + help_text="The date and time the drop ends.", + verbose_name="End Date", + ), + ), + ( + "is_event_based", + models.BooleanField( + default=False, + help_text="If the drop is event based.", + verbose_name="Event Based", + ), + ), + ( + "is_time_based", + models.BooleanField( + default=False, + help_text="If the drop is time based.", + verbose_name="Time Based", + ), + ), + ( + "account_link_url", + models.URLField( + help_text="The URL to link the Twitch account.", + verbose_name="Connection", + ), + ), + ( + "participating_channels", + models.URLField( + help_text="The URL to the Twitch stream.", + verbose_name="Participating Channels", + ), + ), + ( + "status", + models.BooleanField( + default=False, + help_text="If the drop is active.", + verbose_name="Status", + ), + ), + ("history_id", models.AutoField(primary_key=True, serialize=False)), + ("history_date", models.DateTimeField(db_index=True)), + ("history_change_reason", models.CharField(max_length=100, null=True)), + ( + "history_type", + models.CharField( + choices=[("+", "Created"), ("~", "Changed"), ("-", "Deleted")], + max_length=1, + ), + ), + ( + "game", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="twitch_drop_notifier.game", + verbose_name="Game", + ), + ), + ( + "history_user", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "developer", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="twitch_drop_notifier.owner", + verbose_name="Developer", + ), + ), + ( + "reward", + models.ForeignKey( + blank=True, + db_constraint=False, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + related_name="+", + to="twitch_drop_notifier.reward", + verbose_name="Reward", + ), + ), + ], + options={ + "verbose_name": "historical Twitch Drop", + "verbose_name_plural": "historical Twitch Drops", + "db_table": "twitch_drop_history", + "ordering": ("-history_date", "-history_id"), + "get_latest_by": ("history_date", "history_id"), + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + migrations.CreateModel( + name="TwitchDrop", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "drop_id", + models.TextField( + help_text="The ID of the drop.", + verbose_name="Drop ID", + ), + ), + ( + "name", + models.TextField( + help_text="The name of the drop.", + verbose_name="Drop Name", + ), + ), + ( + "description", + models.TextField( + help_text="The description of the drop.", + verbose_name="Description", + ), + ), + ( + "details_url", + models.URLField( + help_text="The URL to the drop details.", + verbose_name="Details URL", + ), + ), + ( + "how_to_earn", + models.TextField( + help_text="How to earn the drop.", + verbose_name="How to Earn", + ), + ), + ("image", models.ImageField(blank=True, upload_to="images/")), + ( + "start_date", + models.DateTimeField( + help_text="The date and time the drop starts.", + verbose_name="Start Date", + ), + ), + ( + "end_date", + models.DateTimeField( + help_text="The date and time the drop ends.", + verbose_name="End Date", + ), + ), + ( + "is_event_based", + models.BooleanField( + default=False, + help_text="If the drop is event based.", + verbose_name="Event Based", + ), + ), + ( + "is_time_based", + models.BooleanField( + default=False, + help_text="If the drop is time based.", + verbose_name="Time Based", + ), + ), + ( + "account_link_url", + models.URLField( + help_text="The URL to link the Twitch account.", + verbose_name="Connection", + ), + ), + ( + "participating_channels", + models.URLField( + help_text="The URL to the Twitch stream.", + verbose_name="Participating Channels", + ), + ), + ( + "status", + models.BooleanField( + default=False, + help_text="If the drop is active.", + verbose_name="Status", + ), + ), + ( + "model_created", + models.DateTimeField( + auto_now_add=True, + help_text="The date and time the drop was model_created.", + ), + ), + ( + "model_updated", + models.DateTimeField( + auto_now=True, + help_text="The date and time the drop was last model_updated.", + ), + ), + ( + "developer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="twitch_drops", + to="twitch_drop_notifier.owner", + verbose_name="Developer", + ), + ), + ( + "game", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="twitch_drops", + to="twitch_drop_notifier.game", + verbose_name="Game", + ), + ), + ( + "reward", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="twitch_drops", + to="twitch_drop_notifier.reward", + verbose_name="Reward", + ), + ), + ], + options={ + "verbose_name": "Twitch Drop", + "db_table": "twitch_drop", + "db_table_comment": "A Twitch Drop.", + "ordering": ["name"], + }, + ), + ] diff --git a/twitch_drop_notifier/models.py b/twitch_drop_notifier/models.py index 6b20219..0bff4c4 100644 --- a/twitch_drop_notifier/models.py +++ b/twitch_drop_notifier/models.py @@ -1 +1,237 @@ -# Create your models here. +from django.db import models +from simple_history.models import HistoricalRecords + + +class Owner(models.Model): + owner_id = models.UUIDField( + primary_key=True, + help_text="The ID of the owner.", + verbose_name="Owner ID", + editable=False, + ) + name = models.TextField( + help_text="The name of the owner.", + verbose_name="Developer Name", + ) + image = models.ImageField(upload_to="images/", blank=True) + model_created = models.DateTimeField(auto_now_add=True) + model_updated = models.DateTimeField(auto_now=True) + history = HistoricalRecords( + table_name="owner_history", + excluded_fields=["model_created", "model_updated"], + ) + + class Meta: + ordering: list[str] = ["name"] + verbose_name: str = "Owner" + db_table: str = "owner" + db_table_comment: str = "An owner." + + def __str__(self) -> str: + return self.name + + +class Game(models.Model): + # TODO: Maybe int? + game_id = models.TextField( + help_text="The ID of the game.", + verbose_name="Game ID", + ) + display_name = models.TextField( + help_text="The display name of the game.", + verbose_name="Game Name", + ) + slug = models.TextField( + help_text="The slug of the game.", + verbose_name="Game Slug", + ) + image = models.ImageField(upload_to="images/", blank=True) + model_created = models.DateTimeField(auto_now_add=True) + model_updated = models.DateTimeField(auto_now=True) + history = HistoricalRecords( + table_name="game_history", + excluded_fields=["model_created", "model_updated"], + ) + + class Meta: + ordering: list[str] = ["display_name"] + verbose_name: str = "Game" + db_table: str = "game" + db_table_comment: str = "A game." + + def __str__(self) -> str: + return f"{self.display_name} (www.twitch.tv/directory/category/{self.slug})" + + +class Reward(models.Model): + reward_id = models.UUIDField( + primary_key=True, + help_text="The ID of the reward.", + verbose_name="Reward ID", + editable=False, + ) + name = models.TextField( + help_text="The name of the reward.", + verbose_name="Reward Name", + ) + required_minutes_watched = models.IntegerField( + help_text="The required minutes watched to earn the reward.", + verbose_name="Required Minutes Watched", + ) + is_available_on_ios = models.BooleanField( + default=False, + help_text="If the reward is available on iOS.", + verbose_name="Available on iOS", + ) + image = models.ImageField(upload_to="images/", blank=True) + start_at = models.DateTimeField( + help_text="The date and time the reward starts.", + verbose_name="Start At", + ) + end_at = models.DateTimeField( + help_text="The date and time the reward ends.", + verbose_name="End At", + ) + created = models.DateTimeField( + help_text="The date and time the reward was model_created. From Twitch JSON.", + ) + + model_created = models.DateTimeField( + auto_now_add=True, + help_text="The date and time the reward was model_created in the database.", + ) + model_model_updated = models.DateTimeField(auto_now=True) + history = HistoricalRecords( + table_name="reward_history", + excluded_fields=["model_model_created", "model_updated"], + ) + + class Meta: + ordering: list[str] = ["name"] + verbose_name: str = "Reward" + db_table: str = "reward" + db_table_comment: str = "A reward." + + def __str__(self) -> str: + return self.name + + +class TwitchChannel(models.Model): + name = models.TextField( + help_text="The name of the Twitch channel.", + verbose_name="Twitch Channel Name", + ) + image = models.ImageField(upload_to="images/", blank=True) + is_live = models.BooleanField(default=False) + model_created = models.DateTimeField(auto_now_add=True) + model_updated = models.DateTimeField(auto_now=True) + history = HistoricalRecords( + table_name="twitch_channel_history", + excluded_fields=["model_created", "model_updated"], + ) + + class Meta: + ordering: list[str] = ["name"] + verbose_name: str = "Twitch Channel" + db_table: str = "twitch_channel" + db_table_comment: str = "A Twitch channel." + + def __str__(self) -> str: + return self.name + + +class TwitchDrop(models.Model): + drop_id = models.TextField( + help_text="The ID of the drop.", + verbose_name="Drop ID", + ) + name = models.TextField( + help_text="The name of the drop.", + verbose_name="Drop Name", + ) + description = models.TextField( + help_text="The description of the drop.", + verbose_name="Description", + ) + details_url = models.URLField( + help_text="The URL to the drop details.", + verbose_name="Details URL", + ) + how_to_earn = models.TextField( + help_text="How to earn the drop.", + verbose_name="How to Earn", + ) + image = models.ImageField(upload_to="images/", blank=True) + start_date = models.DateTimeField( + help_text="The date and time the drop starts.", + verbose_name="Start Date", + ) + end_date = models.DateTimeField( + help_text="The date and time the drop ends.", + verbose_name="End Date", + ) + is_event_based = models.BooleanField( + default=False, + help_text="If the drop is event based.", + verbose_name="Event Based", + ) + is_time_based = models.BooleanField( + default=False, + help_text="If the drop is time based.", + verbose_name="Time Based", + ) + reward = models.ForeignKey( + Reward, + on_delete=models.CASCADE, + related_name="twitch_drops", + verbose_name="Reward", + ) + account_link_url = models.URLField( + help_text="The URL to link the Twitch account.", + verbose_name="Connection", + ) + participating_channels = models.URLField( + help_text="The URL to the Twitch stream.", + verbose_name="Participating Channels", + ) + status = models.BooleanField( + default=False, + help_text="If the drop is active.", + verbose_name="Status", + ) + + model_created = models.DateTimeField( + auto_now_add=True, + editable=False, + help_text="The date and time the drop was model_created.", + ) + model_updated = models.DateTimeField( + auto_now=True, + help_text="The date and time the drop was last model_updated.", + ) + history = HistoricalRecords( + table_name="twitch_drop_history", + excluded_fields=["model_created", "model_updated"], + ) + + game = models.ForeignKey( + Game, + on_delete=models.CASCADE, + related_name="twitch_drops", + verbose_name="Game", + ) + developer = models.ForeignKey( + Owner, + on_delete=models.CASCADE, + related_name="twitch_drops", + verbose_name="Developer", + ) + + class Meta: + ordering: list[str] = ["name"] + verbose_name: str = "Twitch Drop" + db_table: str = "twitch_drop" + db_table_comment: str = "A Twitch Drop." + + def __str__(self) -> str: + return f"{self.name} ({self.game.display_name})"