mirror of https://github.com/rhaamo/camgear
commit
5981124700
23 changed files with 867 additions and 0 deletions
@ -0,0 +1,96 @@ |
|||
# Byte-compiled / optimized / DLL files |
|||
__pycache__/ |
|||
*.py[cod] |
|||
|
|||
# C extensions |
|||
*.so |
|||
|
|||
# Distribution / packaging |
|||
.Python |
|||
/env/ |
|||
/build/ |
|||
/develop-eggs/ |
|||
/dist/ |
|||
/downloads/ |
|||
eggs/ |
|||
.eggs/ |
|||
#lib/ |
|||
/lib64/ |
|||
/parts/ |
|||
/sdist/ |
|||
/var/ |
|||
*.egg-info/ |
|||
.installed.cfg |
|||
*.egg |
|||
|
|||
# PyInstaller |
|||
# Usually these files are written by a python script from a template |
|||
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
|||
*.manifest |
|||
*.spec |
|||
|
|||
# Installer logs |
|||
pip-log.txt |
|||
pip-delete-this-directory.txt |
|||
|
|||
# Unit test / coverage reports |
|||
htmlcov/ |
|||
.tox/ |
|||
.coverage |
|||
.coverage.* |
|||
.cache |
|||
nosetests.xml |
|||
coverage.xml |
|||
*,cover |
|||
|
|||
# Translations |
|||
*.mo |
|||
*.pot |
|||
|
|||
# Django stuff: |
|||
*.log |
|||
|
|||
# Sphinx documentation |
|||
docs/_build/ |
|||
|
|||
# PyBuilder |
|||
target/ |
|||
|
|||
# Stored PDFs |
|||
media/documents/*.gpg |
|||
media/documents/thumbnails/*.gpg |
|||
media/documents/originals/*.gpg |
|||
|
|||
# Sqlite database |
|||
db.sqlite3 |
|||
|
|||
# PyCharm |
|||
.idea |
|||
|
|||
# Other stuff that doesn't belong |
|||
virtualenv |
|||
/venv/ |
|||
.vagrant |
|||
docker-compose.yml |
|||
docker-compose.env |
|||
|
|||
# Used for development |
|||
scripts/import-for-development |
|||
scripts/nuke |
|||
/.env |
|||
/.env.* |
|||
|
|||
# Static |
|||
media/ |
|||
/static/ |
|||
|
|||
TODO |
|||
|
|||
cache/*.djcache |
|||
|
|||
/config/settings/dev.py |
|||
/config/settings/development.py |
|||
/config/settings/prod.py |
|||
/config/settings/production.py |
|||
|
|||
/test-reports |
@ -0,0 +1,15 @@ |
|||
repos: |
|||
- repo: local |
|||
hooks: |
|||
- id: black |
|||
name: black |
|||
language: system |
|||
entry: python3 -m black |
|||
types: [python] |
|||
files: ^api/ |
|||
- id: flake8 |
|||
name: flake8 |
|||
language: system |
|||
entry: flake8 |
|||
types: [python] |
|||
files: ^api/ |
@ -0,0 +1,6 @@ |
|||
from django.contrib import admin |
|||
|
|||
|
|||
class CommonAdmin(admin.ModelAdmin): |
|||
list_per_page = 20 |
|||
list_select_related = True |
@ -0,0 +1,16 @@ |
|||
""" |
|||
ASGI config for config project. |
|||
|
|||
It exposes the ASGI callable as a module-level variable named ``application``. |
|||
|
|||
For more information on this file, see |
|||
https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ |
|||
""" |
|||
|
|||
import os |
|||
|
|||
from django.core.asgi import get_asgi_application |
|||
|
|||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") |
|||
|
|||
application = get_asgi_application() |
@ -0,0 +1,285 @@ |
|||
import logging.config |
|||
import environ |
|||
|
|||
print("Common config included") |
|||
|
|||
logger = logging.getLogger("camgear.config") |
|||
ROOT_DIR = environ.Path(__file__) - 3 # (/a/b/myfile.py - 3 = /) |
|||
APPS_DIR = ROOT_DIR.path("controllers") |
|||
BASE_DIR = environ.Path(__file__) - 3 |
|||
|
|||
env = environ.Env() |
|||
|
|||
# DEBUG |
|||
# ------------------------------------------------------------------------------ |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug |
|||
DEBUG = env.bool("DJANGO_DEBUG", False) |
|||
|
|||
# Logging |
|||
# ------------------------------------------------------------------------------ |
|||
LOGLEVEL = env("LOGLEVEL", default="info").upper() |
|||
LOGGING_CONFIG = None |
|||
logging.config.dictConfig( |
|||
{ |
|||
"version": 1, |
|||
"disable_existing_loggers": False, |
|||
"formatters": {"console": {"format": "%(asctime)s %(name)-12s %(levelname)-8s %(message)s"}}, |
|||
"handlers": { |
|||
"console": {"class": "logging.StreamHandler", "formatter": "console"}, |
|||
# # Add Handler for Sentry for `warning` and above |
|||
# 'sentry': { |
|||
# 'level': 'WARNING', |
|||
# 'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler', |
|||
# }, |
|||
}, |
|||
"loggers": { |
|||
"camgear": { |
|||
"level": LOGLEVEL, |
|||
"handlers": ["console"], |
|||
# required to avoid double logging with root logger |
|||
"propagate": False, |
|||
}, |
|||
"": {"level": LOGLEVEL, "handlers": ["console"]}, |
|||
}, |
|||
} |
|||
) |
|||
|
|||
env_file = env("ENV_FILE", default=None) |
|||
if env_file: |
|||
logger.info("Loading specified env file at %s", env_file) |
|||
# we have an explicitely specified env file |
|||
# so we try to load and it fail loudly if it does not exist |
|||
env.read_env(env_file) |
|||
else: |
|||
# we try to load from .env and config/.env |
|||
# but do not crash if those files don't exist |
|||
paths = [ |
|||
# /srv/camgear/api/.env |
|||
ROOT_DIR, |
|||
# /srv/camgear/.env |
|||
(ROOT_DIR - 1), |
|||
] |
|||
for path in paths: |
|||
try: |
|||
env_path = path.file(".env") |
|||
except FileNotFoundError: |
|||
logger.debug("No env file found at %s/.env", path) |
|||
continue |
|||
env.read_env(env_path) |
|||
logger.info("Loaded env file at %s/.env", path) |
|||
break |
|||
|
|||
ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=[]) |
|||
INTERNAL_IPS = ALLOWED_HOSTS |
|||
|
|||
# APP CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
DJANGO_APPS = [ |
|||
"django.contrib.auth", |
|||
"django.contrib.contenttypes", |
|||
"django.contrib.sessions", |
|||
"django.contrib.messages", |
|||
"django.contrib.staticfiles", |
|||
"django.contrib.postgres", |
|||
"django.contrib.admin", |
|||
] |
|||
|
|||
THIRD_PARTY_APPS = [ |
|||
"mptt", |
|||
"imagekit", |
|||
"django_admin_listfilter_dropdown", |
|||
"django_extensions" |
|||
] |
|||
|
|||
LOCAL_APPS = [ |
|||
"controllers.users", # custom users app |
|||
] |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps |
|||
|
|||
ADDITIONAL_APPS = env.list("ADDITIONAL_APPS", default=[]) |
|||
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + ADDITIONAL_APPS + LOCAL_APPS |
|||
|
|||
# MIDDLEWARE CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
ADDITIONAL_MIDDLEWARES_BEFORE = env.list("ADDITIONAL_MIDDLEWARES_BEFORE", default=[]) |
|||
ADDITIONAL_MIDDLEWARES_AFTER = env.list("ADDITIONAL_MIDDLEWARES_AFTER", default=[]) |
|||
|
|||
MIDDLEWARE = ( |
|||
ADDITIONAL_MIDDLEWARES_BEFORE |
|||
+ [ |
|||
"django.middleware.security.SecurityMiddleware", |
|||
"django.contrib.sessions.middleware.SessionMiddleware", |
|||
"django.middleware.common.CommonMiddleware", |
|||
"django.middleware.csrf.CsrfViewMiddleware", |
|||
"django.contrib.auth.middleware.AuthenticationMiddleware", |
|||
"django.contrib.messages.middleware.MessageMiddleware", |
|||
"django.middleware.clickjacking.XFrameOptionsMiddleware", |
|||
] |
|||
+ ADDITIONAL_MIDDLEWARES_AFTER |
|||
) |
|||
|
|||
# FIXTURE CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS |
|||
FIXTURE_DIRS = (str(APPS_DIR.path("fixtures")),) |
|||
|
|||
# EMAIL CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
|
|||
# EMAIL |
|||
# ------------------------------------------------------------------------------ |
|||
DEFAULT_FROM_EMAIL = env("DEFAULT_FROM_EMAIL", default="Camgear <noreply@localhost>") |
|||
|
|||
EMAIL_SUBJECT_PREFIX = env("EMAIL_SUBJECT_PREFIX", default="[Camgear] ") |
|||
SERVER_EMAIL = env("SERVER_EMAIL", default=DEFAULT_FROM_EMAIL) |
|||
|
|||
|
|||
EMAIL_CONFIG = env.email_url("EMAIL_CONFIG", default="consolemail://") |
|||
|
|||
vars().update(EMAIL_CONFIG) |
|||
|
|||
# SECRET CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key |
|||
# Note: This key only used for development and testing. |
|||
SECRET_KEY = env("DJANGO_SECRET_KEY", default=None) |
|||
|
|||
# DATABASE CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases |
|||
DATABASES = { |
|||
# Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ |
|||
"default": env.db("DATABASE_URL") |
|||
} |
|||
DATABASES["default"]["ATOMIC_REQUESTS"] = True |
|||
# CONN_MAX_AGE seems to causes issues |
|||
# DATABASES["default"]["CONN_MAX_AGE"] = env("DB_CONN_MAX_AGE", default=60 * 5) |
|||
|
|||
MIGRATION_MODULES = { |
|||
# see https://github.com/jazzband/django-oauth-toolkit/issues/634 |
|||
# swappable models are badly designed in oauth2_provider |
|||
# ignore migrations and provide our own models. |
|||
"oauth2_provider": None, |
|||
} |
|||
|
|||
# |
|||
# DATABASES = { |
|||
# 'default': { |
|||
# 'ENGINE': 'django.db.backends.sqlite3', |
|||
# 'NAME': 'db.sqlite3', |
|||
# } |
|||
# } |
|||
# GENERAL CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
# Local time zone for this installation. Choices can be found here: |
|||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name |
|||
# although not all choices may be available on all operating systems. |
|||
# In a Windows environment this must be set to your system time zone. |
|||
TIME_ZONE = env("TIME_ZONE", default="UTC") |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code |
|||
LANGUAGE_CODE = env("LANGUAGE_CODE", default="en-us") |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id |
|||
SITE_ID = 1 |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n |
|||
USE_I18N = True |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n |
|||
USE_L10N = True |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz |
|||
USE_TZ = True |
|||
|
|||
# TEMPLATE CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#templates |
|||
TEMPLATES = [ |
|||
{ |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND |
|||
"BACKEND": "django.template.backends.django.DjangoTemplates", |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs |
|||
"DIRS": [str(APPS_DIR.path("templates"))], |
|||
"OPTIONS": { |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug |
|||
"debug": DEBUG, |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders |
|||
# https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types |
|||
"loaders": [ |
|||
"django.template.loaders.filesystem.Loader", |
|||
"django.template.loaders.app_directories.Loader", |
|||
], |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors |
|||
"context_processors": [ |
|||
"django.template.context_processors.debug", |
|||
"django.template.context_processors.request", |
|||
"django.contrib.auth.context_processors.auth", |
|||
"django.template.context_processors.i18n", |
|||
"django.template.context_processors.media", |
|||
"django.template.context_processors.static", |
|||
"django.template.context_processors.tz", |
|||
"django.contrib.messages.context_processors.messages", |
|||
# Your stuff: custom template context processors go here |
|||
], |
|||
}, |
|||
} |
|||
] |
|||
|
|||
# STATIC FILE CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root |
|||
STATIC_ROOT = env("STATIC_ROOT", default=str(ROOT_DIR("static"))) |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url |
|||
STATIC_URL = env("STATIC_URL", default="/static/") |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS |
|||
# STATICFILES_DIRS = (str(APPS_DIR.path("static")),) |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders |
|||
STATICFILES_FINDERS = ( |
|||
"django.contrib.staticfiles.finders.FileSystemFinder", |
|||
"django.contrib.staticfiles.finders.AppDirectoriesFinder", |
|||
) |
|||
|
|||
# MEDIA CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root |
|||
MEDIA_ROOT = env("MEDIA_ROOT", default=str(APPS_DIR("media"))) |
|||
|
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url |
|||
MEDIA_URL = env("MEDIA_URL", default="/media/") |
|||
FILE_UPLOAD_PERMISSIONS = 0o644 |
|||
|
|||
ATTACHMENTS_UNATTACHED_PRUNE_DELAY = env.int("ATTACHMENTS_UNATTACHED_PRUNE_DELAY", default=3600 * 24) |
|||
|
|||
# URL Configuration |
|||
# ------------------------------------------------------------------------------ |
|||
ROOT_URLCONF = "config.urls" |
|||
ASGI_APPLICATION = "config.asgi.application" |
|||
WSGI_APPLICATION = "config.wsgi.application" |
|||
ADMIN_URL = env("DJANGO_ADMIN_URL", default="^admin/") |
|||
|
|||
# This ensures that Django will be able to detect a secure connection |
|||
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") |
|||
SECURE_BROWSER_XSS_FILTER = True |
|||
SECURE_CONTENT_TYPE_NOSNIFF = True |
|||
|
|||
# AUTHENTICATION CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
LOGIN_URL = "/accounts/login" |
|||
LOGIN_REDIRECT_URL = "/parts" |
|||
LOGOUT_REDIRECT_URL = LOGIN_URL |
|||
|
|||
AUTH_USER_MODEL = "users.User" |
|||
|
|||
# 50M (50*1024*1024) |
|||
FILE_UPLOAD_MAX_MEMORY_SIZE = env("FILE_UPLOAD_MAX_MEMORY_SIZE", default=50 * 1024 * 1024) |
|||
DATA_UPLOAD_MAX_MEMORY_SIZE = FILE_UPLOAD_MAX_MEMORY_SIZE |
|||
|
|||
CACHES = { |
|||
"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache", "LOCATION": "default-cache"}, |
|||
"local": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache", "LOCATION": "local-cache"}, |
|||
} |
@ -0,0 +1,86 @@ |
|||
# -*- coding: utf-8 -*- |
|||
""" |
|||
Local settings |
|||
|
|||
- Run in Debug mode |
|||
- Use console backend for emails |
|||
- Add Django Debug Toolbar |
|||
- Add django-extensions as app |
|||
""" |
|||
|
|||
from .common import * # noqa |
|||
|
|||
print("DEBUG config included") |
|||
|
|||
# DEBUG |
|||
# ------------------------------------------------------------------------------ |
|||
DEBUG = env.bool("DJANGO_DEBUG", default=True) |
|||
FORCE_HTTPS_URLS = env.bool("FORCE_HTTPS_URLS", default=False) |
|||
TEMPLATES[0]["OPTIONS"]["debug"] = DEBUG |
|||
|
|||
# SECRET CONFIGURATION |
|||
# ------------------------------------------------------------------------------ |
|||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key |
|||
# Note: This key only used for development and testing. |
|||
SECRET_KEY = env("DJANGO_SECRET_KEY", default="^@*2wer5(q2k!f1)!bns&%gf_qliixb$cd)%k*=_blze$a4@%1") |
|||
|
|||
# Mail settings |
|||
# ------------------------------------------------------------------------------ |
|||
EMAIL_HOST = "localhost" |
|||
EMAIL_PORT = 25 |
|||
|
|||
# django-debug-toolbar |
|||
# ------------------------------------------------------------------------------ |
|||
|
|||
INTERNAL_IPS = ["127.0.0.1", "0.0.0.0", "192.168.10.167"] |
|||
ALLOWED_HOSTS = INTERNAL_IPS + ALLOWED_HOSTS |
|||
|
|||
DEBUG_TOOLBAR_CONFIG = { |
|||
"DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"], |
|||
"SHOW_TEMPLATE_CONTEXT": True, |
|||
# "SHOW_TOOLBAR_CALLBACK": lambda request: "debug" in request.GET, |
|||
# "JQUERY_URL": "/staticfiles/admin/js/vendor/jquery/jquery.js", |
|||
} |
|||
|
|||
DEBUG_TOOLBAR_PANELS = [ |
|||
"debug_toolbar.panels.versions.VersionsPanel", |
|||
"debug_toolbar.panels.timer.TimerPanel", |
|||
"debug_toolbar.panels.settings.SettingsPanel", |
|||
"debug_toolbar.panels.headers.HeadersPanel", |
|||
"debug_toolbar.panels.request.RequestPanel", |
|||
"debug_toolbar.panels.sql.SQLPanel", # slow down by 300ms |
|||
"debug_toolbar.panels.staticfiles.StaticFilesPanel", |
|||
"debug_toolbar.panels.templates.TemplatesPanel", # slow down by over9000 in admin |
|||
"debug_toolbar.panels.cache.CachePanel", |
|||
"debug_toolbar.panels.signals.SignalsPanel", |
|||
"debug_toolbar.panels.logging.LoggingPanel", |
|||
# "debug_toolbar.panels.redirects.RedirectsPanel", |
|||
"debug_toolbar.panels.profiling.ProfilingPanel", |
|||
] |
|||
|
|||
# django-extensions |
|||
# ------------------------------------------------------------------------------ |
|||
# INSTALLED_APPS += ('django_extensions', ) |
|||
|
|||
# Debug toolbar is slow, we disable it for tests |
|||
DEBUG_TOOLBAR_ENABLED = env.bool("DEBUG_TOOLBAR_ENABLED", default=DEBUG) |
|||
if DEBUG_TOOLBAR_ENABLED: |
|||
MIDDLEWARE += ("debug_toolbar.middleware.DebugToolbarMiddleware",) |
|||
INSTALLED_APPS += ("debug_toolbar",) |
|||
|
|||
ADDITIONAL_MIDDLEWARES_AFTER = ["silk.middleware.SilkyMiddleware"] |
|||
|
|||
# TESTING |
|||
# ------------------------------------------------------------------------------ |
|||
TEST_RUNNER = "django.test.runner.DiscoverRunner" |
|||
|
|||
# Your local stuff: Below this line define 3rd party library settings |
|||
|
|||
CSRF_TRUSTED_ORIGINS = [o for o in ALLOWED_HOSTS] |
|||
CORS_ORIGIN_ALLOW_ALL = True |
|||
|
|||
# Speed up a bit ImageKit |
|||
# if DEBUG=True, all caching is disabled, and calls to like /api/v1/footprints take ages... |
|||
IMAGEKIT_CACHE_BACKEND = "default" |
|||
IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = "imagekit.cachefiles.strategies.Optimistic" |
|||
IMAGEKIT_DEFAULT_CACHEFILE_BACKEND = "imagekit.cachefiles.backends.Simple" |
@ -0,0 +1,40 @@ |
|||
"""config URL Configuration |
|||
|
|||
The `urlpatterns` list routes URLs to views. For more information please see: |
|||
https://docs.djangoproject.com/en/3.0/topics/http/urls/ |
|||
Examples: |
|||
Function views |
|||
1. Add an import: from my_app import views |
|||
2. Add a URL to urlpatterns: path('', views.home, name='home') |
|||
Class-based views |
|||
1. Add an import: from other_app.views import Home |
|||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') |
|||
Including another URLconf |
|||
1. Import the include() function: from django.urls import include, path |
|||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) |
|||
""" |
|||
from django.contrib import admin |
|||
from django.conf import settings |
|||
from django.conf.urls import url, include |
|||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns |
|||
|
|||
from controllers.utils import static |
|||
|
|||
urlpatterns = [ |
|||
url(settings.ADMIN_URL, admin.site.urls), |
|||
] |
|||
|
|||
|
|||
admin.site.site_header = "CamGear Inventory" |
|||
admin.site.site_title = "CamGear Admin Portal" |
|||
admin.site.index_title = "Welcome to CamGear" |
|||
|
|||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) |
|||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) |
|||
|
|||
if settings.DEBUG: |
|||
print("Debug URLs enabled") |
|||
import debug_toolbar |
|||
|
|||
urlpatterns = [url(r"^__debug__/", include(debug_toolbar.urls))] + urlpatterns |
|||
urlpatterns += staticfiles_urlpatterns() |
@ -0,0 +1,16 @@ |
|||
""" |
|||
WSGI config for config 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/3.0/howto/deployment/wsgi/ |
|||
""" |
|||
|
|||
import os |
|||
|
|||
from django.core.wsgi import get_wsgi_application |
|||
|
|||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") |
|||
|
|||
application = get_wsgi_application() |
@ -0,0 +1,3 @@ |
|||
# -*- coding: utf-8 -*- |
|||
__version__ = "0.0.1" |
|||
__version_info__ = tuple([int(num) if num.isdigit() else num for num in __version__.replace("-", ".", 1).split(".")]) |
@ -0,0 +1,7 @@ |
|||
from django.contrib import admin |
|||
from django.contrib.auth.admin import UserAdmin |
|||
|
|||
from .models import User |
|||
|
|||
|
|||
admin.site.register(User, UserAdmin) |
@ -0,0 +1,5 @@ |
|||
from django.apps import AppConfig |
|||
|
|||
|
|||
class UsersConfig(AppConfig): |
|||
name = "users" |
@ -0,0 +1,93 @@ |
|||
# Generated by Django 3.0.1 on 2020-01-30 13:08 |
|||
|
|||
import django.contrib.auth.models |
|||
import django.contrib.auth.validators |
|||
from django.db import migrations, models |
|||
import django.utils.timezone |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
initial = True |
|||
|
|||
dependencies = [ |
|||
("auth", "0011_update_proxy_permissions"), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name="User", |
|||
fields=[ |
|||
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), |
|||
("password", models.CharField(max_length=128, verbose_name="password")), |
|||
("last_login", models.DateTimeField(blank=True, null=True, verbose_name="last login")), |
|||
( |
|||
"is_superuser", |
|||
models.BooleanField( |
|||
default=False, |
|||
help_text="Designates that this user has all permissions without explicitly assigning them.", |
|||
verbose_name="superuser status", |
|||
), |
|||
), |
|||
( |
|||
"username", |
|||
models.CharField( |
|||
error_messages={"unique": "A user with that username already exists."}, |
|||
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.", |
|||
max_length=150, |
|||
unique=True, |
|||
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], |
|||
verbose_name="username", |
|||
), |
|||
), |
|||
("first_name", models.CharField(blank=True, max_length=30, verbose_name="first name")), |
|||
("last_name", models.CharField(blank=True, max_length=150, verbose_name="last name")), |
|||
("email", models.EmailField(blank=True, max_length=254, verbose_name="email address")), |
|||
( |
|||
"is_staff", |
|||
models.BooleanField( |
|||
default=False, |
|||
help_text="Designates whether the user can log into this admin site.", |
|||
verbose_name="staff status", |
|||
), |
|||
), |
|||
( |
|||
"is_active", |
|||
models.BooleanField( |
|||
default=True, |
|||
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", |
|||
verbose_name="active", |
|||
), |
|||
), |
|||
("date_joined", models.DateTimeField(default=django.utils.timezone.now, verbose_name="date joined")), |
|||
( |
|||
"groups", |
|||
models.ManyToManyField( |
|||
blank=True, |
|||
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", |
|||
related_name="user_set", |
|||
related_query_name="user", |
|||
to="auth.Group", |
|||
verbose_name="groups", |
|||
), |
|||
), |
|||
( |
|||
"user_permissions", |
|||
models.ManyToManyField( |
|||
blank=True, |
|||
help_text="Specific permissions for this user.", |
|||
related_name="user_set", |
|||
related_query_name="user", |
|||
to="auth.Permission", |
|||
verbose_name="user permissions", |
|||
), |
|||
), |
|||
], |
|||
options={ |
|||
"db_table": "auth_user", |
|||
}, |
|||
managers=[ |
|||
("objects", django.contrib.auth.models.UserManager()), |
|||
], |
|||
), |
|||
] |
@ -0,0 +1,18 @@ |
|||
# Generated by Django 3.1.2 on 2020-10-26 14:00 |
|||
|
|||
from django.db import migrations, models |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
("users", "0001_initial"), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterField( |
|||
model_name="user", |
|||
name="first_name", |
|||
field=models.CharField(blank=True, max_length=150, verbose_name="first name"), |
|||
), |
|||
] |
@ -0,0 +1,15 @@ |
|||
from django.contrib.auth.models import AbstractUser |
|||
|
|||
PERMISSIONS_CONFIGURATION = { |
|||
"categories": {"label": "Categories", "help_text": "", "scopes": {"read", "write"}}, |
|||
"parts": {"label": "Categories", "help_text": "", "scopes": {"read", "write"}}, |
|||
} |
|||
|
|||
PERMISSIONS = sorted(PERMISSIONS_CONFIGURATION.keys()) |
|||
|
|||
default_permissions = ["categories", "parts"] |
|||
|
|||
|
|||
class User(AbstractUser): |
|||
class Meta: |
|||
db_table = "auth_user" |
@ -0,0 +1,35 @@ |
|||
import re |
|||
|
|||
from django.core.exceptions import ImproperlyConfigured |
|||
from django.urls import re_path |
|||
from django.views.static import serve |
|||
|
|||
|
|||
def join_url(start, end): |
|||
if end.startswith("http://") or end.startswith("https://"): |
|||
# alread a full URL, joining makes no sense |
|||
return end |
|||
if start.endswith("/") and end.startswith("/"): |
|||
return start + end[1:] |
|||
|
|||
if not start.endswith("/") and not end.startswith("/"): |
|||
return start + "/" + end |
|||
|
|||
return start + end |
|||
|
|||
|
|||
# We always serve static, even in production, sorry for the best practices... |
|||
def static(prefix, view=serve, **kwargs): |
|||
""" |
|||
Return a URL pattern for serving files in debug mode. |
|||
from django.conf import settings |
|||
from controllers.utils import static |
|||
urlpatterns = [ |
|||
# ... the rest of your URLconf goes here ... |
|||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) |
|||
""" |
|||
if not prefix: |
|||
raise ImproperlyConfigured("Empty static prefix not permitted") |
|||
return [ |
|||
re_path(r"^%s(?P<path>.*)$" % re.escape(prefix.lstrip("/")), view, kwargs=kwargs), |
|||
] |
@ -0,0 +1,23 @@ |
|||
#!/usr/bin/env python |
|||
"""Django's command-line utility for administrative tasks.""" |
|||
import os |
|||
import sys |
|||
|
|||
sys.path.append(os.path.dirname(os.path.abspath(__file__))) |
|||
|
|||
|
|||
def main(): |
|||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production") |
|||
try: |
|||
from django.core.management import execute_from_command_line |
|||
except ImportError as exc: |
|||
raise ImportError( |
|||
"Couldn't import Django. Are you sure it's installed and " |
|||
"available on your PYTHONPATH environment variable? Did you " |
|||
"forget to activate a virtual environment?" |
|||
) from exc |
|||
execute_from_command_line(sys.argv) |
|||
|
|||
|
|||
if __name__ == "__main__": |
|||
main() |
@ -0,0 +1,15 @@ |
|||
[tool.black] |
|||
line-length = 120 |
|||
exclude = ''' |
|||
/( |
|||
\.git |
|||
| \.eggs |
|||
| \.idea |
|||
| \__pycache__ |
|||
| venv |
|||
| front |
|||
| controllers/part/static/django-dynamic-formset |
|||
| controllers/part/static/qrcode-generator |
|||
)/ |
|||
''' |
|||
skip-numeric-underscore-normalization = true |
@ -0,0 +1,63 @@ |
|||
appdirs==1.4.4 |
|||
asgiref==3.3.1 |
|||
attrs==20.3.0 |
|||
backcall==0.2.0 |
|||
black==20.8b1 |
|||
Django==3.1.4 |
|||
django-admin-list-filter-dropdown==1.0.3 |
|||
django-appconf==1.0.4 |
|||
django-debug-toolbar==3.2 |
|||
django-imagekit==4.0.2 |
|||
django-mptt==0.11.0 |
|||
entrypoints==0.3 |
|||
flake8==3.8.4 |
|||
h11==0.11.0 |
|||
httptools==0.1.1 |
|||
ipdb==0.13.4 |
|||
ipython==7.19.0 |
|||
ipython-genutils==0.2.0 |
|||
jedi==0.17.2 |
|||
mccabe==0.6.1 |
|||
parso==0.7.0 |
|||
pathspec==0.8.1 |
|||
pexpect==4.8.0 |
|||
pickleshare==0.7.5 |
|||
pilkit==2.0 |
|||
Pillow==8.0.1 |
|||
prompt-toolkit==3.0.8 |
|||
psycopg2==2.8.6 |
|||
ptyprocess==0.6.0 |
|||
pycodestyle==2.6.0 |
|||
pyflakes==2.2.0 |
|||
Pygments==2.7.2 |
|||
python-magic==0.4.18 |
|||
pytz==2020.4 |
|||
PyYAML==5.3.1 |
|||
regex==2020.11.13 |
|||
six==1.15.0 |
|||
sqlparse==0.4.1 |
|||
toml==0.10.2 |
|||
traitlets==5.0.5 |
|||
typed-ast==1.4.1 |
|||
uvicorn==0.12.3 |
|||
gunicorn==20.0.4 |
|||
uvloop==0.14.0 |
|||
wcwidth==0.2.5 |
|||
websockets==8.1 |
|||
django-oauth-toolkit==1.3.3 |
|||
django-cors-middleware==1.5.0 |
|||
django-environ==0.4.5 |
|||
djangorestframework==3.12.2 |
|||
django-extensions==3.1.0 |
|||
drf-yasg==1.20.0 |
|||
drf-writable-nested==0.6.2 |
|||
pytest-django==4.1.0 |
|||
pytest==6.1.2 |
|||
pytest-cov==2.10.1 |
|||
factory_boy==3.1.0 |
|||
persisting-theory==0.2.1 |
|||
pytest-env==0.6.2 |
|||
django-silk==4.1.0 |
|||
django-upload-validator==1.1.5 |
|||
djangorestframework-csv==2.1.0 |
|||
drf-renderer-xlsx==0.3.8 |
@ -0,0 +1,30 @@ |
|||
[aliases] |
|||
test=pytest |
|||
|
|||
[tool:pytest] |
|||
addopts = --verbose --cov=. --cov-report=xml:test-reports/coverage.xml -p no:warnings |
|||
python_files = tests.py test_*.py *_tests.py |
|||
testpaths = tests |
|||
env = |
|||
DJANGO_SETTINGS_MODULE=config.settings.local |
|||
DEBUG=True |
|||
DJANGO_DEBUG=True |
|||
|
|||
[flake8] |
|||
max-line-length = 120 |
|||
ignore = F405,E501,W504,W503,E231 |
|||
exclude = .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,venv,.eggs,controllers/part/static/django-dynamic-formset,controllers/part/static/qrcode-generator |
|||
|
|||
[coverage:run] |
|||
omit = |
|||
tests/* |
|||
.eggs/* |
|||
config.py |
|||
configtest.py |
|||
**/*__init__.py |
|||
venv/* |
|||
front/* |
|||
|
|||
[isort] |
|||
line_length=120 |
|||
force_single_line=false |
Loading…
Reference in new issue