~sirn/fanboi2

b897b6703e31d9d216b37ba192be38db6a28dba1 — Kridsada Thanabulpong 1 year, 8 months ago 27c31c6
[chore] modernize python development stack with poetry
12 files changed, 1013 insertions(+), 612 deletions(-)

M .build.yml
A .flake8
M .gitignore
D CHANGES.md
D Dockerfile
D MANIFEST.in
D Makefile
M README.md
A poetry.lock
A pyproject.toml
D setup.cfg
D setup.py
M .build.yml => .build.yml +10 -25
@@ 2,6 2,7 @@ image: freebsd/latest
packages:
  - node8
  - npm-node8
  - postgresql10-client
  - postgresql10-server
  - py36-pip
  - py36-sqlite3


@@ 9,21 10,20 @@ packages:
  - python3
  - python36
  - yarn-node8
secrets:
  - 1628f803-8887-41bc-9044-d8e909dcc77b
sources:
  - https://git.sr.ht/~sirn/fanboi2
environment:
  BUILDDIR: /tmp/fanboi2-build
  VENVDIR: /tmp/fanboi2-venv
tasks:
  - build: |
  - setup: |
      cd fanboi2/ || exit 1
      export PATH=$HOME/.local/bin:$PATH

      make prod
      make assets
      pip install --user poetry
      poetry install
      yarn install
      yarn run gulp
  - test: |
      cd fanboi2/ || exit 1
      export PATH=$HOME/.local/bin:$PATH

      sudo service postgresql oneinitdb
      sudo sysrc postgresql_enable=YES


@@ 41,20 41,5 @@ tasks:
      sudo -u postgres createuser -ds fanboi2
      sudo -u postgres createdb -U fanboi2 fanboi2_test

      make test POSTGRESQL_TEST_DATABASE="postgresql://fanboi2:@localhost:5432/fanboi2_test"

      _local=$(git rev-parse HEAD)
      _remote=$(git ls-remote https://git.sr.ht/~sirn/fanboi2 refs/heads/master | awk '{ print $1 }')
      if [ "$_local" != "$_remote" ]; then
        complete-build
      fi
  - deploy: |
      cd fanboi2/ || exit 1

      make deploy

      $VENVDIR/bin/fbdeploy \
        --path=/srv/fanboi2 \
        --user=fanboi2 \
        --postcmd=/srv/fanboi2/postcmd \
        $(host -t A app.targets.fanboi.ch | awk '{ print $4 }')
      export POSTGRESQL_TEST_DATABASE="postgresql://fanboi2:@localhost:5432/fanboi2_test"
      poetry run nose2

A .flake8 => .flake8 +5 -0
@@ 0,0 1,5 @@
[flake8]
ignore = E203, E266, E501, W503
max-line-length = 80
max-complexity = 18
select = B,C,E,F,W,T4,B9

M .gitignore => .gitignore +2 -3
@@ 16,8 16,7 @@ tmp/
celerybeat*

# Building
*.build
*.venv
dist/

# Assets
node_modules/


@@ 35,4 34,4 @@ node_modules/
.docker-compose.override.yml
.vagrant
node_modules/
out/
\ No newline at end of file
out/

D CHANGES.md => CHANGES.md +0 -165
@@ 1,165 0,0 @@
# 2018.12

-   **Add**: GetIPIntel threshold is now configurable.
-   **Add**: Topics can now be configured to expire after a specific duration of inactivity.
-   **Add**: Allow bans to be scoped using regular expression.
-   **Add**: Allow banwords to be scoped using board and regular expression.
-   **Fix**: Dashboard no longer error if session was never seen.
-   **Change**: Datetime operations now use PostgreSQL and Redis as time sources.
-   **Change**: Memcached cache backend has been replaced with Redis cache backend.
-   **Change**: Banning rules is now part of base rules system.
-   **Change**: Use [Gunicorn](https://gunicorn.org/) as a backend to `fbserve` instead of [Waitress](https://docs.pylonsproject.org/projects/waitress/en/latest/).

## 0.30.0

-   **Add**: Admin panel at /admin.
-   **Add**: Topic view now has canonical link.
-   **Change**: Major refactoring to utilizes [pyramid_services](https://github.com/mmerickel/pyramid_services).
-   **Change**: Application now uses environment variable as a primary means for configuration.
-   **Change**: Switch to use [Pyramid's native CSRF checking](https://docs.pylonsproject.org/projects/pyramid/en/latest/api/csrf.html).
-   **Change**: Switch to use [PyNaCl](https://github.com/Pylons/pyramid_nacl_session/) for session factory.
-   **Remove**: Override rules are now removed as it add unnecessary complexity.
-   **Remove**: Country configuration for post filter is now removed in favor for recently seen.

## 0.10.2

-   **Add**: Allow post filter to be configured per country.
-   **Add**: A `fb2_topic_sync` script for syncing topic's bumped timestamp.
-   **Fix**: CSRF check now use constant-time comparison to prevent timing attack.
-   **Change**: Requires minimum of 5 characters for post body.
-   **Change**: Codebase now uses [Python 3.6](https://docs.python.org/3.6/whatsnew/changelog.html#python-3-6-4-final).

## 0.10.1

-   **Add**: A `board` query string for expanding board from topic API.
-   **Add**: A `topic` query string for expanding post from post API.
-   **Change**: Switch to [Yarn](https://yarnpkg.com/) for assets package management.
-   **Change**: Stylings of appendix section is now consistent with the footer.

## 0.10.0

-   **Add**: Basic API for board, topic and post operations.
-   **Add**: Dark theme ("Obsidian").
-   **Add**: Banning rules allowing an IP address to be blocked.
-   **Add**: Proxy detection allowing open proxies and public VPNs to be blocked.
-   **Add**: Overriding rules allowing board status to be overridden per IP address.
-   **Add**: Board can now be locked or archived.
-   **Add**: Board, topic and post will now create a history copy on change.
-   **Add**: Custom pages for guidelines or site customization ("internal pages").
-   **Add**: YouTube videos now display a thumbnail.
-   **Add**: More random quotes.
-   **Fix**: Imgur album and gallery now no longer matched in thumbnail extractor.
-   **Change**: Rewrite all board templates.
-   **Change**: Application settings can now be override via environment variables.
-   **Change**: Codebase now comes with type annotation for IDE.
-   **Change**: Codebase now uses [Python 3.5](https://docs.python.org/3.5/whatsnew/changelog.html#python-3-5-2).
-   **Change**: Replaced [Jinja2](http://jinja.pocoo.org/) templates with [Mako](http://www.makotemplates.org/) templates.
-   **Change**: Views, models, utils and formatters are now organized into modules.
-   **Change**: Views now use function dispatching instead of class-based dispatching.
-   **Change**: Celery worker now load full Pyramid environment again to simplify initialization.
-   **Change**: Vagrant now use [FreeBSD 10.3](https://www.freebsd.org/) instead of [Ubuntu 12.04](http://releases.ubuntu.com/precise/) to match the new production stack.
-   **Remove**: Get rid of all usage of `pyramid.threadlocal`.
-   **Remove**: Production provisioning is now private.

## 0.8.3

-   **Add**: Referencing post cross-board is now possible with ">>>/board/topic/anchor" syntax (e.g. ">>>/demo/123/10-11").
-   **Change**: Post errors reporting now no longer rely on [Celery](http://www.celeryproject.org)'s exceptions.

## 0.8.2

-   **Fix**: Akismet now properly timed out and will no longer cause posting to hang forever.

## 0.8.1

-   **Fix**: Debug toolbar is now working development mode again (caused by Python 3.2.3 bug).
-   **Change**: Celery worker no longer load full Pyramid environment.
-   **Remove**: No longer use pyramid_zcml and webtest.

## 0.8.0

-   **Change**: Posts are now processed in a separate worker (using [Celery](http://www.celeryproject.org).

## 0.7.2

-   **Change**: Posting is now done via AJAX in both inline reply and normal reply.
-   **Change**: "New since visit" button is now "Reload posts" using AJAX.

## 0.7.1

-   **Change**: Bump status is now remembered per topic.
-   **Change**: Use [jQuery](http://jquery.com) and [CoffeeScript](http://coffeescript.org).
-   **Change**: Update the post number styling to indicate bump status.

## 0.7.0

-   **Add**: When replying, user can now choose to bump topic or to not bump.
-   **Add**: Clicking on post number in reply page will now auto-fill the reply textarea.
-   **Add**: Clicking on post number in listing page will now display inline reply box.

## 0.6.2

-   **Add**: Caching support with [dogpile.cache](http://dogpilecache.readthedocs.org).
-   **Add**: Templates could now be cached using [Memcached](http://memcached.org).
-   **Change**: Initialize [Redis-py](https://redis-py.readthedocs.org) with late-binding to remove [Pyramid registry](http://docs.pylonsproject.org/projects/pyramid/en/latest/glossary.html#term-application-registry) access.
-   **Change**: Ident generator now no longer accessing Pyramid registry.

## 0.6.1

-   **Fix**: The layout no longer collapse when read more posts and thumbnails are displayed together.
-   **Change**: Use [Ansible](http://www.ansibleworks.com) for provisioning instead of [Puppet](http://puppetlabs.com).
-   **Change**: Navigation bar now overlay content to workaround slow DOM update in iOS 7 and Mavericks.

## 0.6.0

-   **Add**: Temporary favicon.
-   **Change**: Posts exceeding 500 characters in topic list will now be abbreviated.
-   **Change**: Rate limit could now be set per-board.
-   **Change**: stylings in all topic list page and reduce font size for 11th posts and on.

## 0.5.1

-   **Fix**: Site will no longer error when board description does not exists.
-   **Fix**: Fix an installation error due to import within setup.py.
-   **Fix**: Post count now takes deleted posts into consideration.
-   **Fix**: Posts are now properly displayed regardless of post count.

## 0.5.0

-   **Add**: Integration with [Akismet](http://akismet.com) for SPAM detection in comments.
-   **Change**: Use URL dispatching instead of [traversal](http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/traversal.html) to reduce complexity.

## 0.4.0

-   **Add**: Add top-right and bottom-right buttons for jumping to header and footer.
-   **Add**: Automatically turning text into links.
-   **Add**: Post anchor popover now support ranged posts.
-   **Fix**: Adjust stylings for error page when post wasn't successful.
-   **Fix**: Character count in form now correctly take DOS newline into consideration.
-   **Fix**: popover to no longer dismiss if user try to mouse over it.
-   **Change**: Move redirect path after reply to last 5 posts instead of full topic.
-   **Change**: Change link target for topic title to recent posts instead of full topic.
-   **Change**: Update header design to be no longer dependent to number of boards.
-   **Change**: Use file hash instead of timestamp for smarter cache expiration.

## 0.3.0

-   **Add**: All assets path now has timestamp appended to it for cache expiration.
-   **Add**: Image links from [Imgur](https://imgur.com) now show thumbnail preview.
-   **Add**: Mouseover post anchor now display a post popover (single post only).
-   **Add**: All use-facing pages now has proper page title.
-   **Change**: Use a fixed 980px layout for widescreen responsive level instead of fluid layout.
-   **Change**: Use the same mobile-optimized layout similar to board listing page in all posts page.

## 0.2.0

-   **Add**: Forms now require [CSRF token](http://wtforms.simplecodes.com/docs/1.0.3/ext.html#module-wtforms.ext.csrf) to be present.
-   **Change**: Switch to use [Beaker](https://github.com/Pylons/pyramid_beaker/) for session factory.
-   **Change**: Use a custom-made template instead of [Bootstrap](http://twitter.github.com/bootstrap/).
-   **Change**: Replaced Makefile-based assets compilation with [Brunch](http://brunch.io/).
-   **Change**: Support Python 3.2 as minimal version (was Python 3.3).
-   **Change**: Use [Vagrant](http://www.vagrantup.com/) for environment provisioning.

## 0.1.0

-   Initial version

D Dockerfile => Dockerfile +0 -71
@@ 1,71 0,0 @@
FROM node:8-alpine as assets

WORKDIR /src

COPY Makefile gulpfile.js package.json tsconfig.json yarn.lock ./
COPY assets ./assets

RUN set -xe \
 && apk add --update --no-cache --virtual .run-deps \
        make \
 && make assets

FROM python:3.6-alpine

ENV S6_VERSION 1.21.7.0

RUN set -xe \
 && apk add --update --no-cache --virtual .s6-fetch \
        ca-certificates \
        curl \
 && S6_DOWNLOAD_URL="https://github.com/just-containers/s6-overlay/releases/download/v${S6_VERSION}/s6-overlay-amd64.tar.gz" \
 && S6_DOWNLOAD_SHA256="7ffd83ad59d00d4c92d594f9c1649faa99c0b87367b920787d185f8335cbac47" \
 && curl -fsL -o s6-overlay.tar.gz "${S6_DOWNLOAD_URL}" \
 && echo "${S6_DOWNLOAD_SHA256}  s6-overlay.tar.gz" |sha256sum -c - \
 && tar -xzC / -f s6-overlay.tar.gz \
 && rm s6-overlay.tar.gz \
 && apk del .s6-fetch

ENV HOME /data

ENV DATADIR /data
ENV VENVDIR /data/venv
ENV BUILDDIR /data/build

WORKDIR /src

COPY Makefile setup.py setup.cfg ./

RUN set -xe \
 && apk add --update --no-cache --virtual .app-build \
        build-base \
        libffi-dev \
        postgresql-dev \
        py3-virtualenv \
 && apk add --update --no-cache --virtual .app-run \
        libffi \
        make \
        postgresql-libs \
 && sed -i -e 's/^all:*/all: prod/' Makefile \
 && sed -i -e 's/^ASSETS_SRCS.*/ASSETS_SRCS ?=/' Makefile \
 && addgroup -g 10000 fanboi2 \
 && adduser -D -h /tmp -u 10000 -G fanboi2 fanboi2 \
 && mkdir -p $DATADIR \
 && chown -R "10000:10000" $DATADIR \
 && chown -R "10000:10000" /src \
 && s6-setuidgid fanboi2 make prod \
 && rm -rf /data/.cache \
 && apk del .app-build

COPY rootfs/ /
COPY --chown=fanboi2:fanboi2 alembic.ini ./
COPY --chown=fanboi2:fanboi2 fanboi2/ ./fanboi2
COPY --chown=fanboi2:fanboi2 migration/ ./migration
COPY --chown=fanboi2:fanboi2 --from=assets /src/fanboi2/static ./fanboi2/static

RUN set -xe \
 && chmod +x /entrypoint

ENTRYPOINT ["/init", "/entrypoint"]

CMD ["serve"]

D MANIFEST.in => MANIFEST.in +0 -3
@@ 1,3 0,0 @@
include *.ini *.cfg *.rst
recursive-include fanboi2 *.py *.ico *.png *.css *.gif *.jpg *.mako *.js
recursive-include migration *.py *.mako

D Makefile => Makefile +0 -156
@@ 1,156 0,0 @@
LDFLAGS+=		-L/usr/local/lib
CFLAGS+=		-I/usr/local/include
HOSTNAME!=		hostname -s

BUILDDIR?=		builds/$(HOSTNAME)
VENVDIR?=		$(BUILDDIR)/venv
YARN?=			yarn

VIRTUALENV?=	virtualenv
ALEMBIC=		$(VENVDIR)/bin/alembic
FBCTL=			$(VENVDIR)/bin/fbctl
FBCELERY=		$(VENVDIR)/bin/fbcelery
PIP=			$(VENVDIR)/bin/pip3
PYTHON=			$(VENVDIR)/bin/python3

BUILDENV=		env LANG=en_US.UTF-8 LDFLAGS="$(LDFLAGS)" CFLAGS="$(CFLAGS)"

ASSETS_SRCS!=	[ -d assets ] && find assets/ -type f


all: assets prod


## Build target
##


$(VENVDIR):
	$(VIRTUALENV) -p python3.6 $(VENVDIR)


$(BUILDDIR):
	mkdir -p $@


$(BUILDDIR)/.build: $(VENVDIR) $(BUILDDIR) setup.py
	$(BUILDENV) $(PIP) install -e .
	touch $(BUILDDIR)/.build


$(BUILDDIR)/.build-test: $(VENVDIR) $(BUILDDIR) setup.py
	$(BUILDENV) $(PIP) install -e .[test]
	touch \
		$(BUILDDIR)/.build \
		$(BUILDDIR)/.build-test


$(BUILDDIR)/.build-dev: $(VENVDIR) $(BUILDDIR) setup.py
	$(BUILDENV) $(PIP) install -e .[test,dev]
	touch \
		$(BUILDDIR)/.build \
		$(BUILDDIR)/.build-test \
		$(BUILDDIR)/.build-dev

$(BUILDDIR)/.build-deploy: $(VENVDIR) $(BUILDDIR) setup.py
	$(BUILDENV) $(PIP) install -e .[deploy]
	touch $(BUILDDIR)/.build-deploy


node_modules: package.json yarn.lock
	$(YARN) install


$(BUILDDIR)/.build-assets: $(ASSETS_SRCS) $(BUILDDIR) node_modules
	$(YARN) run gulp
	touch $(BUILDDIR)/.build-assets


## Production target
##


prod: $(BUILDDIR)/.build


serve: prod
	$(FBCTL) serve


worker: prod
	$(FBCELERY) worker


shell: prod
	$(FBCTL) shell


beat: prod
	$(FBCELERY) beat


assets: $(BUILDDIR)/.build-assets


## Development target
##


dev: $(BUILDDIR)/.build-dev


devserve: dev
	$(FBCTL) serve --reload --workers=1 --threads=4


devassets: assets
	$(YARN) run gulp watch


test: $(BUILDDIR)/.build-test
	$(PYTHON) setup.py nosetests $(ARGS)


## Deploy target
##


deploy: $(BUILDDIR)/.build-deploy


dist: distclean assets distpack


distclean:
	$(PYTHON) setup.py clean


distpack:
	$(PYTHON) setup.py sdist


## Maintenance target
##


migrate: $(BUILDDIR)/.build
	$(ALEMBIC) upgrade head $(ARGS)


clean:
	rm -rf \
		$(BUILDDIR) \
		fanboi2.egg-info \
		fanboi2/__pycache__ \
		fanboi2/static \
		node_modules \
		$(VENVDIR)


$(VERBOSE).SILENT:


.PHONY: all prod serve worker shell beat assets
.PHONY: deploy dist distclean distpack
.PHONY: dev devserve devassets
.PHONY: test migrate clean

M README.md => README.md +11 -71
@@ 8,7 8,7 @@ Board engine behind [Fanboi Channel](https://fanboi.ch/) written in Python.

For production environment, Fanboi2 has the following runtime requirements:

-   [Python 3.6](https://www.python.org/downloads/) with [Virtualenv](https://virtualenv.pypa.io/en/stable/)
-   [Python 3.6](https://www.python.org/downloads/) with [Poetry](https://poetry.eustace.io)
-   [PostgreSQL 10](https://www.postgresql.org/)
-   [Redis](https://redis.io/)



@@ 21,16 21,18 @@ After all packages are installed, setup the application with:

    $ git clone https://git.sr.ht/~sirn/fanboi2 fanboi2
    $ cd fanboi2/
    $ make all -j2
    $ poetry install --no-dev
    $ yarn install && yarn run gulp

Then configure environment variables according to the configuring section below, and run:

    $ make migrate
    $ make serve
    $ poetry run alembic upgrade head
    $ poetry run fbctl serve

You also need to run the worker (in another terminal) with:
You also need to run the worker (each in its own terminal window) with:

    $ make worker
    $ poetry run fbcelery worker
    $ poetry run fbcelery beat

And you're done! Please visit <http://localhost:6543/admin/> to perform initial configuration.



@@ 51,14 53,12 @@ Fanboi2 uses environment variable to configure the application. You may want to 

To setup Fanboi2 in development mode, run the following commands after performing production setup steps:

    $ make dev
    $ poetry install

And run the server with (each in its own terminal window):

    $ make devserve
    $ make devassets
    $ make worker
    $ make beat
    $ poetry run fbctl serve --reload --workers=1 --threads=4
    $ yarn run gulp watch

### Submitting changes



@@ 81,66 81,6 @@ Submitting patches via mailing list is recommended in case you wish to remain an
-   When making a non-trivial changes, please first discuss in the [mailing list](https://lists.sr.ht/~sirn/fanboi2-dev) or in the [development thread](https://fanboi.ch/meta/).
-   Make sure new features has enough tests and no regressions.

## Workflow

Fanboi2 uses a `Makefile`-based workflow in its development and production cycle. You are encourage to use `make` rather than directly invoking underlying commands. The provided `Makefile` can be customized to certain extent using environment variable, such as:

-   `VERBOSE=1` -- Prints the underlying command when running `make`.
-   `VIRTUALENV=virtualenv` -- Specifies the `virtualenv` binary (e.g. `virtualenv-3.6` for BSDs)
-   `YARN=yarn` -- Specifies the `yarn` binary.
-   `VENVDIR=.venv` -- Specifies the virtualenv directory.

The following make targets are available for use in production:

-   `make all` build the application and assets using production configurations.
-   `make prod` build the application using production configuration.
-   `make serve` run the application server.
-   `make worker` run the application worker.
-   `make assets` build assets.
-   `make migrate` migrate daabase.
-   `make clean` remove everything.

The following make targets are available for use in development:

-   `make dev` builds the application using development configuration.
-   `make devrun` run the development application server, application worker and assets watcher.
-   `make devserve` run the development application server.
-   `make devassets` run the development assets watcher.

The following make targets are available for use in test environment:

-   `make test` run tests.

Most of these commands make use of VENVDIR.

### The Adventurous Way

If using `make` is not your thing, you can set everything up manually, for example on macOS:

    $ brew install python@3 node@8 yarn

Create the deploy environment:

    $ mkdir -p $HOME/dev/fanboi2/venv
    $ virtualenv new -p python3 $HOME/dev/fanboi2/venv
    $ git clone https://git.sr.ht/~sirn/fanboi2 $HOME/dev/fanboi2/src

Setup the application:

    $ cd $HOME/dev/fanboi2/src
    $ $HOME/dev/fanboi2/venv/bin/pip3 install -e .[dev,test]
    $ yarn install
    $ yarn run gulp

Configure environment variable then:

    $ $HOME/dev/fanboi2/venv/bin/alembic upgrade head
    $ $HOME/dev/fanboi2/venv/bin/fbctl serve --reload

In another terminal, run the worker:

    $ $HOME/dev/fanboi2/venv/bin/fbcelery worker

## License

Copyright © 2013-2019, Kridsada Thanabulpong. All rights reserved.

A poetry.lock => poetry.lock +927 -0
@@ 0,0 1,927 @@
[[package]]
category = "dev"
description = "A configurable sidebar-enabled Sphinx theme"
name = "alabaster"
optional = true
python-versions = "*"
version = "0.7.12"

[[package]]
category = "main"
description = "A database migration tool for SQLAlchemy."
name = "alembic"
optional = false
python-versions = "*"
version = "0.9.10"

[package.dependencies]
Mako = "*"
SQLAlchemy = ">=0.7.6"
python-dateutil = "*"
python-editor = ">=0.3"

[[package]]
category = "main"
description = "Low-level AMQP client for Python (fork of amqplib)."
name = "amqp"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "2.5.0"

[package.dependencies]
vine = ">=1.1.3,<5.0.0a1"

[[package]]
category = "main"
description = "The secure Argon2 password hashing algorithm."
name = "argon2-cffi"
optional = false
python-versions = "*"
version = "19.1.0"

[package.dependencies]
cffi = ">=1.0.0"
six = "*"

[[package]]
category = "dev"
description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP"
name = "asn1crypto"
optional = true
python-versions = "*"
version = "0.24.0"

[[package]]
category = "dev"
description = "Internationalization utilities"
name = "babel"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "2.7.0"

[package.dependencies]
pytz = ">=2015.7"

[[package]]
category = "dev"
description = "Modern password hashing for your software and your servers"
name = "bcrypt"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "3.1.7"

[package.dependencies]
cffi = ">=1.1"
six = ">=1.4.1"

[[package]]
category = "main"
description = "Python multiprocessing fork with improvements and bugfixes"
name = "billiard"
optional = false
python-versions = "*"
version = "3.5.0.5"

[[package]]
category = "dev"
description = "A thin, practical wrapper around terminal coloring, styling, and positioning"
name = "blessings"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.7"

[package.dependencies]
six = "*"

[[package]]
category = "main"
description = "Distributed Task Queue."
name = "celery"
optional = false
python-versions = "*"
version = "4.1.1"

[package.dependencies]
billiard = ">=3.5.0.2,<3.6.0"
kombu = ">=4.2.0,<5.0"
pytz = ">0.0-dev"

[[package]]
category = "main"
description = "Python package for providing Mozilla's CA Bundle."
name = "certifi"
optional = false
python-versions = "*"
version = "2019.6.16"

[[package]]
category = "main"
description = "Foreign Function Interface for Python calling C code."
name = "cffi"
optional = false
python-versions = "*"
version = "1.12.3"

[package.dependencies]
pycparser = "*"

[[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."
name = "colorama"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "0.4.1"

[[package]]
category = "dev"
description = "Code coverage measurement for Python"
name = "coverage"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <4"
version = "4.5.3"

[[package]]
category = "dev"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
name = "cryptography"
optional = true
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
version = "2.7"

[package.dependencies]
asn1crypto = ">=0.21.0"
cffi = ">=1.8,<1.11.3 || >1.11.3"
six = ">=1.4.1"

[[package]]
category = "main"
description = "Better living through Python with decorators"
name = "decorator"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
version = "4.4.0"

[[package]]
category = "dev"
description = "Docutils -- Python Documentation Utilities"
name = "docutils"
optional = true
python-versions = "*"
version = "0.14"

[[package]]
category = "main"
description = "A caching front-end based on the Dogpile lock."
name = "dogpile.cache"
optional = false
python-versions = "*"
version = "0.7.1"

[package.dependencies]
decorator = "*"

[[package]]
category = "dev"
description = "Python 3.4 Enum backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4"
name = "enum34"
optional = true
python-versions = "*"
version = "1.1.6"

[[package]]
category = "dev"
description = "High level SSH command execution"
name = "fabric"
optional = true
python-versions = "*"
version = "2.4.0"

[package.dependencies]
cryptography = ">=1.1"
invoke = ">=1.1,<2.0"
paramiko = ">=2.4"

[[package]]
category = "main"
description = "MaxMind GeoIP2 API"
name = "geoip2"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
version = "2.9.0"

[package.dependencies]
maxminddb = ">=1.4.0"
requests = ">=2.9"

[[package]]
category = "main"
description = "WSGI HTTP Server for UNIX"
name = "gunicorn"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
version = "19.9.0"

[[package]]
category = "main"
description = "Python wrapper for hiredis"
name = "hiredis"
optional = false
python-versions = "*"
version = "0.2.0"

[[package]]
category = "main"
description = "Integrated process monitor for developing and reloading daemons."
name = "hupper"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
version = "1.8.1"

[[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 = "Getting image size from png/jpeg/jpeg2000/gif file"
name = "imagesize"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.1.0"

[[package]]
category = "dev"
description = "Common/best-practice Invoke tasks and collections"
name = "invocations"
optional = true
python-versions = "*"
version = "1.4.0"

[package.dependencies]
blessings = ">=1.6,<2"
enum34 = ">=1.1,<2"
invoke = ">=1.0,<2.0"
releases = ">=1.6,<2"
semantic-version = ">=2.4,<3"
tabulate = "0.7.5"
tqdm = ">=4.8.1"

[[package]]
category = "dev"
description = "Pythonic task execution"
name = "invoke"
optional = true
python-versions = "*"
version = "1.2.0"

[[package]]
category = "main"
description = "An ISO 8601 date/time/duration parser and formatter"
name = "isodate"
optional = false
python-versions = "*"
version = "0.6.0"

[package.dependencies]
six = "*"

[[package]]
category = "dev"
description = "A small but fast and easy to use stand-alone template engine written in pure python."
name = "jinja2"
optional = true
python-versions = "*"
version = "2.10.1"

[package.dependencies]
MarkupSafe = ">=0.23"

[[package]]
category = "main"
description = "Messaging library for Python."
name = "kombu"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "4.3.0"

[package.dependencies]
amqp = ">=2.4.0,<3.0"

[[package]]
category = "main"
description = "a modern parsing library"
name = "lark-parser"
optional = false
python-versions = "*"
version = "0.6.7"

[[package]]
category = "main"
description = "A super-fast templating language that borrows the  best ideas from the existing templating languages."
name = "mako"
optional = false
python-versions = ">=2.6"
version = "1.0.13"

[package.dependencies]
MarkupSafe = ">=0.9.2"

[[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 = "main"
description = "Reader for the MaxMind DB format"
name = "maxminddb"
optional = false
python-versions = "*"
version = "1.4.1"

[[package]]
category = "main"
description = "A CFFI binding for Hoedown, a markdown parsing library."
name = "misaka"
optional = false
python-versions = "*"
version = "2.1.1"

[package.dependencies]
cffi = ">=1.0.0"

[[package]]
category = "dev"
description = "unittest2 with plugins, the succesor to nose"
name = "nose2"
optional = false
python-versions = "*"
version = "0.9.1"

[package.dependencies]
coverage = ">=4.4.1"
six = ">=1.7"

[[package]]
category = "dev"
description = "Core utilities for Python packages"
name = "packaging"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "19.0"

[package.dependencies]
pyparsing = ">=2.0.2"
six = "*"

[[package]]
category = "dev"
description = "SSH2 protocol library"
name = "paramiko"
optional = true
python-versions = "*"
version = "2.6.0"

[package.dependencies]
bcrypt = ">=3.1.3"
cryptography = ">=2.5"
pynacl = ">=1.0.1"

[[package]]
category = "main"
description = "comprehensive password hashing framework supporting over 30 schemes"
name = "passlib"
optional = false
python-versions = "*"
version = "1.7.1"

[[package]]
category = "main"
description = "Load, configure, and compose WSGI applications and servers"
name = "pastedeploy"
optional = false
python-versions = "*"
version = "2.0.1"

[[package]]
category = "dev"
description = "Deployment/sysadmin operations, powered by Fabric"
name = "patchwork"
optional = true
python-versions = "*"
version = "1.0.1"

[package.dependencies]
fabric = ">=2.0,<3.0"

[[package]]
category = "main"
description = "A loader interface around multiple config file formats."
name = "plaster"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
version = "1.0"

[package.dependencies]
setuptools = "*"

[[package]]
category = "main"
description = "A loader implementing the PasteDeploy syntax to be used by plaster."
name = "plaster-pastedeploy"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
version = "0.7"

[package.dependencies]
PasteDeploy = ">=2.0"
plaster = ">=0.5"

[[package]]
category = "main"
description = "psycopg2 - Python-PostgreSQL Database Adapter"
name = "psycopg2"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
version = "2.8.3"

[[package]]
category = "main"
description = "C parser in Python"
name = "pycparser"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "2.19"

[[package]]
category = "main"
description = "Pygments is a syntax highlighting package written in Python."
name = "pygments"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "2.4.2"

[[package]]
category = "main"
description = "Python binding to the Networking and Cryptography (NaCl) library"
name = "pynacl"
optional = false
python-versions = "*"
version = "1.3.0"

[package.dependencies]
cffi = ">=1.4.1"
six = "*"

[[package]]
category = "dev"
description = "Python parsing module"
name = "pyparsing"
optional = true
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
version = "2.4.0"

[[package]]
category = "main"
description = "The Pyramid Web Framework, a Pylons project"
name = "pyramid"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
version = "1.9.4"

[package.dependencies]
PasteDeploy = ">=1.5.0"
WebOb = ">=1.7.0"
hupper = "*"
plaster = "*"
plaster-pastedeploy = "*"
"repoze.lru" = ">=0.4"
setuptools = "*"
translationstring = ">=0.4"
venusian = ">=1.0a3"
"zope.deprecation" = ">=3.5.0"
"zope.interface" = ">=3.8.0"

[[package]]
category = "main"
description = "A package which provides an interactive HTML debugger for Pyramid application development"
name = "pyramid-debugtoolbar"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
version = "4.5"

[package.dependencies]
Pygments = "*"
pyramid = ">=1.4"
pyramid-mako = ">=0.3.1"
"repoze.lru" = "*"

[[package]]
category = "main"
description = "Mako template bindings for the Pyramid web framework"
name = "pyramid-mako"
optional = false
python-versions = "*"
version = "1.0.2"

[package.dependencies]
Mako = ">=0.8"
pyramid = "*"

[[package]]
category = "main"
description = "Encrypted sessison cookie serializer ofr Pyramid"
name = "pyramid-nacl-session"
optional = false
python-versions = "*"
version = "0.3"

[package.dependencies]
PyNaCl = "*"
pyramid = ">=1.5"

[[package]]
category = "main"
description = "A service layer abstraction for the Pyramid Web Framework."
name = "pyramid-services"
optional = false
python-versions = ">=3.3"
version = "2.2"

[package.dependencies]
pyramid = "*"
wired = ">=0.2"
"zope.interface" = "*"

[[package]]
category = "main"
description = "A package which allows Pyramid requests to join the active transaction"
name = "pyramid-tm"
optional = false
python-versions = "*"
version = "2.2.1"

[package.dependencies]
pyramid = ">=1.5"
transaction = ">=2.0"

[[package]]
category = "main"
description = "Extensions to the standard Python datetime module"
name = "python-dateutil"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
version = "2.8.0"

[package.dependencies]
six = ">=1.5"

[[package]]
category = "main"
description = "Programmatically open an editor, capture the result."
name = "python-editor"
optional = false
python-versions = "*"
version = "1.0.4"

[[package]]
category = "main"
description = "World timezone definitions, modern and historical"
name = "pytz"
optional = false
python-versions = "*"
version = "2019.1"

[[package]]
category = "main"
description = "Python client for Redis key-value store"
name = "redis"
optional = false
python-versions = "*"
version = "2.0.0"

[[package]]
category = "dev"
description = "A Sphinx extension for changelog manipulation"
name = "releases"
optional = true
python-versions = "*"
version = "1.6.1"

[package.dependencies]
semantic-version = "<3.0"
sphinx = ">=1.3,<1.8"

[[package]]
category = "main"
description = "A tiny LRU cache implementation and decorator"
name = "repoze.lru"
optional = false
python-versions = "*"
version = "0.7"

[[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 = "dev"
description = "A library implementing the 'SemVer' scheme."
name = "semantic-version"
optional = true
python-versions = "*"
version = "2.6.0"

[[package]]
category = "main"
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 = "dev"
description = "This package provides 23 stemmers for 22 languages generated from Snowball algorithms."
name = "snowballstemmer"
optional = true
python-versions = "*"
version = "1.9.0"

[[package]]
category = "dev"
description = "Python documentation generator"
name = "sphinx"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.7.9"

[package.dependencies]
Jinja2 = ">=2.3"
Pygments = ">=2.0"
alabaster = ">=0.7,<0.8"
babel = ">=1.3,<2.0 || >2.0"
colorama = ">=0.3.5"
docutils = ">=0.11"
imagesize = "*"
packaging = "*"
requests = ">=2.0.0"
setuptools = "*"
six = ">=1.5"
snowballstemmer = ">=1.1"
sphinxcontrib-websupport = "*"

[[package]]
category = "dev"
description = "Sphinx API for Web Apps"
name = "sphinxcontrib-websupport"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.1.2"

[[package]]
category = "main"
description = "Database Abstraction Library"
name = "sqlalchemy"
optional = false
python-versions = "*"
version = "1.2.19"

[[package]]
category = "dev"
description = "Pretty-print tabular data"
name = "tabulate"
optional = true
python-versions = "*"
version = "0.7.5"

[[package]]
category = "dev"
description = "Fast, Extensible Progress Meter"
name = "tqdm"
optional = true
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
version = "4.32.2"

[[package]]
category = "main"
description = "Transaction management for Python"
name = "transaction"
optional = false
python-versions = "*"
version = "2.4.0"

[package.dependencies]
"zope.interface" = "*"

[[package]]
category = "main"
description = "Utility library for i18n relied on by various Repoze and Pyramid packages"
name = "translationstring"
optional = false
python-versions = "*"
version = "1.3"

[[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 = "main"
description = "A library for deferring decorator actions"
name = "venusian"
optional = false
python-versions = "*"
version = "1.2.0"

[[package]]
category = "main"
description = "Promises, promises, promises."
name = "vine"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "1.3.0"

[[package]]
category = "main"
description = "WSGI request and response object"
name = "webob"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*"
version = "1.8.5"

[[package]]
category = "main"
description = "An inversion-of-control (IoC) container for building decoupled, configurable, pluggable applications."
name = "wired"
optional = false
python-versions = ">=3.4"
version = "0.2"

[package.dependencies]
"zope.interface" = "*"

[[package]]
category = "main"
description = "A flexible forms validation and rendering library for python web development."
name = "wtforms"
optional = false
python-versions = "*"
version = "2.1"

[[package]]
category = "main"
description = "Zope Deprecation Infrastructure"
name = "zope.deprecation"
optional = false
python-versions = "*"
version = "4.4.0"

[package.dependencies]
setuptools = "*"

[[package]]
category = "main"
description = "Interfaces for Python"
name = "zope.interface"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "4.6.0"

[package.dependencies]
setuptools = "*"

[[package]]
category = "main"
description = "Minimal Zope/SQLAlchemy transaction integration"
name = "zope.sqlalchemy"
optional = false
python-versions = "*"
version = "1.1"

[package.dependencies]
SQLAlchemy = ">=0.5.1"
setuptools = "*"
transaction = ">=1.6.0"
"zope.interface" = ">=3.6.0"

[extras]
deploy = []

[metadata]
content-hash = "72385dddd31ce11dd323c327d73270626c8bc4aa6176edf7200a2ba51e6af2c8"
python-versions = "^3.6"

[metadata.hashes]
alabaster = ["446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", "a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"]
alembic = ["1cd32df9a3b8c1749082ef60ffbe05ff16617b6afadfdabc680dcb9344af33d7"]
amqp = ["aa4409446139676943a2eaa27d5f58caf750f4ca5a89f888c452afd86be6a67d", "cbb6f87d53cac612a594f982b717cc1c54c6a1e17943a0a0d32dc6cc9e2120c8"]
argon2-cffi = ["1029fef2f7808a89e3baa306f5ace36e768a2d847ee7b056399adcd7707f6256", "206857d870c6ca3c92514ca70a3c371be47383f7ae6a448f5a16aa17baa550ba", "3558a7e22b886efad0c99b23b9be24880213b4e2d1630095459978cfcae570e2", "457fd6de741859aa91c750ffad97f12675c4356047e43392c5fb21f5d9f48b24", "4a1daa9f6960cdbdb865efcabac4158693459f52e7582c9f8a7c92dc61cdc8e1", "4bfb603184ea678563c0f1f1872367e81a3d2b70646a627d38ccede68d7b9194", "5d7493ed10e384b84b6dac862fe96c443297a25b991a8364d94a67b6cd1e9569", "5fb080047517add8d27baeb38a314814b5ab9c72630606788909b3f60a8f054a", "7453b16496b5629005a43c5f5707ef8a31fcfa5bb0ed34b5ba7b86a3cc9d02f2", "81548a27b919861040cb928a350733f4f9455dd67c7d1ba92eb5960a1d7f8b26", "84fd768d523f87097d572cdfb98e868cdbdc8e80e3d444787fd32e7f6ae25b02", "8b4cf6c0298f33b92fcd50f19899175b7421690fc8bc6ac68368320c158cbf51", "af6a4799411eee3f7133fead973727f5fefacd18ea23f51039e70cae51ceb109", "df7d60a4cf58dc08319fedc0506b42ec0fa5221c6e1f9e2e89fcddff92507390", "f9072e9f70185a57e36228d34aad4bb644e6a8b4fd6a45f856c666f38f6de96c", "fbae1d08b52f9a791500c650ab51ba00e374eaeccb5dbaa41b99dab4fd4115e8", "fe91e3bd95aeae70366693dcc970db03a71619d19df6fbaabf662c3b3c54cdf8", "fec86ee6f913154846171f66ee30c893c0cde3d434911f8b31c1f84a9aea410e"]
asn1crypto = ["2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87", "9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49"]
babel = ["af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab", "e86135ae101e31e2c8ec20a4e0c5220f4eed12487d5cf3f78be7e98d3a57fc28"]
bcrypt = ["0258f143f3de96b7c14f762c770f5fc56ccd72f8a1857a451c1cd9a655d9ac89", "0b0069c752ec14172c5f78208f1863d7ad6755a6fae6fe76ec2c80d13be41e42", "19a4b72a6ae5bb467fea018b825f0a7d917789bcfe893e53f15c92805d187294", "5432dd7b34107ae8ed6c10a71b4397f1c853bd39a4d6ffa7e35f40584cffd161", "69361315039878c0680be456640f8705d76cb4a3a3fe1e057e0f261b74be4b31", "6fe49a60b25b584e2f4ef175b29d3a83ba63b3a4df1b4c0605b826668d1b6be5", "74a015102e877d0ccd02cdeaa18b32aa7273746914a6c5d0456dd442cb65b99c", "763669a367869786bb4c8fcf731f4175775a5b43f070f50f46f0b59da45375d0", "8b10acde4e1919d6015e1df86d4c217d3b5b01bb7744c36113ea43d529e1c3de", "9fe92406c857409b70a38729dbdf6578caf9228de0aef5bc44f859ffe971a39e", "a190f2a5dbbdbff4b74e3103cef44344bc30e61255beb27310e2aec407766052", "a595c12c618119255c90deb4b046e1ca3bcfad64667c43d1166f2b04bc72db09", "c9457fa5c121e94a58d6505cadca8bed1c64444b83b3204928a866ca2e599105", "cb93f6b2ab0f6853550b74e051d297c27a638719753eb9ff66d1e4072be67133", "d7bdc26475679dd073ba0ed2766445bb5b20ca4793ca0db32b399dccc6bc84b7", "ff032765bb8716d9387fd5376d987a937254b0619eff0972779515b5c98820bc"]
billiard = ["42d9a227401ac4fba892918bba0a0c409def5435c4b483267ebfe821afaaba0e"]
blessings = ["98e5854d805f50a5b58ac2333411b0482516a8210f23f43308baeb58d77c157d", "b1fdd7e7a675295630f9ae71527a8ebc10bfefa236b3d6aa4932ee4462c17ba3", "caad5211e7ba5afe04367cdd4cfc68fa886e2e08f6f35e76b7387d2109ccea6e"]
celery = ["6fc4678d1692af97e137b2a9f1c04efd8e7e2fb7134c5c5ad60738cdd927762f", "d1f2a3359bdbdfb344edce98b8e891f5fe64f8a11c5a45538ec20ac237c971f5"]
certifi = ["046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", "945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695"]
cffi = ["041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774", "046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d", "066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90", "066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b", "2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63", "300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45", "34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25", "46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3", "4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b", "4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647", "4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016", "50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4", "55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb", "5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753", "59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7", "73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9", "a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f", "a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8", "a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f", "a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc", "ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42", "b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3", "d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909", "d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45", "dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d", "e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512", "e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff", "ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201"]
chardet = ["84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"]
colorama = ["05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", "f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"]
coverage = ["0c5fe441b9cfdab64719f24e9684502a59432df7570521563d7b1aff27ac755f", "2b412abc4c7d6e019ce7c27cbc229783035eef6d5401695dccba80f481be4eb3", "3684fabf6b87a369017756b551cef29e505cb155ddb892a7a29277b978da88b9", "39e088da9b284f1bd17c750ac672103779f7954ce6125fd4382134ac8d152d74", "3c205bc11cc4fcc57b761c2da73b9b72a59f8d5ca89979afb0c1c6f9e53c7390", "42692db854d13c6c5e9541b6ffe0fe921fe16c9c446358d642ccae1462582d3b", "465ce53a8c0f3a7950dfb836438442f833cf6663d407f37d8c52fe7b6e56d7e8", "48020e343fc40f72a442c8a1334284620f81295256a6b6ca6d8aa1350c763bbe", "4ec30ade438d1711562f3786bea33a9da6107414aed60a5daa974d50a8c2c351", "5296fc86ab612ec12394565c500b412a43b328b3907c0d14358950d06fd83baf", "5f61bed2f7d9b6a9ab935150a6b23d7f84b8055524e7be7715b6513f3328138e", "6899797ac384b239ce1926f3cb86ffc19996f6fa3a1efbb23cb49e0c12d8c18c", "68a43a9f9f83693ce0414d17e019daee7ab3f7113a70c79a3dd4c2f704e4d741", "6b8033d47fe22506856fe450470ccb1d8ba1ffb8463494a15cfc96392a288c09", "7ad7536066b28863e5835e8cfeaa794b7fe352d99a8cded9f43d1161be8e9fbd", "7bacb89ccf4bedb30b277e96e4cc68cd1369ca6841bde7b005191b54d3dd1034", "839dc7c36501254e14331bcb98b27002aa415e4af7ea039d9009409b9d2d5420", "8e679d1bde5e2de4a909efb071f14b472a678b788904440779d2c449c0355b27", "8f9a95b66969cdea53ec992ecea5406c5bd99c9221f539bca1e8406b200ae98c", "932c03d2d565f75961ba1d3cec41ddde00e162c5b46d03f7423edcb807734eab", "93f965415cc51604f571e491f280cff0f5be35895b4eb5e55b47ae90c02a497b", "988529edadc49039d205e0aa6ce049c5ccda4acb2d6c3c5c550c17e8c02c05ba", "998d7e73548fe395eeb294495a04d38942edb66d1fa61eb70418871bc621227e", "9de60893fb447d1e797f6bf08fdf0dbcda0c1e34c1b06c92bd3a363c0ea8c609", "9e80d45d0c7fcee54e22771db7f1b0b126fb4a6c0a2e5afa72f66827207ff2f2", "a545a3dfe5082dc8e8c3eb7f8a2cf4f2870902ff1860bd99b6198cfd1f9d1f49", "a5d8f29e5ec661143621a8f4de51adfb300d7a476224156a39a392254f70687b", "a9abc8c480e103dc05d9b332c6cc9fb1586330356fc14f1aa9c0ca5745097d19", "aca06bfba4759bbdb09bf52ebb15ae20268ee1f6747417837926fae990ebc41d", "bb23b7a6fd666e551a3094ab896a57809e010059540ad20acbeec03a154224ce", "bfd1d0ae7e292105f29d7deaa9d8f2916ed8553ab9d5f39ec65bcf5deadff3f9", "c22ab9f96cbaff05c6a84e20ec856383d27eae09e511d3e6ac4479489195861d", "c62ca0a38958f541a73cf86acdab020c2091631c137bd359c4f5bddde7b75fd4", "c709d8bda72cf4cd348ccec2a4881f2c5848fd72903c185f363d361b2737f773", "c968a6aa7e0b56ecbd28531ddf439c2ec103610d3e2bf3b75b813304f8cb7723", "ca58eba39c68010d7e87a823f22a081b5290e3e3c64714aac3c91481d8b34d22", "df785d8cb80539d0b55fd47183264b7002077859028dfe3070cf6359bf8b2d9c", "f406628ca51e0ae90ae76ea8398677a921b36f0bd71aab2099dfed08abd0322f", "f46087bbd95ebae244a0eda01a618aff11ec7a069b15a3ef8f6b520db523dcf1", "f8019c5279eb32360ca03e9fac40a12667715546eed5c5eb59eb381f2f501260", "fc5f4d209733750afd2714e9109816a29500718b32dd9a5db01c0cb3a019b96a"]
cryptography = ["24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c", "25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643", "3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216", "41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799", "5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a", "5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9", "72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc", "7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8", "961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53", "96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1", "ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609", "b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292", "cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e", "e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6", "f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed", "f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d"]
decorator = ["86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", "f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6"]
docutils = ["02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6", "51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274", "7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"]
"dogpile.cache" = ["691b7f199561c4bd6e7e96f164a43cc3781b0c87bea29b7d59d859f873fd4a31"]
enum34 = ["2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850", "644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a", "6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79", "8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"]
fabric = ["93684ceaac92e0b78faae551297e29c48370cede12ff0f853cdebf67d4b87068", "98538f2f3f63cf52497a8d0b24d18424ae83fe67ac7611225c72afb9e67f2cf6"]
geoip2 = ["a37ddac2d200ffb97c736da8b8ba9d5d8dc47da6ec0f162a461b681ecac53a14", "f7ffe9d258e71a42cf622ce6350d976de1d0312b9f2fbce3975c7d838b57ecf0"]
gunicorn = ["aa8e0b40b4157b36a5df5e599f45c9c76d6af43845ba3b3b0efe2c70473c2471", "fa2662097c66f920f53f70621c6c58ca4a3c4d3434205e608e121b5b3b71f4f3"]
hiredis = ["013c4e31be95bd5d9e45a0f830743458249012dc1691b45b1710976c280074a0", "0805bd9e98551bc904e487388c871c039878e5bf8fefed26b504dfe505ac91b4", "09025bdda2a17294be015bccab7c1039ed41c95cdbef8915f27006c5204e656c", "3f8b334c59c474e2b92580d7f4fb6503a08c013ae8a877ffc5c252f899d90ac6", "45887ded08a2e819123124b5cec4ec1c7e272a8c453d35fecb6d36e5b8c54717", "587f56d987cfa9397362d2f772b34ea69e61637fc0093807525e94cb919aa027", "71303245ea72cd85e72705ad237eb9d3847cdeff45f4ec81b0fa08ef4941610f", "7fd22790038ea983a5ecf8e77697906f59e9f781873cc8c9d6618bebeed7fb0c", "824e223a0e5a3a7b81025aa35075b4be5eec7251cebb3d305b092bc6f0beacaa", "bb2744c6026fa4dc4fb6b58d7b36d62ce3f669bb785956d1e3705b7bdbc23e3c", "c8a2d8d874b1cf6fb104a777846cfa22224f44ce3bef451ec4ae5160082825f7", "ca958e13128e49674aa4a96f02746f5de5973f39b57297b84d59fd44d314d5b5", "f69bffe7c1ad38be95bbb2c3e5c3f6f4eecb28b2f431a3c3e1532509eea89c92"]
hupper = ["5869ec2a46ba8ad481b0a27ca68f3e01dc7d3424925b7c872d9fcdff44b43442", "8532d116fef1f89add74dbd8d5e6541cb3278b04f4fe9780a1356cb6adba1141"]
idna = ["c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"]
imagesize = ["3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8", "f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"]
invocations = ["027f7e2dc3351999c99981c9fc7f70840e966aba7b866d8838bd1959432a1300", "b0b5e8c2a62b7b4267a31ff0c2ae4544fd97dcc70ac6081400f4fb530261a07c"]
invoke = ["4f4de934b15c2276caa4fbc5a3b8a61c0eb0b234f2be1780d2b793321995c2d6", "dc492f8f17a0746e92081aec3f86ae0b4750bf41607ea2ad87e5a7b5705121b7", "eb6f9262d4d25b40330fb21d1e99bf0f85011ccc3526980f8a3eaedd4b43892e"]
isodate = ["2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8", "aa4d33c06640f5352aca96e4b81afd8ab3b47337cc12089822d6f322ac772c81"]
jinja2 = ["065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", "14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"]
kombu = ["529df9e0ecc0bad9fc2b376c3ce4796c41b482cf697b78b71aea6ebe7ca353c8", "7a2cbed551103db9a4e2efafe9b63222e012a61a18a881160ad797b9d4e1d0a1"]
lark-parser = ["062800f3823a6c733ec1d181a2089a22d1f62dbe65f90a3f6b1e6de1934b05ef"]
mako = ["95ee720cc3453063788515d55bd7ce4a2a77b7b209e4ac70ec5c86091eb02541"]
markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"]
maxminddb = ["df1451bcd848199905ac0de4631b3d02d6a655ad28ba5e5a4ca29a23358db712"]
misaka = ["62f35254550095d899fc2ab8b33e156fc5e674176f074959cbca43cf7912ecd7"]
nose2 = ["0ede156fd7974fa40893edeca0b709f402c0ccacd7b81b22e76f73c116d1b999", "31d8beb00aed3ccc6efb1742bb90227d883e471715188249f594310676e0ef0e"]
packaging = ["0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af", "9e1cbf8c12b1f1ce0bb5344b8d7ecf66a6f8a6e91bcb0c84593ed6d3ab5c4ab3"]
paramiko = ["99f0179bdc176281d21961a003ffdb2ec369daac1a1007241f53374e376576cf", "f4b2edfa0d226b70bd4ca31ea7e389325990283da23465d572ed1f70a7583041"]
passlib = ["3d948f64138c25633613f303bcc471126eae67c04d5e3f6b7b8ce6242f8653e0", "43526aea08fa32c6b6dbbbe9963c4c767285b78147b7437597f992812f69d280"]
pastedeploy = ["d423fb9d51fdcf853aa4ff43ac7ec469b643ea19590f67488122d6d0d772350a", "fe53697ec2754703096b75d0ba29112b0590b4ce46726fe4f9408fd006e4eefc"]
patchwork = ["be5e8a52b9c604a853c9d841825b996ee084dfee3181f10e63a942d1fab2d699", "c7fe2830dc3db21e51b9654772fdbe3f14cee6d42467bfceb3491891dd647b68"]
plaster = ["215c921a438b5349931fd7df9a5a11a3572947f20f4bc6dd622ac08f1c3ba249", "8351c7c7efdf33084c1de88dd0f422cbe7342534537b553c49b857b12d98c8c3"]
plaster-pastedeploy = ["391d93a4e1ff81fc3bae27508ebb765b61f1724ae6169f83577f06b6357be7fd", "7c8aa37c917b615c70bf942b24dc1e0455c49f62f1a2214b1a0dd98871644bbb"]
psycopg2 = ["128d0fa910ada0157bba1cb74a9c5f92bb8a1dca77cf91a31eb274d1f889e001", "227fd46cf9b7255f07687e5bde454d7d67ae39ca77e170097cdef8ebfc30c323", "2315e7f104681d498ccf6fd70b0dba5bce65d60ac92171492bfe228e21dcc242", "4b5417dcd2999db0f5a891d54717cfaee33acc64f4772c4bc574d4ff95ed9d80", "640113ddc943522aaf71294e3f2d24013b0edd659b7820621492c9ebd3a2fb0b", "897a6e838319b4bf648a574afb6cabcb17d0488f8c7195100d48d872419f4457", "8dceca81409898c870e011c71179454962dec152a1a6b86a347f4be74b16d864", "b1b8e41da09a0c3ef0b3d4bb72da0dde2abebe583c1e8462973233fd5ad0235f", "cb407fccc12fc29dc331f2b934913405fa49b9b75af4f3a72d0f50f57ad2ca23", "d3a27550a8185e53b244ad7e79e307594b92fede8617d80200a8cce1fba2c60f", "f0e6b697a975d9d3ccd04135316c947dd82d841067c7800ccf622a8717e98df1"]
pycparser = ["a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"]
pygments = ["71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127", "881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"]
pynacl = ["05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255", "0c6100edd16fefd1557da078c7a31e7b7d7a52ce39fdca2bec29d4f7b6e7600c", "0d0a8171a68edf51add1e73d2159c4bc19fc0718e79dec51166e940856c2f28e", "1c780712b206317a746ace34c209b8c29dbfd841dfbc02aa27f2084dd3db77ae", "2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621", "2d23c04e8d709444220557ae48ed01f3f1086439f12dbf11976e849a4926db56", "30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39", "37aa336a317209f1bb099ad177fef0da45be36a2aa664507c5d72015f956c310", "4943decfc5b905748f0756fdd99d4f9498d7064815c4cf3643820c9028b711d1", "57ef38a65056e7800859e5ba9e6091053cd06e1038983016effaffe0efcd594a", "5bd61e9b44c543016ce1f6aef48606280e45f892a928ca7068fba30021e9b786", "6482d3017a0c0327a49dddc8bd1074cc730d45db2ccb09c3bac1f8f32d1eb61b", "7d3ce02c0784b7cbcc771a2da6ea51f87e8716004512493a2b69016326301c3b", "a14e499c0f5955dcc3991f785f3f8e2130ed504fa3a7f44009ff458ad6bdd17f", "a39f54ccbcd2757d1d63b0ec00a00980c0b382c62865b61a505163943624ab20", "aabb0c5232910a20eec8563503c153a8e78bbf5459490c49ab31f6adf3f3a415", "bd4ecb473a96ad0f90c20acba4f0bf0df91a4e03a1f4dd6a4bdc9ca75aa3a715", "e2da3c13307eac601f3de04887624939aca8ee3c9488a0bb0eca4fb9401fc6b1", "f67814c38162f4deb31f68d590771a29d5ae3b1bd64b75cf232308e5c74777e0"]
pyparsing = ["1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a", "9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03"]
pyramid = ["11f3a9763f0906eab3cd9dcb1622bed3bb4b920ff505731c48558a3fa6b5d795", "f0c75c8b2571a9bed71d3992e98887521e7e65711281493604caac2bf4593e3f"]
pyramid-debugtoolbar = ["74c5f52ce33765423810e156949b0f97852c66056c97de8c35a6db9b00195774", "f7c87b4931c17a189a26758c40619e379b670cd18ae1823500ffdc7e79fb6ec9"]
pyramid-mako = ["6da0987b9874cf53e72139624665a73965bbd7fbde504d1753e4231ce916f3a1"]
pyramid-nacl-session = ["12f3486361e6df284d261be22783278805184beadf629ac85c7c58aeba5e609d", "b7dca62622df5d21cd2ee52574d16d4b76c514298ad127f95bb2315e27573a1d"]
pyramid-services = ["01d175d84752e2a4178519cbd26cf900aa62a2e267cdd71370e5b88d06092b38", "459f4da035198592b776fe80f51e72439984f50abd4f2f1719584d37aa763639"]
pyramid-tm = ["7e374c0b774d4a5c83b04fe4c195a601c7219023cf4944a8e4251a86b7e288da", "fde97db9d92039a154ca6afffdd2485874c7d3e7a6432adb51b7a60810bad422"]
python-dateutil = ["7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb", "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"]
python-editor = ["1bf6e860a8ad52a14c3ee1252d5dc25b2030618ed80c022598f00176adc8367d", "51fda6bcc5ddbbb7063b2af7509e43bd84bfc32a4ff71349ec7847713882327b", "5f98b069316ea1c2ed3f67e7f5df6c0d8f10b689964a4a811ff64f0106819ec8", "c3da2053dbab6b29c94e43c486ff67206eafbe7eb52dbec7390b5e2fb05aac77", "ea87e17f6ec459e780e4221f295411462e0d0810858e055fc514684350a2f522"]
pytz = ["303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", "d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141"]
redis = ["81647560cc8d4ffff8c17db207c1410a036a1bc8e9d7cf753b76bc2ac41d0306"]
releases = ["16cc20a59bd00854a8c6070b5b5eb410b093cd59c69bc8feb0cbaadd4ae8bc23", "7a1b3163ab062d41dc4e61d8f51df055756d146f1fb6e18ee5cf55d91c9cda54"]
"repoze.lru" = ["0429a75e19380e4ed50c0694e26ac8819b4ea7851ee1fc7583c8572db80aff77", "f77bf0e1096ea445beadd35f3479c5cff2aa1efe604a133e67150bc8630a62ea"]
requests = ["11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"]
semantic-version = ["2a4328680073e9b243667b201119772aefc5fc63ae32398d6afafff07c4f54c0", "2d06ab7372034bcb8b54f2205370f4aa0643c133b7e6dbd129c5200b83ab394b"]
six = ["3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"]
snowballstemmer = ["9f3b9ffe0809d174f7047e121431acf99c89a7040f0ca84f94ba53a498e6d0c9"]
sphinx = ["217a7705adcb573da5bbe1e0f5cab4fa0bd89fd9342c9159121746f593c2d5a4", "a602513f385f1d5785ff1ca420d9c7eb1a1b63381733b2f0ea8188a391314a86"]
sphinxcontrib-websupport = ["1501befb0fdf1d1c29a800fdbf4ef5dc5369377300ddbdd16d2cd40e54c6eefc", "e02f717baf02d0b6c3dd62cf81232ffca4c9d5c331e03766982e3ff9f1d2bc3f"]
sqlalchemy = ["5bb2c4fc2bcc3447ad45716c66581eab982c007dcf925482498d8733f86f17c7"]
tabulate = ["9071aacbd97a9a915096c1aaf0dc684ac2672904cd876db5904085d6dac9810e"]
tqdm = ["14a285392c32b6f8222ecfbcd217838f88e11630affe9006cd0e94c7eff3cb61", "25d4c0ea02a305a688e7e9c2cdc8f862f989ef2a4701ab28ee963295f5b109ab"]
transaction = ["726059c461b9ec4e69e5bead6680667a3db01bf2adf901f23e4031228a0f9f9f", "b96a5e9aaa73f905759bc9ccf0021bf4864c01ac36666e0d28395e871f6d584a"]
translationstring = ["4ee44cfa58c52ade8910ea0ebc3d2d84bdcad9fa0422405b1801ec9b9a65b72d", "e26c7bf383413234ed442e0980a2ebe192b95e3745288a8fd2805156d27515b4"]
urllib3 = ["b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", "dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"]
venusian = ["2f2d077a1eedc3fda40425f65687c8c494da7e83d7c23bc2c4d1a40eb3ca5b6d", "64ec8285b80b110d0ae5db4280e90e31848a59db98db1aba4d7d46f48ce91e3e"]
vine = ["133ee6d7a9016f177ddeaf191c1f58421a1dcc6ee9a42c58b34bed40e1d2cd87", "ea4947cc56d1fd6f2095c8d543ee25dad966f78692528e68b4fada11ba3f98af"]
webob = ["05aaab7975e0ee8af2026325d656e5ce14a71f1883c52276181821d6d5bf7086", "36db8203c67023d68c1b00208a7bf55e3b10de2aa317555740add29c619de12b"]
wired = ["2151d437f7f1bdc531fb1e5bc3979ac0b8111713f9e7a12085e836f31381828c", "e0b0384347c4429a93e9ef8a49cf74b37278d148c627d73a8a9ffca18feed9d4"]
wtforms = ["ffdf10bd1fa565b8233380cb77a304cd36fd55c73023e91d4b803c96bc11d46f"]
"zope.deprecation" = ["0d453338f04bacf91bbfba545d8bcdf529aa829e67b705eac8c1a7fdce66e2df", "f1480b74995958b24ce37b0ef04d3663d2683e5d6debc96726eff18acf4ea113"]
"zope.interface" = ["086707e0f413ff8800d9c4bc26e174f7ee4c9c8b0302fbad68d083071822316c", "1157b1ec2a1f5bf45668421e3955c60c610e31913cc695b407a574efdbae1f7b", "11ebddf765bff3bbe8dbce10c86884d87f90ed66ee410a7e6c392086e2c63d02", "14b242d53f6f35c2d07aa2c0e13ccb710392bcd203e1b82a1828d216f6f6b11f", "1b3d0dcabc7c90b470e59e38a9acaa361be43b3a6ea644c0063951964717f0e5", "20a12ab46a7e72b89ce0671e7d7a6c3c1ca2c2766ac98112f78c5bddaa6e4375", "298f82c0ab1b182bd1f34f347ea97dde0fffb9ecf850ecf7f8904b8442a07487", "2f6175722da6f23dbfc76c26c241b67b020e1e83ec7fe93c9e5d3dd18667ada2", "3b877de633a0f6d81b600624ff9137312d8b1d0f517064dfc39999352ab659f0", "4265681e77f5ac5bac0905812b828c9fe1ce80c6f3e3f8574acfb5643aeabc5b", "550695c4e7313555549aa1cdb978dc9413d61307531f123558e438871a883d63", "5f4d42baed3a14c290a078e2696c5f565501abde1b2f3f1a1c0a94fbf6fbcc39", "62dd71dbed8cc6a18379700701d959307823b3b2451bdc018594c48956ace745", "7040547e5b882349c0a2cc9b50674b1745db551f330746af434aad4f09fba2cc", "7e099fde2cce8b29434684f82977db4e24f0efa8b0508179fce1602d103296a2", "7e5c9a5012b2b33e87980cee7d1c82412b2ebabcb5862d53413ba1a2cfde23aa", "81295629128f929e73be4ccfdd943a0906e5fe3cdb0d43ff1e5144d16fbb52b1", "95cc574b0b83b85be9917d37cd2fad0ce5a0d21b024e1a5804d044aabea636fc", "968d5c5702da15c5bf8e4a6e4b67a4d92164e334e9c0b6acf080106678230b98", "9e998ba87df77a85c7bed53240a7257afe51a07ee6bc3445a0bf841886da0b97", "a0c39e2535a7e9c195af956610dba5a1073071d2d85e9d2e5d789463f63e52ab", "a15e75d284178afe529a536b0e8b28b7e107ef39626a7809b4ee64ff3abc9127", "a6a6ff82f5f9b9702478035d8f6fb6903885653bff7ec3a1e011edc9b1a7168d", "b639f72b95389620c1f881d94739c614d385406ab1d6926a9ffe1c8abbea23fe", "bad44274b151d46619a7567010f7cde23a908c6faa84b97598fd2f474a0c6891", "bbcef00d09a30948756c5968863316c949d9cedbc7aabac5e8f0ffbdb632e5f1", "d788a3999014ddf416f2dc454efa4a5dbeda657c6aba031cf363741273804c6b", "eed88ae03e1ef3a75a0e96a55a99d7937ed03e53d0cffc2451c208db445a2966", "f99451f3a579e73b5dd58b1b08d1179791d49084371d9a47baad3b22417f0317"]
"zope.sqlalchemy" = ["454f71aa475d47ec4c9ed712eb0c31e90952f24dd690f4a0a41d87d6182fe0a2", "81554c5b03fbf924c4144ef835b7900271fbd85cfe81cb6bd95e3ab7aa85189f"]

A pyproject.toml => pyproject.toml +58 -0
@@ 0,0 1,58 @@
[tool.poetry]
name = "fanboi2"
version = "2019.8"
description = "Pseudonomous message board"
authors = ["Kridsada Thanabulpong <sirn@ogsite.net>"]
license = "BSD-3-Clause"
include = ["migration/**/*"]
exclude = ["fanboi2/tests/**/*"]

[tool.poetry.scripts]
fbctl = "fanboi2.cmd.ctl:main"
fbcelery = "fanboi2.cmd.celery:main"
fbdeploy = "fanboi2.cmd.deploy:main"

[tool.poetry.dependencies]
python = "^3.6"
MarkupSafe = "^1.1"
alembic = "~0.9"
argon2-cffi = "^19.1"
celery = "~4.1"
"dogpile.cache" = "^0.7.1"
geoip2 = "^2.9"
gunicorn = "^19.9"
hiredis = "~0.2"
isodate = "^0.6.0"
kombu = "~4.3"
lark-parser = "~0.6"
misaka = "^2.1"
passlib = "^1.7"
psycopg2 = "^2.8"
pyramid = "~1.9"
pyramid-debugtoolbar = "^4.5"
pyramid-mako = "^1.0"
pyramid-nacl-session = "^0.3.0"
pyramid-services = "^2.2"
pyramid-tm = "^2.2"
pytz = "^2019.1"
redis = "~2.0"
requests = "^2.22"
sqlalchemy = "~1.2"
transaction = "^2.4"
wtforms = "~2.1"
"zope.sqlalchemy" = "^1.1"

[tool.poetry.dev-dependencies]
hupper = "^1.8"
fabric = {version = "^2.4", optional = true}
patchwork = {version = "^1.0", optional = true}
invocations = {version = "^1.4", optional = true}
colorama = {version = "^0.4.1", optional = true}
nose2 = "^0.9.1"

[tool.poetry.extras]
deploy = ["fabric", "patchwork", "invocations", "colorama"]

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

D setup.cfg => setup.cfg +0 -38
@@ 1,38 0,0 @@
[coverage:report]
show_missing = true
omit =
     fanboi2/interfaces.py
     fanboi2/tests/*

[compile_catalog]
directory = fanboi2/locale
domain = fanboi2
statistics = true

[extract_messages]
add_comments = TRANSLATORS:
output_file = fanboi2/locale/fanboi2.pot
width = 80

[flake8]
ignore = E501, W503
max-line-length = 80
max-complexity = 15
select = B,C,E,F,W,B9

[init_catalog]
domain = fanboi2
input_file = fanboi2/locale/fanboi2.pot
output_dir = fanboi2/locale

[nosetests]
match = ^test
cover-package = fanboi2
with-coverage = true
rednose = true

[update_catalog]
domain = fanboi2
input_file = fanboi2/locale/fanboi2.pot
output_dir = fanboi2/locale
previous = true

D setup.py => setup.py +0 -80
@@ 1,80 0,0 @@
import os
from setuptools import setup, find_packages


if os.path.exists("README.md"):
    with open("README.md", "rb") as readme:
        LONG_DESCRIPTION = readme.read().decode("utf-8")
else:
    LONG_DESCRIPTION = ""


setup(
    name="fanboi2",
    version="2019.02",
    description="Board engine behind fanboi.ch",
    long_description=LONG_DESCRIPTION,
    long_description_content_type="text/markdown",
    url="https://git.sr.ht/~sirn/fanboi2",
    author="Kridsada Thanabulpong",
    author_email="sirn@ogsite.net",
    license="BSD-3-Clause",
    classifiers=[
        "Framework :: Pyramid",
        "License :: OSI Approved :: BSD License",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python",
        "Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Message Boards",
        "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
        "Topic :: Internet :: WWW/HTTP",
        "Topic :: Internet",
    ],
    keywords="web wsgi bfg pylons pyramid",
    packages=find_packages(),
    include_package_data=True,
    install_requires=[
        "MarkupSafe",
        "alembic >=0.9, <0.10",
        "argon2_cffi",
        "celery >=4.1, <4.2",
        "dogpile.cache >=0.6",
        "geoip2",
        "gunicorn",
        "hiredis >=0.2, <0.3",
        "isodate",
        "kombu >= 4.3, <4.4",
        "lark-parser >=0.6, <0.7",
        "misaka",
        "passlib",
        "psycopg2",
        "pyramid >=1.9, <1.10",
        "pyramid_debugtoolbar",
        "pyramid_mako",
        "pyramid_nacl_session",
        "pyramid_services",
        "pyramid_tm",
        "pytz",
        "redis >=2.0, <3.0",
        "requests",
        "sqlalchemy >=1.2, <1.3",
        "transaction",
        "wtforms >=2.1, <3.0",
        "zope.sqlalchemy",
    ],
    zip_safe=False,
    test_suite="fanboi2.tests",
    extras_require={
        "dev": ["hupper"],
        "test": ["nose", "coverage", "rednose"],
        "deploy": ["fabric", "patchwork", "invocations", "colorama"],
    },
    python_requires=">=3.6",
    entry_points={
        "console_scripts": [
            "fbctl = fanboi2.cmd.ctl:main",
            "fbcelery = fanboi2.cmd.celery:main",
            "fbdeploy = fanboi2.cmd.deploy:main",
        ]
    },
)