Make Stripe optional

This commit is contained in:
Mark Veidemanis 2022-10-13 18:20:30 +01:00
parent 22df27178b
commit e3fc0317a3
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
6 changed files with 113 additions and 19 deletions

View File

@ -72,6 +72,7 @@ TEMPLATES = [
"django.template.context_processors.request", "django.template.context_processors.request",
"django.contrib.auth.context_processors.auth", "django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages", "django.contrib.messages.context_processors.messages",
"core.util.django_settings_export.settings_export",
], ],
}, },
}, },

View File

@ -1,6 +1,7 @@
import logging import logging
import stripe import stripe
from django.conf import settings
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.db import models from django.db import models
@ -35,8 +36,11 @@ class User(AbstractUser):
""" """
Override the save function to create a Stripe customer. Override the save function to create a Stripe customer.
""" """
if settings.STRIPE_ENABLED:
if not self.stripe_id: # stripe ID not stored if not self.stripe_id: # stripe ID not stored
self.stripe_id = get_or_create(self.email, self.first_name, self.last_name) self.stripe_id = get_or_create(
self.email, self.first_name, self.last_name
)
to_update = {} to_update = {}
if self.email != self._original.email: if self.email != self._original.email:
@ -51,6 +55,7 @@ class User(AbstractUser):
super().save(*args, **kwargs) super().save(*args, **kwargs)
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
if settings.STRIPE_ENABLED:
if self.stripe_id: if self.stripe_id:
stripe.Customer.delete(self.stripe_id) stripe.Customer.delete(self.stripe_id)
logger.info(f"Deleted Stripe customer {self.stripe_id}") logger.info(f"Deleted Stripe customer {self.stripe_id}")

View File

@ -201,11 +201,13 @@
<a class="navbar-item" href="{% url 'home' %}"> <a class="navbar-item" href="{% url 'home' %}">
Home Home
</a> </a>
{% if settings.STRIPE_ENABLED %}
{% if user.is_authenticated %} {% if user.is_authenticated %}
<a class="navbar-item" href="{% url 'billing' %}"> <a class="navbar-item" href="{% url 'billing' %}">
Billing Billing
</a> </a>
{% endif %} {% endif %}
{% endif %}
{% if user.is_superuser %} {% if user.is_superuser %}
<div class="navbar-item has-dropdown is-hoverable"> <div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link"> <a class="navbar-link">

View File

@ -0,0 +1,78 @@
"""
Export Django settings to templates
https://github.com/jakubroztocil/django-settings-export
"""
from django.conf import settings as django_settings
from django.core.exceptions import ImproperlyConfigured
__version__ = '1.2.1'
VARIABLE_NAME = getattr(django_settings,
'SETTINGS_EXPORT_VARIABLE_NAME',
'settings')
class SettingsExportError(ImproperlyConfigured):
"""Base error indicating misconfiguration."""
class UndefinedSettingError(SettingsExportError):
"""An undefined setting name included in SETTINGS_EXPORT."""
class UnexportedSettingError(SettingsExportError):
"""An unexported setting has been accessed from a template."""
def settings_export(request):
"""
The template context processor that adds settings defined in
`SETTINGS_EXPORT` to the context. If SETTINGS_EXPORT_VARIABLE_NAME is not
set, the context variable will be `settings`.
"""
variable_name = getattr(django_settings,
'SETTINGS_EXPORT_VARIABLE_NAME',
'settings')
return {
variable_name: _get_exported_settings()
}
class ExportedSettings(dict):
def __getitem__(self, item):
"""Fail loudly if accessing a setting that is not exported."""
try:
return super(ExportedSettings, self).__getitem__(item)
except KeyError:
if hasattr(self, item):
# Let the KeyError propagate so that Django templates
# can access the existing attribute (e.g. `items()`).
raise
raise UnexportedSettingError(
'The `{key}` setting key is not accessible'
' from templates: add "{key}" to'
' `settings.SETTINGS_EXPORT` to change that.'
.format(key=item)
)
def _get_exported_settings():
exported_settings = ExportedSettings()
for key in getattr(django_settings, 'SETTINGS_EXPORT', []):
try:
value = getattr(django_settings, key)
except AttributeError:
raise UndefinedSettingError(
'"settings.%s" is included in settings.SETTINGS_EXPORT '
'but it does not exist. '
% key
)
exported_settings[key] = value
return exported_settings

View File

@ -30,6 +30,8 @@ class Billing(LoginRequiredMixin, View):
template_name = "billing.html" template_name = "billing.html"
async def get(self, request): async def get(self, request):
if not settings.STRIPE_ENABLED:
return redirect(reverse("home"))
plans = await sync_to_async(list)(Plan.objects.all()) plans = await sync_to_async(list)(Plan.objects.all())
user_plans = await sync_to_async(list)(request.user.plans.all()) user_plans = await sync_to_async(list)(request.user.plans.all())
context = {"plans": plans, "user_plans": user_plans} context = {"plans": plans, "user_plans": user_plans}
@ -38,6 +40,8 @@ class Billing(LoginRequiredMixin, View):
class Order(LoginRequiredMixin, View): class Order(LoginRequiredMixin, View):
async def get(self, request, plan_name): async def get(self, request, plan_name):
if not settings.STRIPE_ENABLED:
return redirect(reverse("home"))
plan = Plan.objects.get(name=plan_name) plan = Plan.objects.get(name=plan_name)
try: try:
cast = { cast = {
@ -63,6 +67,8 @@ class Order(LoginRequiredMixin, View):
class Cancel(LoginRequiredMixin, View): class Cancel(LoginRequiredMixin, View):
async def get(self, request, plan_name): async def get(self, request, plan_name):
if not settings.STRIPE_ENABLED:
return redirect(reverse("home"))
plan = Plan.objects.get(name=plan_name) plan = Plan.objects.get(name=plan_name)
try: try:
subscriptions = stripe.Subscription.list( subscriptions = stripe.Subscription.list(
@ -88,6 +94,8 @@ class Signup(CreateView):
class Portal(LoginRequiredMixin, View): class Portal(LoginRequiredMixin, View):
async def get(self, request): async def get(self, request):
if not settings.STRIPE_ENABLED:
return redirect(reverse("home"))
session = stripe.billing_portal.Session.create( session = stripe.billing_portal.Session.create(
customer=request.user.stripe_id, customer=request.user.stripe_id,
return_url=request.build_absolute_uri(reverse("billing")), return_url=request.build_absolute_uri(reverse("billing")),

View File

@ -9,8 +9,8 @@ services:
# - ${PORTAINER_GIT_DIR}/docker/prod/uwsgi.ini:/conf/uwsgi.ini # - ${PORTAINER_GIT_DIR}/docker/prod/uwsgi.ini:/conf/uwsgi.ini
- ${APP_LOCAL_SETTINGS}:/code/app/local_settings.py - ${APP_LOCAL_SETTINGS}:/code/app/local_settings.py
- ${APP_DATABASE_FILE}:/code/db.sqlite3 - ${APP_DATABASE_FILE}:/code/db.sqlite3
ports: #ports:
- "8000:8000" # uwsgi socket # - "8000:8000" # uwsgi socket
env_file: env_file:
- ../stack.env - ../stack.env
volumes_from: volumes_from: