Merge pull request #2 from jedie/develop

Minimal Django project setup
pull/4/head
Jens Diemer 2020-10-16 18:32:59 +02:00 zatwierdzone przez GitHub
commit 5327987fec
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
23 zmienionych plików z 812 dodań i 356 usunięć

Wyświetl plik

@ -11,7 +11,7 @@ jobs:
strategy:
max-parallel: 2
matrix:
python-version: [3.8, 3.7, 3.6]
python-version: [3.9, 3.8, 3.7]
steps:
- uses: actions/checkout@v1
- name: 'Set up Python ${{ matrix.python-version }}'

2
.gitignore vendored
Wyświetl plik

@ -11,7 +11,7 @@
# from test projects:
inventory_project/static/
inventory_project/media/
test_project_db.sqlite3
*.sqlite3
# Coverage HTML Report files:
htmlcov

Wyświetl plik

@ -18,6 +18,6 @@ known_first_party=inventory,inventory_project,inventory_tests
no_lines_before=LOCALFOLDER
default_section=THIRDPARTY
sections=FUTURE,STDLIB,EXTERNAL,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
lines_after_imports=2

Wyświetl plik

@ -28,6 +28,11 @@ install-poetry: ## install or update poetry
install: check-poetry ## install PyInventory via poetry
poetry install
manage-update: ## Collectstatic + makemigration + migrate
./manage.sh collectstatic --noinput --link
./manage.sh makemigrations
./manage.sh migrate
update: check-poetry ## update the sources and installation
git fetch --all
git pull origin master
@ -70,7 +75,7 @@ publish: ## Release new version to PyPi
run-dev-server: ## Run the django dev server in endless loop.
poetry run inventory run-dev-server
./manage.sh runserver
run-server: ## Run the gunicorn server in endless loop.
poetry run inventory run-server

Wyświetl plik

@ -1,10 +1 @@
"""
created 19.07.2018 by Jens Diemer <opensource@jensdiemer.de>
:copyleft: 2018 by the PyInventory team, see AUTHORS for more details.
:license: GNU GPL v3 or above, see LICENSE for more details.
"""
from inventory.admin.discipline import DisciplineModelAdmin # noqa
from inventory.admin.distance import DistanceModelAdmin # noqa
from inventory.admin.event import EventLinkModelAdmin, EventModelAdmin, ParticipationModelAdmin # noqa
from inventory.admin.gpx import GpxModelAdmin # noqa
from inventory.admin.item import ItemModelAdmin # noqa

Wyświetl plik

@ -0,0 +1,9 @@
from django.contrib import admin
from reversion_compare.admin import CompareVersionAdmin
from inventory.models import ItemModel
@admin.register(ItemModel)
class ItemModelAdmin(CompareVersionAdmin):
pass

Wyświetl plik

@ -1,17 +1 @@
"""
created 28.06.2018 by Jens Diemer <opensource@jensdiemer.de>
:copyleft: 2018 by the PyInventory team, see AUTHORS for more details.
:license: GNU GPL v3 or above, see LICENSE for more details.
"""
from django.db.models.signals import post_save, pre_save
# https://github.com/jedie/PyInventory
from inventory.models.discipline import DisciplineModel # noqa
from inventory.models.distance import DistanceModel # noqa
from inventory.models.event import CostModel, EventLinkModel, EventModel, ParticipationModel # noqa
from inventory.models.gpx import GpxModel # noqa
from inventory.signal_handlers.gpx import gpx_post_save_handler, gpx_pre_save_handler # noqa
pre_save.connect(receiver=gpx_pre_save_handler, sender=GpxModel)
post_save.connect(receiver=gpx_post_save_handler, sender=GpxModel)
from inventory.models.item import ItemModel # noqa

Wyświetl plik

@ -0,0 +1,17 @@
import uuid
from bx_py_utils.models.timetracking import TimetrackingBaseModel
from django.db import models
from django.utils.translation import ugettext_lazy as _
class BaseModel(TimetrackingBaseModel):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False,
verbose_name=_('ID')
)
class Meta:
abstract = True

Wyświetl plik

@ -0,0 +1,20 @@
from ckeditor_uploader.fields import RichTextUploadingField
from django.db import models
from django.utils.translation import ugettext_lazy as _
from inventory.models.base import BaseModel
class ItemModel(BaseModel):
"""
A Item that can be described and store somewhere ;)
"""
description = RichTextUploadingField(
config_name='ItemModel.description'
)
fcc_id = models.CharField(
max_length=20,
blank=True, null=True,
verbose_name='FCC ID',
help_text=_('FCC ID-Number for links to: https://fccid.io/')
)

Wyświetl plik

Wyświetl plik

@ -1,15 +1,12 @@
"""
Just print version line on every call from commandline ;)
"""
import sys
from inventory import __version__
if __name__ == "inventory_project":
#
# This will be called before the click cli
#
if "--version" not in sys.argv:
print(f"PyInventory v{__version__}")
if len(sys.argv) == 1:
# FIXME: How can be a "default" action set in click?
sys.argv.append("run-server")

Wyświetl plik

@ -24,8 +24,8 @@ def publish():
Call this via:
$ poetry run publish
"""
#verbose_check_call('make', 'pytest') # don't publish if tests fail
#verbose_check_call('make', 'fix-code-style') # don't publish if code style wrong
verbose_check_call('make', 'pytest') # don't publish if tests fail
verbose_check_call('make', 'fix-code-style') # don't publish if code style wrong
poetry_publish(
package_root=PACKAGE_ROOT,

Wyświetl plik

@ -0,0 +1,221 @@
"""
Django settings
"""
import logging
from pathlib import Path as __Path
from debug_toolbar.settings import CONFIG_DEFAULTS as DEBUG_TOOLBAR_CONFIG
from django.utils.translation import ugettext_lazy as _
print('Use settings:', __file__)
# Build paths inside the project:
BASE_PATH = __Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'TODO: Read secret.txt ;)'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
SITE_ID = 1
# Required for the debug toolbar to be displayed:
INTERNAL_IPS = '*'
ALLOWED_HOSTS = INTERNAL_IPS
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'debug_toolbar', # https://github.com/jazzband/django-debug-toolbar/
'import_export', # https://github.com/django-import-export/django-import-export
'ckeditor', # https://github.com/django-ckeditor/django-ckeditor
'reversion', # https://github.com/etianen/django-reversion
'reversion_compare', # https://github.com/jedie/django-reversion-compare
'inventory.apps.InventoryConfig',
)
ROOT_URLCONF = 'inventory_project.urls'
WSGI_APPLICATION = 'inventory_project.wsgi.application'
MIDDLEWARE = (
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django_tools.middlewares.ThreadLocal.ThreadLocalMiddleware',
)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
if DEBUG:
# Disable caches:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}}
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': str(__Path(BASE_PATH.parent, 'PyInventory-database.sqlite3')),
# 'NAME': ':memory:'
# https://docs.djangoproject.com/en/dev/ref/databases/#database-is-locked-errors
'timeout': 30,
}
}
print(f'Use Database: {DATABASES["default"]["NAME"]!r}')
# _____________________________________________________________________________
# Internationalization
LANGUAGE_CODE = 'en'
LANGUAGES = [
('de', _('German')),
('en', _('English')),
]
USE_I18N = True
USE_L10N = True
TIME_ZONE = 'Europe/Paris'
USE_TZ = True
# _____________________________________________________________________________
# Static files (CSS, JavaScript, Images)
STATIC_URL = '/static/'
STATIC_ROOT = str(__Path(BASE_PATH, 'static'))
MEDIA_URL = '/media/'
MEDIA_ROOT = str(__Path(BASE_PATH, 'media'))
# _____________________________________________________________________________
# Django-Debug-Toolbar
# Disable some more panels that will slow down the page:
DEBUG_TOOLBAR_CONFIG['DISABLE_PANELS'].add('debug_toolbar.panels.sql.SQLPanel')
DEBUG_TOOLBAR_CONFIG['DISABLE_PANELS'].add('debug_toolbar.panels.cache.CachePanel')
# don't load jquery from ajax.googleapis.com, just use django's version:
DEBUG_TOOLBAR_CONFIG['JQUERY_URL'] = STATIC_URL + 'admin/js/vendor/jquery/jquery.min.js'
DEBUG_TOOLBAR_CONFIG['SHOW_COLLAPSED'] = True # Show toolbar collapsed by default.
# _____________________________________________________________________________
# django-ckeditor
CKEDITOR_BASEPATH = STATIC_URL + 'ckeditor/'
CKEDITOR_UPLOAD_PATH = 'uploads/'
CKEDITOR_FILENAME_GENERATOR = 'utils.get_filename'
CKEDITOR_CONFIGS = {
# 'ItemModel.description': {
# 'toolbar': 'full',
# 'height': '25em',
# 'width': '100%',
# 'removeButtons': 'Language,Flash,iframes,bidiltr'
# },
'ItemModel.description': {
'skin': 'moono-lisa',
# 'toolbar_Basic': [['Source', '-', 'Bold', 'Italic']],
# 'toolbar_Full': [
# [
# 'Styles',
# 'Format',
# 'Bold',
# 'Italic',
# 'Underline',
# 'Strike',
# 'SpellChecker',
# 'Undo',
# 'Redo',
# ],
# ['Link', 'Unlink', 'Anchor'],
# ['Image', 'Flash', 'Table', 'HorizontalRule'],
# ['TextColor', 'BGColor'],
# ['Smiley', 'SpecialChar'],
# ['Source'],
# ],
'removeButtons': 'Language',
# plugins are here: site-packages/ckeditor/static/ckeditor/ckeditor/plugins
'removePlugins': 'wsc,div,flash,iframe,bidi',
'toolbar': 'full',
'height': '25em',
'width': '100%',
'filebrowserWindowWidth': 940,
'filebrowserWindowHeight': 725,
}
}
# _____________________________________________________________________________
# cut 'pathname' in log output
old_factory = logging.getLogRecordFactory()
def cut_path(pathname, max_length):
if len(pathname) <= max_length:
return pathname
return f'...{pathname[-(max_length - 3):]}'
def record_factory(*args, **kwargs):
record = old_factory(*args, **kwargs)
record.cut_path = cut_path(record.pathname, 30)
return record
logging.setLogRecordFactory(record_factory)
# -----------------------------------------------------------------------------
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'colored': { # https://github.com/borntyping/python-colorlog
'()': 'colorlog.ColoredFormatter',
'format': '%(log_color)s%(asctime)s %(levelname)8s %(cut_path)s:%(lineno)-3s %(message)s',
}
},
'handlers': {'console': {'class': 'colorlog.StreamHandler', 'formatter': 'colored'}},
'loggers': {
'': {'handlers': ['console'], 'level': 'DEBUG', 'propagate': False},
'django': {'handlers': ['console'], 'level': 'INFO', 'propagate': False},
'inventory': {'handlers': ['console'], 'level': 'DEBUG', 'propagate': False},
},
}

Wyświetl plik

@ -0,0 +1,26 @@
from django.conf.urls import include, static, url
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.urls import path
from django.views.generic import RedirectView
from inventory_project import settings
admin.autodiscover()
urlpatterns = i18n_patterns(
path('admin/', admin.site.urls),
url(r'^$', RedirectView.as_view(url='/admin/')),
path('ckeditor/', include('ckeditor_uploader.urls')), # TODO: check permissions?
)
if settings.DEBUG:
urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static.static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
import debug_toolbar
urlpatterns = [url(r'^__debug__/', include(debug_toolbar.urls))] + urlpatterns

Wyświetl plik

@ -0,0 +1,12 @@
"""
WSGI config
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "inventory_project.settings")
application = get_wsgi_application()

Wyświetl plik

@ -0,0 +1,4 @@
from inventory_project.settings import * # noqa
DEBUG = True

Wyświetl plik

@ -0,0 +1,17 @@
import pytest
from django.test import TestCase
@pytest.mark.django_db
class AdminAnonymousTests(TestCase):
"""
Anonymous will be redirected to the login page.
"""
def test_login_en(self):
response = self.client.get("/en/admin/", HTTP_ACCEPT_LANGUAGE="en")
self.assertRedirects(response, expected_url="/en/admin/login/?next=/en/admin/")
def test_login_de(self):
response = self.client.get("/de/admin/", HTTP_ACCEPT_LANGUAGE="de")
self.assertRedirects(response, expected_url="/de/admin/login/?next=/de/admin/")

21
manage.py 100644
Wyświetl plik

@ -0,0 +1,21 @@
#!/usr/bin/env python3
import os
import sys
def main():
os.environ['DJANGO_SETTINGS_MODULE'] = 'inventory_project.settings'
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()

3
manage.sh 100755
Wyświetl plik

@ -0,0 +1,3 @@
#!/bin/sh
exec poetry run python3 manage.py "$@"

746
poetry.lock wygenerowano

Plik diff jest za duży Load Diff

Wyświetl plik

@ -35,7 +35,7 @@ classifiers = [
readme='README.rst'
[tool.poetry.dependencies]
python = "^3.8"
python = ">=3.7,<4.0.0"
colorama = "*" # Console colors under windows: https://pypi.org/project/colorama/
colorlog = "*" # https://github.com/borntyping/python-colorlog
gunicorn = "*" # https://gunicorn.org/
@ -45,6 +45,10 @@ gunicorn = "*" # https://gunicorn.org/
django = "2.2.*"
django-debug-toolbar = "*" # http://django-debug-toolbar.readthedocs.io/en/stable/changes.html
django-import-export = "*" # https://github.com/django-import-export/django-import-export
django-tools = "*" # https://github.com/jedie/django-tools/
django-reversion-compare = "*" # https://github.com/jedie/django-reversion-compare/
django-ckeditor = "*" # https://github.com/django-ckeditor/django-ckeditor
bx_py_utils = "*" # https://github.com/boxine/bx_py_utils
[tool.poetry.dev-dependencies]
poetry-publish = "*" # https://github.com/jedie/poetry-publish
@ -61,10 +65,7 @@ autopep8 = "*"
pyupgrade = "*"
[tool.poetry.scripts]
# run the dev. server:
inventory = "inventory_project.cli:cli"
# run manage commands:
manage = "inventory_project.__main__:manage"
manage = "inventory_project.manage:main"
update_rst_readme = "inventory_project.publish:update_readme"
publish = "inventory_project.publish:publish"

Wyświetl plik

@ -3,7 +3,7 @@
# https://pytest-django.readthedocs.io/en/latest/
[pytest]
DJANGO_SETTINGS_MODULE=inventory_project.settings_tests
DJANGO_SETTINGS_MODULE=inventory_tests.settings
testpaths =
inventory
inventory_tests

Wyświetl plik

@ -1,6 +1,6 @@
[tox]
isolated_build = True
envlist = py38,py37,py36
envlist = py39,py38,py37
skip_missing_interpreters = True
[testenv]