^
This commit is contained in:
parent
715491017a
commit
470c808d52
4 changed files with 791 additions and 72 deletions
117
deploy-saleor.sh
117
deploy-saleor.sh
|
@ -258,18 +258,18 @@ done
|
||||||
echo -n "Enter a custom Static Files URI (optional):"
|
echo -n "Enter a custom Static Files URI (optional):"
|
||||||
read STATIC_URL
|
read STATIC_URL
|
||||||
# Get the Admin's email address
|
# Get the Admin's email address
|
||||||
while [ "$EMAIL" = "" ]
|
while [ "$ADMIN_EMAIL" = "" ]
|
||||||
do
|
do
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Enter the Dashboard admin's email:"
|
echo -n "Enter the Dashboard admin's email:"
|
||||||
read EMAIL
|
read ADMIN_EMAIL
|
||||||
done
|
done
|
||||||
# Get the Admin's desired password
|
# Get the Admin's desired password
|
||||||
while [ "$PASSW" = "" ]
|
while [ "$ADMIN_PASS" = "" ]
|
||||||
do
|
do
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Enter the Dashboard admin's desired password:"
|
echo -n "Enter the Dashboard admin's desired password:"
|
||||||
read -s PASSW
|
read -s ADMIN_PASS
|
||||||
done
|
done
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
|
@ -376,24 +376,28 @@ echo ""
|
||||||
# Replace any parameter slugs in the template files with real paramaters & write them to
|
# Replace any parameter slugs in the template files with real paramaters & write them to
|
||||||
# the production files
|
# the production files
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
# Replace the settings.py with the production version
|
||||||
|
if [ -f "$HD/saleor/saleor/settings.py" ]; then
|
||||||
|
sudo rm $HD/saleor/saleor/settings.py
|
||||||
|
fi
|
||||||
|
sudo cp $HD/Deploy_Saleor/resources/saleor/settings.py $HD/saleor/saleor/
|
||||||
|
# Replace the populatedb.py file with the production version
|
||||||
|
if [ -f "$HD/saleor/saleor/core/management/commands/populatedb.py" ]; then
|
||||||
|
sudo rm $HD/saleor/saleor/core/management/commands/populatedb.py
|
||||||
|
fi
|
||||||
|
sudo cp $HD/Deploy_Saleor/resources/saleor/populatedb.py $HD/saleor/saleor/core/management/commands/
|
||||||
|
# Replace the test_core.py file with the production version
|
||||||
|
if [ -f "$HD/saleor/saleor/core/tests/test_core.py" ]; then
|
||||||
|
sudo rm $HD/saleor/saleor/core/tests/test_core.py
|
||||||
|
fi
|
||||||
|
sudo cp $HD/Deploy_Saleor/resources/saleor/test_core.py $HD/saleor/saleor/core/tests/
|
||||||
|
wait
|
||||||
# Does an old saleor.service file exist?
|
# Does an old saleor.service file exist?
|
||||||
if [ -f "/etc/systemd/system/saleor.service" ]; then
|
if [ -f "/etc/systemd/system/saleor.service" ]; then
|
||||||
# Remove the old service file
|
# Remove the old service file
|
||||||
sudo rm /etc/systemd/system/saleor.service
|
sudo rm /etc/systemd/system/saleor.service
|
||||||
fi
|
fi
|
||||||
READ_ENV='
|
###### This following section is for future use and will be modified to allow an alternative repo clone ######
|
||||||
try:
|
|
||||||
from decouple import RepositoryEnv
|
|
||||||
file_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
|
||||||
#print("{}/.env".format(file_path))
|
|
||||||
for k,v in RepositoryEnv("{}/.env".format(file_path)).data.items():
|
|
||||||
print(k, v)
|
|
||||||
os.environ[k] = v
|
|
||||||
except Exception as e:
|
|
||||||
#print(e)
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_list(text):'
|
|
||||||
# Was the -v (version) option used or Mirumee repo specified?
|
# Was the -v (version) option used or Mirumee repo specified?
|
||||||
if [ "vOPT" = "true" ] || [ "$REPO" = "mirumee" ]; then
|
if [ "vOPT" = "true" ] || [ "$REPO" = "mirumee" ]; then
|
||||||
# Create the new service file
|
# Create the new service file
|
||||||
|
@ -411,16 +415,6 @@ if [ "vOPT" = "true" ] || [ "$REPO" = "mirumee" ]; then
|
||||||
s/{host}/$HOST/g
|
s/{host}/$HOST/g
|
||||||
s/{apiport}/$API_PORT/" $HD/Deploy_Saleor/resources/saleor/server_block > /etc/nginx/sites-available/saleor
|
s/{apiport}/$API_PORT/" $HD/Deploy_Saleor/resources/saleor/server_block > /etc/nginx/sites-available/saleor
|
||||||
wait
|
wait
|
||||||
# Replace demo credentials with production credentials in /saleor/saleor/core/management/commands/populatedb.py
|
|
||||||
sudo sed -i 's/{"email": "admin@example.com", "password": "admin"}/{"email": "'$EMAIL'", "password": "'$PASSW'"}/' $HD/saleor/saleor/core/management/commands/populatedb.py
|
|
||||||
wait
|
|
||||||
# Replace demo credentials with production credentials in /saleor/saleor/core/tests/test_core.py
|
|
||||||
sudo sed -i 's/{"email": "admin@example.com", "password": "admin"}/{"email": "'$EMAIL'", "password": "'$PASSW'"}/' $HD/saleor/saleor/core/tests/test_core.py
|
|
||||||
wait
|
|
||||||
# Replace the insecure demo secret key assignemnt with a more secure file reference in /saleor/saleor/settings.py
|
|
||||||
sudo sed -i 's|SECRET_KEY = os.environ.get("SECRET_KEY")|with open("/etc/saleor/api_sk") as f: SECRET_KEY = f.read().strip()|
|
|
||||||
s|def get_list(text):|'$READ_ENV'|' $HD/saleor/saleor/settings.py
|
|
||||||
wait
|
|
||||||
else
|
else
|
||||||
# Create the new service file
|
# Create the new service file
|
||||||
sudo sed "s/{un}/$UN/
|
sudo sed "s/{un}/$UN/
|
||||||
|
@ -437,42 +431,6 @@ else
|
||||||
s/{host}/$HOST/g
|
s/{host}/$HOST/g
|
||||||
s/{apiport}/$API_PORT/" $HD/Deploy_Saleor/resources/saleor/server_block > /etc/nginx/sites-available/saleor
|
s/{apiport}/$API_PORT/" $HD/Deploy_Saleor/resources/saleor/server_block > /etc/nginx/sites-available/saleor
|
||||||
wait
|
wait
|
||||||
# Replace demo credentials with production credentials in /saleor/saleor/core/management/commands/populatedb.py
|
|
||||||
sudo sed -i "s/{\"email\": \"admin@example.com\", \"password\": \"admin\"}/{\"email\": \"$EMAIL\", \"password\": \"$PASSW\"}/" $HD/saleor/saleor/core/management/commands/populatedb.py
|
|
||||||
wait
|
|
||||||
# Replace demo credentials with production credentials in /saleor/saleor/core/tests/test_core.py
|
|
||||||
sudo sed -i "s/{\"email\": \"admin@example.com\", \"password\": \"admin\"}/{\"email\": \"$EMAIL\", \"password\": \"$PASSW\"}/" $HD/saleor/saleor/core/tests/test_core.py
|
|
||||||
wait
|
|
||||||
# Replace the insecure demo secret key assignemnt with a more secure file reference in /saleor/saleor/settings.py
|
|
||||||
sudo sed -i "s|SECRET_KEY = os.environ.get(\"SECRET_KEY\")|with open('/etc/saleor/api_sk') as f: SECRET_KEY = f.read().strip()|
|
|
||||||
s|def get_list(text):|$READ_ENV|" $HD/saleor/saleor/settings.py
|
|
||||||
wait
|
|
||||||
|
|
||||||
###### For possible later use ######
|
|
||||||
# Create the new service file
|
|
||||||
#sudo sed "s/{un}/$UN/
|
|
||||||
# s|{hd}|$HD|" $HD/saleor/resources/saleor/template.service > /etc/systemd/system/saleor.service
|
|
||||||
#wait
|
|
||||||
# Does an old server block exist?
|
|
||||||
#if [ -f "/etc/nginx/sites-available/saleor" ]; then
|
|
||||||
# # Remove the old service file
|
|
||||||
# sudo rm /etc/nginx/sites-available/saleor
|
|
||||||
#fi
|
|
||||||
# Create the new server block
|
|
||||||
#sudo sed "s|{hd}|$HD|
|
|
||||||
# s/{api_host}/$API_HOST/
|
|
||||||
# s/{host}/$HOST/g
|
|
||||||
# s/{apiport}/$API_PORT/" $HD/saleor/resources/saleor/server_block > /etc/nginx/sites-available/saleor
|
|
||||||
#wait
|
|
||||||
# Set the production credentials in /saleor/saleor/core/management/commands/populatedb.py
|
|
||||||
#sudo sed -i "s/{email}/$EMAIL/
|
|
||||||
# s/{passw}/$PASSW/" $HD/saleor/saleor/core/management/commands/populatedb.py
|
|
||||||
#wait
|
|
||||||
# Set the production credentials in /saleor/saleor/core/tests/test_core.py
|
|
||||||
#sudo sed -i "s/{email}/$EMAIL/
|
|
||||||
# s/{passw}/$PASSW/" $HD/saleor/saleor/core/tests/test_core.py
|
|
||||||
#wait
|
|
||||||
###### For possible later use ######
|
|
||||||
fi
|
fi
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
|
@ -503,6 +461,7 @@ sudo sed "s|{dburl}|$DB_URL|
|
||||||
s/{ahosts}/$A_HOSTS/
|
s/{ahosts}/$A_HOSTS/
|
||||||
s|{static}|$STATIC_URL|
|
s|{static}|$STATIC_URL|
|
||||||
s|{media}|$MEDIA_URL|
|
s|{media}|$MEDIA_URL|
|
||||||
|
s/{adminemail}/$ADMIN_EMAIL/
|
||||||
s/{gqlorigins}/$QL_ORIGINS/" $HD/Deploy_Saleor/resources/saleor/template.env > $HD/saleor/.env
|
s/{gqlorigins}/$QL_ORIGINS/" $HD/Deploy_Saleor/resources/saleor/template.env > $HD/saleor/.env
|
||||||
wait
|
wait
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
@ -561,18 +520,29 @@ wait
|
||||||
# Install the project requirements
|
# Install the project requirements
|
||||||
pip3 install -r requirements.txt
|
pip3 install -r requirements.txt
|
||||||
wait
|
wait
|
||||||
|
# Install the decoupler for .env file
|
||||||
|
pip3 install python3-decouple
|
||||||
|
wait
|
||||||
|
# Set any secret Environment Variables
|
||||||
|
export ADMIN_PASS="$ADMIN_PASS"
|
||||||
# Install the project
|
# Install the project
|
||||||
npm install
|
npm install
|
||||||
|
wait
|
||||||
# Run an audit to fix any vulnerabilities
|
# Run an audit to fix any vulnerabilities
|
||||||
npm audit fix
|
npm audit fix
|
||||||
|
wait
|
||||||
# Establish the database
|
# Establish the database
|
||||||
python3 manage.py migrate
|
python3 manage.py migrate --createsuperuser
|
||||||
|
wait
|
||||||
# Collect the static elemants
|
# Collect the static elemants
|
||||||
python3 manage.py collectstatic
|
python3 manage.py collectstatic
|
||||||
|
wait
|
||||||
# Build the schema
|
# Build the schema
|
||||||
npm run build-schema
|
npm run build-schema
|
||||||
|
wait
|
||||||
# Build the emails
|
# Build the emails
|
||||||
npm run build-emails
|
npm run build-emails
|
||||||
|
wait
|
||||||
# Exit the virtual environment here? _#_
|
# Exit the virtual environment here? _#_
|
||||||
deactivate
|
deactivate
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
@ -580,17 +550,13 @@ deactivate
|
||||||
|
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# Create the Saleor service
|
# Enable the Saleor service
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# Touch
|
|
||||||
sudo touch /etc/init.d/saleor
|
|
||||||
# Allow execute
|
|
||||||
sudo chmod +x /etc/init.d/saleor
|
|
||||||
# Update with defaults
|
# Update with defaults
|
||||||
sudo update-rc.d saleor defaults
|
sudo systemctl enable saleor.service
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
systemctl start emperor.uwsgi.service
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
echo "Enabling server block and Restarting nginx..."
|
echo "Enabling server block and Restarting nginx..."
|
||||||
|
@ -606,4 +572,11 @@ sudo systemctl restart nginx
|
||||||
echo ""
|
echo ""
|
||||||
echo "Finished creating production deployment packages for Saleor API & GraphQL"
|
echo "Finished creating production deployment packages for Saleor API & GraphQL"
|
||||||
echo ""
|
echo ""
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
# Call the dashboard deployment script
|
||||||
|
#########################################################################################
|
||||||
|
source ./deploy-dashboard.sh
|
||||||
#########################################################################################
|
#########################################################################################
|
142
resources/saleor/populatedb.py
Normal file
142
resources/saleor/populatedb.py
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
from django.apps import apps
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.management import call_command
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.db import connection
|
||||||
|
|
||||||
|
from ....account.utils import create_superuser
|
||||||
|
from ...utils.random_data import (
|
||||||
|
add_address_to_admin,
|
||||||
|
create_channels,
|
||||||
|
create_gift_card,
|
||||||
|
create_menus,
|
||||||
|
create_orders,
|
||||||
|
create_page_type,
|
||||||
|
create_pages,
|
||||||
|
create_permission_groups,
|
||||||
|
create_product_sales,
|
||||||
|
create_products_by_schema,
|
||||||
|
create_shipping_zones,
|
||||||
|
create_staffs,
|
||||||
|
create_users,
|
||||||
|
create_vouchers,
|
||||||
|
create_warehouses,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Populate database with test objects"
|
||||||
|
placeholders_dir = "saleor/static/placeholders/"
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
"--createsuperuser",
|
||||||
|
action="store_true",
|
||||||
|
dest="createsuperuser",
|
||||||
|
default=False,
|
||||||
|
help="Create admin account",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--sampledata",
|
||||||
|
action="store_true",
|
||||||
|
dest="sampledata",
|
||||||
|
default=False,
|
||||||
|
help="Create sample products, etc..",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--withoutimages",
|
||||||
|
action="store_true",
|
||||||
|
dest="withoutimages",
|
||||||
|
default=False,
|
||||||
|
help="Don't create product images",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--skipsequencereset",
|
||||||
|
action="store_true",
|
||||||
|
dest="skipsequencereset",
|
||||||
|
default=False,
|
||||||
|
help="Don't reset SQL sequences that are out of sync.",
|
||||||
|
)
|
||||||
|
|
||||||
|
def make_database_faster(self):
|
||||||
|
"""Sacrifice some of the safeguards of sqlite3 for speed.
|
||||||
|
|
||||||
|
Users are not likely to run this command in a production environment.
|
||||||
|
They are even less likely to run it in production while using sqlite3.
|
||||||
|
"""
|
||||||
|
if "sqlite3" in connection.settings_dict["ENGINE"]:
|
||||||
|
cursor = connection.cursor()
|
||||||
|
cursor.execute("PRAGMA temp_store = MEMORY;")
|
||||||
|
cursor.execute("PRAGMA synchronous = OFF;")
|
||||||
|
|
||||||
|
def sequence_reset(self):
|
||||||
|
"""Run a SQL sequence reset on all saleor.* apps.
|
||||||
|
|
||||||
|
When a value is manually assigned to an auto-incrementing field
|
||||||
|
it doesn't update the field's sequence, which might cause a conflict
|
||||||
|
later on.
|
||||||
|
"""
|
||||||
|
commands = StringIO()
|
||||||
|
for app in apps.get_app_configs():
|
||||||
|
if "saleor" in app.name:
|
||||||
|
call_command(
|
||||||
|
"sqlsequencereset", app.label, stdout=commands, no_color=True
|
||||||
|
)
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute(commands.getvalue())
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
# set only our custom plugin to not call external API when preparing
|
||||||
|
# example database
|
||||||
|
settings.PLUGINS = [
|
||||||
|
"saleor.payment.gateways.dummy.plugin.DummyGatewayPlugin",
|
||||||
|
"saleor.payment.gateways.dummy_credit_card.plugin."
|
||||||
|
"DummyCreditCardGatewayPlugin",
|
||||||
|
]
|
||||||
|
|
||||||
|
ADMIN_EMAIL = os.environ.get("ADMIN_EMAIL")
|
||||||
|
ADMIN_PASS = os.environ.get("ADMIN_PASS")
|
||||||
|
|
||||||
|
if options["createsuperuser"]:
|
||||||
|
credentials = {"email": ADMIN_EMAIL, "password": ADMIN_PASS}
|
||||||
|
msg = create_superuser(credentials)
|
||||||
|
self.stdout.write(msg)
|
||||||
|
add_address_to_admin(credentials["email"])
|
||||||
|
|
||||||
|
if options["sampledata"]:
|
||||||
|
self.make_database_faster()
|
||||||
|
create_images = not options["withoutimages"]
|
||||||
|
for msg in create_channels():
|
||||||
|
self.stdout.write(msg)
|
||||||
|
for msg in create_shipping_zones():
|
||||||
|
self.stdout.write(msg)
|
||||||
|
create_warehouses()
|
||||||
|
self.stdout.write("Created warehouses")
|
||||||
|
for msg in create_page_type():
|
||||||
|
self.stdout.write(msg)
|
||||||
|
for msg in create_pages():
|
||||||
|
self.stdout.write(msg)
|
||||||
|
create_products_by_schema(self.placeholders_dir, create_images)
|
||||||
|
self.stdout.write("Created products")
|
||||||
|
for msg in create_product_sales(5):
|
||||||
|
self.stdout.write(msg)
|
||||||
|
for msg in create_vouchers():
|
||||||
|
self.stdout.write(msg)
|
||||||
|
for msg in create_gift_card():
|
||||||
|
self.stdout.write(msg)
|
||||||
|
for msg in create_users(20):
|
||||||
|
self.stdout.write(msg)
|
||||||
|
for msg in create_orders(20):
|
||||||
|
self.stdout.write(msg)
|
||||||
|
for msg in create_menus():
|
||||||
|
self.stdout.write(msg)
|
||||||
|
|
||||||
|
if not options["skipsequencereset"]:
|
||||||
|
self.sequence_reset()
|
||||||
|
|
||||||
|
for msg in create_permission_groups():
|
||||||
|
self.stdout.write(msg)
|
||||||
|
for msg in create_staffs():
|
||||||
|
self.stdout.write(msg)
|
603
resources/saleor/settings.py
Normal file
603
resources/saleor/settings.py
Normal file
|
@ -0,0 +1,603 @@
|
||||||
|
import ast
|
||||||
|
import os.path
|
||||||
|
import warnings
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
import dj_database_url
|
||||||
|
import dj_email_url
|
||||||
|
import django_cache_url
|
||||||
|
import jaeger_client
|
||||||
|
import jaeger_client.config
|
||||||
|
import pkg_resources
|
||||||
|
import sentry_sdk
|
||||||
|
import sentry_sdk.utils
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.core.management.utils import get_random_secret_key
|
||||||
|
from pytimeparse import parse
|
||||||
|
from sentry_sdk.integrations.celery import CeleryIntegration
|
||||||
|
from sentry_sdk.integrations.django import DjangoIntegration
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from decouple import RepositoryEnv
|
||||||
|
file_path = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||||
|
#print("{}/.env".format(file_path))
|
||||||
|
for k,v in RepositoryEnv("{}/.env".format(file_path)).data.items():
|
||||||
|
print(k, v)
|
||||||
|
os.environ[k] = v
|
||||||
|
except Exception as e:
|
||||||
|
#print(e)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_list(text):
|
||||||
|
return [item.strip() for item in text.split(",")]
|
||||||
|
|
||||||
|
|
||||||
|
def get_bool_from_env(name, default_value):
|
||||||
|
if name in os.environ:
|
||||||
|
value = os.environ[name]
|
||||||
|
try:
|
||||||
|
return ast.literal_eval(value)
|
||||||
|
except ValueError as e:
|
||||||
|
raise ValueError("{} is an invalid value for {}".format(value, name)) from e
|
||||||
|
return default_value
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG = os.environ.get('DJANGO_DEBUG', '') != 'False'
|
||||||
|
|
||||||
|
SITE_ID = 1
|
||||||
|
|
||||||
|
PROJECT_ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
|
||||||
|
|
||||||
|
ROOT_URLCONF = "saleor.urls"
|
||||||
|
|
||||||
|
WSGI_APPLICATION = "saleor.wsgi.application"
|
||||||
|
|
||||||
|
ADMINS = (
|
||||||
|
# ('Your Name', 'your_email@example.com'),
|
||||||
|
)
|
||||||
|
MANAGERS = ADMINS
|
||||||
|
|
||||||
|
_DEFAULT_CLIENT_HOSTS = "localhost,127.0.0.1"
|
||||||
|
|
||||||
|
ALLOWED_CLIENT_HOSTS = os.environ.get("ALLOWED_CLIENT_HOSTS")
|
||||||
|
if not ALLOWED_CLIENT_HOSTS:
|
||||||
|
if DEBUG:
|
||||||
|
ALLOWED_CLIENT_HOSTS = _DEFAULT_CLIENT_HOSTS
|
||||||
|
else:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"ALLOWED_CLIENT_HOSTS environment variable must be set when DEBUG=False."
|
||||||
|
)
|
||||||
|
|
||||||
|
ALLOWED_CLIENT_HOSTS = get_list(ALLOWED_CLIENT_HOSTS)
|
||||||
|
|
||||||
|
INTERNAL_IPS = get_list(os.environ.get("INTERNAL_IPS", "127.0.0.1"))
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
"default": dj_database_url.config(
|
||||||
|
default="postgres://saleor:saleor@localhost:5432/saleor", conn_max_age=600
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TIME_ZONE = "UTC"
|
||||||
|
LANGUAGE_CODE = "en"
|
||||||
|
LANGUAGES = [
|
||||||
|
("ar", "Arabic"),
|
||||||
|
("az", "Azerbaijani"),
|
||||||
|
("bg", "Bulgarian"),
|
||||||
|
("bn", "Bengali"),
|
||||||
|
("ca", "Catalan"),
|
||||||
|
("cs", "Czech"),
|
||||||
|
("da", "Danish"),
|
||||||
|
("de", "German"),
|
||||||
|
("el", "Greek"),
|
||||||
|
("en", "English"),
|
||||||
|
("es", "Spanish"),
|
||||||
|
("es-co", "Colombian Spanish"),
|
||||||
|
("et", "Estonian"),
|
||||||
|
("fa", "Persian"),
|
||||||
|
("fi", "Finnish"),
|
||||||
|
("fr", "French"),
|
||||||
|
("hi", "Hindi"),
|
||||||
|
("hu", "Hungarian"),
|
||||||
|
("hy", "Armenian"),
|
||||||
|
("id", "Indonesian"),
|
||||||
|
("is", "Icelandic"),
|
||||||
|
("it", "Italian"),
|
||||||
|
("ja", "Japanese"),
|
||||||
|
("ka", "Georgian"),
|
||||||
|
("km", "Khmer"),
|
||||||
|
("ko", "Korean"),
|
||||||
|
("lt", "Lithuanian"),
|
||||||
|
("mn", "Mongolian"),
|
||||||
|
("my", "Burmese"),
|
||||||
|
("nb", "Norwegian"),
|
||||||
|
("nl", "Dutch"),
|
||||||
|
("pl", "Polish"),
|
||||||
|
("pt", "Portuguese"),
|
||||||
|
("pt-br", "Brazilian Portuguese"),
|
||||||
|
("ro", "Romanian"),
|
||||||
|
("ru", "Russian"),
|
||||||
|
("sk", "Slovak"),
|
||||||
|
("sl", "Slovenian"),
|
||||||
|
("sq", "Albanian"),
|
||||||
|
("sr", "Serbian"),
|
||||||
|
("sv", "Swedish"),
|
||||||
|
("sw", "Swahili"),
|
||||||
|
("ta", "Tamil"),
|
||||||
|
("th", "Thai"),
|
||||||
|
("tr", "Turkish"),
|
||||||
|
("uk", "Ukrainian"),
|
||||||
|
("vi", "Vietnamese"),
|
||||||
|
("zh-hans", "Simplified Chinese"),
|
||||||
|
("zh-hant", "Traditional Chinese"),
|
||||||
|
]
|
||||||
|
LOCALE_PATHS = [os.path.join(PROJECT_ROOT, "locale")]
|
||||||
|
USE_I18N = True
|
||||||
|
USE_L10N = True
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
FORM_RENDERER = "django.forms.renderers.TemplatesSetting"
|
||||||
|
|
||||||
|
EMAIL_URL = os.environ.get("EMAIL_URL")
|
||||||
|
SENDGRID_USERNAME = os.environ.get("SENDGRID_USERNAME")
|
||||||
|
SENDGRID_PASSWORD = os.environ.get("SENDGRID_PASSWORD")
|
||||||
|
if not EMAIL_URL and SENDGRID_USERNAME and SENDGRID_PASSWORD:
|
||||||
|
EMAIL_URL = "smtp://%s:%s@smtp.sendgrid.net:587/?tls=True" % (
|
||||||
|
SENDGRID_USERNAME,
|
||||||
|
SENDGRID_PASSWORD,
|
||||||
|
)
|
||||||
|
email_config = dj_email_url.parse(
|
||||||
|
EMAIL_URL or "console://demo@example.com:console@example/"
|
||||||
|
)
|
||||||
|
|
||||||
|
EMAIL_FILE_PATH = email_config["EMAIL_FILE_PATH"]
|
||||||
|
EMAIL_HOST_USER = email_config["EMAIL_HOST_USER"]
|
||||||
|
EMAIL_HOST_PASSWORD = email_config["EMAIL_HOST_PASSWORD"]
|
||||||
|
EMAIL_HOST = email_config["EMAIL_HOST"]
|
||||||
|
EMAIL_PORT = email_config["EMAIL_PORT"]
|
||||||
|
EMAIL_BACKEND = email_config["EMAIL_BACKEND"]
|
||||||
|
EMAIL_USE_TLS = email_config["EMAIL_USE_TLS"]
|
||||||
|
EMAIL_USE_SSL = email_config["EMAIL_USE_SSL"]
|
||||||
|
|
||||||
|
# If enabled, make sure you have set proper storefront address in ALLOWED_CLIENT_HOSTS.
|
||||||
|
ENABLE_ACCOUNT_CONFIRMATION_BY_EMAIL = get_bool_from_env(
|
||||||
|
"ENABLE_ACCOUNT_CONFIRMATION_BY_EMAIL", True
|
||||||
|
)
|
||||||
|
|
||||||
|
ENABLE_SSL = get_bool_from_env("ENABLE_SSL", False)
|
||||||
|
|
||||||
|
if ENABLE_SSL:
|
||||||
|
SECURE_SSL_REDIRECT = not DEBUG
|
||||||
|
|
||||||
|
DEFAULT_FROM_EMAIL = os.environ.get("DEFAULT_FROM_EMAIL", EMAIL_HOST_USER)
|
||||||
|
|
||||||
|
MEDIA_ROOT = os.path.join(PROJECT_ROOT, "media")
|
||||||
|
MEDIA_URL = os.environ.get("MEDIA_URL", "/media/")
|
||||||
|
|
||||||
|
STATIC_ROOT = os.path.join(PROJECT_ROOT, "static")
|
||||||
|
STATIC_URL = os.environ.get("STATIC_URL", "/static/")
|
||||||
|
STATICFILES_DIRS = [
|
||||||
|
("images", os.path.join(PROJECT_ROOT, "saleor", "static", "images"))
|
||||||
|
]
|
||||||
|
STATICFILES_FINDERS = [
|
||||||
|
"django.contrib.staticfiles.finders.FileSystemFinder",
|
||||||
|
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
|
||||||
|
]
|
||||||
|
|
||||||
|
context_processors = [
|
||||||
|
"django.template.context_processors.debug",
|
||||||
|
"django.template.context_processors.media",
|
||||||
|
"django.template.context_processors.static",
|
||||||
|
"saleor.site.context_processors.site",
|
||||||
|
]
|
||||||
|
|
||||||
|
loaders = [
|
||||||
|
"django.template.loaders.filesystem.Loader",
|
||||||
|
"django.template.loaders.app_directories.Loader",
|
||||||
|
]
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
|
"DIRS": [os.path.join(PROJECT_ROOT, "templates")],
|
||||||
|
"OPTIONS": {
|
||||||
|
"debug": DEBUG,
|
||||||
|
"context_processors": context_processors,
|
||||||
|
"loaders": loaders,
|
||||||
|
"string_if_invalid": '<< MISSING VARIABLE "%s" >>' if DEBUG else "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# Read secret key from a file
|
||||||
|
with open('/etc/saleor/api_sk') as f:
|
||||||
|
SECRET_KEY = f.read().strip()
|
||||||
|
|
||||||
|
if not SECRET_KEY and DEBUG:
|
||||||
|
warnings.warn("SECRET_KEY not configured, using a random temporary key.")
|
||||||
|
SECRET_KEY = get_random_secret_key()
|
||||||
|
|
||||||
|
MIDDLEWARE = [
|
||||||
|
"django.middleware.security.SecurityMiddleware",
|
||||||
|
"django.middleware.common.CommonMiddleware",
|
||||||
|
"saleor.core.middleware.request_time",
|
||||||
|
"saleor.core.middleware.discounts",
|
||||||
|
"saleor.core.middleware.google_analytics",
|
||||||
|
"saleor.core.middleware.country",
|
||||||
|
"saleor.core.middleware.currency",
|
||||||
|
"saleor.core.middleware.site",
|
||||||
|
"saleor.core.middleware.plugins",
|
||||||
|
"saleor.core.middleware.jwt_refresh_token_middleware",
|
||||||
|
]
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
# External apps that need to go before django's
|
||||||
|
"storages",
|
||||||
|
# Django modules
|
||||||
|
"django.contrib.contenttypes",
|
||||||
|
"django.contrib.sites",
|
||||||
|
"django.contrib.staticfiles",
|
||||||
|
"django.contrib.auth",
|
||||||
|
"django.contrib.postgres",
|
||||||
|
# Local apps
|
||||||
|
"saleor.plugins",
|
||||||
|
"saleor.account",
|
||||||
|
"saleor.discount",
|
||||||
|
"saleor.giftcard",
|
||||||
|
"saleor.product",
|
||||||
|
"saleor.attribute",
|
||||||
|
"saleor.channel",
|
||||||
|
"saleor.checkout",
|
||||||
|
"saleor.core",
|
||||||
|
"saleor.csv",
|
||||||
|
"saleor.graphql",
|
||||||
|
"saleor.menu",
|
||||||
|
"saleor.order",
|
||||||
|
"saleor.invoice",
|
||||||
|
"saleor.seo",
|
||||||
|
"saleor.shipping",
|
||||||
|
"saleor.search",
|
||||||
|
"saleor.site",
|
||||||
|
"saleor.page",
|
||||||
|
"saleor.payment",
|
||||||
|
"saleor.warehouse",
|
||||||
|
"saleor.webhook",
|
||||||
|
"saleor.wishlist",
|
||||||
|
"saleor.app",
|
||||||
|
# External apps
|
||||||
|
"versatileimagefield",
|
||||||
|
"django_measurement",
|
||||||
|
"django_prices",
|
||||||
|
"django_prices_openexchangerates",
|
||||||
|
"django_prices_vatlayer",
|
||||||
|
"graphene_django",
|
||||||
|
"mptt",
|
||||||
|
"django_countries",
|
||||||
|
"django_filters",
|
||||||
|
"phonenumber_field",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
ENABLE_DEBUG_TOOLBAR = get_bool_from_env("ENABLE_DEBUG_TOOLBAR", False)
|
||||||
|
if ENABLE_DEBUG_TOOLBAR:
|
||||||
|
# Ensure the graphiql debug toolbar is actually installed before adding it
|
||||||
|
try:
|
||||||
|
__import__("graphiql_debug_toolbar")
|
||||||
|
except ImportError as exc:
|
||||||
|
msg = (
|
||||||
|
f"{exc} -- Install the missing dependencies by "
|
||||||
|
f"running `pip install -r requirements_dev.txt`"
|
||||||
|
)
|
||||||
|
warnings.warn(msg)
|
||||||
|
else:
|
||||||
|
INSTALLED_APPS += ["django.forms", "debug_toolbar", "graphiql_debug_toolbar"]
|
||||||
|
MIDDLEWARE.append("saleor.graphql.middleware.DebugToolbarMiddleware")
|
||||||
|
|
||||||
|
DEBUG_TOOLBAR_PANELS = [
|
||||||
|
"ddt_request_history.panels.request_history.RequestHistoryPanel",
|
||||||
|
"debug_toolbar.panels.timer.TimerPanel",
|
||||||
|
"debug_toolbar.panels.headers.HeadersPanel",
|
||||||
|
"debug_toolbar.panels.request.RequestPanel",
|
||||||
|
"debug_toolbar.panels.sql.SQLPanel",
|
||||||
|
"debug_toolbar.panels.profiling.ProfilingPanel",
|
||||||
|
]
|
||||||
|
DEBUG_TOOLBAR_CONFIG = {"RESULTS_CACHE_SIZE": 100}
|
||||||
|
|
||||||
|
LOGGING = {
|
||||||
|
"version": 1,
|
||||||
|
"disable_existing_loggers": False,
|
||||||
|
"root": {"level": "INFO", "handlers": ["default"]},
|
||||||
|
"formatters": {
|
||||||
|
"django.server": {
|
||||||
|
"()": "django.utils.log.ServerFormatter",
|
||||||
|
"format": "[{server_time}] {message}",
|
||||||
|
"style": "{",
|
||||||
|
},
|
||||||
|
"json": {
|
||||||
|
"()": "saleor.core.logging.JsonFormatter",
|
||||||
|
"datefmt": "%Y-%m-%dT%H:%M:%SZ",
|
||||||
|
"format": (
|
||||||
|
"%(asctime)s %(levelname)s %(lineno)s %(message)s %(name)s "
|
||||||
|
+ "%(pathname)s %(process)d %(threadName)s"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
"verbose": {
|
||||||
|
"format": (
|
||||||
|
"%(levelname)s %(name)s %(message)s [PID:%(process)d:%(threadName)s]"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"handlers": {
|
||||||
|
"default": {
|
||||||
|
"level": "DEBUG",
|
||||||
|
"class": "logging.StreamHandler",
|
||||||
|
"formatter": "verbose" if DEBUG else "json",
|
||||||
|
},
|
||||||
|
"django.server": {
|
||||||
|
"level": "INFO",
|
||||||
|
"class": "logging.StreamHandler",
|
||||||
|
"formatter": "django.server" if DEBUG else "json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"loggers": {
|
||||||
|
"django": {"level": "INFO", "propagate": True},
|
||||||
|
"django.server": {
|
||||||
|
"handlers": ["django.server"],
|
||||||
|
"level": "INFO",
|
||||||
|
"propagate": False,
|
||||||
|
},
|
||||||
|
"saleor": {"level": "DEBUG", "propagate": True},
|
||||||
|
"saleor.graphql.errors.handled": {
|
||||||
|
"handlers": ["default"],
|
||||||
|
"level": "INFO",
|
||||||
|
"propagate": False,
|
||||||
|
},
|
||||||
|
"graphql.execution.utils": {"propagate": False},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
AUTH_USER_MODEL = "account.User"
|
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
{
|
||||||
|
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||||
|
"OPTIONS": {"min_length": 8},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
DEFAULT_COUNTRY = os.environ.get("DEFAULT_COUNTRY", "US")
|
||||||
|
DEFAULT_CURRENCY = os.environ.get("DEFAULT_CURRENCY", "USD")
|
||||||
|
DEFAULT_DECIMAL_PLACES = 3
|
||||||
|
DEFAULT_MAX_DIGITS = 12
|
||||||
|
DEFAULT_CURRENCY_CODE_LENGTH = 3
|
||||||
|
|
||||||
|
# The default max length for the display name of the
|
||||||
|
# sender email address.
|
||||||
|
# Following the recommendation of https://tools.ietf.org/html/rfc5322#section-2.1.1
|
||||||
|
DEFAULT_MAX_EMAIL_DISPLAY_NAME_LENGTH = 78
|
||||||
|
|
||||||
|
COUNTRIES_OVERRIDE = {"EU": "European Union"}
|
||||||
|
|
||||||
|
OPENEXCHANGERATES_API_KEY = os.environ.get("OPENEXCHANGERATES_API_KEY")
|
||||||
|
|
||||||
|
GOOGLE_ANALYTICS_TRACKING_ID = os.environ.get("GOOGLE_ANALYTICS_TRACKING_ID")
|
||||||
|
|
||||||
|
|
||||||
|
def get_host():
|
||||||
|
from django.contrib.sites.models import Site
|
||||||
|
|
||||||
|
return Site.objects.get_current().domain
|
||||||
|
|
||||||
|
|
||||||
|
PAYMENT_HOST = get_host
|
||||||
|
|
||||||
|
PAYMENT_MODEL = "order.Payment"
|
||||||
|
|
||||||
|
MAX_CHECKOUT_LINE_QUANTITY = int(os.environ.get("MAX_CHECKOUT_LINE_QUANTITY", 50))
|
||||||
|
|
||||||
|
TEST_RUNNER = "saleor.tests.runner.PytestTestRunner"
|
||||||
|
|
||||||
|
|
||||||
|
PLAYGROUND_ENABLED = get_bool_from_env("PLAYGROUND_ENABLED", True)
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = get_list(os.environ.get("ALLOWED_HOSTS", "localhost,127.0.0.1"))
|
||||||
|
ALLOWED_GRAPHQL_ORIGINS = get_list(os.environ.get("ALLOWED_GRAPHQL_ORIGINS", "*"))
|
||||||
|
|
||||||
|
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
||||||
|
|
||||||
|
# Amazon S3 configuration
|
||||||
|
# See https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html
|
||||||
|
AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID")
|
||||||
|
AWS_LOCATION = os.environ.get("AWS_LOCATION", "")
|
||||||
|
AWS_MEDIA_BUCKET_NAME = os.environ.get("AWS_MEDIA_BUCKET_NAME")
|
||||||
|
AWS_MEDIA_CUSTOM_DOMAIN = os.environ.get("AWS_MEDIA_CUSTOM_DOMAIN")
|
||||||
|
AWS_QUERYSTRING_AUTH = get_bool_from_env("AWS_QUERYSTRING_AUTH", False)
|
||||||
|
AWS_QUERYSTRING_EXPIRE = get_bool_from_env("AWS_QUERYSTRING_EXPIRE", 3600)
|
||||||
|
AWS_S3_CUSTOM_DOMAIN = os.environ.get("AWS_STATIC_CUSTOM_DOMAIN")
|
||||||
|
AWS_S3_ENDPOINT_URL = os.environ.get("AWS_S3_ENDPOINT_URL", None)
|
||||||
|
AWS_S3_REGION_NAME = os.environ.get("AWS_S3_REGION_NAME", None)
|
||||||
|
AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY")
|
||||||
|
AWS_STORAGE_BUCKET_NAME = os.environ.get("AWS_STORAGE_BUCKET_NAME")
|
||||||
|
AWS_DEFAULT_ACL = os.environ.get("AWS_DEFAULT_ACL", None)
|
||||||
|
|
||||||
|
# Google Cloud Storage configuration
|
||||||
|
GS_PROJECT_ID = os.environ.get("GS_PROJECT_ID")
|
||||||
|
GS_STORAGE_BUCKET_NAME = os.environ.get("GS_STORAGE_BUCKET_NAME")
|
||||||
|
GS_MEDIA_BUCKET_NAME = os.environ.get("GS_MEDIA_BUCKET_NAME")
|
||||||
|
GS_AUTO_CREATE_BUCKET = get_bool_from_env("GS_AUTO_CREATE_BUCKET", False)
|
||||||
|
GS_QUERYSTRING_AUTH = get_bool_from_env("GS_QUERYSTRING_AUTH", False)
|
||||||
|
GS_DEFAULT_ACL = os.environ.get("GS_DEFAULT_ACL", None)
|
||||||
|
GS_MEDIA_CUSTOM_ENDPOINT = os.environ.get("GS_MEDIA_CUSTOM_ENDPOINT", None)
|
||||||
|
GS_EXPIRATION = os.environ.get("GS_EXPIRATION", None)
|
||||||
|
|
||||||
|
# If GOOGLE_APPLICATION_CREDENTIALS is set there is no need to load OAuth token
|
||||||
|
# See https://django-storages.readthedocs.io/en/latest/backends/gcloud.html
|
||||||
|
if "GOOGLE_APPLICATION_CREDENTIALS" not in os.environ:
|
||||||
|
GS_CREDENTIALS = os.environ.get("GS_CREDENTIALS")
|
||||||
|
|
||||||
|
if AWS_STORAGE_BUCKET_NAME:
|
||||||
|
STATICFILES_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
|
||||||
|
elif GS_STORAGE_BUCKET_NAME:
|
||||||
|
STATICFILES_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
|
||||||
|
|
||||||
|
if AWS_MEDIA_BUCKET_NAME:
|
||||||
|
DEFAULT_FILE_STORAGE = "saleor.core.storages.S3MediaStorage"
|
||||||
|
THUMBNAIL_DEFAULT_STORAGE = DEFAULT_FILE_STORAGE
|
||||||
|
elif GS_MEDIA_BUCKET_NAME:
|
||||||
|
DEFAULT_FILE_STORAGE = "saleor.core.storages.GCSMediaStorage"
|
||||||
|
THUMBNAIL_DEFAULT_STORAGE = DEFAULT_FILE_STORAGE
|
||||||
|
|
||||||
|
VERSATILEIMAGEFIELD_RENDITION_KEY_SETS = {
|
||||||
|
"products": [
|
||||||
|
("product_gallery", "thumbnail__540x540"),
|
||||||
|
("product_gallery_2x", "thumbnail__1080x1080"),
|
||||||
|
("product_small", "thumbnail__60x60"),
|
||||||
|
("product_small_2x", "thumbnail__120x120"),
|
||||||
|
("product_list", "thumbnail__255x255"),
|
||||||
|
("product_list_2x", "thumbnail__510x510"),
|
||||||
|
],
|
||||||
|
"background_images": [("header_image", "thumbnail__1080x440")],
|
||||||
|
"user_avatars": [("default", "thumbnail__445x445")],
|
||||||
|
}
|
||||||
|
|
||||||
|
VERSATILEIMAGEFIELD_SETTINGS = {
|
||||||
|
# Images should be pre-generated on Production environment
|
||||||
|
"create_images_on_demand": get_bool_from_env("CREATE_IMAGES_ON_DEMAND", DEBUG)
|
||||||
|
}
|
||||||
|
|
||||||
|
PLACEHOLDER_IMAGES = {
|
||||||
|
60: "images/placeholder60x60.png",
|
||||||
|
120: "images/placeholder120x120.png",
|
||||||
|
255: "images/placeholder255x255.png",
|
||||||
|
540: "images/placeholder540x540.png",
|
||||||
|
1080: "images/placeholder1080x1080.png",
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULT_PLACEHOLDER = "images/placeholder255x255.png"
|
||||||
|
|
||||||
|
SEARCH_BACKEND = "saleor.search.backends.postgresql"
|
||||||
|
|
||||||
|
AUTHENTICATION_BACKENDS = [
|
||||||
|
"saleor.core.auth_backend.JSONWebTokenBackend",
|
||||||
|
]
|
||||||
|
|
||||||
|
# CELERY SETTINGS
|
||||||
|
CELERY_TIMEZONE = TIME_ZONE
|
||||||
|
CELERY_BROKER_URL = (
|
||||||
|
os.environ.get("CELERY_BROKER_URL", os.environ.get("CLOUDAMQP_URL")) or ""
|
||||||
|
)
|
||||||
|
CELERY_TASK_ALWAYS_EAGER = not CELERY_BROKER_URL
|
||||||
|
CELERY_ACCEPT_CONTENT = ["json"]
|
||||||
|
CELERY_TASK_SERIALIZER = "json"
|
||||||
|
CELERY_RESULT_SERIALIZER = "json"
|
||||||
|
CELERY_RESULT_BACKEND = os.environ.get("CELERY_RESULT_BACKEND", None)
|
||||||
|
|
||||||
|
# Change this value if your application is running behind a proxy,
|
||||||
|
# e.g. HTTP_CF_Connecting_IP for Cloudflare or X_FORWARDED_FOR
|
||||||
|
REAL_IP_ENVIRON = os.environ.get("REAL_IP_ENVIRON", "REMOTE_ADDR")
|
||||||
|
|
||||||
|
# Slugs for menus precreated in Django migrations
|
||||||
|
DEFAULT_MENUS = {"top_menu_name": "navbar", "bottom_menu_name": "footer"}
|
||||||
|
|
||||||
|
# Slug for channel precreated in Django migrations
|
||||||
|
DEFAULT_CHANNEL_SLUG = os.environ.get("DEFAULT_CHANNEL_SLUG", "default-channel")
|
||||||
|
|
||||||
|
|
||||||
|
# Sentry
|
||||||
|
sentry_sdk.utils.MAX_STRING_LENGTH = 4096
|
||||||
|
SENTRY_DSN = os.environ.get("SENTRY_DSN")
|
||||||
|
if SENTRY_DSN:
|
||||||
|
sentry_sdk.init(
|
||||||
|
dsn=SENTRY_DSN, integrations=[CeleryIntegration(), DjangoIntegration()]
|
||||||
|
)
|
||||||
|
|
||||||
|
GRAPHENE = {
|
||||||
|
"RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST": True,
|
||||||
|
"RELAY_CONNECTION_MAX_LIMIT": 100,
|
||||||
|
"MIDDLEWARE": [
|
||||||
|
"saleor.graphql.middleware.OpentracingGrapheneMiddleware",
|
||||||
|
"saleor.graphql.middleware.JWTMiddleware",
|
||||||
|
"saleor.graphql.middleware.app_middleware",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
PLUGINS_MANAGER = "saleor.plugins.manager.PluginsManager"
|
||||||
|
|
||||||
|
PLUGINS = [
|
||||||
|
"saleor.plugins.avatax.plugin.AvataxPlugin",
|
||||||
|
"saleor.plugins.vatlayer.plugin.VatlayerPlugin",
|
||||||
|
"saleor.plugins.webhook.plugin.WebhookPlugin",
|
||||||
|
"saleor.payment.gateways.dummy.plugin.DummyGatewayPlugin",
|
||||||
|
"saleor.payment.gateways.dummy_credit_card.plugin.DummyCreditCardGatewayPlugin",
|
||||||
|
"saleor.payment.gateways.stripe.plugin.StripeGatewayPlugin",
|
||||||
|
"saleor.payment.gateways.braintree.plugin.BraintreeGatewayPlugin",
|
||||||
|
"saleor.payment.gateways.razorpay.plugin.RazorpayGatewayPlugin",
|
||||||
|
"saleor.payment.gateways.adyen.plugin.AdyenGatewayPlugin",
|
||||||
|
"saleor.payment.gateways.authorize_net.plugin.AuthorizeNetGatewayPlugin",
|
||||||
|
"saleor.plugins.invoicing.plugin.InvoicingPlugin",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Plugin discovery
|
||||||
|
installed_plugins = pkg_resources.iter_entry_points("saleor.plugins")
|
||||||
|
for entry_point in installed_plugins:
|
||||||
|
plugin_path = "{}.{}".format(entry_point.module_name, entry_point.attrs[0])
|
||||||
|
if plugin_path not in PLUGINS:
|
||||||
|
if entry_point.name not in INSTALLED_APPS:
|
||||||
|
INSTALLED_APPS.append(entry_point.name)
|
||||||
|
PLUGINS.append(plugin_path)
|
||||||
|
|
||||||
|
if (
|
||||||
|
not DEBUG
|
||||||
|
and ENABLE_ACCOUNT_CONFIRMATION_BY_EMAIL
|
||||||
|
and ALLOWED_CLIENT_HOSTS == get_list(_DEFAULT_CLIENT_HOSTS)
|
||||||
|
):
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"Make sure you've added storefront address to ALLOWED_CLIENT_HOSTS "
|
||||||
|
"if ENABLE_ACCOUNT_CONFIRMATION_BY_EMAIL is enabled."
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initialize a simple and basic Jaeger Tracing integration
|
||||||
|
# for open-tracing if enabled.
|
||||||
|
#
|
||||||
|
# Refer to our guide on https://docs.saleor.io/docs/next/guides/opentracing-jaeger/.
|
||||||
|
#
|
||||||
|
# If running locally, set:
|
||||||
|
# JAEGER_AGENT_HOST=localhost
|
||||||
|
if "JAEGER_AGENT_HOST" in os.environ:
|
||||||
|
jaeger_client.Config(
|
||||||
|
config={
|
||||||
|
"sampler": {"type": "const", "param": 1},
|
||||||
|
"local_agent": {
|
||||||
|
"reporting_port": os.environ.get(
|
||||||
|
"JAEGER_AGENT_PORT", jaeger_client.config.DEFAULT_REPORTING_PORT
|
||||||
|
),
|
||||||
|
"reporting_host": os.environ.get("JAEGER_AGENT_HOST"),
|
||||||
|
},
|
||||||
|
"logging": get_bool_from_env("JAEGER_LOGGING", False),
|
||||||
|
},
|
||||||
|
service_name="saleor",
|
||||||
|
validate=True,
|
||||||
|
).initialize_tracer()
|
||||||
|
|
||||||
|
|
||||||
|
# Some cloud providers (Heroku) export REDIS_URL variable instead of CACHE_URL
|
||||||
|
REDIS_URL = os.environ.get("REDIS_URL")
|
||||||
|
if REDIS_URL:
|
||||||
|
CACHE_URL = os.environ.setdefault("CACHE_URL", REDIS_URL)
|
||||||
|
CACHES = {"default": django_cache_url.config()}
|
||||||
|
|
||||||
|
# Default False because storefront and dashboard don't support expiration of token
|
||||||
|
JWT_EXPIRE = get_bool_from_env("JWT_EXPIRE", False)
|
||||||
|
JWT_TTL_ACCESS = timedelta(seconds=parse(os.environ.get("JWT_TTL_ACCESS", "5 minutes")))
|
||||||
|
JWT_TTL_APP_ACCESS = timedelta(
|
||||||
|
seconds=parse(os.environ.get("JWT_TTL_APP_ACCESS", "5 minutes"))
|
||||||
|
)
|
||||||
|
JWT_TTL_REFRESH = timedelta(seconds=parse(os.environ.get("JWT_TTL_REFRESH", "30 days")))
|
||||||
|
|
||||||
|
|
||||||
|
JWT_TTL_REQUEST_EMAIL_CHANGE = timedelta(
|
||||||
|
seconds=parse(os.environ.get("JWT_TTL_REQUEST_EMAIL_CHANGE", "1 hour")),
|
||||||
|
)
|
|
@ -22,5 +22,6 @@ MEDIA_URL="{media}"
|
||||||
|
|
||||||
#OPENEXCHANGERATES_API_KEY="{openxkey}"
|
#OPENEXCHANGERATES_API_KEY="{openxkey}"
|
||||||
#GOOGLE_ANALYTICS_TRACKING_ID="{gatid}"
|
#GOOGLE_ANALYTICS_TRACKING_ID="{gatid}"
|
||||||
|
ADMIN_EMAIL="{adminemail}"
|
||||||
|
|
||||||
DEBUG=False
|
DEBUG=False
|
Loading…
Reference in a new issue