Skip to content
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

funding.json (see https://floss.fund) #1753

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions djangoproject/static/.well-known/funding-manifest-urls
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://www.djangoproject.com/funding.json
2 changes: 2 additions & 0 deletions djangoproject/urls/www.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from blog.sitemaps import WeblogSitemap
from foundation.feeds import FoundationMinutesFeed
from foundation.views import CoreDevelopers
from fundraising.views import funding_json

admin.autodiscover()

Expand Down Expand Up @@ -98,6 +99,7 @@
path("foundation/django_core/", CoreDevelopers.as_view()),
path("foundation/minutes/", include("foundation.urls.meetings")),
path("foundation/", include("members.urls")),
path("funding.json", funding_json, name="funding-json"), # see https://floss.fund
path("fundraising/", include("fundraising.urls")),
# Used by docs search suggestions
re_path(
Expand Down
128 changes: 127 additions & 1 deletion fundraising/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST

from members.models import CORPORATE_MEMBERSHIP_AMOUNTS

from .forms import DjangoHeroForm, DonationForm, PaymentForm
from .models import DjangoHero, Donation, Payment, Testimonial
from .models import INTERVAL_CHOICES, DjangoHero, Donation, Payment, Testimonial

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -338,3 +340,127 @@ def checkout_session_completed(self):
)

return HttpResponse(status=204)


def funding_json(request):
"""
Generate a funding.json -- see https://floss.fund/funding-manifest/
"""
funding = {
"version": "v1.0.0",
"entity": {
"type": "organisation",
"role": "owner",
"name": "Django Software Foundation",
"email": "[email protected]",
"description": (
"Development of Django is supported by the Django Software Foundation, "
"a 501(c)(3) non-profit."
),
"webpageUrl": {
"url": "https://www.djangoproject.com/foundation",
},
},
"projects": [
{
"guid": "django",
"name": "Django",
"description": (
"Django is a Python web framework that makes it possible to build "
"better web apps quickly and with less code"
),
"webpageUrl": {
"url": "https://www.djangoproject.com/",
},
"repositoryUrl": {
"url": "https://github.com/django/django",
"wellKnown": (
"https://github.com/django/django/blob/main/static/"
".well-known/funding-manifest-urls"
),
},
"licenses": ["spdx:BSD-3-Clause"],
"tags": ["python", "web", "django"],
}
],
"funding": {
"channels": [
{
"guid": "stripe",
"type": "payment-provider",
"address": "https://www.djangoproject.com/fundraising/",
"description": (
"Pay with your debit/credit card, "
"and set up recurring support."
),
},
{
"guid": "github-sponsors",
"type": "payment-provider",
"address": "https://github.com/sponsors/django",
"description": "Donate via GitHub sponsors",
},
{
"guid": "bank",
"type": "bank",
"description": (
"Pay via bank transfer or check - "
"contact [email protected] for details."
),
},
],
"plans": [],
},
}

# translate our keys for frequency into the ones understood by funding.json
frequency_translation = {
"onetime": "one-time",
"quarterly": "other",
}

# Pay-what-you-want individual funding levels
for frequency, title in INTERVAL_CHOICES:
funding["funding"]["plans"].append(
{
"guid": f"individual-{frequency}",
"status": "active",
"name": f"Django Hero - {title}",
"description": f"Support Django as an individual, - {title.lower()}",
"amount": 0,
"currency": "USD",
"frequency": frequency_translation.get(frequency, frequency),
"channels": [c["guid"] for c in funding["funding"]["channels"]],
}
)

# "leadership level" donation
funding["funding"]["plans"].append(
{
"guid": "individual-leadership",
"status": "active",
"name": "Django Hero - Leadership Level",
"description": "Django Hero - Leadership Level - Donate $1,000/yr or more",
"amount": 1000,
"currency": "USD",
"frequency": "yearly",
"channels": [c["guid"] for c in funding["funding"]["channels"]],
}
)

# corporate sponsorships
for level, amount in CORPORATE_MEMBERSHIP_AMOUNTS.items():
funding["funding"]["plans"].append(
{
"guid": f"corporate-{level}",
"status": "active",
"name": f"Corporate Sponsorship - {level.title()}",
"description": f"Corporate Sponsoreship - {level.title()}",
"amount": amount,
"currency": "USD",
"frequency": "yearly",
"channels": [c["guid"] for c in funding["funding"]["channels"]],
}
)

return JsonResponse(funding)