diff --git a/.gitignore b/.gitignore index 8d9dc8c3..8146570c 100644 --- a/.gitignore +++ b/.gitignore @@ -77,6 +77,7 @@ var/ *.egg-info/ .installed.cfg *.egg +requirements-local.* # PyInstaller # Usually these files are written by a python script from a template diff --git a/.travis.yml b/.travis.yml index 2ec2a418..df1ea53d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,11 @@ before_script: script: - flake8 - pytest -ra -vvv --cov + - | + if [ "$TRAVIS_PYTHON_VERSION" = "3.4" ]; then + pip install -q prequ + prequ check -v + fi after_success: codecov diff --git a/README.md b/README.md index 1e3de204..bdbbe01e 100644 --- a/README.md +++ b/README.md @@ -84,15 +84,13 @@ Run migrations ### Updating requirements files -Use `pip-tools` to update the `requirements*.txt` files. +Use Prequ to update the `requirements*.txt` files. - pip install -U pip # pip-tools needs pip==6.1 or higher (!) - pip install pip-tools + pip install prequ When you change requirements, set them in `requirements.in` or `requirements-dev.in`. Then run: - pip-compile requirements.in - pip-compile requirements-dev.in + prequ update ### Running tests diff --git a/parkings/importers/parking_areas.py b/parkings/importers/parking_areas.py index cbb1c9d9..ea043e29 100644 --- a/parkings/importers/parking_areas.py +++ b/parkings/importers/parking_areas.py @@ -149,7 +149,7 @@ def _download(self): typename='avoindata:liikennemerkkipilotti_pysakointipaikat', ) return etree.fromstring(bytes(response.getvalue(), 'UTF-8')) - except: + except Exception: logger.error('Unable to get data from the server.', exc_info=True) def _parse_member(self, member): @@ -187,7 +187,7 @@ def _parse_member(self, member): self.ns, ).text ) - except: + except Exception: capacity_estimate = None geom = self._get_polygons(data.find('avoindata:geom', self.ns)) diff --git a/parkkihubi/middleware.py b/parkkihubi/middleware.py new file mode 100644 index 00000000..6faa2744 --- /dev/null +++ b/parkkihubi/middleware.py @@ -0,0 +1,31 @@ +import contextlib +from functools import lru_cache + +from django.conf import settings +from django.urls import reverse +from django.utils import timezone + +# No-op context manager +# +# Usable like the one coming in Python 3.7, see +# https://github.com/python/cpython/commit/0784a2e5b174d2dbf7b144d480559e650c5cf64c +nullcontext = contextlib.ExitStack + + +class AdminTimezoneMiddleware: + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + tz_overrider = nullcontext() + if request.path.startswith(get_admin_url_path_prefix()): + admin_tz = getattr(settings, 'ADMIN_TIME_ZONE', None) + if admin_tz: + tz_overrider = timezone.override(admin_tz) + with tz_overrider: + return self.get_response(request) + + +@lru_cache() +def get_admin_url_path_prefix(): + return reverse('admin:index') diff --git a/parkkihubi/settings.py b/parkkihubi/settings.py index e950ac7a..365f874a 100644 --- a/parkkihubi/settings.py +++ b/parkkihubi/settings.py @@ -87,10 +87,11 @@ ############## # Middleware # ############## -MIDDLEWARE_CLASSES = [ +MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', + 'parkkihubi.middleware.AdminTimezoneMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', @@ -133,7 +134,8 @@ # Languages & Localization # ############################ LANGUAGE_CODE = 'en' -TIME_ZONE = 'Europe/Helsinki' +TIME_ZONE = 'UTC' +ADMIN_TIME_ZONE = 'Europe/Helsinki' USE_I18N = True USE_L10N = True USE_TZ = True @@ -159,6 +161,7 @@ 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',), 'EXCEPTION_HANDLER': 'parkings.exception_handler.parkings_exception_handler', 'PAGE_SIZE': 20, + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'TEST_REQUEST_DEFAULT_FORMAT': 'json', } diff --git a/requirements-dev.in b/requirements-dev.in index 8900195b..41f9a446 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -11,3 +11,7 @@ pytest-cov pytest-django pytest-factoryboy werkzeug + +# Factory Boy 2.9.0 to 2.9.2 don't seem to work. See +# https://github.com/pytest-dev/pytest-factoryboy/issues/47 +factory-boy!=2.9.0,!=2.9.1,!=2.9.2 diff --git a/requirements-dev.txt b/requirements-dev.txt index fbf7dd9f..4a2e038e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,42 +1,44 @@ +# This file is autogenerated by Prequ. To update, run: # -# This file is autogenerated by pip-compile -# To update, run: +# prequ update # -# pip-compile --output-file requirements-dev.txt requirements-dev.in -# -appnope==0.1.0 # via ipython -autoflake==0.7 -autopep8==1.3.2 -coverage==4.4.1 # via pytest-cov +attrs==17.3.0 # via pytest +autoflake==1.0 +autopep8==1.3.3 +coverage==4.4.2 # via pytest-cov decorator==4.1.2 # via ipython, traitlets -django-extensions==1.9.0 -factory-boy==2.8.1 # via pytest-factoryboy -faker==0.7.18 # via factory-boy -flake8==3.4.1 +django-extensions==1.9.8 +factory-boy==2.8.1 +faker==0.8.7 # via factory-boy +flake8==3.5.0 freezegun==0.3.9 inflection==0.3.1 # via pytest-factoryboy +ipython==6.2.1 ipython-genutils==0.2.0 # via traitlets -ipython==6.1.0 isort==4.2.15 -jedi==0.10.2 # via ipython +jedi==0.11.0 # via ipython mccabe==0.6.1 # via flake8 -pexpect==4.2.1 # via ipython +parso==0.1.0 # via jedi +pexpect==4.3.0 # via ipython pickleshare==0.7.4 # via ipython +pluggy==0.6.0 # via pytest prompt-toolkit==1.0.15 # via ipython ptyprocess==0.5.2 # via pexpect -py==1.4.34 # via pytest +py==1.5.2 # via pytest pycodestyle==2.3.1 # via autopep8, flake8 -pydocstyle==2.0.0 -pyflakes==1.5.0 # via autoflake, flake8 +pydocstyle==2.1.1 +pyflakes==1.6.0 # via autoflake, flake8 pygments==2.2.0 # via ipython +pytest==3.3.1 pytest-cov==2.5.1 pytest-django==3.1.2 pytest-factoryboy==1.3.1 -pytest==3.2.1 python-dateutil==2.6.1 # via faker, freezegun simplegeneric==0.8.1 # via ipython -six==1.10.0 # via django-extensions, faker, freezegun, prompt-toolkit, pydocstyle, python-dateutil, traitlets +six==1.11.0 # via django-extensions, faker, freezegun, prompt-toolkit, pydocstyle, pytest, python-dateutil, traitlets snowballstemmer==1.2.1 # via pydocstyle +text-unidecode==1.1 # via faker traitlets==4.3.2 # via ipython +typing==3.6.2 # via django-extensions, ipython wcwidth==0.1.7 # via prompt-toolkit -werkzeug==0.12.2 +werkzeug==0.13 diff --git a/requirements.in b/requirements.in index 7836f290..7a35fe74 100644 --- a/requirements.in +++ b/requirements.in @@ -1,5 +1,5 @@ # Django -Django +Django~=1.11 # Settings django-environ diff --git a/requirements.txt b/requirements.txt index 423d0576..bf3b14d9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,25 +1,22 @@ +# This file is autogenerated by Prequ. To update, run: # -# This file is autogenerated by pip-compile -# To update, run: +# prequ update # -# pip-compile --output-file requirements.txt requirements.in -# -certifi==2017.7.27.1 # via requests +certifi==2017.11.5 # via requests chardet==3.0.4 # via requests -contextlib2==0.5.5 # via raven +django==1.11.8 django-environ==0.4.4 -django-filter==1.0.4 -django==1.11.4 # via django-environ -djangorestframework-gis==0.11.2 -djangorestframework==3.6.4 +django-filter==1.1.0 +djangorestframework==3.7.3 +djangorestframework-gis==0.12 idna==2.6 # via requests -lxml==3.8.0 -owslib==0.14.0 -psycopg2==2.7.3.1 +lxml==4.1.1 +owslib==0.15.0 +psycopg2==2.7.3.2 pyproj==1.9.5.1 # via owslib python-dateutil==2.6.1 # via owslib -pytz==2017.2 -raven==6.1.0 +pytz==2017.3 +raven==6.3.0 requests==2.18.4 # via owslib -six==1.10.0 # via django-environ, python-dateutil +six==1.11.0 # via django-environ, djangorestframework-gis, python-dateutil urllib3==1.22 # via requests diff --git a/setup.cfg b/setup.cfg index 27130ce5..a4b13812 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,3 +1,6 @@ +[prequ] +annotate = yes + [pep8] max-line-length = 120 exclude = *migrations*