diff --git a/api/directory_watcher.py b/api/directory_watcher.py index 5cff3a551b..d9a8452e08 100644 --- a/api/directory_watcher.py +++ b/api/directory_watcher.py @@ -6,13 +6,13 @@ import pytz from constance import config as site_config from django import db +from django.conf import settings from django.core.paginator import Paginator from django.db.models import Q, QuerySet from django_q.tasks import AsyncTask import api.models.album_thing import api.util as util -import ownphotos.settings from api.batch_jobs import create_batch_job from api.face_classify import cluster_all_faces from api.models import File, LongRunningJob, Photo @@ -332,12 +332,10 @@ def photo_scanner(user, last_scan, full_scan, path, job_id): def scan_photos(user, full_scan, job_id, scan_directory="", scan_files=[]): - if not os.path.exists( - os.path.join(ownphotos.settings.MEDIA_ROOT, "thumbnails_big") - ): - os.mkdir(os.path.join(ownphotos.settings.MEDIA_ROOT, "square_thumbnails_small")) - os.mkdir(os.path.join(ownphotos.settings.MEDIA_ROOT, "square_thumbnails")) - os.mkdir(os.path.join(ownphotos.settings.MEDIA_ROOT, "thumbnails_big")) + if not os.path.exists(os.path.join(settings.MEDIA_ROOT, "thumbnails_big")): + os.mkdir(os.path.join(settings.MEDIA_ROOT, "square_thumbnails_small")) + os.mkdir(os.path.join(settings.MEDIA_ROOT, "square_thumbnails")) + os.mkdir(os.path.join(settings.MEDIA_ROOT, "thumbnails_big")) if LongRunningJob.objects.filter(job_id=job_id).exists(): lrj = LongRunningJob.objects.get(job_id=job_id) lrj.started_at = datetime.datetime.now().replace(tzinfo=pytz.utc) diff --git a/api/im2txt/sample.py b/api/im2txt/sample.py index 000aed11f6..528d5f5fd1 100644 --- a/api/im2txt/sample.py +++ b/api/im2txt/sample.py @@ -3,16 +3,16 @@ # import matplotlib.pyplot as plt import torch +from django.conf import settings from PIL import Image from torchvision import transforms -import ownphotos.settings from api.im2txt.model import DecoderRNN, EncoderCNN embed_size = 256 hidden_size = 512 num_layers = 1 -im2txt_models_path = ownphotos.settings.IM2TXT_ROOT +im2txt_models_path = settings.IM2TXT_ROOT encoder_path = os.path.join(im2txt_models_path, "models", "encoder-10-1000.ckpt") decoder_path = os.path.join(im2txt_models_path, "models", "decoder-10-1000.ckpt") diff --git a/api/image_similarity.py b/api/image_similarity.py index 2cdd9235ac..6fa58d01fa 100644 --- a/api/image_similarity.py +++ b/api/image_similarity.py @@ -2,12 +2,12 @@ import numpy as np import requests +from django.conf import settings from django.core.paginator import Paginator from django.db.models import Q from api.models import Photo from api.util import logger -from ownphotos.settings import IMAGE_SIMILARITY_SERVER def search_similar_embedding(user, emb, result_count=100, threshold=27): @@ -24,7 +24,7 @@ def search_similar_embedding(user, emb, result_count=100, threshold=27): "n": result_count, "threshold": threshold, } - res = requests.post(IMAGE_SIMILARITY_SERVER + "/search/", json=post_data) + res = requests.post(settings.IMAGE_SIMILARITY_SERVER + "/search/", json=post_data) if res.status_code == 200: return res.json()["result"] else: @@ -48,7 +48,7 @@ def search_similar_image(user, photo, threshold=27): "image_embedding": image_embedding.tolist(), "threshold": threshold, } - res = requests.post(IMAGE_SIMILARITY_SERVER + "/search/", json=post_data) + res = requests.post(settings.IMAGE_SIMILARITY_SERVER + "/search/", json=post_data) if res.status_code == 200: return res.json() else: @@ -85,6 +85,6 @@ def build_image_similarity_index(user): "image_hashes": image_hashes, "image_embeddings": image_embeddings, } - requests.post(IMAGE_SIMILARITY_SERVER + "/build/", json=post_data) + requests.post(settings.IMAGE_SIMILARITY_SERVER + "/build/", json=post_data) elapsed = (datetime.now() - start).total_seconds() logger.info("building similarity index took %.2f seconds" % elapsed) diff --git a/api/models/user.py b/api/models/user.py index 8255cf714f..f26e9a8f8a 100644 --- a/api/models/user.py +++ b/api/models/user.py @@ -1,9 +1,9 @@ import pytz +from django.conf import settings from django.contrib.auth.models import AbstractUser from django.db import models from django_cryptography.fields import encrypt -import ownphotos.settings from api.date_time_extractor import DEFAULT_RULES_JSON @@ -29,7 +29,7 @@ class User(AbstractUser): ) favorite_min_rating = models.IntegerField( - default=ownphotos.settings.DEFAULT_FAVORITE_MIN_RATING, db_index=True + default=settings.DEFAULT_FAVORITE_MIN_RATING, db_index=True ) class SaveMetadata(models.TextChoices): diff --git a/api/places365/places365.py b/api/places365/places365.py index 1a0bec44e2..4cf7095ef8 100644 --- a/api/places365/places365.py +++ b/api/places365/places365.py @@ -5,19 +5,19 @@ import numpy as np import torch +from django.conf import settings from PIL import Image from torch.autograd import Variable as V from torch.nn import functional as F from torchvision import transforms as trn -import ownphotos.settings import wideresnet from api.util import logger # import warnings torch.nn.Module.dump_patches = True -dir_places365_model = ownphotos.settings.PLACES365_ROOT +dir_places365_model = settings.PLACES365_ROOT class Places365: diff --git a/api/semantic_search/semantic_search.py b/api/semantic_search/semantic_search.py index 88ad519adc..eaf8567d4b 100644 --- a/api/semantic_search/semantic_search.py +++ b/api/semantic_search/semantic_search.py @@ -2,12 +2,12 @@ import numpy as np import PIL +from django.conf import settings from sentence_transformers import SentenceTransformer -import ownphotos from api.util import logger -dir_clip_ViT_B_32_model = ownphotos.settings.CLIP_ROOT +dir_clip_ViT_B_32_model = settings.CLIP_ROOT class SemanticSearch: diff --git a/api/thumbnails.py b/api/thumbnails.py index cd2d6d788f..510b6da851 100644 --- a/api/thumbnails.py +++ b/api/thumbnails.py @@ -3,9 +3,9 @@ import pyvips import requests +from django.conf import settings import api.util as util -import ownphotos.settings from api.models.file import is_raw @@ -14,7 +14,7 @@ def createThumbnail(inputPath, outputHeight, outputPath, hash, fileType): if is_raw(inputPath): if "thumbnails_big" in outputPath: completePath = os.path.join( - ownphotos.settings.MEDIA_ROOT, outputPath, hash + fileType + settings.MEDIA_ROOT, outputPath, hash + fileType ).strip() json = { "source": inputPath, @@ -25,7 +25,7 @@ def createThumbnail(inputPath, outputHeight, outputPath, hash, fileType): return response["thumbnail"] else: bigThumbnailPath = os.path.join( - ownphotos.settings.MEDIA_ROOT, "thumbnails_big", hash + fileType + settings.MEDIA_ROOT, "thumbnails_big", hash + fileType ) x = pyvips.Image.thumbnail( bigThumbnailPath, @@ -34,7 +34,7 @@ def createThumbnail(inputPath, outputHeight, outputPath, hash, fileType): size=pyvips.enums.Size.DOWN, ) completePath = os.path.join( - ownphotos.settings.MEDIA_ROOT, outputPath, hash + fileType + settings.MEDIA_ROOT, outputPath, hash + fileType ).strip() x.write_to_file(completePath, Q=95) return completePath @@ -43,7 +43,7 @@ def createThumbnail(inputPath, outputHeight, outputPath, hash, fileType): inputPath, 10000, height=outputHeight, size=pyvips.enums.Size.DOWN ) completePath = os.path.join( - ownphotos.settings.MEDIA_ROOT, outputPath, hash + fileType + settings.MEDIA_ROOT, outputPath, hash + fileType ).strip() x.write_to_file(completePath) return completePath @@ -54,9 +54,7 @@ def createThumbnail(inputPath, outputHeight, outputPath, hash, fileType): def createAnimatedThumbnail(inputPath, outputHeight, outputPath, hash, fileType): try: - output = os.path.join( - ownphotos.settings.MEDIA_ROOT, outputPath, hash + fileType - ).strip() + output = os.path.join(settings.MEDIA_ROOT, outputPath, hash + fileType).strip() subprocess.call( [ "ffmpeg", @@ -92,9 +90,7 @@ def createThumbnailForVideo(inputPath, outputPath, hash, fileType): "00:00:00.000", "-vframes", "1", - os.path.join( - ownphotos.settings.MEDIA_ROOT, outputPath, hash + fileType - ).strip(), + os.path.join(settings.MEDIA_ROOT, outputPath, hash + fileType).strip(), ] ) except Exception as e: @@ -106,11 +102,11 @@ def createThumbnailForVideo(inputPath, outputPath, hash, fileType): def doesStaticThumbnailExists(outputPath, hash): return os.path.exists( - os.path.join(ownphotos.settings.MEDIA_ROOT, outputPath, hash + ".webp").strip() + os.path.join(settings.MEDIA_ROOT, outputPath, hash + ".webp").strip() ) def doesVideoThumbnailExists(outputPath, hash): return os.path.exists( - os.path.join(ownphotos.settings.MEDIA_ROOT, outputPath, hash + ".mp4").strip() + os.path.join(settings.MEDIA_ROOT, outputPath, hash + ".mp4").strip() ) diff --git a/api/util.py b/api/util.py index fc34f11291..dc2de30cea 100644 --- a/api/util.py +++ b/api/util.py @@ -1,4 +1,3 @@ -import logging import logging.handlers import os import os.path @@ -6,8 +5,7 @@ import exiftool import requests from constance import config as site_config - -import ownphotos.settings +from django.conf import settings logger = logging.getLogger("ownphotos") formatter = logging.Formatter( @@ -15,7 +13,7 @@ ) fileMaxByte = 256 * 1024 * 200 # 100MB fileHandler = logging.handlers.RotatingFileHandler( - os.path.join(ownphotos.settings.LOGS_ROOT, "ownphotos.log"), + os.path.join(settings.LOGS_ROOT, "ownphotos.log"), maxBytes=fileMaxByte, backupCount=10, ) diff --git a/api/views/user.py b/api/views/user.py index 4c617b1108..f20f89e513 100644 --- a/api/views/user.py +++ b/api/views/user.py @@ -1,9 +1,9 @@ +from django.conf import settings from rest_framework import status, viewsets from rest_framework.permissions import AllowAny, IsAdminUser from rest_framework.response import Response from rest_framework.views import APIView -import ownphotos.settings from api.api_util import path_to_dict from api.date_time_extractor import DEFAULT_RULES_JSON, PREDEFINED_RULES_JSON from api.models import User @@ -39,7 +39,7 @@ def get(self, request, format=None): if path: res = [path_to_dict(path)] else: - res = [path_to_dict(ownphotos.settings.DATA_ROOT)] + res = [path_to_dict(settings.DATA_ROOT)] return Response(res) except Exception as e: logger.exception(str(e)) diff --git a/api/views/views.py b/api/views/views.py index 789fd43adb..aceca6f4c2 100644 --- a/api/views/views.py +++ b/api/views/views.py @@ -8,6 +8,7 @@ import jsonschema import magic from constance import config as site_config +from django.conf import settings from django.db.models import Q from django.http import HttpResponse, HttpResponseForbidden, StreamingHttpResponse from django.utils.decorators import method_decorator @@ -22,7 +23,6 @@ from rest_framework_simplejwt.exceptions import TokenError from rest_framework_simplejwt.tokens import AccessToken -import ownphotos.settings from api.api_util import get_search_term_examples from api.autoalbum import delete_missing_photos from api.directory_watcher import scan_photos @@ -364,9 +364,7 @@ def _generate_response(self, photo, path, fname, transcode_videos): response = HttpResponse() response["Content-Type"] = filename response["X-Accel-Redirect"] = iri_to_uri( - photo.main_file.path.replace( - ownphotos.settings.DATA_ROOT, "/original" - ) + photo.main_file.path.replace(settings.DATA_ROOT, "/original") ) return response # faces and avatars diff --git a/librephotos/__init__.py b/librephotos/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/librephotos/settings/__init__.py b/librephotos/settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/librephotos/settings/development.py b/librephotos/settings/development.py new file mode 100644 index 0000000000..39cae9f3ab --- /dev/null +++ b/librephotos/settings/development.py @@ -0,0 +1,11 @@ +from .production import * # noqa + +DEBUG = True +MIDDLEWARE += ["silk.middleware.SilkyMiddleware"] # noqa +INSTALLED_APPS += ["silk"] # noqa +INSTALLED_APPS += ["drf_spectacular"] +SPECTACULAR_SETTINGS = { + "TITLE": "LibrePhotos", + "DESCRIPTION": "Your project description", + "VERSION": "1.0.0", +} diff --git a/ownphotos/settings.py b/librephotos/settings/production.py similarity index 75% rename from ownphotos/settings.py rename to librephotos/settings/production.py index 341b51476f..b6dc138f89 100644 --- a/ownphotos/settings.py +++ b/librephotos/settings/production.py @@ -1,77 +1,53 @@ -""" -Django settings for ownphotos project. - -Generated by 'django-admin startproject' using Django 1.11.2. - -For more information on this file, see -https://docs.djangoproject.com/en/1.11/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/1.11/ref/settings/ -""" import datetime import os -for envvar in ( - "SECRET_KEY", - "BACKEND_HOST", - "DB_BACKEND", - "DB_NAME", - "DB_USER", - "DB_PASS", - "DB_HOST", - "DB_PORT", -): - if envvar not in os.environ: - raise NameError("Environment variable not set :" + envvar) - -DEFAULT_AUTO_FIELD='django.db.models.AutoField' - -# Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +BASE_LOGS = os.environ.get("BASE_LOGS", "/logs/") +BASE_DATA = os.environ.get("BASE_DATA", "/") +PHOTOS = os.environ.get("PHOTOS", os.path.join(BASE_DATA, "data")) +STATIC_URL = "api/static/" +MEDIA_URL = "/media/" +MEDIA_ROOT = os.path.join(BASE_DATA, "protected_media") +STATIC_ROOT = os.path.join(BASE_DIR, "static") +DATA_ROOT = PHOTOS +IM2TXT_ROOT = os.path.join(BASE_DATA, "data_models", "im2txt") +PLACES365_ROOT = os.path.join(BASE_DATA, "data_models", "places365", "model") +CLIP_ROOT = os.path.join(BASE_DATA, "data_models", "clip-embeddings") +LOGS_ROOT = BASE_LOGS -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ +WSGI_APPLICATION = "librephotos.wsgi.application" +AUTH_USER_MODEL = "api.User" +ROOT_URLCONF = "librephotos.urls" +DEFAULT_AUTO_FIELD = "django.db.models.AutoField" +DEBUG = False -# SECURITY WARNING: keep the secret key used in production secret! -BASE_LOGS = os.environ.get("BASE_LOGS", "/logs/") SECRET_KEY = "" if os.environ.get("SECRET_KEY"): SECRET_KEY = os.environ["SECRET_KEY"] print("use SECRET_KEY from env") + if not SECRET_KEY and os.path.exists(os.path.join(BASE_LOGS, "secret.key")): - # get secret key from log/secret.key with open(os.path.join(BASE_LOGS, "secret.key"), "r") as f: SECRET_KEY = f.read().strip() print("use SECRET_KEY from file") + if not SECRET_KEY: - # generate secret key and save it to log/secret.key from django.core.management.utils import get_random_secret_key - # save to log/secret.key with open(os.path.join(BASE_LOGS, "secret.key"), "w") as f: f.write(get_random_secret_key()) print("generate SECRET_KEY and save to file") - # read from log/secret.key with open(os.path.join(BASE_LOGS, "secret.key"), "r") as f: SECRET_KEY = f.read().strip() print("use SECRET_KEY from file") -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = os.environ.get("DEBUG", "") == "1" - -ALLOWED_HOSTS = ["backend", "localhost", os.environ.get("BACKEND_HOST")] - -AUTH_USER_MODEL = "api.User" +ALLOWED_HOSTS = ["localhost", os.environ.get("BACKEND_HOST", "backend")] SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": datetime.timedelta(minutes=5), - # 'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=60), "REFRESH_TOKEN_LIFETIME": datetime.timedelta(days=7), } -# Application definition - INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", @@ -91,7 +67,6 @@ "django_q", ] - # Must be less or equal of nb core CPU ( Nearly 2GB per process) HEAVYWEIGHT_PROCESS_ENV = os.environ.get("HEAVYWEIGHT_PROCESS", "1") HEAVYWEIGHT_PROCESS = ( @@ -108,8 +83,6 @@ } CONSTANCE_BACKEND = "constance.backends.database.DatabaseBackend" - - CONSTANCE_ADDITIONAL_FIELDS = { "map_api_provider": [ "django.forms.fields.ChoiceField", @@ -168,7 +141,8 @@ "x-csrftoken", "x-requested-with", ) - +CORS_ALLOW_ALL_ORIGINS = False +CORS_ALLOW_CREDENTIALS = True CORS_ALLOWED_ORIGINS = ("http://localhost:3000", "http://192.168.1.100:3000") REST_FRAMEWORK = { @@ -184,7 +158,6 @@ "EXCEPTION_HANDLER": "api.views.views.custom_exception_handler", "PAGE_SIZE": 20000, } - REST_FRAMEWORK_EXTENSIONS = { "DEFAULT_OBJECT_CACHE_KEY_FUNC": "rest_framework_extensions.utils.default_object_cache_key_func", "DEFAULT_LIST_CACHE_KEY_FUNC": "rest_framework_extensions.utils.default_list_cache_key_func", @@ -202,18 +175,6 @@ "api.middleware.FingerPrintMiddleware", ] -if DEBUG: - MIDDLEWARE += ["silk.middleware.SilkyMiddleware"] - INSTALLED_APPS += ["silk"] - INSTALLED_APPS += ["drf_spectacular"] - SPECTACULAR_SETTINGS = { - "TITLE": "LibrePhotos", - "DESCRIPTION": "Your project description", - "VERSION": "1.0.0", - } - -ROOT_URLCONF = "ownphotos.urls" - TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", @@ -230,25 +191,17 @@ }, ] -WSGI_APPLICATION = "ownphotos.wsgi.application" - -# Database -# https://docs.djangoproject.com/en/1.11/ref/settings/#databases - DATABASES = { "default": { - "ENGINE": "django.db.backends." + os.environ["DB_BACKEND"], - "NAME": os.environ["DB_NAME"], - "USER": os.environ["DB_USER"], - "PASSWORD": os.environ["DB_PASS"], - "HOST": os.environ["DB_HOST"], - "PORT": os.environ["DB_PORT"], + "ENGINE": "django.db.backends.postgresql", + "NAME": os.environ.get("DB_NAME", "db"), + "USER": os.environ.get("DB_USER", "docker"), + "PASSWORD": os.environ.get("DB_PASS", "AaAa1234"), + "HOST": os.environ.get("DB_HOST", "db"), + "PORT": "5432", }, } -# Password validation -# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators - AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", @@ -264,49 +217,15 @@ }, ] -# Internationalization -# https://docs.djangoproject.com/en/1.11/topics/i18n/ - LANGUAGE_CODE = "en-us" - TIME_ZONE = "UTC" - USE_I18N = True - USE_L10N = True - USE_TZ = True -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/1.11/howto/static-files/ - -# Allow to define data folder like /var/lib/librephotos - -BASE_DATA = os.environ.get("BASE_DATA", "/") -PHOTOS = os.environ.get("PHOTOS", os.path.join(BASE_DATA, "data")) -STATIC_URL = "api/static/" -MEDIA_URL = "/media/" -MEDIA_ROOT = os.path.join(BASE_DATA, "protected_media") -STATIC_ROOT = os.path.join(BASE_DIR, "static") -DATA_ROOT = PHOTOS -IM2TXT_ROOT = os.path.join(BASE_DATA, "data_models", "im2txt") -PLACES365_ROOT = os.path.join(BASE_DATA, "data_models", "places365", "model") -CLIP_ROOT = os.path.join(BASE_DATA, "data_models", "clip-embeddings") -LOGS_ROOT = BASE_LOGS - -CHUNKED_UPLOAD_PATH = "" -CHUNKED_UPLOAD_TO = os.path.join("chunked_uploads") - -DEFAULT_FAVORITE_MIN_RATING = os.environ.get("DEFAULT_FAVORITE_MIN_RATING", 4) -CORS_ALLOW_ALL_ORIGINS = False -CORS_ALLOW_CREDENTIALS = True - -IMAGE_SIMILARITY_SERVER = "http://localhost:8002" - CSRF_TRUSTED_ORIGINS = [ "http://localhost:3000", ] - if os.environ.get("CSRF_TRUSTED_ORIGINS"): CSRF_TRUSTED_ORIGINS.append(os.environ.get("CSRF_TRUSTED_ORIGINS")) @@ -325,3 +244,9 @@ }, }, } + +CHUNKED_UPLOAD_PATH = "" +CHUNKED_UPLOAD_TO = os.path.join("chunked_uploads") + +DEFAULT_FAVORITE_MIN_RATING = os.environ.get("DEFAULT_FAVORITE_MIN_RATING", 4) +IMAGE_SIMILARITY_SERVER = "http://localhost:8002" diff --git a/librephotos/settings/test.py b/librephotos/settings/test.py new file mode 100644 index 0000000000..9577f5df67 --- /dev/null +++ b/librephotos/settings/test.py @@ -0,0 +1,3 @@ +from .production import * # noqa + +DEBUG = True diff --git a/ownphotos/urls.py b/librephotos/urls.py similarity index 99% rename from ownphotos/urls.py rename to librephotos/urls.py index b5d4fba123..d8ff7adfbc 100644 --- a/ownphotos/urls.py +++ b/librephotos/urls.py @@ -1,4 +1,4 @@ -"""ownphotos URL Configuration +"""librephotos URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ diff --git a/librephotos/wsgi.py b/librephotos/wsgi.py new file mode 100644 index 0000000000..465a4fa11b --- /dev/null +++ b/librephotos/wsgi.py @@ -0,0 +1,11 @@ +import os + +from django.core.wsgi import get_wsgi_application + +environment = "production" +if os.environ.get("DEBUG", "0") == "1": + environment = "development" + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", f"librephotos.settings.{environment}") + +application = get_wsgi_application() diff --git a/manage.py b/manage.py index 71944d4668..72212c12f4 100755 --- a/manage.py +++ b/manage.py @@ -3,16 +3,20 @@ import sys if __name__ == "__main__": - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ownphotos.settings") + environment = "production" + if os.environ.get("DEBUG", "0") == "1": + environment = "development" try: command = sys.argv[1] except IndexError: command = "help" - collect_coverage = os.environ.get("NO_COVERAGE") is not None + do_not_collect_coverage = os.environ.get("NO_COVERAGE") is not None running_tests = command == "test" - if running_tests and not collect_coverage: + if running_tests: + environment = "test" + if running_tests and not do_not_collect_coverage: from coverage import Coverage cov = Coverage() @@ -23,9 +27,13 @@ from django.core.management import execute_from_command_line except ImportError: raise + + os.environ.setdefault( + "DJANGO_SETTINGS_MODULE", f"librephotos.settings.{environment}" + ) execute_from_command_line(sys.argv) - if running_tests and not collect_coverage: + if running_tests and not do_not_collect_coverage: cov.stop() cov.save() cov.html_report() diff --git a/nextcloud/directory_watcher.py b/nextcloud/directory_watcher.py index 8076742254..48654fb4b5 100644 --- a/nextcloud/directory_watcher.py +++ b/nextcloud/directory_watcher.py @@ -4,12 +4,12 @@ import owncloud as nextcloud import pytz +from django.conf import settings import api.util as util from api.directory_watcher import handle_new_image from api.image_similarity import build_image_similarity_index from api.models import LongRunningJob -from ownphotos import settings def isValidNCMedia(file_obj): diff --git a/ownphotos/wsgi.py b/ownphotos/wsgi.py index 62593784f3..465a4fa11b 100644 --- a/ownphotos/wsgi.py +++ b/ownphotos/wsgi.py @@ -1,16 +1,11 @@ -""" -WSGI config for ownphotos project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ -""" - import os from django.core.wsgi import get_wsgi_application -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ownphotos.settings") +environment = "production" +if os.environ.get("DEBUG", "0") == "1": + environment = "development" + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", f"librephotos.settings.{environment}") application = get_wsgi_application()