autogenerated opengraph images for documents

This commit is contained in:
Tomáš Mládek 2021-01-02 13:09:03 +01:00
parent bd7164dbba
commit 972f6b7b8e
9 changed files with 286 additions and 204 deletions

428
poetry.lock generated
View file

@ -1,67 +1,71 @@
[[package]]
category = "dev"
description = "Disable App Nap on OS X 10.9"
marker = "sys_platform == \"darwin\""
name = "appnope"
version = "0.1.0"
description = "Disable App Nap on OS X 10.9"
category = "dev"
optional = false
python-versions = "*"
version = "0.1.0"
marker = "sys_platform == \"darwin\""
[[package]]
category = "main"
description = "ASGI specs, helper code, and adapters"
name = "asgiref"
version = "3.2.5"
description = "ASGI specs, helper code, and adapters"
category = "main"
optional = false
python-versions = ">=3.5"
version = "3.2.5"
[package.extras]
tests = ["pytest (>=4.3.0,<4.4.0)", "pytest-asyncio (>=0.10.0,<0.11.0)"]
[[package]]
category = "dev"
description = "Specifications for callback functions passed in to an API"
name = "backcall"
version = "0.1.0"
description = "Specifications for callback functions passed in to an API"
category = "dev"
optional = false
python-versions = "*"
version = "0.1.0"
[[package]]
category = "main"
description = "An easy safelist-based HTML-sanitizing tool."
name = "bleach"
version = "3.1.4"
description = "An easy safelist-based HTML-sanitizing tool."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "3.1.4"
[package.dependencies]
six = ">=1.9.0"
webencodings = "*"
[[package]]
category = "main"
description = "cffi-based cairo bindings for Python"
name = "cairocffi"
version = "1.1.0"
description = "cffi-based cairo bindings for Python"
category = "main"
optional = false
python-versions = ">= 3.5"
version = "1.1.0"
[package.dependencies]
cffi = ">=1.1.0"
setuptools = ">=39.2.0"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
xcb = ["xcffib (>=0.3.2)"]
[package.dependencies]
cffi = ">=1.1.0"
setuptools = ">=39.2.0"
[[package]]
category = "main"
description = "A Simple SVG Converter based on Cairo"
name = "cairosvg"
version = "2.4.2"
description = "A Simple SVG Converter based on Cairo"
category = "main"
optional = false
python-versions = ">= 3.5"
version = "2.4.2"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
[package.dependencies]
cairocffi = "*"
@ -70,109 +74,102 @@ defusedxml = "*"
pillow = "*"
tinycss2 = "*"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
[[package]]
category = "main"
description = "Foreign Function Interface for Python calling C code."
name = "cffi"
version = "1.14.0"
description = "Foreign Function Interface for Python calling C code."
category = "main"
optional = false
python-versions = "*"
version = "1.14.0"
[package.dependencies]
pycparser = "*"
[[package]]
category = "dev"
description = "Cross-platform colored terminal text."
marker = "sys_platform == \"win32\""
name = "colorama"
version = "0.4.3"
description = "Cross-platform colored terminal text."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "0.4.3"
marker = "sys_platform == \"win32\""
[[package]]
category = "main"
description = "CSS selectors for Python ElementTree"
name = "cssselect2"
version = "0.3.0"
description = "CSS selectors for Python ElementTree"
category = "main"
optional = false
python-versions = ">=3.5"
version = "0.3.0"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
[package.dependencies]
setuptools = ">=39.2.0"
tinycss2 = "*"
webencodings = "*"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
[[package]]
category = "dev"
description = "Decorators for Humans"
name = "decorator"
version = "4.4.2"
description = "Decorators for Humans"
category = "dev"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*"
version = "4.4.2"
[[package]]
category = "main"
description = "XML bomb protection for Python stdlib modules"
name = "defusedxml"
version = "0.6.0"
description = "XML bomb protection for Python stdlib modules"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "0.6.0"
[[package]]
category = "main"
description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
name = "django"
version = "3.0.4"
description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
category = "main"
optional = false
python-versions = ">=3.6"
version = "3.0.4"
[package.extras]
argon2 = ["argon2-cffi (>=16.1.0)"]
bcrypt = ["bcrypt"]
[package.dependencies]
asgiref = ">=3.2,<4.0"
pytz = "*"
sqlparse = ">=0.2.2"
[package.extras]
argon2 = ["argon2-cffi (>=16.1.0)"]
bcrypt = ["bcrypt"]
[[package]]
category = "main"
description = "Django model mixins and utilities"
name = "django-model-utils"
version = "4.0.0"
description = "Django model mixins and utilities"
category = "main"
optional = false
python-versions = "*"
version = "4.0.0"
[package.dependencies]
Django = ">=2.0.1"
[[package]]
category = "main"
description = "Allows Django models to be ordered and provides a simple admin interface for reordering them."
name = "django-ordered-model"
version = "3.4.1"
description = "Allows Django models to be ordered and provides a simple admin interface for reordering them."
category = "main"
optional = false
python-versions = "*"
version = "3.4.1"
[[package]]
category = "dev"
description = "WSGI HTTP Server for UNIX"
name = "gunicorn"
version = "20.0.4"
description = "WSGI HTTP Server for UNIX"
category = "dev"
optional = false
python-versions = ">=3.4"
version = "20.0.4"
[package.dependencies]
setuptools = ">=3.0"
[package.extras]
eventlet = ["eventlet (>=0.9.7)"]
@ -180,17 +177,16 @@ gevent = ["gevent (>=0.13)"]
setproctitle = ["setproctitle"]
tornado = ["tornado (>=0.2)"]
[package.dependencies]
setuptools = ">=3.0"
[[package]]
category = "main"
description = "HTML parser based on the WHATWG HTML specification"
name = "html5lib"
version = "1.0.1"
description = "HTML parser based on the WHATWG HTML specification"
category = "main"
optional = false
python-versions = "*"
version = "1.0.1"
[package.dependencies]
six = ">=1.9"
webencodings = "*"
[package.extras]
all = ["genshi", "chardet (>=2.2)", "datrie", "lxml"]
@ -199,13 +195,28 @@ datrie = ["datrie"]
genshi = ["genshi"]
lxml = ["lxml"]
[package.dependencies]
six = ">=1.9"
webencodings = "*"
[[package]]
category = "dev"
description = "IPython: Productive Interactive Computing"
name = "ipython"
version = "7.13.0"
description = "IPython: Productive Interactive Computing"
category = "dev"
optional = false
python-versions = ">=3.6"
version = "7.13.0"
[package.extras]
all = ["numpy (>=1.14)", "testpath", "notebook", "nose (>=0.10.1)", "nbconvert", "requests", "ipywidgets", "qtconsole", "ipyparallel", "Sphinx (>=1.3)", "pygments", "nbformat", "ipykernel"]
doc = ["Sphinx (>=1.3)"]
kernel = ["ipykernel"]
nbconvert = ["nbconvert"]
nbformat = ["nbformat"]
notebook = ["notebook", "ipywidgets"]
parallel = ["ipyparallel"]
qtconsole = ["qtconsole"]
test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.14)"]
[package.dependencies]
appnope = "*"
@ -220,236 +231,237 @@ pygments = "*"
setuptools = ">=18.5"
traitlets = ">=4.2"
[package.extras]
all = ["numpy (>=1.14)", "testpath", "notebook", "nose (>=0.10.1)", "nbconvert", "requests", "ipywidgets", "qtconsole", "ipyparallel", "Sphinx (>=1.3)", "pygments", "nbformat", "ipykernel"]
doc = ["Sphinx (>=1.3)"]
kernel = ["ipykernel"]
nbconvert = ["nbconvert"]
nbformat = ["nbformat"]
notebook = ["notebook", "ipywidgets"]
parallel = ["ipyparallel"]
qtconsole = ["qtconsole"]
test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.14)"]
[[package]]
category = "dev"
description = "Vestigial utilities from IPython"
name = "ipython-genutils"
version = "0.2.0"
description = "Vestigial utilities from IPython"
category = "dev"
optional = false
python-versions = "*"
version = "0.2.0"
[[package]]
category = "dev"
description = "An autocompletion tool for Python that can be used for text editors."
name = "jedi"
version = "0.16.0"
description = "An autocompletion tool for Python that can be used for text editors."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "0.16.0"
[package.dependencies]
parso = ">=0.5.2"
[package.extras]
qa = ["flake8 (3.7.9)"]
testing = ["colorama (0.4.1)", "docopt", "pytest (>=3.9.0,<5.0.0)"]
[[package]]
category = "main"
description = "A fast and complete Python implementation of Markdown"
name = "markdown2"
optional = false
python-versions = "*"
version = "2.3.8"
[package.dependencies]
parso = ">=0.5.2"
[[package]]
name = "markdown2"
version = "2.3.8"
description = "A fast and complete Python implementation of Markdown"
category = "main"
optional = false
python-versions = "*"
[[package]]
category = "dev"
description = "A Python Parser"
name = "parso"
version = "0.6.2"
description = "A Python Parser"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "0.6.2"
[package.extras]
testing = ["docopt", "pytest (>=3.0.7)"]
[[package]]
category = "dev"
description = "Pexpect allows easy control of interactive console applications."
marker = "sys_platform != \"win32\""
name = "pexpect"
name = "pdf2image"
version = "1.14.0"
description = "A wrapper around the pdftoppm and pdftocairo command line tools to convert PDF to a PIL Image list."
category = "main"
optional = false
python-versions = "*"
[package.dependencies]
pillow = "*"
[[package]]
name = "pexpect"
version = "4.8.0"
description = "Pexpect allows easy control of interactive console applications."
category = "dev"
optional = false
python-versions = "*"
marker = "sys_platform != \"win32\""
[package.dependencies]
ptyprocess = ">=0.5"
[[package]]
category = "dev"
description = "Tiny 'shelve'-like database with concurrency support"
name = "pickleshare"
version = "0.7.5"
description = "Tiny 'shelve'-like database with concurrency support"
category = "dev"
optional = false
python-versions = "*"
version = "0.7.5"
[[package]]
category = "main"
description = "Python Imaging Library (Fork)"
name = "pillow"
version = "8.0.1"
description = "Python Imaging Library (Fork)"
category = "main"
optional = false
python-versions = ">=3.5"
version = "7.0.0"
python-versions = ">=3.6"
[[package]]
category = "dev"
description = "Library for building powerful interactive command lines in Python"
name = "prompt-toolkit"
version = "3.0.4"
description = "Library for building powerful interactive command lines in Python"
category = "dev"
optional = false
python-versions = ">=3.6.1"
version = "3.0.4"
[package.dependencies]
wcwidth = "*"
[[package]]
category = "dev"
description = "Run a subprocess in a pseudo terminal"
marker = "sys_platform != \"win32\""
name = "ptyprocess"
version = "0.6.0"
description = "Run a subprocess in a pseudo terminal"
category = "dev"
optional = false
python-versions = "*"
version = "0.6.0"
marker = "sys_platform != \"win32\""
[[package]]
category = "main"
description = "C parser in Python"
name = "pycparser"
version = "2.20"
description = "C parser in Python"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "2.20"
[[package]]
category = "dev"
description = "Pygments is a syntax highlighting package written in Python."
name = "pygments"
version = "2.6.1"
description = "Pygments is a syntax highlighting package written in Python."
category = "dev"
optional = false
python-versions = ">=3.5"
version = "2.6.1"
[[package]]
category = "main"
description = "PDF toolkit"
name = "pypdf2"
optional = false
python-versions = "*"
version = "1.26.0"
description = "PDF toolkit"
category = "main"
optional = false
python-versions = "*"
[[package]]
category = "main"
description = "Pure Python module to hyphenate text"
name = "pyphen"
optional = false
python-versions = "*"
version = "0.9.5"
[[package]]
description = "Pure Python module to hyphenate text"
category = "main"
description = "World timezone definitions, modern and historical"
name = "pytz"
optional = false
python-versions = "*"
version = "2019.3"
[[package]]
name = "pytz"
version = "2019.3"
description = "World timezone definitions, modern and historical"
category = "main"
description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = "*"
[[package]]
name = "six"
version = "1.14.0"
description = "Python 2 and 3 compatibility utilities"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
version = "1.14.0"
[[package]]
category = "main"
description = "Non-validating SQL parser"
name = "sqlparse"
version = "0.3.1"
description = "Non-validating SQL parser"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
version = "0.3.1"
[[package]]
category = "main"
description = "Low-level CSS parser for Python"
name = "tinycss2"
version = "1.0.2"
description = "Low-level CSS parser for Python"
category = "main"
optional = false
python-versions = ">= 3.5"
version = "1.0.2"
[package.dependencies]
setuptools = ">=39.2.0"
webencodings = ">=0.4"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
[package.dependencies]
setuptools = ">=39.2.0"
webencodings = ">=0.4"
[[package]]
category = "dev"
description = "Traitlets Python config system"
name = "traitlets"
version = "4.3.3"
description = "Traitlets Python config system"
category = "dev"
optional = false
python-versions = "*"
version = "4.3.3"
[package.extras]
test = ["pytest", "mock"]
[package.dependencies]
decorator = "*"
ipython-genutils = "*"
six = "*"
[package.extras]
test = ["pytest", "mock"]
[[package]]
category = "dev"
description = "Measures number of Terminal column cells of wide-character codes"
name = "wcwidth"
version = "0.1.8"
description = "Measures number of Terminal column cells of wide-character codes"
category = "dev"
optional = false
python-versions = "*"
version = "0.1.8"
[[package]]
category = "main"
description = "The Awesome Document Factory"
name = "weasyprint"
version = "51"
description = "The Awesome Document Factory"
category = "main"
optional = false
python-versions = ">=3.5"
version = "51"
[package.dependencies]
CairoSVG = ">=2.4.0"
Pyphen = ">=0.9.1"
cairocffi = ">=0.9.0"
cffi = ">=0.6"
cssselect2 = ">=0.1"
html5lib = ">=0.999999999"
setuptools = ">=39.2.0"
tinycss2 = ">=1.0.0"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
test = ["pytest-runner", "pytest-cov", "pytest-flake8", "pytest-isort"]
[package.dependencies]
cairocffi = ">=0.9.0"
CairoSVG = ">=2.4.0"
cffi = ">=0.6"
cssselect2 = ">=0.1"
html5lib = ">=0.999999999"
Pyphen = ">=0.9.1"
setuptools = ">=39.2.0"
tinycss2 = ">=1.0.0"
[[package]]
category = "main"
description = "Character encoding aliases for legacy web content"
name = "webencodings"
version = "0.5.1"
description = "Character encoding aliases for legacy web content"
category = "main"
optional = false
python-versions = "*"
version = "0.5.1"
[metadata]
content-hash = "c4c5d2ad677b97810bb47fc430207910d648ddc8ebc22de10715c58d8bb36f32"
lock-version = "1.0"
python-versions = "^3.8"
content-hash = "6d4369e2d21c34afe8c416e78d96e7de712a26b80781513d0296f32c5a556f26"
[metadata.files]
appnope = [
@ -561,6 +573,10 @@ parso = [
{file = "parso-0.6.2-py2.py3-none-any.whl", hash = "sha256:8515fc12cfca6ee3aa59138741fc5624d62340c97e401c74875769948d4f2995"},
{file = "parso-0.6.2.tar.gz", hash = "sha256:0c5659e0c6eba20636f99a04f469798dca8da279645ce5c387315b2c23912157"},
]
pdf2image = [
{file = "pdf2image-1.14.0-py3-none-any.whl", hash = "sha256:cf1b2dc77cf3e050cb06078cd7373469c8dca93d4cea1af2a2e1bbe0ed4a8800"},
{file = "pdf2image-1.14.0.tar.gz", hash = "sha256:066527e1bf954762fb4369c677ae3bc15f2ce8707eee830cccef8471fde736d7"},
]
pexpect = [
{file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
{file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
@ -570,28 +586,34 @@ pickleshare = [
{file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
]
pillow = [
{file = "Pillow-7.0.0-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:5f3546ceb08089cedb9e8ff7e3f6a7042bb5b37c2a95d392fb027c3e53a2da00"},
{file = "Pillow-7.0.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:9d2ba4ed13af381233e2d810ff3bab84ef9f18430a9b336ab69eaf3cd24299ff"},
{file = "Pillow-7.0.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:ff3797f2f16bf9d17d53257612da84dd0758db33935777149b3334c01ff68865"},
{file = "Pillow-7.0.0-cp35-cp35m-win32.whl", hash = "sha256:c18f70dc27cc5d236f10e7834236aff60aadc71346a5bc1f4f83a4b3abee6386"},
{file = "Pillow-7.0.0-cp35-cp35m-win_amd64.whl", hash = "sha256:875358310ed7abd5320f21dd97351d62de4929b0426cdb1eaa904b64ac36b435"},
{file = "Pillow-7.0.0-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:ab76e5580b0ed647a8d8d2d2daee170e8e9f8aad225ede314f684e297e3643c2"},
{file = "Pillow-7.0.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a62ec5e13e227399be73303ff301f2865bf68657d15ea50b038d25fc41097317"},
{file = "Pillow-7.0.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8ac6ce7ff3892e5deaab7abaec763538ffd011f74dc1801d93d3c5fc541feee2"},
{file = "Pillow-7.0.0-cp36-cp36m-win32.whl", hash = "sha256:91b710e3353aea6fc758cdb7136d9bbdcb26b53cefe43e2cba953ac3ee1d3313"},
{file = "Pillow-7.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:bf598d2e37cf8edb1a2f26ed3fb255191f5232badea4003c16301cb94ac5bdd0"},
{file = "Pillow-7.0.0-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:5bfef0b1cdde9f33881c913af14e43db69815c7e8df429ceda4c70a5e529210f"},
{file = "Pillow-7.0.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:dc058b7833184970d1248135b8b0ab702e6daa833be14035179f2acb78ff5636"},
{file = "Pillow-7.0.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c5ed816632204a2fc9486d784d8e0d0ae754347aba99c811458d69fcdfd2a2f9"},
{file = "Pillow-7.0.0-cp37-cp37m-win32.whl", hash = "sha256:54ebae163e8412aff0b9df1e88adab65788f5f5b58e625dc5c7f51eaf14a6837"},
{file = "Pillow-7.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:87269cc6ce1e3dee11f23fa515e4249ae678dbbe2704598a51cee76c52e19cda"},
{file = "Pillow-7.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0a628977ac2e01ca96aaae247ec2bd38e729631ddf2221b4b715446fd45505be"},
{file = "Pillow-7.0.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:62a889aeb0a79e50ecf5af272e9e3c164148f4bd9636cc6bcfa182a52c8b0533"},
{file = "Pillow-7.0.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bf4003aa538af3f4205c5fac56eacaa67a6dd81e454ffd9e9f055fff9f1bc614"},
{file = "Pillow-7.0.0-cp38-cp38-win32.whl", hash = "sha256:7406f5a9b2fd966e79e6abdaf700585a4522e98d6559ce37fc52e5c955fade0a"},
{file = "Pillow-7.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:5f7ae9126d16194f114435ebb79cc536b5682002a4fa57fa7bb2cbcde65f2f4d"},
{file = "Pillow-7.0.0-pp373-pypy36_pp73-win32.whl", hash = "sha256:8453f914f4e5a3d828281a6628cf517832abfa13ff50679a4848926dac7c0358"},
{file = "Pillow-7.0.0.tar.gz", hash = "sha256:4d9ed9a64095e031435af120d3c910148067087541131e82b3e8db302f4c8946"},
{file = "Pillow-8.0.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3"},
{file = "Pillow-8.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302"},
{file = "Pillow-8.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6b4a8fd632b4ebee28282a9fef4c341835a1aa8671e2770b6f89adc8e8c2703c"},
{file = "Pillow-8.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:cc3ea6b23954da84dbee8025c616040d9aa5eaf34ea6895a0a762ee9d3e12e11"},
{file = "Pillow-8.0.1-cp36-cp36m-win32.whl", hash = "sha256:d8a96747df78cda35980905bf26e72960cba6d355ace4780d4bdde3b217cdf1e"},
{file = "Pillow-8.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7ba0ba61252ab23052e642abdb17fd08fdcfdbbf3b74c969a30c58ac1ade7cd3"},
{file = "Pillow-8.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:795e91a60f291e75de2e20e6bdd67770f793c8605b553cb6e4387ce0cb302e09"},
{file = "Pillow-8.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0a2e8d03787ec7ad71dc18aec9367c946ef8ef50e1e78c71f743bc3a770f9fae"},
{file = "Pillow-8.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:006de60d7580d81f4a1a7e9f0173dc90a932e3905cc4d47ea909bc946302311a"},
{file = "Pillow-8.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bd7bf289e05470b1bc74889d1466d9ad4a56d201f24397557b6f65c24a6844b8"},
{file = "Pillow-8.0.1-cp37-cp37m-win32.whl", hash = "sha256:95edb1ed513e68bddc2aee3de66ceaf743590bf16c023fb9977adc4be15bd3f0"},
{file = "Pillow-8.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e38d58d9138ef972fceb7aeec4be02e3f01d383723965bfcef14d174c8ccd039"},
{file = "Pillow-8.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:d3d07c86d4efa1facdf32aa878bd508c0dc4f87c48125cc16b937baa4e5b5e11"},
{file = "Pillow-8.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:fbd922f702582cb0d71ef94442bfca57624352622d75e3be7a1e7e9360b07e72"},
{file = "Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:92c882b70a40c79de9f5294dc99390671e07fc0b0113d472cbea3fde15db1792"},
{file = "Pillow-8.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7c9401e68730d6c4245b8e361d3d13e1035cbc94db86b49dc7da8bec235d0015"},
{file = "Pillow-8.0.1-cp38-cp38-win32.whl", hash = "sha256:6c1aca8231625115104a06e4389fcd9ec88f0c9befbabd80dc206c35561be271"},
{file = "Pillow-8.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:cc9ec588c6ef3a1325fa032ec14d97b7309db493782ea8c304666fb10c3bd9a7"},
{file = "Pillow-8.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:eb472586374dc66b31e36e14720747595c2b265ae962987261f044e5cce644b5"},
{file = "Pillow-8.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0eeeae397e5a79dc088d8297a4c2c6f901f8fb30db47795113a4a605d0f1e5ce"},
{file = "Pillow-8.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81f812d8f5e8a09b246515fac141e9d10113229bc33ea073fec11403b016bcf3"},
{file = "Pillow-8.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:895d54c0ddc78a478c80f9c438579ac15f3e27bf442c2a9aa74d41d0e4d12544"},
{file = "Pillow-8.0.1-cp39-cp39-win32.whl", hash = "sha256:2fb113757a369a6cdb189f8df3226e995acfed0a8919a72416626af1a0a71140"},
{file = "Pillow-8.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:59e903ca800c8cfd1ebe482349ec7c35687b95e98cefae213e271c8c7fffa021"},
{file = "Pillow-8.0.1-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:5abd653a23c35d980b332bc0431d39663b1709d64142e3652890df4c9b6970f6"},
{file = "Pillow-8.0.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:4b0ef2470c4979e345e4e0cc1bbac65fda11d0d7b789dbac035e4c6ce3f98adb"},
{file = "Pillow-8.0.1-pp37-pypy37_pp73-win32.whl", hash = "sha256:8de332053707c80963b589b22f8e0229f1be1f3ca862a932c1bcd48dafb18dd8"},
{file = "Pillow-8.0.1.tar.gz", hash = "sha256:11c5c6e9b02c9dac08af04f093eb5a2f84857df70a7d4a6a6ad461aca803fb9e"},
]
prompt-toolkit = [
{file = "prompt_toolkit-3.0.4-py3-none-any.whl", hash = "sha256:859e1b205b6cf6a51fa57fa34202e45365cf58f8338f0ee9f4e84a4165b37d5b"},

View file

@ -13,6 +13,8 @@ pypdf2 = "^1.26.0"
markdown2 = "^2.3.8"
bleach = "^3.1.4"
django-ordered-model = "^3.4.1"
pillow = "^8.0.1"
pdf2image = "^1.14.0"
[tool.poetry.dev-dependencies]
ipython = "^7.13.0"

View file

@ -0,0 +1,19 @@
# Generated by Django 3.0.4 on 2021-01-02 11:34
import django.core.files.storage
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pile', '0013_auto_20200727_1533'),
]
operations = [
migrations.AddField(
model_name='document',
name='image',
field=models.ImageField(blank=True, null=True, storage=django.core.files.storage.FileSystemStorage(location='docs/images'), upload_to=''),
),
]

View file

@ -6,6 +6,7 @@ from django.db.models import Count, Q
from model_utils.managers import SoftDeletableManager, SoftDeletableQuerySet
from model_utils.models import SoftDeletableModel
from ordered_model.models import OrderedModel
from pdf2image import convert_from_path
BLEACH_ALLOWED_TAGS = bleach.sanitizer.ALLOWED_TAGS + ['p', 'br', 'h1', 'h2', 'h3', 'hr']
@ -59,6 +60,7 @@ class Document(SoftDeletableModel):
published = models.CharField(max_length=128, null=False, blank=True)
description = models.TextField(max_length=2048, null=False, blank=True)
file = models.FileField(null=True, blank=True, storage=FileSystemStorage(location='docs'))
image = models.ImageField(null=True, blank=True, storage=FileSystemStorage(location='docs/images'))
public = models.BooleanField(default=True, null=False, blank=False)
media_type = models.CharField(null=False, blank=False,
max_length=1, choices=DocumentType.choices, default=DocumentType.TEXT)
@ -88,6 +90,13 @@ class Document(SoftDeletableModel):
def is_local_pdf(self):
return self.file.name is not None and self.file.name.endswith(".pdf")
@property
def image_first_page(self):
if self.is_local_pdf:
images = convert_from_path(self.file.path, last_page=1)
if images:
return images[0]
class Meta:
ordering = ['-id']
permissions = [

View file

@ -13,11 +13,11 @@
<meta property="og:title" content="The /-\ Pile"/>
<meta property="og:type" content="website"/>
<meta property="og:url" content="https://pile.sdbs.cz/"/>
<meta property="og:image" content="{% static "favicon.png" %}"/>
<meta property="og:description"
content="This is where we upload the stuff we consider important to the larger conceptual and thematic landscape of what we do: confronting apathy, inter-subjectivity, the human right to self-determination, counter-culture and such..."/>
{% endblock %}
<meta property="og:site_name" content="The /-\ Pile"/>
<meta property="og:image" content="{% static "favicon.png" %}"/>
</head>
<body>

View file

@ -123,4 +123,5 @@
<meta property="og:url" content="https://pile.sdbs.cz{% url "pile:document" document.id %}"/>
<meta property="og:description" content="{{ document.plain_description }}"/>
<meta property="og:type" content="article"/>
<meta property="og:image" content="{% url "pile:image" document.id %}"/>
{% endblock %}

View file

@ -46,5 +46,6 @@
<meta property="og:url" content="https://pile.sdbs.cz{% url "pile:tag" tag.id %}"/>
<meta property="og:description" content="{{ tag.description }}"/>
<meta property="og:type" content="website"/>
<meta property="og:image" content="{% static "favicon.png" %}"/>
{% endif %}
{% endblock %}

View file

@ -10,6 +10,7 @@ urlpatterns = [
path('item/<int:document_id>', views.DocumentView.as_view(), name='document'),
path('label/<int:document_id>', views.LabelView.as_view(), name='label'),
path('retrieve/<int:document_id>', views.DocumentWithLabelView.as_view(), name='retrieve'),
path('image/<int:document_id>', views.BrandedImageView.as_view(), name='image'),
path('feed', views.RecentlyUploadedFeed()),
path('api/external_links', ExternalLinkView),
path('api/ipfs_cids', IPFSView)

View file

@ -7,7 +7,9 @@ from operator import itemgetter
from random import choice
import weasyprint
from PIL import Image
from PyPDF2 import PdfFileWriter, PdfFileReader
from django.contrib.staticfiles import finders
from django.contrib.syndication.views import Feed
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.http import Http404, FileResponse, HttpRequest, HttpResponse
@ -157,6 +159,31 @@ class DocumentWithLabelView(View):
return redirect(document.url)
class BrandedImageView(View):
def get(self, request: HttpRequest, document_id: int):
try:
document = Document.objects.get(pk=document_id)
except ObjectDoesNotExist:
raise Http404
margin = 32
pile_image = Image.open(finders.find('pile_300dpi.png')).resize((256 - margin, 256 - margin))
image = Image.open(document.image) if document.image else document.image_first_page
image.thumbnail((256, 256))
result = Image.new('RGBA', (256, 256), (0, 0, 0, 0))
result.paste(image, ((256 - image.size[0]) // 2, (256 - image.size[1]) // 2))
result.paste(pile_image, (margin//2, margin//2), pile_image)
result = result.crop(result.getbbox())
img_byte_arr = io.BytesIO()
result.save(img_byte_arr, format='PNG')
img_byte_arr = img_byte_arr.getvalue()
return HttpResponse(img_byte_arr, content_type="image/png")
class RecentlyUploadedFeed(Feed):
title = "The /-\\ pile"
link = "https://pile.sbds.cz"