Browse Source

First import

pull/58/head
squeaky otter 2 months ago
commit
5981124700
Signed by: dashie GPG Key ID: C2D57B325840B755
23 changed files with 867 additions and 0 deletions
  1. +96
    -0
      .gitignore
  2. +15
    -0
      .pre-commit-config.yaml
  3. +0
    -0
      config/__init__.py
  4. +6
    -0
      config/admin.py
  5. +16
    -0
      config/asgi.py
  6. +0
    -0
      config/settings/__init__.py
  7. +285
    -0
      config/settings/common.py
  8. +86
    -0
      config/settings/local.py
  9. +40
    -0
      config/urls.py
  10. +16
    -0
      config/wsgi.py
  11. +3
    -0
      controllers/__init__.py
  12. +0
    -0
      controllers/users/__init__.py
  13. +7
    -0
      controllers/users/admin.py
  14. +5
    -0
      controllers/users/apps.py
  15. +93
    -0
      controllers/users/migrations/0001_initial.py
  16. +18
    -0
      controllers/users/migrations/0002_auto_20201026_1400.py
  17. +0
    -0
      controllers/users/migrations/__init__.py
  18. +15
    -0
      controllers/users/models.py
  19. +35
    -0
      controllers/utils.py
  20. +23
    -0
      manage.py
  21. +15
    -0
      pyproject.toml
  22. +63
    -0
      requirements.txt
  23. +30
    -0
      setup.cfg

+ 96
- 0
.gitignore View File

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

+ 15
- 0
.pre-commit-config.yaml View File

@ -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
config/__init__.py View File


+ 6
- 0
config/admin.py View File

@ -0,0 +1,6 @@
from django.contrib import admin
class CommonAdmin(admin.ModelAdmin):
list_per_page = 20
list_select_related = True

+ 16
- 0
config/asgi.py View File

@ -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
config/settings/__init__.py View File


+ 285
- 0
config/settings/common.py View File

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

+ 86
- 0
config/settings/local.py View File

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

+ 40
- 0
config/urls.py View File

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

+ 16
- 0
config/wsgi.py View File

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

+ 3
- 0
controllers/__init__.py View File

@ -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
controllers/users/__init__.py View File


+ 7
- 0
controllers/users/admin.py View File

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

+ 5
- 0
controllers/users/apps.py View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = "users"

+ 93
- 0
controllers/users/migrations/0001_initial.py View File

@ -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()),
],
),
]

+ 18
- 0
controllers/users/migrations/0002_auto_20201026_1400.py View File

@ -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
controllers/users/migrations/__init__.py View File


+ 15
- 0
controllers/users/models.py View File

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

+ 35
- 0
controllers/utils.py View File

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

+ 23
- 0
manage.py View File

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

+ 15
- 0
pyproject.toml View File

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

+ 63
- 0
requirements.txt View File

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

+ 30
- 0
setup.cfg View File

@ -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…
Cancel
Save