-
-
Notifications
You must be signed in to change notification settings - Fork 291
Improved the "/sponsors" command for slack #630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 39 commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
231f5c2
added model, command , algolia , sponsors
abhayymishraa 6fddf74
Enhanced command and removed extra indexed from data
abhayymishraa 70a7dd2
Merge branch 'main' into feat/sponsors
abhayymishraa 2262c9d
Added testcases
abhayymishraa 1260440
verified commit
abhayymishraaa ad7584e
Merge branch 'main' into feat/sponsors
abhayymishraaa 8d3b4f2
verified commit with chnages
abhayymishraa 2df44d4
Merge branch 'main' into feat/sponsors
abhayymishraa fa9459a
fixed importing
abhayymishraa f2dabbe
Merge branch 'main' into feat/sponsors
abhayymishraa d6fe486
Merge branch 'main' into feat/sponsors
abhayymishraa 76e9010
Merge branch 'main' into feat/sponsors
abhayymishraa 5375a5b
Merge branch 'main' into feat/sponsors
abhayymishraa dde2f69
Merge branch 'main' into feat/sponsors
abhayymishraa 9d0c001
resolved conflict
abhayymishraa 16a758b
Merge branch 'main' into feat/sponsors
abhayymishraa fc41e3f
fixed testcase
abhayymishraa 2de5fe4
Merge branch 'main' into feat/sponsors
abhayymishraa c004ae2
fixed makefile
abhayymishraa 965a125
Merge branch 'main' into feat/sponsors
abhayymishraa 874aedc
pre-commit after resolve conflict
abhayymishraa 354149f
migrations
abhayymishraa 8d29ff2
Merge branch 'main' into feat/sponsors
abhayymishraa 3346deb
pre-commmit
abhayymishraa 55103aa
Merge branch 'main' into feat/sponsors
abhayymishraa 689d641
fixed sonaQube warning
abhayymishraa ad4b842
refractor code removed algolia
abhayymishraa 2afa6e3
updated testcase
abhayymishraa ef34968
Merge branch 'main' into feat/sponsors
abhayymishraa 818aa74
added moving Logo compoennt
abhayymishraa 7db1f02
backned test fix
abhayymishraa cfc555d
frontend test case fix
abhayymishraa 2c3eec3
pre-commit
abhayymishraa 930c075
Merge branch 'main' into feat/sponsors
abhayymishraa 5d06b86
fix e2e case
abhayymishraa b65d610
fix bug
abhayymishraa fdda190
improvements
abhayymishraa 35fa0bf
Merge branch 'main' into pr/abhayymishraa/630
arkid15r 370e32b
Update code
arkid15r d9a8317
changes
abhayymishraa b45db63
increase testcase timing
abhayymishraa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| """OWASP sponsors GraphQL node.""" | ||
|
|
||
| from apps.common.graphql.nodes import BaseNode | ||
| from apps.owasp.models.sponsor import Sponsor | ||
|
|
||
|
|
||
| class SponsorNode(BaseNode): | ||
| """Sponsor node.""" | ||
|
|
||
| class Meta: | ||
| model = Sponsor | ||
| fields = ( | ||
| "image_url", | ||
| "name", | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| """OWASP sponsors GraphQL queries.""" | ||
|
|
||
| import graphene | ||
|
|
||
| from apps.common.graphql.queries import BaseQuery | ||
| from apps.owasp.graphql.nodes.sponsor import SponsorNode | ||
| from apps.owasp.models.sponsor import Sponsor | ||
|
|
||
|
|
||
| class SponsorQuery(BaseQuery): | ||
| """Sponsor queries.""" | ||
|
|
||
| sponsors = graphene.List(SponsorNode) | ||
|
|
||
| def resolve_sponsors(root, info): | ||
| """Resolve sponsors.""" | ||
| return Sponsor.objects.all() | ||
20 changes: 20 additions & 0 deletions
20
backend/apps/owasp/management/commands/owasp_update_sponsors.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| """A command to add OWASP sponsors data.""" | ||
|
|
||
| import yaml | ||
| from django.core.management.base import BaseCommand | ||
|
|
||
| from apps.github.utils import get_repository_file_content | ||
| from apps.owasp.models.sponsor import Sponsor | ||
|
|
||
|
|
||
| class Command(BaseCommand): | ||
| help = "Import sponsors from the provided YAML file" | ||
|
|
||
| def handle(self, *args, **kwargs): | ||
| sponsors = yaml.safe_load( | ||
| get_repository_file_content( | ||
| "https://raw.githubusercontent.com/OWASP/owasp.github.io/main/_data/corp_members.yml" | ||
| ).expandtabs() | ||
| ) | ||
|
|
||
| Sponsor.bulk_save([Sponsor.update_data(sponsor) for sponsor in sponsors]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| # Generated by Django 5.1.5 on 2025-03-04 15:28 | ||
|
|
||
| from django.db import migrations, models | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
| dependencies = [ | ||
| ("owasp", "0021_alter_snapshot_key"), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.CreateModel( | ||
| name="Sponsor", | ||
| fields=[ | ||
| ( | ||
| "id", | ||
| models.BigAutoField( | ||
| auto_created=True, | ||
| primary_key=True, | ||
| serialize=False, | ||
| verbose_name="ID", | ||
| ), | ||
| ), | ||
| ("nest_created_at", models.DateTimeField(auto_now_add=True)), | ||
| ("nest_updated_at", models.DateTimeField(auto_now=True)), | ||
| ( | ||
| "description", | ||
| models.TextField(blank=True, verbose_name="Description"), | ||
| ), | ||
| ( | ||
| "key", | ||
| models.CharField(max_length=100, unique=True, verbose_name="Key"), | ||
| ), | ||
| ("name", models.CharField(max_length=255, verbose_name="Name")), | ||
| ( | ||
| "sort_name", | ||
| models.CharField(max_length=255, verbose_name="Sort Name"), | ||
| ), | ||
| ("url", models.URLField(blank=True, verbose_name="Website URL")), | ||
| ("job_url", models.URLField(blank=True, verbose_name="Job URL")), | ||
| ( | ||
| "image_url", | ||
| models.CharField(blank=True, max_length=255, verbose_name="Image Path"), | ||
| ), | ||
| ( | ||
| "is_member", | ||
| models.BooleanField(default=False, verbose_name="Is Corporate Sponsor"), | ||
| ), | ||
| ( | ||
| "member_type", | ||
| models.CharField( | ||
| blank=True, | ||
| choices=[ | ||
| ("Platinum", "Platinum"), | ||
| ("Gold", "Gold"), | ||
| ("Silver", "Silver"), | ||
| ], | ||
| default="Silver", | ||
| max_length=20, | ||
| verbose_name="Member Type", | ||
| ), | ||
| ), | ||
| ( | ||
| "sponsor_type", | ||
| models.CharField( | ||
| choices=[ | ||
| ("Diamond", "Diamond"), | ||
| ("Platinum", "Platinum"), | ||
| ("Gold", "Gold"), | ||
| ("Silver", "Silver"), | ||
| ("Supporter", "Supporter"), | ||
| ("Not a Sponsor", "Not Sponsor"), | ||
| ], | ||
| default="Not a Sponsor", | ||
| max_length=20, | ||
| verbose_name="Sponsor Type", | ||
| ), | ||
| ), | ||
| ], | ||
| options={ | ||
| "verbose_name_plural": "Sponsors", | ||
| "db_table": "owasp_sponsors", | ||
| }, | ||
| ), | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| """OWASP app sponsor models.""" | ||
|
|
||
| from django.db import models | ||
|
|
||
| from apps.common.models import BulkSaveModel, TimestampedModel | ||
| from apps.common.utils import slugify | ||
| from apps.github.utils import normalize_url | ||
|
|
||
|
|
||
| class Sponsor(BulkSaveModel, TimestampedModel): | ||
| """Sponsor model.""" | ||
|
|
||
| objects = models.Manager() | ||
|
|
||
| class Meta: | ||
| db_table = "owasp_sponsors" | ||
| verbose_name_plural = "Sponsors" | ||
|
|
||
| class SponsorType(models.TextChoices): | ||
| DIAMOND = "Diamond" | ||
| PLATINUM = "Platinum" | ||
| GOLD = "Gold" | ||
| SILVER = "Silver" | ||
| SUPPORTER = "Supporter" | ||
| NOT_SPONSOR = "Not a Sponsor" | ||
|
|
||
| class MemberType(models.TextChoices): | ||
| PLATINUM = "Platinum" | ||
| GOLD = "Gold" | ||
| SILVER = "Silver" | ||
|
|
||
| # Basic information | ||
| description = models.TextField(verbose_name="Description", blank=True) | ||
| key = models.CharField(verbose_name="Key", max_length=100, unique=True) | ||
| name = models.CharField(verbose_name="Name", max_length=255) | ||
| sort_name = models.CharField(verbose_name="Sort Name", max_length=255) | ||
|
|
||
| # URLs and images | ||
| url = models.URLField(verbose_name="Website URL", blank=True) | ||
| job_url = models.URLField(verbose_name="Job URL", blank=True) | ||
| image_url = models.CharField(verbose_name="Image Path", max_length=255, blank=True) | ||
|
|
||
| # Status fields | ||
| is_member = models.BooleanField(verbose_name="Is Corporate Sponsor", default=False) | ||
| member_type = models.CharField( | ||
| verbose_name="Member Type", | ||
| max_length=20, | ||
| choices=MemberType.choices, | ||
| default=MemberType.SILVER, | ||
| blank=True, | ||
| ) | ||
| sponsor_type = models.CharField( | ||
| verbose_name="Sponsor Type", | ||
| max_length=20, | ||
| choices=SponsorType.choices, | ||
| default=SponsorType.NOT_SPONSOR, | ||
| ) | ||
|
|
||
| def __str__(self): | ||
| """Sponsor human readable representation.""" | ||
| return f"{self.name}" | ||
|
|
||
| @property | ||
| def readable_member_type(self): | ||
| """Get human-readable member type.""" | ||
| return self.MemberType(self.member_type).label | ||
|
|
||
| @property | ||
| def readable_sponsor_type(self): | ||
| """Get human-readable sponsor type.""" | ||
| return self.SponsorType(self.sponsor_type).label | ||
|
|
||
| @staticmethod | ||
| def bulk_save(sponsors, fields=None): | ||
| """Bulk save sponsors.""" | ||
| BulkSaveModel.bulk_save(Sponsor, sponsors, fields=fields) | ||
|
|
||
| @staticmethod | ||
| def update_data(data, save=True): | ||
| """Update sponsor data.""" | ||
| key = slugify(data["name"]) | ||
| try: | ||
| sponsor = Sponsor.objects.get(key=key) | ||
| except Sponsor.DoesNotExist: | ||
| sponsor = Sponsor(key=key) | ||
|
|
||
| sponsor.from_dict(data) | ||
|
|
||
| if save: | ||
| sponsor.save() | ||
|
|
||
| return sponsor | ||
|
|
||
| def from_dict(self, data): | ||
| """Update instance based on the dict data.""" | ||
| image_path = data.get("image", "").lstrip("/") | ||
| image_url = f"https://raw.githubusercontent.com/OWASP/owasp.github.io/main/{image_path}" | ||
|
|
||
| member_type_mapping = { | ||
| 2: self.MemberType.PLATINUM, | ||
| 3: self.MemberType.GOLD, | ||
| 4: self.MemberType.SILVER, | ||
| } | ||
| sponsor_type_mapping = { | ||
| -1: self.SponsorType.NOT_SPONSOR, | ||
| 1: self.SponsorType.DIAMOND, | ||
| 2: self.SponsorType.PLATINUM, | ||
| 3: self.SponsorType.GOLD, | ||
| 4: self.SponsorType.SILVER, | ||
| 5: self.SponsorType.SUPPORTER, | ||
| } | ||
|
|
||
| member_key = data.get("membertype", 4) | ||
| sponsor_key = data.get("sponsor", -1) | ||
| member_type_label = member_type_mapping.get(member_key, self.MemberType.SILVER) | ||
| sponsor_type_label = sponsor_type_mapping.get(sponsor_key, self.SponsorType.NOT_SPONSOR) | ||
|
|
||
| fields = { | ||
| "description": data.get("description", ""), | ||
| "image_url": image_url, | ||
| "is_member": data.get("member", False), | ||
| "job_url": normalize_url(data.get("job_url", "")) or "", | ||
| "member_type": member_type_label, | ||
| "name": data["name"], | ||
| "sort_name": data.get("sortname", ""), | ||
| "sponsor_type": sponsor_type_label, | ||
| "url": normalize_url(data.get("url", "")) or "", | ||
| } | ||
|
|
||
| for key, value in fields.items(): | ||
| setattr(self, key, value) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Implement pagination and filtering for better performance.
The current implementation fetches all sponsors without pagination or filtering. This could lead to performance issues if there are many sponsors.
Consider implementing pagination and filtering:
class SponsorQuery(BaseQuery): """Sponsor queries.""" - sponsors = graphene.List(SponsorNode) + sponsors = graphene.List( + SponsorNode, + sponsor_type=graphene.String(required=False), + is_member=graphene.Boolean(required=False), + limit=graphene.Int(required=False, default_value=10), + offset=graphene.Int(required=False, default_value=0), + ) - def resolve_sponsors(root, info): + def resolve_sponsors(root, info, sponsor_type=None, is_member=None, limit=10, offset=0): """Resolve sponsors.""" - return Sponsor.objects.all() + query = Sponsor.objects.all() + + if sponsor_type: + query = query.filter(sponsor_type=sponsor_type) + + if is_member is not None: + query = query.filter(is_member=is_member) + + return query[offset:offset+limit]📝 Committable suggestion