Make Stripe optional
This commit is contained in:
parent
22df27178b
commit
e3fc0317a3
|
@ -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,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}")
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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…
Reference in New Issue