From b3bc0a95fd6740d89eb3bfd5b1e612a6a5c55254 Mon Sep 17 00:00:00 2001 From: Lars van Rhijn <38525109+KiOui@users.noreply.github.com> Date: Mon, 20 Jul 2020 21:36:33 +0200 Subject: [PATCH] Feature/docs (#90) --- .github/workflows/docker.yaml | 48 ++- .github/workflows/docs-update.yaml | 60 +++ .github/workflows/docs.yaml | 41 ++ .github/workflows/linting.yaml | 50 +++ .github/workflows/linting.yml | 49 --- .github/workflows/testing.yaml | 83 ++-- .gitignore | 3 + README.md | 69 +++ docs/Makefile | 20 + docs/make.bat | 35 ++ docs/source/conf.py | 102 +++++ docs/source/index.rst | 21 + docs/source/installation.rst | 26 ++ docs/source/marietje.rst | 76 ++++ docs/source/modules.rst | 11 + docs/source/orders.rst | 72 ++++ docs/source/overview.rst | 23 + docs/source/tosti.rst | 43 ++ docs/source/users.rst | 72 ++++ docs/source/venues.rst | 43 ++ poetry.lock | 408 ++++++++++++++++-- pyproject.toml | 3 + resources/entrypoint.sh | 1 - website/manage.py | 2 +- website/marietje/models.py | 2 - website/orders/views.py | 14 - website/tosti/settings/__init__.py | 29 ++ website/tosti/settings/development.py | 2 +- website/tosti/settings/production.py | 35 +- .../tosti/settings/{base.py => settings.py} | 12 +- website/tosti/urls.py | 20 +- 31 files changed, 1301 insertions(+), 174 deletions(-) create mode 100644 .github/workflows/docs-update.yaml create mode 100644 .github/workflows/docs.yaml create mode 100644 .github/workflows/linting.yaml delete mode 100644 .github/workflows/linting.yml create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst create mode 100644 docs/source/installation.rst create mode 100644 docs/source/marietje.rst create mode 100644 docs/source/modules.rst create mode 100644 docs/source/orders.rst create mode 100644 docs/source/overview.rst create mode 100644 docs/source/tosti.rst create mode 100644 docs/source/users.rst create mode 100644 docs/source/venues.rst create mode 100644 website/tosti/settings/__init__.py rename website/tosti/settings/{base.py => settings.py} (93%) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index eaed72c7..961329bc 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -1,31 +1,33 @@ --- -name: Build Production Docker Image +name: "Build Production Docker Image" on: push: - branches: [ master ] + branches: + - master jobs: - build-docker: - name: "Build Production Docker Image" - runs-on: "ubuntu-latest" - steps: - - name: "Checkout repository" - uses: "actions/checkout@v2" - - - name: "Create environment for repository names" - run: | - echo "::set-env name=DOCKER_LATEST::docker.pkg.github.com/${GITHUB_REPOSITORY}/${GITHUB_REPOSITORY##*/}:latest" - echo "::set-env name=DOCKER_TAG_PRODUCTION::docker.pkg.github.com/${GITHUB_REPOSITORY}/${GITHUB_REPOSITORY##*/}:${GITHUB_SHA}" + build-docker: + name: "Build Production Docker Image" + runs-on: ubuntu-latest + steps: - - name: "Build Docker image" - run: docker build --tag ${DOCKER_LATEST,,} . + - name: "Checkout repository" + uses: actions/checkout@v2 - - name: "Login to GitHub" - run: echo "${{ secrets.GH_TOKEN }}" | docker login docker.pkg.github.com -u "${{ github.repository_owner }}" --password-stdin - - - name: "Tag and publish" - run: | - docker tag "${DOCKER_LATEST,,}" "${DOCKER_TAG_PRODUCTION,,}" - docker push "${DOCKER_TAG_PRODUCTION,,}" - docker push "${DOCKER_LATEST,,}" + - name: "Create environment for repository names" + run: | + echo "::set-env name=DOCKER_LATEST::docker.pkg.github.com/${GITHUB_REPOSITORY}/${GITHUB_REPOSITORY##*/}:latest" + echo "::set-env name=DOCKER_TAG_PRODUCTION::docker.pkg.github.com/${GITHUB_REPOSITORY}/${GITHUB_REPOSITORY##*/}:${GITHUB_SHA}" + + - name: "Build Docker image" + run: docker build --tag ${DOCKER_LATEST,,} . + + - name: "Login to GitHub" + run: echo "${{ secrets.GH_TOKEN }}" | docker login docker.pkg.github.com -u "${{ github.repository_owner }}" --password-stdin + + - name: "Tag and publish" + run: | + docker tag "${DOCKER_LATEST,,}" "${DOCKER_TAG_PRODUCTION,,}" + docker push "${DOCKER_TAG_PRODUCTION,,}" + docker push "${DOCKER_LATEST,,}" diff --git a/.github/workflows/docs-update.yaml b/.github/workflows/docs-update.yaml new file mode 100644 index 00000000..2b0eb719 --- /dev/null +++ b/.github/workflows/docs-update.yaml @@ -0,0 +1,60 @@ +--- + +name: "Update documentation on GitHub Pages" +on: + push: + branches: + - master + +jobs: + docs: + name: "Update documentation on GitHub Pages" + runs-on: ubuntu-latest + steps: + + - name: "Checkout the repository" + uses: actions/checkout@v2 + + - name: "Setup Python" + uses: actions/setup-python@v1 + with: + python-version: '3.7' + + - name: "Install Poetry" + run: | + python -m pip install --upgrade pip + python -m pip install poetry + + - name: "Restore any cached Poetry dependencies" + uses: actions/cache@v1 + with: + path: ~/.cache/pypoetry/virtualenvs + key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }} + restore-keys: | + ${{ runner.os }}-poetry- + + - name: "Install any new dependencies" + run: poetry install + if: steps.cache.outputs.cache-hit != 'true' + + - name: "Build documentation" + run: | + cd docs + poetry run make html + + - name: "Commit documentation changes" + run: | + git clone https://github.com/KiOui/TOSTI.git --branch gh-pages --single-branch gh-pages + cp -r docs/build/html/* gh-pages/ + cd gh-pages + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add . + git commit -m "Update documentation" -a || true + + - name: "Push changes" + uses: ad-m/github-push-action@master + with: + branch: gh-pages + directory: gh-pages + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 00000000..852d3176 --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,41 @@ +--- + +name: "Documentation" +on: + - push + +jobs: + docs: + name: "Check Sphinx documentation" + runs-on: ubuntu-latest + steps: + + - name: "Checkout the repository" + uses: actions/checkout@v2 + + - name: "Setup Python" + uses: actions/setup-python@v1 + with: + python-version: '3.7' + + - name: "Install Poetry" + run: | + python -m pip install --upgrade pip + python -m pip install poetry + + - name: "Restore any cached Poetry dependencies" + uses: actions/cache@v1 + with: + path: ~/.cache/pypoetry/virtualenvs + key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }} + restore-keys: | + ${{ runner.os }}-poetry- + + - name: "Install any new dependencies" + run: poetry install + if: steps.cache.outputs.cache-hit != 'true' + + - name: "Build documentation" + run: | + cd docs + poetry run make html \ No newline at end of file diff --git a/.github/workflows/linting.yaml b/.github/workflows/linting.yaml new file mode 100644 index 00000000..2facffb8 --- /dev/null +++ b/.github/workflows/linting.yaml @@ -0,0 +1,50 @@ +--- + +name: "Linting" +on: + - push + +jobs: + lint: + name: "Linting" + runs-on: ubuntu-latest + steps: + + - name: "Checkout the repository" + uses: actions/checkout@v2 + + - name: "Setup Python" + uses: actions/setup-python@v1 + with: + python-version: '3.7' + + - name: "Install Poetry" + run: | + python -m pip install --upgrade pip + python -m pip install poetry + + - name: "Restore any cached Poetry dependencies" + uses: actions/cache@v1 + with: + path: ~/.cache/pypoetry/virtualenvs + key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }} + restore-keys: | + ${{ runner.os }}-poetry- + + - name: "Install any new dependencies" + run: poetry install + if: steps.cache.outputs.cache-hit != 'true' + + - name: "Run Black" + run: poetry run black --quiet --check website + + - name: "Run flake8" + run: >- + poetry run + flake8 + --exclude="migrations,website/tosti/settings/*.py" + --max-line-length=119 + website + + - name: "Run PyDocStyle" + run: poetry run pydocstyle --explain --add-ignore=D100,D104 --match-dir='(?!migrations).*' diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml deleted file mode 100644 index 68b579e4..00000000 --- a/.github/workflows/linting.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- - -name: "Linting and Testing" -on: "push" - -jobs: - lint: - name: "Linting" - runs-on: "ubuntu-latest" - steps: - - - name: "Checkout the repository" - uses: "actions/checkout@v1" - - - name: "Setup Python" - uses: "actions/setup-python@v1" - with: - python-version: '3.7' - - - name: "Install Poetry" - run: | - python -m pip install --upgrade pip - python -m pip install poetry - - - name: "Restore any cached Poetry dependencies" - uses: actions/cache@v1 - with: - path: ~/.cache/pypoetry/virtualenvs - key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }} - restore-keys: | - ${{ runner.os }}-poetry- - - - name: "Install any new dependencies" - run: poetry install - if: steps.cache.outputs.cache-hit != 'true' - - - name: "Run Black" - run: "poetry run black --quiet --check website" - - - name: "Run flake8" - run: >- - poetry run - flake8 - --exclude="migrations,website/tosti/settings.py" - --max-line-length=119 - website - - - name: "Run PyDocStyle" - run: "poetry run pydocstyle --explain --add-ignore=D100,D104 --match-dir='(?!migrations).*'" diff --git a/.github/workflows/testing.yaml b/.github/workflows/testing.yaml index 18671f56..4799e822 100644 --- a/.github/workflows/testing.yaml +++ b/.github/workflows/testing.yaml @@ -1,49 +1,50 @@ +--- + name: "Testing" on: - pull_request: - branches: [ master ] + - push jobs: build: name: "Testing" runs-on: ubuntu-latest - strategy: - matrix: - python-version: [3.7] steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - - name: "Install Poetry" - run: | - python -m pip install --upgrade pip - python -m pip install poetry - - - name: "Restore any cached Poetry dependencies" - uses: actions/cache@v1 - with: - path: ~/.cache/pypoetry/virtualenvs - key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }} - restore-keys: | - ${{ runner.os }}-poetry- - - - name: "Install any new dependencies" - run: poetry install - if: steps.cache.outputs.cache-hit != 'true' - - - name: "Test migrations" - run: | - poetry run python website/manage.py makemigrations --no-input --check --dry-run - - - name: Check server - run: | - poetry run python3 website/manage.py check - - - name: "Run Django tests using Coverage" - run: "poetry run coverage run website/manage.py test website/" - - - name: "Check Coverage report" - run: "poetry run coverage report" + + - name: "Checkout the repository" + uses: actions/checkout@v2 + + - name: "Setup Python" + uses: actions/setup-python@v1 + with: + python-version: '3.7' + + - name: "Install Poetry" + run: | + python -m pip install --upgrade pip + python -m pip install poetry + + - name: "Restore any cached Poetry dependencies" + uses: actions/cache@v1 + with: + path: ~/.cache/pypoetry/virtualenvs + key: ${{ runner.os }}-poetry-${{ hashFiles('poetry.lock') }} + restore-keys: | + ${{ runner.os }}-poetry- + + - name: "Install any new dependencies" + run: poetry install + if: steps.cache.outputs.cache-hit != 'true' + + - name: "Test migrations" + run: | + poetry run python website/manage.py makemigrations --no-input --check --dry-run + + - name: "Perform Django self-check" + run: | + poetry run python3 website/manage.py check + + - name: "Run Django tests using Coverage" + run: poetry run coverage run website/manage.py test website/ + + - name: "Check Coverage report" + run: poetry run coverage report diff --git a/.gitignore b/.gitignore index 625a73b6..b2c8a0b9 100644 --- a/.gitignore +++ b/.gitignore @@ -145,3 +145,6 @@ docker-compose.yml # Settings cache (Spotify) /website/cache +# Documentation +/docs/build + diff --git a/README.md b/README.md index 9e1cbc69..d801e621 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,72 @@ Now your server is setup and running on ```localhost:8000```. The administrator ### Docker For running this application with a docker, a docker image of the latest build is provided on [this page](https://hub.docker.com/repository/docker/larsvanrhijn/tosti). You can also build your own docker image by executing ```docker build .``` in the main directory. An example docker-compose file is added as ```docker-compose.yml.example```. + +## Module explanations + +This section will go over the modules in TOSTI and explain design decisions and basic funtionality. + +### Venues + +The venues module provides a model `Venue` for differentiating between venues. This way, users can interact with multiple venues from the same website. + +### Orders + +There are two important functionalities of the orders module. The first being the ability to create, manage and start shifts with different users. The second being the ability for users to place orders in shifts. + +#### Products + +Products are items users can order in shifts. + +#### Shifts + +A user with the authorization of creating shifts can create a `Shift` for a specific `Venue`. There can only be one shift at a specific time per venue. Shifts represent time windows in which users can place and pick up orders. + +Users can only place orders in active shifts, a shift is active if an authorized user has set a shift to active and if the current time is within the time window of the shift. + +A maximum amount of orders can be set on a per shift and per user basis. + +#### Orders + +Orders can be placed in active shifts. A user can place an order by specifying the ``Product`` he or she wants to order. + +### Users + +The custom `users` module enables TOSTI to authenticate users via OpenID. Currently, [OpenID version 1.1](https://openid.net/specs/openid-authentication-1_1.html#mode_associate) is supported by the `users` module. An OpenID host can be set in the settings file by specifying the following variable: + +- `OPENID_SERVER_ENDPOINT`: the server endpoint fot the OpenID verification + +Additionally, the following variables can be set in settings to change the behaviour of the OpenID implementation: + +- `OPENID_RETURN_URL`: where the user should be taken when coming from the OpenID server (should be set to a view name) +- `OPENID_USERNAME_PREFIX`: a prefix to prepend to the username users enter when starting authentication +- `OPENID_USERNAME_POSTFIX`: a postfix to append to the username users enter when starting authentication + +### Marietje + +This module is used to connect a Spotify player to venues. A SpotifyAccount object can be configured and connected to a venue. This enables users of TOSTI to control and listen to music from Spotify. The main features of the Marietje module are: + +- Connecting a Spotify account to TOSTI +- Showing the currently playing song +- Controlling the queue and controls for play/pausing the song and skipping/reverting a track + +The Marietje module makes use of the [Spotify API](https://developer.spotify.com) via the [spotipy library](https://spotipy.readthedocs.io/en/2.12.0/). There are three stages in configuring Marietje for playback controls: + +1. Adding a Spotify account to TOSTI + +In order to add a Spotify account to TOSTI, head over to the administrator view and add a `Spotify Settings` object to the database. You will be automatically redirected to a page where you need to enter a public and private Spotify API key which can be created on the [Spotify API dashboard](https://developer.spotify.com/dashboard/applications). Follow the instructions on the page and continue to the next step if everything succeeded. + +Note that the spotipy library makes use of its own caching system to cache the Spotify OAUTH2 tokens. The directory where these cache files are stored can be configured by setting the `SPOTIFY_CACHE_PATH` in the Django settings file. Only the Spotify API client id and client secret are stored in the Django database, the other identifiers and keys used in the OAUTH2 protocol are handled by spotipy and are thus stored in the spotipy cache files. + +2. Configuring a Spotify account + +A Spotify account can be configured after setting it up. Two things need to be changed before a venue is shown with a music player on the Marietje overview page: + +- Set a venue +- Set a playback device + +Setting a venue is easy, just select the venue from the dropdown list and it will be connected to the Spotify account you are configuring. Setting a playback device is a little more difficult as now is the time where you need to start up a Spotify client on a computer system connected to the internet. Note that after setting a playback device, the device must stay on and the Spotify client must remain open, otherwise the pages corresponding to the Spotify account will throw a server error (500) as the playback device can not be found. If the playback device is not displayed within the list, refresh the configuration page and try again. After setting a playback device and venue, a spotify player is shown at `/Marietje/index`. + +3. Using the playback functions + +If everything went well, a Spotify player is displayed on the `/Marietje/index` page. Administrators are able to play/pause and skip or revert songs, normal users are not. If you open the Spotify player, a search view is displayed and the recent items added to the queue. The search view can be used to search tracks on Spotify. The queue displays only tracks added via Marietje, as there is currently no way to request the queue from a Spotify playback device. \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..d0c3cbf1 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..6247f7e2 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..8fe06542 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,102 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. + +import os +import sys +import sphinx_rtd_theme + +sys.path.insert(0, os.path.abspath("../../website")) + +import django +from django.conf import settings + +from tosti import settings as tosti_settings + +# -- Initialise Django ---------------------------------------------------- + +settings.configure(tosti_settings) +django.setup() + +# -- Project information ----------------------------------------------------- + +project = 'TOSTI' +copyright = '2020, Tartarus' +author = 'Tartarus' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx_rtd_theme", + "recommonmark", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = "" +# The full version, including alpha/beta/rc tags. +release = "" + +# The master toctree document. +master_doc = "index" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + +# default domain: +primary_domain = "py" + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ['_static'] + +# -- Options for autodoc -------------------------------------------------- + +# Default options for autodoc +autodoc_default_options = { + "members": True, + "undoc-members": True, +} diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..ff97f7c8 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,21 @@ +.. TOSTI documentation master file, created by + sphinx-quickstart on Sun Jul 5 19:05:24 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to TOSTI's documentation! +================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + overview + installation + modules + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` diff --git a/docs/source/installation.rst b/docs/source/installation.rst new file mode 100644 index 00000000..6a6c3672 --- /dev/null +++ b/docs/source/installation.rst @@ -0,0 +1,26 @@ +Installation +============ + +This project is built using the Django_ framework. Poetry_ is used for dependency management. + +Setup +----- + +0. Get at least Python_ 3.7 installed on your system. +1. Clone this repository. +2. If ``pip3`` is not installed on your system yet, execute ``apt install python3-pip`` on your system. +3. Also make sure ``python3-dev`` is installed on your system, execute ``apt install python3-dev``. +4. Install Poetry by following the steps on `their website `_. Make sure poetry is added to ``PATH`` before continuing. +5. Make sure ``poetry`` uses your python 3 installation: ``poetry env use python3``. +6. Run ``poetry install`` to install all dependencies. +7. Run ``poetry shell`` to start a shell with the dependencies loaded. This command needs to be ran every time you open a new shell and want to run the development server. +8. Run ``cd website`` to change directories to the ``website`` folder containing the project. +9. Run ``./manage.py migrate`` to initialise the database and run all migrations. +10. Run ``./manage.py createsuperuser`` to create an administrator that is able to access the backend interface later on. The password you set here will not be used as the openid server will be used for identification, be sure to set the super user to your science login name. +11. Run ``./manage.py runserver`` to start the development server locally. + +Now your server is setup and running on ``localhost:8000``. The administrator interface can be accessed by going to ``localhost:8000/admin``. + +.. _django: https://github.com/django/django +.. _poetry: https://python-poetry.org +.. _python: https://www.python.org \ No newline at end of file diff --git a/docs/source/marietje.rst b/docs/source/marietje.rst new file mode 100644 index 00000000..764a6908 --- /dev/null +++ b/docs/source/marietje.rst @@ -0,0 +1,76 @@ +Marietje package +================= + +.. automodule:: marietje + :members: + :undoc-members: + :show-inheritance: + +Spotipy +------- + +The Marietje package uses spotipy_ for the connection to Spotify_. Note that the spotipy package uses caching files for +caching the Spotify OAuth2 tokens. When using the default settings, a ``cache`` folder will be created in the +``website`` folder storing these caching files. + +Submodules +---------- + +marietje.admin module +---------------------- + +.. automodule:: marietje.admin + :members: + :undoc-members: + :show-inheritance: + +marietje.apps module +--------------------- + +.. automodule:: marietje.apps + :members: + :undoc-members: + :show-inheritance: + +marietje.forms module +---------------------- + +.. automodule:: marietje.forms + :members: + :undoc-members: + :show-inheritance: + +marietje.models module +----------------------- + +.. automodule:: marietje.models + :members: + :undoc-members: + :show-inheritance: + +marietje.templatetags module +---------------------------- + +.. automodule:: marietje.templatetags.marietje + :members: + :undoc-members: + :show-inheritance: + +marietje.urls module +--------------------- + +.. automodule:: marietje.urls + :members: + :undoc-members: + :show-inheritance: + +marietje.views module +---------------------- + +.. automodule:: marietje.views + :members: + :undoc-members: + :show-inheritance: + +.. _spotipy: https://spotipy.readthedocs.io +.. _spotify: https://spotify.com \ No newline at end of file diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 00000000..1d540f7e --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,11 @@ +Website modules +=============== + +.. toctree:: + :maxdepth: 4 + + marietje + orders + tosti + users + venues diff --git a/docs/source/orders.rst b/docs/source/orders.rst new file mode 100644 index 00000000..622cafae --- /dev/null +++ b/docs/source/orders.rst @@ -0,0 +1,72 @@ +Orders package +================= + +.. automodule:: orders + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +orders.admin module +---------------------- + +.. automodule:: orders.admin + :members: + :undoc-members: + :show-inheritance: + +orders.apps module +--------------------- + +.. automodule:: orders.apps + :members: + :undoc-members: + :show-inheritance: + +orders.forms module +---------------------- + +.. automodule:: orders.forms + :members: + :undoc-members: + :show-inheritance: + +orders.models module +----------------------- + +.. automodule:: orders.models + :members: + :undoc-members: + :show-inheritance: + +orders.templatetags module +--------------------------- + +.. automodule:: orders.templatetags.order_now + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: orders.templatetags.start_shift + :members: + :undoc-members: + :show-inheritance: + +orders.urls module +--------------------- + +.. automodule:: orders.urls + :members: + :undoc-members: + :show-inheritance: + +orders.views module +---------------------- + +.. automodule:: orders.views + :members: + :undoc-members: + :show-inheritance: + diff --git a/docs/source/overview.rst b/docs/source/overview.rst new file mode 100644 index 00000000..05825ff3 --- /dev/null +++ b/docs/source/overview.rst @@ -0,0 +1,23 @@ +Overview +======== + +Welcome to the repository of Tartarus Order System for Take-away Items, TOSTI for short. This application is designed to provide Tartarus_ with an online tool to order items. + +Current features +---------------- + +- An implementation of OpenID_ that enables users to login via the `Science OpenID server`_. +- An easy-to-use order system that makes it possible for authenticated users to order and control shifts in venues. +- An implementation of the Spotify_ API to control music in venues. + +Source and issue tracker +------------------------ + +Sources are available at the `TOSTI GitHub page`_. You can also file a bug there. + + +.. _tartarus: https://tartarus.science.ru.nl +.. _spotify: https://api.spotify.com +.. _openid: https://openid.net +.. _science openid server: https://openid.science.ru.nl +.. _TOSTI GitHub page: https://github.com/KiOui/TOSTI \ No newline at end of file diff --git a/docs/source/tosti.rst b/docs/source/tosti.rst new file mode 100644 index 00000000..e90304ae --- /dev/null +++ b/docs/source/tosti.rst @@ -0,0 +1,43 @@ +Tosti package +================= + +.. automodule:: tosti + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +tosti.admin module +---------------------- + +.. automodule:: tosti.admin + :members: + :undoc-members: + :show-inheritance: + +tosti.templatetags module +------------------------- + +.. automodule:: tosti.templatetags.venue_cards + :members: + :undoc-members: + :show-inheritance: + +tosti.urls module +--------------------- + +.. automodule:: tosti.urls + :members: + :undoc-members: + :show-inheritance: + +tosti.views module +---------------------- + +.. automodule:: tosti.views + :members: + :undoc-members: + :show-inheritance: + diff --git a/docs/source/users.rst b/docs/source/users.rst new file mode 100644 index 00000000..df8ee849 --- /dev/null +++ b/docs/source/users.rst @@ -0,0 +1,72 @@ +Users package +================= + +.. automodule:: users + :members: + :undoc-members: + :show-inheritance: + +OpenID implementation +--------------------- +The user module lets Django use the `Science OpenID server`_ for authentication. The `Science OpenID server`_ uses +`OpenID version 1.1`_. The ``OpenIDVerifier`` object in ``users/services`` handles all OpenID verification. + +User models +----------- +This module does not create a custom Django user model but rather uses the common `auth.User` model. In addition, +the module contains a `GroupSettings` model, related to the `auth.Group` model, to define special properties for +certain `auth.Group`'s. + +Submodules +---------- + +users.admin module +---------------------- + +.. automodule:: users.admin + :members: + :undoc-members: + :show-inheritance: + +users.apps module +--------------------- + +.. automodule:: users.apps + :members: + :undoc-members: + :show-inheritance: + +users.forms module +---------------------- + +.. automodule:: users.forms + :members: + :undoc-members: + :show-inheritance: + +users.models module +----------------------- + +.. automodule:: users.models + :members: + :undoc-members: + :show-inheritance: + +users.urls module +--------------------- + +.. automodule:: users.urls + :members: + :undoc-members: + :show-inheritance: + +users.views module +---------------------- + +.. automodule:: users.views + :members: + :undoc-members: + :show-inheritance: + +.. _science openid server: https://openid.science.ru.nl +.. _openid version 1.1: https://openid.net/specs/openid-authentication-1_1.html#mode_associate \ No newline at end of file diff --git a/docs/source/venues.rst b/docs/source/venues.rst new file mode 100644 index 00000000..ab0f8331 --- /dev/null +++ b/docs/source/venues.rst @@ -0,0 +1,43 @@ +Venues package +================= + +.. automodule:: venues + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +venues.admin module +---------------------- + +.. automodule:: venues.admin + :members: + :undoc-members: + :show-inheritance: + +venues.apps module +--------------------- + +.. automodule:: venues.apps + :members: + :undoc-members: + :show-inheritance: + +venues.models module +----------------------- + +.. automodule:: venues.models + :members: + :undoc-members: + :show-inheritance: + +venues.views module +---------------------- + +.. automodule:: venues.views + :members: + :undoc-members: + :show-inheritance: + diff --git a/poetry.lock b/poetry.lock index c3c3f475..7cf28642 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,11 @@ +[[package]] +category = "main" +description = "A configurable sidebar-enabled Sphinx theme" +name = "alabaster" +optional = false +python-versions = "*" +version = "0.7.12" + [[package]] category = "dev" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." @@ -31,6 +39,17 @@ dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.int docs = ["sphinx", "zope.interface"] tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +[[package]] +category = "main" +description = "Internationalization utilities" +name = "babel" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.8.0" + +[package.dependencies] +pytz = ">=2015.7" + [[package]] category = "dev" description = "The uncompromising code formatter." @@ -75,6 +94,26 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "7.1.2" +[[package]] +category = "main" +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.*, !=3.4.*" +version = "0.4.3" + +[[package]] +category = "main" +description = "Python parser for the CommonMark Markdown spec" +name = "commonmark" +optional = false +python-versions = "*" +version = "0.9.1" + +[package.extras] +test = ["flake8 (3.7.8)", "hypothesis (3.55.3)"] + [[package]] category = "main" description = "Code coverage measurement for Python" @@ -99,8 +138,8 @@ category = "main" description = "Repackaging of Google's Diff Match and Patch libraries. Offers robust algorithms to perform the operations required for synchronizing plain text." name = "diff-match-patch" optional = false -python-versions = "*" -version = "20181111" +python-versions = ">=2.7" +version = "20200713" [[package]] category = "main" @@ -147,16 +186,24 @@ description = "Django application and library for importing and exporting data w name = "django-import-export" optional = false python-versions = ">=3.5" -version = "2.2.0" +version = "2.3.0" [package.dependencies] Django = ">=2.0" diff-match-patch = "*" [package.dependencies.tablib] -extras = ["html", "ods", "xls", "yaml", "xlsx"] +extras = ["xls", "xlsx", "ods", "yaml", "html"] version = ">=0.14.0" +[[package]] +category = "main" +description = "Docutils -- Python Documentation Utilities" +name = "docutils" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.16" + [[package]] category = "main" description = "An implementation of lxml.xmlfile for the standard library" @@ -190,6 +237,14 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "2.10" +[[package]] +category = "main" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +name = "imagesize" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.2.0" + [[package]] category = "dev" description = "Read metadata from Python packages" @@ -214,6 +269,20 @@ optional = false python-versions = "*" version = "1.4.1" +[[package]] +category = "main" +description = "A very fast and expressive template engine." +name = "jinja2" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.11.2" + +[package.dependencies] +MarkupSafe = ">=0.23" + +[package.extras] +i18n = ["Babel (>=0.8)"] + [[package]] category = "main" description = "An HTML/XML generator" @@ -222,6 +291,14 @@ optional = false python-versions = "*" version = "1.14" +[[package]] +category = "main" +description = "Safely add untrusted strings to HTML/XML markup." +name = "markupsafe" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "1.1.1" + [[package]] category = "dev" description = "McCabe checker, plugin for flake8" @@ -253,6 +330,18 @@ version = "3.0.4" et-xmlfile = "*" jdcal = "*" +[[package]] +category = "main" +description = "Core utilities for Python packages" +name = "packaging" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "20.4" + +[package.dependencies] +pyparsing = ">=2.0.2" +six = "*" + [[package]] category = "dev" description = "Utility library for gitignore style pattern matching of file paths." @@ -304,6 +393,22 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "2.2.0" +[[package]] +category = "main" +description = "Pygments is a syntax highlighting package written in Python." +name = "pygments" +optional = false +python-versions = ">=3.5" +version = "2.6.1" + +[[package]] +category = "main" +description = "Python parsing module" +name = "pyparsing" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "2.4.7" + [[package]] category = "main" description = "World timezone definitions, modern and historical" @@ -320,13 +425,26 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "5.3.1" +[[package]] +category = "main" +description = "A docutils-compatibility bridge to CommonMark, enabling you to write CommonMark inside of Docutils & Sphinx projects." +name = "recommonmark" +optional = false +python-versions = "*" +version = "0.6.0" + +[package.dependencies] +commonmark = ">=0.8.1" +docutils = ">=0.11" +sphinx = ">=1.3.1" + [[package]] category = "dev" description = "Alternative regular expression module, to replace re." name = "regex" optional = false python-versions = "*" -version = "2020.6.8" +version = "2020.7.14" [[package]] category = "main" @@ -355,13 +473,130 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" version = "1.15.0" [[package]] -category = "dev" +category = "main" description = "This package provides 26 stemmers for 25 languages generated from Snowball algorithms." name = "snowballstemmer" optional = false python-versions = "*" version = "2.0.0" +[[package]] +category = "main" +description = "Python documentation generator" +name = "sphinx" +optional = false +python-versions = ">=3.5" +version = "3.1.2" + +[package.dependencies] +Jinja2 = ">=2.3" +Pygments = ">=2.0" +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = ">=0.3.5" +docutils = ">=0.12" +imagesize = "*" +packaging = "*" +requests = ">=2.5.0" +setuptools = "*" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = "*" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = "*" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["flake8 (>=3.5.0)", "flake8-import-order", "mypy (>=0.780)", "docutils-stubs"] +test = ["pytest", "pytest-cov", "html5lib", "typed-ast", "cython"] + +[[package]] +category = "main" +description = "Read the Docs theme for Sphinx" +name = "sphinx-rtd-theme" +optional = false +python-versions = "*" +version = "0.5.0" + +[package.dependencies] +sphinx = "*" + +[package.extras] +dev = ["transifex-client", "sphinxcontrib-httpdomain", "bump2version"] + +[[package]] +category = "main" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +name = "sphinxcontrib-applehelp" +optional = false +python-versions = ">=3.5" +version = "1.0.2" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +category = "main" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +name = "sphinxcontrib-devhelp" +optional = false +python-versions = ">=3.5" +version = "1.0.2" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +category = "main" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +name = "sphinxcontrib-htmlhelp" +optional = false +python-versions = ">=3.5" +version = "1.0.3" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest", "html5lib"] + +[[package]] +category = "main" +description = "A sphinx extension which renders display math in HTML via JavaScript" +name = "sphinxcontrib-jsmath" +optional = false +python-versions = ">=3.5" +version = "1.0.1" + +[package.extras] +test = ["pytest", "flake8", "mypy"] + +[[package]] +category = "main" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +name = "sphinxcontrib-qthelp" +optional = false +python-versions = ">=3.5" +version = "1.0.3" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + +[[package]] +category = "main" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +name = "sphinxcontrib-serializinghtml" +optional = false +python-versions = ">=3.5" +version = "1.1.4" + +[package.extras] +lint = ["flake8", "mypy", "docutils-stubs"] +test = ["pytest"] + [[package]] category = "main" description = "A light weight Python library for the Spotify Web API" @@ -496,10 +731,14 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["jaraco.itertools", "func-timeout"] [metadata] -content-hash = "6fc9e0140bbb4108c40cc258b5bcae6629d139394d286eb7fac9aad6eed00b12" +content-hash = "dd96d7555af950c7517a37d9446832d2756ceb64068fde77441b77f3c9299ba9" python-versions = "^3.7" [metadata.files] +alabaster = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, @@ -512,6 +751,10 @@ attrs = [ {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, ] +babel = [ + {file = "Babel-2.8.0-py2.py3-none-any.whl", hash = "sha256:d670ea0b10f8b723672d3a6abeb87b565b244da220d76b4dba1b66269ec152d4"}, + {file = "Babel-2.8.0.tar.gz", hash = "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38"}, +] black = [ {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, @@ -528,6 +771,14 @@ click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, ] +colorama = [ + {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, + {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, +] +commonmark = [ + {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, + {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, +] coverage = [ {file = "coverage-5.2-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:d9ad0a988ae20face62520785ec3595a5e64f35a21762a57d115dae0b8fb894a"}, {file = "coverage-5.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:4bb385a747e6ae8a65290b3df60d6c8a692a5599dc66c9fa3520e667886f2e10"}, @@ -569,7 +820,8 @@ defusedxml = [ {file = "defusedxml-0.6.0.tar.gz", hash = "sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5"}, ] diff-match-patch = [ - {file = "diff-match-patch-20181111.tar.gz", hash = "sha256:a809a996d0f09b9bbd59e9bbd0b71eed8c807922512910e05cbd3f9480712ddb"}, + {file = "diff-match-patch-20200713.tar.gz", hash = "sha256:da6f5a01aa586df23dfc89f3827e1cafbb5420be9d87769eeb079ddfd9477a18"}, + {file = "diff_match_patch-20200713-py3-none-any.whl", hash = "sha256:8bf9d9c4e059d917b5c6312bac0c137971a32815ddbda9c682b949f2986b4d34"}, ] django = [ {file = "Django-3.0.8-py3-none-any.whl", hash = "sha256:5457fc953ec560c5521b41fad9e6734a4668b7ba205832191bbdff40ec61073c"}, @@ -584,7 +836,12 @@ django-guardian = [ {file = "django_guardian-2.3.0-py3-none-any.whl", hash = "sha256:0e70706c6cda88ddaf8849bddb525b8df49de05ba0798d4b3506049f0d95cbc8"}, ] django-import-export = [ - {file = "django-import-export-2.2.0.tar.gz", hash = "sha256:83be410caca8c1b78585677c0fd7ae0e4de5dd5507ad3cea815fbcd29323f448"}, + {file = "django-import-export-2.3.0.tar.gz", hash = "sha256:21464304cb64e57809f3d6f5ad45108d5b02c556ab115b493a547304d2dddc70"}, + {file = "django_import_export-2.3.0-py3-none-any.whl", hash = "sha256:8ffddb1f39f2768a747df90c8b55c46c7198e41e9f78bc83427a5b7fc0e78bac"}, +] +docutils = [ + {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, + {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, ] et-xmlfile = [ {file = "et_xmlfile-1.0.1.tar.gz", hash = "sha256:614d9722d572f6246302c4491846d2c393c199cfa4edc9af593437691683335b"}, @@ -597,6 +854,10 @@ idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] +imagesize = [ + {file = "imagesize-1.2.0-py2.py3-none-any.whl", hash = "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1"}, + {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"}, +] importlib-metadata = [ {file = "importlib_metadata-1.7.0-py2.py3-none-any.whl", hash = "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070"}, {file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"}, @@ -605,9 +866,48 @@ jdcal = [ {file = "jdcal-1.4.1-py2.py3-none-any.whl", hash = "sha256:1abf1305fce18b4e8aa248cf8fe0c56ce2032392bc64bbd61b5dff2a19ec8bba"}, {file = "jdcal-1.4.1.tar.gz", hash = "sha256:472872e096eb8df219c23f2689fc336668bdb43d194094b5cc1707e1640acfc8"}, ] +jinja2 = [ + {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, + {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, +] markuppy = [ {file = "MarkupPy-1.14.tar.gz", hash = "sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f"}, ] +markupsafe = [ + {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, + {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, + {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, + {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, + {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, + {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, + {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, + {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, + {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, +] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, @@ -620,6 +920,10 @@ openpyxl = [ {file = "openpyxl-3.0.4-py2.py3-none-any.whl", hash = "sha256:6e62f058d19b09b95d20ebfbfb04857ad08d0833190516c1660675f699c6186f"}, {file = "openpyxl-3.0.4.tar.gz", hash = "sha256:d88dd1480668019684c66cfff3e52a5de4ed41e9df5dd52e008cbf27af0dbf87"}, ] +packaging = [ + {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, + {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, +] pathspec = [ {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, @@ -696,6 +1000,14 @@ pyflakes = [ {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, ] +pygments = [ + {file = "Pygments-2.6.1-py3-none-any.whl", hash = "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"}, + {file = "Pygments-2.6.1.tar.gz", hash = "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] pytz = [ {file = "pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"}, {file = "pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"}, @@ -713,28 +1025,32 @@ pyyaml = [ {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, ] +recommonmark = [ + {file = "recommonmark-0.6.0-py2.py3-none-any.whl", hash = "sha256:2ec4207a574289355d5b6ae4ae4abb29043346ca12cdd5f07d374dc5987d2852"}, + {file = "recommonmark-0.6.0.tar.gz", hash = "sha256:29cd4faeb6c5268c633634f2d69aef9431e0f4d347f90659fd0aab20e541efeb"}, +] regex = [ - {file = "regex-2020.6.8-cp27-cp27m-win32.whl", hash = "sha256:fbff901c54c22425a5b809b914a3bfaf4b9570eee0e5ce8186ac71eb2025191c"}, - {file = "regex-2020.6.8-cp27-cp27m-win_amd64.whl", hash = "sha256:112e34adf95e45158c597feea65d06a8124898bdeac975c9087fe71b572bd938"}, - {file = "regex-2020.6.8-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:92d8a043a4241a710c1cf7593f5577fbb832cf6c3a00ff3fc1ff2052aff5dd89"}, - {file = "regex-2020.6.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bae83f2a56ab30d5353b47f9b2a33e4aac4de9401fb582b55c42b132a8ac3868"}, - {file = "regex-2020.6.8-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:b2ba0f78b3ef375114856cbdaa30559914d081c416b431f2437f83ce4f8b7f2f"}, - {file = "regex-2020.6.8-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:95fa7726d073c87141f7bbfb04c284901f8328e2d430eeb71b8ffdd5742a5ded"}, - {file = "regex-2020.6.8-cp36-cp36m-win32.whl", hash = "sha256:e3cdc9423808f7e1bb9c2e0bdb1c9dc37b0607b30d646ff6faf0d4e41ee8fee3"}, - {file = "regex-2020.6.8-cp36-cp36m-win_amd64.whl", hash = "sha256:c78e66a922de1c95a208e4ec02e2e5cf0bb83a36ceececc10a72841e53fbf2bd"}, - {file = "regex-2020.6.8-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:08997a37b221a3e27d68ffb601e45abfb0093d39ee770e4257bd2f5115e8cb0a"}, - {file = "regex-2020.6.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2f6f211633ee8d3f7706953e9d3edc7ce63a1d6aad0be5dcee1ece127eea13ae"}, - {file = "regex-2020.6.8-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:55b4c25cbb3b29f8d5e63aeed27b49fa0f8476b0d4e1b3171d85db891938cc3a"}, - {file = "regex-2020.6.8-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:89cda1a5d3e33ec9e231ece7307afc101b5217523d55ef4dc7fb2abd6de71ba3"}, - {file = "regex-2020.6.8-cp37-cp37m-win32.whl", hash = "sha256:690f858d9a94d903cf5cada62ce069b5d93b313d7d05456dbcd99420856562d9"}, - {file = "regex-2020.6.8-cp37-cp37m-win_amd64.whl", hash = "sha256:1700419d8a18c26ff396b3b06ace315b5f2a6e780dad387e4c48717a12a22c29"}, - {file = "regex-2020.6.8-cp38-cp38-manylinux1_i686.whl", hash = "sha256:654cb773b2792e50151f0e22be0f2b6e1c3a04c5328ff1d9d59c0398d37ef610"}, - {file = "regex-2020.6.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:52e1b4bef02f4040b2fd547357a170fc1146e60ab310cdbdd098db86e929b387"}, - {file = "regex-2020.6.8-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:cf59bbf282b627130f5ba68b7fa3abdb96372b24b66bdf72a4920e8153fc7910"}, - {file = "regex-2020.6.8-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:5aaa5928b039ae440d775acea11d01e42ff26e1561c0ffcd3d805750973c6baf"}, - {file = "regex-2020.6.8-cp38-cp38-win32.whl", hash = "sha256:97712e0d0af05febd8ab63d2ef0ab2d0cd9deddf4476f7aa153f76feef4b2754"}, - {file = "regex-2020.6.8-cp38-cp38-win_amd64.whl", hash = "sha256:6ad8663c17db4c5ef438141f99e291c4d4edfeaacc0ce28b5bba2b0bf273d9b5"}, - {file = "regex-2020.6.8.tar.gz", hash = "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac"}, + {file = "regex-2020.7.14-cp27-cp27m-win32.whl", hash = "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7"}, + {file = "regex-2020.7.14-cp27-cp27m-win_amd64.whl", hash = "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd"}, + {file = "regex-2020.7.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88"}, + {file = "regex-2020.7.14-cp36-cp36m-win32.whl", hash = "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4"}, + {file = "regex-2020.7.14-cp36-cp36m-win_amd64.whl", hash = "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7"}, + {file = "regex-2020.7.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89"}, + {file = "regex-2020.7.14-cp37-cp37m-win32.whl", hash = "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6"}, + {file = "regex-2020.7.14-cp37-cp37m-win_amd64.whl", hash = "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e"}, + {file = "regex-2020.7.14-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a"}, + {file = "regex-2020.7.14-cp38-cp38-win32.whl", hash = "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341"}, + {file = "regex-2020.7.14-cp38-cp38-win_amd64.whl", hash = "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840"}, + {file = "regex-2020.7.14.tar.gz", hash = "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb"}, ] requests = [ {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, @@ -748,6 +1064,38 @@ snowballstemmer = [ {file = "snowballstemmer-2.0.0-py2.py3-none-any.whl", hash = "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0"}, {file = "snowballstemmer-2.0.0.tar.gz", hash = "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"}, ] +sphinx = [ + {file = "Sphinx-3.1.2-py3-none-any.whl", hash = "sha256:97dbf2e31fc5684bb805104b8ad34434ed70e6c588f6896991b2fdfd2bef8c00"}, + {file = "Sphinx-3.1.2.tar.gz", hash = "sha256:b9daeb9b39aa1ffefc2809b43604109825300300b987a24f45976c001ba1a8fd"}, +] +sphinx-rtd-theme = [ + {file = "sphinx_rtd_theme-0.5.0-py2.py3-none-any.whl", hash = "sha256:373413d0f82425aaa28fb288009bf0d0964711d347763af2f1b65cafcb028c82"}, + {file = "sphinx_rtd_theme-0.5.0.tar.gz", hash = "sha256:22c795ba2832a169ca301cd0a083f7a434e09c538c70beb42782c073651b707d"}, +] +sphinxcontrib-applehelp = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] +sphinxcontrib-devhelp = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] +sphinxcontrib-htmlhelp = [ + {file = "sphinxcontrib-htmlhelp-1.0.3.tar.gz", hash = "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b"}, + {file = "sphinxcontrib_htmlhelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f"}, +] +sphinxcontrib-jsmath = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] +sphinxcontrib-qthelp = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] +sphinxcontrib-serializinghtml = [ + {file = "sphinxcontrib-serializinghtml-1.1.4.tar.gz", hash = "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc"}, + {file = "sphinxcontrib_serializinghtml-1.1.4-py2.py3-none-any.whl", hash = "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"}, +] spotipy = [ {file = "spotipy-2.13.0-py2-none-any.whl", hash = "sha256:600f05bccd4b4217a02843a01025cf94b65c2ff2babeff3dcbd091a6e09ab0af"}, {file = "spotipy-2.13.0-py3-none-any.whl", hash = "sha256:a8221233a486584666ab20faf730439b5d8026d63c162cd51bda752ec7c91deb"}, diff --git a/pyproject.toml b/pyproject.toml index 4c777fbd..7cbd6fb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,9 @@ uwsgi = "^2.0.18" psycopg2-binary = "^2.8.5" spotipy = "^2.12.0" coverage = "^5.1" +sphinx = "^3.1.2" +recommonmark = "^0.6.0" +sphinx_rtd_theme = "^0.5.0" django-guardian = "^2.3.0" [tool.poetry.dev-dependencies] diff --git a/resources/entrypoint.sh b/resources/entrypoint.sh index 3695c47b..49544838 100644 --- a/resources/entrypoint.sh +++ b/resources/entrypoint.sh @@ -11,7 +11,6 @@ touch -a /tosti/log/django.log cd /tosti/src/website -./manage.py collectstatic --no-input -v0 --ignore="*.scss" ./manage.py migrate --no-input chown --recursive www-data:www-data /tosti/ diff --git a/website/manage.py b/website/manage.py index 951dc24b..0a139c32 100755 --- a/website/manage.py +++ b/website/manage.py @@ -6,7 +6,7 @@ def main(): """Django management command.""" - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tosti.settings.development") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tosti.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: diff --git a/website/marietje/models.py b/website/marietje/models.py index 6596a729..b1900794 100644 --- a/website/marietje/models.py +++ b/website/marietje/models.py @@ -63,12 +63,10 @@ def currently_playing(self): Get currently playing music information. :return: a dictionary with the following content: - { image: [link to image of track], name: [name of currently playing track], artists: [list of artist names], is_playing: [True|False] - } """ if not self.configured: raise RuntimeError("This Spotify account is not configured yet.") diff --git a/website/orders/views.py b/website/orders/views.py index b2f13b81..b2e76702 100644 --- a/website/orders/views.py +++ b/website/orders/views.py @@ -394,9 +394,7 @@ def post(self, request, **kwargs): :param request: the request :param kwargs: keyword arguments :return: a JsonResponse of the following format: - { active: [shift.can_order] - } """ shift = kwargs.get("shift") active = request.POST.get("active", "false") @@ -434,9 +432,7 @@ def post(self, request, **kwargs): :param request: the request :param kwargs: keyword arguments :return: a JsonResponse of the following format: - { error: False - } """ shift = kwargs.get("shift") @@ -473,9 +469,7 @@ def post(self, request, **kwargs): :param request: the request :param kwargs: keyword arguments :return: a JsonResponse of the following format: - { error: False - } """ shift = kwargs.get("shift") try: @@ -506,9 +500,7 @@ def post(self, request, **kwargs): :param request: the request :param kwargs: keyword arguments :return: The header in the following JSON format: - { data: [header] - } """ shift = kwargs.get("shift") header = get_template(self.template_name).render( @@ -529,9 +521,7 @@ def post(self, request, **kwargs): :param request: the request :param kwargs: keyword arguments :return: The product overview in the following JSON format: - { data: [header] - } """ shift = kwargs.get("shift") overview = get_template(self.template_name).render( @@ -554,9 +544,7 @@ def post(self, request, **kwargs): :param request: the request :param kwargs: keyword arguments :return: The footer in the following JSON format: - { status: [shift.can_order] - } """ shift = kwargs.get("shift") return JsonResponse({"status": shift.can_order}) @@ -587,9 +575,7 @@ def post(self, request, **kwargs): :param request: the request :param kwargs: keyword arguments :return: The orders in the following JSON format: - { data: [orders] - } """ shift = kwargs.get("shift") admin = request.POST.get("admin", "false") == "true" diff --git a/website/tosti/settings/__init__.py b/website/tosti/settings/__init__.py new file mode 100644 index 00000000..db2febf4 --- /dev/null +++ b/website/tosti/settings/__init__.py @@ -0,0 +1,29 @@ +""" +Settings module. + +This file controls what settings are loaded. + +Using environment variables you can control the loading of various +overrides. +""" + +import logging + +# Load all default settings because we need to use settings.configure +# for sphinx documentation generation. +from django.conf.global_settings import * + +# Load base settings +from .settings import * + +logger = logging.getLogger(__name__) + +# Attempt to load local overrides +try: + from .localsettings import * +except ImportError: + pass + +# Load production settings if DJANGO_PRODUCTION is set +if os.environ.get("DJANGO_PRODUCTION"): + from .production import * diff --git a/website/tosti/settings/development.py b/website/tosti/settings/development.py index ae286b80..5ba1d498 100644 --- a/website/tosti/settings/development.py +++ b/website/tosti/settings/development.py @@ -11,7 +11,7 @@ """ import os -from tosti.settings.base import * # noqa +from tosti.settings import * # noqa SECRET_KEY = "7c^z*je^r!@aw!0*vuc1t4cp1rfi+4+xu@x5pva@xc@rf%3#lt" diff --git a/website/tosti/settings/production.py b/website/tosti/settings/production.py index 40a6f6f4..8e0da89a 100644 --- a/website/tosti/settings/production.py +++ b/website/tosti/settings/production.py @@ -12,7 +12,7 @@ import os -from tosti.settings.base import * # noqa +from tosti.settings import * # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY") @@ -20,11 +20,32 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = False +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.abspath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..") +) ALLOWED_HOSTS = ["tosti.science.ru.nl", "tosti.total5.nl"] SESSION_COOKIE_SECURE = True +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [os.path.join(BASE_DIR, "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", + "tosti.context_processors.google_analytics", + ], + }, + }, +] + DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", @@ -51,6 +72,15 @@ }, # noqa } +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.2/howto/static-files/ + +STATIC_ROOT = os.path.join(BASE_DIR, "static/") +STATIC_URL = "/static/" + +MEDIA_ROOT = os.path.join(BASE_DIR, "media/") +MEDIA_URL = "/media/" + if os.environ.get("GOOGLE_ANALYTICS_KEY"): GOOGLE_ANALYTICS_KEY = os.environ.get("GOOGLE_ANALYTICS_KEY") @@ -66,6 +96,3 @@ SPOTIFY_CACHE_PATH = os.environ.get("DJANGO_SPOTIFY_CACHE_PATH") else: SPOTIFY_CACHE_PATH = os.path.join(BASE_DIR, "cache") # noqa - -if os.environ.get("GOOGLE_ANALYTICS_KEY"): - GOOGLE_ANALYTICS_KEY = os.environ.get("GOOGLE_ANALYTICS_KEY") diff --git a/website/tosti/settings/base.py b/website/tosti/settings/settings.py similarity index 93% rename from website/tosti/settings/base.py rename to website/tosti/settings/settings.py index 1656a40c..1e3865bb 100644 --- a/website/tosti/settings/base.py +++ b/website/tosti/settings/settings.py @@ -10,7 +10,15 @@ https://docs.djangoproject.com/en/2.2/ref/settings/ """ -import os # noqa +import os + + +SECRET_KEY = "7c^z*je^r!@aw!0*vuc1t4cp1rfi+4+xu@x5pva@xc@rf%3#lt" + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.abspath( @@ -134,3 +142,5 @@ OPENID_SERVER_ENDPOINT = "https://openid.science.ru.nl/openid-server" OPENID_USERNAME_PREFIX = "http://openid.science.ru.nl/" OPENID_USERNAME_POSTFIX = "/" + +SPOTIFY_CACHE_PATH = os.path.join(BASE_DIR, "cache") # noqa diff --git a/website/tosti/urls.py b/website/tosti/urls.py index 4bc5b7c1..a8818789 100644 --- a/website/tosti/urls.py +++ b/website/tosti/urls.py @@ -2,17 +2,23 @@ TOSTI URL Configuration. The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/2.2/topics/http/urls/ +https://docs.djangoproject.com/en/2.2/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') + +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') + +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')) + +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.urls import path, include