Make Stripe optional

master
Mark Veidemanis 2 years ago
parent 22df27178b
commit e3fc0317a3
Signed by: m
GPG Key ID: 5ACFCEED46C0904F

@ -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",
], ],
}, },
}, },

@ -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,25 +36,29 @@ class User(AbstractUser):
""" """
Override the save function to create a Stripe customer. Override the save function to create a Stripe customer.
""" """
if not self.stripe_id: # stripe ID not stored if settings.STRIPE_ENABLED:
self.stripe_id = get_or_create(self.email, self.first_name, self.last_name) if not self.stripe_id: # stripe ID not stored
self.stripe_id = get_or_create(
to_update = {} self.email, self.first_name, self.last_name
if self.email != self._original.email: )
to_update["email"] = self.email
if self.first_name != self._original.first_name: to_update = {}
to_update["first_name"] = self.first_name if self.email != self._original.email:
if self.last_name != self._original.last_name: to_update["email"] = self.email
to_update["last_name"] = self.last_name if self.first_name != self._original.first_name:
to_update["first_name"] = self.first_name
update_customer_fields(self.stripe_id, **to_update) if self.last_name != self._original.last_name:
to_update["last_name"] = self.last_name
update_customer_fields(self.stripe_id, **to_update)
super().save(*args, **kwargs) super().save(*args, **kwargs)
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
if self.stripe_id: if settings.STRIPE_ENABLED:
stripe.Customer.delete(self.stripe_id) if self.stripe_id:
logger.info(f"Deleted Stripe customer {self.stripe_id}") stripe.Customer.delete(self.stripe_id)
logger.info(f"Deleted Stripe customer {self.stripe_id}")
super().delete(*args, **kwargs) super().delete(*args, **kwargs)
def has_plan(self, plan): def has_plan(self, plan):

@ -201,10 +201,12 @@
<a class="navbar-item" href="{% url 'home' %}"> <a class="navbar-item" href="{% url 'home' %}">
Home Home
</a> </a>
{% if user.is_authenticated %} {% if settings.STRIPE_ENABLED %}
<a class="navbar-item" href="{% url 'billing' %}"> {% if user.is_authenticated %}
Billing <a class="navbar-item" href="{% url 'billing' %}">
</a> Billing
</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">

@ -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

@ -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")),

@ -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:

Loading…
Cancel
Save