From a08d6e044b7387cf8ee5735a7064f4887097ef44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 1 Sep 2019 00:25:25 +0200 Subject: [PATCH 1/3] Use poetry to control the projects dependencies. Also setup black for pre-commit. --- .pre-commit-config.yaml | 33 ++-- Makefile | 12 +- README.md | 24 +++ README.rst | 19 -- poetry.lock | 415 ++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 20 ++ requirements.txt | 2 - requirements_dev.txt | 3 - 8 files changed, 484 insertions(+), 44 deletions(-) create mode 100644 README.md delete mode 100644 README.rst create mode 100644 poetry.lock create mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 requirements_dev.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2b36a80..0c7675a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,21 @@ repos: -- repo: git://github.com/pre-commit/pre-commit-hooks - rev: v1.3.0 - hooks: - - id: trailing-whitespace - - id: flake8 - - id: check-yaml - - id: check-added-large-files - - id: debug-statements - - id: end-of-file-fixer -- repo: https://github.com/asottile/reorder_python_imports - rev: v1.0.1 - hooks: - - id: reorder-python-imports +- repo: git://github.com/pre-commit/pre-commit-hooks + rev: v1.3.0 + hooks: + - id: trailing-whitespace + - id: flake8 + - id: check-yaml + - id: check-added-large-files + - id: debug-statements + - id: end-of-file-fixer +- repo: https://github.com/asottile/reorder_python_imports + rev: v1.0.1 + hooks: + - id: reorder-python-imports + types: [file, python] +- repo: https://github.com/psf/black + rev: stable + hooks: + - id: black + language: python + types: [file, python] diff --git a/Makefile b/Makefile index d57229e..3f22263 100644 --- a/Makefile +++ b/Makefile @@ -2,14 +2,12 @@ # are supposed to be run, but feel free to change them! dev-setup: - pip install -r requirements_dev.txt --upgrade - pip install -r requirements.txt --upgrade - pre-commit install - python manage.py migrate - python manage.py createsuperuser + poetry run pre-commit install + poetry run python manage.py migrate + poetry run python manage.py createsuperuser lint: - pre-commit run --all + poetry run pre-commit run --all test: - pytest + poetry run pytest diff --git a/README.md b/README.md new file mode 100644 index 0000000..a93d8f2 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# member.data.coop + +To start developing: + +Get poetry + + $ python3 -m pip install --user pipx + $ pipx install poetry + +Run poetry to setup environment + + $ poetry install + +Run this make target, which installs all the requirements and sets up a development database. + + $ make dev-setup + +To run the Django development server: + + $ poetry run python manage.py runserver + +Before you push your stuff, run tests: + + $ make test diff --git a/README.rst b/README.rst deleted file mode 100644 index 2ac2ce6..0000000 --- a/README.rst +++ /dev/null @@ -1,19 +0,0 @@ -member.data.coop -================ - -To start developing: - - # Create a virtualenv with python 3 - $ mkvirtualenv -p python3 datacoop - - # Run this make target, which installs all the requirements and sets up a - # development database. - $ make dev-setup - -To run the Django development server: - - $ python manage.py runserver - -Before you push your stuff, run tests: - - $ make test diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..eee2170 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,415 @@ +[[package]] +category = "dev" +description = "A few extensions to pyyaml." +name = "aspy.yaml" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.3.0" + +[package.dependencies] +pyyaml = "*" + +[[package]] +category = "dev" +description = "Atomic file writes." +name = "atomicwrites" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.3.0" + +[[package]] +category = "dev" +description = "Classes Without Boilerplate" +name = "attrs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "19.1.0" + +[[package]] +category = "main" +description = "Python package for providing Mozilla's CA Bundle." +name = "certifi" +optional = false +python-versions = "*" +version = "2019.6.16" + +[[package]] +category = "dev" +description = "Validate configuration and produce human readable error messages." +name = "cfgv" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.0.1" + +[package.dependencies] +six = "*" + +[[package]] +category = "main" +description = "Universal encoding detector for Python 2 and 3" +name = "chardet" +optional = false +python-versions = "*" +version = "3.0.4" + +[[package]] +category = "dev" +description = "Cross-platform colored terminal text." +marker = "sys_platform == \"win32\"" +name = "colorama" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.4.1" + +[[package]] +category = "main" +description = "XML bomb protection for Python stdlib modules" +name = "defusedxml" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.6.0" + +[[package]] +category = "main" +description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." +name = "django" +optional = false +python-versions = ">=3.5" +version = "2.2.4" + +[package.dependencies] +pytz = "*" +sqlparse = "*" + +[[package]] +category = "main" +description = "Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication." +name = "django-allauth" +optional = false +python-versions = "*" +version = "0.40.0" + +[package.dependencies] +Django = ">=1.11" +python3-openid = ">=3.0.8" +requests = "*" +requests-oauthlib = ">=0.3.0" + +[[package]] +category = "main" +description = "Adds support for using money and currency fields in django models and forms. Uses py-moneyed as the money implementation." +name = "django-money" +optional = false +python-versions = "*" +version = "0.15" + +[package.dependencies] +Django = ">=1.8" +py-moneyed = ">=0.8" +setuptools = "*" + +[[package]] +category = "dev" +description = "File identification library for Python" +name = "identify" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.4.7" + +[[package]] +category = "main" +description = "Internationalized Domain Names in Applications (IDNA)" +name = "idna" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.8" + +[[package]] +category = "dev" +description = "Read metadata from Python packages" +name = "importlib-metadata" +optional = false +python-versions = ">=2.7,!=3.0,!=3.1,!=3.2,!=3.3" +version = "0.19" + +[package.dependencies] +zipp = ">=0.5" + +[[package]] +category = "dev" +description = "More routines for operating on iterables, beyond itertools" +name = "more-itertools" +optional = false +python-versions = ">=3.4" +version = "7.2.0" + +[[package]] +category = "dev" +description = "Node.js virtual environment builder" +name = "nodeenv" +optional = false +python-versions = "*" +version = "1.3.3" + +[[package]] +category = "main" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +name = "oauthlib" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.1.0" + +[[package]] +category = "dev" +description = "Core utilities for Python packages" +name = "packaging" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "19.1" + +[package.dependencies] +attrs = "*" +pyparsing = ">=2.0.2" +six = "*" + +[[package]] +category = "dev" +description = "plugin and hook calling mechanisms for python" +name = "pluggy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.12.0" + +[package.dependencies] +importlib-metadata = ">=0.12" + +[[package]] +category = "dev" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +name = "pre-commit" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.18.3" + +[package.dependencies] +"aspy.yaml" = "*" +cfgv = ">=2.0.0" +identify = ">=1.0.0" +importlib-metadata = "*" +nodeenv = ">=0.11.1" +pyyaml = "*" +six = "*" +toml = "*" +virtualenv = ">=15.2" + +[[package]] +category = "dev" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "py" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.8.0" + +[[package]] +category = "main" +description = "Provides Currency and Money classes for use in your Python code." +name = "py-moneyed" +optional = false +python-versions = "*" +version = "0.8.0" + +[[package]] +category = "dev" +description = "Python parsing module" +name = "pyparsing" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "2.4.2" + +[[package]] +category = "dev" +description = "pytest: simple powerful testing with Python" +name = "pytest" +optional = false +python-versions = ">=3.5" +version = "5.1.2" + +[package.dependencies] +atomicwrites = ">=1.0" +attrs = ">=17.4.0" +colorama = "*" +more-itertools = ">=4.0.0" +packaging = "*" +pluggy = ">=0.12,<1.0" +py = ">=1.5.0" +wcwidth = "*" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + +[[package]] +category = "dev" +description = "A Django plugin for pytest." +name = "pytest-django" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.5.1" + +[package.dependencies] +pytest = ">=3.6" + +[[package]] +category = "main" +description = "OpenID support for modern servers and consumers." +name = "python3-openid" +optional = false +python-versions = "*" +version = "3.1.0" + +[package.dependencies] +defusedxml = "*" + +[[package]] +category = "main" +description = "World timezone definitions, modern and historical" +name = "pytz" +optional = false +python-versions = "*" +version = "2019.2" + +[[package]] +category = "dev" +description = "YAML parser and emitter for Python" +name = "pyyaml" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "5.1.2" + +[[package]] +category = "main" +description = "Python HTTP for Humans." +name = "requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.22.0" + +[package.dependencies] +certifi = ">=2017.4.17" +chardet = ">=3.0.2,<3.1.0" +idna = ">=2.5,<2.9" +urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" + +[[package]] +category = "main" +description = "OAuthlib authentication support for Requests." +name = "requests-oauthlib" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.2.0" + +[package.dependencies] +oauthlib = ">=3.0.0" +requests = ">=2.0.0" + +[[package]] +category = "dev" +description = "Python 2 and 3 compatibility utilities" +name = "six" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*" +version = "1.12.0" + +[[package]] +category = "main" +description = "Non-validating SQL parser" +name = "sqlparse" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.3.0" + +[[package]] +category = "dev" +description = "Python Library for Tom's Obvious, Minimal Language" +name = "toml" +optional = false +python-versions = "*" +version = "0.10.0" + +[[package]] +category = "main" +description = "HTTP library with thread-safe connection pooling, file post, and more." +name = "urllib3" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" +version = "1.25.3" + +[[package]] +category = "dev" +description = "Virtual Python Environment builder" +name = "virtualenv" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "16.7.4" + +[[package]] +category = "dev" +description = "Measures number of Terminal column cells of wide-character codes" +name = "wcwidth" +optional = false +python-versions = "*" +version = "0.1.7" + +[[package]] +category = "dev" +description = "Backport of pathlib-compatible object wrapper for zip files" +name = "zipp" +optional = false +python-versions = ">=2.7" +version = "0.6.0" + +[package.dependencies] +more-itertools = "*" + +[metadata] +content-hash = "2ce01170127003b7107bd9d94d7225f3860356ebb3cda1bee98f894e82cf8d99" +python-versions = "^3.7" + +[metadata.hashes] +"aspy.yaml" = ["463372c043f70160a9ec950c3f1e4c3a82db5fca01d334b6bc89c7164d744bdc", "e7c742382eff2caed61f87a39d13f99109088e5e93f04d76eb8d4b28aa143f45"] +atomicwrites = ["03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", "75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"] +attrs = ["69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", "f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"] +certifi = ["046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", "945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695"] +cfgv = ["edb387943b665bf9c434f717bf630fa78aecd53d5900d2e05da6ad6048553144", "fbd93c9ab0a523bf7daec408f3be2ed99a980e20b2d19b50fc184ca6b820d289"] +chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"] +colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"] +defusedxml = ["6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93", "f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5"] +django = ["16a5d54411599780ac9dfe3b9b38f90f785c51259a584e0b24b6f14a7f69aae8", "9a2f98211ab474c710fcdad29c82f30fc14ce9917c7a70c3682162a624de4035"] +django-allauth = ["6a189fc4d3ee23596c3fd6e9f49c59b5b15618980118171a50675dd6a27cc589"] +django-money = ["4ce2d6a085739b4982cb6205fedfed4541295405e3e5001c4fad8f486c331997", "791e4454a970c1078db31a4a74a991cd13a75921c51dcaeaebd07fb4daa8114a"] +identify = ["4f1fe9a59df4e80fcb0213086fcf502bc1765a01ea4fe8be48da3b65afd2a017", "d8919589bd2a5f99c66302fec0ef9027b12ae150b0b0213999ad3f695fc7296e"] +idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"] +importlib-metadata = ["23d3d873e008a513952355379d93cbcab874c58f4f034ff657c7a87422fa64e8", "80d2de76188eabfbfcf27e6a37342c2827801e59c4cc14b0371c56fed43820e3"] +more-itertools = ["409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", "92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"] +nodeenv = ["ad8259494cf1c9034539f6cced78a1da4840a4b157e23640bc4a0c0546b0cb7a"] +oauthlib = ["bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889", "df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea"] +packaging = ["a7ac867b97fdc07ee80a8058fe4435ccd274ecc3b0ed61d852d7d53055528cf9", "c491ca87294da7cc01902edbe30a5bc6c4c28172b5138ab4e4aa1b9d7bfaeafe"] +pluggy = ["0825a152ac059776623854c1543d65a4ad408eb3d33ee114dff91e57ec6ae6fc", "b9817417e95936bf75d85d3f8767f7df6cdde751fc40aed3bb3074cbcb77757c"] +pre-commit = ["1d3c0587bda7c4e537a46c27f2c84aa006acc18facf9970bf947df596ce91f3f", "fa78ff96e8e9ac94c748388597693f18b041a181c94a4f039ad20f45287ba44a"] +py = ["64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", "dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"] +py-moneyed = ["c6691b914a5e4b5b2335cf113620479a52cc82988c0e143435a7c5c7d60cd4ad", "ec73795171919d537880a33c44d07fcdf0a5225e8368684fe02f0e75a6404742"] +pyparsing = ["6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", "d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4"] +pytest = ["95d13143cc14174ca1a01ec68e84d76ba5d9d493ac02716fd9706c949a505210", "b78fe2881323bd44fd9bd76e5317173d4316577e7b1cddebae9136a4495ec865"] +pytest-django = ["264fb4c506db5d48a6364c311a0b00b7b48a52715bad8839b2d8bee9b99ed6bb", "4adfe5fb3ed47f0ba55506dd3daf688b1f74d5e69148c10ad2dd2f79f40c0d62"] +python3-openid = ["0086da6b6ef3161cfe50fb1ee5cceaf2cda1700019fda03c2c5c440ca6abe4fa", "628d365d687e12da12d02c6691170f4451db28d6d68d050007e4a40065868502"] +pytz = ["26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32", "c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7"] +pyyaml = ["0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9", "01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4", "5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8", "5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696", "7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34", "7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9", "87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73", "9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299", "a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b", "b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae", "b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681", "bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41", "f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"] +requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"] +requests-oauthlib = ["bd6533330e8748e94bf0b214775fed487d309b8b8fe823dc45641ebcd9a32f57", "d3ed0c8f2e3bbc6b344fa63d6f933745ab394469da38db16bdddb461c7e25140", "dd5a0499abfefd087c6dd96693cbd5bfd28aa009719a7f85ab3fabe3956ef19a"] +six = ["3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"] +sqlparse = ["40afe6b8d4b1117e7dff5504d7a8ce07d9a1b15aeeade8a2d10f130a834f8177", "7c3dca29c022744e95b547e867cee89f4fce4373f3549ccd8797d8eb52cdb873"] +toml = ["229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", "235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e", "f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"] +urllib3 = ["b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", "dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"] +virtualenv = ["94a6898293d07f84a98add34c4df900f8ec64a570292279f6d91c781d37fd305", "f6fc312c031f2d2344f885de114f1cb029dfcffd26aa6e57d2ee2296935c4e7d"] +wcwidth = ["3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", "f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"] +zipp = ["3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e", "f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335"] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..86eb875 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,20 @@ +[tool.poetry] +name = "membersystem" +version = "0.1.0" +description = "" +authors = ["Your Name "] + +[tool.poetry.dependencies] +python = "^3.7" +Django = "^2.2" +django-money = "^0.15.0" +django-allauth = "^0.40.0" + +[tool.poetry.dev-dependencies] +pre-commit = "^1.18" +pytest = "^5.1" +pytest-django = "^3.5" + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 6fa7cbf..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -Django>=2.2,<2.3 -django-money==0.15 diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index ad11934..0000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,3 +0,0 @@ -pytest -pytest-django -pre-commit From c4596c25c6594d4b7602d913ec68df4423c0f5df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 1 Sep 2019 00:27:36 +0200 Subject: [PATCH 2/3] Run linting (aka the blackening) --- accounting/admin.py | 7 +- accounting/apps.py | 2 +- accounting/migrations/0001_initial.py | 251 ++++++++++++++++++++------ accounting/models.py | 61 ++----- accounting/tests.py | 5 +- manage.py | 2 +- membership/apps.py | 2 +- membership/migrations/0001_initial.py | 230 +++++++++++++++++------ membership/models.py | 47 ++--- project/context_processors.py | 4 +- project/settings/base.py | 101 +++++------ project/urls.py | 4 +- users/admin.py | 4 +- users/apps.py | 2 +- users/migrations/0001_initial.py | 75 ++++++-- users/models.py | 12 +- users/urls.py | 67 +++++-- users/views.py | 14 +- 18 files changed, 590 insertions(+), 300 deletions(-) diff --git a/accounting/admin.py b/accounting/admin.py index 41d2755..61e4ada 100644 --- a/accounting/admin.py +++ b/accounting/admin.py @@ -7,22 +7,25 @@ from . import models @admin.register(models.Order) class OrderAdmin(admin.ModelAdmin): - list_display = ('who', 'description', 'created', 'is_paid',) + list_display = ("who", "description", "created", "is_paid") def who(self, instance): return instance.user.get_full_name() + who.short_description = _("Customer") @admin.register(models.Payment) class PaymentAdmin(admin.ModelAdmin): - list_display = ('who', 'description', 'order_id', 'created',) + list_display = ("who", "description", "order_id", "created") def who(self, instance): return instance.order.user.get_full_name() + who.short_description = _("Customer") def order_id(self, instance): return instance.order.id + order_id.short_description = _("Order ID") diff --git a/accounting/apps.py b/accounting/apps.py index bbcd3d0..e142288 100644 --- a/accounting/apps.py +++ b/accounting/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class AccountingConfig(AppConfig): - name = 'accounting' + name = "accounting" diff --git a/accounting/migrations/0001_initial.py b/accounting/migrations/0001_initial.py index a226af6..23a2ef0 100644 --- a/accounting/migrations/0001_initial.py +++ b/accounting/migrations/0001_initial.py @@ -12,73 +12,222 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] + dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)] operations = [ migrations.CreateModel( - name='Account', + name="Account", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')), - ('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "modified", + models.DateTimeField(auto_now=True, verbose_name="modified"), + ), + ( + "created", + models.DateTimeField(auto_now_add=True, verbose_name="created"), + ), + ( + "owner", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), migrations.CreateModel( - name='Order', + name="Order", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')), - ('description', models.CharField(max_length=1024, verbose_name='description')), - ('price_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)), - ('price', djmoney.models.fields.MoneyField(decimal_places=2, default=Decimal('0.0'), max_digits=16, verbose_name='price (excl. VAT)')), - ('vat_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)), - ('vat', djmoney.models.fields.MoneyField(decimal_places=2, default=Decimal('0.0'), max_digits=16, verbose_name='VAT')), - ('is_paid', models.BooleanField(default=False, verbose_name='is paid')), - ('account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='accounting.Account')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "modified", + models.DateTimeField(auto_now=True, verbose_name="modified"), + ), + ( + "created", + models.DateTimeField(auto_now_add=True, verbose_name="created"), + ), + ( + "description", + models.CharField(max_length=1024, verbose_name="description"), + ), + ( + "price_currency", + djmoney.models.fields.CurrencyField( + choices=[("DKK", "DKK")], + default="XYZ", + editable=False, + max_length=3, + ), + ), + ( + "price", + djmoney.models.fields.MoneyField( + decimal_places=2, + default=Decimal("0.0"), + max_digits=16, + verbose_name="price (excl. VAT)", + ), + ), + ( + "vat_currency", + djmoney.models.fields.CurrencyField( + choices=[("DKK", "DKK")], + default="XYZ", + editable=False, + max_length=3, + ), + ), + ( + "vat", + djmoney.models.fields.MoneyField( + decimal_places=2, + default=Decimal("0.0"), + max_digits=16, + verbose_name="VAT", + ), + ), + ("is_paid", models.BooleanField(default=False, verbose_name="is paid")), + ( + "account", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="accounting.Account", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), ], - options={ - 'verbose_name': 'Order', - 'verbose_name_plural': 'Orders', - }, + options={"verbose_name": "Order", "verbose_name_plural": "Orders"}, ), migrations.CreateModel( - name='Payment', + name="Payment", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')), - ('amount_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)), - ('amount', djmoney.models.fields.MoneyField(decimal_places=2, default=Decimal('0.0'), max_digits=16)), - ('description', models.CharField(max_length=1024, verbose_name='description')), - ('stripe_charge_id', models.CharField(blank=True, max_length=255, null=True)), - ('order', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='accounting.Order')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "modified", + models.DateTimeField(auto_now=True, verbose_name="modified"), + ), + ( + "created", + models.DateTimeField(auto_now_add=True, verbose_name="created"), + ), + ( + "amount_currency", + djmoney.models.fields.CurrencyField( + choices=[("DKK", "DKK")], + default="XYZ", + editable=False, + max_length=3, + ), + ), + ( + "amount", + djmoney.models.fields.MoneyField( + decimal_places=2, default=Decimal("0.0"), max_digits=16 + ), + ), + ( + "description", + models.CharField(max_length=1024, verbose_name="description"), + ), + ( + "stripe_charge_id", + models.CharField(blank=True, max_length=255, null=True), + ), + ( + "order", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="accounting.Order", + ), + ), ], - options={ - 'verbose_name': 'payment', - 'verbose_name_plural': 'payments', - }, + options={"verbose_name": "payment", "verbose_name_plural": "payments"}, ), migrations.CreateModel( - name='Transaction', + name="Transaction", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')), - ('amount_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)), - ('amount', djmoney.models.fields.MoneyField(decimal_places=2, default=Decimal('0.0'), help_text='This will include VAT', max_digits=16, verbose_name='amount')), - ('description', models.CharField(max_length=1024, verbose_name='description')), - ('account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='transactions', to='accounting.Account')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "modified", + models.DateTimeField(auto_now=True, verbose_name="modified"), + ), + ( + "created", + models.DateTimeField(auto_now_add=True, verbose_name="created"), + ), + ( + "amount_currency", + djmoney.models.fields.CurrencyField( + choices=[("DKK", "DKK")], + default="XYZ", + editable=False, + max_length=3, + ), + ), + ( + "amount", + djmoney.models.fields.MoneyField( + decimal_places=2, + default=Decimal("0.0"), + help_text="This will include VAT", + max_digits=16, + verbose_name="amount", + ), + ), + ( + "description", + models.CharField(max_length=1024, verbose_name="description"), + ), + ( + "account", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="transactions", + to="accounting.Account", + ), + ), ], - options={ - 'abstract': False, - }, + options={"abstract": False}, ), ] diff --git a/accounting/models.py b/accounting/models.py index 0b55eb3..d7aa141 100644 --- a/accounting/models.py +++ b/accounting/models.py @@ -11,14 +11,8 @@ from djmoney.models.fields import MoneyField class CreatedModifiedAbstract(models.Model): - modified = models.DateTimeField( - auto_now=True, - verbose_name=_("modified"), - ) - created = models.DateTimeField( - auto_now_add=True, - verbose_name=_("created"), - ) + modified = models.DateTimeField(auto_now=True, verbose_name=_("modified")) + created = models.DateTimeField(auto_now_add=True, verbose_name=_("created")) class Meta: abstract = True @@ -34,7 +28,7 @@ class Account(CreatedModifiedAbstract): @property def balance(self): - return self.transactions.all().aggregate(Sum('amount')).get('amount', 0) + return self.transactions.all().aggregate(Sum("amount")).get("amount", 0) class Transaction(CreatedModifiedAbstract): @@ -44,20 +38,15 @@ class Transaction(CreatedModifiedAbstract): """ account = models.ForeignKey( - Account, - on_delete=models.PROTECT, - related_name="transactions", + Account, on_delete=models.PROTECT, related_name="transactions" ) amount = MoneyField( verbose_name=_("amount"), max_digits=16, decimal_places=2, - help_text=_("This will include VAT") - ) - description = models.CharField( - max_length=1024, - verbose_name=_("description") + help_text=_("This will include VAT"), ) + description = models.CharField(max_length=1024, verbose_name=_("description")) class Order(CreatedModifiedAbstract): @@ -71,26 +60,14 @@ class Order(CreatedModifiedAbstract): account = models.ForeignKey(Account, on_delete=models.PROTECT) is_paid = models.BooleanField(default=False) - description = models.CharField( - max_length=1024, - verbose_name=_("description") - ) + description = models.CharField(max_length=1024, verbose_name=_("description")) price = MoneyField( - verbose_name=_("price (excl. VAT)"), - max_digits=16, - decimal_places=2, - ) - vat = MoneyField( - verbose_name=_("VAT"), - max_digits=16, - decimal_places=2, + verbose_name=_("price (excl. VAT)"), max_digits=16, decimal_places=2 ) + vat = MoneyField(verbose_name=_("VAT"), max_digits=16, decimal_places=2) - is_paid = models.BooleanField( - default=False, - verbose_name=_("is paid"), - ) + is_paid = models.BooleanField(default=False, verbose_name=_("is paid")) @property def total(self): @@ -105,7 +82,7 @@ class Order(CreatedModifiedAbstract): pk = str(self.pk).encode("utf-8") x = md5() x.update(pk) - extra_hash = (settings.SECRET_KEY + 'blah').encode('utf-8') + extra_hash = (settings.SECRET_KEY + "blah").encode("utf-8") x.update(extra_hash) return x.hexdigest() @@ -119,22 +96,12 @@ class Order(CreatedModifiedAbstract): class Payment(CreatedModifiedAbstract): - amount = MoneyField( - max_digits=16, - decimal_places=2, - ) + amount = MoneyField(max_digits=16, decimal_places=2) order = models.ForeignKey(Order, on_delete=models.PROTECT) - description = models.CharField( - max_length=1024, - verbose_name=_("description") - ) + description = models.CharField(max_length=1024, verbose_name=_("description")) - stripe_charge_id = models.CharField( - max_length=255, - null=True, - blank=True, - ) + stripe_charge_id = models.CharField(max_length=255, null=True, blank=True) @property def display_id(self): diff --git a/accounting/tests.py b/accounting/tests.py index b2e28e3..c847203 100644 --- a/accounting/tests.py +++ b/accounting/tests.py @@ -7,10 +7,9 @@ from . import models # def test(): # do stuff + @pytest.mark.django_db def test_balance(): user = User.objects.create_user("test", "lala@adas.com", "1234") - account = models.Account.objects.create( - owner=user - ) + account = models.Account.objects.create(owner=user) assert account.balance == 0 diff --git a/manage.py b/manage.py index 0b8fe53..548b6a5 100755 --- a/manage.py +++ b/manage.py @@ -6,7 +6,7 @@ if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") try: from django.core.management import execute_from_command_line - except ImportError as exc: + except ImportError: raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " diff --git a/membership/apps.py b/membership/apps.py index 537f521..d4f0399 100644 --- a/membership/apps.py +++ b/membership/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class MembershipConfig(AppConfig): - name = 'membership' + name = "membership" diff --git a/membership/migrations/0001_initial.py b/membership/migrations/0001_initial.py index 70b3ad8..2a32dcf 100644 --- a/membership/migrations/0001_initial.py +++ b/membership/migrations/0001_initial.py @@ -12,90 +12,216 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] + dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)] operations = [ migrations.CreateModel( - name='Membership', + name="Membership", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')), - ('can_vote', models.BooleanField(default=False, help_text='Indicates that the user has a democratic membership of the organization.', verbose_name='can vote')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "modified", + models.DateTimeField(auto_now=True, verbose_name="modified"), + ), + ( + "created", + models.DateTimeField(auto_now_add=True, verbose_name="created"), + ), + ( + "can_vote", + models.BooleanField( + default=False, + help_text="Indicates that the user has a democratic membership of the organization.", + verbose_name="can vote", + ), + ), ], options={ - 'verbose_name': 'membership', - 'verbose_name_plural': 'memberships', + "verbose_name": "membership", + "verbose_name_plural": "memberships", }, ), migrations.CreateModel( - name='Organization', + name="Organization", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')), - ('name', models.CharField(max_length=64, verbose_name='name')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "modified", + models.DateTimeField(auto_now=True, verbose_name="modified"), + ), + ( + "created", + models.DateTimeField(auto_now_add=True, verbose_name="created"), + ), + ("name", models.CharField(max_length=64, verbose_name="name")), ], options={ - 'verbose_name': 'organization', - 'verbose_name_plural': 'organizations', + "verbose_name": "organization", + "verbose_name_plural": "organizations", }, ), migrations.CreateModel( - name='Subscription', + name="Subscription", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')), - ('active', models.BooleanField(default=False, help_text='Automatically set by payment system.', verbose_name='active')), - ('starts', models.DateField()), - ('ends', models.DateField()), - ('renewed_subscription', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='membership.Subscription', verbose_name='renewed subscription')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "modified", + models.DateTimeField(auto_now=True, verbose_name="modified"), + ), + ( + "created", + models.DateTimeField(auto_now_add=True, verbose_name="created"), + ), + ( + "active", + models.BooleanField( + default=False, + help_text="Automatically set by payment system.", + verbose_name="active", + ), + ), + ("starts", models.DateField()), + ("ends", models.DateField()), + ( + "renewed_subscription", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="membership.Subscription", + verbose_name="renewed subscription", + ), + ), ], options={ - 'verbose_name': 'subscription', - 'verbose_name_plural': 'subscriptions', + "verbose_name": "subscription", + "verbose_name_plural": "subscriptions", }, ), migrations.CreateModel( - name='SubscriptionType', + name="SubscriptionType", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), - ('created', models.DateTimeField(auto_now_add=True, verbose_name='created')), - ('name', models.CharField(max_length=64, verbose_name='name')), - ('fee_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)), - ('fee', djmoney.models.fields.MoneyField(decimal_places=2, default=Decimal('0.0'), max_digits=16)), - ('fee_vat_currency', djmoney.models.fields.CurrencyField(choices=[('DKK', 'DKK')], default='XYZ', editable=False, max_length=3)), - ('fee_vat', djmoney.models.fields.MoneyField(decimal_places=2, default=Decimal('0'), max_digits=16)), - ('duration', models.PositiveSmallIntegerField(choices=[(1, 'annual')], default=1, verbose_name='duration')), - ('organization', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='membership.Organization')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "modified", + models.DateTimeField(auto_now=True, verbose_name="modified"), + ), + ( + "created", + models.DateTimeField(auto_now_add=True, verbose_name="created"), + ), + ("name", models.CharField(max_length=64, verbose_name="name")), + ( + "fee_currency", + djmoney.models.fields.CurrencyField( + choices=[("DKK", "DKK")], + default="XYZ", + editable=False, + max_length=3, + ), + ), + ( + "fee", + djmoney.models.fields.MoneyField( + decimal_places=2, default=Decimal("0.0"), max_digits=16 + ), + ), + ( + "fee_vat_currency", + djmoney.models.fields.CurrencyField( + choices=[("DKK", "DKK")], + default="XYZ", + editable=False, + max_length=3, + ), + ), + ( + "fee_vat", + djmoney.models.fields.MoneyField( + decimal_places=2, default=Decimal("0"), max_digits=16 + ), + ), + ( + "duration", + models.PositiveSmallIntegerField( + choices=[(1, "annual")], default=1, verbose_name="duration" + ), + ), + ( + "organization", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="membership.Organization", + ), + ), ], options={ - 'verbose_name': 'subscription type', - 'verbose_name_plural': 'subscription types', + "verbose_name": "subscription type", + "verbose_name_plural": "subscription types", }, ), migrations.AddField( - model_name='subscription', - name='subscription_type', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='memberships', to='membership.SubscriptionType', verbose_name='subscription type'), + model_name="subscription", + name="subscription_type", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="memberships", + to="membership.SubscriptionType", + verbose_name="subscription type", + ), ), migrations.AddField( - model_name='subscription', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + model_name="subscription", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL + ), ), migrations.AddField( - model_name='membership', - name='organization', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='membership.Organization'), + model_name="membership", + name="organization", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="membership.Organization", + ), ), migrations.AddField( - model_name='membership', - name='user', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL), + model_name="membership", + name="user", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL + ), ), ] diff --git a/membership/models.py b/membership/models.py index aaca0de..ec70410 100644 --- a/membership/models.py +++ b/membership/models.py @@ -6,14 +6,8 @@ from djmoney.models.fields import MoneyField class CreatedModifiedAbstract(models.Model): - modified = models.DateTimeField( - auto_now=True, - verbose_name=_("modified"), - ) - created = models.DateTimeField( - auto_now_add=True, - verbose_name=_("created"), - ) + modified = models.DateTimeField(auto_now=True, verbose_name=_("modified")) + created = models.DateTimeField(auto_now_add=True, verbose_name=_("created")) class Meta: abstract = True @@ -24,10 +18,8 @@ class Organization(CreatedModifiedAbstract): This holds the data of the organization that someone is a member of. It is possible that we'll create more advanced features here. """ - name = models.CharField( - verbose_name=_("name"), - max_length=64, - ) + + name = models.CharField(verbose_name=_("name"), max_length=64) def __str__(self): return self.name @@ -56,14 +48,13 @@ class Membership(CreatedModifiedAbstract): help_text=_( "Indicates that the user has a democratic membership of the " "organization." - ) + ), ) def __str__(self): return _("{} is a member of {}").format( - self.user.get_full_name(), - self.organization.name, + self.user.get_full_name(), self.organization.name ) class Meta: @@ -79,26 +70,14 @@ class SubscriptionType(CreatedModifiedAbstract): organization = models.ForeignKey(Organization, on_delete=models.PROTECT) - name = models.CharField( - verbose_name=_("name"), - max_length=64, - ) + name = models.CharField(verbose_name=_("name"), max_length=64) - fee = MoneyField( - max_digits=16, - decimal_places=2, - ) + fee = MoneyField(max_digits=16, decimal_places=2) - fee_vat = MoneyField( - max_digits=16, - decimal_places=2, - default=0, - ) + fee_vat = MoneyField(max_digits=16, decimal_places=2, default=0) duration = models.PositiveSmallIntegerField( - default=1, - choices=[(1, _("annual"))], - verbose_name=_("duration"), + default=1, choices=[(1, _("annual"))], verbose_name=_("duration") ) class Meta: @@ -116,7 +95,7 @@ class Subscription(CreatedModifiedAbstract): subscription_type = models.ForeignKey( SubscriptionType, - related_name='memberships', + related_name="memberships", verbose_name=_("subscription type"), on_delete=models.PROTECT, ) @@ -125,14 +104,14 @@ class Subscription(CreatedModifiedAbstract): active = models.BooleanField( default=False, verbose_name=_("active"), - help_text=_("Automatically set by payment system.") + help_text=_("Automatically set by payment system."), ) starts = models.DateField() ends = models.DateField() renewed_subscription = models.ForeignKey( - 'self', + "self", null=True, blank=True, verbose_name=_("renewed subscription"), diff --git a/project/context_processors.py b/project/context_processors.py index c4873c2..7e80076 100644 --- a/project/context_processors.py +++ b/project/context_processors.py @@ -4,6 +4,4 @@ from django.contrib.sites.shortcuts import get_current_site def current_site(request): """Include the current site in the context.""" - return { - 'site': get_current_site(request) - } + return {"site": get_current_site(request)} diff --git a/project/settings/base.py b/project/settings/base.py index 513b05d..fcbda74 100644 --- a/project/settings/base.py +++ b/project/settings/base.py @@ -26,63 +26,62 @@ ALLOWED_HOSTS = [] # 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', - - 'users', - 'accounting', - 'membership', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "django.contrib.sites", + "users", + "accounting", + "membership", ] MIDDLEWARE = [ - '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', + "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", ] -ROOT_URLCONF = 'project.urls' +ROOT_URLCONF = "project.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join("project", "templates")], - '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', - 'project.context_processors.current_site', - ], + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [os.path.join("project", "templates")], + "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", + "project.context_processors.current_site", + ] }, - }, + } ] AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', - 'allauth.account.auth_backends.AuthenticationBackend', + "django.contrib.auth.backends.ModelBackend", + "allauth.account.auth_backends.AuthenticationBackend", ) -WSGI_APPLICATION = 'project.wsgi.application' +WSGI_APPLICATION = "project.wsgi.application" # Database # https://docs.djangoproject.com/en/2.0/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": os.path.join(BASE_DIR, "db.sqlite3"), } } @@ -92,28 +91,24 @@ DATABASES = { AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', # noqa + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" # noqa }, + {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, # noqa + {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, # noqa { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', # noqa - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', # noqa - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', # noqa + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator" # noqa }, ] -AUTH_USER_MODEL = 'users.User' +AUTH_USER_MODEL = "users.User" # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -125,13 +120,13 @@ USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ -STATIC_URL = '/static/' +STATIC_URL = "/static/" -STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] +STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")] SITE_ID = 1 -EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" -CURRENCIES = ('DKK',) -CURRENCY_CHOICES = [('DKK', 'DKK')] +CURRENCIES = ("DKK",) +CURRENCY_CHOICES = [("DKK", "DKK")] diff --git a/project/urls.py b/project/urls.py index 41148c9..3e82ac1 100644 --- a/project/urls.py +++ b/project/urls.py @@ -6,7 +6,7 @@ from django.urls import path from . import views urlpatterns = [ - path('', views.index), + path("", views.index), path("users/", include("users.urls")), - path('admin/', admin.site.urls), + path("admin/", admin.site.urls), ] diff --git a/users/admin.py b/users/admin.py index 8c38f3f..a3c40c7 100644 --- a/users/admin.py +++ b/users/admin.py @@ -1,3 +1 @@ -from django.contrib import admin - -# Register your models here. +from django.contrib import admin # noqa diff --git a/users/apps.py b/users/apps.py index 4ce1fab..3ef1284 100644 --- a/users/apps.py +++ b/users/apps.py @@ -2,4 +2,4 @@ from django.apps import AppConfig class UsersConfig(AppConfig): - name = 'users' + name = "users" diff --git a/users/migrations/0001_initial.py b/users/migrations/0001_initial.py index b9ab905..386b839 100644 --- a/users/migrations/0001_initial.py +++ b/users/migrations/0001_initial.py @@ -9,28 +9,65 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ('auth', '0011_update_proxy_permissions'), - ] + dependencies = [("auth", "0011_update_proxy_permissions")] operations = [ migrations.CreateModel( - name='User', + 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')), - ('nick', models.CharField(blank=True, max_length=60, null=True)), - ('email', models.EmailField(help_text='Your email address will be used for password resets and notification about your event/submissions.', max_length=254, unique=True, verbose_name='E-Mail')), - ('is_active', models.BooleanField(default=True)), - ('is_staff', models.BooleanField(default=False)), - ('is_superuser', models.BooleanField(default=False)), - ('token_uuid', models.UUIDField(default=uuid.uuid4, editable=False)), - ('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')), + ( + "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" + ), + ), + ("nick", models.CharField(blank=True, max_length=60, null=True)), + ( + "email", + models.EmailField( + help_text="Your email address will be used for password resets and notification about your event/submissions.", + max_length=254, + unique=True, + verbose_name="E-Mail", + ), + ), + ("is_active", models.BooleanField(default=True)), + ("is_staff", models.BooleanField(default=False)), + ("is_superuser", models.BooleanField(default=False)), + ("token_uuid", models.UUIDField(default=uuid.uuid4, editable=False)), + ( + "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={ - 'verbose_name': 'User', - }, - ), + options={"verbose_name": "User"}, + ) ] diff --git a/users/models.py b/users/models.py index 5c96291..6de0dcc 100644 --- a/users/models.py +++ b/users/models.py @@ -20,23 +20,23 @@ class UserManager(BaseUserManager): user = self.create_user(password=password, **kwargs) user.is_staff = True user.is_superuser = True - user.save(update_fields=['is_staff', 'is_superuser']) + user.save(update_fields=["is_staff", "is_superuser"]) return user class User(PermissionsMixin, AbstractBaseUser): - EMAIL_FIELD = 'email' - USERNAME_FIELD = 'email' + EMAIL_FIELD = "email" + USERNAME_FIELD = "email" objects = UserManager() nick = models.CharField(max_length=60, null=True, blank=True) email = models.EmailField( unique=True, - verbose_name=_('E-Mail'), + verbose_name=_("E-Mail"), help_text=_( - 'Your email address will be used for password resets and notification about your event/submissions.' + "Your email address will be used for password resets and notification about your event/submissions." ), ) @@ -54,7 +54,7 @@ class User(PermissionsMixin, AbstractBaseUser): return self.get_display_name() def get_display_name(self) -> str: - return self.nick if self.nick else str(_('Unnamed user')) + return self.nick if self.nick else str(_("Unnamed user")) class Meta: verbose_name = _("User") diff --git a/users/urls.py b/users/urls.py index 5651d02..009e547 100644 --- a/users/urls.py +++ b/users/urls.py @@ -3,20 +3,59 @@ from django.urls import path from . import views -app_name = 'users' +app_name = "users" urlpatterns = [ - path('signup/', views.SignupView.as_view(), name='signup'), - path('signup/confirm/', views.SignupConfirmView.as_view(), name='signup_confirm'), - - path('login/', auth_views.LoginView.as_view(template_name="users/login.html"), name='login'), - path('logout/', auth_views.LogoutView.as_view(template_name="users/logged_out.html"), name='logout'), - - path('password_change/', views.PasswordChangeView.as_view(template_name="users/password_change_form.html"), name='password_change'), - path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(template_name="users/password_change_done.html"), name='password_change_done'), - - path('password_reset/', views.PasswordResetView.as_view(template_name="users/password_reset_form.html"), name='password_reset'), - path('password_reset/done/', auth_views.PasswordResetDoneView.as_view(template_name="users/password_reset_done.html"), name='password_reset_done'), - path('reset///', views.PasswordResetConfirmView.as_view(template_name="users/password_reset_confirm.html"), name='password_reset_confirm'), - path('reset/done/', auth_views.PasswordResetCompleteView.as_view(template_name="users/password_reset_complete.html"), name='password_reset_complete'), + path("signup/", views.SignupView.as_view(), name="signup"), + path("signup/confirm/", views.SignupConfirmView.as_view(), name="signup_confirm"), + path( + "login/", + auth_views.LoginView.as_view(template_name="users/login.html"), + name="login", + ), + path( + "logout/", + auth_views.LogoutView.as_view(template_name="users/logged_out.html"), + name="logout", + ), + path( + "password_change/", + views.PasswordChangeView.as_view( + template_name="users/password_change_form.html" + ), + name="password_change", + ), + path( + "password_change/done/", + auth_views.PasswordChangeDoneView.as_view( + template_name="users/password_change_done.html" + ), + name="password_change_done", + ), + path( + "password_reset/", + views.PasswordResetView.as_view(template_name="users/password_reset_form.html"), + name="password_reset", + ), + path( + "password_reset/done/", + auth_views.PasswordResetDoneView.as_view( + template_name="users/password_reset_done.html" + ), + name="password_reset_done", + ), + path( + "reset///", + views.PasswordResetConfirmView.as_view( + template_name="users/password_reset_confirm.html" + ), + name="password_reset_confirm", + ), + path( + "reset/done/", + auth_views.PasswordResetCompleteView.as_view( + template_name="users/password_reset_complete.html" + ), + name="password_reset_complete", + ), ] diff --git a/users/views.py b/users/views.py index 631f57e..30df8e5 100644 --- a/users/views.py +++ b/users/views.py @@ -6,20 +6,21 @@ from django.views.generic.base import TemplateView from django.views.generic.edit import FormView from . import forms + # from . import email class PasswordResetView(auth_views.PasswordResetView): - email_template_name = 'users/password_reset_email.html' - success_url = reverse_lazy('users:password_reset_done') + email_template_name = "users/password_reset_email.html" + success_url = reverse_lazy("users:password_reset_done") class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): - success_url = reverse_lazy('users:password_reset_complete') + success_url = reverse_lazy("users:password_reset_complete") class PasswordChangeView(auth_views.PasswordChangeView): - success_url = reverse_lazy('users:password_change_done') + success_url = reverse_lazy("users:password_change_done") class SignupView(FormView): @@ -31,7 +32,7 @@ class SignupView(FormView): user = form.save(commit=False) user.is_active = False - user.set_password(form.cleaned_data['password1']) + user.set_password(form.cleaned_data["password1"]) user.save() # mail = email.UserConfirm(user=user) @@ -48,10 +49,9 @@ class SignupConfirmView(TemplateView): class SignupConfirmRedirectView(RedirectView): - def get_redirect_url(self): - uuid = self.kwargs['uuid'] + uuid = self.kwargs["uuid"] if self.kwargs["token"] == forms.get_confirm_code(uuid): redirect("users:confirmed") # TODO From 07170082e3c01c71605594222d10c2a73e76bfa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 1 Sep 2019 09:45:45 +0200 Subject: [PATCH 3/3] Remove setup.cfg, move relevant flake8 arguments into pre-commit config. Update pre-commit hooks. --- .pre-commit-config.yaml | 6 ++++-- setup.cfg | 13 ------------- 2 files changed, 4 insertions(+), 15 deletions(-) delete mode 100644 setup.cfg diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0c7675a..6614006 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,17 @@ repos: - repo: git://github.com/pre-commit/pre-commit-hooks - rev: v1.3.0 + rev: v2.3.0 hooks: - id: trailing-whitespace - id: flake8 + args: [--max-line-length=120, --exclude=*/migrations/*] - id: check-yaml - id: check-added-large-files - id: debug-statements - id: end-of-file-fixer + - id: check-toml - repo: https://github.com/asottile/reorder_python_imports - rev: v1.0.1 + rev: v1.6.1 hooks: - id: reorder-python-imports types: [file, python] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 7235929..0000000 --- a/setup.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[flake8] -ignore = E226,E302,E41 -max-line-length = 160 -max-complexity = 10 -exclude = */migrations/* - -[isort] -atomic = true -multi_line_output = 5 -line_length = 160 -indent = ' ' -combine_as_imports = true -skip = wsgi.py,.eggs,setup.py