From 0f0b4f8aa3c0872cdb41fbc4829e14bfe6946552 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 15:24:26 +0200 Subject: [PATCH 01/46] migrate to poetry --- .dockerignore | 3 - .github/workflows/build.yml | 34 +++ .github/workflows/main.yml | 36 --- Dockerfile | 31 -- LICENSE | 2 +- Pipfile | 32 -- Pipfile.lock | 578 ------------------------------------ poetry.lock | 74 +++++ pyproject.toml | 28 ++ 9 files changed, 137 insertions(+), 681 deletions(-) delete mode 100644 .dockerignore create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/main.yml delete mode 100644 Dockerfile delete mode 100644 Pipfile delete mode 100644 Pipfile.lock create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 563864d2..00000000 --- a/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -.git -__pycache__ -*.egg-info diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..86894ff2 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,34 @@ +name: build + +on: + push: + pull_request: + schedule: + - cron: "0 4 * * *" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Poetry + run: pipx install poetry + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 + cache: poetry + + - name: Install dependencies + run: poetry install + + - name: Test + run: poetry run pythoncz test + + - if: ${{ github.ref == 'refs/heads/main' }} + name: Deploy + run: pipenv run pythoncz deploy + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 328f09fe..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Main -on: - push: - pull_request: - schedule: - - cron: "0 4 * * *" -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Python 3.9 - uses: actions/setup-python@v2 - with: - python-version: 3.9 - - name: Install dependencies - run: | - python -m pip install --upgrade pipenv - pipenv install --dev - - name: Test - run: pipenv run test - - if: ${{ github.event_name == 'pull_request' }} - name: Build without fetching GitHub Issues - run: | - export DISABLE_GITHUB_ISSUES_FETCH=true - pipenv run build - - if: ${{ github.event_name != 'pull_request' }} - name: Build with fetching GitHub Issues - run: pipenv run build - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - if: ${{ github.ref == 'refs/heads/master' }} - name: Deploy - run: pipenv run deploy - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 6d9cd7a5..00000000 --- a/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -# This Dockerfile allows you to run python.cz website easily and without -# issues with dependencies - locally, on your server or in cloud like now.sh. -# That's handy for testing or for demonstration of new feature in a pull request. -# -# For running the website locally: -# -# docker build -t python.cz . -# docker run -p 8000:8000 python.cz -# -# ...and open in your browser: http://localhost:8000 -# -# Environment variables can be specified too> -# -# docker run -p 8000:8000 -e GITHUB_TOKEN=token123 python.cz - -FROM python:3.7-alpine - -RUN python3 -m venv /venv -RUN /venv/bin/pip install gunicorn pipenv -WORKDIR /app -COPY . ./ -RUN /venv/bin/pipenv install - -EXPOSE 8000 - -CMD [ \ - "/venv/bin/gunicorn", \ - "--bind", "0.0.0.0:8000", \ - "--workers", "4", \ - "pythoncz:app" \ -] diff --git a/LICENSE b/LICENSE index feca57bc..95958e53 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013 Honza Javorek +Copyright (c) 2013-2023 Honza Javorek and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 04accafe..00000000 --- a/Pipfile +++ /dev/null @@ -1,32 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[scripts] -test = "python -m pytest ./tests --cov=pythoncz --tb=native" -serve = "python runserver.py serve" -build = "python runserver.py freeze" -deploy = "python runserver.py deploy --no-freeze --push" - -[packages] -elsa = "*" -flask = "*" -frozen-flask = "*" -requests = "*" -czech-sort = "*" -pyyaml = "*" -python-slugify = "*" -ics = "*" -arrow = "*" -lxml = "*" -cssselect = "*" -cachelib = "*" - -[dev-packages] -pytest = "*" -pytest-cov = "*" -responses = "*" - -[requires] -python_version = "3.9" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index 35430184..00000000 --- a/Pipfile.lock +++ /dev/null @@ -1,578 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "20648e54d177f143b9e290844e848fc215f941f5d55a19bdea39cceb3fa3c8a0" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.9" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "arrow": { - "hashes": [ - "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1", - "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2" - ], - "index": "pypi", - "version": "==1.2.3" - }, - "attrs": { - "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" - ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" - }, - "cachelib": { - "hashes": [ - "sha256:38222cc7c1b79a23606de5c2607f4925779e37cdcea1c2ad21b8bae94b5425a5", - "sha256:811ceeb1209d2fe51cd2b62810bd1eccf70feba5c52641532498be5c675493b3" - ], - "index": "pypi", - "version": "==0.9.0" - }, - "certifi": { - "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.12.7" - }, - "charset-normalizer": { - "hashes": [ - "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", - "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" - ], - "markers": "python_version >= '3.6'", - "version": "==2.1.1" - }, - "click": { - "hashes": [ - "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e", - "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48" - ], - "markers": "python_version >= '3.7'", - "version": "==8.1.3" - }, - "cssselect": { - "hashes": [ - "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc", - "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e" - ], - "index": "pypi", - "version": "==1.2.0" - }, - "czech-sort": { - "hashes": [ - "sha256:340bd050ef536ffcdd938fd162e39542964f65ceb4a08320fbf54d14c22121ec" - ], - "index": "pypi", - "version": "==1.0.1" - }, - "elsa": { - "hashes": [ - "sha256:caa4f03d1060c3ef960d25ad45d4548c6b937fe47aa3ff408f21fcd68dbe9db1", - "sha256:e0cb4c504e12e9f9e00486aa48ea549ebc2b46d93a175758a62f5644f2562355" - ], - "index": "pypi", - "version": "==0.1.6" - }, - "flask": { - "hashes": [ - "sha256:642c450d19c4ad482f96729bd2a8f6d32554aa1e231f4f6b4e7e5264b16cca2b", - "sha256:b9c46cc36662a7949f34b52d8ec7bb59c0d74ba08ba6cb9ce9adc1d8676d9526" - ], - "index": "pypi", - "version": "==2.2.2" - }, - "frozen-flask": { - "hashes": [ - "sha256:4113638baebb348e16b10b12cbd88bddc7309f24d94332a18ae6a56c8ac02d3d", - "sha256:6d892fd929f6676c3270b7d91d86a1fc03c9850dc21e3b02b3946381c48ab307" - ], - "index": "pypi", - "version": "==0.18" - }, - "ghp-import": { - "hashes": [ - "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", - "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343" - ], - "version": "==2.1.0" - }, - "ics": { - "hashes": [ - "sha256:5fcf4d29ec6e7dfcb84120abd617bbba632eb77b097722b7df70e48dbcf26103", - "sha256:6743539bca10391635249b87d74fcd1094af20b82098bebf7c7521df91209f05", - "sha256:da352bdf8418619dc93611e6d251f3cefbb42664777f6e00b580a722098124b7" - ], - "index": "pypi", - "version": "==0.7.2" - }, - "idna": { - "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" - ], - "markers": "python_version >= '3.5'", - "version": "==3.4" - }, - "importlib-metadata": { - "hashes": [ - "sha256:d5059f9f1e8e41f80e9c56c2ee58811450c31984dfa625329ffd7c0dad88a73b", - "sha256:d84d17e21670ec07990e1044a99efe8d615d860fd176fc29ef5c306068fda313" - ], - "markers": "python_version < '3.10'", - "version": "==5.1.0" - }, - "itsdangerous": { - "hashes": [ - "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", - "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.2" - }, - "jinja2": { - "hashes": [ - "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", - "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.2" - }, - "lxml": { - "hashes": [ - "sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7", - "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726", - "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03", - "sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140", - "sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a", - "sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05", - "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03", - "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419", - "sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4", - "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e", - "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67", - "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50", - "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894", - "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf", - "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947", - "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1", - "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd", - "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92", - "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457", - "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74", - "sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf", - "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1", - "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4", - "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975", - "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5", - "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe", - "sha256:6943826a0374fb135bb11843594eda9ae150fba9d1d027d2464c713da7c09afe", - "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7", - "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2", - "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409", - "sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f", - "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f", - "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5", - "sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24", - "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e", - "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4", - "sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a", - "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c", - "sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f", - "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7", - "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a", - "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c", - "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9", - "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e", - "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab", - "sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941", - "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5", - "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45", - "sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7", - "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892", - "sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746", - "sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c", - "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53", - "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184", - "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38", - "sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9", - "sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b", - "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2", - "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0", - "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b", - "sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380", - "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8", - "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1", - "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889", - "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9", - "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f", - "sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c" - ], - "index": "pypi", - "version": "==4.9.2" - }, - "markupsafe": { - "hashes": [ - "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", - "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", - "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", - "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", - "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", - "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", - "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", - "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", - "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", - "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", - "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", - "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", - "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", - "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", - "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", - "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", - "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", - "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", - "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", - "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", - "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", - "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", - "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", - "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", - "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", - "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", - "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", - "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", - "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", - "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", - "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", - "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", - "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", - "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", - "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", - "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", - "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", - "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", - "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", - "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.1" - }, - "python-dateutil": { - "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.8.2" - }, - "python-slugify": { - "hashes": [ - "sha256:003aee64f9fd955d111549f96c4b58a3f40b9319383c70fad6277a4974bbf570", - "sha256:7a0f21a39fa6c1c4bf2e5984c9b9ae944483fd10b54804cb0e23a3ccd4954f0b" - ], - "index": "pypi", - "version": "==7.0.0" - }, - "pyyaml": { - "hashes": [ - "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf", - "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", - "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", - "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", - "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", - "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", - "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", - "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", - "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", - "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", - "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", - "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", - "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782", - "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", - "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", - "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", - "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", - "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", - "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1", - "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", - "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", - "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", - "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", - "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", - "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", - "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d", - "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", - "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", - "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7", - "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", - "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", - "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", - "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358", - "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", - "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", - "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", - "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", - "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f", - "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", - "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" - ], - "index": "pypi", - "version": "==6.0" - }, - "requests": { - "hashes": [ - "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", - "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" - ], - "index": "pypi", - "version": "==2.28.1" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "tatsu": { - "hashes": [ - "sha256:0a836692e67247cad9f251e083b045b13345cc715e69a7fbc16522beaa0f2163", - "sha256:571ecbcdf33b7828c05e5cd95a8e8ad06af111c2c83a6a245be4d8f7c43de7bb" - ], - "markers": "python_version >= '3.8'", - "version": "==5.8.3" - }, - "text-unidecode": { - "hashes": [ - "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", - "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93" - ], - "version": "==1.3" - }, - "urllib3": { - "hashes": [ - "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc", - "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.13" - }, - "werkzeug": { - "hashes": [ - "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f", - "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5" - ], - "markers": "python_version >= '3.7'", - "version": "==2.2.2" - }, - "zipp": { - "hashes": [ - "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa", - "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766" - ], - "markers": "python_version >= '3.7'", - "version": "==3.11.0" - } - }, - "develop": { - "attrs": { - "hashes": [ - "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", - "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" - ], - "markers": "python_version >= '3.5'", - "version": "==22.1.0" - }, - "certifi": { - "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.12.7" - }, - "charset-normalizer": { - "hashes": [ - "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845", - "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f" - ], - "markers": "python_version >= '3.6'", - "version": "==2.1.1" - }, - "coverage": { - "extras": [ - "toml" - ], - "hashes": [ - "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79", - "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a", - "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f", - "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a", - "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa", - "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398", - "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba", - "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d", - "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf", - "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b", - "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518", - "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d", - "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795", - "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2", - "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e", - "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32", - "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745", - "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b", - "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e", - "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d", - "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f", - "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660", - "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62", - "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6", - "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04", - "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c", - "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5", - "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef", - "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc", - "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae", - "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578", - "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466", - "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4", - "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91", - "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0", - "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4", - "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b", - "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe", - "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b", - "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75", - "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b", - "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c", - "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72", - "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b", - "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f", - "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e", - "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53", - "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3", - "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84", - "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987" - ], - "markers": "python_version >= '3.7'", - "version": "==6.5.0" - }, - "exceptiongroup": { - "hashes": [ - "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828", - "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec" - ], - "markers": "python_version < '3.11'", - "version": "==1.0.4" - }, - "idna": { - "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" - ], - "markers": "python_version >= '3.5'", - "version": "==3.4" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "packaging": { - "hashes": [ - "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3", - "sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3" - ], - "markers": "python_version >= '3.7'", - "version": "==22.0" - }, - "pluggy": { - "hashes": [ - "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" - ], - "markers": "python_full_version >= '3.6.0'", - "version": "==1.0.0" - }, - "pytest": { - "hashes": [ - "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71", - "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59" - ], - "index": "pypi", - "version": "==7.2.0" - }, - "pytest-cov": { - "hashes": [ - "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b", - "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470" - ], - "index": "pypi", - "version": "==4.0.0" - }, - "requests": { - "hashes": [ - "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", - "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" - ], - "index": "pypi", - "version": "==2.28.1" - }, - "responses": { - "hashes": [ - "sha256:396acb2a13d25297789a5866b4881cf4e46ffd49cc26c43ab1117f40b973102e", - "sha256:dcf294d204d14c436fddcc74caefdbc5764795a40ff4e6a7740ed8ddbf3294be" - ], - "index": "pypi", - "version": "==0.22.0" - }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - }, - "tomli": { - "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" - ], - "markers": "python_version < '3.11'", - "version": "==2.0.1" - }, - "types-toml": { - "hashes": [ - "sha256:171bdb3163d79a520560f24ba916a9fc9bff81659c5448a9fea89240923722be", - "sha256:b7b5c4977f96ab7b5ac06d8a6590d17c0bf252a96efc03b109c2711fb3e0eafd" - ], - "version": "==0.10.8.1" - }, - "urllib3": { - "hashes": [ - "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc", - "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==1.26.13" - } - } -} diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 00000000..3b3bdd1c --- /dev/null +++ b/poetry.lock @@ -0,0 +1,74 @@ +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "packaging" +version = "23.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, +] + +[[package]] +name = "pluggy" +version = "1.2.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pytest" +version = "7.4.0" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, + {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[metadata] +lock-version = "2.0" +python-versions = "3.11.*" +content-hash = "d1cc5651551f3b789040e1ef9378715e3155ae4e223f38336f85e8cf838532e8" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..5b9cd41b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,28 @@ +[tool.poetry] +name = "pythoncz" +version = "0.0.0" +description = "Czech Python user group homepage" +authors = ["Honza Javorek "] +readme = "README.md" +homepage = "https://python.cz/" +repository = "https://github.com/honzajavorek/mkdocs-python.cz/" +classifiers = ["Private :: Do Not Upload"] + +[tool.poetry.scripts] +pythoncz = "pythoncz:main" + +[tool.poetry.dependencies] +python = "3.11.*" + +[tool.poetry.group.dev.dependencies] +pytest = "7.4.0" + +[tool.pytest.ini_options] +python_files = "test_*.py" +testpaths = "tests" +norecursedirs = "node_modules" +addopts = "--ff" + +[build-system] +requires = ["poetry-core>=1.5.0"] +build-backend = "poetry.core.masonry.api" From b64011d4fce2ecfe3bfac55f5faf4e1f60267a82 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 15:47:16 +0200 Subject: [PATCH 02/46] set up mkdocs --- .gitignore | 4 - README.md | 52 +------- docs/index.md | 17 +++ mkdocs.yml | 11 ++ poetry.lock | 318 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 6 files changed, 352 insertions(+), 51 deletions(-) create mode 100644 docs/index.md create mode 100644 mkdocs.yml diff --git a/.gitignore b/.gitignore index 01d66724..e603a349 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,3 @@ pip-log.txt /cache/ .cache .pytest_cache/ - -# Elsa -_build/ -/talks-archive/ diff --git a/README.md b/README.md index 7673a081..bbd9e09d 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,14 @@ -

⚠️

-

Tento projekt nemá aktuálně nikoho, kdo by se o něj staral

-

Lákalo by tě python.cz udržovat, rozvíjet, nebo to celé předělat? Ozvi se na Slacku!

-
- # python.cz Czech Python community homepage. -## Installation - -The code is **Python 3.7**. - -1. [Install Pipenv](https://pipenv.readthedocs.io/en/latest/install/#installing-pipenv) -1. Clone the project: - - ```sh - $ git clone git@github.com:pyvec/python.cz.git --depth=10 - ``` - - It is recommended to start with a [shallow clone](https://git-scm.com/docs/git-clone#git-clone---depthltdepthgt) as historically, this repo has contained a lot of rather large photos. -1. Go inside the project directory and run Pipenv to install dependencies: - - ``` - $ cd ./python.cz - $ pipenv install --dev - ``` - -### Development - -The site uses GitHub API. For certain pages to work correctly, you need to set the `GITHUB_TOKEN` environment variable to a [GitHub Personal Access Token](https://github.com/settings/tokens) (no scopes needed). - -```sh -$ export GITHUB_TOKEN=... -$ pipenv run serve -``` - -### Deployment - -The site gets automatically deployed after any push to the `master` branch. It is frozen by [Elsa](https://github.com/pyvec/elsa). A GitHub action redeploys it daily, so any content of dynamic nature isn't outdated. - -- **Domain:** bestowed by [KRAXNET](http://www.kraxnet.cz/)
- Access: e-mail request to [KRAXNET](http://www.kraxnet.cz/) -- **Public Analytics:** [Simple Analytics](https://simpleanalytics.com/python.cz)
- Access: [@honzajavorek](http://github.com/honzajavorek) - -## Authors & Contributions - -**This site is community effort and contributions are very welcome!** See the [Hall of fame](https://github.com/pyvec/python.cz/graphs/contributors) for the most active contributors. +## TODO -The site is backed by [Pyvec](http://pyvec.org/), nonprofit organization dedicated to support of Python in the Czech Republic. [Honza Javorek](http://github.com/honzajavorek) is the original author, the [@pyvec/python-cz](https://github.com/orgs/pyvec/teams/python-cz) are python.cz maintainers. +- port static content +- events as a plugin +- localize the theme - https://www.mkdocs.org/user-guide/localizing-your-theme/ +- customize the theme - https://www.mkdocs.org/user-guide/customizing-your-theme/#using-the-theme_dir +- legacy redirects ## License diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..000ea345 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,17 @@ +# Welcome to MkDocs + +For full documentation visit [mkdocs.org](https://www.mkdocs.org). + +## Commands + +* `mkdocs new [dir-name]` - Create a new project. +* `mkdocs serve` - Start the live-reloading docs server. +* `mkdocs build` - Build the documentation site. +* `mkdocs -h` - Print help message and exit. + +## Project layout + + mkdocs.yml # The configuration file. + docs/ + index.md # The documentation homepage. + ... # Other markdown pages, images and other files. diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..b0530e28 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,11 @@ +site_name: Python v ČR +site_url: https://python.cz/ +nav: + - Ahoj!: index.md + - Akce: akce.md + - Pro začátečníky: zacatecnici.md + - Práce: prace.md + - Zapoj se!: prace.md +theme: + name: mkdocs + locale: cs diff --git a/poetry.lock b/poetry.lock index 3b3bdd1c..a3c24373 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,19 @@ # This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -11,6 +25,23 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -22,6 +53,138 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "markdown" +version = "3.4.4" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Markdown-3.4.4-py3-none-any.whl", hash = "sha256:a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941"}, + {file = "Markdown-3.4.4.tar.gz", hash = "sha256:225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6"}, +] + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.0)", "mkdocs-nature (>=0.4)"] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "mkdocs" +version = "1.5.2" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs-1.5.2-py3-none-any.whl", hash = "sha256:60a62538519c2e96fe8426654a67ee177350451616118a41596ae7c876bb7eac"}, + {file = "mkdocs-1.5.2.tar.gz", hash = "sha256:70d0da09c26cff288852471be03c23f0f521fc15cf16ac89c7a3bfb9ae8d24f9"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +jinja2 = ">=2.11.1" +markdown = ">=3.2.1" +markupsafe = ">=2.0.1" +mergedeep = ">=1.3.4" +packaging = ">=20.5" +pathspec = ">=0.11.1" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] + [[package]] name = "packaging" version = "23.1" @@ -33,6 +196,32 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] +[[package]] +name = "pathspec" +version = "0.11.2" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, +] + +[[package]] +name = "platformdirs" +version = "3.10.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.7" +files = [ + {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, + {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, +] + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] + [[package]] name = "pluggy" version = "1.2.0" @@ -68,7 +257,134 @@ pluggy = ">=0.12,<2.0" [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "watchdog" +version = "3.0.0" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.7" +files = [ + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, + {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, + {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, + {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, + {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, + {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, + {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, + {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, + {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, + {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, + {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, + {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, + {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, + {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "d1cc5651551f3b789040e1ef9378715e3155ae4e223f38336f85e8cf838532e8" +content-hash = "e7635e9a18b6404266b698cb6a2e2af945591df8250cfbf64585ab271fc3db88" diff --git a/pyproject.toml b/pyproject.toml index 5b9cd41b..9ac8d4b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ pythoncz = "pythoncz:main" [tool.poetry.dependencies] python = "3.11.*" +mkdocs = "1.5.2" [tool.poetry.group.dev.dependencies] pytest = "7.4.0" From eba10557f911113861d67b7fcf8ba2a95da3ca1c Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 16:46:44 +0200 Subject: [PATCH 03/46] port most of the textual content to Markdown --- README.md | 2 + docs/akce.md | 20 + docs/index.md | 36 +- docs/prace.md | 84 ++++ docs/zacatecnici.md | 127 ++++++ docs/zapojse.md | 87 ++++ mkdocs.yml | 11 +- text.html | 945 ++++++++++++++++++++++++++++++++++++++++++++ text.md | 349 ++++++++++++++++ 9 files changed, 1648 insertions(+), 13 deletions(-) create mode 100644 docs/akce.md create mode 100644 docs/prace.md create mode 100644 docs/zacatecnici.md create mode 100644 docs/zapojse.md create mode 100644 text.html create mode 100644 text.md diff --git a/README.md b/README.md index bbd9e09d..38543e0a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ Czech Python community homepage. - localize the theme - https://www.mkdocs.org/user-guide/localizing-your-theme/ - customize the theme - https://www.mkdocs.org/user-guide/customizing-your-theme/#using-the-theme_dir - legacy redirects +- english version +- fix absolute links and make them relative ## License diff --git a/docs/akce.md b/docs/akce.md new file mode 100644 index 00000000..7502bce1 --- /dev/null +++ b/docs/akce.md @@ -0,0 +1,20 @@ +# Akce + +Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na jednom místě. + +[Chci uspořádat sraz v mém městě](https://docs.pyvec.org/guides/meetup.html) + +## Všechny akce {: #akce :} + +- **Pravidelné akce** lze přidat přes tzv. + [iCal](https://cs.wikipedia.org/wiki/ICalendar) export. Ten může + generovat přímo vaše webová stránka (jako v případě + [pyvo.cz](https://pyvo.cz)), nebo jej lze vytáhnout z nějaké služby + (Google Calendar, meetup.com). URL exportu pak na náš web [přidejte pomocí Pull Requestu](https://github.com/pyvec/python.cz/edit/master/pythoncz/static/data/events_feeds.yml). +- **Jednorázové akce** lze přidat přes kalendář [Czech Python Events](https://calendar.google.com/calendar/embed?src=kfdeelic1a13jsp7jvai861vfs%40group.calendar.google.com&ctz=Europe%2FPrague). + Do kalendáře má přístup mnoho z organizátorů existujících Python + akcí, takže je poproste, ať vaši akci přidají, nebo napište na + . První URL z popisu události se zde zobrazí jako + odkaz. + +[iCal na všechny akce](/events.ics) diff --git a/docs/index.md b/docs/index.md index 000ea345..70067cde 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,17 +1,29 @@ -# Welcome to MkDocs +# Python v ČR -For full documentation visit [mkdocs.org](https://www.mkdocs.org). +Python je moderní programovací jazyk. Je univerzální – pohání weby i rakety. +Dobře se čte a dá se velice rychle naučit. Je skvělý pro výuku programování. +Česká komunita je aktivní. Najdeš v ní pomoc, kamarády i práci. -## Commands +## Kde nás najdeš -* `mkdocs new [dir-name]` - Create a new project. -* `mkdocs serve` - Start the live-reloading docs server. -* `mkdocs build` - Build the documentation site. -* `mkdocs -h` - Print help message and exit. +- [Skupina Pyonýři](https://www.facebook.com/groups/pyonieri/) +- [Discord](https://discord.gg/yUbgArVAyF) +- [E-mailová skupina](https://groups.google.com/group/django-cs/) +- [E-mailová skupina na py.cz](http://www.py.cz/mailman/listinfo/python) +- [Srazy Pyvo](https://twitter.com/naPyvo) +- [PyCon CZ](https://twitter.com/PyConCZ) +- [PyLadies CZ](https://twitter.com/PyLadiesCZ) +- [PyData Praha](https://twitter.com/PyDataPrague) +- [IRC #python-cs](irc://irc.freenode.net/python-cs) +- [IRC #django-cs](irc://irc.freenode.net/django-cs) +- [Slack pro organizátory](http://pyvec.slack.com/) -## Project layout +## Nejbližší akce - mkdocs.yml # The configuration file. - docs/ - index.md # The documentation homepage. - ... # Other markdown pages, images and other files. +TODO + +## Odkazy + +- [Blog](http://blog.python.cz/) - Díky blogu se **dovíš o všem, co se v české Python komunitě zrovna děje**. A co je nejlepší – můžeš klidně přidat svůj vlastní článek! +- [PyCon CZ](http://cz.pycon.org/) - Česká Python konference! Pomoz nám s přípravami, propagací, zkus si přihlásit přednášku nebo workshop, sponzoruj nás, nebo prostě jen přijď a akci si užij! +- [Knihovna](https://books.pyvo.cz/) - Máme knihovničku s literaturou o Pythonu a podobných technologiích. Knihy si lze **zdarma půjčit** – ozvi se a přijď si knížku vyzvednout na nejbližším [srazu](akce.md). Mimochodem, [Python Books](http://pythonbooks.revolunet.com/) znáš, že? diff --git a/docs/prace.md b/docs/prace.md new file mode 100644 index 00000000..de7971c5 --- /dev/null +++ b/docs/prace.md @@ -0,0 +1,84 @@ +# Python a práce + +Používá vůbec někdo Python? **Ano!** Jde o jazyk vhodný k výuce nebo +skriptování, ale to neznamená, že jej nepoužívají firmy z celého světa a +nepíšou se v něm rozsáhlé projekty. + +Ve světě Python používají např. **Blender 3D, Google (YouTube!), +Dropbox, Disqus, IBM, Instagram, Lucasfilm, Mozilla, NASA, Spotify, Walt +Disney, [a mnoho dalších](https://www.python.org/about/success/)** – +mimo jiné také spousta vědeckých organizací **včetně švýcarského +CERNu**. + +## Python u nás + +TODO + +## Jak najít práci? {:#poptavka} + +- Přijď na [sraz](/#akce) a poptej se tam. +- Sleduj všechny [diskusní kanály](/#komunikace), kde se nabídky + objevují. +- Na zmíněné kanály aktivně napiš, že hledáš práci nebo stáž. +- Zkus přímo oslovit [firmy výše](#kdo). +- Sleduj Twitter účet [@pyjobo](https://twitter.com/pyjobo) a + pročítej [globální nástěnku nabídek](https://www.python.org/jobs/) + – inzeráty lze hledat [podle + lokace](https://www.python.org/jobs/locations/) nebo třeba i podle + toho, [zda lze pracovat na + dálku](https://www.python.org/jobs/location/telecommute/). Sleduj + Python na pracovních serverech: + [Jobs.cz](http://www.jobs.cz/prace/?q%5B%5D=python), + [StartupJobs.cz](https://www.startupjobs.cz/nabidky/15/python-programmer), + ... (Víš o dalších? [Přidej + odkaz!](https://github.com/pyvec/python.cz/edit/master/pythoncz/static/data/jobs.yml)) +- Odzkoušej si své znalosti v testech: + [StartupJobs.cz](https://www.startupjobs.cz/test/python), + [Toptal.com](http://www.toptal.com/python/interview-questions), + ... (Víš o dalších? [Přidej + odkaz!](https://github.com/pyvec/python.cz/edit/master/pythoncz/static/data/jobs.yml)) + +## Jak najít Python programátory? {:#nabidka} + +- Přijď na [sraz](/#akce) a poptej se tam. Promluv si s reálnými + lidmi, nadchni je, zlákej je, zjisti jaké mají možnosti a požadavky. +- Popros svou společnost, aby sponzorovala příští [PyCon + CZ](http://cz.pycon.org/) nebo [PyCon SK](http://pycon.sk/). Obě + konference jsou jedinečnou příležitostí promluvit si s 400+ vývojáři + z celé střední Evropy. +- Sepiš si inzerát a konkretizuj jej, aspoň do tvaru něčeho jako + *\"hledám nadšence/nájemného profíka na krátkodobý projekt ve stylu + CMS s galerií, nejspíš v Djangu, platím penězi\"*. Čím víc bude + **lidsky od srdíčka** a čím méně to budou odrážky ve stylu + poptáváme/nabízíme, tím více lidí to zaujme. **Nezapomeň napsat do + jaké míry je možná práce na dálku.** +- Napiš inzerát na diskuse django-cs a py.cz ([viz hlavní + stránka](/#komunikace)) a na [Facebookovou + skupinu](https://www.facebook.com/groups/pyonieri/). Čte je mnoho + českých a slovenských Pythonistů. +- Nepřehlcuj žádnou z diskusí. Inzeráty jsou vítány, jsou zadarmo a + bez omezení, ale pokud se to zvrhne, nemusí to tak zůstat. +- Pošli inzerát na [globální nástěnku + nabídek](https://www.python.org/community/jobs/howto/) – ta + uveřejňuje nabídky zdarma, jen je potřeba se registrovat. Nabídka se + pak objeví i na Twitter účtu [\@pyjobo](https://twitter.com/pyjobo). + Inzeruj nabídku na pracovních serverech: + [Jobs.cz](http://www.jobs.cz/prace/?q%5B%5D=python), + [StartupJobs.cz](https://www.startupjobs.cz/nabidky/15/python-programmer), + ... + +## Chci, aby bylo víc Pythonistů! {:#vic} + +**My taky!** Máme na to dokonce [neziskovku Pyvec](http://pyvec.org/). +Můžeš se [zapojit](/zapojse/) a s naší misí nám pomoci. + +Pokud zastupuješ nějakou firmu, můžeš nás **sponzorovat ([číslo +účtu](https://www.fio.cz/scgi-bin/hermes/dz-transparent.cgi?ID_ucet=2600260438))**. +Přes Pyvec se peníze rozdělí na dílčí projekty. Podporujeme např. srazy +a workshopy pro dámy – [PyLadies](http://pyladies.cz), +[DjangoGirls](http://djangogirls.org). + +Budeme také rádi, pokud nám **napíšete *success story* o tom, jak jste +Python použili u vás** a jak vám to usnadnilo práci a co vše jste s ním +dokázali. Takovou zkušenost zde rádi uveřejníme, klidně i na samostatné +stránce, s logem apod. diff --git a/docs/zacatecnici.md b/docs/zacatecnici.md new file mode 100644 index 00000000..93261ee9 --- /dev/null +++ b/docs/zacatecnici.md @@ -0,0 +1,127 @@ +# Učíme se Python + +- Česká **komunita je přátelská a živá**. Vždy bude po ruce **někdo, + kdo ti pomůže**. +- **Nebudeš mít problém [sehnat práci](/prace/).** Pythonistů je + nedostatek! +- I kdyby weby vyšly z módy, Python nachází **uplatnění v desítkách + dalších oborů**. + +## Online materiály – neumím vůbec programovat {: #onlineneumim } + +Následující materiály vznikly v rámci aktivit, které se snaží přiblížit +**IT ženám a ženy k IT**. Jsou skvěle zpracované a může se z nich naučit +programovat od úplných základů kdokoliv. + +- [Materiály od PyLadies](http://naucse.python.cz/course/pyladies/) +- [Návod od Django Girls](http://tutorial.djangogirls.org/) + +## Online materiály – programovat trochu umím {#onlineumim} + +### Přecházím z jiného jazyka + +- [Naučte se Python za X minut](http://learnxinyminutes.com/docs/cs-cz/python3/) +- [Jak přejít z PHP](http://www.zdrojak.cz/clanky/jak-napisu-webovou-aplikaci-v-pythonu/) + ([2. díl](http://www.zdrojak.cz/clanky/jak-napisu-webovou-aplikaci-v-pythonu-2/)) +- [Úvod do Pythonu pro programátory](https://speakerdeck.com/u/pydanny/p/intro-to-python) +- [Tahák na podobné konstrukce v PHP, Perlu, Pythonu a Ruby](http://hyperpolyglot.org/scripting) +- [Pragmatické tipy na to jak začít a co použít](http://blog.jmoz.co.uk/learning-python-the-pragmatic-way/) +- [Průvodce Python ekosystémem](http://docs.python-guide.org/) +- [Oficiální návod k Pythonu](https://docs.python.org/3/tutorial/) +- [Rychlokurz Pythonu pro programátory](http://stephensugden.com/crash_into_python/) + +### Návody pro začátečníky + +- [Kniha Ponořme se do Pythonu 3](http://diveintopython3.py.cz/index.html) + ([PDF](http://knihy.nic.cz/files/nic/edice/mark_pilgrim_dip3_ver3.pdf)) +- [Učíme se programovat v jazyce Python 3](http://howto.py.cz/) +- [Základy Pythonu 3, interaktivní materiály](https://github.com/tomasbedrich/skoleni-python) +- [Seznam nejlepších materiálů](http://net.tutsplus.com/tutorials/the-best-way-to-learn-python/) +- [Sada krátkých videí jako úvod do Pythonu](https://www.cbtnuggets.com/it-training/python-programming) +- [Sada screencastů k vylepšení dovedností s Pythonem](http://www.neckbeardrepublic.com/screencasts/) +- [Screencasty pro webový framework Django](https://godjango.com/) +- [Dokumentace k webovému frameworku Django](https://docs.djangoproject.com/) +- [Základní algoritmy - v Pythonu a interaktivně](http://interactivepython.org/runestone/static/pythonds/index.html) +- [Vysvětlení nejčastějších chyb začátečníků](https://inventwithpython.com/blog/2012/07/09/16-common-python-runtime-errors-beginners-find/) +- [Různé úvodní lekce od Microsoft Virtual Academy](https://mva.microsoft.com/search/SearchResults.aspx?q=python&index=2&lang=1029$1033) +- [Odkazy na vysvětlení zajímavých či pokročilých detailů jazyka](https://web.archive.org/web/20170912115918/http://jessenoller.com/good-to-great-python-reads/) +- [Syntaxi už umím, co dál?](http://newcoder.io/) +- [Learn Python The Hard Way](http://learnpythonthehardway.org/) + +### Chci si to hned zkusit + +- [Python na Umíme programovat](https://www.umimeprogramovat.cz/programovani-v-pythonu) +- [Python konzole v prohlížeči](http://repl.it/) +- [Programovací hra](http://www.checkio.org) +- [Python na Codecademy, interaktivní online kurz](https://www.codecademy.com/pro/intensive/programming-with-python) +- [Python na Code School, interaktivní online kurz](https://www.codeschool.com/learn/python) +- [Programming for Everybody, interaktivní online kurz](https://www.coursera.org/course/pythonlearn) +- [Interaktivní vysvětlení toho, co se děje v kódu](http://www.pythontutor.com/) +- [Codewars](https://www.codewars.com/?language=python) + +### Knihy + +Díky [naší knihovničce](https://books.pyvo.cz/) si můžeš zadarmo půjčit +knihy o Pythonu. Na stránkách [Python Books](http://pythonbooks.revolunet.com/) navíc najdeš seznam knih, +které si můžeš zdarma číst online nebo si je rovnou stáhnout. Určitě to +omrkni! + +### Přednášky + +Nahráváme přednášky ze [srazů](/#akce) a [dáváme je na YouTube](https://www.youtube.com/user/pyvec/playlists). Na stránkách +[pyvideo.org](http://pyvideo.org/) najdeš přednášky z celého světa. + +### Konvence pro psaní kódu + +- [Style Guide for Python Code](https://pep8.org/) +- [Python Docstring Conventions](http://www.python.org/dev/peps/pep-0257/) +- [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) + +### Kam nahrát web napsaný v Pythonu? + +- [Roští.cz](https://rosti.cz/python-hosting/) +- [Heroku](https://www.heroku.com/) +- [Google App Engine](https://developers.google.com/appengine/) +- [PythonAnywhere](https://www.pythonanywhere.com/) +- [AlwaysData](https://www.alwaysdata.com/) + +## Kurzy + +### Pro dámy + +- [Pravidelné srazy PyLadies](http://pyladies.cz) +- [Jednorázové workshopy Django Girls](http://djangogirls.org) +- [Workshopy Czechitas (v Pythonu jen některé)](http://www.czechitas.cz) +- [Workshopy Geek Girls Carrots v Ostravě (v Pythonu jen některé)](http://geekgirlscarrots.org) + +### Pro studenty + +- [Kurz ČVUT FEL A4B99RPH](https://cw.fel.cvut.cz/wiki/courses/a4b99rph/prednasky/start) +- [Kurzy MU Brno](http://is.muni.cz/vyhledavani/?search=jazyk+python+agenda%3Apr) +- [Kurz ZČU v Plzni KKY/ITE](https://portal.zcu.cz/StagPortletsJSR168/CleanUrl?urlid=prohlizeni-predmet-sylabus&predmetZkrPrac=KKY&predmetZkrPred=ITE) +- [Kurz ZČU v Plzni KKY/APK](https://portal.zcu.cz/StagPortletsJSR168/CleanUrl?urlid=prohlizeni-predmet-sylabus&predmetZkrPrac=KKY&predmetZkrPred=APK) +- [Kurz FIT ČVUT v Praze (BI-PYT)](http://bk.fit.cvut.cz/cz/predmety/00/00/00/00/00/00/01/29/14/p1291406.html) + +### Pro mládež + +- [Kroužek na Praze 10](http://kapsa.cz/cs/krouzky-pro-deti#python) +- [Kroužek v Lázně Toušeň](https://www.programovanihrou.cz/) +- [Czechitas - kroužky a tábory pro různé věkové kategorie](http://www.czechitas.cz) +- [Kroužky, workshopy a tábory makeITtoday](https://makeittoday.cz/courses_cz.html) +- [Kurzy v Praze pro děti 8-12 let](https://www.digikids.cz) +- [Kurzy v Praze a online od 11-19 let](https://vzdelanibudoucnosti.cz) + +### Ostatní + +- [Nepravidelné intenzivní Python kurzy kiwi.com](https://pythonweekend.cz/) +- [Celodenní workshopy a setkání pro Python začátečníky](https://pyworking.cz/) +- [Sedlákovi - různé kurzy související s Pythonem](https://www.sedlakovi.org/kurzy/) +- [Engeto - Python akademie v Praze a Brně](https://engeto.cz/python-akademie/) + +[Přidat kurz](https://github.com/pyvec/python.cz/edit/master/pythoncz/static/data/beginners.yml) + +## Koučování {: #koucovani } + +Aneb osobní konzultace, mentoring, doučování... + +- Učíme Python: [Facebook skupina](https://www.facebook.com/groups/800923800012580/), [Google Groups](https://groups.google.com/forum/#!forum/ucime-python) diff --git a/docs/zapojse.md b/docs/zapojse.md new file mode 100644 index 00000000..e84bc5f3 --- /dev/null +++ b/docs/zapojse.md @@ -0,0 +1,87 @@ +# Zapoj se! + +Líbí se ti Python? **Pomoz nám ho rozšířit i mezi ostatní.** Můžeš nám poslat peníze, učit, přednášet, psát, organizovat, programovat, ale třeba i jen vymýšlet, co a jak by se dalo zlepšit. Máme práci pro každého! + +Python komunita je fajn jen díky tomu, že jsou v ní **lidi, kteří se nebojí přiložit ruku k dílu**. Všichni to děláme po večerech ve volném čase, z čirého nadšení. **Děláme to proto, že chceme, aby to bylo lepší i pro tebe.** Ať jsi profík nebo začátečník, z Prahy nebo z Karviné, můžeš nám pomoci. Odměnou ti budou kontakty, reference, zkušenosti. + +## Přispěj + +Budeme rádi, když přispěješ na provoz neziskovky [Pyvec](http://pyvec.org/), jejíž misí je podporovat a propagovat Python komunitu v ČR. + +Srazy nebo workshopy dělají konkrétní lidé a Pyvec jim do toho nemluví - nabízí ale pomocnou ruku co se týče financí a zázemí. + +## Vyučuj + +- Přidej se na skupiny **Učíme Python**: + [Facebook](https://www.facebook.com/groups/800923800012580/), + [Google + Groups](https://groups.google.com/forum/#!forum/ucime-python). +- Koučuj pro [PyLadies](http://pyladies.cz/). +- [Rozjeď kurz pro začátečníky podle našeho + návodu](https://docs.pyvec.org/guides/beginners-course.html). Použij + a vylepšuj naše Open Source [materiály](/zacatecnici/#onlineneumim). +- Přečti si [tipy na koučování od Django + Girls](https://coach.djangogirls.org/). + +## Přednášej + +- Přihlaš se s přednáškou na nejbližší [sraz](https://pyvo.cz). +- Pokud se necítíš na 15-20 minut, připrav si tzv. lightning talk. Je + to pětiminutovka o čemkoliv a můžeš s ní přijít na + [srazy](https://pyvo.cz) přijít i bez ohlášení. +- Koukni se, jestli zrovna nehledají řečníky + [PyCon CZ](https://cz.pycon.org/) nebo + [PyCon SK](https://www.pycon.sk/). Na mnohé konference se může + přihlásit s přednáškou kdokoliv, stačí vyplnit formulář – tzv. CfP + (Call for Proposals). + +## Piš + +- Poděl se o zážitky z akcí nebo o svůj životní příběh na [komunitní + blog](http://blog.python.cz). +- Technické články piš např. na [Zdroják.cz](http://zdrojak.cz/). + Redakce bude nadšená a ty budeš mít větší publikum. +- Python učíme podle Open Source + [materiálů](/zacatecnici/#onlineneumim). Můžeš nám pomoci je + vylepšovat. +- Když se nám povede něco zorganizovat, snažíme se sepsat naše + know-how do [komunitní dokumentace](https://docs.pyvec.org/). Chybí + tam ještě spousta věcí! + +## Organizuj + +- Pokud ve tvém městě není [Python sraz](https://pyvo.cz) nebo třeba + [PyLadies](http://pyladies.cz/) skupina, tak gratulujeme: Můžeš je + založit! Jestliže už se kolem tebe něco koná, nejlepší bude, když se + spojíš s organizátory a zeptáš se, jak jim můžeš pomoci. +- Každoročně sháníme dobrovolníky na konferenci [PyCon + CZ](https://pycon.cz). Potřebné činnosti mají většinou pramálo + společného s Pythonem a programováním. +- Když se nám povede něco zorganizovat, snažíme se sepsat naše + know-how do [komunitní dokumentace](https://docs.pyvec.org/). +- Všechny důležité věci řešíme na [Slacku](http://pyvec.slack.com/). + Napiš nám na , my tě přidáme, pak můžeš pokukovat co + se v jaké místnosti řeší a brzy uvidíš, kde je tvoje pomoc nejvíc + potřeba. +- Máme neziskovku [Pyvec](http://pyvec.org/). Její misí je podporovat + a propagovat Python komunitu v ČR. Srazy nebo workshopy dělají lidé + jako ty a Pyvec jim do toho nemluví - nabízí ale pomocnou ruku co se + týče financí a zázemí. + +## Další nápady + +Pro organizaci jednorázových úkolů používáme +[GitHub](https://github.com/pyvec/zapojse/). Když nic, tak aspoň +[hlasuj](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) +nebo [přidej vlastní +nápad](https://github.com/pyvec/zapojse/issues/new). Díky hlasům budeme +mít přinejmenším přehled o tom, co si přeje nejvíc lidí. + +Značka _Kouč pomůže!_ znamená, že někdo navrhl, +že ti s úkolem pomůže, pokud se do něj pustíš. Jestli se ty chceš někde +navrhnout jako kouč, napiš to do komentáře pod daný úkol a [přiřaď mu +štítek](https://help.github.com/articles/applying-labels-to-issues-and-pull-requests/) + +TODO + +![Přidat nápad](https://github.com/pyvec/zapojse/issues/new) diff --git a/mkdocs.yml b/mkdocs.yml index b0530e28..6ccb20fa 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,11 +1,20 @@ site_name: Python v ČR site_url: https://python.cz/ + nav: - Ahoj!: index.md - Akce: akce.md - Pro začátečníky: zacatecnici.md - Práce: prace.md - - Zapoj se!: prace.md + - Zapoj se!: zapojse.md + theme: name: mkdocs locale: cs + +markdown_extensions: + - toc: + toc_depth: '2-2' + permalink: '#' + permalink_title: Odkaz na tuto sekci + - attr_list diff --git a/text.html b/text.html new file mode 100644 index 00000000..b537dc16 --- /dev/null +++ b/text.html @@ -0,0 +1,945 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Python v ČR: Akce + + + + + + + + + +
+ + + + + + +
+ +

Akce

+
+

+ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na jednom místě. +

+
+
+ +
+
+ +

Srazy

+

+ Srazy Python programátorů zvané + Pyvo se pořádají po celé republice. Přijď si + poslechnout přednášky od chytrých lidí a + popovídat si nejen o Pythonu! +

+ +
+ + + + + + + + + +
+ +

+ + Chci uspořádat sraz v mém městě + +

+ +
+ +
+ +
+ +

Všechny akce

+
    +
  • + Pravidelné akce lze přidat přes tzv. + iCal export. + Ten může generovat přímo vaše webová stránka (jako v případě + pyvo.cz), nebo jej lze vytáhnout + z nějaké služby (Google Calendar, meetup.com). URL exportu pak + na náš web přidejte pomocí + Pull Requestu. +
  • +
  • + Jednorázové akce lze přidat přes kalendář + Czech + Python Events. Do kalendáře má přístup mnoho z organizátorů + existujících Python akcí, takže je poproste, ať vaši akci přidají, + nebo napište na info@pyvec.org. První URL z popisu události se zde zobrazí jako + odkaz. +
  • +
+ + +

Srpen

+ + +

Září

+
    + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Plzeňské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
+ +

Říjen

+
    + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
+ +

Listopad

+
    + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Plzeňské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
+ +

Prosinec

+
    + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
+ +

Leden

+
    + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Plzeňské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
  • +
    +
    + +
    +
    +

    + + + + Pyvo + + + — iCal + + + + (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) + +

    + +
    +
    +
  • + +
+ + +

+ + iCal na všechny akce + +

+ +
+ +
+ + + + + + + + + + +
+ + diff --git a/text.md b/text.md new file mode 100644 index 00000000..d7699346 --- /dev/null +++ b/text.md @@ -0,0 +1,349 @@ +::: container +::: {.header .clearfix} +- [ English, please!](/en/) + +[![](/static/images/logo-plain.png){height="30"} Python v ČR](/) +::: + +1. [Domů](/) +2. Akce + +::: content +# Akce + +::: row +Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, +na jednom místě. +::: + +::: {.row .cartoon-container .cartoon-hr} +![](/static/images/ukulele.svg){.cartoon} +::: + +::: row +::: {.col-md-8 .col-md-offset-2} +## Srazy + +[Srazy Python programátorů](https://pyvo.cz) zvané **Pyvo** se pořádají +po celé republice. Přijď si poslechnout **přednášky** od chytrých lidí a +**popovídat si** nejen o Pythonu! + +::: {.row .meetups} +::: {.meetups-city .col-sm-4 .col-xs-6} +[Pražské Pyvo](https://pyvo.cz/praha-pyvo/) +::: + +::: {.meetups-city .col-sm-4 .col-xs-6} +[Brněnské Pyvo](https://pyvo.cz/brno-pyvo/) +::: + +::: {.meetups-city .col-sm-4 .col-xs-6} +[Ostravské Pyvo](https://pyvo.cz/ostrava-pyvo/) +::: + +::: {.meetups-city .col-sm-4 .col-xs-6} +[Plzeňské Pyvo](https://pyvo.cz/plzen-pyvo/) +::: +::: + +[ Chci uspořádat sraz v mém +městě](https://docs.pyvec.org/guides/meetup.html){.btn .btn-primary +.btn-lg} +::: +::: + +------------------------------------------------------------------------ + +::: row +::: {.col-md-8 .col-md-offset-2} +## Všechny akce {#akce} + +- **Pravidelné akce** lze přidat přes tzv. + [iCal](https://cs.wikipedia.org/wiki/ICalendar) export. Ten může + generovat přímo vaše webová stránka (jako v případě + [pyvo.cz](https://pyvo.cz)), nebo jej lze vytáhnout z nějaké služby + (Google Calendar, meetup.com). URL exportu pak na náš web [přidejte + pomocí Pull + Requestu](https://github.com/pyvec/python.cz/edit/master/pythoncz/static/data/events_feeds.yml). +- **Jednorázové akce** lze přidat přes kalendář [Czech Python + Events](https://calendar.google.com/calendar/embed?src=kfdeelic1a13jsp7jvai861vfs%40group.calendar.google.com&ctz=Europe%2FPrague). + Do kalendáře má přístup mnoho z organizátorů existujících Python + akcí, takže je poproste, ať vaši akci přidají, nebo napište na + . První URL z popisu události se zde zobrazí jako + odkaz. + +### Srpen {#month-2023-8 .events-month} + +- ::: media + ::: media-left + [30]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [31]{.event-day} [čtvrtek]{.small} [18:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [Brněnské Pyvo -- Grilovací + II](https://pyvo.cz/brno-pyvo/2023-08/){.event-title} + Lužánky, Veřejný gril při zastávce Pionýrská, Brno + + [Mapy.cz](https://mapy.cz/zakladni?q=Lu%C5%BE%C3%A1nky%2C+Ve%C5%99ejn%C3%BD+gril+p%C5%99i+zast%C3%A1vce+Pion%C3%BDrsk%C3%A1%2C+Brno) + [Google + Maps](https://www.google.com/maps?q=Lu%C5%BE%C3%A1nky%2C+Ve%C5%99ejn%C3%BD+gril+p%C5%99i+zast%C3%A1vce+Pion%C3%BDrsk%C3%A1%2C+Brno) + ::: + ::: + +### Září {#month-2023-9 .events-month} + +- ::: media + ::: media-left + [13]{.event-day} [st]{.small} [18:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Plzeňské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [20]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [27]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [28]{.event-day} [čt]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +### Říjen {#month-2023-10 .events-month} + +- ::: media + ::: media-left + [18]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [25]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [26]{.event-day} [čt]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +### Listopad {#month-2023-11 .events-month} + +- ::: media + ::: media-left + [08]{.event-day} [st]{.small} [18:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Plzeňské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [15]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [29]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [30]{.event-day} [čt]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +### Prosinec {#month-2023-12 .events-month} + +- ::: media + ::: media-left + [20]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [27]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [28]{.event-day} [čt]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +### Leden {#month-2024-1 .events-month} + +- ::: media + ::: media-left + [10]{.event-day} [st]{.small} [18:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Plzeňské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [17]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [25]{.event-day} [čt]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +- ::: media + ::: media-left + [31]{.event-day} [st]{.small} [19:00]{.small} + ::: + + ::: media-body + [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) + ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín + srazu)]{.event-title} + ::: + ::: + +[ iCal na všechny akce](/events.ics){.btn .btn-primary .btn-lg} +::: +::: +::: + +::: {.row .footer} +Stránky spravuje nezisková organizace [Pyvec](http://pyvec.org). Pište +na , tweetujte na [\@pyvec](https://twitter.com/pyvec).\ +Ilustrace kreslí [Honza Javorek](http://honzajavorek.cz). Doménu +python.cz zapůjčil [KRAXNET](http://xnet.cz/). Děkujeme! + +[ Upravit tuto +stránku](https://github.com/pyvec/python.cz/edit/master/pythoncz/templates/events_cs.html){.btn +.btn-default} +::: + +![](https://queue.simpleanalyticscdn.com/noscript.gif){referrerpolicy="no-referrer-when-downgrade"} +::: From 53198ddfb5d776f4b3db85bcdb17346acab3142a Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 17:14:33 +0200 Subject: [PATCH 04/46] oops --- text.html | 945 ------------------------------------------------------ text.md | 349 -------------------- 2 files changed, 1294 deletions(-) delete mode 100644 text.html delete mode 100644 text.md diff --git a/text.html b/text.html deleted file mode 100644 index b537dc16..00000000 --- a/text.html +++ /dev/null @@ -1,945 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - Python v ČR: Akce - - - - - - - - - -
- - - - - - -
- -

Akce

-
-

- Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na jednom místě. -

-
-
- -
-
- -

Srazy

-

- Srazy Python programátorů zvané - Pyvo se pořádají po celé republice. Přijď si - poslechnout přednášky od chytrých lidí a - popovídat si nejen o Pythonu! -

- -
- - - - - - - - - -
- -

- - Chci uspořádat sraz v mém městě - -

- -
- -
- -
- -

Všechny akce

-
    -
  • - Pravidelné akce lze přidat přes tzv. - iCal export. - Ten může generovat přímo vaše webová stránka (jako v případě - pyvo.cz), nebo jej lze vytáhnout - z nějaké služby (Google Calendar, meetup.com). URL exportu pak - na náš web přidejte pomocí - Pull Requestu. -
  • -
  • - Jednorázové akce lze přidat přes kalendář - Czech - Python Events. Do kalendáře má přístup mnoho z organizátorů - existujících Python akcí, takže je poproste, ať vaši akci přidají, - nebo napište na info@pyvec.org. První URL z popisu události se zde zobrazí jako - odkaz. -
  • -
- - -

Srpen

- - -

Září

-
    - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Plzeňské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
- -

Říjen

-
    - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
- -

Listopad

-
    - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Plzeňské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
- -

Prosinec

-
    - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
- -

Leden

-
    - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Plzeňské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Pražské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Brněnské Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
  • -
    -
    - -
    -
    -

    - - - - Pyvo - - - — iCal - - - - (Olomoucké Pyvo – nepotvrzeno; tradiční termín srazu) - -

    - -
    -
    -
  • - -
- - -

- - iCal na všechny akce - -

- -
- -
- - - - - - - - - - -
- - diff --git a/text.md b/text.md deleted file mode 100644 index d7699346..00000000 --- a/text.md +++ /dev/null @@ -1,349 +0,0 @@ -::: container -::: {.header .clearfix} -- [ English, please!](/en/) - -[![](/static/images/logo-plain.png){height="30"} Python v ČR](/) -::: - -1. [Domů](/) -2. Akce - -::: content -# Akce - -::: row -Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, -na jednom místě. -::: - -::: {.row .cartoon-container .cartoon-hr} -![](/static/images/ukulele.svg){.cartoon} -::: - -::: row -::: {.col-md-8 .col-md-offset-2} -## Srazy - -[Srazy Python programátorů](https://pyvo.cz) zvané **Pyvo** se pořádají -po celé republice. Přijď si poslechnout **přednášky** od chytrých lidí a -**popovídat si** nejen o Pythonu! - -::: {.row .meetups} -::: {.meetups-city .col-sm-4 .col-xs-6} -[Pražské Pyvo](https://pyvo.cz/praha-pyvo/) -::: - -::: {.meetups-city .col-sm-4 .col-xs-6} -[Brněnské Pyvo](https://pyvo.cz/brno-pyvo/) -::: - -::: {.meetups-city .col-sm-4 .col-xs-6} -[Ostravské Pyvo](https://pyvo.cz/ostrava-pyvo/) -::: - -::: {.meetups-city .col-sm-4 .col-xs-6} -[Plzeňské Pyvo](https://pyvo.cz/plzen-pyvo/) -::: -::: - -[ Chci uspořádat sraz v mém -městě](https://docs.pyvec.org/guides/meetup.html){.btn .btn-primary -.btn-lg} -::: -::: - ------------------------------------------------------------------------- - -::: row -::: {.col-md-8 .col-md-offset-2} -## Všechny akce {#akce} - -- **Pravidelné akce** lze přidat přes tzv. - [iCal](https://cs.wikipedia.org/wiki/ICalendar) export. Ten může - generovat přímo vaše webová stránka (jako v případě - [pyvo.cz](https://pyvo.cz)), nebo jej lze vytáhnout z nějaké služby - (Google Calendar, meetup.com). URL exportu pak na náš web [přidejte - pomocí Pull - Requestu](https://github.com/pyvec/python.cz/edit/master/pythoncz/static/data/events_feeds.yml). -- **Jednorázové akce** lze přidat přes kalendář [Czech Python - Events](https://calendar.google.com/calendar/embed?src=kfdeelic1a13jsp7jvai861vfs%40group.calendar.google.com&ctz=Europe%2FPrague). - Do kalendáře má přístup mnoho z organizátorů existujících Python - akcí, takže je poproste, ať vaši akci přidají, nebo napište na - . První URL z popisu události se zde zobrazí jako - odkaz. - -### Srpen {#month-2023-8 .events-month} - -- ::: media - ::: media-left - [30]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [31]{.event-day} [čtvrtek]{.small} [18:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [Brněnské Pyvo -- Grilovací - II](https://pyvo.cz/brno-pyvo/2023-08/){.event-title} - Lužánky, Veřejný gril při zastávce Pionýrská, Brno - - [Mapy.cz](https://mapy.cz/zakladni?q=Lu%C5%BE%C3%A1nky%2C+Ve%C5%99ejn%C3%BD+gril+p%C5%99i+zast%C3%A1vce+Pion%C3%BDrsk%C3%A1%2C+Brno) - [Google - Maps](https://www.google.com/maps?q=Lu%C5%BE%C3%A1nky%2C+Ve%C5%99ejn%C3%BD+gril+p%C5%99i+zast%C3%A1vce+Pion%C3%BDrsk%C3%A1%2C+Brno) - ::: - ::: - -### Září {#month-2023-9 .events-month} - -- ::: media - ::: media-left - [13]{.event-day} [st]{.small} [18:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Plzeňské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [20]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [27]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [28]{.event-day} [čt]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -### Říjen {#month-2023-10 .events-month} - -- ::: media - ::: media-left - [18]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [25]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [26]{.event-day} [čt]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -### Listopad {#month-2023-11 .events-month} - -- ::: media - ::: media-left - [08]{.event-day} [st]{.small} [18:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Plzeňské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [15]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [29]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [30]{.event-day} [čt]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -### Prosinec {#month-2023-12 .events-month} - -- ::: media - ::: media-left - [20]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [27]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [28]{.event-day} [čt]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -### Leden {#month-2024-1 .events-month} - -- ::: media - ::: media-left - [10]{.event-day} [st]{.small} [18:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Plzeňské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [17]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Pražské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [25]{.event-day} [čt]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Brněnské Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -- ::: media - ::: media-left - [31]{.event-day} [st]{.small} [19:00]{.small} - ::: - - ::: media-body - [ [Pyvo](https://pyvo.cz/) --- [iCal](https://pyvo.cz/api/pyvo.ics) - ]{.event-feed} [(Olomoucké Pyvo -- nepotvrzeno; tradiční termín - srazu)]{.event-title} - ::: - ::: - -[ iCal na všechny akce](/events.ics){.btn .btn-primary .btn-lg} -::: -::: -::: - -::: {.row .footer} -Stránky spravuje nezisková organizace [Pyvec](http://pyvec.org). Pište -na , tweetujte na [\@pyvec](https://twitter.com/pyvec).\ -Ilustrace kreslí [Honza Javorek](http://honzajavorek.cz). Doménu -python.cz zapůjčil [KRAXNET](http://xnet.cz/). Děkujeme! - -[ Upravit tuto -stránku](https://github.com/pyvec/python.cz/edit/master/pythoncz/templates/events_cs.html){.btn -.btn-default} -::: - -![](https://queue.simpleanalyticscdn.com/noscript.gif){referrerpolicy="no-referrer-when-downgrade"} -::: From 0e84742f804e5b5cc7a4780fea8a07ad63021429 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 19:28:40 +0200 Subject: [PATCH 05/46] customize the theme --- README.md | 10 +- docs/akce.md | 6 +- docs/css/extra.css | 22 ++ docs/images/favicon.ico | Bin 0 -> 15086 bytes docs/images/logo.svg | 247 ++++++++++++++ docs/index.md | 8 +- docs/prace.md | 18 +- docs/zacatecnici.md | 11 +- mkdocs.yml | 30 +- overrides/partials/copyright.html | 8 + poetry.lock | 515 +++++++++++++++++++++++++++++- pyproject.toml | 1 + 12 files changed, 852 insertions(+), 24 deletions(-) create mode 100644 docs/css/extra.css create mode 100644 docs/images/favicon.ico create mode 100644 docs/images/logo.svg create mode 100644 overrides/partials/copyright.html diff --git a/README.md b/README.md index 38543e0a..b2766a93 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,17 @@ Czech Python community homepage. ## TODO -- port static content +- ~~port static content~~ +- customize the theme - https://www.mkdocs.org/user-guide/customizing-your-theme/#using-the-theme_dir +- fix absolute links and make them relative +- images - events as a plugin - localize the theme - https://www.mkdocs.org/user-guide/localizing-your-theme/ -- customize the theme - https://www.mkdocs.org/user-guide/customizing-your-theme/#using-the-theme_dir - legacy redirects - english version -- fix absolute links and make them relative +- analytics - https://squidfunk.github.io/mkdocs-material/setup/setting-up-site-analytics/#custom-site-analytics +- social cards - https://squidfunk.github.io/mkdocs-material/setup/setting-up-social-cards/ +- logo should be on a white circle ## License diff --git a/docs/akce.md b/docs/akce.md index 7502bce1..85031ecc 100644 --- a/docs/akce.md +++ b/docs/akce.md @@ -1,10 +1,12 @@ # Akce +
Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na jednom místě. +
[Chci uspořádat sraz v mém městě](https://docs.pyvec.org/guides/meetup.html) -## Všechny akce {: #akce :} +## Všechny akce {: #akce } - **Pravidelné akce** lze přidat přes tzv. [iCal](https://cs.wikipedia.org/wiki/ICalendar) export. Ten může @@ -17,4 +19,6 @@ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na je . První URL z popisu události se zde zobrazí jako odkaz. +TODO + [iCal na všechny akce](/events.ics) diff --git a/docs/css/extra.css b/docs/css/extra.css new file mode 100644 index 00000000..fcdf8d7a --- /dev/null +++ b/docs/css/extra.css @@ -0,0 +1,22 @@ +:root { + --md-primary-fg-color: #4b8bbe; + --md-accent-fg-color: #306998; + --md-primary-fg-color--dark: #306998; +} + +.md-typeset h1 { + color: var(--md-default-fg-color); + font-weight: 700; + font-size: 2.5em; + margin-bottom: 1em; +} + +.md-content { + padding-bottom: 2em; +} + +.lead { + font-size: 1.2em; + font-weight: 400; + line-height: 1.6em; +} diff --git a/docs/images/favicon.ico b/docs/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c9efc5844a2627a8474949724a2aefe4ab2baee4 GIT binary patch literal 15086 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 + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/index.md b/docs/index.md index 70067cde..66781f4d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,10 @@ # Python v ČR -Python je moderní programovací jazyk. Je univerzální – pohání weby i rakety. -Dobře se čte a dá se velice rychle naučit. Je skvělý pro výuku programování. -Česká komunita je aktivní. Najdeš v ní pomoc, kamarády i práci. +
+Python je **moderní programovací jazyk**. Je **univerzální** – pohání weby i rakety. +Dobře se čte a dá se velice **rychle naučit**. Je skvělý pro **výuku** programování. +**Česká komunita** je aktivní. Najdeš v ní **pomoc, kamarády i práci**. +
## Kde nás najdeš diff --git a/docs/prace.md b/docs/prace.md index de7971c5..3af985b7 100644 --- a/docs/prace.md +++ b/docs/prace.md @@ -1,10 +1,14 @@ # Python a práce +
Používá vůbec někdo Python? **Ano!** Jde o jazyk vhodný k výuce nebo skriptování, ale to neznamená, že jej nepoužívají firmy z celého světa a nepíšou se v něm rozsáhlé projekty. +
-Ve světě Python používají např. **Blender 3D, Google (YouTube!), +## Python ve světě + +Python používají např. **Blender 3D, YouTube, Dropbox, Disqus, IBM, Instagram, Lucasfilm, Mozilla, NASA, Spotify, Walt Disney, [a mnoho dalších](https://www.python.org/about/success/)** – mimo jiné také spousta vědeckých organizací **včetně švýcarského @@ -14,7 +18,7 @@ CERNu**. TODO -## Jak najít práci? {:#poptavka} +## Jak najít práci? {: #poptavka } - Přijď na [sraz](/#akce) a poptej se tam. - Sleduj všechny [diskusní kanály](/#komunikace), kde se nabídky @@ -38,7 +42,7 @@ TODO ... (Víš o dalších? [Přidej odkaz!](https://github.com/pyvec/python.cz/edit/master/pythoncz/static/data/jobs.yml)) -## Jak najít Python programátory? {:#nabidka} +## Jak najít Python programátory? {: #nabidka } - Přijď na [sraz](/#akce) a poptej se tam. Promluv si s reálnými lidmi, nadchni je, zlákej je, zjisti jaké mají možnosti a požadavky. @@ -47,8 +51,8 @@ TODO konference jsou jedinečnou příležitostí promluvit si s 400+ vývojáři z celé střední Evropy. - Sepiš si inzerát a konkretizuj jej, aspoň do tvaru něčeho jako - *\"hledám nadšence/nájemného profíka na krátkodobý projekt ve stylu - CMS s galerií, nejspíš v Djangu, platím penězi\"*. Čím víc bude + *„hledám nadšence/nájemného profíka na krátkodobý projekt ve stylu + CMS s galerií, nejspíš v Djangu, platím penězi“*. Čím víc bude **lidsky od srdíčka** a čím méně to budou odrážky ve stylu poptáváme/nabízíme, tím více lidí to zaujme. **Nezapomeň napsat do jaké míry je možná práce na dálku.** @@ -61,13 +65,13 @@ TODO - Pošli inzerát na [globální nástěnku nabídek](https://www.python.org/community/jobs/howto/) – ta uveřejňuje nabídky zdarma, jen je potřeba se registrovat. Nabídka se - pak objeví i na Twitter účtu [\@pyjobo](https://twitter.com/pyjobo). + pak objeví i na Twitter účtu [@pyjobo](https://twitter.com/pyjobo). Inzeruj nabídku na pracovních serverech: [Jobs.cz](http://www.jobs.cz/prace/?q%5B%5D=python), [StartupJobs.cz](https://www.startupjobs.cz/nabidky/15/python-programmer), ... -## Chci, aby bylo víc Pythonistů! {:#vic} +## Chci, aby bylo víc Pythonistů! {: #vic } **My taky!** Máme na to dokonce [neziskovku Pyvec](http://pyvec.org/). Můžeš se [zapojit](/zapojse/) a s naší misí nám pomoci. diff --git a/docs/zacatecnici.md b/docs/zacatecnici.md index 93261ee9..681aac7f 100644 --- a/docs/zacatecnici.md +++ b/docs/zacatecnici.md @@ -1,11 +1,10 @@ # Učíme se Python -- Česká **komunita je přátelská a živá**. Vždy bude po ruce **někdo, - kdo ti pomůže**. -- **Nebudeš mít problém [sehnat práci](/prace/).** Pythonistů je - nedostatek! -- I kdyby weby vyšly z módy, Python nachází **uplatnění v desítkách - dalších oborů**. +
+Česká **komunita je přátelská a živá**. Vždy bude po ruce **někdo, kdo ti pomůže**. +**Nebudeš mít problém [sehnat práci](/prace/).** Pythonistů je nedostatek! +I kdyby weby vyšly z módy, Python nachází **uplatnění v desítkách dalších oborů**. +
## Online materiály – neumím vůbec programovat {: #onlineneumim } diff --git a/mkdocs.yml b/mkdocs.yml index 6ccb20fa..44d59a10 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,6 +1,9 @@ site_name: Python v ČR site_url: https://python.cz/ +repo_url: https://github.com/pyvec/python.cz +repo_name: Upravit tyto stránky + nav: - Ahoj!: index.md - Akce: akce.md @@ -9,12 +12,33 @@ nav: - Zapoj se!: zapojse.md theme: - name: mkdocs - locale: cs + name: material + logo: images/logo.svg + favicon: images/favicon.ico + language: cs + palette: + primary: custom + accent: custom + font: false + features: + - navigation.tabs + - navigation.path + - toc.integrate + - content.action.edit + custom_dir: overrides + icon: + repo: fontawesome/brands/github + edit_uri: edit/main/docs/ markdown_extensions: - toc: - toc_depth: '2-2' + toc_depth: 2-2 permalink: '#' permalink_title: Odkaz na tuto sekci - attr_list + - md_in_html + +extra_css: + - css/extra.css + +plugins: [] diff --git a/overrides/partials/copyright.html b/overrides/partials/copyright.html new file mode 100644 index 00000000..ee10b8cc --- /dev/null +++ b/overrides/partials/copyright.html @@ -0,0 +1,8 @@ + diff --git a/poetry.lock b/poetry.lock index a3c24373..ee7980ea 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,129 @@ # This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +[[package]] +name = "babel" +version = "2.12.1" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, + {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.2" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, + {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "certifi" +version = "2023.7.22" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.2.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, + {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, +] + [[package]] name = "click" version = "8.1.7" @@ -25,6 +149,17 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "cssselect" +version = "1.2.0" +description = "cssselect parses CSS3 Selectors and translates them to XPath 1.0" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cssselect-1.2.0-py2.py3-none-any.whl", hash = "sha256:da1885f0c10b60c03ed5eccbb6b68d6eff248d91976fcde348f395d54c9fd35e"}, + {file = "cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc"}, +] + [[package]] name = "ghp-import" version = "2.1.0" @@ -42,6 +177,17 @@ python-dateutil = ">=2.8.1" [package.extras] dev = ["flake8", "markdown", "twine", "wheel"] +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] + [[package]] name = "iniconfig" version = "2.0.0" @@ -70,6 +216,102 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "lxml" +version = "4.9.3" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" +files = [ + {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, + {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, + {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, + {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, + {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, + {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, + {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, + {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, + {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, + {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, + {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, + {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, + {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, + {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, + {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, + {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, + {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, + {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, + {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, + {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, + {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, + {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, + {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, + {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, + {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, + {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, + {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, + {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, + {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, + {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, + {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, + {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, + {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, + {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, + {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, + {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, + {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, + {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, + {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, + {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, + {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, + {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, + {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (>=0.29.35)"] + [[package]] name = "markdown" version = "3.4.4" @@ -85,6 +327,22 @@ files = [ docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.0)", "mkdocs-nature (>=0.4)"] testing = ["coverage", "pyyaml"] +[[package]] +name = "markdown2" +version = "2.4.10" +description = "A fast and complete Python implementation of Markdown" +optional = false +python-versions = ">=3.5, <4" +files = [ + {file = "markdown2-2.4.10-py2.py3-none-any.whl", hash = "sha256:e6105800483783831f5dc54f827aa5b44eb137ecef5a70293d8ecfbb4109ecc6"}, + {file = "markdown2-2.4.10.tar.gz", hash = "sha256:cdba126d90dc3aef6f4070ac342f974d63f415678959329cc7909f96cc235d72"}, +] + +[package.extras] +all = ["pygments (>=2.7.3)", "wavedrom"] +code-syntax-highlighting = ["pygments (>=2.7.3)"] +wavedrom = ["wavedrom"] + [[package]] name = "markupsafe" version = "2.1.3" @@ -185,6 +443,43 @@ watchdog = ">=2.0" i18n = ["babel (>=2.9.0)"] min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] +[[package]] +name = "mkdocs-material" +version = "9.2.3" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs_material-9.2.3-py3-none-any.whl", hash = "sha256:1cbac871826bbe0b5a42d7a86cfe729e03cef60cbd4d7425c640115bf1936360"}, + {file = "mkdocs_material-9.2.3.tar.gz", hash = "sha256:7a8c5638e28cb1c0a0c7596dd85835c461a73637ce8640ea9302dbc674c2aa29"}, +] + +[package.dependencies] +babel = ">=2.10.3" +colorama = ">=0.4" +jinja2 = ">=3.0" +lxml = ">=4.6" +markdown = ">=3.2" +mkdocs = ">=1.5.2" +mkdocs-material-extensions = ">=1.1" +paginate = ">=0.5.6" +pygments = ">=2.14" +pymdown-extensions = ">=9.9.1" +readtime = ">=2.0" +regex = ">=2022.4.24" +requests = ">=2.26" + +[[package]] +name = "mkdocs-material-extensions" +version = "1.1.1" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.7" +files = [ + {file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"}, + {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, +] + [[package]] name = "packaging" version = "23.1" @@ -196,6 +491,16 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] +[[package]] +name = "paginate" +version = "0.5.6" +description = "Divides large result sets into pages for easier browsing" +optional = false +python-versions = "*" +files = [ + {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, +] + [[package]] name = "pathspec" version = "0.11.2" @@ -237,6 +542,53 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "pygments" +version = "2.16.1" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, +] + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pymdown-extensions" +version = "10.1" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pymdown_extensions-10.1-py3-none-any.whl", hash = "sha256:ef25dbbae530e8f67575d222b75ff0649b1e841e22c2ae9a20bad9472c2207dc"}, + {file = "pymdown_extensions-10.1.tar.gz", hash = "sha256:508009b211373058debb8247e168de4cbcb91b1bff7b5e961b2c3e864e00b195"}, +] + +[package.dependencies] +markdown = ">=3.2" +pyyaml = "*" + +[[package]] +name = "pyquery" +version = "2.0.0" +description = "A jquery-like library for python" +optional = false +python-versions = "*" +files = [ + {file = "pyquery-2.0.0-py3-none-any.whl", hash = "sha256:8dfc9b4b7c5f877d619bbae74b1898d5743f6ca248cfd5d72b504dd614da312f"}, + {file = "pyquery-2.0.0.tar.gz", hash = "sha256:963e8d4e90262ff6d8dec072ea97285dc374a2f69cad7776f4082abcf6a1d8ae"}, +] + +[package.dependencies] +cssselect = ">=1.2.0" +lxml = ">=2.1" + +[package.extras] +test = ["pytest", "pytest-cov", "requests", "webob", "webtest"] + [[package]] name = "pytest" version = "7.4.0" @@ -334,6 +686,139 @@ files = [ [package.dependencies] pyyaml = "*" +[[package]] +name = "readtime" +version = "3.0.0" +description = "Calculates the time some text takes the average human to read, based on Medium's read time forumula" +optional = false +python-versions = "*" +files = [ + {file = "readtime-3.0.0.tar.gz", hash = "sha256:76c5a0d773ad49858c53b42ba3a942f62fbe20cc8c6f07875797ac7dc30963a9"}, +] + +[package.dependencies] +beautifulsoup4 = ">=4.0.1" +markdown2 = ">=2.4.3" +pyquery = ">=1.2" + +[[package]] +name = "regex" +version = "2023.8.8" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.6" +files = [ + {file = "regex-2023.8.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb"}, + {file = "regex-2023.8.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3611576aff55918af2697410ff0293d6071b7e00f4b09e005d614686ac4cd57c"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8a0ccc8f2698f120e9e5742f4b38dc944c38744d4bdfc427616f3a163dd9de5"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c662a4cbdd6280ee56f841f14620787215a171c4e2d1744c9528bed8f5816c96"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf0633e4a1b667bfe0bb10b5e53fe0d5f34a6243ea2530eb342491f1adf4f739"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:551ad543fa19e94943c5b2cebc54c73353ffff08228ee5f3376bd27b3d5b9800"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54de2619f5ea58474f2ac211ceea6b615af2d7e4306220d4f3fe690c91988a61"}, + {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ec4b3f0aebbbe2fc0134ee30a791af522a92ad9f164858805a77442d7d18570"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ae646c35cb9f820491760ac62c25b6d6b496757fda2d51be429e0e7b67ae0ab"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca339088839582d01654e6f83a637a4b8194d0960477b9769d2ff2cfa0fa36d2"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d9b6627408021452dcd0d2cdf8da0534e19d93d070bfa8b6b4176f99711e7f90"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:bd3366aceedf274f765a3a4bc95d6cd97b130d1dda524d8f25225d14123c01db"}, + {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7aed90a72fc3654fba9bc4b7f851571dcc368120432ad68b226bd593f3f6c0b7"}, + {file = "regex-2023.8.8-cp310-cp310-win32.whl", hash = "sha256:80b80b889cb767cc47f31d2b2f3dec2db8126fbcd0cff31b3925b4dc6609dcdb"}, + {file = "regex-2023.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:b82edc98d107cbc7357da7a5a695901b47d6eb0420e587256ba3ad24b80b7d0b"}, + {file = "regex-2023.8.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1e7d84d64c84ad97bf06f3c8cb5e48941f135ace28f450d86af6b6512f1c9a71"}, + {file = "regex-2023.8.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce0f9fbe7d295f9922c0424a3637b88c6c472b75eafeaff6f910494a1fa719ef"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06c57e14ac723b04458df5956cfb7e2d9caa6e9d353c0b4c7d5d54fcb1325c46"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7a9aaa5a1267125eef22cef3b63484c3241aaec6f48949b366d26c7250e0357"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b7408511fca48a82a119d78a77c2f5eb1b22fe88b0d2450ed0756d194fe7a9a"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14dc6f2d88192a67d708341f3085df6a4f5a0c7b03dec08d763ca2cd86e9f559"}, + {file = "regex-2023.8.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48c640b99213643d141550326f34f0502fedb1798adb3c9eb79650b1ecb2f177"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0085da0f6c6393428bf0d9c08d8b1874d805bb55e17cb1dfa5ddb7cfb11140bf"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:964b16dcc10c79a4a2be9f1273fcc2684a9eedb3906439720598029a797b46e6"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7ce606c14bb195b0e5108544b540e2c5faed6843367e4ab3deb5c6aa5e681208"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:40f029d73b10fac448c73d6eb33d57b34607f40116e9f6e9f0d32e9229b147d7"}, + {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3b8e6ea6be6d64104d8e9afc34c151926f8182f84e7ac290a93925c0db004bfd"}, + {file = "regex-2023.8.8-cp311-cp311-win32.whl", hash = "sha256:942f8b1f3b223638b02df7df79140646c03938d488fbfb771824f3d05fc083a8"}, + {file = "regex-2023.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:51d8ea2a3a1a8fe4f67de21b8b93757005213e8ac3917567872f2865185fa7fb"}, + {file = "regex-2023.8.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e951d1a8e9963ea51efd7f150450803e3b95db5939f994ad3d5edac2b6f6e2b4"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704f63b774218207b8ccc6c47fcef5340741e5d839d11d606f70af93ee78e4d4"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22283c769a7b01c8ac355d5be0715bf6929b6267619505e289f792b01304d898"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91129ff1bb0619bc1f4ad19485718cc623a2dc433dff95baadbf89405c7f6b57"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de35342190deb7b866ad6ba5cbcccb2d22c0487ee0cbb251efef0843d705f0d4"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b993b6f524d1e274a5062488a43e3f9f8764ee9745ccd8e8193df743dbe5ee61"}, + {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3026cbcf11d79095a32d9a13bbc572a458727bd5b1ca332df4a79faecd45281c"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:293352710172239bf579c90a9864d0df57340b6fd21272345222fb6371bf82b3"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d909b5a3fff619dc7e48b6b1bedc2f30ec43033ba7af32f936c10839e81b9217"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3d370ff652323c5307d9c8e4c62efd1956fb08051b0e9210212bc51168b4ff56"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:b076da1ed19dc37788f6a934c60adf97bd02c7eea461b73730513921a85d4235"}, + {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e9941a4ada58f6218694f382e43fdd256e97615db9da135e77359da257a7168b"}, + {file = "regex-2023.8.8-cp36-cp36m-win32.whl", hash = "sha256:a8c65c17aed7e15a0c824cdc63a6b104dfc530f6fa8cb6ac51c437af52b481c7"}, + {file = "regex-2023.8.8-cp36-cp36m-win_amd64.whl", hash = "sha256:aadf28046e77a72f30dcc1ab185639e8de7f4104b8cb5c6dfa5d8ed860e57236"}, + {file = "regex-2023.8.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:423adfa872b4908843ac3e7a30f957f5d5282944b81ca0a3b8a7ccbbfaa06103"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ae594c66f4a7e1ea67232a0846649a7c94c188d6c071ac0210c3e86a5f92109"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e51c80c168074faa793685656c38eb7a06cbad7774c8cbc3ea05552d615393d8"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09b7f4c66aa9d1522b06e31a54f15581c37286237208df1345108fcf4e050c18"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e73e5243af12d9cd6a9d6a45a43570dbe2e5b1cdfc862f5ae2b031e44dd95a8"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941460db8fe3bd613db52f05259c9336f5a47ccae7d7def44cc277184030a116"}, + {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f0ccf3e01afeb412a1a9993049cb160d0352dba635bbca7762b2dc722aa5742a"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2e9216e0d2cdce7dbc9be48cb3eacb962740a09b011a116fd7af8c832ab116ca"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5cd9cd7170459b9223c5e592ac036e0704bee765706445c353d96f2890e816c8"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4873ef92e03a4309b3ccd8281454801b291b689f6ad45ef8c3658b6fa761d7ac"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:239c3c2a339d3b3ddd51c2daef10874410917cd2b998f043c13e2084cb191684"}, + {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1005c60ed7037be0d9dea1f9c53cc42f836188227366370867222bda4c3c6bd7"}, + {file = "regex-2023.8.8-cp37-cp37m-win32.whl", hash = "sha256:e6bd1e9b95bc5614a7a9c9c44fde9539cba1c823b43a9f7bc11266446dd568e3"}, + {file = "regex-2023.8.8-cp37-cp37m-win_amd64.whl", hash = "sha256:9a96edd79661e93327cfeac4edec72a4046e14550a1d22aa0dd2e3ca52aec921"}, + {file = "regex-2023.8.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2181c20ef18747d5f4a7ea513e09ea03bdd50884a11ce46066bb90fe4213675"}, + {file = "regex-2023.8.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a2ad5add903eb7cdde2b7c64aaca405f3957ab34f16594d2b78d53b8b1a6a7d6"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9233ac249b354c54146e392e8a451e465dd2d967fc773690811d3a8c240ac601"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:920974009fb37b20d32afcdf0227a2e707eb83fe418713f7a8b7de038b870d0b"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2b6c5dfe0929b6c23dde9624483380b170b6e34ed79054ad131b20203a1a63"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96979d753b1dc3b2169003e1854dc67bfc86edf93c01e84757927f810b8c3c93"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ae54a338191e1356253e7883d9d19f8679b6143703086245fb14d1f20196be9"}, + {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2162ae2eb8b079622176a81b65d486ba50b888271302190870b8cc488587d280"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c884d1a59e69e03b93cf0dfee8794c63d7de0ee8f7ffb76e5f75be8131b6400a"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf9273e96f3ee2ac89ffcb17627a78f78e7516b08f94dc435844ae72576a276e"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:83215147121e15d5f3a45d99abeed9cf1fe16869d5c233b08c56cdf75f43a504"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f7454aa427b8ab9101f3787eb178057c5250478e39b99540cfc2b889c7d0586"}, + {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0640913d2c1044d97e30d7c41728195fc37e54d190c5385eacb52115127b882"}, + {file = "regex-2023.8.8-cp38-cp38-win32.whl", hash = "sha256:0c59122ceccb905a941fb23b087b8eafc5290bf983ebcb14d2301febcbe199c7"}, + {file = "regex-2023.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:c12f6f67495ea05c3d542d119d270007090bad5b843f642d418eb601ec0fa7be"}, + {file = "regex-2023.8.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:82cd0a69cd28f6cc3789cc6adeb1027f79526b1ab50b1f6062bbc3a0ccb2dbc3"}, + {file = "regex-2023.8.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bb34d1605f96a245fc39790a117ac1bac8de84ab7691637b26ab2c5efb8f228c"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:987b9ac04d0b38ef4f89fbc035e84a7efad9cdd5f1e29024f9289182c8d99e09"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dd6082f4e2aec9b6a0927202c85bc1b09dcab113f97265127c1dc20e2e32495"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7eb95fe8222932c10d4436e7a6f7c99991e3fdd9f36c949eff16a69246dee2dc"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7098c524ba9f20717a56a8d551d2ed491ea89cbf37e540759ed3b776a4f8d6eb"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b694430b3f00eb02c594ff5a16db30e054c1b9589a043fe9174584c6efa8033"}, + {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2aeab3895d778155054abea5238d0eb9a72e9242bd4b43f42fd911ef9a13470"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:988631b9d78b546e284478c2ec15c8a85960e262e247b35ca5eaf7ee22f6050a"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:67ecd894e56a0c6108ec5ab1d8fa8418ec0cff45844a855966b875d1039a2e34"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:14898830f0a0eb67cae2bbbc787c1a7d6e34ecc06fbd39d3af5fe29a4468e2c9"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f2200e00b62568cfd920127782c61bc1c546062a879cdc741cfcc6976668dfcf"}, + {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9691a549c19c22d26a4f3b948071e93517bdf86e41b81d8c6ac8a964bb71e5a6"}, + {file = "regex-2023.8.8-cp39-cp39-win32.whl", hash = "sha256:6ab2ed84bf0137927846b37e882745a827458689eb969028af8032b1b3dac78e"}, + {file = "regex-2023.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5543c055d8ec7801901e1193a51570643d6a6ab8751b1f7dd9af71af467538bb"}, + {file = "regex-2023.8.8.tar.gz", hash = "sha256:fcbdc5f2b0f1cd0f6a56cdb46fe41d2cce1e644e3b68832f3eeebc5fb0f7712e"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + [[package]] name = "six" version = "1.16.0" @@ -345,6 +830,34 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "soupsieve" +version = "2.4.1" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, + {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, +] + +[[package]] +name = "urllib3" +version = "2.0.4" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.7" +files = [ + {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, + {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + [[package]] name = "watchdog" version = "3.0.0" @@ -387,4 +900,4 @@ watchmedo = ["PyYAML (>=3.10)"] [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "e7635e9a18b6404266b698cb6a2e2af945591df8250cfbf64585ab271fc3db88" +content-hash = "63ccef1855b97a344b48b6da222efe60b755b721d62497ab56a8ea4fd8dc9593" diff --git a/pyproject.toml b/pyproject.toml index 9ac8d4b3..7057244d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ pythoncz = "pythoncz:main" [tool.poetry.dependencies] python = "3.11.*" mkdocs = "1.5.2" +mkdocs-material = "^9.2.3" [tool.poetry.group.dev.dependencies] pytest = "7.4.0" From ad5e000b654975466e7a24f438cbab297e9a3b89 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 19:35:06 +0200 Subject: [PATCH 06/46] fix build --- .github/workflows/build.yml | 17 +++++++++++------ .gitignore | 3 +++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 86894ff2..ef0a64be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,11 +24,16 @@ jobs: - name: Install dependencies run: poetry install - - name: Test - run: poetry run pythoncz test + # - name: Test + # run: poetry run pytest + + - name: Build + run: poetry run mkdocs build - if: ${{ github.ref == 'refs/heads/main' }} - name: Deploy - run: pipenv run pythoncz deploy - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./site + #cname: python.cz diff --git a/.gitignore b/.gitignore index e603a349..3d1c66e0 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ pip-log.txt /cache/ .cache .pytest_cache/ + +# MkDocs +/site/ From c690436ae81451e4eca9405ed6258450be739338 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 19:46:29 +0200 Subject: [PATCH 07/46] update readme and a few other fixes --- README.md | 14 ++++++++++++++ docs/zapojse.md | 4 ++++ mkdocs.yml | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b2766a93..c742df65 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,20 @@ Czech Python community homepage. +## Status + +See the website at [honzajavorek.github.io/mkdocs-python.cz](https://honzajavorek.github.io/mkdocs-python.cz/). +This is a proof of concept and a work in progress. + +## Goals + +- Give up on complicated custom solutions which have little added value, but enormous overhead +- Give up on custom design, because there is nobody in the community to maintain custom designs +- Use as much existing software as possible +- Make the website easy to maintain, easy to edit, easy to contribute + +Intentionally not trying to achieve feature parity with existing python.cz website. + ## TODO - ~~port static content~~ diff --git a/docs/zapojse.md b/docs/zapojse.md index e84bc5f3..647f2e8b 100644 --- a/docs/zapojse.md +++ b/docs/zapojse.md @@ -1,6 +1,10 @@ # Zapoj se! +
Líbí se ti Python? **Pomoz nám ho rozšířit i mezi ostatní.** Můžeš nám poslat peníze, učit, přednášet, psát, organizovat, programovat, ale třeba i jen vymýšlet, co a jak by se dalo zlepšit. Máme práci pro každého! +
+ +## Proč? Python komunita je fajn jen díky tomu, že jsou v ní **lidi, kteří se nebojí přiložit ruku k dílu**. Všichni to děláme po večerech ve volném čase, z čirého nadšení. **Děláme to proto, že chceme, aby to bylo lepší i pro tebe.** Ať jsi profík nebo začátečník, z Prahy nebo z Karviné, můžeš nám pomoci. Odměnou ti budou kontakty, reference, zkušenosti. diff --git a/mkdocs.yml b/mkdocs.yml index 44d59a10..83319908 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -22,7 +22,7 @@ theme: font: false features: - navigation.tabs - - navigation.path + - navigation.tabs.sticky - toc.integrate - content.action.edit custom_dir: overrides From 3f2a02d7ccf3bee245daf26a983bb955cfe66d43 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 19:50:45 +0200 Subject: [PATCH 08/46] addition --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c742df65..1d504e78 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # python.cz -Czech Python community homepage. +Czech Python community homepage on MkDocs. ## Status From 6cbcea693be2eff79936d79b7563025b1f71d335 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 20:06:19 +0200 Subject: [PATCH 09/46] document intentions --- docs/akce.md | 2 +- docs/index.md | 2 +- docs/prace.md | 2 +- docs/zapojse.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/akce.md b/docs/akce.md index 85031ecc..146ccf9a 100644 --- a/docs/akce.md +++ b/docs/akce.md @@ -19,6 +19,6 @@ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na je . První URL z popisu události se zde zobrazí jako odkaz. -TODO +TODO - tohle je nejdůležitější část webu a musí být naprogramovaná a funkční [iCal na všechny akce](/events.ics) diff --git a/docs/index.md b/docs/index.md index 66781f4d..c7a1fed4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,7 +22,7 @@ Dobře se čte a dá se velice **rychle naučit**. Je skvělý pro **výuku** pr ## Nejbližší akce -TODO +TODO - tohle je nejdůležitější část webu a musí být naprogramovaná a funkční ## Odkazy diff --git a/docs/prace.md b/docs/prace.md index 3af985b7..a1de52e0 100644 --- a/docs/prace.md +++ b/docs/prace.md @@ -16,7 +16,7 @@ CERNu**. ## Python u nás -TODO +TODO - zrušit seznam, dát sem sponzory PyConu a nějaký text, možná odkazy na job boardy s filtrováním na python ## Jak najít práci? {: #poptavka } diff --git a/docs/zapojse.md b/docs/zapojse.md index 647f2e8b..1f5c0dc4 100644 --- a/docs/zapojse.md +++ b/docs/zapojse.md @@ -86,6 +86,6 @@ Značka _Kouč pomůže!_ znamená, že někdo navrhl, navrhnout jako kouč, napiš to do komentáře pod daný úkol a [přiřaď mu štítek](https://help.github.com/articles/applying-labels-to-issues-and-pull-requests/) -TODO +TODO - zrušit, možná udělat jen seznam organizací nebo repozitářů ![Přidat nápad](https://github.com/pyvec/zapojse/issues/new) From 7ee1ef61183744e8620e38bfe286008792bdcbcd Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Fri, 25 Aug 2023 20:07:30 +0200 Subject: [PATCH 10/46] update readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1d504e78..0f49f18e 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,11 @@ Intentionally not trying to achieve feature parity with existing python.cz websi ## TODO - ~~port static content~~ -- customize the theme - https://www.mkdocs.org/user-guide/customizing-your-theme/#using-the-theme_dir +- ~~customize the theme~~ +- events as a plugin - fix absolute links and make them relative - images -- events as a plugin +- icons - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#additional-icons - localize the theme - https://www.mkdocs.org/user-guide/localizing-your-theme/ - legacy redirects - english version From 6d2aa660a924f458f4cf0b9b8183a909aca53e6a Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 12:54:28 +0200 Subject: [PATCH 11/46] fetch events --- .gitignore | 3 + events.py | 103 ++++++++ events_feeds.yml | 24 ++ mkdocs.yml | 3 + poetry.lock | 324 +++++++++++++++++++++++++- pyproject.toml | 12 +- pythoncz/static/data/events_feeds.yml | 19 -- 7 files changed, 467 insertions(+), 21 deletions(-) create mode 100644 events.py create mode 100644 events_feeds.yml delete mode 100644 pythoncz/static/data/events_feeds.yml diff --git a/.gitignore b/.gitignore index 3d1c66e0..19f85a57 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ pip-log.txt # MkDocs /site/ + +# custom +.events_cache.json diff --git a/events.py b/events.py new file mode 100644 index 00000000..5b825d2e --- /dev/null +++ b/events.py @@ -0,0 +1,103 @@ +from datetime import date, datetime, timedelta, timezone +import json +from operator import itemgetter +from pathlib import Path + +import pytz +import extruct +import ics +from mkdocs.config import Config +import requests +from strictyaml import load as load_yaml, Map, Str, Seq, Url + + +YAML_SCHEMA = Seq( + Map( + { + 'name': Str(), + 'site_url': Url(), + 'url': Url(), + 'format': Str(), + } + ) +) + +USER_AGENT = 'python.cz (+https://python.cz)' + +TIMELINE_LIMIT_DAYS = 60 + + +def on_post_build(config: Config | None=None): + cache_path = Path('.events_cache.json') + try: + print(f'Loading events feeds from {cache_path}') + data = json.loads(cache_path.read_text()) + except FileNotFoundError: + print('No cache') + yaml = Path('events_feeds.yml').read_text() + data = [] + for feed in load_yaml(yaml, YAML_SCHEMA).data: + print(f"Fetching {feed['url']}") + response = requests.get(feed['url'], headers={'User-Agent': USER_AGENT}) + response.raise_for_status() + feed['url'] = response.url # overwrite with the final URL + feed['data'] = response.text + data.append(feed) + cache_path.write_text(json.dumps(data, indent=2, ensure_ascii=False)) + + print('Parsing events') + events = [] + for feed in data: + if feed['format'] == 'icalendar': + events.extend([dict(feed=feed, **event_data) + for event_data in parse_icalendar(feed['data'])]) + elif feed['format'] == 'json-dl': + events.extend([dict(feed=feed, **event_data) + for event_data in parse_json_dl(feed['data'], feed['url'])]) + else: + raise ValueError(f"Unknown feed format {feed['format']!r}") + + print('Filtering and sorting events') + today = date.today() + timeline_limit = today + timedelta(days=TIMELINE_LIMIT_DAYS) + events = sorted((event for event in events + if (event['starts_at'].date() >= today or (event['ends_at'] and event['ends_at'].date() >= today)) + and event['starts_at'].date() <= timeline_limit), + key=itemgetter('starts_at')) + for event in events: + print(event['starts_at'], event['name']) + + +def parse_icalendar(text: str): + return [dict(name=event.summary, + starts_at=to_prague_tz(event.begin), + ends_at=to_prague_tz(event.end) if event.end else None, + location_raw=event.location, + url=event.url) + for event in ics.Calendar(text).events] + + +def parse_json_dl(html: str, base_url: str): + data = extruct.extract(html, base_url, syntaxes=['json-ld']) + return [dict(name=item['name'], + starts_at=to_prague_tz(datetime.fromisoformat(item['startDate'])), + ends_at=to_prague_tz(datetime.fromisoformat(item['endDate'])), + location_raw=parse_json_dl_location(item['location']), + url=item['url']) + for item in data['json-ld'] + if item['@type'] == 'Event' and base_url in item['url']] + + +def parse_json_dl_location(location: dict[str, str]) -> str: + return f"{location['name']}, {location['address']['streetAddress']}, {location['address']['addressLocality']}, {location['address']['addressCountry']}" + + +def to_prague_tz(dt: datetime) -> datetime: + prague_tz = pytz.timezone('Europe/Prague') + if dt.tzinfo is None: + return dt.replace(tzinfo=prague_tz) + return dt.astimezone(prague_tz) + + +if __name__ == '__main__': + on_post_build() diff --git a/events_feeds.yml b/events_feeds.yml new file mode 100644 index 00000000..7873d75c --- /dev/null +++ b/events_feeds.yml @@ -0,0 +1,24 @@ +- name: Pyvo + site_url: https://pyvo.cz/ + url: https://pyvo.cz/api/pyvo.ics + format: icalendar + +- name: PyWorking + site_url: https://pyworking.cz/ + url: https://pyworking.cz/workshops.ics + format: icalendar + +- name: PyWorking Sessions + site_url: https://pyworking.cz/ + url: https://www.meetup.com/pyworking/events/ + format: json-dl + +- name: PyData Prague + site_url: https://www.meetup.com/PyData-Prague/ + url: https://www.meetup.com/PyData-Prague/events/ + format: json-dl + +- name: Czech Python Events + site_url: https://calendar.google.com/calendar/embed?src=kfdeelic1a13jsp7jvai861vfs%40group.calendar.google.com&ctz=Europe%2FPrague + url: https://calendar.google.com/calendar/ical/kfdeelic1a13jsp7jvai861vfs%40group.calendar.google.com/public/basic.ics + format: icalendar diff --git a/mkdocs.yml b/mkdocs.yml index 83319908..dc1c3e5a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -38,6 +38,9 @@ markdown_extensions: - attr_list - md_in_html +hooks: + - hooks.py + extra_css: - css/extra.css diff --git a/poetry.lock b/poetry.lock index ee7980ea..38c72698 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,23 @@ # This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +[[package]] +name = "attrs" +version = "23.1.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] + [[package]] name = "babel" version = "2.12.1" @@ -29,6 +47,50 @@ soupsieve = ">1.2" html5lib = ["html5lib"] lxml = ["lxml"] +[[package]] +name = "black" +version = "23.7.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"}, + {file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"}, + {file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"}, + {file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"}, + {file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"}, + {file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"}, + {file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"}, + {file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"}, + {file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"}, + {file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"}, + {file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"}, + {file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"}, + {file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"}, + {file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"}, + {file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"}, + {file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"}, +] + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + [[package]] name = "certifi" version = "2023.7.22" @@ -160,6 +222,30 @@ files = [ {file = "cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc"}, ] +[[package]] +name = "extruct" +version = "0.16.0" +description = "Extract embedded metadata from HTML markup" +optional = false +python-versions = "*" +files = [ + {file = "extruct-0.16.0-py2.py3-none-any.whl", hash = "sha256:2499ea9e7d22744745ca708acee9542a4aa231871620c4f65f869a1286e64aa8"}, + {file = "extruct-0.16.0.tar.gz", hash = "sha256:d09cb3d86d149a276b277b3bd45b2b867ef3ec78bed9cd58ee0f2ae01ae670c4"}, +] + +[package.dependencies] +html-text = ">=0.5.1" +jstyleson = "*" +lxml = "*" +mf2py = "*" +pyrdfa3 = "*" +rdflib = {version = ">=6.0.0", markers = "python_version >= \"3.7\""} +six = "*" +w3lib = "*" + +[package.extras] +cli = ["requests"] + [[package]] name = "ghp-import" version = "2.1.0" @@ -177,6 +263,80 @@ python-dateutil = ">=2.8.1" [package.extras] dev = ["flake8", "markdown", "twine", "wheel"] +[[package]] +name = "html-text" +version = "0.5.2" +description = "Extract text from HTML" +optional = false +python-versions = "*" +files = [ + {file = "html_text-0.5.2-py2.py3-none-any.whl", hash = "sha256:3f1e063f05eddf3e099a88f0440219c55fdc01c44f1291fe59c66e5228d7fc56"}, + {file = "html_text-0.5.2.tar.gz", hash = "sha256:afd61bbb70651d494a8c32670a29b9140492eccc9690109857beae41c3093ded"}, +] + +[package.dependencies] +lxml = "*" + +[[package]] +name = "html5lib" +version = "1.1" +description = "HTML parser based on the WHATWG HTML specification" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, + {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, +] + +[package.dependencies] +six = ">=1.9" +webencodings = "*" + +[package.extras] +all = ["chardet (>=2.2)", "genshi", "lxml"] +chardet = ["chardet (>=2.2)"] +genshi = ["genshi"] +lxml = ["lxml"] + +[[package]] +name = "ics" +version = "0.8.0.dev0" +description = "Pythonic iCalendar (RFC 5545) Parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ics-0.8.0.dev0-py3-none-any.whl", hash = "sha256:7b78a02d3aa7e7143f27ff9072390cbda5795839f59fd09bd2f404932b49eaf6"}, + {file = "ics-0.8.0.dev0.tar.gz", hash = "sha256:51169026b9368e88abf167e7a86cb39c576299d7c36a871f1a39e36beabcfcae"}, +] + +[package.dependencies] +attrs = ">=20.3" +ics-vtimezones = ">=2020.1" +python-dateutil = ">=2.8" + +[package.extras] +checks = ["flake8 (>=3.8.1)", "mypy (==0.960)"] +dev = ["bump2version (>=1.0.0)", "tox (>=3.25)"] +docs = ["sphinx (>=5)", "sphinx-autodoc-typehints"] +test = ["freezegun (>=1.2.1)", "hypothesis (>=6)", "importlib-resources (>=1.4)", "lipsum (>=0.1.2)", "pytest (>=7)", "pytest-cov (>=3)", "tatsu (>4.2)"] + +[[package]] +name = "ics-vtimezones" +version = "2020.1" +description = "iCalendar vTimezone Data" +optional = false +python-versions = ">=3.6,<4.0" +files = [ + {file = "ics_vtimezones-2020.1-py3-none-any.whl", hash = "sha256:775f0c3a9a417a9466e511bc1068e239036f4ea405a55d0cec0ba95e551717c4"}, + {file = "ics_vtimezones-2020.1.tar.gz", hash = "sha256:04ab770ceb68a304de65be12257340c74e811cc925e771c10aab166de05768c6"}, +] + +[package.dependencies] +importlib_resources = ">=1.4,<2.0" + +[package.extras] +update = ["ics (>=0.8.0,<0.9.0)"] + [[package]] name = "idna" version = "3.4" @@ -188,6 +348,20 @@ files = [ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, ] +[[package]] +name = "importlib-resources" +version = "1.5.0" +description = "Read resources from Python packages" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "importlib_resources-1.5.0-py2.py3-none-any.whl", hash = "sha256:85dc0b9b325ff78c8bef2e4ff42616094e16b98ebd5e3b50fe7e2f0bbcdcde49"}, + {file = "importlib_resources-1.5.0.tar.gz", hash = "sha256:6f87df66833e1942667108628ec48900e02a4ab4ad850e25fbf07cb17cf734ca"}, +] + +[package.extras] +docs = ["jaraco.packaging", "rst.linker", "sphinx"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -199,6 +373,20 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + [[package]] name = "jinja2" version = "3.1.2" @@ -216,6 +404,16 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "jstyleson" +version = "0.0.2" +description = "Library to parse JSON with js-style comments." +optional = false +python-versions = "*" +files = [ + {file = "jstyleson-0.0.2.tar.gz", hash = "sha256:680003f3b15a2959e4e6a351f3b858e3c07dd3e073a0d54954e34d8ea5e1308e"}, +] + [[package]] name = "lxml" version = "4.9.3" @@ -413,6 +611,22 @@ files = [ {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, ] +[[package]] +name = "mf2py" +version = "1.1.3" +description = "Python Microformats2 parser" +optional = false +python-versions = ">=2.7" +files = [ + {file = "mf2py-1.1.3-py3-none-any.whl", hash = "sha256:8f9e2c147beadd56f8839644124c7d141d96e879319b9f50d02826c88766bf4d"}, + {file = "mf2py-1.1.3.tar.gz", hash = "sha256:4241e91ed4b644dd666d9fbd2557ed86e5bb7399c196026f7b0a1f413b33f59f"}, +] + +[package.dependencies] +BeautifulSoup4 = ">=4.6.0" +html5lib = ">=1.0.1" +requests = ">=2.18.4" + [[package]] name = "mkdocs" version = "1.5.2" @@ -480,6 +694,17 @@ files = [ {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, ] +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + [[package]] name = "packaging" version = "23.1" @@ -571,6 +796,20 @@ files = [ markdown = ">=3.2" pyyaml = "*" +[[package]] +name = "pyparsing" +version = "3.1.1" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, + {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + [[package]] name = "pyquery" version = "2.0.0" @@ -589,6 +828,21 @@ lxml = ">=2.1" [package.extras] test = ["pytest", "pytest-cov", "requests", "webob", "webtest"] +[[package]] +name = "pyrdfa3" +version = "3.5.3" +description = "pyRdfa Libray" +optional = false +python-versions = "*" +files = [ + {file = "pyRdfa3-3.5.3-py3-none-any.whl", hash = "sha256:4da7ed49e8f524b573ed67e4f7bc7f403bff3be00546d7438fe263c924a91ccf"}, + {file = "pyRdfa3-3.5.3.tar.gz", hash = "sha256:157663a92b87df345b6f69bde235dff5f797891608e12fe1e4fa8dad687131ae"}, +] + +[package.dependencies] +html5lib = "*" +rdflib = "*" + [[package]] name = "pytest" version = "7.4.0" @@ -623,6 +877,17 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "pytz" +version = "2023.3" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, + {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, +] + [[package]] name = "pyyaml" version = "6.0.1" @@ -686,6 +951,27 @@ files = [ [package.dependencies] pyyaml = "*" +[[package]] +name = "rdflib" +version = "7.0.0" +description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." +optional = false +python-versions = ">=3.8.1,<4.0.0" +files = [ + {file = "rdflib-7.0.0-py3-none-any.whl", hash = "sha256:0438920912a642c866a513de6fe8a0001bd86ef975057d6962c79ce4771687cd"}, + {file = "rdflib-7.0.0.tar.gz", hash = "sha256:9995eb8569428059b8c1affd26b25eac510d64f5043d9ce8c84e0d0036e995ae"}, +] + +[package.dependencies] +isodate = ">=0.6.0,<0.7.0" +pyparsing = ">=2.1.0,<4" + +[package.extras] +berkeleydb = ["berkeleydb (>=18.1.0,<19.0.0)"] +html = ["html5lib (>=1.0,<2.0)"] +lxml = ["lxml (>=4.3.0,<5.0.0)"] +networkx = ["networkx (>=2.0.0,<3.0.0)"] + [[package]] name = "readtime" version = "3.0.0" @@ -841,6 +1127,20 @@ files = [ {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, ] +[[package]] +name = "strictyaml" +version = "1.7.3" +description = "Strict, typed YAML parser" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "strictyaml-1.7.3-py3-none-any.whl", hash = "sha256:fb5c8a4edb43bebb765959e420f9b3978d7f1af88c80606c03fb420888f5d1c7"}, + {file = "strictyaml-1.7.3.tar.gz", hash = "sha256:22f854a5fcab42b5ddba8030a0e4be51ca89af0267961c8d6cfa86395586c407"}, +] + +[package.dependencies] +python-dateutil = ">=2.6.0" + [[package]] name = "urllib3" version = "2.0.4" @@ -858,6 +1158,17 @@ secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17. socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "w3lib" +version = "2.1.2" +description = "Library of web-related functions" +optional = false +python-versions = ">=3.7" +files = [ + {file = "w3lib-2.1.2-py3-none-any.whl", hash = "sha256:c4432926e739caa8e3f49f5de783f336df563d9490416aebd5d39fb896d264e7"}, + {file = "w3lib-2.1.2.tar.gz", hash = "sha256:ed5b74e997eea2abe3c1321f916e344144ee8e9072a6f33463ee8e57f858a4b1"}, +] + [[package]] name = "watchdog" version = "3.0.0" @@ -897,7 +1208,18 @@ files = [ [package.extras] watchmedo = ["PyYAML (>=3.10)"] +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "63ccef1855b97a344b48b6da222efe60b755b721d62497ab56a8ea4fd8dc9593" +content-hash = "cb2df3b2bbaea132dccabda04169445e03b9b0509af3f4000150b11fda9d091c" diff --git a/pyproject.toml b/pyproject.toml index 7057244d..d2752421 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,10 +14,15 @@ pythoncz = "pythoncz:main" [tool.poetry.dependencies] python = "3.11.*" mkdocs = "1.5.2" -mkdocs-material = "^9.2.3" +mkdocs-material = "9.2.3" +strictyaml = "1.7.3" +ics = {version = "0.8.0.dev0", allow-prereleases = true} +extruct = "0.16.0" +pytz = "2023.3" [tool.poetry.group.dev.dependencies] pytest = "7.4.0" +black = "23.7.0" [tool.pytest.ini_options] python_files = "test_*.py" @@ -25,6 +30,11 @@ testpaths = "tests" norecursedirs = "node_modules" addopts = "--ff" +[tool.black] +target-versions = ["py311"] +include = "\\.py$" +exclude = "node_modules" + [build-system] requires = ["poetry-core>=1.5.0"] build-backend = "poetry.core.masonry.api" diff --git a/pythoncz/static/data/events_feeds.yml b/pythoncz/static/data/events_feeds.yml deleted file mode 100644 index 09a3f2ee..00000000 --- a/pythoncz/static/data/events_feeds.yml +++ /dev/null @@ -1,19 +0,0 @@ -feeds: - - name: Pyvo - url: https://pyvo.cz/ - ical: https://pyvo.cz/api/pyvo.ics - - name: PyWorking - url: https://pyworking.cz/ - ical: https://pyworking.cz/workshops.ics - -## Meetup.com iCal is not available, see https://github.com/pyvec/python.cz/issues/557 -# - name: PyWorking Sessions -# url: https://pyworking.cz/ -# ical: https://www.meetup.com/pyworking/events/ical/ -# - name: PyData Prague -# url: https://www.meetup.com/PyData-Prague/ -# ical: https://www.meetup.com/PyData-Prague/events/ical/ - - - name: Czech Python Events - url: https://calendar.google.com/calendar/embed?src=kfdeelic1a13jsp7jvai861vfs%40group.calendar.google.com&ctz=Europe%2FPrague - ical: https://calendar.google.com/calendar/ical/kfdeelic1a13jsp7jvai861vfs%40group.calendar.google.com/public/basic.ics From ec300645b797920a4fb60bccc5092473c458682e Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 12:54:42 +0200 Subject: [PATCH 12/46] reformat --- events.py | 108 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 42 deletions(-) diff --git a/events.py b/events.py index 5b825d2e..84dd15ac 100644 --- a/events.py +++ b/events.py @@ -14,78 +14,102 @@ YAML_SCHEMA = Seq( Map( { - 'name': Str(), - 'site_url': Url(), - 'url': Url(), - 'format': Str(), + "name": Str(), + "site_url": Url(), + "url": Url(), + "format": Str(), } ) ) -USER_AGENT = 'python.cz (+https://python.cz)' +USER_AGENT = "python.cz (+https://python.cz)" TIMELINE_LIMIT_DAYS = 60 -def on_post_build(config: Config | None=None): - cache_path = Path('.events_cache.json') +def on_post_build(config: Config | None = None): + cache_path = Path(".events_cache.json") try: - print(f'Loading events feeds from {cache_path}') + print(f"Loading events feeds from {cache_path}") data = json.loads(cache_path.read_text()) except FileNotFoundError: - print('No cache') - yaml = Path('events_feeds.yml').read_text() + print("No cache") + yaml = Path("events_feeds.yml").read_text() data = [] for feed in load_yaml(yaml, YAML_SCHEMA).data: print(f"Fetching {feed['url']}") - response = requests.get(feed['url'], headers={'User-Agent': USER_AGENT}) + response = requests.get(feed["url"], headers={"User-Agent": USER_AGENT}) response.raise_for_status() - feed['url'] = response.url # overwrite with the final URL - feed['data'] = response.text + feed["url"] = response.url # overwrite with the final URL + feed["data"] = response.text data.append(feed) cache_path.write_text(json.dumps(data, indent=2, ensure_ascii=False)) - print('Parsing events') + print("Parsing events") events = [] for feed in data: - if feed['format'] == 'icalendar': - events.extend([dict(feed=feed, **event_data) - for event_data in parse_icalendar(feed['data'])]) - elif feed['format'] == 'json-dl': - events.extend([dict(feed=feed, **event_data) - for event_data in parse_json_dl(feed['data'], feed['url'])]) + if feed["format"] == "icalendar": + events.extend( + [ + dict(feed=feed, **event_data) + for event_data in parse_icalendar(feed["data"]) + ] + ) + elif feed["format"] == "json-dl": + events.extend( + [ + dict(feed=feed, **event_data) + for event_data in parse_json_dl(feed["data"], feed["url"]) + ] + ) else: raise ValueError(f"Unknown feed format {feed['format']!r}") - print('Filtering and sorting events') + print("Filtering and sorting events") today = date.today() timeline_limit = today + timedelta(days=TIMELINE_LIMIT_DAYS) - events = sorted((event for event in events - if (event['starts_at'].date() >= today or (event['ends_at'] and event['ends_at'].date() >= today)) - and event['starts_at'].date() <= timeline_limit), - key=itemgetter('starts_at')) + events = sorted( + ( + event + for event in events + if ( + event["starts_at"].date() >= today + or (event["ends_at"] and event["ends_at"].date() >= today) + ) + and event["starts_at"].date() <= timeline_limit + ), + key=itemgetter("starts_at"), + ) for event in events: - print(event['starts_at'], event['name']) + print(event["starts_at"], event["name"]) def parse_icalendar(text: str): - return [dict(name=event.summary, - starts_at=to_prague_tz(event.begin), - ends_at=to_prague_tz(event.end) if event.end else None, - location_raw=event.location, - url=event.url) - for event in ics.Calendar(text).events] + return [ + dict( + name=event.summary, + starts_at=to_prague_tz(event.begin), + ends_at=to_prague_tz(event.end) if event.end else None, + location_raw=event.location, + url=event.url, + ) + for event in ics.Calendar(text).events + ] def parse_json_dl(html: str, base_url: str): - data = extruct.extract(html, base_url, syntaxes=['json-ld']) - return [dict(name=item['name'], - starts_at=to_prague_tz(datetime.fromisoformat(item['startDate'])), - ends_at=to_prague_tz(datetime.fromisoformat(item['endDate'])), - location_raw=parse_json_dl_location(item['location']), - url=item['url']) - for item in data['json-ld'] - if item['@type'] == 'Event' and base_url in item['url']] + data = extruct.extract(html, base_url, syntaxes=["json-ld"]) + return [ + dict( + name=item["name"], + starts_at=to_prague_tz(datetime.fromisoformat(item["startDate"])), + ends_at=to_prague_tz(datetime.fromisoformat(item["endDate"])), + location_raw=parse_json_dl_location(item["location"]), + url=item["url"], + ) + for item in data["json-ld"] + if item["@type"] == "Event" and base_url in item["url"] + ] def parse_json_dl_location(location: dict[str, str]) -> str: @@ -93,11 +117,11 @@ def parse_json_dl_location(location: dict[str, str]) -> str: def to_prague_tz(dt: datetime) -> datetime: - prague_tz = pytz.timezone('Europe/Prague') + prague_tz = pytz.timezone("Europe/Prague") if dt.tzinfo is None: return dt.replace(tzinfo=prague_tz) return dt.astimezone(prague_tz) -if __name__ == '__main__': +if __name__ == "__main__": on_post_build() From c1592c05f2edf0e85982426ecca986dae9578082 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 12:54:59 +0200 Subject: [PATCH 13/46] not needed --- events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/events.py b/events.py index 84dd15ac..9e998e7f 100644 --- a/events.py +++ b/events.py @@ -1,4 +1,4 @@ -from datetime import date, datetime, timedelta, timezone +from datetime import date, datetime, timedelta import json from operator import itemgetter from pathlib import Path From 913f05bfb08df7759ec6033a3a9ba85e81fd87cc Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 14:17:05 +0200 Subject: [PATCH 14/46] implement events --- .gitignore | 1 + README.md | 2 +- docs/akce.md | 18 ++++++++++++- docs/index.md | 16 ++++++++++- docs/zacatecnici.md | 2 +- hooks/__init__.py | 0 events.py => hooks/events.py | 51 +++++++++++++++++++++++++----------- hooks/on_page_markdown.py | 18 +++++++++++++ hooks/on_pre_build.py | 9 +++++++ mkdocs.yml | 5 +++- pyproject.toml | 4 --- 11 files changed, 102 insertions(+), 24 deletions(-) create mode 100644 hooks/__init__.py rename events.py => hooks/events.py (72%) create mode 100644 hooks/on_page_markdown.py create mode 100644 hooks/on_pre_build.py diff --git a/.gitignore b/.gitignore index 19f85a57..efc45ae4 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ pip-log.txt # custom .events_cache.json +overrides/events.ics diff --git a/README.md b/README.md index 0f49f18e..553c3a7f 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Intentionally not trying to achieve feature parity with existing python.cz websi - ~~port static content~~ - ~~customize the theme~~ -- events as a plugin +- ~~events as a plugin~~ - fix absolute links and make them relative - images - icons - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#additional-icons diff --git a/docs/akce.md b/docs/akce.md index 146ccf9a..6c4403eb 100644 --- a/docs/akce.md +++ b/docs/akce.md @@ -19,6 +19,22 @@ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na je . První URL z popisu události se zde zobrazí jako odkaz. -TODO - tohle je nejdůležitější část webu a musí být naprogramovaná a funkční +## Kalendář + +
    +{% for event in events %} +
  • + + {% if event.url %} + {{ event.name }} + {% else %} + {{ event.name }} + {% endif %} + +
    + {{ "{:%-d.%-m.%-Y}".format(event.starts_at) }} +
  • +{% endfor %} +
[iCal na všechny akce](/events.ics) diff --git a/docs/index.md b/docs/index.md index c7a1fed4..22d4fd89 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,7 +22,21 @@ Dobře se čte a dá se velice **rychle naučit**. Je skvělý pro **výuku** pr ## Nejbližší akce -TODO - tohle je nejdůležitější část webu a musí být naprogramovaná a funkční +
    +{% for event in events %} +
  • + + {% if event.url %} + {{ event.name }} + {% else %} + {{ event.name }} + {% endif %} + +
    + {{ "{:%-d.%-m.%-Y}".format(event.starts_at) }} +
  • +{% endfor %} +
## Odkazy diff --git a/docs/zacatecnici.md b/docs/zacatecnici.md index 681aac7f..a17cb72a 100644 --- a/docs/zacatecnici.md +++ b/docs/zacatecnici.md @@ -15,7 +15,7 @@ programovat od úplných základů kdokoliv. - [Materiály od PyLadies](http://naucse.python.cz/course/pyladies/) - [Návod od Django Girls](http://tutorial.djangogirls.org/) -## Online materiály – programovat trochu umím {#onlineumim} +## Online materiály – programovat trochu umím {: #onlineumim } ### Přecházím z jiného jazyka diff --git a/hooks/__init__.py b/hooks/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/events.py b/hooks/events.py similarity index 72% rename from events.py rename to hooks/events.py index 9e998e7f..ff1880da 100644 --- a/events.py +++ b/hooks/events.py @@ -2,11 +2,12 @@ import json from operator import itemgetter from pathlib import Path +import re +from functools import cache +from zoneinfo import ZoneInfo -import pytz import extruct import ics -from mkdocs.config import Config import requests from strictyaml import load as load_yaml, Map, Str, Seq, Url @@ -27,13 +28,14 @@ TIMELINE_LIMIT_DAYS = 60 -def on_post_build(config: Config | None = None): +@cache +def fetch_events() -> list[dict]: cache_path = Path(".events_cache.json") try: - print(f"Loading events feeds from {cache_path}") + print(f"INFO - Loading events feeds from {cache_path}") data = json.loads(cache_path.read_text()) except FileNotFoundError: - print("No cache") + print("INFO - No cache") yaml = Path("events_feeds.yml").read_text() data = [] for feed in load_yaml(yaml, YAML_SCHEMA).data: @@ -45,7 +47,7 @@ def on_post_build(config: Config | None = None): data.append(feed) cache_path.write_text(json.dumps(data, indent=2, ensure_ascii=False)) - print("Parsing events") + print("INFO - Parsing events") events = [] for feed in data: if feed["format"] == "icalendar": @@ -65,7 +67,7 @@ def on_post_build(config: Config | None = None): else: raise ValueError(f"Unknown feed format {feed['format']!r}") - print("Filtering and sorting events") + print("INFO - Filtering and sorting events") today = date.today() timeline_limit = today + timedelta(days=TIMELINE_LIMIT_DAYS) events = sorted( @@ -80,31 +82,43 @@ def on_post_build(config: Config | None = None): ), key=itemgetter("starts_at"), ) + return events + + +def generate_icalendar(events: list[dict]) -> str: + calendar = ics.Calendar() for event in events: - print(event["starts_at"], event["name"]) + calendar.events.append(ics.Event( + summary=event['name'], + begin=event['starts_at'], + end=event['ends_at'], + location=event['location'], + url=event['url'], + )) + return calendar.serialize() -def parse_icalendar(text: str): +def parse_icalendar(text: str) -> list[dict]: return [ dict( name=event.summary, starts_at=to_prague_tz(event.begin), ends_at=to_prague_tz(event.end) if event.end else None, - location_raw=event.location, - url=event.url, + location=event.location, + url=event.url if event.url else find_first_url(event.description), ) for event in ics.Calendar(text).events ] -def parse_json_dl(html: str, base_url: str): +def parse_json_dl(html: str, base_url: str) -> list[dict]: data = extruct.extract(html, base_url, syntaxes=["json-ld"]) return [ dict( name=item["name"], starts_at=to_prague_tz(datetime.fromisoformat(item["startDate"])), ends_at=to_prague_tz(datetime.fromisoformat(item["endDate"])), - location_raw=parse_json_dl_location(item["location"]), + location=parse_json_dl_location(item["location"]), url=item["url"], ) for item in data["json-ld"] @@ -117,11 +131,18 @@ def parse_json_dl_location(location: dict[str, str]) -> str: def to_prague_tz(dt: datetime) -> datetime: - prague_tz = pytz.timezone("Europe/Prague") + prague_tz = ZoneInfo("Europe/Prague") if dt.tzinfo is None: return dt.replace(tzinfo=prague_tz) return dt.astimezone(prague_tz) +def find_first_url(text: str) -> str | None: + if match := re.search(r'https?://[^\s"<]+', text or ''): + return match.group(0) + return None + + if __name__ == "__main__": - on_post_build() + from pprint import pprint + pprint(fetch_events(), depth=2) diff --git a/hooks/on_page_markdown.py b/hooks/on_page_markdown.py new file mode 100644 index 00000000..5262a489 --- /dev/null +++ b/hooks/on_page_markdown.py @@ -0,0 +1,18 @@ +from jinja2 import Environment +from mkdocs.config import Config +from mkdocs.structure.pages import Page +from mkdocs.structure.files import Files + +from hooks.events import fetch_events + + +def on_page_markdown( + markdown: str, + page: Page, + config: Config, + files: Files, +) -> str: + print(f'INFO - Rendering jinja on {page.file.src_path}') + env = Environment() + template = env.from_string(markdown) + return template.render(events=fetch_events()) diff --git a/hooks/on_pre_build.py b/hooks/on_pre_build.py new file mode 100644 index 00000000..9175d354 --- /dev/null +++ b/hooks/on_pre_build.py @@ -0,0 +1,9 @@ +from pathlib import Path +from mkdocs.config import Config + +from hooks.events import fetch_events, generate_icalendar + + +def on_pre_build(config: Config): + print('INFO - Generating events.ics') + Path('overrides/events.ics').write_text(generate_icalendar(fetch_events())) diff --git a/mkdocs.yml b/mkdocs.yml index dc1c3e5a..2192b06a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -26,6 +26,8 @@ theme: - toc.integrate - content.action.edit custom_dir: overrides + static_templates: + - events.ics icon: repo: fontawesome/brands/github edit_uri: edit/main/docs/ @@ -39,7 +41,8 @@ markdown_extensions: - md_in_html hooks: - - hooks.py + - hooks/on_pre_build.py + - hooks/on_page_markdown.py extra_css: - css/extra.css diff --git a/pyproject.toml b/pyproject.toml index d2752421..10a56b4c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,9 +8,6 @@ homepage = "https://python.cz/" repository = "https://github.com/honzajavorek/mkdocs-python.cz/" classifiers = ["Private :: Do Not Upload"] -[tool.poetry.scripts] -pythoncz = "pythoncz:main" - [tool.poetry.dependencies] python = "3.11.*" mkdocs = "1.5.2" @@ -18,7 +15,6 @@ mkdocs-material = "9.2.3" strictyaml = "1.7.3" ics = {version = "0.8.0.dev0", allow-prereleases = true} extruct = "0.16.0" -pytz = "2023.3" [tool.poetry.group.dev.dependencies] pytest = "7.4.0" From 68043fb78bfc0fe4b7390aa27d7c7d9fcec3e762 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 14:23:39 +0200 Subject: [PATCH 15/46] fix links --- README.md | 2 +- docs/prace.md | 12 ++++++------ docs/zacatecnici.md | 4 ++-- docs/zapojse.md | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 553c3a7f..e299e4a3 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Intentionally not trying to achieve feature parity with existing python.cz websi - ~~port static content~~ - ~~customize the theme~~ - ~~events as a plugin~~ -- fix absolute links and make them relative +- ~~fix absolute links and make them relative~~ - images - icons - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#additional-icons - localize the theme - https://www.mkdocs.org/user-guide/localizing-your-theme/ diff --git a/docs/prace.md b/docs/prace.md index a1de52e0..c3cbb1b5 100644 --- a/docs/prace.md +++ b/docs/prace.md @@ -20,11 +20,11 @@ TODO - zrušit seznam, dát sem sponzory PyConu a nějaký text, možná odkazy ## Jak najít práci? {: #poptavka } -- Přijď na [sraz](/#akce) a poptej se tam. -- Sleduj všechny [diskusní kanály](/#komunikace), kde se nabídky +- Přijď na [sraz](akce.md) a poptej se tam. +- Sleduj všechny [diskusní kanály](index.md), kde se nabídky objevují. - Na zmíněné kanály aktivně napiš, že hledáš práci nebo stáž. -- Zkus přímo oslovit [firmy výše](#kdo). +- Zkus přímo oslovit firmy výše. - Sleduj Twitter účet [@pyjobo](https://twitter.com/pyjobo) a pročítej [globální nástěnku nabídek](https://www.python.org/jobs/) – inzeráty lze hledat [podle @@ -44,7 +44,7 @@ TODO - zrušit seznam, dát sem sponzory PyConu a nějaký text, možná odkazy ## Jak najít Python programátory? {: #nabidka } -- Přijď na [sraz](/#akce) a poptej se tam. Promluv si s reálnými +- Přijď na [sraz](akce.md) a poptej se tam. Promluv si s reálnými lidmi, nadchni je, zlákej je, zjisti jaké mají možnosti a požadavky. - Popros svou společnost, aby sponzorovala příští [PyCon CZ](http://cz.pycon.org/) nebo [PyCon SK](http://pycon.sk/). Obě @@ -57,7 +57,7 @@ TODO - zrušit seznam, dát sem sponzory PyConu a nějaký text, možná odkazy poptáváme/nabízíme, tím více lidí to zaujme. **Nezapomeň napsat do jaké míry je možná práce na dálku.** - Napiš inzerát na diskuse django-cs a py.cz ([viz hlavní - stránka](/#komunikace)) a na [Facebookovou + stránka](index.md)) a na [Facebookovou skupinu](https://www.facebook.com/groups/pyonieri/). Čte je mnoho českých a slovenských Pythonistů. - Nepřehlcuj žádnou z diskusí. Inzeráty jsou vítány, jsou zadarmo a @@ -74,7 +74,7 @@ TODO - zrušit seznam, dát sem sponzory PyConu a nějaký text, možná odkazy ## Chci, aby bylo víc Pythonistů! {: #vic } **My taky!** Máme na to dokonce [neziskovku Pyvec](http://pyvec.org/). -Můžeš se [zapojit](/zapojse/) a s naší misí nám pomoci. +Můžeš se [zapojit](zapojse.md) a s naší misí nám pomoci. Pokud zastupuješ nějakou firmu, můžeš nás **sponzorovat ([číslo účtu](https://www.fio.cz/scgi-bin/hermes/dz-transparent.cgi?ID_ucet=2600260438))**. diff --git a/docs/zacatecnici.md b/docs/zacatecnici.md index a17cb72a..dd9bd047 100644 --- a/docs/zacatecnici.md +++ b/docs/zacatecnici.md @@ -2,7 +2,7 @@
Česká **komunita je přátelská a živá**. Vždy bude po ruce **někdo, kdo ti pomůže**. -**Nebudeš mít problém [sehnat práci](/prace/).** Pythonistů je nedostatek! +**Nebudeš mít problém [sehnat práci](prace.md).** Pythonistů je nedostatek! I kdyby weby vyšly z módy, Python nachází **uplatnění v desítkách dalších oborů**.
@@ -67,7 +67,7 @@ omrkni! ### Přednášky -Nahráváme přednášky ze [srazů](/#akce) a [dáváme je na YouTube](https://www.youtube.com/user/pyvec/playlists). Na stránkách +Nahráváme přednášky ze [srazů](akce.md) a [dáváme je na YouTube](https://www.youtube.com/user/pyvec/playlists). Na stránkách [pyvideo.org](http://pyvideo.org/) najdeš přednášky z celého světa. ### Konvence pro psaní kódu diff --git a/docs/zapojse.md b/docs/zapojse.md index 1f5c0dc4..75fb8d93 100644 --- a/docs/zapojse.md +++ b/docs/zapojse.md @@ -23,7 +23,7 @@ Srazy nebo workshopy dělají konkrétní lidé a Pyvec jim do toho nemluví - n - Koučuj pro [PyLadies](http://pyladies.cz/). - [Rozjeď kurz pro začátečníky podle našeho návodu](https://docs.pyvec.org/guides/beginners-course.html). Použij - a vylepšuj naše Open Source [materiály](/zacatecnici/#onlineneumim). + a vylepšuj naše Open Source [materiály](zacatecnici.md). - Přečti si [tipy na koučování od Django Girls](https://coach.djangogirls.org/). @@ -46,7 +46,7 @@ Srazy nebo workshopy dělají konkrétní lidé a Pyvec jim do toho nemluví - n - Technické články piš např. na [Zdroják.cz](http://zdrojak.cz/). Redakce bude nadšená a ty budeš mít větší publikum. - Python učíme podle Open Source - [materiálů](/zacatecnici/#onlineneumim). Můžeš nám pomoci je + [materiálů](zacatecnici.md). Můžeš nám pomoci je vylepšovat. - Když se nám povede něco zorganizovat, snažíme se sepsat naše know-how do [komunitní dokumentace](https://docs.pyvec.org/). Chybí From a77e22959a3c7a624e3c37269ed2c1590c5bb5d1 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 15:23:31 +0200 Subject: [PATCH 16/46] improve events --- README.md | 2 +- docs/akce.md | 8 +++++++- docs/css/extra.css | 4 ++++ docs/index.md | 16 +--------------- hooks/events.py | 37 +++++++++++++++++++++---------------- hooks/on_page_markdown.py | 6 ++++-- mkdocs.yml | 3 +++ 7 files changed, 41 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index e299e4a3..81427f40 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ Intentionally not trying to achieve feature parity with existing python.cz websi - ~~customize the theme~~ - ~~events as a plugin~~ - ~~fix absolute links and make them relative~~ +- ~~icons~~ (index is here: https://emojipedia.org/twitter) - images -- icons - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#additional-icons - localize the theme - https://www.mkdocs.org/user-guide/localizing-your-theme/ - legacy redirects - english version diff --git a/docs/akce.md b/docs/akce.md index 6c4403eb..42cad5c6 100644 --- a/docs/akce.md +++ b/docs/akce.md @@ -23,7 +23,7 @@ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na je
    {% for event in events %} -
  • + {% if event.url %} {{ event.name }} @@ -33,6 +33,12 @@ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na je
    {{ "{:%-d.%-m.%-Y}".format(event.starts_at) }} + {% if event.location %} +
    {{ event.location }} +
    + Mapy.cz + Google Mapy + {% endif %}
  • {% endfor %}
diff --git a/docs/css/extra.css b/docs/css/extra.css index fcdf8d7a..a17e244f 100644 --- a/docs/css/extra.css +++ b/docs/css/extra.css @@ -20,3 +20,7 @@ font-weight: 400; line-height: 1.6em; } + +.tentative { + opacity: 0.3; +} diff --git a/docs/index.md b/docs/index.md index 22d4fd89..75c758a1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,21 +22,7 @@ Dobře se čte a dá se velice **rychle naučit**. Je skvělý pro **výuku** pr ## Nejbližší akce -
    -{% for event in events %} -
  • - - {% if event.url %} - {{ event.name }} - {% else %} - {{ event.name }} - {% endif %} - -
    - {{ "{:%-d.%-m.%-Y}".format(event.starts_at) }} -
  • -{% endfor %} -
+Mrkni [sem](akce.md). ## Odkazy diff --git a/hooks/events.py b/hooks/events.py index ff1880da..83ce4b00 100644 --- a/hooks/events.py +++ b/hooks/events.py @@ -25,11 +25,9 @@ USER_AGENT = "python.cz (+https://python.cz)" -TIMELINE_LIMIT_DAYS = 60 - @cache -def fetch_events() -> list[dict]: +def fetch_events(days_limit: int | None=None, past: bool = False) -> list[dict]: cache_path = Path(".events_cache.json") try: print(f"INFO - Loading events feeds from {cache_path}") @@ -67,21 +65,25 @@ def fetch_events() -> list[dict]: else: raise ValueError(f"Unknown feed format {feed['format']!r}") - print("INFO - Filtering and sorting events") - today = date.today() - timeline_limit = today + timedelta(days=TIMELINE_LIMIT_DAYS) - events = sorted( - ( + print("INFO - Sorting events") + return sorted(events, key=itemgetter("starts_at")) + + +def filter_events(events: list[dict], days_limit: int | None=None, only_upcoming: bool = True, today: date | None = None) -> list[dict]: + today = today or date.today() + if only_upcoming: + events = [ event for event in events - if ( - event["starts_at"].date() >= today - or (event["ends_at"] and event["ends_at"].date() >= today) - ) - and event["starts_at"].date() <= timeline_limit - ), - key=itemgetter("starts_at"), - ) + if event["starts_at"].date() >= today + or (event["ends_at"] and event["ends_at"].date() >= today) + ] + if days_limit is not None: + events = [ + event + for event in events + if event["starts_at"].date() <= today + timedelta(days=days_limit) + ] return events @@ -94,6 +96,7 @@ def generate_icalendar(events: list[dict]) -> str: end=event['ends_at'], location=event['location'], url=event['url'], + categories=['tentative-date'] if event['is_tentative'] else [], )) return calendar.serialize() @@ -106,6 +109,7 @@ def parse_icalendar(text: str) -> list[dict]: ends_at=to_prague_tz(event.end) if event.end else None, location=event.location, url=event.url if event.url else find_first_url(event.description), + is_tentative='tentative-date' in event.categories, ) for event in ics.Calendar(text).events ] @@ -120,6 +124,7 @@ def parse_json_dl(html: str, base_url: str) -> list[dict]: ends_at=to_prague_tz(datetime.fromisoformat(item["endDate"])), location=parse_json_dl_location(item["location"]), url=item["url"], + is_tentative=False, ) for item in data["json-ld"] if item["@type"] == "Event" and base_url in item["url"] diff --git a/hooks/on_page_markdown.py b/hooks/on_page_markdown.py index 5262a489..ef283417 100644 --- a/hooks/on_page_markdown.py +++ b/hooks/on_page_markdown.py @@ -1,9 +1,10 @@ +from urllib.parse import urlencode from jinja2 import Environment from mkdocs.config import Config from mkdocs.structure.pages import Page from mkdocs.structure.files import Files -from hooks.events import fetch_events +from hooks.events import fetch_events, filter_events def on_page_markdown( @@ -14,5 +15,6 @@ def on_page_markdown( ) -> str: print(f'INFO - Rendering jinja on {page.file.src_path}') env = Environment() + env.filters['urlencode'] = urlencode template = env.from_string(markdown) - return template.render(events=fetch_events()) + return template.render(events=filter_events(fetch_events(), days_limit=60, only_upcoming=True)) diff --git a/mkdocs.yml b/mkdocs.yml index 2192b06a..e4f8c690 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -37,6 +37,9 @@ markdown_extensions: toc_depth: 2-2 permalink: '#' permalink_title: Odkaz na tuto sekci + - pymdownx.emoji: + emoji_index: !!python/name:pymdownx.emoji.twemoji + emoji_generator: !!python/name:pymdownx.emoji.to_svg - attr_list - md_in_html From ec0aca1912674335aef0fcaa7b2f1a7d6203a9ba Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 15:59:21 +0200 Subject: [PATCH 17/46] images --- README.md | 2 +- docs/akce.md | 12 +- docs/css/extra.css | 26 + .../images/czech-python-user-group.svg | 0 {pythoncz/static => docs}/images/jobs.svg | 0 .../images/learning-python-general.svg | 0 .../images/learning-python-web.svg | 0 .../images/learning-python.svg | 0 .../logo.svg => docs/images/python-logo.svg | 0 docs/images/{logo.svg => site-logo.svg} | 0 {pythoncz/static => docs}/images/ukulele.svg | 2 +- docs/index.md | 8 +- docs/prace.md | 4 + docs/zacatecnici.md | 4 + docs/zapojse.md | 4 + hooks/on_page_markdown.py | 4 +- mkdocs.yml | 2 +- .../static/images/learning-python-web.svg | 863 ------------------ 18 files changed, 60 insertions(+), 871 deletions(-) rename {pythoncz/static => docs}/images/czech-python-user-group.svg (100%) rename {pythoncz/static => docs}/images/jobs.svg (100%) rename {pythoncz/static => docs}/images/learning-python-general.svg (100%) rename pythoncz/static/images/learning-python-job.svg => docs/images/learning-python-web.svg (100%) rename {pythoncz/static => docs}/images/learning-python.svg (100%) rename pythoncz/static/images/logo.svg => docs/images/python-logo.svg (100%) rename docs/images/{logo.svg => site-logo.svg} (100%) rename {pythoncz/static => docs}/images/ukulele.svg (99%) delete mode 100644 pythoncz/static/images/learning-python-web.svg diff --git a/README.md b/README.md index 81427f40..93205a6a 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Intentionally not trying to achieve feature parity with existing python.cz websi - ~~events as a plugin~~ - ~~fix absolute links and make them relative~~ - ~~icons~~ (index is here: https://emojipedia.org/twitter) -- images +- ~~images~~ - localize the theme - https://www.mkdocs.org/user-guide/localizing-your-theme/ - legacy redirects - english version diff --git a/docs/akce.md b/docs/akce.md index 42cad5c6..e7997b39 100644 --- a/docs/akce.md +++ b/docs/akce.md @@ -4,6 +4,10 @@ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na jednom místě. +
+![Ilustrace hada hrajícího na ukulele](images/ukulele.svg) +
+ [Chci uspořádat sraz v mém městě](https://docs.pyvec.org/guides/meetup.html) ## Všechny akce {: #akce } @@ -36,8 +40,12 @@ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na je {% if event.location %}
{{ event.location }}
- Mapy.cz - Google Mapy + + Mapy.cz + + + Google Mapy + {% endif %} {% endfor %} diff --git a/docs/css/extra.css b/docs/css/extra.css index a17e244f..ee2094b2 100644 --- a/docs/css/extra.css +++ b/docs/css/extra.css @@ -15,6 +15,32 @@ padding-bottom: 2em; } +.md-typeset figure { + text-align: center; +} + +.md-typeset figure img { + margin: 1em auto; +} + +.md-typeset figure.md img { + max-width: 700px; +} + +.md-typeset figure.sm img { + max-width: 400px; +} + +.logo { + text-align: center; +} + +.logo img { + margin: 0; + width: 100%; + max-width: 700px; +} + .lead { font-size: 1.2em; font-weight: 400; diff --git a/pythoncz/static/images/czech-python-user-group.svg b/docs/images/czech-python-user-group.svg similarity index 100% rename from pythoncz/static/images/czech-python-user-group.svg rename to docs/images/czech-python-user-group.svg diff --git a/pythoncz/static/images/jobs.svg b/docs/images/jobs.svg similarity index 100% rename from pythoncz/static/images/jobs.svg rename to docs/images/jobs.svg diff --git a/pythoncz/static/images/learning-python-general.svg b/docs/images/learning-python-general.svg similarity index 100% rename from pythoncz/static/images/learning-python-general.svg rename to docs/images/learning-python-general.svg diff --git a/pythoncz/static/images/learning-python-job.svg b/docs/images/learning-python-web.svg similarity index 100% rename from pythoncz/static/images/learning-python-job.svg rename to docs/images/learning-python-web.svg diff --git a/pythoncz/static/images/learning-python.svg b/docs/images/learning-python.svg similarity index 100% rename from pythoncz/static/images/learning-python.svg rename to docs/images/learning-python.svg diff --git a/pythoncz/static/images/logo.svg b/docs/images/python-logo.svg similarity index 100% rename from pythoncz/static/images/logo.svg rename to docs/images/python-logo.svg diff --git a/docs/images/logo.svg b/docs/images/site-logo.svg similarity index 100% rename from docs/images/logo.svg rename to docs/images/site-logo.svg diff --git a/pythoncz/static/images/ukulele.svg b/docs/images/ukulele.svg similarity index 99% rename from pythoncz/static/images/ukulele.svg rename to docs/images/ukulele.svg index b92041e5..45fb70a1 100644 --- a/pythoncz/static/images/ukulele.svg +++ b/docs/images/ukulele.svg @@ -8,7 +8,7 @@ Created by potrace 1.13, written by Peter Selinger 2001-2015 +fill="#333333" stroke="none"> + Python v ČR +
Python je **moderní programovací jazyk**. Je **univerzální** – pohání weby i rakety. @@ -6,6 +8,10 @@ Dobře se čte a dá se velice **rychle naučit**. Je skvělý pro **výuku** pr **Česká komunita** je aktivní. Najdeš v ní **pomoc, kamarády i práci**.
+
+![česká Python komunita](images/czech-python-user-group.svg) +
+ ## Kde nás najdeš - [Skupina Pyonýři](https://www.facebook.com/groups/pyonieri/) diff --git a/docs/prace.md b/docs/prace.md index c3cbb1b5..defd66c0 100644 --- a/docs/prace.md +++ b/docs/prace.md @@ -6,6 +6,10 @@ skriptování, ale to neznamená, že jej nepoužívají firmy z celého světa nepíšou se v něm rozsáhlé projekty. +
+![Ilustrace hada v kanceláři](images/jobs.svg) +
+ ## Python ve světě Python používají např. **Blender 3D, YouTube, diff --git a/docs/zacatecnici.md b/docs/zacatecnici.md index dd9bd047..2a67dfda 100644 --- a/docs/zacatecnici.md +++ b/docs/zacatecnici.md @@ -6,6 +6,10 @@ I kdyby weby vyšly z módy, Python nachází **uplatnění v desítkách dalších oborů**. +
+![Ilustrace hada s knížkou](images/learning-python.svg) +
+ ## Online materiály – neumím vůbec programovat {: #onlineneumim } Následující materiály vznikly v rámci aktivit, které se snaží přiblížit diff --git a/docs/zapojse.md b/docs/zapojse.md index 75fb8d93..fa791ae7 100644 --- a/docs/zapojse.md +++ b/docs/zapojse.md @@ -4,6 +4,10 @@ Líbí se ti Python? **Pomoz nám ho rozšířit i mezi ostatní.** Můžeš nám poslat peníze, učit, přednášet, psát, organizovat, programovat, ale třeba i jen vymýšlet, co a jak by se dalo zlepšit. Máme práci pro každého! +
+![česká Python komunita](images/czech-python-user-group.svg) +
+ ## Proč? Python komunita je fajn jen díky tomu, že jsou v ní **lidi, kteří se nebojí přiložit ruku k dílu**. Všichni to děláme po večerech ve volném čase, z čirého nadšení. **Děláme to proto, že chceme, aby to bylo lepší i pro tebe.** Ať jsi profík nebo začátečník, z Prahy nebo z Karviné, můžeš nám pomoci. Odměnou ti budou kontakty, reference, zkušenosti. diff --git a/hooks/on_page_markdown.py b/hooks/on_page_markdown.py index ef283417..82a8a8c1 100644 --- a/hooks/on_page_markdown.py +++ b/hooks/on_page_markdown.py @@ -1,4 +1,4 @@ -from urllib.parse import urlencode +from urllib.parse import quote_plus from jinja2 import Environment from mkdocs.config import Config from mkdocs.structure.pages import Page @@ -15,6 +15,6 @@ def on_page_markdown( ) -> str: print(f'INFO - Rendering jinja on {page.file.src_path}') env = Environment() - env.filters['urlencode'] = urlencode + env.filters['urlencode'] = quote_plus template = env.from_string(markdown) return template.render(events=filter_events(fetch_events(), days_limit=60, only_upcoming=True)) diff --git a/mkdocs.yml b/mkdocs.yml index e4f8c690..44d25a3f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -13,7 +13,7 @@ nav: theme: name: material - logo: images/logo.svg + logo: images/site-logo.svg favicon: images/favicon.ico language: cs palette: diff --git a/pythoncz/static/images/learning-python-web.svg b/pythoncz/static/images/learning-python-web.svg deleted file mode 100644 index 2655e7ce..00000000 --- a/pythoncz/static/images/learning-python-web.svg +++ /dev/null @@ -1,863 +0,0 @@ - - - - -Created by potrace 1.13, written by Peter Selinger 2001-2015 - - - - - - - - - - - - - - - - - - - - From 5057809b64da93d3741606afa886b7581153acf4 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 17:02:30 +0200 Subject: [PATCH 18/46] analytics --- README.md | 1 - docs/css/extra.css | 4 +++- overrides/main.html | 7 +++++++ 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 overrides/main.html diff --git a/README.md b/README.md index 93205a6a..abfae3fe 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ Intentionally not trying to achieve feature parity with existing python.cz websi - ~~fix absolute links and make them relative~~ - ~~icons~~ (index is here: https://emojipedia.org/twitter) - ~~images~~ -- localize the theme - https://www.mkdocs.org/user-guide/localizing-your-theme/ - legacy redirects - english version - analytics - https://squidfunk.github.io/mkdocs-material/setup/setting-up-site-analytics/#custom-site-analytics diff --git a/docs/css/extra.css b/docs/css/extra.css index ee2094b2..114d7710 100644 --- a/docs/css/extra.css +++ b/docs/css/extra.css @@ -24,10 +24,12 @@ } .md-typeset figure.md img { - max-width: 700px; + max-height: 440px; + max-width: 704px; } .md-typeset figure.sm img { + max-height: 250px; max-width: 400px; } diff --git a/overrides/main.html b/overrides/main.html new file mode 100644 index 00000000..d41ba3ed --- /dev/null +++ b/overrides/main.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + +{% block scripts %} + {{ super() }} + + +{% endblock %} From 1abcee63cdf73924aeed166a5453c77068ecde72 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 18:39:44 +0200 Subject: [PATCH 19/46] format code --- hooks/events.py | 32 ++++++++++++++++++++------------ hooks/on_page_markdown.py | 8 +++++--- hooks/on_pre_build.py | 4 ++-- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/hooks/events.py b/hooks/events.py index 83ce4b00..86ba9618 100644 --- a/hooks/events.py +++ b/hooks/events.py @@ -27,7 +27,7 @@ @cache -def fetch_events(days_limit: int | None=None, past: bool = False) -> list[dict]: +def fetch_events(days_limit: int | None = None, past: bool = False) -> list[dict]: cache_path = Path(".events_cache.json") try: print(f"INFO - Loading events feeds from {cache_path}") @@ -69,7 +69,12 @@ def fetch_events(days_limit: int | None=None, past: bool = False) -> list[dict]: return sorted(events, key=itemgetter("starts_at")) -def filter_events(events: list[dict], days_limit: int | None=None, only_upcoming: bool = True, today: date | None = None) -> list[dict]: +def filter_events( + events: list[dict], + days_limit: int | None = None, + only_upcoming: bool = True, + today: date | None = None, +) -> list[dict]: today = today or date.today() if only_upcoming: events = [ @@ -90,14 +95,16 @@ def filter_events(events: list[dict], days_limit: int | None=None, only_upcoming def generate_icalendar(events: list[dict]) -> str: calendar = ics.Calendar() for event in events: - calendar.events.append(ics.Event( - summary=event['name'], - begin=event['starts_at'], - end=event['ends_at'], - location=event['location'], - url=event['url'], - categories=['tentative-date'] if event['is_tentative'] else [], - )) + calendar.events.append( + ics.Event( + summary=event["name"], + begin=event["starts_at"], + end=event["ends_at"], + location=event["location"], + url=event["url"], + categories=["tentative-date"] if event["is_tentative"] else [], + ) + ) return calendar.serialize() @@ -109,7 +116,7 @@ def parse_icalendar(text: str) -> list[dict]: ends_at=to_prague_tz(event.end) if event.end else None, location=event.location, url=event.url if event.url else find_first_url(event.description), - is_tentative='tentative-date' in event.categories, + is_tentative="tentative-date" in event.categories, ) for event in ics.Calendar(text).events ] @@ -143,11 +150,12 @@ def to_prague_tz(dt: datetime) -> datetime: def find_first_url(text: str) -> str | None: - if match := re.search(r'https?://[^\s"<]+', text or ''): + if match := re.search(r'https?://[^\s"<]+', text or ""): return match.group(0) return None if __name__ == "__main__": from pprint import pprint + pprint(fetch_events(), depth=2) diff --git a/hooks/on_page_markdown.py b/hooks/on_page_markdown.py index 82a8a8c1..cd55bfbf 100644 --- a/hooks/on_page_markdown.py +++ b/hooks/on_page_markdown.py @@ -13,8 +13,10 @@ def on_page_markdown( config: Config, files: Files, ) -> str: - print(f'INFO - Rendering jinja on {page.file.src_path}') + print(f"INFO - Rendering jinja on {page.file.src_path}") env = Environment() - env.filters['urlencode'] = quote_plus + env.filters["urlencode"] = quote_plus template = env.from_string(markdown) - return template.render(events=filter_events(fetch_events(), days_limit=60, only_upcoming=True)) + return template.render( + events=filter_events(fetch_events(), days_limit=60, only_upcoming=True) + ) diff --git a/hooks/on_pre_build.py b/hooks/on_pre_build.py index 9175d354..a2ade617 100644 --- a/hooks/on_pre_build.py +++ b/hooks/on_pre_build.py @@ -5,5 +5,5 @@ def on_pre_build(config: Config): - print('INFO - Generating events.ics') - Path('overrides/events.ics').write_text(generate_icalendar(fetch_events())) + print("INFO - Generating events.ics") + Path("overrides/events.ics").write_text(generate_icalendar(fetch_events())) From d94b732a65ea416bd4832659f4b002021d94bd8c Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 19:35:38 +0200 Subject: [PATCH 20/46] redirects --- .gitignore | 1 + hooks/on_post_build.py | 76 ++++++++++++++++++++++++++++++++++++++++++ hooks/on_pre_build.py | 2 +- mkdocs.yml | 1 + poetry.lock | 13 +------- pyproject.toml | 1 + 6 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 hooks/on_post_build.py diff --git a/.gitignore b/.gitignore index efc45ae4..9fb3d8d4 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ pip-log.txt # custom .events_cache.json overrides/events.ics +/talks_archive/ diff --git a/hooks/on_post_build.py b/hooks/on_post_build.py new file mode 100644 index 00000000..807312ab --- /dev/null +++ b/hooks/on_post_build.py @@ -0,0 +1,76 @@ +from io import BytesIO +from pathlib import Path +from zipfile import ZipFile +from mkdocs.config import Config +import requests + + +def on_post_build(config: Config): + site_dir = Path(config['site_dir']) + + print("INFO - Generating redirects") + # https://developers.google.com/search/docs/advanced/crawling/301-redirects + redirects = { + 'pyladies/s001-install/index.html': 'https://pyladies.cz/v1/s001-install/', + 'pyladies/s002-hello-world/index.html': 'https://pyladies.cz/v1/s002-hello-world/', + 'pyladies/s003-looping/index.html': 'https://pyladies.cz/v1/s003-looping/', + 'pyladies/s004-strings/index.html': 'https://pyladies.cz/v1/s004-strings/', + 'pyladies/s005-modules/index.html': 'https://pyladies.cz/v1/s005-modules/', + 'pyladies/s006-lists/index.html': 'https://pyladies.cz/v1/s006-lists/', + 'pyladies/s007-cards/index.html': 'https://pyladies.cz/v1/s007-cards/', + 'pyladies/s008-cards2/index.html': 'https://pyladies.cz/v1/s008-cards2/', + 'pyladies/s009-git/index.html': 'https://pyladies.cz/v1/s009-git/', + 'pyladies/s010-data/index.html': 'https://pyladies.cz/v1/s010-data/', + 'pyladies/s011-dicts/index.html': 'https://pyladies.cz/v1/s011-dicts/', + 'pyladies/s012-pyglet/index.html': 'https://pyladies.cz/v1/s012-pyglet/', + 'pyladies/s014-class/index.html': 'https://pyladies.cz/v1/s014-class/', + 'pyladies/s015-asteroids/index.html': 'https://pyladies.cz/v1/s015-asteroids/', + 'pyladies/s016-micropython/index.html': 'https://pyladies.cz/v1/s016-micropython/', + } + for src, dst in redirects.items(): + path = Path(f"{site_dir}/{src}") + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(f""" + + + + + Přesměrování + + + + + +

Přesměrování

+

To, co tady bylo, je teď jinde: {dst}

+ + + """.strip()) + + print("INFO - Generating talks archive redirects") + path = Path(f"{site_dir}/404.html") + path.write_text(""" + + + + + 404 + + + +

404

+ + + """.strip()) + diff --git a/hooks/on_pre_build.py b/hooks/on_pre_build.py index a2ade617..d8cc4b8d 100644 --- a/hooks/on_pre_build.py +++ b/hooks/on_pre_build.py @@ -6,4 +6,4 @@ def on_pre_build(config: Config): print("INFO - Generating events.ics") - Path("overrides/events.ics").write_text(generate_icalendar(fetch_events())) + Path(f"{config['theme'].dirs[0]}/events.ics").write_text(generate_icalendar(fetch_events())) diff --git a/mkdocs.yml b/mkdocs.yml index 44d25a3f..d1883a9f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -46,6 +46,7 @@ markdown_extensions: hooks: - hooks/on_pre_build.py - hooks/on_page_markdown.py + - hooks/on_post_build.py extra_css: - css/extra.css diff --git a/poetry.lock b/poetry.lock index 38c72698..b3cb13ae 100644 --- a/poetry.lock +++ b/poetry.lock @@ -877,17 +877,6 @@ files = [ [package.dependencies] six = ">=1.5" -[[package]] -name = "pytz" -version = "2023.3" -description = "World timezone definitions, modern and historical" -optional = false -python-versions = "*" -files = [ - {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, - {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, -] - [[package]] name = "pyyaml" version = "6.0.1" @@ -1222,4 +1211,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "cb2df3b2bbaea132dccabda04169445e03b9b0509af3f4000150b11fda9d091c" +content-hash = "7ce9107733e04473f1fd9a96ac0380206476b5ec61f238572a6a29d24fb6919b" diff --git a/pyproject.toml b/pyproject.toml index 10a56b4c..6cc4255b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ mkdocs-material = "9.2.3" strictyaml = "1.7.3" ics = {version = "0.8.0.dev0", allow-prereleases = true} extruct = "0.16.0" +requests = "2.31.0" [tool.poetry.group.dev.dependencies] pytest = "7.4.0" From 0bc6aeb3a8645d5c7836f3a0cf2c6edece9ada55 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 19:40:43 +0200 Subject: [PATCH 21/46] redirects --- hooks/on_post_build.py | 48 +++++++++++++++++++++--------------------- hooks/on_pre_build.py | 4 +++- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/hooks/on_post_build.py b/hooks/on_post_build.py index 807312ab..6ec381aa 100644 --- a/hooks/on_post_build.py +++ b/hooks/on_post_build.py @@ -1,36 +1,34 @@ -from io import BytesIO from pathlib import Path -from zipfile import ZipFile from mkdocs.config import Config -import requests def on_post_build(config: Config): - site_dir = Path(config['site_dir']) + site_dir = Path(config["site_dir"]) print("INFO - Generating redirects") # https://developers.google.com/search/docs/advanced/crawling/301-redirects redirects = { - 'pyladies/s001-install/index.html': 'https://pyladies.cz/v1/s001-install/', - 'pyladies/s002-hello-world/index.html': 'https://pyladies.cz/v1/s002-hello-world/', - 'pyladies/s003-looping/index.html': 'https://pyladies.cz/v1/s003-looping/', - 'pyladies/s004-strings/index.html': 'https://pyladies.cz/v1/s004-strings/', - 'pyladies/s005-modules/index.html': 'https://pyladies.cz/v1/s005-modules/', - 'pyladies/s006-lists/index.html': 'https://pyladies.cz/v1/s006-lists/', - 'pyladies/s007-cards/index.html': 'https://pyladies.cz/v1/s007-cards/', - 'pyladies/s008-cards2/index.html': 'https://pyladies.cz/v1/s008-cards2/', - 'pyladies/s009-git/index.html': 'https://pyladies.cz/v1/s009-git/', - 'pyladies/s010-data/index.html': 'https://pyladies.cz/v1/s010-data/', - 'pyladies/s011-dicts/index.html': 'https://pyladies.cz/v1/s011-dicts/', - 'pyladies/s012-pyglet/index.html': 'https://pyladies.cz/v1/s012-pyglet/', - 'pyladies/s014-class/index.html': 'https://pyladies.cz/v1/s014-class/', - 'pyladies/s015-asteroids/index.html': 'https://pyladies.cz/v1/s015-asteroids/', - 'pyladies/s016-micropython/index.html': 'https://pyladies.cz/v1/s016-micropython/', + "pyladies/s001-install/index.html": "https://pyladies.cz/v1/s001-install/", + "pyladies/s002-hello-world/index.html": "https://pyladies.cz/v1/s002-hello-world/", + "pyladies/s003-looping/index.html": "https://pyladies.cz/v1/s003-looping/", + "pyladies/s004-strings/index.html": "https://pyladies.cz/v1/s004-strings/", + "pyladies/s005-modules/index.html": "https://pyladies.cz/v1/s005-modules/", + "pyladies/s006-lists/index.html": "https://pyladies.cz/v1/s006-lists/", + "pyladies/s007-cards/index.html": "https://pyladies.cz/v1/s007-cards/", + "pyladies/s008-cards2/index.html": "https://pyladies.cz/v1/s008-cards2/", + "pyladies/s009-git/index.html": "https://pyladies.cz/v1/s009-git/", + "pyladies/s010-data/index.html": "https://pyladies.cz/v1/s010-data/", + "pyladies/s011-dicts/index.html": "https://pyladies.cz/v1/s011-dicts/", + "pyladies/s012-pyglet/index.html": "https://pyladies.cz/v1/s012-pyglet/", + "pyladies/s014-class/index.html": "https://pyladies.cz/v1/s014-class/", + "pyladies/s015-asteroids/index.html": "https://pyladies.cz/v1/s015-asteroids/", + "pyladies/s016-micropython/index.html": "https://pyladies.cz/v1/s016-micropython/", } for src, dst in redirects.items(): path = Path(f"{site_dir}/{src}") path.parent.mkdir(parents=True, exist_ok=True) - path.write_text(f""" + path.write_text( + f""" @@ -45,11 +43,13 @@ def on_post_build(config: Config):

To, co tady bylo, je teď jinde: {dst}

- """.strip()) + """.strip() + ) print("INFO - Generating talks archive redirects") path = Path(f"{site_dir}/404.html") - path.write_text(""" + path.write_text( + """ @@ -72,5 +72,5 @@ def on_post_build(config: Config):

404

- """.strip()) - + """.strip() + ) diff --git a/hooks/on_pre_build.py b/hooks/on_pre_build.py index d8cc4b8d..d48b4a32 100644 --- a/hooks/on_pre_build.py +++ b/hooks/on_pre_build.py @@ -6,4 +6,6 @@ def on_pre_build(config: Config): print("INFO - Generating events.ics") - Path(f"{config['theme'].dirs[0]}/events.ics").write_text(generate_icalendar(fetch_events())) + Path(f"{config['theme'].dirs[0]}/events.ics").write_text( + generate_icalendar(fetch_events()) + ) From 66e19651db08846d5c1943c9e2122975a7d2a125 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 21:07:26 +0200 Subject: [PATCH 22/46] english version --- README.md | 4 +- docs/akce.md | 6 ++- docs/css/extra.css | 29 +++++++++++++ docs/en.md | 85 +++++++++++++++++++++++++++++++++++++++ docs/index.md | 19 ++++++--- hooks/on_page_markdown.py | 6 +++ hooks/on_post_build.py | 2 + mkdocs.yml | 4 +- 8 files changed, 146 insertions(+), 9 deletions(-) create mode 100644 docs/en.md diff --git a/README.md b/README.md index abfae3fe..3b1d651d 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,9 @@ Intentionally not trying to achieve feature parity with existing python.cz websi - ~~fix absolute links and make them relative~~ - ~~icons~~ (index is here: https://emojipedia.org/twitter) - ~~images~~ -- legacy redirects +- ~~legacy redirects~~ +- ~~analytics~~ - english version -- analytics - https://squidfunk.github.io/mkdocs-material/setup/setting-up-site-analytics/#custom-site-analytics - social cards - https://squidfunk.github.io/mkdocs-material/setup/setting-up-social-cards/ - logo should be on a white circle diff --git a/docs/akce.md b/docs/akce.md index e7997b39..adf32ac2 100644 --- a/docs/akce.md +++ b/docs/akce.md @@ -8,7 +8,9 @@ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na je ![Ilustrace hada hrajícího na ukulele](images/ukulele.svg) + ## Všechny akce {: #akce } @@ -51,4 +53,6 @@ Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na je {% endfor %} -[iCal na všechny akce](/events.ics) + diff --git a/docs/css/extra.css b/docs/css/extra.css index 114d7710..f5957c43 100644 --- a/docs/css/extra.css +++ b/docs/css/extra.css @@ -11,6 +11,10 @@ margin-bottom: 1em; } +.md-grid { + max-width: 50rem; +} + .md-content { padding-bottom: 2em; } @@ -33,6 +37,31 @@ max-width: 400px; } +.md-typeset button.center { + display: block; + width: 100%; + text-align: center; +} + +.md-typeset button a { + display: inline-block; + margin: 1em auto; + padding: 0.5em 1em; + background-color: var(--md-primary-fg-color); + color: #fff; +} + +.md-typeset button a:hover, +.md-typeset button a:focus, +.md-typeset button a:active { + background-color: var(--md-accent-fg-color); + color: #fff; +} + +.md-typeset h1 .headerlink { + display: none; +} + .logo { text-align: center; } diff --git a/docs/en.md b/docs/en.md new file mode 100644 index 00000000..67b3a0bb --- /dev/null +++ b/docs/en.md @@ -0,0 +1,85 @@ +

+ ![Czech Python User Group](images/python-logo.svg) +

+ +
+Python is a modern programming language. See [python.org](https://python.org) for details. +The Czech Python community is **active and friendly**. +Come and **join us** at meetups and workshops in several cities! +
+ +
+![Czech Python User Group](images/czech-python-user-group.svg) +
+ +## Where you can find us? + +- [Pyonýři on Facebook](https://www.facebook.com/groups/pyonieri/) +- [Discord](https://discord.gg/yUbgArVAyF) +- [Email group](https://groups.google.com/group/django-cs/) +- [Email group at py.cz](http://www.py.cz/mailman/listinfo/python) +- [Pyvo meetups](https://twitter.com/naPyvo) +- [PyCon CZ](https://twitter.com/PyConCZ) +- [PyLadies CZ](https://twitter.com/PyLadiesCZ) +- [PyData Prague](https://twitter.com/PyDataPrague) +- [IRC #python-cs](irc://irc.freenode.net/python-cs) +- [IRC #django-cs](irc://irc.freenode.net/django-cs) +- [Slack for organizers](http://pyvec.slack.com/) + +## Events + +The events page are in Czech, but we believe the calendar is quite obvious even to someone who doesn't understand Czech. +English speakers are welcome to most of our events. + + + +## Links + +- [PyLadies CZ](https://pyladies.cz/) - There are events for ladies in multiple Czech cities. +- [Blog](http://blog.python.cz/) - TODO +- [PyCon CZ](http://cz.pycon.org/) - Czech Python conference! Help us with preparations, spread the word, register a talk or workshop, consider sponsorship, or just come and enjoy the event! +- [Knihovna](https://books.pyvo.cz/) - We have a library of Python-related books. If you want to borrow one, let us know, and come to the nearest [Pyvo meetup](#meetups) to pick the book up. By the way, you already know [Python Books](http://pythonbooks.revolunet.com/), right? + +## Jobs + +How can you address Czech software engineers working in Python with your +**job offer**? Why is it **worth the effort**? + +### How to find Czech Python software engineers? {#offer} + +- Attend a [meetup](/en/#meetups) and ask around. Speak to real + people, get them hooked for your ideas, learn about their options + and requirements. +- Ask your company to sponsor the next [PyCon + CZ](http://cz.pycon.org/) or [PyCon SK](http://pycon.sk/) + conferences. Both are unique opportunities to speak with 400+ + developers from the central-european region. +- Write down a job offer. **Honest story instead of boring bullet + points** will bring you larger audience. **Don\'t forget to mention + how much is it possible to work remotely.** +- Send the offer to django-cs and py.cz discussions (see + [homepage](/en/#communication)) and to the [Facebook + group](https://www.facebook.com/groups/pyonieri/). Many Czech + Pythonistas are subscribed to them. +- Please do not overuse any of the discussions. Job offers are + welcome, they\'re free and without limitations, but if it starts to + be annoying, it doesn\'t have to be without regulation forever. +- Post the offer to [global job + board](https://www.python.org/community/jobs/howto/) -- the board is + free, only registration is needed. The offer then appears also on + [@pyjobo](https://twitter.com/pyjobo) Twitter account. Advertise + also at Czech job boards: + [Jobs.cz](http://www.jobs.cz/prace/?q%5B%5D=python){target="_blank"}, + [StartupJobs.cz](https://www.startupjobs.cz/nabidky/15/python-programmer){target="_blank"}, + ... + +### I wish more Czech Pythonistas would exist! {#more} + +We too and it's also the main goal of [Pyvec](http://pyvec.org/), our +nonprofit. Pyvec is dedicated to support all sorts of activities focused +on introducing more people to Python in the Czech Republic. Pyvec also +supports local chapters of [PyLadies](http://pyladies.cz) and +[DjangoGirls](http://djangogirls.org). If you wish to sponsor our +activities, please drop an e-mail to . diff --git a/docs/index.md b/docs/index.md index 9e634d0b..24bcd5ba 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,5 +1,11 @@ -

- Python v ČR +--- +hide: + - toc + - navigation +--- + +

+ ![Python v ČR](images/python-logo.svg)

@@ -26,12 +32,15 @@ Dobře se čte a dá se velice **rychle naučit**. Je skvělý pro **výuku** pr - [IRC #django-cs](irc://irc.freenode.net/django-cs) - [Slack pro organizátory](http://pyvec.slack.com/) -## Nejbližší akce +## Akce -Mrkni [sem](akce.md). + ## Odkazy +- [PyLadies CZ](https://pyladies.cz/) - TODO - [Blog](http://blog.python.cz/) - Díky blogu se **dovíš o všem, co se v české Python komunitě zrovna děje**. A co je nejlepší – můžeš klidně přidat svůj vlastní článek! - [PyCon CZ](http://cz.pycon.org/) - Česká Python konference! Pomoz nám s přípravami, propagací, zkus si přihlásit přednášku nebo workshop, sponzoruj nás, nebo prostě jen přijď a akci si užij! -- [Knihovna](https://books.pyvo.cz/) - Máme knihovničku s literaturou o Pythonu a podobných technologiích. Knihy si lze **zdarma půjčit** – ozvi se a přijď si knížku vyzvednout na nejbližším [srazu](akce.md). Mimochodem, [Python Books](http://pythonbooks.revolunet.com/) znáš, že? +- [Knihovna](https://books.pyvo.cz/) - Máme knihovničku s literaturou o Pythonu a podobných technologiích. Knihy si lze **zdarma půjčit** – ozvi se a přijď si knížku vyzvednout na nejbližším [srazu](akce.md). Mimochodem, [Python Books](http://pythonbooks.revolunet.com/) znáš, že? diff --git a/hooks/on_page_markdown.py b/hooks/on_page_markdown.py index cd55bfbf..eeb7d8a7 100644 --- a/hooks/on_page_markdown.py +++ b/hooks/on_page_markdown.py @@ -13,6 +13,12 @@ def on_page_markdown( config: Config, files: Files, ) -> str: + # Unfortunately this is aparently the only way to hide the navigation + # on every page using the material theme. Solution described in + # https://github.com/squidfunk/mkdocs-material/issues/3686 breaks + # hamburger menu on small viewports. + page.meta["hide"] = ["toc", "navigation"] + print(f"INFO - Rendering jinja on {page.file.src_path}") env = Environment() env.filters["urlencode"] = quote_plus diff --git a/hooks/on_post_build.py b/hooks/on_post_build.py index 6ec381aa..e3b5d289 100644 --- a/hooks/on_post_build.py +++ b/hooks/on_post_build.py @@ -8,6 +8,8 @@ def on_post_build(config: Config): print("INFO - Generating redirects") # https://developers.google.com/search/docs/advanced/crawling/301-redirects redirects = { + "en/jobs/index.html": "https://python.cz/en/", + "en/events/index.html": "https://python.cz/akce/", "pyladies/s001-install/index.html": "https://pyladies.cz/v1/s001-install/", "pyladies/s002-hello-world/index.html": "https://pyladies.cz/v1/s002-hello-world/", "pyladies/s003-looping/index.html": "https://pyladies.cz/v1/s003-looping/", diff --git a/mkdocs.yml b/mkdocs.yml index d1883a9f..9a3315dc 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,6 +10,7 @@ nav: - Pro začátečníky: zacatecnici.md - Práce: prace.md - Zapoj se!: zapojse.md + - English: en.md theme: name: material @@ -21,9 +22,10 @@ theme: accent: custom font: false features: + - navigation.instant + - navigation.tracking - navigation.tabs - navigation.tabs.sticky - - toc.integrate - content.action.edit custom_dir: overrides static_templates: From 322f2b2790981a60cc10826002ff6b153057eb7b Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 21:48:24 +0200 Subject: [PATCH 23/46] fixes --- docs/css/extra.css | 1 + docs/en.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/css/extra.css b/docs/css/extra.css index f5957c43..6be81532 100644 --- a/docs/css/extra.css +++ b/docs/css/extra.css @@ -24,6 +24,7 @@ } .md-typeset figure img { + width: 100%; margin: 1em auto; } diff --git a/docs/en.md b/docs/en.md index 67b3a0bb..a7d50176 100644 --- a/docs/en.md +++ b/docs/en.md @@ -47,7 +47,7 @@ English speakers are welcome to most of our events. How can you address Czech software engineers working in Python with your **job offer**? Why is it **worth the effort**? -### How to find Czech Python software engineers? {#offer} +### How to find Czech Python software engineers? {: #offer } - Attend a [meetup](/en/#meetups) and ask around. Speak to real people, get them hooked for your ideas, learn about their options @@ -75,7 +75,7 @@ How can you address Czech software engineers working in Python with your [StartupJobs.cz](https://www.startupjobs.cz/nabidky/15/python-programmer){target="_blank"}, ... -### I wish more Czech Pythonistas would exist! {#more} +### I wish more Czech Pythonistas would exist! {: #more } We too and it's also the main goal of [Pyvec](http://pyvec.org/), our nonprofit. Pyvec is dedicated to support all sorts of activities focused From a346fd0e4ec3bd0a76d0a1bb0d464495e14529dd Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 22:14:04 +0200 Subject: [PATCH 24/46] delete the old code --- README.md | 8 +- pythoncz/__init__.py | 47 - pythoncz/models/__init__.py | 0 pythoncz/models/beginners.py | 14 - pythoncz/models/events.py | 92 -- pythoncz/models/github.py | 169 --- pythoncz/models/github_get_issues.graphql | 77 -- pythoncz/models/jobs.py | 65 - pythoncz/models/meetups.py | 90 -- pythoncz/static/data/beginners.yml | 54 - pythoncz/static/data/business.geojson | 1437 --------------------- pythoncz/static/data/jobs.yml | 20 - pythoncz/static/favicon.ico | Bin 15086 -> 0 bytes pythoncz/static/images/404.png | Bin 50516 -> 0 bytes pythoncz/static/images/icon.png | Bin 721 -> 0 bytes pythoncz/static/images/logo-fb.png | Bin 5530 -> 0 bytes pythoncz/static/images/logo-plain.png | Bin 179155 -> 0 bytes pythoncz/static/images/pyvo.png | Bin 5543 -> 0 bytes pythoncz/static/images/uk-flag.svg | 10 - pythoncz/static/main.css | 725 ----------- pythoncz/static/maps.js | 42 - pythoncz/static/permalinks.js | 27 - pythoncz/templates/404.html | 13 - pythoncz/templates/_base.html | 141 -- pythoncz/templates/_communication.html | 93 -- pythoncz/templates/_events.html | 61 - pythoncz/templates/_meetups.html | 7 - pythoncz/templates/beginners_cs.html | 234 ---- pythoncz/templates/events_cs.html | 81 -- pythoncz/templates/events_en.html | 73 -- pythoncz/templates/get_involved_cs.html | 259 ---- pythoncz/templates/index_cs.html | 180 --- pythoncz/templates/index_en.html | 150 --- pythoncz/templates/jobs_cs.html | 154 --- pythoncz/templates/jobs_en.html | 113 -- pythoncz/templates/meta_redirect.html | 19 - pythoncz/views.py | 242 ---- runserver.py | 7 - 38 files changed, 5 insertions(+), 4699 deletions(-) delete mode 100644 pythoncz/__init__.py delete mode 100644 pythoncz/models/__init__.py delete mode 100644 pythoncz/models/beginners.py delete mode 100644 pythoncz/models/events.py delete mode 100644 pythoncz/models/github.py delete mode 100644 pythoncz/models/github_get_issues.graphql delete mode 100644 pythoncz/models/jobs.py delete mode 100644 pythoncz/models/meetups.py delete mode 100644 pythoncz/static/data/beginners.yml delete mode 100644 pythoncz/static/data/business.geojson delete mode 100644 pythoncz/static/data/jobs.yml delete mode 100644 pythoncz/static/favicon.ico delete mode 100644 pythoncz/static/images/404.png delete mode 100644 pythoncz/static/images/icon.png delete mode 100644 pythoncz/static/images/logo-fb.png delete mode 100644 pythoncz/static/images/logo-plain.png delete mode 100644 pythoncz/static/images/pyvo.png delete mode 100644 pythoncz/static/images/uk-flag.svg delete mode 100644 pythoncz/static/main.css delete mode 100644 pythoncz/static/maps.js delete mode 100644 pythoncz/static/permalinks.js delete mode 100644 pythoncz/templates/404.html delete mode 100644 pythoncz/templates/_base.html delete mode 100644 pythoncz/templates/_communication.html delete mode 100644 pythoncz/templates/_events.html delete mode 100644 pythoncz/templates/_meetups.html delete mode 100644 pythoncz/templates/beginners_cs.html delete mode 100644 pythoncz/templates/events_cs.html delete mode 100644 pythoncz/templates/events_en.html delete mode 100644 pythoncz/templates/get_involved_cs.html delete mode 100644 pythoncz/templates/index_cs.html delete mode 100644 pythoncz/templates/index_en.html delete mode 100644 pythoncz/templates/jobs_cs.html delete mode 100644 pythoncz/templates/jobs_en.html delete mode 100644 pythoncz/templates/meta_redirect.html delete mode 100644 pythoncz/views.py delete mode 100755 runserver.py diff --git a/README.md b/README.md index 3b1d651d..ef020242 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,11 @@ Intentionally not trying to achieve feature parity with existing python.cz websi - ~~images~~ - ~~legacy redirects~~ - ~~analytics~~ -- english version -- social cards - https://squidfunk.github.io/mkdocs-material/setup/setting-up-social-cards/ -- logo should be on a white circle +- ~~english version~~ +- ~~delete the old code~~ +- keep tests which make sense and delete the rest +- nice to have: social cards - https://squidfunk.github.io/mkdocs-material/setup/setting-up-social-cards/ +- nice to have: logo should be on a white circle ## License diff --git a/pythoncz/__init__.py b/pythoncz/__init__.py deleted file mode 100644 index 89c65a3f..00000000 --- a/pythoncz/__init__.py +++ /dev/null @@ -1,47 +0,0 @@ -import os - -import yaml -from flask import Flask -from flask_frozen import Freezer - - -ROOT_DIR = os.path.join(os.path.dirname(__file__), '..') - -GITHUB_URL = 'https://github.com/pyvec/python.cz' -GITHUB_EDIT_URL = GITHUB_URL + '/edit/master/pythoncz' - -TEMPLATES_DIR_URL = GITHUB_EDIT_URL + '/templates/' -BUSINESS_LIST_URL = GITHUB_EDIT_URL + '/static/data/business.geojson' -BEGINNERS_DATA_URL = GITHUB_EDIT_URL + '/static/data/beginners.yml' -EVENTS_DATA_URL = GITHUB_EDIT_URL + '/static/data/events_feeds.yml' -JOBS_DATA_URL = GITHUB_EDIT_URL + '/static/data/jobs.yml' - -PYVEC_ACCOUNT_URL = ( - 'https://www.fio.cz/scgi-bin/hermes/' - 'dz-transparent.cgi?ID_ucet=2600260438' -) -GET_INVOLVED_URL = ( - 'https://github.com/pulls?utf8=%E2%9C%93&q=is%3Aopen+org%3Apyvec' -) - -GITHUB_ORGANIZATIONS = ('pyvec', 'pyladiescz') -GITHUB_TOKEN = os.getenv('GITHUB_TOKEN') or os.getenv('GH_TOKEN') -CACHE_DIR = os.getenv('CACHE_DIR') or os.path.join(ROOT_DIR, 'cache') - - -app = Flask('pythoncz') - - -with open(os.path.join(app.static_folder, 'data', 'events_feeds.yml')) as f: - app.config['CZECH_PYTHON_EVENTS_CALENDAR_URL'] = next(filter( - lambda feed: feed['name'] == 'Czech Python Events', - yaml.safe_load(f.read())['feeds'] - ))['url'] - - -freezer = Freezer(app) - -app.config.from_object(__name__) - - -from . import views # NOQA diff --git a/pythoncz/models/__init__.py b/pythoncz/models/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/pythoncz/models/beginners.py b/pythoncz/models/beginners.py deleted file mode 100644 index f3efef6a..00000000 --- a/pythoncz/models/beginners.py +++ /dev/null @@ -1,14 +0,0 @@ -import os - -import yaml - -from .. import app - - -__all__ = ('data',) - - -# Data loaded on import time so file system is not read and YAML parsed -# on every request. -with open(os.path.join(app.static_folder, 'data', 'beginners.yml')) as f: - data = yaml.safe_load(f.read()) diff --git a/pythoncz/models/events.py b/pythoncz/models/events.py deleted file mode 100644 index a1238999..00000000 --- a/pythoncz/models/events.py +++ /dev/null @@ -1,92 +0,0 @@ -import re -from pathlib import Path -from typing import List - -import yaml -import requests -import ics -import arrow - -from pythoncz import app - - -feeds_datafile = Path(app.root_path) / "static/data/events_feeds.yml" -data = [] - - -def preprocess_ical(text: str) -> str: - """Removes VALARM ACTION:NONE from the iCal file (included in some events from Google Calendar) - """ - lines = text.splitlines() - new_lines = [] - - i = 0 - - try: - while i < len(lines): - if lines[i] != "BEGIN:VALARM" or lines[i + 1].replace("ACTION:", "") in {"DISPLAY", "AUDIO"}: - new_lines.append(lines[i]) - i += 1 - continue - - while lines[i] != "END:VALARM": - i += 1 - - i += 1 - except IndexError: - raise ValueError("Can't preprocess iCal file to remove ACTION:NONE") - - return '\r\n'.join(new_lines) - - -def load_events(ical_url): - try: - response = requests.get(ical_url) - - response.raise_for_status() - except Exception as e: - raise ValueError(f"Could not load iCal feed from {ical_url}") from e - - text = preprocess_ical(response.text) - - calendar = ics.Calendar(text) - - return calendar.events - - -def find_first_url(text): - match = re.search(r'https?://\S+', text or '') - if match: - return match.group(0) - return None - - -def set_url_from_description(event): - if not event.url: - url = find_first_url(event.description) - if url: - event.url = url - return event - - -@app.before_first_request -def load_data(): - feeds = yaml.safe_load(feeds_datafile.read_text())["feeds"] - - now = arrow.now("Europe/Prague") - for feed in feeds: - data.extend( - {"feed": feed, "event": set_url_from_description(event)} - for event in load_events(feed["ical"]) - if event.begin > now - ) - - data.sort(key=lambda e: e["event"].begin) - - -def get_calendar(): - calendar = ics.Calendar() - for e in data: - calendar.events.add(e["event"]) - - return calendar diff --git a/pythoncz/models/github.py b/pythoncz/models/github.py deleted file mode 100644 index b4417981..00000000 --- a/pythoncz/models/github.py +++ /dev/null @@ -1,169 +0,0 @@ -import os -import itertools -import warnings -from datetime import datetime - -import requests -from cachelib import FileSystemCache - -from pythoncz import app - - -__all__ = ('get_issues',) - - -get_issues_graphql_filename = ( - os.path.join(os.path.dirname(__file__), 'github_get_issues.graphql') -) -with open(get_issues_graphql_filename) as f: - GET_ISSUES_GRAPHQL = f.read() - -SIX_HOURS_AS_SECONDS = 21600 - - -cache = FileSystemCache(app.config['CACHE_DIR'], - default_timeout=SIX_HOURS_AS_SECONDS) - - -def get_issues(org_names): - issues = cache.get('github-issues') - if issues is None: - session = _create_api_session() - issues = itertools.chain(*( - _get_issues_for_org(session, org_name) for org_name in org_names) - ) - issues = _sort_issues(issues) - cache.set('github-issues', issues) - return issues - - -def _create_api_session(): - user_agent = ('pythoncz/{now.year}-{now.month} ' - '(+https://python.cz)').format(now=datetime.now()) - - session = requests.Session() - token = app.config['GITHUB_TOKEN'] - if not token: - raise Exception('GITHUB_TOKEN not configured') - session.headers.update({ - 'User-Agent': user_agent, - 'Authorization': 'token {}'.format(token), - }) - return session - - -def _get_issues_for_org(session, org_name): - json = _request_api(session, GET_ISSUES_GRAPHQL, {'org_name': org_name}) - try: - organization = json['data']['organization'] - repositories = _get_nodes(organization, 'repositories') - - for repository in repositories: - if repository['isPrivate']: - continue - - for issue in _get_nodes(repository, 'issues'): - yield _format_issue(org_name, repository, issue) - - for pull_request in _get_nodes(repository, 'pullRequests'): - yield _format_issue(org_name, repository, pull_request, - is_pull_request=True) - except KeyError as e: - raise ValueError( - 'Unexpected structure of the GitHub API response: {}'.format(e) - ) - - -def _request_api(session, query, variables): - res = session.post('https://api.github.com/graphql', json={ - 'query': query, - 'variables': variables, - }) - try: - json = res.json() - except ValueError as e: - res.raise_for_status() - raise ValueError( - 'Unexpected structure of the GitHub API response: {}'.format(e) - ) - if json.get('errors'): - message = '; '.join(error['message'] for error in json['errors']) - raise requests.HTTPError(message, response=res) - res.raise_for_status() - return json - - -def _format_issue(org_name, repository, issue, is_pull_request=False): - author = issue['author'] or { - 'login': None, - 'url': 'https://github.com/ghost', - } - labels = [label['name'] for label in _get_nodes(issue, 'labels')] - - return { - 'title': issue['title'], - 'html_url': issue['url'], - 'updated_at': issue['updatedAt'], - 'user': { - 'login': author['login'], - 'html_url': author['url'], - }, - 'is_pull_request': is_pull_request, - 'repository_name': repository['name'], - 'repository_url_html': repository['url'], - 'organization_name': org_name, - 'comments': issue['comments']['totalCount'], - 'participants': issue['participants']['totalCount'], - 'votes': _calculate_votes(issue), - 'labels': labels, - 'coach': 'coach' in labels, - 'sprint-idea': 'sprint-idea' in labels, - } - - -def _calculate_votes(issue): - """Get votes per issue from counts of Reactions - - A THUMBS_DOWN and CONFUSED counts as "-1", the rest as "+1". - """ - # First, count *all* reactions as "+1" - score = issue['reactions']['totalCount'] - - # Then change the negative ones from "+1" to "-1" - # (subtract 2 for each negative reaction) - score -= issue['thumbs_down']['totalCount'] * 2 - score -= issue['confuseds']['totalCount'] * 2 - - return score - - -def _get_nodes(node, connection_name): - connection_nodes = node[connection_name]['nodes'] - - if 'totalCount' in node[connection_name]: - connection_nodes_count = len(connection_nodes) - connection_nodes_total_count = node[connection_name]['totalCount'] - - if connection_nodes_count < connection_nodes_total_count: - warnings.warn(( - "The '{}' contain {} nodes in total, but only {} was fetched" - ).format( - connection_name, - connection_nodes_total_count, - connection_nodes_count, - ), UserWarning) - - return connection_nodes - - -def _sort_issues(issues): - return sorted(issues, key=_get_issue_sort_key, reverse=True) - - -def _get_issue_sort_key(issue): - return ( - issue['coach'], - issue['votes'], - issue['comments'] + issue['participants'], - issue['updated_at'], - ) diff --git a/pythoncz/models/github_get_issues.graphql b/pythoncz/models/github_get_issues.graphql deleted file mode 100644 index ba4f1bef..00000000 --- a/pythoncz/models/github_get_issues.graphql +++ /dev/null @@ -1,77 +0,0 @@ -query($org_name:String!) { - organization(login:$org_name) { - repositories(first:10, isLocked:false, privacy:PUBLIC, orderBy:{direction:DESC, field:PUSHED_AT}) { - totalCount - nodes { - name - nameWithOwner - isPrivate - url - issues(first:20, states:OPEN, orderBy:{direction:DESC, field:UPDATED_AT}) { - totalCount - nodes { - title - url - updatedAt - author { - login - url - } - labels(first:5) { - nodes { - name - } - } - reactions { - totalCount - } - thumbs_down:reactions(content:THUMBS_DOWN) { - totalCount - } - confuseds:reactions(content:CONFUSED) { - totalCount - } - comments { - totalCount - } - participants { - totalCount - } - } - } - pullRequests(first:20, states:OPEN, orderBy:{direction:DESC, field:UPDATED_AT}) { - totalCount - nodes { - title - url - updatedAt - author { - login - url - } - labels(first:5) { - nodes { - name - } - } - reactions { - totalCount - } - thumbs_down:reactions(content:THUMBS_DOWN) { - totalCount - } - confuseds:reactions(content:CONFUSED) { - totalCount - } - comments { - totalCount - } - participants { - totalCount - } - } - } - } - } - } -} diff --git a/pythoncz/models/jobs.py b/pythoncz/models/jobs.py deleted file mode 100644 index 0873e4ca..00000000 --- a/pythoncz/models/jobs.py +++ /dev/null @@ -1,65 +0,0 @@ -import os -import json - -import yaml -import czech_sort - -from pythoncz import app - - -__all__ = ('data',) - - -def _group_business_data(data): - groups = {} - for point in data: - if point.get('company'): - name = 'companies' - else: - name = 'individuals' - - groups.setdefault(name, []) - groups[name].append(point) - - for name, group in groups.items(): - groups[name] = _sort_cs(group) - - return groups - - -def _load_business_data(data_file): - with open(data_file) as f: - data = json.load(f) - - for feature in data['features']: - point = feature['properties'] - - geometry = feature.get('geometry') - if geometry: - point['coordinates'] = geometry['coordinates'] - - yield point - - -def _sort_cs(iterable, key='name'): - def item_key(item): - return czech_sort.key(item[key]) - return sorted(iterable, key=item_key) - - -# Data loaded on import time so file system is not read and YAML parsed -# on every request. - - -# jobs.yml -_path = os.path.join(app.static_folder, 'data', 'jobs.yml') -with open(os.path.join(_path)) as f: - data = yaml.safe_load(f.read()) - -data['job_boards'] = _sort_cs(data['job_boards']) -data['knowledge_tests'] = _sort_cs(data['knowledge_tests']) - - -# business.geojson -_path = os.path.join(app.static_folder, 'data', 'business.geojson') -data['business_groups'] = _group_business_data(_load_business_data(_path)) diff --git a/pythoncz/models/meetups.py b/pythoncz/models/meetups.py deleted file mode 100644 index ce28f6b2..00000000 --- a/pythoncz/models/meetups.py +++ /dev/null @@ -1,90 +0,0 @@ -from functools import lru_cache -from lxml import html -import requests -from slugify import slugify - - -__all__ = ('get_meetups',) - - -# Source: https://cs.wikipedia.org/wiki/Seznam_m%C4%9Bst_v_%C4%8Cesku_podle_po%C4%8Dtu_obyvatel -SORTED_CITY_SLUGS = [ - 'praha-pyvo', - 'brno-pyvo', - 'ostrava-pyvo', - 'plzen-pyvo', - 'liberec-pyvo', - 'olomouc-pyvo', - 'ceske-budejovice-pyvo', - 'usti-nad-labem-pyvo', - 'hradec-pyvo', - 'pardubice-pyvo', - 'zlin-pyvo', - 'havirov-pyvo', - 'kladno-pyvo', - 'most-pyvo', - 'opava-pyvo', - 'frydek-mistek-pyvo', - 'karvina-pyvo', - 'jihlava-pyvo', - 'teplice-pyvo', - 'decin-pyvo', - 'karlovy-vary-pyvo', -] - - -@lru_cache() -def get_meetups(lang='cs'): - return sort_by_city_size(scrape_meetups(lang)) - - -def scrape_meetups(lang='cs'): - """ - Ideally, pyvo.cz would have an API where we get all this info. Let's assume - HTML API is good enough API for us now. - """ - url = 'https://pyvo.cz/en/' if lang == 'en' else 'https://pyvo.cz/' - res = requests.get(url, headers={'Accept-Charset': 'utf-8'}) - res.raise_for_status() - - root = html.fromstring(res.content.decode('utf-8')) - root.make_links_absolute(res.url) - - for event in root.cssselect('#events .event'): - try: - yield { - 'name': event.cssselect('h3')[0].text_content().strip(), - 'url': event.cssselect('h3 a')[0].get('href'), - } - except IndexError: - continue - - -@lru_cache() -def scrape_cities(): - res = requests.get(WIKI_URL) - res.raise_for_status() - root = html.fromstring(res.text) - rows = root.cssselect('.wikitable tbody tr') - return [row.cssselect('td')[1].text_content().strip() for row in rows[1:]] - - -def sort_by_city_size(meetups): - """ - Sorts given iterable of meetups by the size of the city. While pyvo.cz - lists the meetups according to when the closest event happens or happened, - this doesn't make sense for python.cz where the meetups are listed just - as a general overview. Also alphabetical sorting is pretty much just - confusing for the visitor. It only makes sense to sort the meetups by the - size of the city. The most populated cities have a larger probability - that the visitor of the page is close to them, thus they deserve to be - higher in the list. - """ - # convert list [city1, city2, ...] into dict {city1: 0, city2: 1, ...} - city_slugs = {city: n for n, city in enumerate(SORTED_CITY_SLUGS)} - - def key_func(meetup): - slug = meetup['url'].rstrip('/').split('/')[-1] - return city_slugs[slug] - - return sorted(meetups, key=key_func) diff --git a/pythoncz/static/data/beginners.yml b/pythoncz/static/data/beginners.yml deleted file mode 100644 index b0e74777..00000000 --- a/pythoncz/static/data/beginners.yml +++ /dev/null @@ -1,54 +0,0 @@ -courses: - - name: Pro dámy - icon: female - links: - - text: Pravidelné srazy PyLadies - url: http://pyladies.cz - - text: Jednorázové workshopy Django Girls - url: http://djangogirls.org - - text: Workshopy Czechitas (v Pythonu jen některé) - url: http://www.czechitas.cz - - text: Workshopy Geek Girls Carrots v Ostravě (v Pythonu jen některé) - url: http://geekgirlscarrots.org - - - name: Pro studenty - icon: graduation-cap - links: - - text: Kurz ČVUT FEL A4B99RPH - url: https://cw.fel.cvut.cz/wiki/courses/a4b99rph/prednasky/start - - text: Kurzy MU Brno - url: http://is.muni.cz/vyhledavani/?search=jazyk+python+agenda%3Apr - - text: Kurz ZČU v Plzni KKY/ITE - url: https://portal.zcu.cz/StagPortletsJSR168/CleanUrl?urlid=prohlizeni-predmet-sylabus&predmetZkrPrac=KKY&predmetZkrPred=ITE - - text: Kurz ZČU v Plzni KKY/APK - url: https://portal.zcu.cz/StagPortletsJSR168/CleanUrl?urlid=prohlizeni-predmet-sylabus&predmetZkrPrac=KKY&predmetZkrPred=APK - - text: Kurz FIT ČVUT v Praze (BI-PYT) - url: http://bk.fit.cvut.cz/cz/predmety/00/00/00/00/00/00/01/29/14/p1291406.html - - - name: Pro mládež - icon: child - links: - - text: Kroužek na Praze 10 - url: 'http://kapsa.cz/cs/krouzky-pro-deti#python' - - text: Kroužek v Lázně Toušeň - url: 'https://www.programovanihrou.cz/' - - text: Czechitas - kroužky a tábory pro různé věkové kategorie - url: http://www.czechitas.cz - - text: Kroužky, workshopy a tábory makeITtoday - url: https://makeittoday.cz/courses_cz.html - - text: Kurzy v Praze pro děti 8-12 let - url: https://www.digikids.cz - - text: Kurzy v Praze a online od 11-19 let - url: https://vzdelanibudoucnosti.cz - - - name: Ostatní - icon: code - links: - - text: Nepravidelné intenzivní Python kurzy kiwi.com - url: 'https://pythonweekend.cz/' - - text: Celodenní workshopy a setkání pro Python začátečníky - url: 'https://pyworking.cz/' - - text: Sedlákovi - různé kurzy související s Pythonem - url: 'https://www.sedlakovi.org/kurzy/' - - text: Engeto - Python akademie v Praze a Brně - url: 'https://engeto.cz/python-akademie/' diff --git a/pythoncz/static/data/business.geojson b/pythoncz/static/data/business.geojson deleted file mode 100644 index 6238b411..00000000 --- a/pythoncz/static/data/business.geojson +++ /dev/null @@ -1,1437 +0,0 @@ -{ - "type":"FeatureCollection", - "features":[ - { - "type":"Feature", - "properties":{ - "name":"Neuron soundware", - "url":"https://www.neuronsw.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4301578, - 50.0599442 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"H2O.ai", - "url":"https://www.h2o.ai", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.452568, - 50.092226 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Akamai", - "url":"https://www.akamai.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4006753, - 50.0703272 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"CreativeDock", - "url":"https://creativedock.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.403246, - 50.076407 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"CYAN Research & Development s.r.o.", - "url":"https://www.cyanrd.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.594788, - 49.224163 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Twisto", - "url":"https://www.twisto.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.448897, - 50.093668 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Exponea", - "url":"https://exponea.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 17.125383000000056, - 48.145637 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Red Hat", - "url":"http://www.redhat.cz", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.5816069, - 49.2261222 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Vaultier", - "url":"http://www.vaultier.org", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4319322, - 50.0713247 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Nanooq IT", - "url":"http://www.nanooq.eu/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4412558, - 50.1005167 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Inuits", - "url":"https://www.inuits.eu/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.402740, - 50.066360 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Y Soft", - "url":"https://www.ysoft.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.5805856, - 49.2222800 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Economia", - "url":"http://economia.ihned.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4538628, - 50.0912414 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Business Factory", - "url":"http://business-factory.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.6127981, - 49.2007753 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"ROI Hunter", - "url":"http://www.roihunter.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.6127981, - 49.2007753 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"ARMATURY Group a.s.", - "url":"http://www.armaturygroup.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 18.117507, - 49.922203 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"AOW", - "url":"http://aow.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.5758983, - 49.2182178 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"WebSupport", - "url":"https://www.websupport.sk/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 17.0734000, - 48.1551500 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"WebExpo", - "url":"http://webexpo.net/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.402740, - 50.066360 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Videoflot", - "url":"http://www.videoflot.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.5989164, - 49.2099833 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Grand IT", - "url":"http://grandit.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4812706, - 50.0713181 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"User Technologies", - "url":"http://usertechnologies.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4077361, - 50.0970125 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Tabfoundry", - "url":"https://www.tabfoundry.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4070231, - 50.0516553 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Kiwi.com", - "url":"http://kiwi.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.6007883, - 49.1840633 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Seznam.cz", - "url":"https://kariera.seznam.cz/", - "company":true - }, - "geometry":{ - "type":"MultiPoint", - "coordinates":[ - [ - 14.4009400, - 50.0710808 - ], - [ - 18.2722244, - 49.8162225 - ], - [ - 16.5990161, - 49.1718178 - ] - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Scuk.cz", - "url":"http://www.scuk.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4211, - 50.0872 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Scarfbot", - "url":"https://scarfbot.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.3937183, - 50.0746403 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"PC HELP", - "url":"http://www.pchelp.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 15.8952006, - 49.2172933 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Národní knihovna České republiky", - "url":"http://www.nkp.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4155778, - 50.0864564 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Česká národní banka", - "url":"https://www.cnb.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4285386, - 50.0870197 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Český Rozhlas", - "url":"http://www.rozhlas.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4345006, - 50.0785892 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Mergado", - "url":"https://www.mergado.cz/prace", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.5858589, - 49.2103950 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"IT4Innovations", - "url":"http://www.it4i.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 18.1560956, - 49.8376314 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"CodeScale", - "url":"http://www.codescale.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4009383, - 50.0694664 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"COEX", - "url":"https://www.coex.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4534092, - 50.1017800 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"WalkSource", - "url":"https://www.walksource.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.2538889, - 50.4236111 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Common Tongue", - "url":"http://www.commontongue.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4643847, - 50.0766186 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"CZ.NIC", - "url":"http://www.nic.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4513181, - 50.0791300 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"DIFFSolutions", - "url":"http://www.yottly.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4584328, - 50.0492022 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Dynameyes", - "url":"https://dynameyes.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.5476861, - 50.0728192 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Energomonitor", - "url":"https://www.energomonitor.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 17.9881464, - 49.4765639 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Fragaria", - "url":"http://www.fragaria.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4226003, - 50.0754761 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"ICFLIX", - "url":"http://www.icflix.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.0736344, - 49.9654289 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Imper", - "url":"https://imper.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4092097, - 50.0615613 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Investiční aukce", - "url":"http://www.investaukce.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.5727125, - 49.2332925 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"IT Academy", - "url":"http://www.it-academy.sk/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 17.1261600, - 48.1686100 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Vladimír Macek", - "url":"http://macek.sandbox.cz/" - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 15.0957467, - 50.7451942 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Tomáš Ehrlich", - "url":"http://www.tomasehrlich.cz/" - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.616667, - 49.2 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Creatiweb s.r.o.", - "url":"https://creatiweb.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4477, - 50.0772 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"CzechGlobe", - "url":"http://www.czechglobe.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.5930000, - 49.1870000 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Věroš Kaplan", - "url":"http://veroskaplan.cz" - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.62073, - 49.19031 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Nubium Development SE", - "url":"http://www.nubium.cz", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4292935, - 50.0809328 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"tcp cloud a.s.", - "url":"http://tcpcloud.eu", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4527403, - 50.0919999 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"OpenGeoLabs s.r.o.", - "url":"http://opengeolabs.cz", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.5160186, - 50.0324947 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Direct-services s.r.o.", - "url":"http://www.direct-services.cz", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 18.010309, - 49.594368 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Leadhub s.r.o.", - "url":"http://www.leadhub.co/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4036089, - 50.0751008 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Leadspicker s.r.o.", - "url":"https://leadspicker.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4262344, - 50.0907506 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Roští.cz, s.r.o.", - "url":"http://rosti.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 15.814811, - 50.206445 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Miloň Krejča", - "url":"http://www.milonline.eu" - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 15.2232711, - 49.4309486 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Stories", - "url":"http://www.stories.bi/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4070231, - 50.0516553 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Vojtěch Bartoš", - "url":"http://vojtech.me" - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.2134464, - 50.1236622 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"SparkTECH s.r.o.", - "url":"http://www.sparktech.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.341330, - 50.088202 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Jan Šváger", - "url":"https://www.svager.cz" - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.631337, - 50.918289 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Petr Blahoš", - "url":"http://petr.blahos.com/" - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.6380850, - 49.6401267 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"EPAM", - "url":"https://www.epam.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4343922, - 50.0506023 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Proboston Creative", - "url":"https://www.proboston.net", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4368203, - 50.0770531 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"OLC Systems s.r.o.", - "url":"https://www.olc.cz", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 17.282280, - 49.576409 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"DANTEM s.r.o.", - "url":"http://www.dantem.cz/", - "company":true - }, - "geometry":{ - "type":"MultiPoint", - "coordinates":[ - [ - 14.3755908, - 50.0806400 - ], - [ - 18.2618453, - 49.8317611 - ] - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Jack.cz", - "url":"http://www.jack.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4334178, - 50.0896022 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"MSD IT Global Innovation Center s.r.o.", - "url":"http://www.msdit.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4099194, - 50.0670106 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"NTK - Národní technická knihovna", - "url":"https://www.techlib.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.3905997, - 50.1039000 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"SlushPool", - "url":"https://slushpool.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.47374, - 50.10514 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"STOCKED s.r.o.", - "url":"https://www.stocked.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4722669, - 50.0781181 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Atollon CS", - "url":"http://www.atollon.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.424799, - 50.088100 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"LMC s.r.o.", - "url":"https://www.lmc.eu/cs/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4568872, - 50.1028653 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"OKIN BPS", - "url":"https://okinbps.com/us/home/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 18.2923319, - 49.8392964 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"AutoCont CZ a. s.", - "url":"http://www.autocont.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 18.2715000, - 49.8410000 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"REMAK a.s.", - "url":"http://www.remak.eu/cs/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 18.1154847, - 49.4607186 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Heureka", - "url":"https://www.heurekadevs.cz/", - "company":true - }, - "geometry":{ - "type":"MultiPoint", - "coordinates":[ - [ - 15.058695, - 50.766428 - ], - [ - 14.443173, - 50.094377 - ], - [ - 13.3818922, - 49.7372414 - ] - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"SpaceKnow", - "url":"https://spaceknow.com/", - "company":true - }, - "geometry":{ - "type":"MultiPoint", - "coordinates":[ - [ - 14.4525094, - 50.0924147 - ] - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"BoxtrapSecurity", - "url":"https://www.boxtrapsecurity.com/", - "company":true - }, - "geometry":{ - "type":"MultiPoint", - "coordinates":[ - [ - 14.4220517, - 50.0823494 - ] - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Monitora media", - "url":"https://monitora.cz/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4092097, - 50.0615613 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Josef Rousek", - "url":"https://rousek.name/" - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4537655, - 50.0714368 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Oracle", - "url":"https://www.oracle.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.3753233, - 50.0559844 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Colpirio.com s.r.o.", - "url":"https://www.colpirio.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.602532, - 49.200819 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"ICT & MEDIA s.r.o.", - "url":"https://www.ictmedia.cz", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.594788, - 49.224163 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"REDAMP.cz", - "url":"https://www.redamp.cz", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 16.594788, - 49.224163 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Truly Scaled", - "url":"https://trulyscaled.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4538687, - 50.0696205 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Orgis IT", - "url":"https://www.orgis.cz", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 13.3701336, - 49.7315498 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"SentinelOne", - "url":"https://www.sentinelone.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.45066, - 50.0981919 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Medallia", - "url":"https://www.medallia.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.4216931, - 50.0833064 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Rossum", - "url":"https://www.rossum.ai", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.46422, - 50.09559 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Ataccama", - "url":"https://www.ataccama.com", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.45096, - 50.09214 - ] - } - }, - { - "type":"Feature", - "properties":{ - "name":"Pure Storage", - "url":"https://www.purestorage.com/", - "company":true - }, - "geometry":{ - "type":"Point", - "coordinates":[ - 14.44641, - 50.09437 - ] - } - } - ] -} diff --git a/pythoncz/static/data/jobs.yml b/pythoncz/static/data/jobs.yml deleted file mode 100644 index 38801866..00000000 --- a/pythoncz/static/data/jobs.yml +++ /dev/null @@ -1,20 +0,0 @@ -job_boards: - # Pravidla: - # - # * Pouze odkazy, které přímo filtrují Python. - # * Pouze odkazy na české (maximálně slovenské) weby. - # * Odkazy, které v době přidávání povedou na prázdné výsledky vyhledávání - # (tzn. žádná nabídka práce v Pythonu) mají minimální šanci, že budou - # schváleny. - # - - name: StartupJobs.cz - url: 'https://www.startupjobs.cz/nabidky/15/python-programmer' - - - name: Jobs.cz - url: 'http://www.jobs.cz/prace/?q[]=python' - -knowledge_tests: - - name: StartupJobs.cz - url: 'https://www.startupjobs.cz/test/python' - - name: Toptal.com - url: 'http://www.toptal.com/python/interview-questions' diff --git a/pythoncz/static/favicon.ico b/pythoncz/static/favicon.ico deleted file mode 100644 index c9efc5844a2627a8474949724a2aefe4ab2baee4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 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œ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 diff --git a/pythoncz/static/images/logo-plain.png b/pythoncz/static/images/logo-plain.png deleted file mode 100644 index dd4b3741393733f9cbcaf537a321053d365f50ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179155 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

Fkm+&*z;(G&gl(9Q*OptmdCT|RJNsWi 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

43UfrO)V^Gr$K}e!`;GyFlFbsP`eOi~erb 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

  • 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

    t83wDFCtKK^8>eota2ACP;Lm=1?HAh) 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 - - - - - - - - - \ No newline at end of file diff --git a/pythoncz/static/main.css b/pythoncz/static/main.css deleted file mode 100644 index ac96a212..00000000 --- a/pythoncz/static/main.css +++ /dev/null @@ -1,725 +0,0 @@ - -body { - padding-top: 20px; - padding-bottom: 20px; - text-align: center; - height: auto; -} - -.container { - margin: 0 auto; - text-align: left; -} - -.header, -.marketing, -.footer { - padding-right: 15px; - padding-left: 15px; -} - -hr { - margin: 4em 0; -} - -h1, -h2, -h3, -h4, -.title, -.tasks .panel-body, -.online-courses .panel-body { - font-family: 'Arbutus Slab', serif; -} - -.content > h1, -h2, -h3 { - margin: 1.3em 0 1em 0; -} - -.content > h1 { - text-align: center; - font-size: 400%; - margin-bottom: 1.5em; -} - -.get-involved h2, -.beginners h2, -.jobs h2 { - text-align: center; -} - -.boxes h2 { - text-align: left; -} - -.boxes #organizuj h2 { - text-align: center; -} - -.columns h3 { - margin-top: 2em; -} - -.permalink-container { - position: relative; -} - -a.permalink { - position: absolute; - left: 0; - bottom: 0; - visibility: hidden; - font-family: sans-serif; - margin-left: 0.1em; - padding: 0 0.3em; - text-decoration: none; - color: #d5d5d5; -} - -h1[id]:hover .permalink, -h2[id]:hover .permalink, -h3[id]:hover .permalink, -h4[id]:hover .permalink, -h5[id]:hover .permalink, -h6[id]:hover .permalink { - visibility: visible; -} - -ul { - padding-left: 1.5em; -} - -ul li { - list-style-type: none; - position: relative; - margin-bottom: 0.3em; -} - -ul li:before { - content: '•'; - position: absolute; - left: -1em; -} - -.header { - padding-bottom: 1.5em; -} - -.header .title { - margin-top: 0; - margin-bottom: 0; - line-height: 2em; - font-size: 1.5em; -} - -.header .title a { - text-decoration: none; - color: #646464; -} - -.header .title img { - vertical-align: text-top; - margin-right: 0.1em; -} - -.logo { - text-align: center; - margin-bottom: 2em; -} - -.logo img { - width: 100%; -} - -ul.lead { - text-align: center; - padding: 0; -} - -ul.lead li:before, -ul.nav li:before, -ul.list-group li:before, -ul.events-list li:before { - display: none; -} - -.box-body { - min-height: 18em; - padding: 1em 0; -} - -.box-content { - min-height: 10em; -} - -.box h2 { - margin: 0 0 0.5em 0; -} - -.boxes { - margin: 2em 0; -} - -.index .call-to-action, .beginners .call-to-action { - text-align: right; -} - -.beginners .index .btn, .beginners .call-to-action .btn { - margin: 1em 0.5em 0 auto; -} - -.jobs .call-to-action, .get-involved .call-to-action, .events .call-to-action { - text-align: center; -} - -.jobs .call-to-action { - margin-top: -1em; -} - -.jobs .call-to-action .btn { - margin: 0 auto; -} - -.get-involved .call-to-action .btn { - margin: 1em auto; -} - -.discussions { - margin: 0; -} - -.discussions .list-group-item { - border: none; -} - -i.fa { - margin-right: 0.3em; -} - -h2 i.fa { - margin-right: 0.1em; -} - -.footer { - margin-top: 2em; - padding: 2em 1em; - border-top: 1px solid #e5e5e5; -} - -.footer p { - line-height: 2em; -} - -.footer .edit { - text-align: right; -} - -.footer .edit a { - text-align: left; -} - -.columns { - margin: 4em 2em; - - -webkit-columns: 2; - -moz-columns: 2; - columns: 2; - - -webkit-column-rule: 1px dotted #aaa; - -moz-column-rule: 1px dotted #aaa; - column-rule: 1px dotted #aaa; - - -webkit-column-gap: 3em; - -moz-column-gap: 3em; - column-gap: 3em; -} - -.columns-many { - -webkit-columns: 4; - -moz-columns: 4; - columns: 4; -} - -.columns h2:first-of-type, -.columns h3:first-of-type { - margin-top: 0; -} - -.columns img { - width: 100%; -} - -.help { - cursor: help; -} - -i.fa.help { - margin-left: 0.3em; -} - -img.img-small { - width: 50%; - margin-left: 25%; - margin-right: 25%; -} - -.tasks h3 { - text-align: center; - margin: 2em 0 2em 0; -} - -.tasks .panel-body { - height: 120px; - overflow: hidden; - position: relative; -} - -.tasks .panel-body .shadow { - position: absolute; - height: 20px; - bottom: 0; - left: 0; - right: 0; - box-shadow: inset 0px -15px 20px 0px rgba(255,255,255,1); -} - -.tasks .panel-body, -.online-courses .panel-body { - text-align: center; - font-size: 110%; -} - -.tasks .panel-body a { - color: #333; - height: 70px; - width: 100%; - display: table; -} - -.tasks .panel-body a span, -.tasks .panel-body a strong { - display: table-cell; - vertical-align: middle; -} - -.tasks .panel-footer { - text-align: right; -} - -.tasks .votes { - margin-right: 1em; -} - -.online-courses { - margin: 3em 0 1em 0; -} - -.online-courses .panel { - text-align: center; -} - -.jobs .thumbnail { - margin-top: 2em; -} - -.jobs #map, .events #map { - height: 350px; -} - -.cartoon { - display: block; - width: 100%; -} - -.cartoon-container { - margin: 0 auto; - padding: 2em 0; - max-width: 768px; -} - -.cartoon-hr { - padding-bottom: 4em; -} - -.panel-body .cartoon { - margin: 0 auto 1.5em auto; - max-height: 10em; - width: auto; -} - -.get-involved .cartoon { - margin-bottom: 2em; -} - -img[src*="jobs.svg"] { - max-height: 400px; -} - -.communication { - text-align: center; - display: flex; - justify-content: center; - flex-wrap: wrap; - margin: 2em 0 0 0; -} - -.communication-item { - display: block; - width: 10em; - height: 8em; - padding: 0; - margin: 0; - list-style-type: none; -} - -li.communication-item::before { - display: none; -} - -.communication-item a { - text-decoration: none; -} - -.communication-item-icon { - font-size: 2.5em; - display: block; -} - -.communication-item-icon i { - margin: 0; -} - -.communication-item-caption { - display: block; -} - -.label { - margin-right: 0.5em; -} - -.issues, .issues-error { - margin: 2em 0; -} - -.issues-error { - text-align: center; -} - -.issues-error .fa { - font-size: 200%; - margin-bottom: 0.3em; -} - -.issue { - padding: 0.5em 0.5em 0.5em 2em; - margin: 0.5em 0; - border-bottom: #F5F5F5 1px solid; - position: relative; -} - -.issue h3 { - font-size: inherit; - font-family: inherit; - margin: 0.3em 0 0.5em 0; - padding: 0; - white-space: nowrap; - overflow: hidden; -} - -.issue-title a { - color: #333; -} - -.issue-title::before { - content: "\00a0"; - width: 2em; - background: linear-gradient( - to right, - rgba(255,255,255,0) 0%, - rgba(255,255,255,1) 100% - ); - position: absolute; - right: 0.5em; -} - -.issue-icon { - color: #6CC644; - font-size: 1.5em; - position: absolute; - left: 0; - top: 0.7em; -} - -.issue-repo { - line-height: 0.7em; - font-size: 0.7em; - display: table; /* trick to have a 'block' as wide as content */ -} - -.issue-repo-specific .issue-title { - line-height: 1.3em; -} - -.issue-general .issue-title { - line-height: 2em; -} - -a.issue-repo, -a.issue-repo:hover, -a.issue-repo:focus, -.issue-details .label-default, -.issue-details a.label-default:hover, -.issue-details a.label-default:focus { - color: #777; -} - -.issue-details .label-default { - background-color: #F5F5F5; -} - -.issue-details a.label-default:hover, -.issue-details a.label-default:focus { - background-color: #E5E5E5; -} - -.label-pyladies { - background-color: #FF8181; -} -.label-sprint-idea { - background-color: #FBCA04; - color: black; -} - -i.icon-english { - display: inline-block; - width: 1.3em; - border-radius: 0.4em; - background: url("./images/uk-flag.svg"); - background-repeat: no-repeat; - background-size: contain; - background-position: center center; -} - -i.icon-english::before { - content: "\00a0"; -} - -.notice { - background: #337ab7; - color: #fff; - padding: 0.5em; - text-align: center; - margin-top: -20px; - margin-bottom: 0.5em; -} - -.notice a { - color: #fff; - text-decoration: underline; - font-weight: bold; -} - -.pagenotfound { - text-align: center; - margin-bottom: 2em; -} - -.pagenotfound img { - width: 50%; -} - -.events .lead, -.events-index h2 { - text-align: center; -} - -.events-index h3 { - text-align: left; -} - -.events .cartoon { - height: 10em; -} - -.events .content h2, -.events .content p, -.events-month { - text-align: center; -} - -.events-list, -.events-list li { - padding: 0; - margin: 0; -} - -.events-month { - padding-bottom: 0.3em; - border-bottom: 1px #eee solid; -} - -.events-list .event { - margin-bottom: 2em; -} - -.event-datetime { - color: #337ab7; - display: block; - text-align: center; - border: 1px #337ab7 solid; - border-radius: 0.3em; - min-width: 8em; /* sized for "WEDNESDAY" */ - padding: 0.3em 1em 1em 1em; -} - -.event-day, -.event-time { - display: block; -} - -.event-day { - font-size: 230%; -} - -.event-weekday { - text-transform: uppercase; - text-align: center; - display: inline-block; - min-width: 4.5em; -} - -.event h4 { - font-size: inherit; - font-family: inherit; - margin: 0.3em 0 0.5em 0; - padding: 0; - white-space: nowrap; - overflow: hidden; -} - -.event-title, a.event-title { - line-height: 2em; -} - -.event-title::before { - content: "\00a0"; - width: 2em; - background: linear-gradient( - to right, - rgba(255,255,255,0) 0%, - rgba(255,255,255,1) 100% - ); - position: absolute; - right: 0; -} - -.event-feed { - line-height: 0.7em; - font-size: 0.7em; - display: table; /* trick to have a 'block' as wide as content */ -} - -.event-feed, -.event-feed a, -.event-feed a:hover, -.event-feed a:focus { - color: #777; -} - -.events .content p.event-location, -.events .content p.event-map-links { - text-align: left; - font-size: 90%; - margin: 0; - margin-bottom: 0.1em; -} - -.event-map-links a { - margin-right: 0.5em; -} - -.event-tentative, -.event-tentative a, -.event-tentative a:hover, -.event-tentative a:focus, -.event-tentative .event-feed, -.event-tentative .event-datetime { - color: #AAA; - border-color: #AAA; -} - -.event-tentative .event-datetime { - padding-bottom: 0.5em; -} - -.event-tentative .event-day { - font-size: 180%; -} - -.event-tentative .event-weekday, -.event-tentative .event-time { - display: inline; -} - -.meetups { - margin: 2em 0; -} - -.meetups-city { - text-align: center; - font-size: 120%; -} - -.meetups-city a { - display: inline-block; - line-height: 2.5em; - padding-left: 3em; - margin: 0.5em 0; - background: url("./images/pyvo.png"); - background-size: 2em; - background-repeat: no-repeat; -} - - -@media only screen and (max-width: 992px) { - .boxes { - margin: 0; - padding: 0; - } - - .columns { - margin: 0; - - -webkit-columns: 1; - -moz-columns: 1; - columns: 1; - } - - .columns-many { - margin: 4em 2em; - - -webkit-columns: 3; - -moz-columns: 3; - columns: 3; - } -} - - -@media only screen and (max-width: 768px) { - .columns-many { - -webkit-columns: 2; - -moz-columns: 2; - columns: 2; - } - - .discussions { - width: 50%; - margin: 0 auto; - } - - .pagenotfound img { - width: 80%; - } -} diff --git a/pythoncz/static/maps.js b/pythoncz/static/maps.js deleted file mode 100644 index 889daaa4..00000000 --- a/pythoncz/static/maps.js +++ /dev/null @@ -1,42 +0,0 @@ - -var layer = L.tileLayer('https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', { - maxZoom: 18, - attribution: '© OpenStreetMap contributors' -}); - - -$(function() { - var element = $('#map'); - - var iconSize = parseInt(element.attr('data-icon-size'), 10) || 16; - var icon = L.icon({ - iconUrl: element.attr('data-icon-src'), - iconSize: [iconSize, iconSize], - shadowSize: [0, 0], - iconAnchor: [iconSize / 2, iconSize / 2], - popupAnchor: [0, 0] - }); - - var zoom = element.attr('data-zoom') || 7; - var lat = element.attr('data-lat') || 49.8; - var lng = element.attr('data-lng') || 15.55; - - var map = L.map('map', {'scrollWheelZoom': false}) - .setView([lat, lng], zoom) - .addLayer(layer); - - var dataUrl = element.attr('data-src'); - $.getJSON(dataUrl, function(data) { - L.geoJson(data, { - pointToLayer: function (feature, coordinates) { - return L.marker(coordinates, {icon: icon}); - }, - onEachFeature: function (feature, marker) { - if (feature.properties) { - text = '

    ' + feature.properties.name + '

    ' - marker.bindPopup(text); - } - } - }).addTo(map); - }); -}); diff --git a/pythoncz/static/permalinks.js b/pythoncz/static/permalinks.js deleted file mode 100644 index d5484bbc..00000000 --- a/pythoncz/static/permalinks.js +++ /dev/null @@ -1,27 +0,0 @@ - -$(function() { - var lang = $('html').attr('lang'); - var title = (lang == 'cs') ? 'Trvalý odkaz' : 'Permanent link'; - - var selectors = []; - for (var i = 1; i <= 6; i++) { - selectors.push('h' + i + '[id]'); - } - - $(selectors.join(', ')).each(function () { - var $heading = $(this); - - var $link = $('', { - 'href': '#' + $heading.attr('id'), - 'class': 'permalink', - 'title': title, - 'text': '¶', - }); - var $container = $('', { - 'class': 'permalink-container', - }); - - $heading.append($container); - $container.append($link); - }); -}); diff --git a/pythoncz/templates/404.html b/pythoncz/templates/404.html deleted file mode 100644 index 0616c8e9..00000000 --- a/pythoncz/templates/404.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - Python - 404 -{% endblock %} -{% block content %} - -
    -

    Stránka nenalezena.

    -

    Page not found.

    - 404 -
    - -{% endblock %} diff --git a/pythoncz/templates/_base.html b/pythoncz/templates/_base.html deleted file mode 100644 index 2b143256..00000000 --- a/pythoncz/templates/_base.html +++ /dev/null @@ -1,141 +0,0 @@ -{% set is_homepage = request.path in ['/', '/{}'.format(lang), '/{}/'.format(lang)] %} - - - - - - - - - - - - - - - - - - - - - - - - {% block head %} - Python, programovací jazyk - - - - - {% endblock %} - - - - -
    - - - {% if not is_homepage %} - - {% endif %} - -
    - {% block content %}{% endblock %} -
    - - - - - - {% if not debug %} - - - {% endif %} - {% block scripts %}{% endblock %} -
    - - diff --git a/pythoncz/templates/_communication.html b/pythoncz/templates/_communication.html deleted file mode 100644 index 3df9f06f..00000000 --- a/pythoncz/templates/_communication.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - diff --git a/pythoncz/templates/_events.html b/pythoncz/templates/_events.html deleted file mode 100644 index 1eb794d9..00000000 --- a/pythoncz/templates/_events.html +++ /dev/null @@ -1,61 +0,0 @@ -{% for (year, month), events in data %} -

    {{ month|format_month(lang) }}

    -
      - {% for event in events %} -
    • -
      -
      - -
      -
      -

      - - {% if event.feed.url %} - - {{ event.feed.name }} - - {% else %} - {{ event.feed.name }} - {% endif %} - — iCal - - - {% if event.event.url %} - {{ event.event.name }} - {% else %} - {{ event.event.name }} - {% endif %} -

      - {% if event.event.location %} -

      - {{ event.event.location }} -

      - - {% endif %} -
      -
      -
    • - {% endfor %} -
    -{% endfor %} diff --git a/pythoncz/templates/_meetups.html b/pythoncz/templates/_meetups.html deleted file mode 100644 index fd8a40b3..00000000 --- a/pythoncz/templates/_meetups.html +++ /dev/null @@ -1,7 +0,0 @@ -
    -{% for meetup in meetups %} - -{% endfor %} -
    diff --git a/pythoncz/templates/beginners_cs.html b/pythoncz/templates/beginners_cs.html deleted file mode 100644 index 1363ebce..00000000 --- a/pythoncz/templates/beginners_cs.html +++ /dev/null @@ -1,234 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - Python v ČR: Pro začátečníky - - - - -{% endblock %} - -{% block body_class %}beginners{% endblock %} - -{% block breadcrumb %} - Pro začátečníky -{% endblock %} - -{% set en = ''|safe %} - -{% block content %} -

    Učíme se Python

    -
      -
    • - Česká komunita je přátelská a živá. Vždy bude po ruce někdo, kdo ti pomůže. -
    • -
    • - Nebudeš mít problém sehnat práci. Pythonistů je nedostatek! -
    • -
    • - I kdyby weby vyšly z módy, Python nachází uplatnění v desítkách dalších oborů. -
    • -
    - -
    - -
    - -

    Online materiály – neumím vůbec programovat

    -
    -
    -

    - Následující materiály vznikly v rámci aktivit, které se snaží přiblížit IT ženám a ženy k IT. Jsou skvěle zpracované a může se z nich naučit programovat od úplných základů kdokoliv. -

    - -
    -
    -
    -
    - - Chci umět obecně programovat -
    - -
    -
    -
    -
    -
    - - Chci vytvořit webovou stránku -
    - -
    -
    -
    -
    -
    - -
    - -

    Online materiály – programovat trochu umím

    -
    -

    - - Přecházím z jiného jazyka -

    - - -

    - - Návody pro začátečníky -

    - - -

    - - Chci si to hned zkusit -

    - - -

    - - Knihy -

    -

    - Díky naší knihovničce si můžeš zadarmo půjčit knihy o Pythonu. Na stránkách Python Books navíc najdeš seznam knih, které si můžeš zdarma číst online nebo si je rovnou stáhnout. Určitě to omrkni! -

    - -

    - - Přednášky -

    -

    - Nahráváme přednášky ze srazů a dáváme je na YouTube. Na stránkách pyvideo.org najdeš přednášky z celého světa. -

    - -

    - - Konvence pro psaní kódu -

    - - -

    - - Kam nahrát web napsaný v Pythonu? -

    - -
    - -
    - -

    Kurzy

    -
    - {% for column in data.courses %} -
    -
    -
    - - {{ column.name }} -
    - -
    -
    - {% endfor %} -
    - - -

    Koučování

    - -
    -
    -

    Aneb osobní konzultace, mentoring, doučování…

    - -
    -
    -{% endblock %} diff --git a/pythoncz/templates/events_cs.html b/pythoncz/templates/events_cs.html deleted file mode 100644 index eb4893eb..00000000 --- a/pythoncz/templates/events_cs.html +++ /dev/null @@ -1,81 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - Python v ČR: Akce - - - - -{% endblock %} - -{% block body_class %}events{% endblock %} - -{% block breadcrumb %} - Akce -{% endblock %} - -{% block content %} -

    Akce

    -
    -

    - Srazy, konference, workshopy. Vše, co se v ČR děje kolem jazyka Python, na jednom místě. -

    -
    -
    - -
    -
    - -

    Srazy

    -

    - Srazy Python programátorů zvané - Pyvo se pořádají po celé republice. Přijď si - poslechnout přednášky od chytrých lidí a - popovídat si nejen o Pythonu! -

    - - {% include '_meetups.html' with context %} - -

    - - Chci uspořádat sraz v mém městě - -

    - -
    - -
    - -
    - -

    Všechny akce

    -
      -
    • - Pravidelné akce lze přidat přes tzv. - iCal export. - Ten může generovat přímo vaše webová stránka (jako v případě - pyvo.cz), nebo jej lze vytáhnout - z nějaké služby (Google Calendar, meetup.com). URL exportu pak - na náš web přidejte pomocí - Pull Requestu. -
    • -
    • - Jednorázové akce lze přidat přes kalendář - Czech - Python Events. Do kalendáře má přístup mnoho z organizátorů - existujících Python akcí, takže je poproste, ať vaši akci přidají, - nebo napište na info@pyvec.org. První URL z popisu události se zde zobrazí jako - odkaz. -
    • -
    - - {% include '_events.html' with context %} - -

    - - iCal na všechny akce - -

    - -
    -{% endblock %} diff --git a/pythoncz/templates/events_en.html b/pythoncz/templates/events_en.html deleted file mode 100644 index b1ce4c4f..00000000 --- a/pythoncz/templates/events_en.html +++ /dev/null @@ -1,73 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - Python in the Czech Republic: Events - - - - -{% endblock %} - -{% block body_class %}events{% endblock %} - -{% block breadcrumb %} - Events -{% endblock %} - -{% block content %} -

    Events

    -
    -

    - Meetups, conferences, workshops. All Czech Python events, at one place. -

    -
    -
    - -
    -
    - -

    Meetups

    -

    - Python meetups called “Pyvo” are happening - across the country. You're welcome to come, or present at one! -

    - - {% include '_meetups.html' with context %} - -
    - -
    - -
    - -

    All Events

    -
      -
    • - Regular events can be added using an - iCal feed. - The feed can be generated directly by your website (as in the case of - pyvo.cz), or you can obtain it from - your platform, such as Google Calendar, meetup.com, etc. - Then send a Pull Request - to add your iCal feed URL to our website. -
    • -
    • - One-time events can be added using the - Czech - Python Events calendar. A lot of local event organizers have - access to edit the calendar, so you can ask them to add your event, - or let us know at info@pyvec.org. The first URL in the event description will - display here as a link. -
    • -
    - - {% include '_events.html' with context %} - -

    - - iCal of all events - -

    - -
    -{% endblock %} diff --git a/pythoncz/templates/get_involved_cs.html b/pythoncz/templates/get_involved_cs.html deleted file mode 100644 index c83940f4..00000000 --- a/pythoncz/templates/get_involved_cs.html +++ /dev/null @@ -1,259 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - Python v ČR: Zapoj se! - - - - -{% endblock %} - -{% block body_class %}get-involved{% endblock %} - -{% block breadcrumb %} - Zapoj se! -{% endblock %} - -{% block content %} -

    Zapoj se!

    -
    -
    -

    - Líbí se ti Python? Pomoz nám ho rozšířit i mezi ostatní. Můžeš nám poslat peníze, učit, přednášet, psát, organizovat, programovat, ale třeba i jen vymýšlet, co a jak by se dalo zlepšit. Máme práci pro každého! -

    -

    - Python komunita je fajn jen díky tomu, že jsou v ní lidi, kteří se nebojí přiložit ruku k dílu. Všichni to děláme po večerech ve volném čase, z čirého nadšení. Děláme to proto, že chceme, aby to bylo lepší i pro tebe. Ať jsi profík nebo začátečník, z Prahy nebo z Karviné, můžeš nám pomoci. Odměnou ti budou kontakty, reference, zkušenosti. -

    -
    -
    - -
    - Česká Python komunita -
    - -
    -
    -
    -
    -

    - - Přispěj -

    -

    - Budeme rádi, když přispěješ na provoz neziskovky Pyvec, jejíž misí je podporovat a propagovat Python komunitu v ČR. -

    -

    - Srazy nebo workshopy dělají konkrétní lidé a Pyvec jim do toho nemluví - nabízí ale pomocnou ruku co se týče financí a zázemí. -

    -
    -
    -
    -
    -
    -
    -

    - - Vyučuj -

    - -
    -
    -
    - -
    - -
    -
    -
    -

    - - Přednášej -

    -
      -
    • - Přihlaš se s přednáškou na nejbližší sraz. -
    • -
    • - Pokud se necítíš na 15-20 minut, připrav si tzv. lightning talk. Je to pětiminutovka o čemkoliv a můžeš s ní přijít na srazy přijít i bez ohlášení. -
    • -
    • - Koukni se, jestli zrovna nehledají řečníky PyCon CZ nebo PyCon SK. Na mnohé konference se může přihlásit s přednáškou kdokoliv, stačí vyplnit formulář – tzv. CfP (Call for Proposals). -
    • -
    -
    -
    -
    - -
    -
    -
    -

    - - Piš -

    -
      -
    • - Poděl se o zážitky z akcí nebo o svůj životní příběh na komunitní blog. -
    • -
    • - Technické články piš např. na Zdroják.cz. Redakce bude nadšená a ty budeš mít větší publikum. -
    • -
    • - Python učíme podle Open Source materiálů. Můžeš nám pomoci je vylepšovat. -
    • -
    • - Když se nám povede něco zorganizovat, snažíme se sepsat naše know-how do komunitní dokumentace. Chybí tam ještě spousta věcí! -
    • -
    -
    -
    -
    -
    - -

    Organizuj

    -
    -
    -
      -
    • - Pokud ve tvém městě není Python sraz nebo třeba PyLadies skupina, tak gratulujeme: Můžeš je založit! Jestliže už se kolem tebe něco koná, nejlepší bude, když se spojíš s organizátory a zeptáš se, jak jim můžeš pomoci. -
    • -
    • - Každoročně sháníme dobrovolníky na konferenci PyCon CZ. Potřebné činnosti mají většinou pramálo společného s Pythonem a programováním. -
    • -
    • - Když se nám povede něco zorganizovat, snažíme se sepsat naše know-how do komunitní dokumentace. -
    • -
    -
    -
    -
      -
    • - Všechny důležité věci řešíme na Slacku. Napiš nám na info@pyvec.org, my tě přidáme, pak můžeš pokukovat co se v jaké místnosti řeší a brzy uvidíš, kde je tvoje pomoc nejvíc potřeba. -
    • -
    • - Máme neziskovku Pyvec. Její misí je podporovat a propagovat Python komunitu v ČR. Srazy nebo workshopy dělají lidé jako ty a Pyvec jim do toho nemluví - nabízí ale pomocnou ruku co se týče financí a zázemí. -
    • -
    -
    -
    - -

    Další nápady

    -
    -
    -

    - Pro organizaci jednorázových úkolů používáme GitHub. Když nic, tak aspoň hlasuj nebo přidej vlastní nápad. Díky hlasům budeme mít přinejmenším přehled o tom, co si přeje nejvíc lidí. -

    -

    - Značka Kouč pomůže! znamená, že někdo navrhl, že ti s úkolem pomůže, pokud se do něj pustíš. Jestli se ty chceš někde navrhnout jako kouč, napiš to do komentáře pod daný úkol a přiřaď mu štítek „coach“. -

    -

    - - Přidat nápad - -

    -
    -
    - - {% if error %} -
    -
    -

    -
    - Nápady se nepovedlo načíst. Většinu z nich lze alternativně najít na pyvec/zapojse. Pokud tento stav přetrvává, dejte nám o tom prosím vědět sem. -

    -
    -
    - {% else %} -
    - {% for issue in issues %} -
    -

    - {% if issue.is_pull_request %} - - {% else %} - - {% endif %} - - {% if issue.repository_name != 'zapojse' %} - - {{ issue.repository_name|lower }} - - {% endif %} - - - {{ issue.title }} - - -

    -

    - {% if issue.user.login %} - - {{ issue.user.login }} - - {% else %} - - ? - - {% endif %} - {% if issue.participants %} - - {{ issue.participants }} - - {% endif %} - {% if issue.votes %} - - {{ issue.votes }} - - {% endif %} - {% if issue.comments %} - - {{ issue.comments }} - - {% endif %} - - {% if issue.organization_name|lower == 'pyladiescz' %} - - PyLadies - - {% endif %} - {% if issue.coach %} - - Kouč pomůže! - - {% endif %} - {% if issue['sprint-idea'] %} - - Sprint - - {% endif %} -

    -
    - {% endfor %} -
    - {% endif %} - - -{% endblock %} diff --git a/pythoncz/templates/index_cs.html b/pythoncz/templates/index_cs.html deleted file mode 100644 index 81a08795..00000000 --- a/pythoncz/templates/index_cs.html +++ /dev/null @@ -1,180 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - Python, programovací jazyk - - - - -{% endblock %} -{% block content %} - -
      -
    • - Python je moderní programovací jazyk. - Je univerzální – pohání weby i rakety. -
    • -
    • - Dobře se čte a dá se velice rychle naučit. - Je skvělý pro výuku programování. -
    • -
    • - Česká komunita je aktivní. - Najdeš v ní pomoc, kamarády i práci. -
    • -
    - -
    - Česká Python komunita -
    -
    - {% include '_communication.html' %} -
    - -
    - -
    -

    - - Nejbližší akce -

    - {% include '_events.html' with context %} -

    - - - Všechny akce - -

    -
    - -
    - -
    -
    -
    -
    -

    - - Blog -

    -

    - Díky blogu se dovíš o všem, co se v české Python komunitě zrovna děje. A co je nejlepší – můžeš klidně přidat svůj vlastní článek! -

    -
    -

    - - - Chci být v obraze! - -

    -
    -
    -
    -
    -
    -

    - - Pro začátečníky -

    -

    - Základy Pythonu se dají naučit i z prohlížeče. Máme pro tebe odkazy na výukové hry, online kurzy, videa, články, knihy a další. -

    -
    -

    - - - Prahnu po vědění - -

    -
    -
    - -
    - -
    -
    -
    -

    - - Práce -

    -

    - Jakou práci seženeš, když se naučíš Python? Kdo jej používá? Jak a kam napsat nabídku práce pro Pythonisty? -

    -
    -

    - - - Nabízím, poptávám - -

    -
    -
    - -
    - -
    -
    -
    -

    - - Zapoj se! -

    -

    - Pomoz nám rozšířit Python mezi ostatní. Pro lenochy s penězi máme číslo účtu, ale spíš oceníme, když se chopíš nějakého úkolu a dotlačíš jej do konce. Věčná sláva zaručena! Pokud chceš zorganizovat sraz či workshop ve svém městě, koukni na příručky pro pořadatele. -

    -
    -

    - - - Toužím po věčné slávě - -

    -
    -
    - -
    - -
    -
    -
    -

    - - PyCon CZ -

    -

    - Česká Python konference! Pomoz nám s přípravami, propagací, zkus si přihlásit přednášku nebo workshop, sponzoruj nás, nebo prostě jen přijď a akci si užij! -

    -
    -

    - - - Hurá, konference! - -

    -
    -
    -
    -
    -
    -

    - - Knihovna -

    -

    - Máme knihovničku s literaturou o Pythonu a podobných technologiích. Knihy si lze zdarma půjčit – ozvi se a přijď si knížku vyzvednout na nejbližším srazu. Mimochodem, Python Books znáš, že? -

    -
    -

    - - - Co si můžu půjčit? - -

    -
    -
    -
    -{% endblock %} diff --git a/pythoncz/templates/index_en.html b/pythoncz/templates/index_en.html deleted file mode 100644 index 74ffa688..00000000 --- a/pythoncz/templates/index_en.html +++ /dev/null @@ -1,150 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - Python in the Czech Republic - - - - -{% endblock %} -{% block content %} - -
      -
    • - Python is a modern programming language. See python.org for details. -
    • -
    • - The Czech Python community is active and friendly. -
    • -
    • - Come and join us at meetups and workshops in several cities! -
    • -
    - -
    - Czech Python User Group -
    -
    - {% include '_communication.html' %} -
    - -
    - -
    -

    - - Closest Events -

    - {% include '_events.html' with context %} -

    - - - All events - -

    -
    - -
    - -
    - -
    -
    -
    -
    -

    - - Jobs -

    -

    - How can you address Czech software engineers working in Python with your job offer? Why is it worth the effort? -

    -
    -

    - - - Let me hunt some heads! - -

    -
    -
    - -
    - -
    -
    -
    -

    - - For Ladies -

    -

    - There are events for ladies in multiple Czech cities. -

    - -
    -

    - - - I want to get involved - -

    -
    -
    - -
    - -
    -
    -
    -

    - - PyCon CZ -

    -

    - Czech Python conference! Help us with preparations, spread the word, register a talk or workshop, consider sponsorship, or just come and enjoy the event! -

    -
    -

    - - - Let me be your speaker! - -

    -
    -
    - -
    - -
    -
    -
    -

    - - Library -

    -

    - We have a library of Python-related books. If you want to borrow one, let us know, and come to the nearest Pyvo meetup to pick the book up. By the way, you already know Python Books, right? -

    -
    -

    - - - What can I borrow? - -

    -
    -
    -
    -{% endblock %} diff --git a/pythoncz/templates/jobs_cs.html b/pythoncz/templates/jobs_cs.html deleted file mode 100644 index 6b08ec1e..00000000 --- a/pythoncz/templates/jobs_cs.html +++ /dev/null @@ -1,154 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - Python v ČR: Práce - - - - - - -{% endblock %} - -{% block body_class %}jobs{% endblock %} - -{% block breadcrumb %} - Práce -{% endblock %} - -{% block content %} -

    Python a práce

    -
    -
    -

    - Používá vůbec někdo Python? Ano! Jde o jazyk vhodný k výuce nebo skriptování, ale to neznamená, že jej nepoužívají firmy z celého světa a nepíšou se v něm rozsáhlé projekty. -

    -

    - Ve světě Python používají např. Blender 3D, Google (YouTube!), Dropbox, Disqus, IBM, Instagram, Lucasfilm, Mozilla, NASA, Spotify, Walt Disney, a mnoho dalších – mimo jiné také spousta vědeckých organizací včetně švýcarského CERNu. -

    -
    -
    - -
    - -
    - -

    Python u nás

    -
    -
    -
    -
    -
    - -
    -

    - - Firmy, instituce -

    - - -

    - - Jednotlivci -

    - -
    -

    - - - Chci být na seznamu - -

    - -
    - -

    Jak najít práci?

    -
    -
    - -
    -
    - -

    Jak najít Python programátory?

    -
    -
    -
      -
    • - Přijď na sraz a poptej se tam. Promluv si s reálnými lidmi, nadchni je, zlákej je, zjisti jaké mají možnosti a požadavky. -
    • -
    • - Popros svou společnost, aby sponzorovala příští PyCon CZ nebo PyCon SK. Obě konference jsou jedinečnou příležitostí promluvit si s 400+ vývojáři z celé střední Evropy. -
    • -
    • - Sepiš si inzerát a konkretizuj jej, aspoň do tvaru něčeho jako "hledám nadšence/nájemného profíka na krátkodobý projekt ve stylu CMS s galerií, nejspíš v Djangu, platím penězi". Čím víc bude lidsky od srdíčka a čím méně to budou odrážky ve stylu poptáváme/nabízíme, tím více lidí to zaujme. Nezapomeň napsat do jaké míry je možná práce na dálku. -
    • -
    • - Napiš inzerát na diskuse django-cs a py.cz (viz hlavní stránka) a na Facebookovou skupinu. Čte je mnoho českých a slovenských Pythonistů. -
    • -
    • - Nepřehlcuj žádnou z diskusí. Inzeráty jsou vítány, jsou zadarmo a bez omezení, ale pokud se to zvrhne, nemusí to tak zůstat. -
    • -
    • - Pošli inzerát na globální nástěnku nabídek – ta uveřejňuje nabídky zdarma, jen je potřeba se registrovat. Nabídka se pak objeví i na Twitter účtu @pyjobo. Inzeruj nabídku na pracovních serverech: {% for link in data.job_boards %}{{ link.name }}, {% endfor %}… -
    • -
    -
    -
    - -

    Chci, aby bylo víc Pythonistů!

    -
    -
    -

    - My taky! Máme na to dokonce neziskovku Pyvec. Můžeš se zapojit a s naší misí nám pomoci. -

    -

    - Pokud zastupuješ nějakou firmu, můžeš nás sponzorovat (číslo účtu). Přes Pyvec se peníze rozdělí na dílčí projekty. Podporujeme např. srazy a workshopy pro dámy – PyLadies, DjangoGirls. -

    -

    - Budeme také rádi, pokud nám napíšete success story o tom, jak jste Python použili u vás a jak vám to usnadnilo práci a co vše jste s ním dokázali. Takovou zkušenost zde rádi uveřejníme, klidně i na samostatné stránce, s logem apod. -

    -
    -
    -{% endblock %} - - -{% block scripts %} - - -{% endblock %} diff --git a/pythoncz/templates/jobs_en.html b/pythoncz/templates/jobs_en.html deleted file mode 100644 index 9d5eb668..00000000 --- a/pythoncz/templates/jobs_en.html +++ /dev/null @@ -1,113 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - Python in the Czech Republic: Jobs - - - - - - -{% endblock %} - -{% block body_class %}jobs{% endblock %} - -{% block breadcrumb %} - Jobs -{% endblock %} - -{% block content %} -

    Python Jobs

    - -

    Who uses Python in the Czech Republic?

    -
    -
    -
    -
    -
    - -
    -

    - - Companies, institutions -

    - - -

    - - Individuals -

    - -
    -

    - - - I want to be on the list - -

    - -
    - -

    How to find Czech Python software engineers?

    -
    -
    -
      -
    • - Attend a meetup and ask around. Speak to real people, get them hooked for your ideas, learn about their options and requirements. -
    • -
    • - Ask your company to sponsor the next PyCon CZ or PyCon SK conferences. Both are unique opportunities to speak with 400+ developers from the central-european region. -
    • -
    • - Write down a job offer. Honest story instead of boring bullet points will bring you larger audience. Don't forget to mention how much is it possible to work remotely. -
    • -
    • - Send the offer to django-cs and py.cz discussions (see homepage) and to the Facebook group. Many Czech Pythonistas are subscribed to them. -
    • -
    • - Please do not overuse any of the discussions. Job offers are welcome, they're free and without limitations, but if it starts to be annoying, it doesn't have to be without regulation forever. -
    • -
    • - Post the offer to global job board – the board is free, only registration is needed. The offer then appears also on @pyjobo Twitter account. Advertise also at Czech job boards: {% for link in data.job_boards %}{{ link.name }}, {% endfor %}… -
    • -
    -
    -
    - -

    I wish more Czech Pythonistas would exist!

    -
    -
    -

    - We too and it's also the main goal of Pyvec, our nonprofit. Pyvec is dedicated to support all sorts of activities focused on introducing more people to Python in the Czech Republic. Pyvec also supports local chapters of PyLadies and DjangoGirls. If you wish to sponsor our activities, please drop an e-mail to info@pyvec.org. -

    -
    -
    - -
    - -
    -{% endblock %} - - -{% block scripts %} - - -{% endblock %} diff --git a/pythoncz/templates/meta_redirect.html b/pythoncz/templates/meta_redirect.html deleted file mode 100644 index 7c460b55..00000000 --- a/pythoncz/templates/meta_redirect.html +++ /dev/null @@ -1,19 +0,0 @@ -{% extends '_base.html' %} -{% block head %} - - - - -{% endblock %} - -{% block content %} -

    Přesměrování

    -
    -
    -

    - Obsah této stránky byl přesunut na novou adresu: - {{ url }}. -

    -
    -
    -{% endblock %} diff --git a/pythoncz/views.py b/pythoncz/views.py deleted file mode 100644 index 7dfa5cfc..00000000 --- a/pythoncz/views.py +++ /dev/null @@ -1,242 +0,0 @@ -import logging -import os -import subprocess -import itertools -from fnmatch import fnmatch -from urllib.parse import quote_plus as url_quote_plus - -from arrow import Arrow -from flask import (render_template as _render_template, url_for, - request, make_response, send_from_directory, Response) - -from pythoncz import app, freezer -from pythoncz.models import jobs, beginners, github, events, meetups - - -INDEX_EVENTS_LIMIT = 3 - -logger = logging.getLogger(__name__) - - -# Templating - -def render_template(filename, **kwargs): - kwargs['template_url'] = app.config['TEMPLATES_DIR_URL'] + filename - return _render_template(filename, **kwargs) - - -@app.errorhandler(404) -def page_not_found(e): - return render_template('404.html'), 404 - - -@app.template_filter('urlencode') -def urlencode_filter(s): - return url_quote_plus(str(s).encode('utf8')) - - -@app.template_filter('format_dt') -def format_dt_filter(dt: Arrow, fmt): - return dt.to('Europe/Prague').strftime(fmt) - - -@app.template_filter('format_dt_iso') -def format_dt_iso_filter(dt: Arrow): - return dt.to('Europe/Prague').isoformat() - - -@app.template_filter('format_month') -def format_month_filter(month, lang='cs'): - months = {'en': [None, 'January', 'February', 'March', 'April', 'May', - 'June', 'July', 'August', 'September', 'October', - 'November', 'December'], - 'cs': [None, 'Leden', 'Únor', 'Březen', 'Duben', 'Květen', - 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', - 'Listopad', 'Prosinec']} - return months[lang][month] - - -@app.template_filter('format_weekday') -def format_weekday_filter(weekday, lang='cs'): - weekdays = {'en': ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', - 'Friday', 'Saturday'], - 'cs': ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', - 'pátek', 'sobota']} - return weekdays[lang][weekday] - - -@app.template_filter('format_weekday_short') -def format_weekday_short_filter(weekday, lang='cs'): - weekdays = {'en': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], - 'cs': ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so']} - return weekdays[lang][weekday] - - -@app.context_processor -def inject_context(): - return { - 'debug': app.debug, - 'config': app.config, - 'url': request.url, - 'lang': 'cs', - } - - -def by_month(event): - return (event['event'].begin.year, event['event'].begin.month) - - -# Regular views - -@app.route('/') -def index_cs(): - data = itertools.groupby(events.data[:INDEX_EVENTS_LIMIT], key=by_month) - return render_template('index_cs.html', data=data) - - -@app.route('/en/') -def index_en(): - data = itertools.groupby(events.data[:INDEX_EVENTS_LIMIT], key=by_month) - return render_template('index_en.html', lang='en', data=data) - - -@app.route('/zacatecnici/') -def beginners_cs(): - return render_template('beginners_cs.html', data=beginners.data) - - -@app.route('/prace/') -def jobs_cs(): - return render_template('jobs_cs.html', data=jobs.data) - - -@app.route('/en/jobs/') -def jobs_en(): - return render_template('jobs_en.html', data=jobs.data, lang='en') - - -@app.route('/akce/') -def events_cs(): - return render_template('events_cs.html', - data=itertools.groupby(events.data, key=by_month), - meetups=meetups.get_meetups()) - - -@app.route('/en/events/') -def events_en(): - return render_template('events_en.html', lang='en', - data=itertools.groupby(events.data, key=by_month), - meetups=meetups.get_meetups(lang='en')) - - -@app.route('/events.ics') -def events_ical(): - return Response(events.get_calendar().serialize(), mimetype='text/calendar') - - -@app.route('/zapojse/') -def get_involved_cs(): - disabled = os.getenv('DISABLE_GITHUB_ISSUES_FETCH', False) - issues = [] - error = None - if not disabled: - try: - issues = github.get_issues(app.config['GITHUB_ORGANIZATIONS']) - except Exception as e: - logger.exception('Failed to fetch GitHub issues') - error = e - template = render_template('get_involved_cs.html', issues=issues, error=error) - return make_response(template) - - -# Redirects of legacy stuff - -def redirect(url, code=None): - """Return a response with a Meta redirect, code is unused""" - - # With static pages, we can't use HTTP redirects. - # Return a page wit instead. - # - # When Frozen-Flask gets support for redirects - # (https://github.com/Frozen-Flask/Frozen-Flask/issues/81), - # this should be revisited. - - return render_template('meta_redirect.html', url=url) - - -@app.route('/english.html') -def index_en_legacy(): - return redirect(url_for('index_en'), code=301) - - -@app.route('/pyladies/') -def pyladies(target): - return redirect('http://pyladies.cz/v1/' + target, code=301) - - -@freezer.register_generator -def pyladies(): - # This is hardcoded because it doesn't change & it's easier to hardcode it - targets = ( - 's001-install/', - 's002-hello-world/', - 's003-looping/', - 's004-strings/', - 's005-modules/', - 's006-lists/', - 's007-cards/', - 's008-cards2/', - 's009-git/', - 's010-data/', - 's011-dicts/', - 's012-pyglet/', - 's014-class/', - 's015-asteroids/', - 's016-micropython/', - ) - yield from ({'target': t} for t in targets) - - -@app.route('/pyladies/') -def pyladies_index(): - return redirect('http://pyladies.cz/', code=301) - - -# Talks, this used to redirect, but that's not possible with *.pdf HTML files -talks_dir = 'talks-archive' - - -@app.before_first_request -def clone_talks(): - try: - os.chdir(talks_dir) - except FileNotFoundError: - subprocess.run(('git', 'clone', - 'https://github.com/pyvec/talks-archive', - '--depth', '1')) - os.chdir(talks_dir) - else: - subprocess.run(('git', 'fetch', 'origin'), check=True) - subprocess.run(('git', 'reset', '--hard', 'origin/master'), check=True) - finally: - os.chdir('..') - - -@app.route('/talks/') -def talks(target): - # sends from pythoncz directory, hence ../ - return send_from_directory(f'../{talks_dir}', target) - - -@freezer.register_generator -def talks(): - ignore = ['.travis.yml', '.gitignore'] - for name, dirs, files in os.walk(talks_dir): - if '.git' in dirs: - dirs.remove('.git') - for file in files: - if file == '.git': - continue - if not any(fnmatch(file, ig) for ig in ignore): - path = os.path.relpath(os.path.join(name, file), talks_dir) - yield {'target': path} diff --git a/runserver.py b/runserver.py deleted file mode 100755 index 36a6ac31..00000000 --- a/runserver.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python -from pythoncz import app, freezer - - -if __name__ == '__main__': - from elsa import cli - cli(app, freezer=freezer, base_url='https://python.cz') From 9bd09892fb20587e36eaba987726c12a360fbb27 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 26 Aug 2023 22:18:18 +0200 Subject: [PATCH 25/46] move readme to https://github.com/pyvec/python.cz/pull/559 --- README.md | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/README.md b/README.md index ef020242..a95d5f8b 100644 --- a/README.md +++ b/README.md @@ -2,36 +2,6 @@ Czech Python community homepage on MkDocs. -## Status - -See the website at [honzajavorek.github.io/mkdocs-python.cz](https://honzajavorek.github.io/mkdocs-python.cz/). -This is a proof of concept and a work in progress. - -## Goals - -- Give up on complicated custom solutions which have little added value, but enormous overhead -- Give up on custom design, because there is nobody in the community to maintain custom designs -- Use as much existing software as possible -- Make the website easy to maintain, easy to edit, easy to contribute - -Intentionally not trying to achieve feature parity with existing python.cz website. - -## TODO - -- ~~port static content~~ -- ~~customize the theme~~ -- ~~events as a plugin~~ -- ~~fix absolute links and make them relative~~ -- ~~icons~~ (index is here: https://emojipedia.org/twitter) -- ~~images~~ -- ~~legacy redirects~~ -- ~~analytics~~ -- ~~english version~~ -- ~~delete the old code~~ -- keep tests which make sense and delete the rest -- nice to have: social cards - https://squidfunk.github.io/mkdocs-material/setup/setting-up-social-cards/ -- nice to have: logo should be on a white circle - ## License [MIT](LICENSE) From 49175f09993dbac05f7a4ff7331164b0a221c665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Fri, 30 Aug 2024 15:46:20 +0200 Subject: [PATCH 26/46] just add space --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a95d5f8b..28bfcd1a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ Czech Python community homepage on MkDocs. + ## License [MIT](LICENSE) From 393790fbc2e5270ae282754ef1a9d58673c81d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Fri, 30 Aug 2024 17:42:45 +0200 Subject: [PATCH 27/46] integrate teemup for scraping events --- hooks/events.py | 18 +-- hooks/on_page_markdown.py | 1 + poetry.lock | 323 ++++++++++++++++++++++++++++---------- pyproject.toml | 1 + 4 files changed, 248 insertions(+), 95 deletions(-) diff --git a/hooks/events.py b/hooks/events.py index 86ba9618..34b43e82 100644 --- a/hooks/events.py +++ b/hooks/events.py @@ -6,7 +6,7 @@ from functools import cache from zoneinfo import ZoneInfo -import extruct +import teemup import ics import requests from strictyaml import load as load_yaml, Map, Str, Seq, Url @@ -123,18 +123,18 @@ def parse_icalendar(text: str) -> list[dict]: def parse_json_dl(html: str, base_url: str) -> list[dict]: - data = extruct.extract(html, base_url, syntaxes=["json-ld"]) + response = requests.get(base_url) + events = teemup.parse(response.text) return [ dict( - name=item["name"], - starts_at=to_prague_tz(datetime.fromisoformat(item["startDate"])), - ends_at=to_prague_tz(datetime.fromisoformat(item["endDate"])), - location=parse_json_dl_location(item["location"]), - url=item["url"], + name=event['title'], + starts_at=event['starts_at'], + ends_at=event['ends_at'], + location=event['venue'], + url=event['url'], is_tentative=False, ) - for item in data["json-ld"] - if item["@type"] == "Event" and base_url in item["url"] + for event in events ] diff --git a/hooks/on_page_markdown.py b/hooks/on_page_markdown.py index eeb7d8a7..b905e47f 100644 --- a/hooks/on_page_markdown.py +++ b/hooks/on_page_markdown.py @@ -23,6 +23,7 @@ def on_page_markdown( env = Environment() env.filters["urlencode"] = quote_plus template = env.from_string(markdown) + return template.render( events=filter_events(fetch_events(), days_limit=60, only_upcoming=True) ) diff --git a/poetry.lock b/poetry.lock index b3cb13ae..8c875b4a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,9 +1,10 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry and should not be changed by hand. [[package]] name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -22,6 +23,7 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "babel" version = "2.12.1" description = "Internationalization utilities" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -33,6 +35,7 @@ files = [ name = "beautifulsoup4" version = "4.12.2" description = "Screen-scraping library" +category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -51,6 +54,7 @@ lxml = ["lxml"] name = "black" version = "23.7.0" description = "The uncompromising code formatter." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -95,6 +99,7 @@ uvloop = ["uvloop (>=0.15.2)"] name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -106,6 +111,7 @@ files = [ name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -190,6 +196,7 @@ files = [ name = "click" version = "8.1.7" description = "Composable command line interface toolkit" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -204,6 +211,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -215,6 +223,7 @@ files = [ name = "cssselect" version = "1.2.0" description = "cssselect parses CSS3 Selectors and translates them to XPath 1.0" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -226,6 +235,7 @@ files = [ name = "extruct" version = "0.16.0" description = "Extract embedded metadata from HTML markup" +category = "main" optional = false python-versions = "*" files = [ @@ -250,6 +260,7 @@ cli = ["requests"] name = "ghp-import" version = "2.1.0" description = "Copy your docs directly to the gh-pages branch." +category = "main" optional = false python-versions = "*" files = [ @@ -267,6 +278,7 @@ dev = ["flake8", "markdown", "twine", "wheel"] name = "html-text" version = "0.5.2" description = "Extract text from HTML" +category = "main" optional = false python-versions = "*" files = [ @@ -281,6 +293,7 @@ lxml = "*" name = "html5lib" version = "1.1" description = "HTML parser based on the WHATWG HTML specification" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -302,6 +315,7 @@ lxml = ["lxml"] name = "ics" version = "0.8.0.dev0" description = "Pythonic iCalendar (RFC 5545) Parser" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -324,6 +338,7 @@ test = ["freezegun (>=1.2.1)", "hypothesis (>=6)", "importlib-resources (>=1.4)" name = "ics-vtimezones" version = "2020.1" description = "iCalendar vTimezone Data" +category = "main" optional = false python-versions = ">=3.6,<4.0" files = [ @@ -341,6 +356,7 @@ update = ["ics (>=0.8.0,<0.9.0)"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -352,6 +368,7 @@ files = [ name = "importlib-resources" version = "1.5.0" description = "Read resources from Python packages" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -366,6 +383,7 @@ docs = ["jaraco.packaging", "rst.linker", "sphinx"] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -377,6 +395,7 @@ files = [ name = "isodate" version = "0.6.1" description = "An ISO 8601 date/time/duration parser and formatter" +category = "main" optional = false python-versions = "*" files = [ @@ -391,6 +410,7 @@ six = "*" name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -408,6 +428,7 @@ i18n = ["Babel (>=2.7)"] name = "jstyleson" version = "0.0.2" description = "Library to parse JSON with js-style comments." +category = "main" optional = false python-versions = "*" files = [ @@ -416,104 +437,164 @@ files = [ [[package]] name = "lxml" -version = "4.9.3" +version = "5.3.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" +python-versions = ">=3.6" files = [ - {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, - {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, - {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, - {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, - {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, - {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"}, - {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"}, - {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"}, - {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"}, - {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"}, - {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"}, - {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"}, - {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"}, - {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"}, - {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"}, - {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"}, - {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"}, - {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"}, - {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"}, - {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"}, - {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"}, - {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"}, - {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"}, - {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"}, - {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"}, - {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"}, - {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"}, - {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"}, - {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"}, - {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"}, - {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"}, - {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"}, - {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"}, - {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"}, - {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"}, - {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"}, - {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"}, - {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"}, - {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"}, - {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"}, - {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"}, - {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"}, - {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"}, - {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"}, - {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"}, - {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"}, - {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"}, - {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"}, - {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"}, - {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"}, - {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"}, - {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"}, - {file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"}, - {file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"}, + {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656"}, + {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8"}, + {file = "lxml-5.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03"}, + {file = "lxml-5.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7"}, + {file = "lxml-5.3.0-cp310-cp310-win32.whl", hash = "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80"}, + {file = "lxml-5.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3"}, + {file = "lxml-5.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b"}, + {file = "lxml-5.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080"}, + {file = "lxml-5.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec"}, + {file = "lxml-5.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be"}, + {file = "lxml-5.3.0-cp311-cp311-win32.whl", hash = "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9"}, + {file = "lxml-5.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1"}, + {file = "lxml-5.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859"}, + {file = "lxml-5.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c"}, + {file = "lxml-5.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8"}, + {file = "lxml-5.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d"}, + {file = "lxml-5.3.0-cp312-cp312-win32.whl", hash = "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30"}, + {file = "lxml-5.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f"}, + {file = "lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a"}, + {file = "lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367"}, + {file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb"}, + {file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b"}, + {file = "lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957"}, + {file = "lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d"}, + {file = "lxml-5.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8f0de2d390af441fe8b2c12626d103540b5d850d585b18fcada58d972b74a74e"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1afe0a8c353746e610bd9031a630a95bcfb1a720684c3f2b36c4710a0a96528f"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56b9861a71575f5795bde89256e7467ece3d339c9b43141dbdd54544566b3b94"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:9fb81d2824dff4f2e297a276297e9031f46d2682cafc484f49de182aa5e5df99"}, + {file = "lxml-5.3.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2c226a06ecb8cdef28845ae976da407917542c5e6e75dcac7cc33eb04aaeb237"}, + {file = "lxml-5.3.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:7d3d1ca42870cdb6d0d29939630dbe48fa511c203724820fc0fd507b2fb46577"}, + {file = "lxml-5.3.0-cp36-cp36m-win32.whl", hash = "sha256:094cb601ba9f55296774c2d57ad68730daa0b13dc260e1f941b4d13678239e70"}, + {file = "lxml-5.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:eafa2c8658f4e560b098fe9fc54539f86528651f61849b22111a9b107d18910c"}, + {file = "lxml-5.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cb83f8a875b3d9b458cada4f880fa498646874ba4011dc974e071a0a84a1b033"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25f1b69d41656b05885aa185f5fdf822cb01a586d1b32739633679699f220391"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23e0553b8055600b3bf4a00b255ec5c92e1e4aebf8c2c09334f8368e8bd174d6"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ada35dd21dc6c039259596b358caab6b13f4db4d4a7f8665764d616daf9cc1d"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:81b4e48da4c69313192d8c8d4311e5d818b8be1afe68ee20f6385d0e96fc9512"}, + {file = "lxml-5.3.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:2bc9fd5ca4729af796f9f59cd8ff160fe06a474da40aca03fcc79655ddee1a8b"}, + {file = "lxml-5.3.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:07da23d7ee08577760f0a71d67a861019103e4812c87e2fab26b039054594cc5"}, + {file = "lxml-5.3.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:ea2e2f6f801696ad7de8aec061044d6c8c0dd4037608c7cab38a9a4d316bfb11"}, + {file = "lxml-5.3.0-cp37-cp37m-win32.whl", hash = "sha256:5c54afdcbb0182d06836cc3d1be921e540be3ebdf8b8a51ee3ef987537455f84"}, + {file = "lxml-5.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f2901429da1e645ce548bf9171784c0f74f0718c3f6150ce166be39e4dd66c3e"}, + {file = "lxml-5.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c56a1d43b2f9ee4786e4658c7903f05da35b923fb53c11025712562d5cc02753"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ee8c39582d2652dcd516d1b879451500f8db3fe3607ce45d7c5957ab2596040"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdf3a3059611f7585a78ee10399a15566356116a4288380921a4b598d807a22"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:146173654d79eb1fc97498b4280c1d3e1e5d58c398fa530905c9ea50ea849b22"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:0a7056921edbdd7560746f4221dca89bb7a3fe457d3d74267995253f46343f15"}, + {file = "lxml-5.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:9e4b47ac0f5e749cfc618efdf4726269441014ae1d5583e047b452a32e221920"}, + {file = "lxml-5.3.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f914c03e6a31deb632e2daa881fe198461f4d06e57ac3d0e05bbcab8eae01945"}, + {file = "lxml-5.3.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:213261f168c5e1d9b7535a67e68b1f59f92398dd17a56d934550837143f79c42"}, + {file = "lxml-5.3.0-cp38-cp38-win32.whl", hash = "sha256:218c1b2e17a710e363855594230f44060e2025b05c80d1f0661258142b2add2e"}, + {file = "lxml-5.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:315f9542011b2c4e1d280e4a20ddcca1761993dda3afc7a73b01235f8641e903"}, + {file = "lxml-5.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1ffc23010330c2ab67fac02781df60998ca8fe759e8efde6f8b756a20599c5de"}, + {file = "lxml-5.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2b3778cb38212f52fac9fe913017deea2fdf4eb1a4f8e4cfc6b009a13a6d3fcc"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b0c7a688944891086ba192e21c5229dea54382f4836a209ff8d0a660fac06be"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:747a3d3e98e24597981ca0be0fd922aebd471fa99d0043a3842d00cdcad7ad6a"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86a6b24b19eaebc448dc56b87c4865527855145d851f9fc3891673ff97950540"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b11a5d918a6216e521c715b02749240fb07ae5a1fefd4b7bf12f833bc8b4fe70"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68b87753c784d6acb8a25b05cb526c3406913c9d988d51f80adecc2b0775d6aa"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:109fa6fede314cc50eed29e6e56c540075e63d922455346f11e4d7a036d2b8cf"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:02ced472497b8362c8e902ade23e3300479f4f43e45f4105c85ef43b8db85229"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:6b038cc86b285e4f9fea2ba5ee76e89f21ed1ea898e287dc277a25884f3a7dfe"}, + {file = "lxml-5.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:7437237c6a66b7ca341e868cda48be24b8701862757426852c9b3186de1da8a2"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7f41026c1d64043a36fda21d64c5026762d53a77043e73e94b71f0521939cc71"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:482c2f67761868f0108b1743098640fbb2a28a8e15bf3f47ada9fa59d9fe08c3"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:1483fd3358963cc5c1c9b122c80606a3a79ee0875bcac0204149fa09d6ff2727"}, + {file = "lxml-5.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dec2d1130a9cda5b904696cec33b2cfb451304ba9081eeda7f90f724097300a"}, + {file = "lxml-5.3.0-cp39-cp39-win32.whl", hash = "sha256:a0eabd0a81625049c5df745209dc7fcef6e2aea7793e5f003ba363610aa0a3ff"}, + {file = "lxml-5.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:89e043f1d9d341c52bf2af6d02e6adde62e0a46e6755d5eb60dc6e4f0b8aeca2"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83"}, + {file = "lxml-5.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:94d6c3782907b5e40e21cadf94b13b0842ac421192f26b84c45f13f3c9d5dc27"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c300306673aa0f3ed5ed9372b21867690a17dba38c68c44b287437c362ce486b"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d9b952e07aed35fe2e1a7ad26e929595412db48535921c5013edc8aa4a35ce"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:01220dca0d066d1349bd6a1726856a78f7929f3878f7e2ee83c296c69495309e"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2d9b8d9177afaef80c53c0a9e30fa252ff3036fb1c6494d427c066a4ce6a282f"}, + {file = "lxml-5.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:20094fc3f21ea0a8669dc4c61ed7fa8263bd37d97d93b90f28fc613371e7a875"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ace2c2326a319a0bb8a8b0e5b570c764962e95818de9f259ce814ee666603f19"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92e67a0be1639c251d21e35fe74df6bcc40cba445c2cda7c4a967656733249e2"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd5350b55f9fecddc51385463a4f67a5da829bc741e38cf689f38ec9023f54ab"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c1fefd7e3d00921c44dc9ca80a775af49698bbfd92ea84498e56acffd4c5469"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:71a8dd38fbd2f2319136d4ae855a7078c69c9a38ae06e0c17c73fd70fc6caad8"}, + {file = "lxml-5.3.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:97acf1e1fd66ab53dacd2c35b319d7e548380c2e9e8c54525c6e76d21b1ae3b1"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:68934b242c51eb02907c5b81d138cb977b2129a0a75a8f8b60b01cb8586c7b21"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b710bc2b8292966b23a6a0121f7a6c51d45d2347edcc75f016ac123b8054d3f2"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18feb4b93302091b1541221196a2155aa296c363fd233814fa11e181adebc52f"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3eb44520c4724c2e1a57c0af33a379eee41792595023f367ba3952a2d96c2aab"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:609251a0ca4770e5a8768ff902aa02bf636339c5a93f9349b48eb1f606f7f3e9"}, + {file = "lxml-5.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:516f491c834eb320d6c843156440fe7fc0d50b33e44387fcec5b02f0bc118a4c"}, + {file = "lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f"}, ] [package.extras] cssselect = ["cssselect (>=0.7)"] +html-clean = ["lxml-html-clean"] html5 = ["html5lib"] htmlsoup = ["BeautifulSoup4"] -source = ["Cython (>=0.29.35)"] +source = ["Cython (>=3.0.11)"] [[package]] name = "markdown" version = "3.4.4" description = "Python implementation of John Gruber's Markdown." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -529,6 +610,7 @@ testing = ["coverage", "pyyaml"] name = "markdown2" version = "2.4.10" description = "A fast and complete Python implementation of Markdown" +category = "main" optional = false python-versions = ">=3.5, <4" files = [ @@ -545,6 +627,7 @@ wavedrom = ["wavedrom"] name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -568,6 +651,16 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -604,6 +697,7 @@ files = [ name = "mergedeep" version = "1.3.4" description = "A deep merge function for 🐍." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -615,6 +709,7 @@ files = [ name = "mf2py" version = "1.1.3" description = "Python Microformats2 parser" +category = "main" optional = false python-versions = ">=2.7" files = [ @@ -631,6 +726,7 @@ requests = ">=2.18.4" name = "mkdocs" version = "1.5.2" description = "Project documentation with Markdown." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -661,6 +757,7 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp name = "mkdocs-material" version = "9.2.3" description = "Documentation that simply works" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -687,6 +784,7 @@ requests = ">=2.26" name = "mkdocs-material-extensions" version = "1.1.1" description = "Extension pack for Python Markdown and MkDocs Material." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -698,6 +796,7 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -709,6 +808,7 @@ files = [ name = "packaging" version = "23.1" description = "Core utilities for Python packages" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -720,6 +820,7 @@ files = [ name = "paginate" version = "0.5.6" description = "Divides large result sets into pages for easier browsing" +category = "main" optional = false python-versions = "*" files = [ @@ -730,6 +831,7 @@ files = [ name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -741,6 +843,7 @@ files = [ name = "platformdirs" version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -756,6 +859,7 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "pluggy" version = "1.2.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -771,6 +875,7 @@ testing = ["pytest", "pytest-benchmark"] name = "pygments" version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -785,6 +890,7 @@ plugins = ["importlib-metadata"] name = "pymdown-extensions" version = "10.1" description = "Extension pack for Python Markdown." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -800,6 +906,7 @@ pyyaml = "*" name = "pyparsing" version = "3.1.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "main" optional = false python-versions = ">=3.6.8" files = [ @@ -814,6 +921,7 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pyquery" version = "2.0.0" description = "A jquery-like library for python" +category = "main" optional = false python-versions = "*" files = [ @@ -832,6 +940,7 @@ test = ["pytest", "pytest-cov", "requests", "webob", "webtest"] name = "pyrdfa3" version = "3.5.3" description = "pyRdfa Libray" +category = "main" optional = false python-versions = "*" files = [ @@ -847,6 +956,7 @@ rdflib = "*" name = "pytest" version = "7.4.0" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -867,6 +977,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -881,6 +992,7 @@ six = ">=1.5" name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -889,6 +1001,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -896,8 +1009,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -914,6 +1035,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -921,6 +1043,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -930,6 +1053,7 @@ files = [ name = "pyyaml-env-tag" version = "0.1" description = "A custom YAML tag for referencing environment variables in YAML files. " +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -944,6 +1068,7 @@ pyyaml = "*" name = "rdflib" version = "7.0.0" description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." +category = "main" optional = false python-versions = ">=3.8.1,<4.0.0" files = [ @@ -965,6 +1090,7 @@ networkx = ["networkx (>=2.0.0,<3.0.0)"] name = "readtime" version = "3.0.0" description = "Calculates the time some text takes the average human to read, based on Medium's read time forumula" +category = "main" optional = false python-versions = "*" files = [ @@ -980,6 +1106,7 @@ pyquery = ">=1.2" name = "regex" version = "2023.8.8" description = "Alternative regular expression module, to replace re." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1077,6 +1204,7 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1098,6 +1226,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1109,6 +1238,7 @@ files = [ name = "soupsieve" version = "2.4.1" description = "A modern CSS selector implementation for Beautiful Soup." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1120,6 +1250,7 @@ files = [ name = "strictyaml" version = "1.7.3" description = "Strict, typed YAML parser" +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -1130,10 +1261,27 @@ files = [ [package.dependencies] python-dateutil = ">=2.6.0" +[[package]] +name = "teemup" +version = "1.0.3" +description = "If Meetup didn't become a walled garden, the world wouldn't need Teemup" +category = "main" +optional = false +python-versions = "==3.11.*" +files = [ + {file = "teemup-1.0.3-py3-none-any.whl", hash = "sha256:f4e18eccc6a56bc9c8b628dc35dd65ec82a97e7b2140be802cd839cc49b188d6"}, + {file = "teemup-1.0.3.tar.gz", hash = "sha256:577945c42e143d1239913b962587efae4722b90e3eb6c1af1974324045dcaf23"}, +] + +[package.dependencies] +cssselect = "1.2.0" +lxml = "5.3.0" + [[package]] name = "urllib3" version = "2.0.4" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1151,6 +1299,7 @@ zstd = ["zstandard (>=0.18.0)"] name = "w3lib" version = "2.1.2" description = "Library of web-related functions" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1162,6 +1311,7 @@ files = [ name = "watchdog" version = "3.0.0" description = "Filesystem events monitoring" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1201,6 +1351,7 @@ watchmedo = ["PyYAML (>=3.10)"] name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" +category = "main" optional = false python-versions = "*" files = [ @@ -1211,4 +1362,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "7ce9107733e04473f1fd9a96ac0380206476b5ec61f238572a6a29d24fb6919b" +content-hash = "681aba0e549c066c44eb1621ee063f00bcd171dbc1b3783e7be6f6baa313173d" diff --git a/pyproject.toml b/pyproject.toml index 6cc4255b..f2c81fb4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ strictyaml = "1.7.3" ics = {version = "0.8.0.dev0", allow-prereleases = true} extruct = "0.16.0" requests = "2.31.0" +teemup = "^1.0.3" [tool.poetry.group.dev.dependencies] pytest = "7.4.0" From 68ef0dc925d81e4b18200a93320bc47c6ef8ff4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Fri, 30 Aug 2024 18:46:10 +0200 Subject: [PATCH 28/46] removing obsolete entrypoint --- app.py | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 app.py diff --git a/app.py b/app.py deleted file mode 100644 index 25c6a0ae..00000000 --- a/app.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env python - - -from pythoncz import app as application # NOQA - - -application.config['SERVER_NAME'] = 'python.cz' From 5f1ab72d6e269ddc4e000ebacd80f01dd24dc35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Fri, 30 Aug 2024 18:47:39 +0200 Subject: [PATCH 29/46] add README by notes for development --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 28bfcd1a..8ddc9540 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,13 @@ Czech Python community homepage on MkDocs. +# How to run (for development) + +1. clone repository +1. `poetry install` +1. activate venv (created by poetry by itself, if it's not activated already) +1. `PYTHONPATH=. mkdocs serve` + ## License From 26faf924715d397adfe04dc31f36eeef3aa23dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sat, 31 Aug 2024 12:43:42 +0200 Subject: [PATCH 30/46] add PYTHONPATH to build --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ef0a64be..5289219a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,6 +29,8 @@ jobs: - name: Build run: poetry run mkdocs build + env: + PYTHONPATH: . - if: ${{ github.ref == 'refs/heads/main' }} name: Deploy to GitHub Pages From 94262d08daa5c2d252e0da3c669a3913fb47a6d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sat, 31 Aug 2024 13:04:14 +0200 Subject: [PATCH 31/46] watch also hooks folder --- mkdocs.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index 9a3315dc..b953ac23 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -54,3 +54,8 @@ extra_css: - css/extra.css plugins: [] + + +watch: + - docs + - hooks From e8fd1a3c16512156eb9c94ce2ada1ec8f2ab046e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sat, 31 Aug 2024 13:07:29 +0200 Subject: [PATCH 32/46] remove extruct --- poetry.lock | 184 +------------------------------------------------ pyproject.toml | 1 - 2 files changed, 1 insertion(+), 184 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8c875b4a..e6e854b2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -231,31 +231,6 @@ files = [ {file = "cssselect-1.2.0.tar.gz", hash = "sha256:666b19839cfaddb9ce9d36bfe4c969132c647b92fc9088c4e23f786b30f1b3dc"}, ] -[[package]] -name = "extruct" -version = "0.16.0" -description = "Extract embedded metadata from HTML markup" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "extruct-0.16.0-py2.py3-none-any.whl", hash = "sha256:2499ea9e7d22744745ca708acee9542a4aa231871620c4f65f869a1286e64aa8"}, - {file = "extruct-0.16.0.tar.gz", hash = "sha256:d09cb3d86d149a276b277b3bd45b2b867ef3ec78bed9cd58ee0f2ae01ae670c4"}, -] - -[package.dependencies] -html-text = ">=0.5.1" -jstyleson = "*" -lxml = "*" -mf2py = "*" -pyrdfa3 = "*" -rdflib = {version = ">=6.0.0", markers = "python_version >= \"3.7\""} -six = "*" -w3lib = "*" - -[package.extras] -cli = ["requests"] - [[package]] name = "ghp-import" version = "2.1.0" @@ -274,43 +249,6 @@ python-dateutil = ">=2.8.1" [package.extras] dev = ["flake8", "markdown", "twine", "wheel"] -[[package]] -name = "html-text" -version = "0.5.2" -description = "Extract text from HTML" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "html_text-0.5.2-py2.py3-none-any.whl", hash = "sha256:3f1e063f05eddf3e099a88f0440219c55fdc01c44f1291fe59c66e5228d7fc56"}, - {file = "html_text-0.5.2.tar.gz", hash = "sha256:afd61bbb70651d494a8c32670a29b9140492eccc9690109857beae41c3093ded"}, -] - -[package.dependencies] -lxml = "*" - -[[package]] -name = "html5lib" -version = "1.1" -description = "HTML parser based on the WHATWG HTML specification" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, - {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, -] - -[package.dependencies] -six = ">=1.9" -webencodings = "*" - -[package.extras] -all = ["chardet (>=2.2)", "genshi", "lxml"] -chardet = ["chardet (>=2.2)"] -genshi = ["genshi"] -lxml = ["lxml"] - [[package]] name = "ics" version = "0.8.0.dev0" @@ -391,21 +329,6 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] -[[package]] -name = "isodate" -version = "0.6.1" -description = "An ISO 8601 date/time/duration parser and formatter" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, - {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, -] - -[package.dependencies] -six = "*" - [[package]] name = "jinja2" version = "3.1.2" @@ -424,17 +347,6 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] -[[package]] -name = "jstyleson" -version = "0.0.2" -description = "Library to parse JSON with js-style comments." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "jstyleson-0.0.2.tar.gz", hash = "sha256:680003f3b15a2959e4e6a351f3b858e3c07dd3e073a0d54954e34d8ea5e1308e"}, -] - [[package]] name = "lxml" version = "5.3.0" @@ -705,23 +617,6 @@ files = [ {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, ] -[[package]] -name = "mf2py" -version = "1.1.3" -description = "Python Microformats2 parser" -category = "main" -optional = false -python-versions = ">=2.7" -files = [ - {file = "mf2py-1.1.3-py3-none-any.whl", hash = "sha256:8f9e2c147beadd56f8839644124c7d141d96e879319b9f50d02826c88766bf4d"}, - {file = "mf2py-1.1.3.tar.gz", hash = "sha256:4241e91ed4b644dd666d9fbd2557ed86e5bb7399c196026f7b0a1f413b33f59f"}, -] - -[package.dependencies] -BeautifulSoup4 = ">=4.6.0" -html5lib = ">=1.0.1" -requests = ">=2.18.4" - [[package]] name = "mkdocs" version = "1.5.2" @@ -902,21 +797,6 @@ files = [ markdown = ">=3.2" pyyaml = "*" -[[package]] -name = "pyparsing" -version = "3.1.1" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -category = "main" -optional = false -python-versions = ">=3.6.8" -files = [ - {file = "pyparsing-3.1.1-py3-none-any.whl", hash = "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb"}, - {file = "pyparsing-3.1.1.tar.gz", hash = "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - [[package]] name = "pyquery" version = "2.0.0" @@ -936,22 +816,6 @@ lxml = ">=2.1" [package.extras] test = ["pytest", "pytest-cov", "requests", "webob", "webtest"] -[[package]] -name = "pyrdfa3" -version = "3.5.3" -description = "pyRdfa Libray" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "pyRdfa3-3.5.3-py3-none-any.whl", hash = "sha256:4da7ed49e8f524b573ed67e4f7bc7f403bff3be00546d7438fe263c924a91ccf"}, - {file = "pyRdfa3-3.5.3.tar.gz", hash = "sha256:157663a92b87df345b6f69bde235dff5f797891608e12fe1e4fa8dad687131ae"}, -] - -[package.dependencies] -html5lib = "*" -rdflib = "*" - [[package]] name = "pytest" version = "7.4.0" @@ -1064,28 +928,6 @@ files = [ [package.dependencies] pyyaml = "*" -[[package]] -name = "rdflib" -version = "7.0.0" -description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." -category = "main" -optional = false -python-versions = ">=3.8.1,<4.0.0" -files = [ - {file = "rdflib-7.0.0-py3-none-any.whl", hash = "sha256:0438920912a642c866a513de6fe8a0001bd86ef975057d6962c79ce4771687cd"}, - {file = "rdflib-7.0.0.tar.gz", hash = "sha256:9995eb8569428059b8c1affd26b25eac510d64f5043d9ce8c84e0d0036e995ae"}, -] - -[package.dependencies] -isodate = ">=0.6.0,<0.7.0" -pyparsing = ">=2.1.0,<4" - -[package.extras] -berkeleydb = ["berkeleydb (>=18.1.0,<19.0.0)"] -html = ["html5lib (>=1.0,<2.0)"] -lxml = ["lxml (>=4.3.0,<5.0.0)"] -networkx = ["networkx (>=2.0.0,<3.0.0)"] - [[package]] name = "readtime" version = "3.0.0" @@ -1295,18 +1137,6 @@ secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17. socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] -[[package]] -name = "w3lib" -version = "2.1.2" -description = "Library of web-related functions" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "w3lib-2.1.2-py3-none-any.whl", hash = "sha256:c4432926e739caa8e3f49f5de783f336df563d9490416aebd5d39fb896d264e7"}, - {file = "w3lib-2.1.2.tar.gz", hash = "sha256:ed5b74e997eea2abe3c1321f916e344144ee8e9072a6f33463ee8e57f858a4b1"}, -] - [[package]] name = "watchdog" version = "3.0.0" @@ -1347,19 +1177,7 @@ files = [ [package.extras] watchmedo = ["PyYAML (>=3.10)"] -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] - [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "681aba0e549c066c44eb1621ee063f00bcd171dbc1b3783e7be6f6baa313173d" +content-hash = "1227118ca0f1fd98c06ee678e853c28fd1c93a472b1d965629ecb1e4f0e88f60" diff --git a/pyproject.toml b/pyproject.toml index f2c81fb4..909f5e5e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,6 @@ mkdocs = "1.5.2" mkdocs-material = "9.2.3" strictyaml = "1.7.3" ics = {version = "0.8.0.dev0", allow-prereleases = true} -extruct = "0.16.0" requests = "2.31.0" teemup = "^1.0.3" From 1d9d1733abf7c1e16e5376ef6ea6a88025cbb74b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sat, 31 Aug 2024 14:36:07 +0200 Subject: [PATCH 33/46] poetry, just download deps --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 909f5e5e..3d031c05 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] -name = "pythoncz" -version = "0.0.0" description = "Czech Python user group homepage" authors = ["Honza Javorek "] readme = "README.md" homepage = "https://python.cz/" repository = "https://github.com/honzajavorek/mkdocs-python.cz/" classifiers = ["Private :: Do Not Upload"] +package-mode = false + [tool.poetry.dependencies] python = "3.11.*" From 55dc9821a78404195aa6885997e4089f39127b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sat, 31 Aug 2024 14:39:45 +0200 Subject: [PATCH 34/46] fix link syntax at zapojse page --- docs/zapojse.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zapojse.md b/docs/zapojse.md index fa791ae7..3e85dfad 100644 --- a/docs/zapojse.md +++ b/docs/zapojse.md @@ -92,4 +92,4 @@ navrhnout jako kouč, napiš to do komentáře pod daný úkol a [přiřaď mu TODO - zrušit, možná udělat jen seznam organizací nebo repozitářů -![Přidat nápad](https://github.com/pyvec/zapojse/issues/new) +[Přidat nápad](https://github.com/pyvec/zapojse/issues/new) From e10732eee48fbf3eec3f690e60fdbce7be0e5bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sat, 31 Aug 2024 14:42:07 +0200 Subject: [PATCH 35/46] remove path from gh actions --- .github/workflows/build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5289219a..ef0a64be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,8 +29,6 @@ jobs: - name: Build run: poetry run mkdocs build - env: - PYTHONPATH: . - if: ${{ github.ref == 'refs/heads/main' }} name: Deploy to GitHub Pages From 21bd14287b496c29ecf6a294db4f51d1c4e63173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sat, 31 Aug 2024 14:58:18 +0200 Subject: [PATCH 36/46] try to disable a lot of gh actions --- .github/workflows/build.yml | 50 ++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ef0a64be..be25a1fc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,28 +12,28 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Install Poetry - run: pipx install poetry - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: 3.11 - cache: poetry - - - name: Install dependencies - run: poetry install - - # - name: Test - # run: poetry run pytest - - - name: Build - run: poetry run mkdocs build - - - if: ${{ github.ref == 'refs/heads/main' }} - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./site - #cname: python.cz + # - name: Install Poetry + # run: pipx install poetry + # + # - name: Set up Python + # uses: actions/setup-python@v4 + # with: + # python-version: 3.11 + # cache: poetry + # + # - name: Install dependencies + # run: poetry install + # + # # - name: Test + # # run: poetry run pytest + # + # - name: Build + # run: poetry run mkdocs build + # + # - if: ${{ github.ref == 'refs/heads/main' }} + # name: Deploy to GitHub Pages + # uses: peaceiris/actions-gh-pages@v3 + # with: + # github_token: ${{ secrets.GITHUB_TOKEN }} + # publish_dir: ./site + # #cname: python.cz From 6b1769d1e4d054651284fee8ffad1083aba29d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sat, 31 Aug 2024 15:02:58 +0200 Subject: [PATCH 37/46] gh actions troubleshooting --- .github/workflows/build.yml | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index be25a1fc..0a76a81b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,28 +12,6 @@ jobs: steps: - uses: actions/checkout@v3 - # - name: Install Poetry - # run: pipx install poetry - # - # - name: Set up Python - # uses: actions/setup-python@v4 - # with: - # python-version: 3.11 - # cache: poetry - # - # - name: Install dependencies - # run: poetry install - # - # # - name: Test - # # run: poetry run pytest - # - # - name: Build - # run: poetry run mkdocs build - # - # - if: ${{ github.ref == 'refs/heads/main' }} - # name: Deploy to GitHub Pages - # uses: peaceiris/actions-gh-pages@v3 - # with: - # github_token: ${{ secrets.GITHUB_TOKEN }} - # publish_dir: ./site - # #cname: python.cz + - name: Install Poetry + run: pipx install poetry + From 6a2ebff2087cf379ab9f43a0ff956365f4933a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sat, 31 Aug 2024 15:09:48 +0200 Subject: [PATCH 38/46] gh actions troubleshooting hopefully --- .github/workflows/build.yml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0a76a81b..5289219a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,4 +14,28 @@ jobs: - name: Install Poetry run: pipx install poetry - + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 + cache: poetry + + - name: Install dependencies + run: poetry install + + # - name: Test + # run: poetry run pytest + + - name: Build + run: poetry run mkdocs build + env: + PYTHONPATH: . + + - if: ${{ github.ref == 'refs/heads/main' }} + name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./site + #cname: python.cz From fd205485837fcc019041abac0681694d24fce27c Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 31 Aug 2024 15:41:40 +0200 Subject: [PATCH 39/46] upgrade mkdocs to 1.6 --- poetry.lock | 923 +++++++++++++++++++++++++------------------------ pyproject.toml | 5 +- 2 files changed, 465 insertions(+), 463 deletions(-) diff --git a/poetry.lock b/poetry.lock index e6e854b2..9f92cc8a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,52 +1,56 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "attrs" -version = "23.1.0" +version = "24.2.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "babel" -version = "2.12.1" +version = "2.16.0" description = "Internationalization utilities" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, - {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + [[package]] name = "beautifulsoup4" -version = "4.12.2" +version = "4.12.3" description = "Screen-scraping library" -category = "main" optional = false python-versions = ">=3.6.0" files = [ - {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, - {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, ] [package.dependencies] soupsieve = ">1.2" [package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] html5lib = ["html5lib"] lxml = ["lxml"] @@ -54,7 +58,6 @@ lxml = ["lxml"] name = "black" version = "23.7.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -97,106 +100,118 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2023.7.22" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] name = "charset-normalizer" -version = "3.2.0" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -211,7 +226,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -223,7 +237,6 @@ files = [ name = "cssselect" version = "1.2.0" description = "cssselect parses CSS3 Selectors and translates them to XPath 1.0" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -235,7 +248,6 @@ files = [ name = "ghp-import" version = "2.1.0" description = "Copy your docs directly to the gh-pages branch." -category = "main" optional = false python-versions = "*" files = [ @@ -253,7 +265,6 @@ dev = ["flake8", "markdown", "twine", "wheel"] name = "ics" version = "0.8.0.dev0" description = "Pythonic iCalendar (RFC 5545) Parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -274,54 +285,55 @@ test = ["freezegun (>=1.2.1)", "hypothesis (>=6)", "importlib-resources (>=1.4)" [[package]] name = "ics-vtimezones" -version = "2020.1" +version = "2020.2" description = "iCalendar vTimezone Data" -category = "main" optional = false -python-versions = ">=3.6,<4.0" +python-versions = ">=3.7,<4.0" files = [ - {file = "ics_vtimezones-2020.1-py3-none-any.whl", hash = "sha256:775f0c3a9a417a9466e511bc1068e239036f4ea405a55d0cec0ba95e551717c4"}, - {file = "ics_vtimezones-2020.1.tar.gz", hash = "sha256:04ab770ceb68a304de65be12257340c74e811cc925e771c10aab166de05768c6"}, + {file = "ics_vtimezones-2020.2-py3-none-any.whl", hash = "sha256:e26de1a7e732b53f23bce88431ce6b2db59d03aad72f47d5785bfa3f56cdf118"}, + {file = "ics_vtimezones-2020.2.tar.gz", hash = "sha256:ee02fb3bb7df7e2e60ea11ad07ca30d3fee4d40929ae496651f76b76dc1cac73"}, ] [package.dependencies] -importlib_resources = ">=1.4,<2.0" +importlib_resources = ">=1.4" [package.extras] -update = ["ics (>=0.8.0,<0.9.0)"] +update = ["ics (==0.8.*)"] [[package]] name = "idna" -version = "3.4" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] name = "importlib-resources" -version = "1.5.0" +version = "6.4.4" description = "Read resources from Python packages" -category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.8" files = [ - {file = "importlib_resources-1.5.0-py2.py3-none-any.whl", hash = "sha256:85dc0b9b325ff78c8bef2e4ff42616094e16b98ebd5e3b50fe7e2f0bbcdcde49"}, - {file = "importlib_resources-1.5.0.tar.gz", hash = "sha256:6f87df66833e1942667108628ec48900e02a4ab4ad850e25fbf07cb17cf734ca"}, + {file = "importlib_resources-6.4.4-py3-none-any.whl", hash = "sha256:dda242603d1c9cd836c3368b1174ed74cb4049ecd209e7a1a0104620c18c5c11"}, + {file = "importlib_resources-6.4.4.tar.gz", hash = "sha256:20600c8b7361938dc0bb2d5ec0297802e575df486f5a544fa414da65e13721f7"}, ] [package.extras] -docs = ["jaraco.packaging", "rst.linker", "sphinx"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] +type = ["pytest-mypy"] [[package]] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -331,14 +343,13 @@ files = [ [[package]] name = "jinja2" -version = "3.1.2" +version = "3.1.4" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, ] [package.dependencies] @@ -351,7 +362,6 @@ i18n = ["Babel (>=2.7)"] name = "lxml" version = "5.3.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -504,112 +514,109 @@ source = ["Cython (>=3.0.11)"] [[package]] name = "markdown" -version = "3.4.4" +version = "3.7" description = "Python implementation of John Gruber's Markdown." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Markdown-3.4.4-py3-none-any.whl", hash = "sha256:a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941"}, - {file = "Markdown-3.4.4.tar.gz", hash = "sha256:225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6"}, + {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, + {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, ] [package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.0)", "mkdocs-nature (>=0.4)"] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] testing = ["coverage", "pyyaml"] [[package]] name = "markdown2" -version = "2.4.10" +version = "2.5.0" description = "A fast and complete Python implementation of Markdown" -category = "main" optional = false -python-versions = ">=3.5, <4" +python-versions = "<4,>=3.8" files = [ - {file = "markdown2-2.4.10-py2.py3-none-any.whl", hash = "sha256:e6105800483783831f5dc54f827aa5b44eb137ecef5a70293d8ecfbb4109ecc6"}, - {file = "markdown2-2.4.10.tar.gz", hash = "sha256:cdba126d90dc3aef6f4070ac342f974d63f415678959329cc7909f96cc235d72"}, + {file = "markdown2-2.5.0-py2.py3-none-any.whl", hash = "sha256:300d4429b620ebc974ef512339a9e08bc080473f95135a91f33906e24e8280c1"}, + {file = "markdown2-2.5.0.tar.gz", hash = "sha256:9bff02911f8b617b61eb269c4c1a5f9b2087d7ff051604f66a61b63cab30adc2"}, ] [package.extras] -all = ["pygments (>=2.7.3)", "wavedrom"] +all = ["latex2mathml", "pygments (>=2.7.3)", "wavedrom"] code-syntax-highlighting = ["pygments (>=2.7.3)"] +latex = ["latex2mathml"] wavedrom = ["wavedrom"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] name = "mergedeep" version = "1.3.4" description = "A deep merge function for 🐍." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -619,14 +626,13 @@ files = [ [[package]] name = "mkdocs" -version = "1.5.2" +version = "1.6.1" description = "Project documentation with Markdown." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocs-1.5.2-py3-none-any.whl", hash = "sha256:60a62538519c2e96fe8426654a67ee177350451616118a41596ae7c876bb7eac"}, - {file = "mkdocs-1.5.2.tar.gz", hash = "sha256:70d0da09c26cff288852471be03c23f0f521fc15cf16ac89c7a3bfb9ae8d24f9"}, + {file = "mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e"}, + {file = "mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2"}, ] [package.dependencies] @@ -634,25 +640,40 @@ click = ">=7.0" colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} ghp-import = ">=1.0" jinja2 = ">=2.11.1" -markdown = ">=3.2.1" +markdown = ">=3.3.6" markupsafe = ">=2.0.1" mergedeep = ">=1.3.4" +mkdocs-get-deps = ">=0.2.0" packaging = ">=20.5" pathspec = ">=0.11.1" -platformdirs = ">=2.2.0" pyyaml = ">=5.1" pyyaml-env-tag = ">=0.1" watchdog = ">=2.0" [package.extras] i18n = ["babel (>=2.9.0)"] -min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.3)", "jinja2 (==2.11.1)", "markdown (==3.2.1)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "packaging (==20.5)", "pathspec (==0.11.1)", "platformdirs (==2.2.0)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "typing-extensions (==3.10)", "watchdog (==2.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, + {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, +] + +[package.dependencies] +mergedeep = ">=1.3.4" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" [[package]] name = "mkdocs-material" version = "9.2.3" description = "Documentation that simply works" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -677,21 +698,19 @@ requests = ">=2.26" [[package]] name = "mkdocs-material-extensions" -version = "1.1.1" +version = "1.3.1" description = "Extension pack for Python Markdown and MkDocs Material." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"}, - {file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"}, + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, ] [[package]] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -701,65 +720,66 @@ files = [ [[package]] name = "packaging" -version = "23.1" +version = "24.1" description = "Core utilities for Python packages" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] name = "paginate" -version = "0.5.6" +version = "0.5.7" description = "Divides large result sets into pages for easier browsing" -category = "main" optional = false python-versions = "*" files = [ - {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, + {file = "paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591"}, + {file = "paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945"}, ] +[package.extras] +dev = ["pytest", "tox"] +lint = ["black"] + [[package]] name = "pathspec" -version = "0.11.2" +version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] [[package]] name = "platformdirs" -version = "3.10.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, - {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] name = "pluggy" -version = "1.2.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] @@ -768,45 +788,45 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pygments" -version = "2.16.1" +version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, - {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [package.extras] -plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pymdown-extensions" -version = "10.1" +version = "10.9" description = "Extension pack for Python Markdown." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.1-py3-none-any.whl", hash = "sha256:ef25dbbae530e8f67575d222b75ff0649b1e841e22c2ae9a20bad9472c2207dc"}, - {file = "pymdown_extensions-10.1.tar.gz", hash = "sha256:508009b211373058debb8247e168de4cbcb91b1bff7b5e961b2c3e864e00b195"}, + {file = "pymdown_extensions-10.9-py3-none-any.whl", hash = "sha256:d323f7e90d83c86113ee78f3fe62fc9dee5f56b54d912660703ea1816fed5626"}, + {file = "pymdown_extensions-10.9.tar.gz", hash = "sha256:6ff740bcd99ec4172a938970d42b96128bdc9d4b9bcad72494f29921dc69b753"}, ] [package.dependencies] -markdown = ">=3.2" +markdown = ">=3.6" pyyaml = "*" +[package.extras] +extra = ["pygments (>=2.12)"] + [[package]] name = "pyquery" -version = "2.0.0" +version = "2.0.1" description = "A jquery-like library for python" -category = "main" optional = false python-versions = "*" files = [ - {file = "pyquery-2.0.0-py3-none-any.whl", hash = "sha256:8dfc9b4b7c5f877d619bbae74b1898d5743f6ca248cfd5d72b504dd614da312f"}, - {file = "pyquery-2.0.0.tar.gz", hash = "sha256:963e8d4e90262ff6d8dec072ea97285dc374a2f69cad7776f4082abcf6a1d8ae"}, + {file = "pyquery-2.0.1-py3-none-any.whl", hash = "sha256:aedfa0bd0eb9afc94b3ddbec8f375a6362b32bc9662f46e3e0d866483f4771b0"}, + {file = "pyquery-2.0.1.tar.gz", hash = "sha256:0194bb2706b12d037db12c51928fe9ebb36b72d9e719565daba5a6c595322faf"}, ] [package.dependencies] @@ -820,7 +840,6 @@ test = ["pytest", "pytest-cov", "requests", "webob", "webtest"] name = "pytest" version = "7.4.0" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -839,14 +858,13 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -854,70 +872,70 @@ six = ">=1.5" [[package]] name = "pyyaml" -version = "6.0.1" +version = "6.0.2" description = "YAML parser and emitter for Python" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] name = "pyyaml-env-tag" version = "0.1" description = "A custom YAML tag for referencing environment variables in YAML files. " -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -932,7 +950,6 @@ pyyaml = "*" name = "readtime" version = "3.0.0" description = "Calculates the time some text takes the average human to read, based on Medium's read time forumula" -category = "main" optional = false python-versions = "*" files = [ @@ -946,107 +963,96 @@ pyquery = ">=1.2" [[package]] name = "regex" -version = "2023.8.8" +version = "2024.7.24" description = "Alternative regular expression module, to replace re." -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "regex-2023.8.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb"}, - {file = "regex-2023.8.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3611576aff55918af2697410ff0293d6071b7e00f4b09e005d614686ac4cd57c"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8a0ccc8f2698f120e9e5742f4b38dc944c38744d4bdfc427616f3a163dd9de5"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c662a4cbdd6280ee56f841f14620787215a171c4e2d1744c9528bed8f5816c96"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf0633e4a1b667bfe0bb10b5e53fe0d5f34a6243ea2530eb342491f1adf4f739"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:551ad543fa19e94943c5b2cebc54c73353ffff08228ee5f3376bd27b3d5b9800"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54de2619f5ea58474f2ac211ceea6b615af2d7e4306220d4f3fe690c91988a61"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ec4b3f0aebbbe2fc0134ee30a791af522a92ad9f164858805a77442d7d18570"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ae646c35cb9f820491760ac62c25b6d6b496757fda2d51be429e0e7b67ae0ab"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca339088839582d01654e6f83a637a4b8194d0960477b9769d2ff2cfa0fa36d2"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d9b6627408021452dcd0d2cdf8da0534e19d93d070bfa8b6b4176f99711e7f90"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:bd3366aceedf274f765a3a4bc95d6cd97b130d1dda524d8f25225d14123c01db"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7aed90a72fc3654fba9bc4b7f851571dcc368120432ad68b226bd593f3f6c0b7"}, - {file = "regex-2023.8.8-cp310-cp310-win32.whl", hash = "sha256:80b80b889cb767cc47f31d2b2f3dec2db8126fbcd0cff31b3925b4dc6609dcdb"}, - {file = "regex-2023.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:b82edc98d107cbc7357da7a5a695901b47d6eb0420e587256ba3ad24b80b7d0b"}, - {file = "regex-2023.8.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1e7d84d64c84ad97bf06f3c8cb5e48941f135ace28f450d86af6b6512f1c9a71"}, - {file = "regex-2023.8.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce0f9fbe7d295f9922c0424a3637b88c6c472b75eafeaff6f910494a1fa719ef"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06c57e14ac723b04458df5956cfb7e2d9caa6e9d353c0b4c7d5d54fcb1325c46"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7a9aaa5a1267125eef22cef3b63484c3241aaec6f48949b366d26c7250e0357"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b7408511fca48a82a119d78a77c2f5eb1b22fe88b0d2450ed0756d194fe7a9a"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14dc6f2d88192a67d708341f3085df6a4f5a0c7b03dec08d763ca2cd86e9f559"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48c640b99213643d141550326f34f0502fedb1798adb3c9eb79650b1ecb2f177"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0085da0f6c6393428bf0d9c08d8b1874d805bb55e17cb1dfa5ddb7cfb11140bf"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:964b16dcc10c79a4a2be9f1273fcc2684a9eedb3906439720598029a797b46e6"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7ce606c14bb195b0e5108544b540e2c5faed6843367e4ab3deb5c6aa5e681208"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:40f029d73b10fac448c73d6eb33d57b34607f40116e9f6e9f0d32e9229b147d7"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3b8e6ea6be6d64104d8e9afc34c151926f8182f84e7ac290a93925c0db004bfd"}, - {file = "regex-2023.8.8-cp311-cp311-win32.whl", hash = "sha256:942f8b1f3b223638b02df7df79140646c03938d488fbfb771824f3d05fc083a8"}, - {file = "regex-2023.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:51d8ea2a3a1a8fe4f67de21b8b93757005213e8ac3917567872f2865185fa7fb"}, - {file = "regex-2023.8.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e951d1a8e9963ea51efd7f150450803e3b95db5939f994ad3d5edac2b6f6e2b4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704f63b774218207b8ccc6c47fcef5340741e5d839d11d606f70af93ee78e4d4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22283c769a7b01c8ac355d5be0715bf6929b6267619505e289f792b01304d898"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91129ff1bb0619bc1f4ad19485718cc623a2dc433dff95baadbf89405c7f6b57"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de35342190deb7b866ad6ba5cbcccb2d22c0487ee0cbb251efef0843d705f0d4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b993b6f524d1e274a5062488a43e3f9f8764ee9745ccd8e8193df743dbe5ee61"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3026cbcf11d79095a32d9a13bbc572a458727bd5b1ca332df4a79faecd45281c"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:293352710172239bf579c90a9864d0df57340b6fd21272345222fb6371bf82b3"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d909b5a3fff619dc7e48b6b1bedc2f30ec43033ba7af32f936c10839e81b9217"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3d370ff652323c5307d9c8e4c62efd1956fb08051b0e9210212bc51168b4ff56"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:b076da1ed19dc37788f6a934c60adf97bd02c7eea461b73730513921a85d4235"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e9941a4ada58f6218694f382e43fdd256e97615db9da135e77359da257a7168b"}, - {file = "regex-2023.8.8-cp36-cp36m-win32.whl", hash = "sha256:a8c65c17aed7e15a0c824cdc63a6b104dfc530f6fa8cb6ac51c437af52b481c7"}, - {file = "regex-2023.8.8-cp36-cp36m-win_amd64.whl", hash = "sha256:aadf28046e77a72f30dcc1ab185639e8de7f4104b8cb5c6dfa5d8ed860e57236"}, - {file = "regex-2023.8.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:423adfa872b4908843ac3e7a30f957f5d5282944b81ca0a3b8a7ccbbfaa06103"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ae594c66f4a7e1ea67232a0846649a7c94c188d6c071ac0210c3e86a5f92109"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e51c80c168074faa793685656c38eb7a06cbad7774c8cbc3ea05552d615393d8"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09b7f4c66aa9d1522b06e31a54f15581c37286237208df1345108fcf4e050c18"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e73e5243af12d9cd6a9d6a45a43570dbe2e5b1cdfc862f5ae2b031e44dd95a8"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941460db8fe3bd613db52f05259c9336f5a47ccae7d7def44cc277184030a116"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f0ccf3e01afeb412a1a9993049cb160d0352dba635bbca7762b2dc722aa5742a"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2e9216e0d2cdce7dbc9be48cb3eacb962740a09b011a116fd7af8c832ab116ca"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5cd9cd7170459b9223c5e592ac036e0704bee765706445c353d96f2890e816c8"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4873ef92e03a4309b3ccd8281454801b291b689f6ad45ef8c3658b6fa761d7ac"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:239c3c2a339d3b3ddd51c2daef10874410917cd2b998f043c13e2084cb191684"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1005c60ed7037be0d9dea1f9c53cc42f836188227366370867222bda4c3c6bd7"}, - {file = "regex-2023.8.8-cp37-cp37m-win32.whl", hash = "sha256:e6bd1e9b95bc5614a7a9c9c44fde9539cba1c823b43a9f7bc11266446dd568e3"}, - {file = "regex-2023.8.8-cp37-cp37m-win_amd64.whl", hash = "sha256:9a96edd79661e93327cfeac4edec72a4046e14550a1d22aa0dd2e3ca52aec921"}, - {file = "regex-2023.8.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2181c20ef18747d5f4a7ea513e09ea03bdd50884a11ce46066bb90fe4213675"}, - {file = "regex-2023.8.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a2ad5add903eb7cdde2b7c64aaca405f3957ab34f16594d2b78d53b8b1a6a7d6"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9233ac249b354c54146e392e8a451e465dd2d967fc773690811d3a8c240ac601"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:920974009fb37b20d32afcdf0227a2e707eb83fe418713f7a8b7de038b870d0b"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2b6c5dfe0929b6c23dde9624483380b170b6e34ed79054ad131b20203a1a63"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96979d753b1dc3b2169003e1854dc67bfc86edf93c01e84757927f810b8c3c93"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ae54a338191e1356253e7883d9d19f8679b6143703086245fb14d1f20196be9"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2162ae2eb8b079622176a81b65d486ba50b888271302190870b8cc488587d280"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c884d1a59e69e03b93cf0dfee8794c63d7de0ee8f7ffb76e5f75be8131b6400a"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf9273e96f3ee2ac89ffcb17627a78f78e7516b08f94dc435844ae72576a276e"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:83215147121e15d5f3a45d99abeed9cf1fe16869d5c233b08c56cdf75f43a504"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f7454aa427b8ab9101f3787eb178057c5250478e39b99540cfc2b889c7d0586"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0640913d2c1044d97e30d7c41728195fc37e54d190c5385eacb52115127b882"}, - {file = "regex-2023.8.8-cp38-cp38-win32.whl", hash = "sha256:0c59122ceccb905a941fb23b087b8eafc5290bf983ebcb14d2301febcbe199c7"}, - {file = "regex-2023.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:c12f6f67495ea05c3d542d119d270007090bad5b843f642d418eb601ec0fa7be"}, - {file = "regex-2023.8.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:82cd0a69cd28f6cc3789cc6adeb1027f79526b1ab50b1f6062bbc3a0ccb2dbc3"}, - {file = "regex-2023.8.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bb34d1605f96a245fc39790a117ac1bac8de84ab7691637b26ab2c5efb8f228c"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:987b9ac04d0b38ef4f89fbc035e84a7efad9cdd5f1e29024f9289182c8d99e09"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dd6082f4e2aec9b6a0927202c85bc1b09dcab113f97265127c1dc20e2e32495"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7eb95fe8222932c10d4436e7a6f7c99991e3fdd9f36c949eff16a69246dee2dc"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7098c524ba9f20717a56a8d551d2ed491ea89cbf37e540759ed3b776a4f8d6eb"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b694430b3f00eb02c594ff5a16db30e054c1b9589a043fe9174584c6efa8033"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2aeab3895d778155054abea5238d0eb9a72e9242bd4b43f42fd911ef9a13470"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:988631b9d78b546e284478c2ec15c8a85960e262e247b35ca5eaf7ee22f6050a"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:67ecd894e56a0c6108ec5ab1d8fa8418ec0cff45844a855966b875d1039a2e34"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:14898830f0a0eb67cae2bbbc787c1a7d6e34ecc06fbd39d3af5fe29a4468e2c9"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f2200e00b62568cfd920127782c61bc1c546062a879cdc741cfcc6976668dfcf"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9691a549c19c22d26a4f3b948071e93517bdf86e41b81d8c6ac8a964bb71e5a6"}, - {file = "regex-2023.8.8-cp39-cp39-win32.whl", hash = "sha256:6ab2ed84bf0137927846b37e882745a827458689eb969028af8032b1b3dac78e"}, - {file = "regex-2023.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5543c055d8ec7801901e1193a51570643d6a6ab8751b1f7dd9af71af467538bb"}, - {file = "regex-2023.8.8.tar.gz", hash = "sha256:fcbdc5f2b0f1cd0f6a56cdb46fe41d2cce1e644e3b68832f3eeebc5fb0f7712e"}, + {file = "regex-2024.7.24-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b0d3f567fafa0633aee87f08b9276c7062da9616931382993c03808bb68ce"}, + {file = "regex-2024.7.24-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3426de3b91d1bc73249042742f45c2148803c111d1175b283270177fdf669024"}, + {file = "regex-2024.7.24-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f273674b445bcb6e4409bf8d1be67bc4b58e8b46fd0d560055d515b8830063cd"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23acc72f0f4e1a9e6e9843d6328177ae3074b4182167e34119ec7233dfeccf53"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65fd3d2e228cae024c411c5ccdffae4c315271eee4a8b839291f84f796b34eca"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c414cbda77dbf13c3bc88b073a1a9f375c7b0cb5e115e15d4b73ec3a2fbc6f59"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf7a89eef64b5455835f5ed30254ec19bf41f7541cd94f266ab7cbd463f00c41"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19c65b00d42804e3fbea9708f0937d157e53429a39b7c61253ff15670ff62cb5"}, + {file = "regex-2024.7.24-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7a5486ca56c8869070a966321d5ab416ff0f83f30e0e2da1ab48815c8d165d46"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6f51f9556785e5a203713f5efd9c085b4a45aecd2a42573e2b5041881b588d1f"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:a4997716674d36a82eab3e86f8fa77080a5d8d96a389a61ea1d0e3a94a582cf7"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:c0abb5e4e8ce71a61d9446040c1e86d4e6d23f9097275c5bd49ed978755ff0fe"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:18300a1d78cf1290fa583cd8b7cde26ecb73e9f5916690cf9d42de569c89b1ce"}, + {file = "regex-2024.7.24-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:416c0e4f56308f34cdb18c3f59849479dde5b19febdcd6e6fa4d04b6c31c9faa"}, + {file = "regex-2024.7.24-cp310-cp310-win32.whl", hash = "sha256:fb168b5924bef397b5ba13aabd8cf5df7d3d93f10218d7b925e360d436863f66"}, + {file = "regex-2024.7.24-cp310-cp310-win_amd64.whl", hash = "sha256:6b9fc7e9cc983e75e2518496ba1afc524227c163e43d706688a6bb9eca41617e"}, + {file = "regex-2024.7.24-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:382281306e3adaaa7b8b9ebbb3ffb43358a7bbf585fa93821300a418bb975281"}, + {file = "regex-2024.7.24-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4fdd1384619f406ad9037fe6b6eaa3de2749e2e12084abc80169e8e075377d3b"}, + {file = "regex-2024.7.24-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3d974d24edb231446f708c455fd08f94c41c1ff4f04bcf06e5f36df5ef50b95a"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2ec4419a3fe6cf8a4795752596dfe0adb4aea40d3683a132bae9c30b81e8d73"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb563dd3aea54c797adf513eeec819c4213d7dbfc311874eb4fd28d10f2ff0f2"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45104baae8b9f67569f0f1dca5e1f1ed77a54ae1cd8b0b07aba89272710db61e"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:994448ee01864501912abf2bad9203bffc34158e80fe8bfb5b031f4f8e16da51"}, + {file = "regex-2024.7.24-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fac296f99283ac232d8125be932c5cd7644084a30748fda013028c815ba3364"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7e37e809b9303ec3a179085415cb5f418ecf65ec98cdfe34f6a078b46ef823ee"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:01b689e887f612610c869421241e075c02f2e3d1ae93a037cb14f88ab6a8934c"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f6442f0f0ff81775eaa5b05af8a0ffa1dda36e9cf6ec1e0d3d245e8564b684ce"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:871e3ab2838fbcb4e0865a6e01233975df3a15e6fce93b6f99d75cacbd9862d1"}, + {file = "regex-2024.7.24-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c918b7a1e26b4ab40409820ddccc5d49871a82329640f5005f73572d5eaa9b5e"}, + {file = "regex-2024.7.24-cp311-cp311-win32.whl", hash = "sha256:2dfbb8baf8ba2c2b9aa2807f44ed272f0913eeeba002478c4577b8d29cde215c"}, + {file = "regex-2024.7.24-cp311-cp311-win_amd64.whl", hash = "sha256:538d30cd96ed7d1416d3956f94d54e426a8daf7c14527f6e0d6d425fcb4cca52"}, + {file = "regex-2024.7.24-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fe4ebef608553aff8deb845c7f4f1d0740ff76fa672c011cc0bacb2a00fbde86"}, + {file = "regex-2024.7.24-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:74007a5b25b7a678459f06559504f1eec2f0f17bca218c9d56f6a0a12bfffdad"}, + {file = "regex-2024.7.24-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7df9ea48641da022c2a3c9c641650cd09f0cd15e8908bf931ad538f5ca7919c9"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a1141a1dcc32904c47f6846b040275c6e5de0bf73f17d7a409035d55b76f289"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80c811cfcb5c331237d9bad3bea2c391114588cf4131707e84d9493064d267f9"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7214477bf9bd195894cf24005b1e7b496f46833337b5dedb7b2a6e33f66d962c"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d55588cba7553f0b6ec33130bc3e114b355570b45785cebdc9daed8c637dd440"}, + {file = "regex-2024.7.24-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:558a57cfc32adcf19d3f791f62b5ff564922942e389e3cfdb538a23d65a6b610"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a512eed9dfd4117110b1881ba9a59b31433caed0c4101b361f768e7bcbaf93c5"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:86b17ba823ea76256b1885652e3a141a99a5c4422f4a869189db328321b73799"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5eefee9bfe23f6df09ffb6dfb23809f4d74a78acef004aa904dc7c88b9944b05"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:731fcd76bbdbf225e2eb85b7c38da9633ad3073822f5ab32379381e8c3c12e94"}, + {file = "regex-2024.7.24-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eaef80eac3b4cfbdd6de53c6e108b4c534c21ae055d1dbea2de6b3b8ff3def38"}, + {file = "regex-2024.7.24-cp312-cp312-win32.whl", hash = "sha256:185e029368d6f89f36e526764cf12bf8d6f0e3a2a7737da625a76f594bdfcbfc"}, + {file = "regex-2024.7.24-cp312-cp312-win_amd64.whl", hash = "sha256:2f1baff13cc2521bea83ab2528e7a80cbe0ebb2c6f0bfad15be7da3aed443908"}, + {file = "regex-2024.7.24-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:66b4c0731a5c81921e938dcf1a88e978264e26e6ac4ec96a4d21ae0354581ae0"}, + {file = "regex-2024.7.24-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:88ecc3afd7e776967fa16c80f974cb79399ee8dc6c96423321d6f7d4b881c92b"}, + {file = "regex-2024.7.24-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:64bd50cf16bcc54b274e20235bf8edbb64184a30e1e53873ff8d444e7ac656b2"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb462f0e346fcf41a901a126b50f8781e9a474d3927930f3490f38a6e73b6950"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a82465ebbc9b1c5c50738536fdfa7cab639a261a99b469c9d4c7dcbb2b3f1e57"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68a8f8c046c6466ac61a36b65bb2395c74451df2ffb8458492ef49900efed293"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac8e84fff5d27420f3c1e879ce9929108e873667ec87e0c8eeb413a5311adfe"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba2537ef2163db9e6ccdbeb6f6424282ae4dea43177402152c67ef869cf3978b"}, + {file = "regex-2024.7.24-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:43affe33137fcd679bdae93fb25924979517e011f9dea99163f80b82eadc7e53"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:c9bb87fdf2ab2370f21e4d5636e5317775e5d51ff32ebff2cf389f71b9b13750"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:945352286a541406f99b2655c973852da7911b3f4264e010218bbc1cc73168f2"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:8bc593dcce679206b60a538c302d03c29b18e3d862609317cb560e18b66d10cf"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3f3b6ca8eae6d6c75a6cff525c8530c60e909a71a15e1b731723233331de4169"}, + {file = "regex-2024.7.24-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c51edc3541e11fbe83f0c4d9412ef6c79f664a3745fab261457e84465ec9d5a8"}, + {file = "regex-2024.7.24-cp38-cp38-win32.whl", hash = "sha256:d0a07763776188b4db4c9c7fb1b8c494049f84659bb387b71c73bbc07f189e96"}, + {file = "regex-2024.7.24-cp38-cp38-win_amd64.whl", hash = "sha256:8fd5afd101dcf86a270d254364e0e8dddedebe6bd1ab9d5f732f274fa00499a5"}, + {file = "regex-2024.7.24-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0ffe3f9d430cd37d8fa5632ff6fb36d5b24818c5c986893063b4e5bdb84cdf24"}, + {file = "regex-2024.7.24-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:25419b70ba00a16abc90ee5fce061228206173231f004437730b67ac77323f0d"}, + {file = "regex-2024.7.24-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:33e2614a7ce627f0cdf2ad104797d1f68342d967de3695678c0cb84f530709f8"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d33a0021893ede5969876052796165bab6006559ab845fd7b515a30abdd990dc"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04ce29e2c5fedf296b1a1b0acc1724ba93a36fb14031f3abfb7abda2806c1535"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b16582783f44fbca6fcf46f61347340c787d7530d88b4d590a397a47583f31dd"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:836d3cc225b3e8a943d0b02633fb2f28a66e281290302a79df0e1eaa984ff7c1"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:438d9f0f4bc64e8dea78274caa5af971ceff0f8771e1a2333620969936ba10be"}, + {file = "regex-2024.7.24-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:973335b1624859cb0e52f96062a28aa18f3a5fc77a96e4a3d6d76e29811a0e6e"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c5e69fd3eb0b409432b537fe3c6f44ac089c458ab6b78dcec14478422879ec5f"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fbf8c2f00904eaf63ff37718eb13acf8e178cb940520e47b2f05027f5bb34ce3"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ae2757ace61bc4061b69af19e4689fa4416e1a04840f33b441034202b5cd02d4"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:44fc61b99035fd9b3b9453f1713234e5a7c92a04f3577252b45feefe1b327759"}, + {file = "regex-2024.7.24-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:84c312cdf839e8b579f504afcd7b65f35d60b6285d892b19adea16355e8343c9"}, + {file = "regex-2024.7.24-cp39-cp39-win32.whl", hash = "sha256:ca5b2028c2f7af4e13fb9fc29b28d0ce767c38c7facdf64f6c2cd040413055f1"}, + {file = "regex-2024.7.24-cp39-cp39-win_amd64.whl", hash = "sha256:7c479f5ae937ec9985ecaf42e2e10631551d909f203e31308c12d703922742f9"}, + {file = "regex-2024.7.24.tar.gz", hash = "sha256:9cfd009eed1a46b27c14039ad5bbc5e71b6367c5b2e6d5f5da0ea91600817506"}, ] [[package]] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1068,7 +1074,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1078,21 +1083,19 @@ files = [ [[package]] name = "soupsieve" -version = "2.4.1" +version = "2.6" description = "A modern CSS selector implementation for Beautiful Soup." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, - {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, + {file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"}, + {file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"}, ] [[package]] name = "strictyaml" version = "1.7.3" description = "Strict, typed YAML parser" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -1107,7 +1110,6 @@ python-dateutil = ">=2.6.0" name = "teemup" version = "1.0.3" description = "If Meetup didn't become a walled garden, the world wouldn't need Teemup" -category = "main" optional = false python-versions = "==3.11.*" files = [ @@ -1121,57 +1123,58 @@ lxml = "5.3.0" [[package]] name = "urllib3" -version = "2.0.4" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, - {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "watchdog" -version = "3.0.0" +version = "5.0.0" description = "Filesystem events monitoring" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, - {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, - {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, - {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, - {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, - {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, - {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, - {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, - {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, + {file = "watchdog-5.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bf3216ec994eabb2212df9861f19056ca0d4cd3516d56cb95801933876519bfe"}, + {file = "watchdog-5.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cb59ad83a1700304fc1ac7bc53ae9e5cbe9d60a52ed9bba8e2e2d782a201bb2b"}, + {file = "watchdog-5.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1228cb097e855d1798b550be8f0e9f0cfbac4384f9a3e91f66d250d03e11294e"}, + {file = "watchdog-5.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3c177085c3d210d1c73cb4569442bdaef706ebebc423bd7aed9e90fc12b2e553"}, + {file = "watchdog-5.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01ab36cddc836a0f202c66267daaef92ba5c17c7d6436deff0587bb61234c5c9"}, + {file = "watchdog-5.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0834c21efa3e767849b09e667274604c7cdfe30b49eb95d794565c53f4db3c1e"}, + {file = "watchdog-5.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1e26f570dd7f5178656affb24d6f0e22ce66c8daf88d4061a27bfb9ac866b40d"}, + {file = "watchdog-5.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d146331e6b206baa9f6dd40f72b5783ad2302c240df68e7fce196d30588ccf7b"}, + {file = "watchdog-5.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6c96b1706430839872a3e33b9370ee3f7a0079f6b828129d88498ad1f96a0f45"}, + {file = "watchdog-5.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:663b096368ed7831ac42259919fdb9e0a1f0a8994d972675dfbcca0225e74de1"}, + {file = "watchdog-5.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:685931412978d00a91a193d9018fc9e394e565e8e7a0c275512a80e59c6e85f8"}, + {file = "watchdog-5.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:109daafc5b0f2a98d1fa9475ff9737eb3559d57b18129a36495e20c71de0b44f"}, + {file = "watchdog-5.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c2b4d90962639ae7cee371ea3a8da506831945d4418eee090c53bc38e6648dc6"}, + {file = "watchdog-5.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e58eafe9cc5ceebe1562cdb89bacdcd0ef470896e8b0139fe677a5abec243da"}, + {file = "watchdog-5.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b8d747bf6d8fe5ce89cb1a36c3724d1599bd4cde3f90fcba518e6260c7058a52"}, + {file = "watchdog-5.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:bc16d448a74a929b896ed9578c25756b2125400b19b3258be8d9a681c7ae8e71"}, + {file = "watchdog-5.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7e6b0e9b8a9dc3865d65888b5f5222da4ba9c4e09eab13cff5e305e7b7e7248f"}, + {file = "watchdog-5.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4fe6780915000743074236b21b6c37419aea71112af62237881bc265589fe463"}, + {file = "watchdog-5.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0710e9502727f688a7e06d48078545c54485b3d6eb53b171810879d8223c362a"}, + {file = "watchdog-5.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d76efab5248aafbf8a2c2a63cd7b9545e6b346ad1397af8b862a3bb3140787d8"}, + {file = "watchdog-5.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:ff4e957c45c446de34c513eadce01d0b65da7eee47c01dce472dd136124552c9"}, + {file = "watchdog-5.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:16c1aa3377bb1f82c5e24277fcbf4e2cac3c4ce46aaaf7212d53caa9076eb7b7"}, + {file = "watchdog-5.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:22fcad6168fc43cf0e709bd854be5b8edbb0b260f0a6f28f1ea9baa53c6907f7"}, + {file = "watchdog-5.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:0120b2fa65732797ffa65fa8ee5540c288aa861d91447df298626d6385a24658"}, + {file = "watchdog-5.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2aa59fab7ff75281778c649557275ca3085eccbdf825a0e2a5ca3810e977afe5"}, + {file = "watchdog-5.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:78db0fe0336958fc0e1269545c980b6f33d04d184ba191b2800a8b71d3e971a9"}, + {file = "watchdog-5.0.0-py3-none-win32.whl", hash = "sha256:d1acef802916083f2ad7988efc7decf07e46e266916c0a09d8fb9d387288ea12"}, + {file = "watchdog-5.0.0-py3-none-win_amd64.whl", hash = "sha256:3c2d50fdb86aa6df3973313272f5a17eb26eab29ff5a0bf54b6d34597b4dc4e4"}, + {file = "watchdog-5.0.0-py3-none-win_ia64.whl", hash = "sha256:1d17ec7e022c34fa7ddc72aa41bf28c9d1207ffb193df18ba4f6fde453725b3c"}, + {file = "watchdog-5.0.0.tar.gz", hash = "sha256:990aedb9e2f336b45a70aed9c014450e7c4a70fd99c5f5b1834d57e1453a177e"}, ] [package.extras] @@ -1180,4 +1183,4 @@ watchmedo = ["PyYAML (>=3.10)"] [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "1227118ca0f1fd98c06ee678e853c28fd1c93a472b1d965629ecb1e4f0e88f60" +content-hash = "a3251287eea7c262aa534aed518124075d05a86658c20e18436655ace24ea18d" diff --git a/pyproject.toml b/pyproject.toml index 3d031c05..803da759 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,15 +7,14 @@ repository = "https://github.com/honzajavorek/mkdocs-python.cz/" classifiers = ["Private :: Do Not Upload"] package-mode = false - [tool.poetry.dependencies] python = "3.11.*" -mkdocs = "1.5.2" mkdocs-material = "9.2.3" strictyaml = "1.7.3" ics = {version = "0.8.0.dev0", allow-prereleases = true} requests = "2.31.0" -teemup = "^1.0.3" +teemup = "1.0.3" +mkdocs = "1.6.1" [tool.poetry.group.dev.dependencies] pytest = "7.4.0" From 7fc40e83605d3c088802bfe87ffb6180ff1f9336 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 31 Aug 2024 15:42:23 +0200 Subject: [PATCH 40/46] mkdocs 1.6 modifies python path and allows for straightforward imports in hooks --- hooks/on_page_markdown.py | 2 +- hooks/on_pre_build.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hooks/on_page_markdown.py b/hooks/on_page_markdown.py index b905e47f..344061e6 100644 --- a/hooks/on_page_markdown.py +++ b/hooks/on_page_markdown.py @@ -4,7 +4,7 @@ from mkdocs.structure.pages import Page from mkdocs.structure.files import Files -from hooks.events import fetch_events, filter_events +from events import fetch_events, filter_events def on_page_markdown( diff --git a/hooks/on_pre_build.py b/hooks/on_pre_build.py index d48b4a32..9638105a 100644 --- a/hooks/on_pre_build.py +++ b/hooks/on_pre_build.py @@ -1,7 +1,7 @@ from pathlib import Path from mkdocs.config import Config -from hooks.events import fetch_events, generate_icalendar +from events import fetch_events, generate_icalendar def on_pre_build(config: Config): From 10255b2962728d3c85e2adf5027fb6b0fb8b9561 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 31 Aug 2024 15:42:36 +0200 Subject: [PATCH 41/46] update readme --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8ddc9540..a8165c43 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,12 @@ # python.cz -Czech Python community homepage on MkDocs. +Czech Python community homepage powered by [MkDocs](https://www.mkdocs.org/). # How to run (for development) -1. clone repository +1. Clone repository 1. `poetry install` -1. activate venv (created by poetry by itself, if it's not activated already) -1. `PYTHONPATH=. mkdocs serve` +1. `poetry run mkdocs serve` ## License From 3332c490c7959f686d47375bbdfb3314e5c4e83f Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 31 Aug 2024 15:44:20 +0200 Subject: [PATCH 42/46] remove unknown config option --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 803da759..3b5eb87e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,6 @@ norecursedirs = "node_modules" addopts = "--ff" [tool.black] -target-versions = ["py311"] include = "\\.py$" exclude = "node_modules" From df981b5fd75befb95965d7267d85fdd4bcfe7a78 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 31 Aug 2024 15:44:58 +0200 Subject: [PATCH 43/46] this shouldnt be necessary anymore --- .github/workflows/build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5289219a..ef0a64be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,8 +29,6 @@ jobs: - name: Build run: poetry run mkdocs build - env: - PYTHONPATH: . - if: ${{ github.ref == 'refs/heads/main' }} name: Deploy to GitHub Pages From f3f2200ab47b89bb420952c9c3ef2cb7bb5973a8 Mon Sep 17 00:00:00 2001 From: Honza Javorek Date: Sat, 31 Aug 2024 15:48:14 +0200 Subject: [PATCH 44/46] use ruff instead of black --- hooks/events.py | 20 +- hooks/on_page_markdown.py | 6 +- hooks/on_post_build.py | 1 + hooks/on_pre_build.py | 2 +- poetry.lock | 99 ++++---- pyproject.toml | 16 +- tests/models/events_test.py | 60 +++-- tests/models/github_test.py | 285 +++++++++++++---------- tests/models/github_test_fixtures.py | 92 ++++---- tests/static/data/geojson_europe_test.py | 18 +- tests/static/data/valid_json_test.py | 12 +- tests/static/data/valid_yaml_test.py | 14 +- tests/views_test.py | 190 ++++++++------- 13 files changed, 442 insertions(+), 373 deletions(-) diff --git a/hooks/events.py b/hooks/events.py index 34b43e82..0aca20ab 100644 --- a/hooks/events.py +++ b/hooks/events.py @@ -1,15 +1,15 @@ -from datetime import date, datetime, timedelta import json -from operator import itemgetter -from pathlib import Path import re +from datetime import date, datetime, timedelta from functools import cache +from operator import itemgetter +from pathlib import Path from zoneinfo import ZoneInfo -import teemup import ics import requests -from strictyaml import load as load_yaml, Map, Str, Seq, Url +import teemup +from strictyaml import Map, Seq, Str, Url, load as load_yaml YAML_SCHEMA = Seq( @@ -127,11 +127,11 @@ def parse_json_dl(html: str, base_url: str) -> list[dict]: events = teemup.parse(response.text) return [ dict( - name=event['title'], - starts_at=event['starts_at'], - ends_at=event['ends_at'], - location=event['venue'], - url=event['url'], + name=event["title"], + starts_at=event["starts_at"], + ends_at=event["ends_at"], + location=event["venue"], + url=event["url"], is_tentative=False, ) for event in events diff --git a/hooks/on_page_markdown.py b/hooks/on_page_markdown.py index 344061e6..6be48d30 100644 --- a/hooks/on_page_markdown.py +++ b/hooks/on_page_markdown.py @@ -1,10 +1,10 @@ from urllib.parse import quote_plus + +from events import fetch_events, filter_events from jinja2 import Environment from mkdocs.config import Config -from mkdocs.structure.pages import Page from mkdocs.structure.files import Files - -from events import fetch_events, filter_events +from mkdocs.structure.pages import Page def on_page_markdown( diff --git a/hooks/on_post_build.py b/hooks/on_post_build.py index e3b5d289..1d723a0e 100644 --- a/hooks/on_post_build.py +++ b/hooks/on_post_build.py @@ -1,4 +1,5 @@ from pathlib import Path + from mkdocs.config import Config diff --git a/hooks/on_pre_build.py b/hooks/on_pre_build.py index 9638105a..bb434a9f 100644 --- a/hooks/on_pre_build.py +++ b/hooks/on_pre_build.py @@ -1,7 +1,7 @@ from pathlib import Path -from mkdocs.config import Config from events import fetch_events, generate_icalendar +from mkdocs.config import Config def on_pre_build(config: Config): diff --git a/poetry.lock b/poetry.lock index 9f92cc8a..f726c66c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -54,50 +54,6 @@ charset-normalizer = ["charset-normalizer"] html5lib = ["html5lib"] lxml = ["lxml"] -[[package]] -name = "black" -version = "23.7.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"}, - {file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"}, - {file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"}, - {file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"}, - {file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"}, - {file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"}, - {file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"}, - {file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"}, - {file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"}, - {file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"}, - {file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"}, - {file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"}, - {file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"}, - {file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"}, - {file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"}, - {file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"}, - {file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"}, - {file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"}, - {file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"}, - {file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"}, - {file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"}, - {file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - [[package]] name = "certifi" version = "2024.8.30" @@ -707,17 +663,6 @@ files = [ {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, ] -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -files = [ - {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, - {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, -] - [[package]] name = "packaging" version = "24.1" @@ -856,6 +801,21 @@ pluggy = ">=0.12,<2.0" [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-ruff" +version = "0.4.1" +description = "pytest plugin to check ruff requirements." +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "pytest_ruff-0.4.1-py3-none-any.whl", hash = "sha256:69acd5b2ba68d65998c730b5b4d656788193190e45f61a53aa66ef8b390634a4"}, + {file = "pytest_ruff-0.4.1.tar.gz", hash = "sha256:2c9a30f15f384c229c881b52ec86cfaf1e79d39530dd7dd5f2d6aebe278f7eb7"}, +] + +[package.dependencies] +pytest = ">=5" +ruff = ">=0.0.242" + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1070,6 +1030,33 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "ruff" +version = "0.6.3" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.6.3-py3-none-linux_armv6l.whl", hash = "sha256:97f58fda4e309382ad30ede7f30e2791d70dd29ea17f41970119f55bdb7a45c3"}, + {file = "ruff-0.6.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b061e49b5cf3a297b4d1c27ac5587954ccb4ff601160d3d6b2f70b1622194dc"}, + {file = "ruff-0.6.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:34e2824a13bb8c668c71c1760a6ac7d795ccbd8d38ff4a0d8471fdb15de910b1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bddfbb8d63c460f4b4128b6a506e7052bad4d6f3ff607ebbb41b0aa19c2770d1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ced3eeb44df75353e08ab3b6a9e113b5f3f996bea48d4f7c027bc528ba87b672"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47021dff5445d549be954eb275156dfd7c37222acc1e8014311badcb9b4ec8c1"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d7bd20dc07cebd68cc8bc7b3f5ada6d637f42d947c85264f94b0d1cd9d87384"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:500f166d03fc6d0e61c8e40a3ff853fa8a43d938f5d14c183c612df1b0d6c58a"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42844ff678f9b976366b262fa2d1d1a3fe76f6e145bd92c84e27d172e3c34500"}, + {file = "ruff-0.6.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70452a10eb2d66549de8e75f89ae82462159855e983ddff91bc0bce6511d0470"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65a533235ed55f767d1fc62193a21cbf9e3329cf26d427b800fdeacfb77d296f"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2e2c23cef30dc3cbe9cc5d04f2899e7f5e478c40d2e0a633513ad081f7361b5"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d8a136aa7d228975a6aee3dd8bea9b28e2b43e9444aa678fb62aeb1956ff2351"}, + {file = "ruff-0.6.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:f92fe93bc72e262b7b3f2bba9879897e2d58a989b4714ba6a5a7273e842ad2f8"}, + {file = "ruff-0.6.3-py3-none-win32.whl", hash = "sha256:7a62d3b5b0d7f9143d94893f8ba43aa5a5c51a0ffc4a401aa97a81ed76930521"}, + {file = "ruff-0.6.3-py3-none-win_amd64.whl", hash = "sha256:746af39356fee2b89aada06c7376e1aa274a23493d7016059c3a72e3b296befb"}, + {file = "ruff-0.6.3-py3-none-win_arm64.whl", hash = "sha256:14a9528a8b70ccc7a847637c29e56fd1f9183a9db743bbc5b8e0c4ad60592a82"}, + {file = "ruff-0.6.3.tar.gz", hash = "sha256:183b99e9edd1ef63be34a3b51fee0a9f4ab95add123dbf89a71f7b1f0c991983"}, +] + [[package]] name = "six" version = "1.16.0" @@ -1183,4 +1170,4 @@ watchmedo = ["PyYAML (>=3.10)"] [metadata] lock-version = "2.0" python-versions = "3.11.*" -content-hash = "a3251287eea7c262aa534aed518124075d05a86658c20e18436655ace24ea18d" +content-hash = "8d2f9fd1d95ee3b6db7a79a6bd3fd2160953ae6ca1dc34273f5cea1d5b4ba7a8" diff --git a/pyproject.toml b/pyproject.toml index 3b5eb87e..e7073caf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,17 +18,23 @@ mkdocs = "1.6.1" [tool.poetry.group.dev.dependencies] pytest = "7.4.0" -black = "23.7.0" +pytest-ruff = "0.4.1" [tool.pytest.ini_options] python_files = "test_*.py" testpaths = "tests" norecursedirs = "node_modules" -addopts = "--ff" +addopts = "--ff --ruff --ruff-format" -[tool.black] -include = "\\.py$" -exclude = "node_modules" +[tool.ruff] +target-version = "py312" + +[tool.ruff.lint] +extend-select = ["I"] + +[tool.ruff.lint.isort] +combine-as-imports = true +lines-after-imports = 2 [build-system] requires = ["poetry-core>=1.5.0"] diff --git a/tests/models/events_test.py b/tests/models/events_test.py index 6a1b7564..17abe67a 100644 --- a/tests/models/events_test.py +++ b/tests/models/events_test.py @@ -2,13 +2,15 @@ import pytest from ics import Calendar, Event - -from pythoncz.models.events import (preprocess_ical, find_first_url, - set_url_from_description) +from pythoncz.models.events import ( + find_first_url, + preprocess_ical, + set_url_from_description, +) def test_preprocess_ical(): - path = Path(__file__).parent / 'invalid_ical.ics' + path = Path(__file__).parent / "invalid_ical.ics" text = preprocess_ical(path.read_text()) calendar = Calendar(text) @@ -24,31 +26,43 @@ def test_preprocess_ical(): assert events[0].alarms[0].action == "AUDIO" -@pytest.mark.parametrize('text,expected', [ - (None, None), - ('', None), - ('lorem ipsum dolor sit amet', None), - ('https://python.cz', 'https://python.cz'), - ('http://python.cz', 'http://python.cz'), - ('lorem ipsum https://python.cz dolor sit amet', 'https://python.cz'), - ('lorem https://python.cz ipsum https://pyvo.cz', 'https://python.cz'), -]) +@pytest.mark.parametrize( + "text,expected", + [ + (None, None), + ("", None), + ("lorem ipsum dolor sit amet", None), + ("https://python.cz", "https://python.cz"), + ("http://python.cz", "http://python.cz"), + ("lorem ipsum https://python.cz dolor sit amet", "https://python.cz"), + ("lorem https://python.cz ipsum https://pyvo.cz", "https://python.cz"), + ], +) def test_find_first_url(text, expected): assert find_first_url(text) == expected -@pytest.mark.parametrize('event,expected_url', [ - (Event(), None), - (Event(url='https://python.cz'), 'https://python.cz'), - (Event(description='https://pyvo.cz', url='https://python.cz'), - 'https://python.cz'), - (Event(description='https://pyvo.cz'), 'https://pyvo.cz'), - (Event(description=''' +@pytest.mark.parametrize( + "event,expected_url", + [ + (Event(), None), + (Event(url="https://python.cz"), "https://python.cz"), + ( + Event(description="https://pyvo.cz", url="https://python.cz"), + "https://python.cz", + ), + (Event(description="https://pyvo.cz"), "https://pyvo.cz"), + ( + Event( + description=""" See: https://www.meetup.com/PyData-Prague/events/257775220 Looking forward to see you! - '''), - 'https://www.meetup.com/PyData-Prague/events/257775220'), -]) + """ + ), + "https://www.meetup.com/PyData-Prague/events/257775220", + ), + ], +) def test_set_url_from_description(event, expected_url): assert set_url_from_description(event).url == expected_url diff --git a/tests/models/github_test.py b/tests/models/github_test.py index 7cde2447..d8137d18 100644 --- a/tests/models/github_test.py +++ b/tests/models/github_test.py @@ -1,14 +1,13 @@ import re import warnings +import github_test_fixtures as fixtures import pytest import requests import responses from cachelib import NullCache - from pythoncz import app from pythoncz.models import github as github_module -import github_test_fixtures as fixtures class RequestsMock(responses.RequestsMock): @@ -17,8 +16,9 @@ def add_github_graphql(self, *args, **kwargs): Convenience method to simplify adding fake responses for calls to GitHub's v4 GraphQL API """ - return self.add(responses.POST, 'https://api.github.com/graphql', - *args, **kwargs) + return self.add( + responses.POST, "https://api.github.com/graphql", *args, **kwargs + ) @pytest.fixture() @@ -27,10 +27,10 @@ def patched_token(): Code expects the token to be configured. Also this makes sure that we do not accidentally access the non-mock API. """ - orig_value = app.config['GITHUB_TOKEN'] - app.config['GITHUB_TOKEN'] = 'test' + orig_value = app.config["GITHUB_TOKEN"] + app.config["GITHUB_TOKEN"] = "test" yield - app.config['GITHUB_TOKEN'] = orig_value + app.config["GITHUB_TOKEN"] = orig_value @pytest.fixture() @@ -56,23 +56,29 @@ def test_get_issues_merges_orgs(github, requests_mock): """ issue_org1 = fixtures.issue() requests_mock.add_github_graphql( - json=fixtures.api_response_body(repos=[ - fixtures.repository(issues=[issue_org1], pull_requests=[], - private=False), - ]), + json=fixtures.api_response_body( + repos=[ + fixtures.repository( + issues=[issue_org1], pull_requests=[], private=False + ), + ] + ), ) issue_org2 = fixtures.issue() requests_mock.add_github_graphql( - json=fixtures.api_response_body(repos=[ - fixtures.repository(issues=[issue_org2], pull_requests=[], - private=False), - ]), + json=fixtures.api_response_body( + repos=[ + fixtures.repository( + issues=[issue_org2], pull_requests=[], private=False + ), + ] + ), ) - issues = github.get_issues(['org1', 'org2']) - titles = set(i['title'] for i in issues) + issues = github.get_issues(["org1", "org2"]) + titles = set(i["title"] for i in issues) - assert titles == {issue_org1['title'], issue_org2['title']} + assert titles == {issue_org1["title"], issue_org2["title"]} def test_get_issues_api_error(github, requests_mock): @@ -82,11 +88,11 @@ def test_get_issues_api_error(github, requests_mock): """ requests_mock.add_github_graphql( status=500, - json={'errors': [{'message': 'Error 1'}, {'message': 'Error 2'}]}, + json={"errors": [{"message": "Error 1"}, {"message": "Error 2"}]}, ) - error_message = 'Error 1; Error 2' + error_message = "Error 1; Error 2" with pytest.raises(requests.HTTPError, match=error_message) as excinfo: - github.get_issues(['org']) + github.get_issues(["org"]) assert excinfo.value.response.status_code == 500 @@ -99,8 +105,8 @@ def test_create_api_session(patched_token, github): session = github._create_api_session() headers = session.headers - assert 'https://python.cz' in headers.get('User-Agent') - assert re.match(r'token \w+', headers.get('Authorization')) + assert "https://python.cz" in headers.get("User-Agent") + assert re.match(r"token \w+", headers.get("Authorization")) def test_get_issues_for_org_key_error(github, requests_mock): @@ -108,10 +114,10 @@ def test_get_issues_for_org_key_error(github, requests_mock): If the API response doesn't have the expected structure, the '_get_issues_for_org' helper should raise ValueError """ - requests_mock.add_github_graphql(json={'data': {}}) - error_message = 'Unexpected structure of the GitHub API response' + requests_mock.add_github_graphql(json={"data": {}}) + error_message = "Unexpected structure of the GitHub API response" with pytest.raises(ValueError, match=error_message): - list(github._get_issues_for_org(requests.Session(), 'org')) + list(github._get_issues_for_org(requests.Session(), "org")) def test_get_issues_for_org_merges_issues_pull_requests(github, requests_mock): @@ -122,26 +128,26 @@ def test_get_issues_for_org_merges_issues_pull_requests(github, requests_mock): repo1 = fixtures.repository( issues=[fixtures.issue(), fixtures.issue(), fixtures.issue()], pull_requests=[fixtures.issue(pr=True)], - private=False + private=False, ) repo2 = fixtures.repository( issues=[fixtures.issue(), fixtures.issue()], pull_requests=[fixtures.issue(pr=True), fixtures.issue(pr=True)], - private=False + private=False, ) expected_titles_are_pr = {} for repo in [repo1, repo2]: - for issue in repo['issues']['nodes']: - expected_titles_are_pr[issue['title']] = False - for pull_request in repo['pullRequests']['nodes']: - expected_titles_are_pr[pull_request['title']] = True + for issue in repo["issues"]["nodes"]: + expected_titles_are_pr[issue["title"]] = False + for pull_request in repo["pullRequests"]["nodes"]: + expected_titles_are_pr[pull_request["title"]] = True api_response_body = fixtures.api_response_body(repos=[repo1, repo2]) requests_mock.add_github_graphql(json=api_response_body) - issues = github._get_issues_for_org(requests.Session(), 'org') + issues = github._get_issues_for_org(requests.Session(), "org") - titles_are_pr = {i['title']: i['is_pull_request'] for i in issues} + titles_are_pr = {i["title"]: i["is_pull_request"] for i in issues} assert titles_are_pr == expected_titles_are_pr @@ -153,22 +159,24 @@ def test_get_issues_for_org_skips_private(github, requests_mock): public_repo = fixtures.repository(private=False) expected_titles = set() - for issue in public_repo['issues']['nodes']: - expected_titles.add(issue['title']) - for pull_request in public_repo['pullRequests']['nodes']: - expected_titles.add(pull_request['title']) - - api_response_body = fixtures.api_response_body(repos=[ - fixtures.repository(private=True), - public_repo, - fixtures.repository(private=True), - fixtures.repository(private=True), - fixtures.repository(private=True), - ]) + for issue in public_repo["issues"]["nodes"]: + expected_titles.add(issue["title"]) + for pull_request in public_repo["pullRequests"]["nodes"]: + expected_titles.add(pull_request["title"]) + + api_response_body = fixtures.api_response_body( + repos=[ + fixtures.repository(private=True), + public_repo, + fixtures.repository(private=True), + fixtures.repository(private=True), + fixtures.repository(private=True), + ] + ) requests_mock.add_github_graphql(json=api_response_body) - issues = github._get_issues_for_org(requests.Session(), 'org') + issues = github._get_issues_for_org(requests.Session(), "org") - titles = set(i['title'] for i in issues) + titles = set(i["title"] for i in issues) assert titles == expected_titles @@ -177,10 +185,10 @@ def test_request_api_200_invalid_json(github, requests_mock): The '_request_api' helper should raise 'ValueError' if the JSON in the response cannot be decoded """ - requests_mock.add_github_graphql(body='... invalid JSON ...') - error_message = 'Unexpected structure of the GitHub API response' + requests_mock.add_github_graphql(body="... invalid JSON ...") + error_message = "Unexpected structure of the GitHub API response" with pytest.raises(ValueError, match=error_message): - github._request_api(requests.Session(), '... query ...', {}) + github._request_api(requests.Session(), "... query ...", {}) def test_request_api_500_invalid_json(github, requests_mock): @@ -188,14 +196,14 @@ def test_request_api_500_invalid_json(github, requests_mock): The '_request_api' helper should raise HTTP error even if the JSON in the response cannot be decoded """ - requests_mock.add_github_graphql(status=500, body='... invalid JSON ...') + requests_mock.add_github_graphql(status=500, body="... invalid JSON ...") with pytest.raises(requests.HTTPError) as excinfo: - github._request_api(requests.Session(), '... query ...', {}) + github._request_api(requests.Session(), "... query ...", {}) assert excinfo.value.response.status_code == 500 -@pytest.mark.parametrize('status_code', (200, 500)) +@pytest.mark.parametrize("status_code", (200, 500)) def test_request_api_X00_errors(github, requests_mock, status_code): """ The '_request_api' helper should raise HTTP error with error messages @@ -204,11 +212,11 @@ def test_request_api_X00_errors(github, requests_mock, status_code): """ requests_mock.add_github_graphql( status=status_code, - json={'errors': [{'message': 'Error 1'}, {'message': 'Error 2'}]}, + json={"errors": [{"message": "Error 1"}, {"message": "Error 2"}]}, ) - error_message = 'Error 1; Error 2' + error_message = "Error 1; Error 2" with pytest.raises(requests.HTTPError, match=error_message) as excinfo: - github._request_api(requests.Session(), '... query ...', {}) + github._request_api(requests.Session(), "... query ...", {}) assert excinfo.value.response.status_code == status_code @@ -217,10 +225,10 @@ def test_request_api_200(github, requests_mock): """ The '_request_api' helper should parse valid JSON response and return it """ - requests_mock.add_github_graphql(json={'data': '...'}) - json = github._request_api(requests.Session(), '... query ...', {}) + requests_mock.add_github_graphql(json={"data": "..."}) + json = github._request_api(requests.Session(), "... query ...", {}) - assert json == {'data': '...'} + assert json == {"data": "..."} def test_request_api_500(github, requests_mock): @@ -228,9 +236,9 @@ def test_request_api_500(github, requests_mock): The '_request_api' helper should raise HTTP error if the HTTP status code indicates HTTP error, even if there are no errors in the JSON response """ - requests_mock.add_github_graphql(status=500, json={'data': '...'}) + requests_mock.add_github_graphql(status=500, json={"data": "..."}) with pytest.raises(requests.HTTPError) as excinfo: - github._request_api(requests.Session(), '... query ...', {}) + github._request_api(requests.Session(), "... query ...", {}) assert excinfo.value.response.status_code == 500 @@ -241,34 +249,34 @@ def test_format_issue_missing_author(github): when the author is deleted/disabled user """ issue = fixtures.issue() - issue['author'] = None - formatted_issue = github._format_issue('org', fixtures.repository(), issue) + issue["author"] = None + formatted_issue = github._format_issue("org", fixtures.repository(), issue) - assert formatted_issue['user'] == { - 'login': None, - 'html_url': 'https://github.com/ghost', + assert formatted_issue["user"] == { + "login": None, + "html_url": "https://github.com/ghost", } def test_format_issue_labels(github): """The '_format_issue' helper should be able to process labels""" - issue = fixtures.issue(labels=[{'name': 'bug'}, {'name': 'feature'}]) - formatted_issue = github._format_issue('org', fixtures.repository(), issue) + issue = fixtures.issue(labels=[{"name": "bug"}, {"name": "feature"}]) + formatted_issue = github._format_issue("org", fixtures.repository(), issue) - assert formatted_issue['labels'] == ['bug', 'feature'] - assert formatted_issue['coach'] is False + assert formatted_issue["labels"] == ["bug", "feature"] + assert formatted_issue["coach"] is False -@pytest.mark.parametrize('label_name', ('coach', 'sprint-idea')) +@pytest.mark.parametrize("label_name", ("coach", "sprint-idea")) def test_format_issue_special_labels(github, label_name): """ The '_format_issue' helper should be able to process the 'coach' label and to mark the resulting formatted issue with the 'coach' flag accordingly """ - issue = fixtures.issue(labels=[{'name': 'bug'}, {'name': label_name}]) - formatted_issue = github._format_issue('org', fixtures.repository(), issue) + issue = fixtures.issue(labels=[{"name": "bug"}, {"name": label_name}]) + formatted_issue = github._format_issue("org", fixtures.repository(), issue) - assert formatted_issue['labels'] == ['bug', label_name] + assert formatted_issue["labels"] == ["bug", label_name] assert formatted_issue[label_name] is True @@ -277,44 +285,55 @@ def test_format_issue_reactions(github): The '_format_issue' helper should be able to calculate 'votes' from reactions """ - issue = fixtures.issue(reactions_counts={ - 'LAUGH': 42, - 'HEART': 3, - }) - formatted_issue = github._format_issue('org', fixtures.repository(), issue) + issue = fixtures.issue( + reactions_counts={ + "LAUGH": 42, + "HEART": 3, + } + ) + formatted_issue = github._format_issue("org", fixtures.repository(), issue) - assert formatted_issue['votes'] == 42 + 3 + assert formatted_issue["votes"] == 42 + 3 def test_calculate_votes(github): """ The '_calculate_votes' helper should correctly deal with negative votes """ - votes = github._calculate_votes(fixtures.issue(reactions_counts={ - 'THUMBS_UP': 1, - 'THUMBS_DOWN': 1, - 'LAUGH': 1, - 'HOORAY': 1, - 'CONFUSED': 1, - 'HEART': 1, - })) + votes = github._calculate_votes( + fixtures.issue( + reactions_counts={ + "THUMBS_UP": 1, + "THUMBS_DOWN": 1, + "LAUGH": 1, + "HOORAY": 1, + "CONFUSED": 1, + "HEART": 1, + } + ) + ) assert votes == 2 def test_get_nodes_without_total_count(github): subnodes = [1, 2, 3, 4] - result = github._get_nodes({'something': {'nodes': subnodes}}, 'something') + result = github._get_nodes({"something": {"nodes": subnodes}}, "something") assert result == subnodes def test_get_nodes_with_total_count(github): subnodes = [1, 2, 3, 4] - result = github._get_nodes({'something': { - 'totalCount': len(subnodes), - 'nodes': subnodes, - }}, 'something') + result = github._get_nodes( + { + "something": { + "totalCount": len(subnodes), + "nodes": subnodes, + } + }, + "something", + ) assert result == subnodes @@ -326,17 +345,19 @@ def test_get_nodes_with_different_total_count(github): some data missing and limits should be raised or results paginated """ subnodes = [1, 2, 3, 4] - node = {'something': { - 'totalCount': len(subnodes) + 42, - 'nodes': subnodes, - }} + node = { + "something": { + "totalCount": len(subnodes) + 42, + "nodes": subnodes, + } + } with warnings.catch_warnings(record=True) as recorded_warnings: - result = github._get_nodes(node, 'something') + result = github._get_nodes(node, "something") assert result == subnodes assert len(recorded_warnings) == 1 assert issubclass(recorded_warnings[0].category, UserWarning) - assert 'nodes in total, but only' in str(recorded_warnings[0].message) + assert "nodes in total, but only" in str(recorded_warnings[0].message) def test_sort_issues_coach(github): @@ -344,15 +365,18 @@ def test_sort_issues_coach(github): Issues with coaching offer should always go first no matter what """ repository = fixtures.repository() - issues = [github._format_issue('org', repository, issue) for issue in [ - fixtures.issue(labels=[]), - fixtures.issue(labels=[{'name': 'foo'}]), - fixtures.issue(labels=[{'name': 'bar'}, {'name': 'coach'}]), - fixtures.issue(labels=[]), - ]] + issues = [ + github._format_issue("org", repository, issue) + for issue in [ + fixtures.issue(labels=[]), + fixtures.issue(labels=[{"name": "foo"}]), + fixtures.issue(labels=[{"name": "bar"}, {"name": "coach"}]), + fixtures.issue(labels=[]), + ] + ] sorted_issues = github._sort_issues(issues) - assert sorted_issues[0]['coach'] is True + assert sorted_issues[0]["coach"] is True def test_sort_issues_votes(github): @@ -360,15 +384,18 @@ def test_sort_issues_votes(github): Issues with most votes should go first if there's no 'coach' issue """ repository = fixtures.repository() - issues = [github._format_issue('org', repository, issue) for issue in [ - fixtures.issue(labels=[], reactions_counts={'THUMBS_UP': 1}), - fixtures.issue(labels=[], reactions_counts={'THUMBS_DOWN': 1}), - fixtures.issue(labels=[], reactions_counts={'THUMBS_UP': 4}), - fixtures.issue(labels=[], reactions_counts={'THUMBS_UP': 3}), - ]] + issues = [ + github._format_issue("org", repository, issue) + for issue in [ + fixtures.issue(labels=[], reactions_counts={"THUMBS_UP": 1}), + fixtures.issue(labels=[], reactions_counts={"THUMBS_DOWN": 1}), + fixtures.issue(labels=[], reactions_counts={"THUMBS_UP": 4}), + fixtures.issue(labels=[], reactions_counts={"THUMBS_UP": 3}), + ] + ] sorted_issues = github._sort_issues(issues) - assert sorted_issues[0]['votes'] == 4 + assert sorted_issues[0]["votes"] == 4 def test_sort_issues_activity(github): @@ -378,23 +405,25 @@ def test_sort_issues_activity(github): User activity is comments count + participants count """ issue1 = fixtures.issue(labels=[], reactions_counts={}) - issue1['comments']['totalCount'] = 3 - issue1['participants']['totalCount'] = 2 + issue1["comments"]["totalCount"] = 3 + issue1["participants"]["totalCount"] = 2 issue2 = fixtures.issue(labels=[], reactions_counts={}) - issue2['comments']['totalCount'] = 1 - issue2['participants']['totalCount'] = 9 + issue2["comments"]["totalCount"] = 1 + issue2["participants"]["totalCount"] = 9 issue3 = fixtures.issue(labels=[], reactions_counts={}) - issue3['comments']['totalCount'] = 0 - issue3['participants']['totalCount'] = 4 + issue3["comments"]["totalCount"] = 0 + issue3["participants"]["totalCount"] = 4 repository = fixtures.repository() - sorted_issues = github._sort_issues([ - github._format_issue('org', repository, issue) - for issue in [issue1, issue2, issue3] - ]) - - assert sorted_issues[0]['comments'] == 1 # + 9 = 10 - assert sorted_issues[1]['comments'] == 3 # + 2 = 7 - assert sorted_issues[2]['comments'] == 0 # + 4 = 4 + sorted_issues = github._sort_issues( + [ + github._format_issue("org", repository, issue) + for issue in [issue1, issue2, issue3] + ] + ) + + assert sorted_issues[0]["comments"] == 1 # + 9 = 10 + assert sorted_issues[1]["comments"] == 3 # + 2 = 7 + assert sorted_issues[2]["comments"] == 0 # + 4 = 4 diff --git a/tests/models/github_test_fixtures.py b/tests/models/github_test_fixtures.py index 06c3e0ca..51da350b 100644 --- a/tests/models/github_test_fixtures.py +++ b/tests/models/github_test_fixtures.py @@ -1,5 +1,5 @@ -import uuid import random +import uuid def api_response_body(repos=None, repos_count=None): @@ -10,15 +10,25 @@ def api_response_body(repos=None, repos_count=None): else: repos_count = len(repos) - return {'data': {'organization': {'repositories': { - 'totalCount': repos_count, - 'nodes': repos, - }}}} + return { + "data": { + "organization": { + "repositories": { + "totalCount": repos_count, + "nodes": repos, + } + } + } + } -def repository(issues=None, issues_count=None, - pull_requests=None, pull_requests_count=None, - private=None): +def repository( + issues=None, + issues_count=None, + pull_requests=None, + pull_requests_count=None, + private=None, +): if issues is None: if issues_count is None: issues_count = random.randint(0, 4) @@ -29,9 +39,7 @@ def repository(issues=None, issues_count=None, if pull_requests is None: if pull_requests_count is None: pull_requests_count = random.randint(0, 4) - pull_requests = [ - issue(pr=True) for i in range(pull_requests_count) - ] + pull_requests = [issue(pr=True) for i in range(pull_requests_count)] else: pull_requests_count = len(pull_requests) @@ -39,40 +47,40 @@ def repository(issues=None, issues_count=None, private = random.choice([True, False]) return { - 'name': 'repo-{}'.format(uuid.uuid4()), - 'nameWithOwner': 'org/repo', - 'isPrivate': private, - 'url': 'https://github.com/org/repo', - 'issues': { - 'totalCount': issues_count, - 'nodes': issues, + "name": "repo-{}".format(uuid.uuid4()), + "nameWithOwner": "org/repo", + "isPrivate": private, + "url": "https://github.com/org/repo", + "issues": { + "totalCount": issues_count, + "nodes": issues, }, - 'pullRequests': { - 'totalCount': pull_requests_count, - 'nodes': pull_requests, + "pullRequests": { + "totalCount": pull_requests_count, + "nodes": pull_requests, }, } def issue(pr=False, labels=None, reactions_counts=None): issue_number = random.randint(1, 4242) - author = random.choice(['zuzejk', 'zzuzzy', 'encukou', 'honzajavorek']) + author = random.choice(["zuzejk", "zzuzzy", "encukou", "honzajavorek"]) if pr: - issue_type = 'pull' + issue_type = "pull" title = "Fix '{}'".format(uuid.uuid4()) else: - issue_type = 'issue' + issue_type = "issue" title = "Looks like '{}' is broken".format(uuid.uuid4()) - url = 'https://github.com/org/repo/{}/{}'.format(issue_type, issue_number) + url = "https://github.com/org/repo/{}/{}".format(issue_type, issue_number) if labels is None: - labels_fake_values = ['bug', 'improvement', 'coach', 'duplicate'] + labels_fake_values = ["bug", "improvement", "coach", "duplicate"] labels_count = random.randint(0, len(labels_fake_values)) labels = [ - {'name': label_name} for label_name in - random.sample(labels_fake_values, labels_count) + {"name": label_name} + for label_name in random.sample(labels_fake_values, labels_count) ] if reactions_counts is None: @@ -81,21 +89,21 @@ def issue(pr=False, labels=None, reactions_counts=None): confused_count = random.randint(0, reaction_count - thumbsdown_count) else: reaction_count = sum(reactions_counts.values()) - thumbsdown_count = reactions_counts.get('THUMBS_DOWN', 0) - confused_count = reactions_counts.get('CONFUSED', 0) + thumbsdown_count = reactions_counts.get("THUMBS_DOWN", 0) + confused_count = reactions_counts.get("CONFUSED", 0) return { - 'title': title, - 'url': url, - 'updatedAt': '2017-02-07T16:52:01Z', - 'author': { - 'login': author, - 'url': 'https://github.com/{}'.format(author), + "title": title, + "url": url, + "updatedAt": "2017-02-07T16:52:01Z", + "author": { + "login": author, + "url": "https://github.com/{}".format(author), }, - 'labels': {'nodes': labels}, - 'reactions': {'totalCount': reaction_count}, - 'thumbs_down': {'totalCount': thumbsdown_count}, - 'confuseds': {'totalCount': confused_count}, - 'comments': {'totalCount': random.randint(1, 4242)}, - 'participants': {'totalCount': random.randint(1, 42)}, + "labels": {"nodes": labels}, + "reactions": {"totalCount": reaction_count}, + "thumbs_down": {"totalCount": thumbsdown_count}, + "confuseds": {"totalCount": confused_count}, + "comments": {"totalCount": random.randint(1, 4242)}, + "participants": {"totalCount": random.randint(1, 42)}, } diff --git a/tests/static/data/geojson_europe_test.py b/tests/static/data/geojson_europe_test.py index 243123f8..9bf7f461 100644 --- a/tests/static/data/geojson_europe_test.py +++ b/tests/static/data/geojson_europe_test.py @@ -10,16 +10,16 @@ ) -path = Path(__file__).parent / '../../../pythoncz/static/data/business.geojson' +path = Path(__file__).parent / "../../../pythoncz/static/data/business.geojson" with path.open() as f: - features = json.load(f)['features'] + features = json.load(f)["features"] assert len(features) > 0 -@pytest.mark.parametrize('feature', [ - pytest.param(feature, id=feature['properties']['name']) - for feature in features -]) +@pytest.mark.parametrize( + "feature", + [pytest.param(feature, id=feature["properties"]["name"]) for feature in features], +) def test_geojson_coords_are_in_europe(feature): """Tests whether entries in GeoJSON are in Europe. If this test failed for you, it's very likely because you have @@ -33,9 +33,9 @@ def test_geojson_coords_are_in_europe(feature): (which is Prague) in your GeoJSON entry. """ # For Point, convert list of coords to nested list - geometry_type = feature['geometry']['type'] - coords = feature['geometry']['coordinates'] - places = [coords] if geometry_type == 'Point' else coords + geometry_type = feature["geometry"]["type"] + coords = feature["geometry"]["coordinates"] + places = [coords] if geometry_type == "Point" else coords for place_coords in places: for i, coord in enumerate(place_coords): diff --git a/tests/static/data/valid_json_test.py b/tests/static/data/valid_json_test.py index 10b0a390..a139c156 100644 --- a/tests/static/data/valid_json_test.py +++ b/tests/static/data/valid_json_test.py @@ -4,15 +4,15 @@ import pytest -project_dir = Path(__file__).parent / '../../..' -paths = list(project_dir.rglob('*.*json')) +project_dir = Path(__file__).parent / "../../.." +paths = list(project_dir.rglob("*.*json")) assert len(paths) > 0 -@pytest.mark.parametrize('path', [ - pytest.param(path, id=str(path.relative_to(project_dir))) - for path in paths -]) +@pytest.mark.parametrize( + "path", + [pytest.param(path, id=str(path.relative_to(project_dir))) for path in paths], +) def test_json_file_is_valid(path): """Tests whether JSON data file is a valid JSON document.""" with path.open() as f: diff --git a/tests/static/data/valid_yaml_test.py b/tests/static/data/valid_yaml_test.py index bce25e02..890e8f3e 100644 --- a/tests/static/data/valid_yaml_test.py +++ b/tests/static/data/valid_yaml_test.py @@ -1,18 +1,18 @@ -import yaml from pathlib import Path import pytest +import yaml -project_dir = Path(__file__).parent / '../../..' -paths = list(project_dir.rglob('*.y*ml')) +project_dir = Path(__file__).parent / "../../.." +paths = list(project_dir.rglob("*.y*ml")) assert len(paths) > 0 -@pytest.mark.parametrize('path', [ - pytest.param(path, id=str(path.relative_to(project_dir))) - for path in paths -]) +@pytest.mark.parametrize( + "path", + [pytest.param(path, id=str(path.relative_to(project_dir))) for path in paths], +) def test_json_file_is_valid(path): """Tests whether YAML data file is a valid YAML document.""" with path.open() as f: diff --git a/tests/views_test.py b/tests/views_test.py index 941e421d..ba9749ad 100644 --- a/tests/views_test.py +++ b/tests/views_test.py @@ -2,9 +2,8 @@ import ics import pytest -from flask import url_for from cachelib import NullCache - +from flask import url_for from pythoncz import app from pythoncz.models import github as github_module @@ -17,23 +16,23 @@ def generate_issue_mock(**kwargs): of testing. """ issue = { - 'title': 'Test Issue', - 'html_url': 'http://github.com/pyvec/zapojse/issues/42', - 'updated_at': '2017-02-07T16:52:01Z', - 'user': { - 'login': 'encukou', - 'html_url': 'https://github.com/encukou', + "title": "Test Issue", + "html_url": "http://github.com/pyvec/zapojse/issues/42", + "updated_at": "2017-02-07T16:52:01Z", + "user": { + "login": "encukou", + "html_url": "https://github.com/encukou", }, - 'is_pull_request': False, - 'repository_name': 'zapojse', - 'repository_url_html': 'http://github.com/pyvec/zapojse/', - 'organization_name': 'pyvec', - 'comments': 5, - 'participants': 6, - 'votes': 3, - 'labels': ['bug'], - 'coach': False, - 'sprint-idea': False, + "is_pull_request": False, + "repository_name": "zapojse", + "repository_url_html": "http://github.com/pyvec/zapojse/", + "organization_name": "pyvec", + "comments": 5, + "participants": 6, + "votes": 3, + "labels": ["bug"], + "coach": False, + "sprint-idea": False, } for key, value in kwargs.items(): issue[key] = value @@ -77,97 +76,122 @@ def github(): def test_get_involved_cs_renders_ordinary_issue(github, test_client): def get_issues(self, *args, **kwargs): return [generate_issue_mock()] + github.get_issues = get_issues - response = test_client.get('/zapojse/') + response = test_client.get("/zapojse/") html = extract_issues_html(response.get_data(as_text=True)) assertions = [ - ('Test Issue', 'Issue title'), - ('http://github.com/pyvec/zapojse/issues/42', 'Issue URL'), - ('https://github.com/encukou', 'Issue author URL'), - ('od encukou', 'Issue author'), - ('komentářů: 5', 'Comments count'), - ('účastníků diskuze: 6', 'Participants count'), - ('hlasů: 3', 'Votes count'), + ("Test Issue", "Issue title"), + ("http://github.com/pyvec/zapojse/issues/42", "Issue URL"), + ("https://github.com/encukou", "Issue author URL"), + ("od encukou", "Issue author"), + ("komentářů: 5", "Comments count"), + ("účastníků diskuze: 6", "Participants count"), + ("hlasů: 3", "Votes count"), ] assert response.status_code == 200 for expectation, description in assertions: assert expectation in html, description + " isn't present in the HTML" -@pytest.mark.parametrize('label_name,label_text', [ - ('coach', 'Kouč pomůže!'), - ('sprint-idea', 'Sprint'), -]) -def test_get_involved_cs_renders_special_labels(github, test_client, - label_name, label_text): +@pytest.mark.parametrize( + "label_name,label_text", + [ + ("coach", "Kouč pomůže!"), + ("sprint-idea", "Sprint"), + ], +) +def test_get_involved_cs_renders_special_labels( + github, test_client, label_name, label_text +): """ Some GitHub issue labels have a special meaning and the 'get_involved_cs' page promotes them """ + def get_issues(self, *args, **kwargs): - return [generate_issue_mock(**{ - 'labels': [label_name], - label_name: True, - })] + return [ + generate_issue_mock( + **{ + "labels": [label_name], + label_name: True, + } + ) + ] + github.get_issues = get_issues - response = test_client.get('/zapojse/') + response = test_client.get("/zapojse/") html = extract_issues_html(response.get_data(as_text=True)) assert response.status_code == 200 assert label_text in html, "Special label isn't present in the HTML" -@pytest.mark.parametrize('repo_name,is_rendered,label_cls', [ - ('pyvec/zapojse', False, None), - ('pyvec/repo', True, None), - ('pyladiescz/repo', True, 'label-pyladies'), -]) -def test_get_involved_cs_renders_repo_name(github, test_client, - repo_name, is_rendered, label_cls): +@pytest.mark.parametrize( + "repo_name,is_rendered,label_cls", + [ + ("pyvec/zapojse", False, None), + ("pyvec/repo", True, None), + ("pyladiescz/repo", True, "label-pyladies"), + ], +) +def test_get_involved_cs_renders_repo_name( + github, test_client, repo_name, is_rendered, label_cls +): """ If the issue (or pull request) is not from the pyvec/zapojse repository, it is preceeded by a link to its repository. If the issue is from the PyLadiesCZ GitHub organization, it is labeled with a 'PyLadies' label """ + def get_issues(self, *args, **kwargs): - return [generate_issue_mock( - html_url='http://github.com/{}/issues/42'.format(repo_name), - repository_name=repo_name.split('/')[1], - repository_url_html='http://github.com/{}/'.format(repo_name), - organization_name=repo_name.split('/')[0], - )] + return [ + generate_issue_mock( + html_url="http://github.com/{}/issues/42".format(repo_name), + repository_name=repo_name.split("/")[1], + repository_url_html="http://github.com/{}/".format(repo_name), + organization_name=repo_name.split("/")[0], + ) + ] + github.get_issues = get_issues - response = test_client.get('/zapojse/') + response = test_client.get("/zapojse/") html = extract_issues_html(response.get_data(as_text=True)) if is_rendered: - assert 'fa-code-branch' in html, "Repo icon isn't present in the HTML" - url = 'http://github.com/{}/'.format(repo_name) + assert "fa-code-branch" in html, "Repo icon isn't present in the HTML" + url = "http://github.com/{}/".format(repo_name) assert url in html, "Repo URL isn't present in the HTML" else: - assert 'fa-code-branch' not in html, "Repo icon is present in the HTML" + assert "fa-code-branch" not in html, "Repo icon is present in the HTML" if label_cls: assert label_cls in html, "Label isn't present in the HTML" -@pytest.mark.parametrize('is_pull_request,icon_name', [ - (True, 'fa-pencil-square'), - (False, 'fa-exclamation-circle'), -]) -def test_get_involved_cs_pull_request_icon(github, test_client, - is_pull_request, icon_name): +@pytest.mark.parametrize( + "is_pull_request,icon_name", + [ + (True, "fa-pencil-square"), + (False, "fa-exclamation-circle"), + ], +) +def test_get_involved_cs_pull_request_icon( + github, test_client, is_pull_request, icon_name +): """ Pull Requests have a different icon than Issues """ + def get_issues(self, *args, **kwargs): return [generate_issue_mock(is_pull_request=is_pull_request)] + github.get_issues = get_issues - response = test_client.get('/zapojse/') + response = test_client.get("/zapojse/") html = extract_issues_html(response.get_data(as_text=True)) assert icon_name in html @@ -179,56 +203,56 @@ def test_get_involved_cs_handles_error(github, test_client): should handle it and still display most of the content. The issues section should contain an error message with some useful links """ + def get_issues(self, *args, **kwargs): - raise RuntimeError('Ouch!') + raise RuntimeError("Ouch!") + github.get_issues = get_issues - response = test_client.get('/zapojse/') + response = test_client.get("/zapojse/") html = extract_issues_html(response.get_data(as_text=True)) assert response.status_code == 200 # otherwise Elsa build fails message = "DIV with the 'issues-error' class isn't present in the HTML" - assert 'issues-error' in html, message + assert "issues-error" in html, message message = "Link to alternative issues listing isn't present in the HTML" - assert 'https://github.com/pyvec/zapojse/issues' in html, message - url = '{base_url}?title={title}&body={body}'.format( - base_url='https://github.com/pyvec/python.cz/issues/new', - title=url_quote_plus('Nefunguje Zapoj se'), - body=url_quote_plus('RuntimeError: Ouch!'), + assert "https://github.com/pyvec/zapojse/issues" in html, message + url = "{base_url}?title={title}&body={body}".format( + base_url="https://github.com/pyvec/python.cz/issues/new", + title=url_quote_plus("Nefunguje Zapoj se"), + body=url_quote_plus("RuntimeError: Ouch!"), ) assert url in html, "URL for filing a bug report isn't present in the HTML" def test_index_en_legacy_redirect(test_client): - response = test_client.get('/english.html') - url = url_for('index_en') + response = test_client.get("/english.html") + url = url_for("index_en") html = response.get_data(as_text=True) - head = html[:html.find('')] + head = html[: html.find("")] assert ''.format(url) in head -@pytest.mark.parametrize('suffix', ('', 's001-install/')) +@pytest.mark.parametrize("suffix", ("", "s001-install/")) def test_pyladies_redirect(test_client, suffix): - response = test_client.get('/pyladies/' + suffix) - url = 'http://pyladies.cz/' + response = test_client.get("/pyladies/" + suffix) + url = "http://pyladies.cz/" if suffix: - url += 'v1/' + suffix + url += "v1/" + suffix html = response.get_data(as_text=True) - head = html[:html.find('')] + head = html[: html.find("")] assert ''.format(url) in head def test_talks_pdf_download(test_client): - response = test_client.get( - '/talks/brno-2013-11-28-veros-kaplan-postgis.pdf' - ) - assert response.headers['content-type'] == 'application/pdf' + response = test_client.get("/talks/brno-2013-11-28-veros-kaplan-postgis.pdf") + assert response.headers["content-type"] == "application/pdf" def test_ical_generation(test_client): - response = test_client.get('events.ics') + response = test_client.get("events.ics") assert response.status_code == 200 - assert 'text/calendar' in response.headers['content-type'] + assert "text/calendar" in response.headers["content-type"] assert ics.Calendar(response.get_data(as_text=True)) From 3c4dc958a1a3aa87da3c017f74aed8c183f0db94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sun, 1 Sep 2024 21:24:34 +0200 Subject: [PATCH 45/46] =?UTF-8?q?o=C4=8Dista=20sekce=20Zapojse,=20odstran?= =?UTF-8?q?=C4=9Bn=C3=AD=20TODO=20pozn=C3=A1mky?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zapojse.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/zapojse.md b/docs/zapojse.md index 3e85dfad..a12a2bb6 100644 --- a/docs/zapojse.md +++ b/docs/zapojse.md @@ -79,7 +79,9 @@ Srazy nebo workshopy dělají konkrétní lidé a Pyvec jim do toho nemluví - n ## Další nápady Pro organizaci jednorázových úkolů používáme -[GitHub](https://github.com/pyvec/zapojse/). Když nic, tak aspoň +[GitHub](https://github.com/pyvec/zapojse/) (viz Issues, můžeš tady [přidat svůj nápad](https://github.com/pyvec/zapojse/issues/new)) + +Když nic, tak aspoň [hlasuj](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) nebo [přidej vlastní nápad](https://github.com/pyvec/zapojse/issues/new). Díky hlasům budeme @@ -90,6 +92,3 @@ Značka _Kouč pomůže!_ znamená, že někdo navrhl, navrhnout jako kouč, napiš to do komentáře pod daný úkol a [přiřaď mu štítek](https://help.github.com/articles/applying-labels-to-issues-and-pull-requests/) -TODO - zrušit, možná udělat jen seznam organizací nebo repozitářů - -[Přidat nápad](https://github.com/pyvec/zapojse/issues/new) From 9fc294200e0eeb1475e74772683f54ac75f67598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pavl=C3=A1sek?= Date: Sun, 1 Sep 2024 21:30:10 +0200 Subject: [PATCH 46/46] remove tests that now they don't make sense --- tests/models/github_test.py | 429 --------------------------- tests/models/github_test_fixtures.py | 109 ------- 2 files changed, 538 deletions(-) delete mode 100644 tests/models/github_test.py delete mode 100644 tests/models/github_test_fixtures.py diff --git a/tests/models/github_test.py b/tests/models/github_test.py deleted file mode 100644 index d8137d18..00000000 --- a/tests/models/github_test.py +++ /dev/null @@ -1,429 +0,0 @@ -import re -import warnings - -import github_test_fixtures as fixtures -import pytest -import requests -import responses -from cachelib import NullCache -from pythoncz import app -from pythoncz.models import github as github_module - - -class RequestsMock(responses.RequestsMock): - def add_github_graphql(self, *args, **kwargs): - """ - Convenience method to simplify adding fake responses for calls - to GitHub's v4 GraphQL API - """ - return self.add( - responses.POST, "https://api.github.com/graphql", *args, **kwargs - ) - - -@pytest.fixture() -def patched_token(): - """ - Code expects the token to be configured. - Also this makes sure that we do not accidentally access the non-mock API. - """ - orig_value = app.config["GITHUB_TOKEN"] - app.config["GITHUB_TOKEN"] = "test" - yield - app.config["GITHUB_TOKEN"] = orig_value - - -@pytest.fixture() -def requests_mock(patched_token): - """Provides mechanism for faking HTTP responses""" - with RequestsMock() as mock: - yield mock - - -@pytest.fixture() -def github(): - """Provides the 'github' module with caching disabled""" - original_cache = github_module.cache - github_module.cache = NullCache() - yield github_module - github_module.cache = original_cache - - -def test_get_issues_merges_orgs(github, requests_mock): - """ - Tests whether 'get_issues' makes two HTTP requests for each given GitHub - organization name and whether both data gets combined in the results - """ - issue_org1 = fixtures.issue() - requests_mock.add_github_graphql( - json=fixtures.api_response_body( - repos=[ - fixtures.repository( - issues=[issue_org1], pull_requests=[], private=False - ), - ] - ), - ) - issue_org2 = fixtures.issue() - requests_mock.add_github_graphql( - json=fixtures.api_response_body( - repos=[ - fixtures.repository( - issues=[issue_org2], pull_requests=[], private=False - ), - ] - ), - ) - - issues = github.get_issues(["org1", "org2"]) - titles = set(i["title"] for i in issues) - - assert titles == {issue_org1["title"], issue_org2["title"]} - - -def test_get_issues_api_error(github, requests_mock): - """ - In case of API error, the 'get_issues' function should raise HTTPError - with combined error messages - """ - requests_mock.add_github_graphql( - status=500, - json={"errors": [{"message": "Error 1"}, {"message": "Error 2"}]}, - ) - error_message = "Error 1; Error 2" - with pytest.raises(requests.HTTPError, match=error_message) as excinfo: - github.get_issues(["org"]) - - assert excinfo.value.response.status_code == 500 - - -def test_create_api_session(patched_token, github): - """ - The '_create_api_session' helper should add User-Agent and Authorization - HTTP headers to the HTTP session - """ - session = github._create_api_session() - headers = session.headers - - assert "https://python.cz" in headers.get("User-Agent") - assert re.match(r"token \w+", headers.get("Authorization")) - - -def test_get_issues_for_org_key_error(github, requests_mock): - """ - If the API response doesn't have the expected structure, the - '_get_issues_for_org' helper should raise ValueError - """ - requests_mock.add_github_graphql(json={"data": {}}) - error_message = "Unexpected structure of the GitHub API response" - with pytest.raises(ValueError, match=error_message): - list(github._get_issues_for_org(requests.Session(), "org")) - - -def test_get_issues_for_org_merges_issues_pull_requests(github, requests_mock): - """ - The '_get_issues_for_org' helper should merge both issues with - pull requests and treat them both as issues - """ - repo1 = fixtures.repository( - issues=[fixtures.issue(), fixtures.issue(), fixtures.issue()], - pull_requests=[fixtures.issue(pr=True)], - private=False, - ) - repo2 = fixtures.repository( - issues=[fixtures.issue(), fixtures.issue()], - pull_requests=[fixtures.issue(pr=True), fixtures.issue(pr=True)], - private=False, - ) - - expected_titles_are_pr = {} - for repo in [repo1, repo2]: - for issue in repo["issues"]["nodes"]: - expected_titles_are_pr[issue["title"]] = False - for pull_request in repo["pullRequests"]["nodes"]: - expected_titles_are_pr[pull_request["title"]] = True - - api_response_body = fixtures.api_response_body(repos=[repo1, repo2]) - requests_mock.add_github_graphql(json=api_response_body) - issues = github._get_issues_for_org(requests.Session(), "org") - - titles_are_pr = {i["title"]: i["is_pull_request"] for i in issues} - - assert titles_are_pr == expected_titles_are_pr - - -def test_get_issues_for_org_skips_private(github, requests_mock): - """ - The '_get_issues_for_org' helper should skip private repositories - """ - public_repo = fixtures.repository(private=False) - - expected_titles = set() - for issue in public_repo["issues"]["nodes"]: - expected_titles.add(issue["title"]) - for pull_request in public_repo["pullRequests"]["nodes"]: - expected_titles.add(pull_request["title"]) - - api_response_body = fixtures.api_response_body( - repos=[ - fixtures.repository(private=True), - public_repo, - fixtures.repository(private=True), - fixtures.repository(private=True), - fixtures.repository(private=True), - ] - ) - requests_mock.add_github_graphql(json=api_response_body) - issues = github._get_issues_for_org(requests.Session(), "org") - - titles = set(i["title"] for i in issues) - assert titles == expected_titles - - -def test_request_api_200_invalid_json(github, requests_mock): - """ - The '_request_api' helper should raise 'ValueError' if the JSON in the - response cannot be decoded - """ - requests_mock.add_github_graphql(body="... invalid JSON ...") - error_message = "Unexpected structure of the GitHub API response" - with pytest.raises(ValueError, match=error_message): - github._request_api(requests.Session(), "... query ...", {}) - - -def test_request_api_500_invalid_json(github, requests_mock): - """ - The '_request_api' helper should raise HTTP error even if the JSON in the - response cannot be decoded - """ - requests_mock.add_github_graphql(status=500, body="... invalid JSON ...") - with pytest.raises(requests.HTTPError) as excinfo: - github._request_api(requests.Session(), "... query ...", {}) - - assert excinfo.value.response.status_code == 500 - - -@pytest.mark.parametrize("status_code", (200, 500)) -def test_request_api_X00_errors(github, requests_mock, status_code): - """ - The '_request_api' helper should raise HTTP error with error messages - sent in the response body if they're present, regardless of the HTTP status - code - """ - requests_mock.add_github_graphql( - status=status_code, - json={"errors": [{"message": "Error 1"}, {"message": "Error 2"}]}, - ) - error_message = "Error 1; Error 2" - with pytest.raises(requests.HTTPError, match=error_message) as excinfo: - github._request_api(requests.Session(), "... query ...", {}) - - assert excinfo.value.response.status_code == status_code - - -def test_request_api_200(github, requests_mock): - """ - The '_request_api' helper should parse valid JSON response and return it - """ - requests_mock.add_github_graphql(json={"data": "..."}) - json = github._request_api(requests.Session(), "... query ...", {}) - - assert json == {"data": "..."} - - -def test_request_api_500(github, requests_mock): - """ - The '_request_api' helper should raise HTTP error if the HTTP status code - indicates HTTP error, even if there are no errors in the JSON response - """ - requests_mock.add_github_graphql(status=500, json={"data": "..."}) - with pytest.raises(requests.HTTPError) as excinfo: - github._request_api(requests.Session(), "... query ...", {}) - - assert excinfo.value.response.status_code == 500 - - -def test_format_issue_missing_author(github): - """ - The '_format_issue' helper should be able to deal with the situation - when the author is deleted/disabled user - """ - issue = fixtures.issue() - issue["author"] = None - formatted_issue = github._format_issue("org", fixtures.repository(), issue) - - assert formatted_issue["user"] == { - "login": None, - "html_url": "https://github.com/ghost", - } - - -def test_format_issue_labels(github): - """The '_format_issue' helper should be able to process labels""" - issue = fixtures.issue(labels=[{"name": "bug"}, {"name": "feature"}]) - formatted_issue = github._format_issue("org", fixtures.repository(), issue) - - assert formatted_issue["labels"] == ["bug", "feature"] - assert formatted_issue["coach"] is False - - -@pytest.mark.parametrize("label_name", ("coach", "sprint-idea")) -def test_format_issue_special_labels(github, label_name): - """ - The '_format_issue' helper should be able to process the 'coach' label - and to mark the resulting formatted issue with the 'coach' flag accordingly - """ - issue = fixtures.issue(labels=[{"name": "bug"}, {"name": label_name}]) - formatted_issue = github._format_issue("org", fixtures.repository(), issue) - - assert formatted_issue["labels"] == ["bug", label_name] - assert formatted_issue[label_name] is True - - -def test_format_issue_reactions(github): - """ - The '_format_issue' helper should be able to calculate 'votes' - from reactions - """ - issue = fixtures.issue( - reactions_counts={ - "LAUGH": 42, - "HEART": 3, - } - ) - formatted_issue = github._format_issue("org", fixtures.repository(), issue) - - assert formatted_issue["votes"] == 42 + 3 - - -def test_calculate_votes(github): - """ - The '_calculate_votes' helper should correctly deal with negative votes - """ - votes = github._calculate_votes( - fixtures.issue( - reactions_counts={ - "THUMBS_UP": 1, - "THUMBS_DOWN": 1, - "LAUGH": 1, - "HOORAY": 1, - "CONFUSED": 1, - "HEART": 1, - } - ) - ) - - assert votes == 2 - - -def test_get_nodes_without_total_count(github): - subnodes = [1, 2, 3, 4] - result = github._get_nodes({"something": {"nodes": subnodes}}, "something") - - assert result == subnodes - - -def test_get_nodes_with_total_count(github): - subnodes = [1, 2, 3, 4] - result = github._get_nodes( - { - "something": { - "totalCount": len(subnodes), - "nodes": subnodes, - } - }, - "something", - ) - - assert result == subnodes - - -def test_get_nodes_with_different_total_count(github): - """ - If the total count of sub-nodes is different then the number of sub-nodes - available in the API response, at least warn about the fact that there's - some data missing and limits should be raised or results paginated - """ - subnodes = [1, 2, 3, 4] - node = { - "something": { - "totalCount": len(subnodes) + 42, - "nodes": subnodes, - } - } - with warnings.catch_warnings(record=True) as recorded_warnings: - result = github._get_nodes(node, "something") - - assert result == subnodes - assert len(recorded_warnings) == 1 - assert issubclass(recorded_warnings[0].category, UserWarning) - assert "nodes in total, but only" in str(recorded_warnings[0].message) - - -def test_sort_issues_coach(github): - """ - Issues with coaching offer should always go first no matter what - """ - repository = fixtures.repository() - issues = [ - github._format_issue("org", repository, issue) - for issue in [ - fixtures.issue(labels=[]), - fixtures.issue(labels=[{"name": "foo"}]), - fixtures.issue(labels=[{"name": "bar"}, {"name": "coach"}]), - fixtures.issue(labels=[]), - ] - ] - sorted_issues = github._sort_issues(issues) - - assert sorted_issues[0]["coach"] is True - - -def test_sort_issues_votes(github): - """ - Issues with most votes should go first if there's no 'coach' issue - """ - repository = fixtures.repository() - issues = [ - github._format_issue("org", repository, issue) - for issue in [ - fixtures.issue(labels=[], reactions_counts={"THUMBS_UP": 1}), - fixtures.issue(labels=[], reactions_counts={"THUMBS_DOWN": 1}), - fixtures.issue(labels=[], reactions_counts={"THUMBS_UP": 4}), - fixtures.issue(labels=[], reactions_counts={"THUMBS_UP": 3}), - ] - ] - sorted_issues = github._sort_issues(issues) - - assert sorted_issues[0]["votes"] == 4 - - -def test_sort_issues_activity(github): - """ - Issues with most user activity should go first if there's no 'coach' - issue and no reactions. - User activity is comments count + participants count - """ - issue1 = fixtures.issue(labels=[], reactions_counts={}) - issue1["comments"]["totalCount"] = 3 - issue1["participants"]["totalCount"] = 2 - - issue2 = fixtures.issue(labels=[], reactions_counts={}) - issue2["comments"]["totalCount"] = 1 - issue2["participants"]["totalCount"] = 9 - - issue3 = fixtures.issue(labels=[], reactions_counts={}) - issue3["comments"]["totalCount"] = 0 - issue3["participants"]["totalCount"] = 4 - - repository = fixtures.repository() - sorted_issues = github._sort_issues( - [ - github._format_issue("org", repository, issue) - for issue in [issue1, issue2, issue3] - ] - ) - - assert sorted_issues[0]["comments"] == 1 # + 9 = 10 - assert sorted_issues[1]["comments"] == 3 # + 2 = 7 - assert sorted_issues[2]["comments"] == 0 # + 4 = 4 diff --git a/tests/models/github_test_fixtures.py b/tests/models/github_test_fixtures.py deleted file mode 100644 index 51da350b..00000000 --- a/tests/models/github_test_fixtures.py +++ /dev/null @@ -1,109 +0,0 @@ -import random -import uuid - - -def api_response_body(repos=None, repos_count=None): - if repos is None: - if repos_count is None: - repos_count = random.randint(2, 4) - repos = [repository() for i in range(repos_count)] - else: - repos_count = len(repos) - - return { - "data": { - "organization": { - "repositories": { - "totalCount": repos_count, - "nodes": repos, - } - } - } - } - - -def repository( - issues=None, - issues_count=None, - pull_requests=None, - pull_requests_count=None, - private=None, -): - if issues is None: - if issues_count is None: - issues_count = random.randint(0, 4) - issues = [issue() for i in range(issues_count)] - else: - issues_count = len(issues) - - if pull_requests is None: - if pull_requests_count is None: - pull_requests_count = random.randint(0, 4) - pull_requests = [issue(pr=True) for i in range(pull_requests_count)] - else: - pull_requests_count = len(pull_requests) - - if private is None: - private = random.choice([True, False]) - - return { - "name": "repo-{}".format(uuid.uuid4()), - "nameWithOwner": "org/repo", - "isPrivate": private, - "url": "https://github.com/org/repo", - "issues": { - "totalCount": issues_count, - "nodes": issues, - }, - "pullRequests": { - "totalCount": pull_requests_count, - "nodes": pull_requests, - }, - } - - -def issue(pr=False, labels=None, reactions_counts=None): - issue_number = random.randint(1, 4242) - author = random.choice(["zuzejk", "zzuzzy", "encukou", "honzajavorek"]) - - if pr: - issue_type = "pull" - title = "Fix '{}'".format(uuid.uuid4()) - else: - issue_type = "issue" - title = "Looks like '{}' is broken".format(uuid.uuid4()) - - url = "https://github.com/org/repo/{}/{}".format(issue_type, issue_number) - - if labels is None: - labels_fake_values = ["bug", "improvement", "coach", "duplicate"] - labels_count = random.randint(0, len(labels_fake_values)) - labels = [ - {"name": label_name} - for label_name in random.sample(labels_fake_values, labels_count) - ] - - if reactions_counts is None: - reaction_count = random.randint(0, 4242) - thumbsdown_count = random.randint(0, reaction_count) - confused_count = random.randint(0, reaction_count - thumbsdown_count) - else: - reaction_count = sum(reactions_counts.values()) - thumbsdown_count = reactions_counts.get("THUMBS_DOWN", 0) - confused_count = reactions_counts.get("CONFUSED", 0) - - return { - "title": title, - "url": url, - "updatedAt": "2017-02-07T16:52:01Z", - "author": { - "login": author, - "url": "https://github.com/{}".format(author), - }, - "labels": {"nodes": labels}, - "reactions": {"totalCount": reaction_count}, - "thumbs_down": {"totalCount": thumbsdown_count}, - "confuseds": {"totalCount": confused_count}, - "comments": {"totalCount": random.randint(1, 4242)}, - "participants": {"totalCount": random.randint(1, 42)}, - }