From 36517504f36b4c20409ba5cfc5f3f80c8db67c96 Mon Sep 17 00:00:00 2001 From: Krrish Sehgal <133865424+krrish-sehgal@users.noreply.github.com> Date: Sun, 1 Dec 2024 21:55:58 +0530 Subject: [PATCH] Automated site specific badges (#3026) * initial * pre-commit fix * auto * user auth --- website/migrations/0161_alter_badge_icon.py | 17 +++++++ website/migrations/0162_add_new_badges.py | 52 +++++++++++++++++++++ website/signals.py | 40 ++++++++++++++-- 3 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 website/migrations/0161_alter_badge_icon.py create mode 100644 website/migrations/0162_add_new_badges.py diff --git a/website/migrations/0161_alter_badge_icon.py b/website/migrations/0161_alter_badge_icon.py new file mode 100644 index 000000000..92d93f702 --- /dev/null +++ b/website/migrations/0161_alter_badge_icon.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.3 on 2024-11-30 14:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("website", "0160_merge_20241129_0712"), + ] + + operations = [ + migrations.AlterField( + model_name="badge", + name="icon", + field=models.ImageField(blank=True, null=True, upload_to="badges/"), + ), + ] diff --git a/website/migrations/0162_add_new_badges.py b/website/migrations/0162_add_new_badges.py new file mode 100644 index 000000000..1247b30ee --- /dev/null +++ b/website/migrations/0162_add_new_badges.py @@ -0,0 +1,52 @@ +# Generated by Django 5.1.3 on 2024-11-30 14:15 + +from django.db import migrations + + +def add_new_badges(apps, schema_editor): + # Get the Badge model + Badge = apps.get_model("website", "Badge") + + # Define the new badges to add + new_badges = [ + { + "title": "First IP Reported", + "description": "Awarded for reporting the first intellectual property.", + "type": "automatic", + }, + { + "title": "First Bid Placed", + "description": "Awarded for placing the first bid.", + "type": "automatic", + }, + { + "title": "First Bug Bounty", + "description": "Awarded for earning the first bug bounty.", + "type": "automatic", + }, + { + "title": "First Suggestion", + "description": "Awarded for making the first suggestion.", + "type": "automatic", + }, + ] + + # Loop through the new badges and create them if they don't already exist + for badge in new_badges: + Badge.objects.get_or_create( + title=badge["title"], + defaults={ + "description": badge["description"], + "type": badge["type"], + }, + ) + + +class Migration(migrations.Migration): + dependencies = [ + ("website", "0161_alter_badge_icon"), # Adjust based on your actual previous migration + ] + + operations = [ + migrations.RunPython(add_new_badges), + ] diff --git a/website/signals.py b/website/signals.py index b397987c6..5c4528b46 100644 --- a/website/signals.py +++ b/website/signals.py @@ -5,7 +5,7 @@ from blog.models import Post -from .models import Activity, Hunt, IpReport, Issue +from .models import Activity, Badge, Bid, Hunt, IpReport, Issue, Suggestion, UserBadge def get_default_user(): @@ -13,6 +13,17 @@ def get_default_user(): return User.objects.get_or_create(username="anonymous")[0] +# Helper function to assign the badge based on action +def assign_first_action_badge(user, action_title): + """Assign badges for first-time actions.""" + if user is not None and user.is_authenticated: + badge, created = Badge.objects.get_or_create(title=action_title, type="automatic") + + if not UserBadge.objects.filter(user=user, badge=badge).exists(): + UserBadge.objects.get_or_create(user=user, badge=badge) + print(f"Assigned '{action_title}' badge to {user.username}") + + def create_activity(instance, action_type): """Generic function to create an activity for a given model instance.""" model_name = instance._meta.model_name @@ -41,9 +52,30 @@ def create_activity(instance, action_type): @receiver(post_save) def handle_post_save(sender, instance, created, **kwargs): """Generic handler for post_save signal.""" - if sender in [Issue, Hunt, IpReport, Post]: # Add any model you want to track - if created: - create_activity(instance, "created") + if sender == IpReport and created: # Track first IP report + assign_first_action_badge(instance.user, "First IP Reported") + create_activity(instance, "created") + + elif sender == Post and created: # Track first blog post + assign_first_action_badge(instance.user, "First Blog Posted") + create_activity(instance, "created") + + elif sender == Issue and created: # Track first bug report + assign_first_action_badge(instance.user, "First Bug Reported") + create_activity(instance, "created") + + elif sender == Hunt and created: # Track first bid placed + assign_first_action_badge(instance.user, "First Bug Bounty") + create_activity(instance, "created") + + elif sender == Suggestion and created: # Track first suggestion + assign_first_action_badge(instance.user, "First Suggestion") + create_activity(instance, "suggested") + + elif sender == Bid and created: # Track first bid placed + assign_first_action_badge(instance.user, "First Bid Placed") + create_activity(instance, "placed") + elif sender is User and created: # Handle user sign-up Activity.objects.create( user=instance,