feat: Add Twitch Drops Tracker application with campaign management
- Implemented models for DropCampaign, Game, Organization, DropBenefit, TimeBasedDrop, and DropBenefitEdge. - Created views for listing and detailing drop campaigns. - Added templates for dashboard, campaign list, and campaign detail. - Developed management command to import drop campaigns from JSON files. - Configured admin interface for managing campaigns and related models. - Updated URL routing for the application. - Enhanced README with installation instructions and project structure.
This commit is contained in:
parent
0c7c1c3f30
commit
5c482c1729
15 changed files with 1145 additions and 10 deletions
101
twitch/migrations/0001_initial.py
Normal file
101
twitch/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# Generated by Django 5.2.4 on 2025-07-09 20:44
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DropBenefit',
|
||||
fields=[
|
||||
('id', models.TextField(primary_key=True, serialize=False)),
|
||||
('name', models.TextField()),
|
||||
('image_asset_url', models.URLField(blank=True, default='', max_length=500)),
|
||||
('created_at', models.DateTimeField()),
|
||||
('entitlement_limit', models.PositiveIntegerField(default=1)),
|
||||
('is_ios_available', models.BooleanField(default=False)),
|
||||
('distribution_type', models.TextField(choices=[('DIRECT_ENTITLEMENT', 'Direct Entitlement'), ('CODE', 'Code')])),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Game',
|
||||
fields=[
|
||||
('id', models.TextField(primary_key=True, serialize=False)),
|
||||
('slug', models.TextField(blank=True, default='')),
|
||||
('display_name', models.TextField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Organization',
|
||||
fields=[
|
||||
('id', models.TextField(primary_key=True, serialize=False)),
|
||||
('name', models.TextField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DropBenefitEdge',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('entitlement_limit', models.PositiveIntegerField(default=1)),
|
||||
('benefit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='twitch.dropbenefit')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dropbenefit',
|
||||
name='game',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drop_benefits', to='twitch.game'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DropCampaign',
|
||||
fields=[
|
||||
('id', models.TextField(primary_key=True, serialize=False)),
|
||||
('name', models.TextField()),
|
||||
('description', models.TextField(blank=True)),
|
||||
('details_url', models.URLField(blank=True, default='', max_length=500)),
|
||||
('account_link_url', models.URLField(blank=True, default='', max_length=500)),
|
||||
('image_url', models.URLField(blank=True, default='', max_length=500)),
|
||||
('start_at', models.DateTimeField()),
|
||||
('end_at', models.DateTimeField()),
|
||||
('status', models.TextField(choices=[('ACTIVE', 'Active'), ('UPCOMING', 'Upcoming'), ('EXPIRED', 'Expired')])),
|
||||
('is_account_connected', models.BooleanField(default=False)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('game', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drop_campaigns', to='twitch.game')),
|
||||
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drop_campaigns', to='twitch.organization')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dropbenefit',
|
||||
name='owner_organization',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='drop_benefits', to='twitch.organization'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TimeBasedDrop',
|
||||
fields=[
|
||||
('id', models.TextField(primary_key=True, serialize=False)),
|
||||
('name', models.TextField()),
|
||||
('required_minutes_watched', models.PositiveIntegerField()),
|
||||
('required_subs', models.PositiveIntegerField(default=0)),
|
||||
('start_at', models.DateTimeField()),
|
||||
('end_at', models.DateTimeField()),
|
||||
('benefits', models.ManyToManyField(related_name='drops', through='twitch.DropBenefitEdge', to='twitch.dropbenefit')),
|
||||
('campaign', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='time_based_drops', to='twitch.dropcampaign')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dropbenefitedge',
|
||||
name='drop',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='twitch.timebaseddrop'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='dropbenefitedge',
|
||||
unique_together={('drop', 'benefit')},
|
||||
),
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue