Skip to content

Commit

Permalink
added model, command , algolia , sponsors
Browse files Browse the repository at this point in the history
  • Loading branch information
abhayymishraa committed Jan 27, 2025
1 parent 60ad19b commit 231f5c2
Show file tree
Hide file tree
Showing 10 changed files with 517 additions and 12 deletions.
1 change: 1 addition & 0 deletions backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ index-data:
load-data:
@echo "Loading Nest data"
@CMD="poetry run python manage.py load_data" $(MAKE) exec-backend-command
@CMD="poetry run python manage.py load_sponsor_data" $(MAKE) exec-backend-command

merge-migrations:
@CMD="poetry run python manage.py makemigrations --merge" $(MAKE) exec-backend-command
Expand Down
46 changes: 46 additions & 0 deletions backend/apps/owasp/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from apps.owasp.models.committee import Committee
from apps.owasp.models.event import Event
from apps.owasp.models.project import Project
from apps.owasp.models.sponsor import Sponsor


class GenericEntityAdminMixin:
Expand Down Expand Up @@ -100,8 +101,53 @@ def custom_field_name(self, obj):

custom_field_name.short_description = "Name"

class SponsorAdmin(admin.ModelAdmin):
"""Admin configuration for Sponsor model."""

list_display = (
'name',
'sort_name',
'is_active_sponsor',
'sponsor_type',
'is_member',
'member_type',
)

search_fields = (
'name',
'sort_name',
'description',
)

list_filter = (
'sponsor_type',
'is_member',
'member_type',
)

fieldsets = (
('Basic Information', {
'fields': ('name', 'sort_name', 'description')
}),
('URLs and Images', {
'fields': ('url', 'job_url', 'image')
}),
('Status', {
'fields': ('is_member', 'member_type', 'sponsor_type')
}),
)

readonly_fields = ('is_active_sponsor',)

def is_active_sponsor(self, obj):
"""Display if sponsor is active."""
return obj.is_active_sponsor
is_active_sponsor.boolean = True
is_active_sponsor.short_description = "Active Sponsor"


admin.site.register(Chapter, ChapterAdmin)
admin.site.register(Committee, CommetteeAdmin)
admin.site.register(Event, EventAdmin)
admin.site.register(Project, ProjectAdmin)
admin.site.register(Sponsor, SponsorAdmin)
29 changes: 29 additions & 0 deletions backend/apps/owasp/api/search/sponsor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""OWASP app sponsor search API."""

from algoliasearch_django import raw_search
from apps.owasp.models.sponsor import Sponsor

def get_sponsors(query, attributes=None, limit=25, page=1):
params = {
"attributesToHighlight": [],
"attributesToRetrieve": attributes
or [
"idx_name",
"idx_sort_name",
"idx_description",
"idx_url",
"idx_job_url",
"idx_image",
"idx_member_type",
"idx_sponsor_type",
"idx_member_level",
"idx_sponsor_level",
"idx_is_member",
"idx_is_active_sponsor"
],
"hitsPerPage": limit,
"minProximity": 4,
"page": page - 1,
"typoTolerance": "min"
}
return raw_search(Sponsor, query, params)
1 change: 1 addition & 0 deletions backend/apps/owasp/index/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from apps.owasp.index.chapter import ChapterIndex
from apps.owasp.index.committee import CommitteeIndex
from apps.owasp.index.project import ProjectIndex
from apps.owasp.index.sponsor import SponsorIndex
54 changes: 54 additions & 0 deletions backend/apps/owasp/index/sponsor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""OWASP app sponsor index."""

from algoliasearch_django import AlgoliaIndex
from algoliasearch_django.decorators import register
from apps.common.index import IS_LOCAL_BUILD, LOCAL_INDEX_LIMIT
from apps.owasp.models.sponsor import Sponsor

@register(Sponsor)
class SponsorIndex(AlgoliaIndex):
index_name = "sponsors"
fields = (
"idx_name",
"idx_sort_name",
"idx_description",
"idx_url",
"idx_job_url",
"idx_image",
"idx_member_type",
"idx_sponsor_type",
"idx_member_level",
"idx_sponsor_level",
"idx_is_member",
"idx_is_active_sponsor",
)
settings = {
"attributesForFaceting": [
"filterOnly(idx_name)",
"idx_is_active_sponsor",
],
"indexLanguages": ["en"],
"customRanking": [
"asc(idx_sort_name)",
],
"ranking": [
"typo",
"words",
"filters",
"proximity",
"attribute",
"exact",
"custom",
],
"searchableAttributes": [
"unordered(idx_name)",
"unordered(idx_sort_name)",
"unordered(idx_member_level)",
"unordered(idx_sponsor_level)",
],
}
should_index = "is_indexable"

def get_queryset(self):
qs = Sponsor.objects.all()
return qs[:LOCAL_INDEX_LIMIT] if IS_LOCAL_BUILD else qs
29 changes: 29 additions & 0 deletions backend/apps/owasp/management/commands/load_sponsor_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import yaml
from django.core.management.base import BaseCommand
from apps.owasp.models.sponsor import Sponsor
from apps.github.utils import get_repository_file_content, normalize_url

class Command(BaseCommand):
help = "Import sponsors from OWASP GitHub repository"

def handle(self, *args, **kwargs):
url = "https://raw.githubusercontent.com/OWASP/owasp.github.io/main/_data/corp_members.yml"
yaml_content = get_repository_file_content(url).replace("\t", " ")
data = yaml.safe_load(yaml_content)

for entry in data:
sponsor = Sponsor(
name=entry.get("name", ""),
sort_name=entry.get("sortname", ""),
description=entry.get("description", ""),
url=normalize_url(entry.get("url", "")),
job_url=normalize_url(entry.get("job_url", "") or ""),
image=entry.get("image", ""),
is_member=entry.get("member", False),
member_type=entry.get("membertype", "4") or "4",
sponsor_type=entry.get("sponsor", "-1") or "-1",
)
sponsor.save()
self.stdout.write(self.style.SUCCESS(f"Successfully imported sponsor: {sponsor.name}"))

self.stdout.write(self.style.SUCCESS("Finished importing sponsors"))
74 changes: 74 additions & 0 deletions backend/apps/owasp/models/mixins/sponsor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""OWASP app sponsor mixins."""

from apps.owasp.models.mixins.common import GenericEntityMixin

class SponsorIndexMixin(GenericEntityMixin):
@property
def idx_created_at(self):
"""Get created timestamp for index."""
return self.nest_created_at

@property
def idx_updated_at(self):
"""Get updated timestamp for index."""
return self.nest_updated_at

@property
def idx_name(self):
"""Get name for index."""
return self.name

@property
def idx_sort_name(self):
"""Get sort name for index."""
return self.sort_name

@property
def idx_description(self):
"""Get description for index."""
return self.description

@property
def idx_url(self):
"""Get URL for index."""
return self.url

@property
def idx_job_url(self):
"""Get job URL for index."""
return self.job_url

@property
def idx_image(self):
"""Get image path for index."""
return self.image

@property
def idx_member_type(self):
"""Get member type for index."""
return self.member_type

@property
def idx_sponsor_type(self):
"""Get sponsor type for index."""
return self.sponsor_type

@property
def idx_member_level(self):
"""Get member level for index."""
return self.member_level

@property
def idx_sponsor_level(self):
"""Get sponsor level for index."""
return self.sponsor_level

@property
def idx_is_member(self):
"""Get member status for index."""
return self.is_member

@property
def idx_is_active_sponsor(self):
"""Get active sponsor status for index."""
return self.is_active_sponsor
Loading

0 comments on commit 231f5c2

Please sign in to comment.