diff --git a/.env-sample b/.env-sample
deleted file mode 100644
index 682d427..0000000
--- a/.env-sample
+++ /dev/null
@@ -1,2 +0,0 @@
-GOOGLE_API_AUTH=google_auth.json
-GOOGLE_API_CALENDAR_ID=API_CALENDAR_ID
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
deleted file mode 100644
index 152135f..0000000
--- a/.github/workflows/deploy.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-name: Deploy
-on:
- push:
- branches: "master"
-env:
- LANG: "pt_BR.UTF-8"
-
-jobs:
- deploy:
- runs-on: ubuntu-latest
- steps:
- # Setup Environment
- - uses: actions/checkout@v3
- - name: Install poetry
- run: pipx install poetry
- - uses: actions/setup-python@v4
- with:
- python-version: '3.10'
- cache: 'poetry'
- - name: Set locale
- run: |
- sudo locale-gen pt_BR.UTF-8
- sudo update-locale LANG=pt_BR.UTF-8
- # Install Dependencies
- - name: Install dependencies
- run: poetry install
- # Deploy
- - name: Decrypt key
- run: |
- mkdir $GITHUB_WORKSPACE/secrets
- gpg --quiet --batch --yes --decrypt --passphrase="$GOOGLE_API_PASSWORD" \
- --output $GITHUB_WORKSPACE/secrets/credentials.json credentials.json.gpg
- env:
- GOOGLE_API_PASSWORD: ${{ secrets.GOOGLE_API_PASSWORD }}
- - name: Build
- run: poetry run pythonnobrasil build --update-external-calendar --output ./public
- env:
- GOOGLE_API_AUTH: ${{ secrets.GOOGLE_API_AUTH }}
- GOOGLE_API_CALENDAR_ID: ${{ secrets.GOOGLE_API_CALENDAR_ID }}
- - name: Deploy 🚀
- uses: JamesIves/github-pages-deploy-action@v4.3.0
- with:
- branch: gh-pages
- folder: public/
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 0c9bf8a..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,107 +0,0 @@
-google_auth.json
-pythonnobrasil/build/
-
-# Created by https://www.gitignore.io/api/python
-
-### Python ###
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-wheels/
-*.egg-info/
-.installed.cfg
-*.egg
-
-# PyInstaller
-# Usually these files are written by a python script from a template
-# before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.coverage
-.coverage.*
-.cache
-.pytest_cache/
-nosetests.xml
-coverage.xml
-*.cover
-.hypothesis/
-
-# Translations
-*.mo
-*.pot
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-target/
-
-# Jupyter Notebook
-.ipynb_checkpoints
-
-# pyenv
-.python-version
-
-# celery beat schedule file
-celerybeat-schedule.*
-
-# SageMath parsed files
-*.sage.py
-
-# Environments
-.env
-.venv
-env/
-venv/
-ENV/
-env.bak/
-venv.bak/
-
-# Spyder project settings
-.spyderproject
-.spyproject
-
-# Rope project settings
-.ropeproject
-
-# mkdocs documentation
-/site
-
-# mypy
-.mypy_cache/
-
-
-# End of https://www.gitignore.io/api/python
diff --git a/CNAME b/CNAME
new file mode 100644
index 0000000..300c64b
--- /dev/null
+++ b/CNAME
@@ -0,0 +1 @@
+eventos.python.org.br
\ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md
deleted file mode 100644
index 79f887f..0000000
--- a/LICENSE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 Marco Rougeth
-
-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 the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
deleted file mode 100644
index 97eba86..0000000
--- a/README.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# 📅 Eventos Python no Brasil
-
-
-
-## Como adicionar um novo evento na agenda?
-
-Para adicionar um evento/meetup/conferência/etc na agenda, basta seguir os passos abaixo:
-
-### 1. Forkar esse repositório
-
-O primeiro passo é criar um `fork` desse respositório na sua conta do Github. Se você não sabe como fazer isso, você pode seguir um dos [guias[1]](https://help.github.com/articles/fork-a-repo/) [oficias[2]](https://guides.github.com/activities/forking/) do Github em inglês, ou pode dar uma olhada no texto que a [leportella](http://leportella.com) escreveu sobre [como contribuir com projetos open source[3]](http://leportella.com/pt-br/2017/04/17/como-contribuir-com-open-source.html).
-
-### 2. Adicionar novo evento na agenda
-
-Para adicionar um novo evento na agenda e no site [eventos.python.org.br](https://eventos.python.org.br), basta alterar o arquivo `conferencias.toml` com os dados do seu evento. É preciso preencher nome, data que o evento começa e termina no padrão yyyy-mm-dd, local onde vai acontecer e url do site. Você pode usar o modelo abaixo como exemplo:
-
-```toml
-[[events]]
-name = "PyConBrasil 2006"
-start = 2006年06月01日
-end = 2006年06月02日
-location = "Brasília, DF"
-url = "https://manual-do-big-kahuna.readthedocs.io/en/latest/historia/pyconbrasil2.html"
-```
-
-### 3. Fazer um pull request com as alterações
-
-Pronto, agora basta fazer um pull request com as suas mudanças, quando o PR for revisado e aceito, o novo evento deverá aparecer na [agenda](https://calendar.google.com/calendar/embed?src=rougeth.com_5a9t9ilqlfumkopl3nlmmkq9kk%40group.calendar.google.com&ctz=America%2FSao_Paulo) e no site [eventos.python.org.br](https://eventos.python.org.br).
diff --git a/conferencias.toml b/conferencias.toml
deleted file mode 100644
index 70a4c77..0000000
--- a/conferencias.toml
+++ /dev/null
@@ -1,482 +0,0 @@
-[[events]]
-name = "Django Girls Porto Alegre"
-start = 2018年03月23日
-end = 2018年03月24日
-location = "Porto Alegre, RS"
-url = "https://www.djangogirls.org/portoalegre"
-
-[[events]]
-name = "Python Sudeste"
-start = 2018年03月30日
-end = 2018年04月01日
-location = "São Paulo, SP"
-url = "http://pythonsudeste.org/"
-
-[[events]]
-name = "4° PyData BSB"
-start = 2018年04月06日
-end = 2018年04月06日
-location = "Brasília, DF"
-url = "https://www.meetup.com/pt-BR/PyData-Brasilia/events/249137931/"
-
-[[events]]
-name = "Django Girls Santa Maria"
-start = 2018年04月06日
-end = 2018年04月07日
-location = "Santa Maria, RS"
-url = "https://www.djangogirls.org/santamaria"
-
-[[events]]
-name = "Python Sul"
-start = 2018年04月06日
-end = 2018年04月08日
-location = "Florianópolis, SC"
-url = "http://pythonsul.org"
-
-[[events]]
-name = "Django Girls Canoas"
-start = 2018年05月04日
-end = 2018年05月05日
-location = "Canoas, RS"
-url = "https://www.djangogirls.org/canoas"
-
-[[events]]
-name = "AfroPython - Palmares"
-start = 2018年05月12日
-end = 2018年05月12日
-location = "Porto Alegre, RS"
-url = "https://www.facebook.com/AfroPython/"
-
-[[events]]
-name = "Django Girls Bento Gonçalves"
-start = 2018年05月19日
-end = 2018年05月19日
-location = "Bento Gonçalves, RS"
-url = "https://www.djangogirls.org/bentogoncalves"
-
-[[events]]
-name = "Python Nordeste"
-start = 2018年05月24日
-end = 2018年05月26日
-location = "Paraíba, PB"
-url = "https://2018.pythonnordeste.org/"
-
-[[events]]
-name = "Caipyra 2018"
-start = 2018年06月08日
-end = 2018年06月11日
-location = "São Carlos, SP"
-url = "http://caipyra.python.org.br"
-
-[[events]]
-name = "Aniversário 2 anos PyLadies Porto Alegre"
-start = 2018年06月16日
-end = 2018年06月16日
-location = "Porto Alegre, RS"
-url = "https://pyladiespoa.pythonanywhere.com"
-
-[[events]]
-name = "7° PyData BSB"
-start = 2018年07月04日
-end = 2018年07月04日
-location = "Brasília, DF"
-url = "https://www.meetup.com/pt-BR/PyData-Brasilia/events/252167449/"
-
-[[events]]
-name = "Just Python"
-start = 2018年07月14日
-end = 2018年07月14日
-location = "São Paulo, SP"
-url = "http://justpython.style"
-
-[[events]]
-name = "TDC SP (Trilha Python)"
-start = 2018年07月21日
-end = 2018年07月21日
-location = "São Paulo, SP"
-url = "http://www.thedevelopersconference.com.br/tdc/2018/saopaulo/trilhas"
-
-[[events]]
-name = "Python do zero"
-start = 2018年07月27日
-end = 2018年07月27日
-location = "São Paulo, SP"
-url = "https://www.eventbrite.com.br/e/python-do-zero-soparamulheres-tickets-47237842659"
-
-[[events]]
-name = "Django Girls São Paulo"
-start = 2018年07月28日
-end = 2018年07月28日
-location = "São Paulo, SP"
-url = "https://djangogirls.org/saopaulo/"
-
-[[events]]
-name = "AfroPython - Wakanda"
-start = 2018年08月11日
-end = 2018年08月11日
-location = "Porto Alegre, RS"
-url = "https://www.facebook.com/AfroPython/"
-
-[[events]]
-name = "Flask Conference"
-start = 2018年08月24日
-end = 2018年08月25日
-location = "São Paulo, SP"
-url = "http://flask.python.org.br"
-
-[[events]]
-name = "SciPy LA"
-start = 2018年08月29日
-end = 2018年09月01日
-location = "Curitiba, PR"
-url = "http://scipyla.org/conf/2018/"
-
-[[events]]
-name = "Python Cerrado"
-start = 2018年09月29日
-end = 2018年09月30日
-location = "Brasília, DF"
-url = "http://2018.pythoncerrado.org/"
-
-[[events]]
-name = "Django Girls Passo Fundo"
-start = 2018年09月29日
-end = 2018年09月29日
-location = "Passo Fundo, RS"
-url = "https://www.djangogirls.org/passofundo"
-
-[[events]]
-name = "Django Girls Pelotas"
-start = 2018年10月06日
-end = 2018年10月06日
-location = "Pelotas, RS"
-url = "https://www.djangogirls.org/pelotas"
-
-[[events]]
-name = "Python Brasil"
-start = 2018年10月17日
-end = 2018年10月22日
-location = "Natal, RN"
-url = "https://2018.pythonbrasil.org.br"
-
-[[events]]
-name = "PyData Porto Alegre"
-start = 2018年11月08日
-end = 2018年11月08日
-location = "Porto Alegre, RS"
-url = "https://www.meetup.com/pt-BR/PyData-Porto-Alegre/"
-
-[[events]]
-name = "AfroPython 2018"
-start = 2018年11月23日
-end = 2018年11月24日
-location = "Porto Alegre, RS"
-url = "https://www.facebook.com/AfroPython/"
-
-[[events]]
-name = "PyData Porto Alegre"
-start = 2018年12月15日
-end = 2018年12月15日
-location = "Porto Alegre, RS"
-url = "https://www.meetup.com/pt-BR/PyData-Porto-Alegre/"
-
-[[events]]
-name = "PyCommunities Experience"
-start = 2019年01月26日
-end = 2019年01月26日
-location = "Belo Horizonte, MG"
-url = "https://pycommunitiesexperience.github.io/"
-
-[[events]]
-name = "Python Sudeste 2019"
-start = 2019年04月26日
-end = 2019年04月28日
-location = "Vitória, ES"
-url = "http://2019.pythonsudeste.org/"
-
-[[events]]
-name = "PySM 2019"
-start = 2019年06月01日
-end = 2019年06月01日
-location = "Santa Maria, RS"
-url = "http://pysm.github.io/"
-
-[[events]]
-name = "Caipyra 2019"
-start = 2019年06月07日
-end = 2019年06月10日
-location = "São Carlos, SP"
-url = "https://caipyra.python.org.br/"
-
-[[events]]
-name = "Python Nordeste"
-start = 2019年07月19日
-end = 2019年07月21日
-location = "Recife, PE"
-url = "https://2019.pythonnordeste.org/"
-
-[[events]]
-name = "PyCon Amazônia 2019"
-start = 2019年08月03日
-end = 2019年08月04日
-location = "Porto Velho, RO"
-url = "https://amazonia.python.org.br/"
-
-[[events]]
-name = "PyCaxias 2019"
-start = 2019年08月17日
-end = 2019年08月17日
-location = "Caxias do Sul, RS"
-url = "https://pycaxias.org/"
-
-[[events]]
-name = "Python Cerrado 2019"
-start = 2019年09月05日
-end = 2019年09月05日
-location = "Goiânia, GO"
-url = "http://pythoncerrado.grupy.goiania.br"
-
-[[events]]
-name = "Python Brasil"
-start = 2019年10月23日
-end = 2019年10月28日
-location = "Ribeirão Preto, SP"
-url = "https://2019.pythonbrasil.org.br"
-
-[[events]]
-name = "justpython"
-start = 2019年11月09日
-end = 2019年11月09日
-location = "São Paulo, SP"
-url = "https://justpython.style"
-
-[[events]]
-name = "PyPOA"
-start = 2019年11月09日
-end = 2019年11月09日
-location = "Porto Alegre, RS"
-url = "http://pypoa.org/"
-
-[[events]]
-name = "1o PyQui"
-start = 2019年11月23日
-end = 2019年11月23日
-location = "Cuiabá, MT"
-url = "https://www.meetup.com/pt-BR/DevMatoGrosso/events/266411758/"
-
-[[events]]
-name = "PyLadies Recife & PUG-PE apresentam - um pedaço de Recife na PyBR 2019"
-start = 2019年11月30日
-end = 2019年11月30日
-location = "Recife, PE"
-url = "https://www.sympla.com.br/pyladies-recife--pug-pe-apresentam-um-pedaco-de-recife-na-pybr-2019__710578"
-
-[[events]]
-name = "Django XP"
-start = 2020年03月14日
-end = 2020年03月14日
-location = "Jundiaí, SP"
-url = "http://2020.djangoxp.python.org.br/"
-
-[[events]]
-name = "PyCaxias"
-start = 2020年03月14日
-end = 2020年03月14日
-location = "Caxias do Sul, RS"
-url = "https://pycaxias.org/"
-
-[[events]]
-name = "Python Brasil 2020"
-start = 2020年11月02日
-end = 2020年11月08日
-location = "Online"
-url = "https://2020.pythonbrasil.org.br/"
-
-[[events]]
-name = "Python Brasil 2021"
-start = 2021年10月11日
-end = 2021年10月17日
-location = "Online"
-url = "https://2021.pythonbrasil.org.br/"
-
-[[events]]
-name = "Python Nordeste 2022"
-start = 2022年08月26日
-end = 2022年08月28日
-location = "Aracaju, SE"
-url = "https://2022.pythonnordeste.org"
-
-[[events]]
-name = "Python Sul 2022"
-start = 2022年09月09日
-end = 2022年09月11日
-location = "Jaraguá do Sul, SC"
-url = "https://pythonsul.dev/"
-
-[[events]]
-name = "Python Brasil 2022"
-start = 2022年10月15日
-end = 2022年10月23日
-location = "Manaus, AM"
-url = "https://2022.pythonbrasil.org.br"
-
-[[events]]
-name = "Pyjamas 2022"
-start = 2022年11月26日
-end = 2022年11月27日
-location = "Online - YouTube"
-url = "https://pyjamas.live/"
-
-[[events]]
-name = "PyCON US 2023"
-start = 2023年04月19日
-end = 2023年04月23日
-location = "Salt Lake City, Utah"
-url = "https://us.pycon.org/2023/"
-
-[[events]]
-name = "PyCaxias 2023"
-start = 2023年03月11日
-end = 2023年03月11日
-location = "Caxias do Sul, RS"
-url = "https://pycaxias.com.br"
-
-[[events]]
-name = "Python Brasil 2023"
-start = 2023年10月30日
-end = 2023年11月05日
-location = "Caxias do Sul, RS"
-url = "https://2023.pythonbrasil.org.br"
-
-[[events]]
-name = "Open Data Day Recife 2023"
-start = 2023年03月11日
-end = 2023年03月11日
-location = "Recife, PE"
-url = "https://linktr.ee/pyladiesrecife"
-
-[[events]]
-name = "#43 Coding Dojo Python @ Arquivei - grupy-sanca"
-start = 2023年03月16日
-end = 2023年03月16日
-location = "São Carlos, SP"
-url = "https://www.meetup.com/pt-BR/grupy-sanca/events/292080370/"
-
-[[events]]
-name = "Python Sul 2023"
-start = 2023年09月22日
-end = 2023年09月23日
-location = "Balneário Camboriú, Santa Catarina"
-url = "https://pythonsul.dev/"
-
-[[events]]
-name = "Python Nordeste 2023"
-start = 2023年09月22日
-end = 2023年09月24日
-location = "Salvador"
-url = "https://2023.pythonnordeste.org/"
-
-[[events]]
-name = "Python Norte 2023"
-start = 2023年09月29日
-end = 2023年09月30日
-location = "Manaus, AM"
-url = "https://2023.pythonnorte.org/"
-
-[[events]]
-name = "Python Brasil"
-start = 2024年10月16日
-end = 2024年10月21日
-location = "Rio de Janeiro, RJ"
-url = "https://2024.pythonbrasil.org.br/"
-
-[[events]]
-name = "Python Sul"
-start = 2024年09月13日
-end = 2024年09月15日
-location = "Florianópolis, SC"
-url = "https://sul.python.org.br/"
-
-[[events]]
-name = "PyCaxias"
-start = 2024年04月20日
-end = 2024年04月20日
-location = "Caxias do Sul, RS"
-url = "https://pycaxias.com.br/"
-
-[[events]]
-name = "Python Cerrado 2024 + Plone Conference"
-start = 2024年11月25日
-end = 2024年12月01日
-location = "Brasilia, DF"
-url = "https://2024.ploneconf.org/pt-br"
-
-[[events]]
-name = "Python Nordeste"
-start = 2024年08月09日
-end = 2024年08月10日
-location = "Natal, RN"
-url = "https://2024.pythonnordeste.org/"
-
-[[events]]
-name = "Python Sudeste"
-start = 2024年05月30日
-end = 2024年06月02日
-location = "São Carlos, SP"
-url = "https://www.instagram.com/pythonsudeste/"
-
-[[events]]
-name = "Python Norte 2024"
-start = 2024年09月27日
-end = 2024年09月28日
-location = "Itacoatiara, AM"
-url = "https://2024.pythonnorte.org/"
-
-[[events]]
-name = "PyCaxias"
-start = 2025年05月17日
-end = 2025年05月17日
-location = "Caxias do Sul, RS"
-url = "https://pycaxias.com.br/"
-
-[[events]]
-name = "Python Sul"
-start = 2025年11月21日
-end = 2025年11月23日
-location = "Porto Alegre, RS"
-url = "https://sul.python.org.br/"
-
-[[events]]
-name = "Python Brasil"
-start = 2025年10月21日
-end = 2025年10月27日
-location = "São Paulo, SP"
-url = "https://2025.pythonbrasil.org.br"
-
-[[events]]
-name = "Python Cerrado"
-start = 2025年07月31日
-end = 2025年08月01日
-location = "Brasília, DF"
-url = "https://www.eventbrite.com.br/e/python-cerrado-2025-tickets-1098869210389"
-
-[[events]]
-name = "Caipyra"
-start = 2025年06月19日
-end = 2025年06月22日
-location = "Ribeirão Preto, SP"
-url = "https://2025.caipyra.python.org.br"
-
-[[events]]
-name = "Python Sudeste"
-start = 2025年05月30日
-end = 2025年06月02日
-location = "Belo Horizonte, MG"
-url = "https://www.instagram.com/pythonsudeste/"
-
-[[events]]
-name = "Python Sul"
-start = 2026年05月01日
-end = 2026年05月03日
-location = "Londrina-PR"
-url = "https://sul.python.org.br/"
diff --git a/credentials.json.gpg b/credentials.json.gpg
deleted file mode 100644
index 7827b2e..0000000
Binary files a/credentials.json.gpg and /dev/null differ
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..e4b4deb
--- /dev/null
+++ b/index.html
@@ -0,0 +1,626 @@
+
+
+
+
+ Python no Brasil
+
+
+
+
+
+
+ Próximos Eventos
+
+
+
mai 01
+
+
Londrina-PR
+
+
+
+
+
+
+ 2025
+
+
+
mai 17
+
+
Caxias do Sul, RS
+
+
+
+
mai 30
+
+
Belo Horizonte, MG
+
+
+
+
jun 19
+
+
Ribeirão Preto, SP
+
+
+
+
jul 31
+
+
Brasília, DF
+
+
+
+
out 21
+
+
São Paulo, SP
+
+
+
+
nov 21
+
+
Porto Alegre, RS
+
+
+
+
+
+ 2024
+
+
+
abr 20
+
+
Caxias do Sul, RS
+
+
+
+
mai 30
+
+
São Carlos, SP
+
+
+
+
+
+
set 13
+
+
Florianópolis, SC
+
+
+
+
set 27
+
+
Itacoatiara, AM
+
+
+
+
out 16
+
+
Rio de Janeiro, RJ
+
+
+
+
nov 25
+
+
Brasilia, DF
+
+
+
+
+
+ 2023
+
+
+
mar 11
+
+
Caxias do Sul, RS
+
+
+
+
mar 11
+
+
Recife, PE
+
+
+
+
mar 16
+
+
São Carlos, SP
+
+
+
+
abr 19
+
+
Salt Lake City, Utah
+
+
+
+
set 22
+
+
Balneário Camboriú, Santa Catarina
+
+
+
+
+
+
set 29
+
+
Manaus, AM
+
+
+
+
out 30
+
+
Caxias do Sul, RS
+
+
+
+
+
+ 2022
+
+
+
ago 26
+
+
Aracaju, SE
+
+
+
+
set 09
+
+
Jaraguá do Sul, SC
+
+
+
+
out 15
+
+
Manaus, AM
+
+
+
+
nov 26
+
+
Online - YouTube
+
+
+
+
+
+
+
+ 2020
+
+
+
mar 14
+
+
Jundiaí, SP
+
+
+
+
mar 14
+
+
Caxias do Sul, RS
+
+
+
+
+
+
+
+ 2019
+
+
+
jan 26
+
+
Belo Horizonte, MG
+
+
+
+
abr 26
+
+
Vitória, ES
+
+
+
+
jun 01
+
+
Santa Maria, RS
+
+
+
+
jun 07
+
+
São Carlos, SP
+
+
+
+
jul 19
+
+
Recife, PE
+
+
+
+
ago 03
+
+
Porto Velho, RO
+
+
+
+
ago 17
+
+
Caxias do Sul, RS
+
+
+
+
set 05
+
+
Goiânia, GO
+
+
+
+
out 23
+
+
Ribeirão Preto, SP
+
+
+
+
nov 09
+
+
São Paulo, SP
+
+
+
+
nov 09
+
+
Porto Alegre, RS
+
+
+
+
nov 23
+
+
Cuiabá, MT
+
+
+
+
nov 30
+
+
Recife, PE
+
+
+
+
+
+ 2018
+
+
+
mar 23
+
+
Porto Alegre, RS
+
+
+
+
mar 30
+
+
São Paulo, SP
+
+
+
+
abr 06
+
+
Brasília, DF
+
+
+
+
abr 06
+
+
Santa Maria, RS
+
+
+
+
abr 06
+
+
Florianópolis, SC
+
+
+
+
mai 04
+
+
Canoas, RS
+
+
+
+
mai 12
+
+
Porto Alegre, RS
+
+
+
+
mai 19
+
+
Bento Gonçalves, RS
+
+
+
+
mai 24
+
+
Paraíba, PB
+
+
+
+
jun 08
+
+
São Carlos, SP
+
+
+
+
jun 16
+
+
Porto Alegre, RS
+
+
+
+
jul 04
+
+
Brasília, DF
+
+
+
+
jul 14
+
+
São Paulo, SP
+
+
+
+
jul 21
+
+
São Paulo, SP
+
+
+
+
jul 27
+
+
São Paulo, SP
+
+
+
+
jul 28
+
+
São Paulo, SP
+
+
+
+
ago 11
+
+
Porto Alegre, RS
+
+
+
+
ago 24
+
+
São Paulo, SP
+
+
+
+
ago 29
+
+
Curitiba, PR
+
+
+
+
set 29
+
+
Brasília, DF
+
+
+
+
set 29
+
+
Passo Fundo, RS
+
+
+
+
out 06
+
+
Pelotas, RS
+
+
+
+
+
+
nov 08
+
+
Porto Alegre, RS
+
+
+
+
nov 23
+
+
Porto Alegre, RS
+
+
+
+
dez 15
+
+
Porto Alegre, RS
+
+
+
+
+
+
+
+
diff --git a/pythonnobrasil/static/logo.png b/logo.png
similarity index 100%
rename from pythonnobrasil/static/logo.png
rename to logo.png
diff --git a/poetry.lock b/poetry.lock
deleted file mode 100644
index 7876e3e..0000000
--- a/poetry.lock
+++ /dev/null
@@ -1,957 +0,0 @@
-# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
-
-[[package]]
-name = "appnope"
-version = "0.1.3"
-description = "Disable App Nap on macOS>= 10.9"
-optional = false
-python-versions = "*"
-files = [
- {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"},
- {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"},
-]
-
-[[package]]
-name = "arrow"
-version = "1.2.3"
-description = "Better dates & times for Python"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"},
- {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"},
-]
-
-[package.dependencies]
-python-dateutil = ">=2.7.0"
-
-[[package]]
-name = "asttokens"
-version = "2.2.1"
-description = "Annotate AST trees with source code positions"
-optional = false
-python-versions = "*"
-files = [
- {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"},
- {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"},
-]
-
-[package.dependencies]
-six = "*"
-
-[package.extras]
-test = ["astroid", "pytest"]
-
-[[package]]
-name = "attr"
-version = "0.3.2"
-description = "Simple decorator to set attributes of target function or class in a DRY way."
-optional = false
-python-versions = "*"
-files = [
- {file = "attr-0.3.2-py2.py3-none-any.whl", hash = "sha256:4f4bffeea8c27387bde446675a7ac24f3b8fea1075f12d849b5f5c5181fc8336"},
- {file = "attr-0.3.2.tar.gz", hash = "sha256:1ceebca768181cdcce9827611b1d728e592be5d293911539ea3d0b0bfa1146f4"},
-]
-
-[[package]]
-name = "attrs"
-version = "22.1.0"
-description = "Classes Without Boilerplate"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"},
- {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"},
-]
-
-[package.extras]
-dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"]
-docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"]
-tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"]
-tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"]
-
-[[package]]
-name = "backcall"
-version = "0.2.0"
-description = "Specifications for callback functions passed in to an API"
-optional = false
-python-versions = "*"
-files = [
- {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
- {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
-]
-
-[[package]]
-name = "cachetools"
-version = "5.2.0"
-description = "Extensible memoizing collections and decorators"
-optional = false
-python-versions = "~=3.7"
-files = [
- {file = "cachetools-5.2.0-py3-none-any.whl", hash = "sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db"},
- {file = "cachetools-5.2.0.tar.gz", hash = "sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757"},
-]
-
-[[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 = "2.1.1"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-optional = false
-python-versions = ">=3.6.0"
-files = [
- {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"},
- {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"},
-]
-
-[package.extras]
-unicode-backport = ["unicodedata2"]
-
-[[package]]
-name = "click"
-version = "8.1.3"
-description = "Composable command line interface toolkit"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
- {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
-]
-
-[package.dependencies]
-colorama = {version = "*", markers = "platform_system == \"Windows\""}
-
-[[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 = "decorator"
-version = "5.1.1"
-description = "Decorators for Humans"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
- {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
-]
-
-[[package]]
-name = "exceptiongroup"
-version = "1.0.4"
-description = "Backport of PEP 654 (exception groups)"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "exceptiongroup-1.0.4-py3-none-any.whl", hash = "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828"},
- {file = "exceptiongroup-1.0.4.tar.gz", hash = "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec"},
-]
-
-[package.extras]
-test = ["pytest (>=6)"]
-
-[[package]]
-name = "executing"
-version = "1.2.0"
-description = "Get the currently executing AST node of a frame, and other information"
-optional = false
-python-versions = "*"
-files = [
- {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"},
- {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"},
-]
-
-[package.extras]
-tests = ["asttokens", "littleutils", "pytest", "rich"]
-
-[[package]]
-name = "google-api-core"
-version = "2.11.0"
-description = "Google API client core library"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "google-api-core-2.11.0.tar.gz", hash = "sha256:4b9bb5d5a380a0befa0573b302651b8a9a89262c1730e37bf423cec511804c22"},
- {file = "google_api_core-2.11.0-py3-none-any.whl", hash = "sha256:ce222e27b0de0d7bc63eb043b956996d6dccab14cc3b690aaea91c9cc99dc16e"},
-]
-
-[package.dependencies]
-google-auth = ">=2.14.1,<3.0dev" -googleapis-common-protos = ">=1.56.2,<2.0dev" -protobuf = ">=3.19.5,<3.20.0 ||>3.20.0,<3.20.1 ||>3.20.1,<4.21.0 ||>4.21.0,<4.21.1 ||>4.21.1,<4.21.2 ||>4.21.2,<4.21.3 ||>4.21.3,<4.21.4 ||>4.21.4,<4.21.5 ||>4.21.5,<5.0.0dev" -requests = ">=2.18.0,<3.0.0dev" - -[package.extras] -grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status (>=1.33.2,<2.0dev)", "grpcio-status (>=1.49.1,<2.0dev)"] -grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] -grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] - -[[package]] -name = "google-api-python-client" -version = "2.69.0" -description = "Google API Client Library for Python" -optional = false -python-versions = ">=3.7"
-files = [
- {file = "google-api-python-client-2.69.0.tar.gz", hash = "sha256:03624a28b5ba94f3c3d44761081f5dbf8cabaa20c5c3a96c046457c5713efb9b"},
- {file = "google_api_python_client-2.69.0-py2.py3-none-any.whl", hash = "sha256:bc2447a7479006d98927fb20faa74d892d3758ff68e99b621367632bc42b8af8"},
-]
-
-[package.dependencies]
-google-api-core = ">=1.31.5,<2.0.dev0 ||>2.3.0,<3.0.0dev" -google-auth = ">=1.19.0,<3.0.0dev" -google-auth-httplib2 = ">=0.1.0"
-httplib2 = ">=0.15.0,<1dev" -uritemplate = ">=3.0.1,<5" - -[[package]] -name = "google-auth" -version = "2.15.0" -description = "Google Authentication Library" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
-files = [
- {file = "google-auth-2.15.0.tar.gz", hash = "sha256:72f12a6cfc968d754d7bdab369c5c5c16032106e52d32c6dfd8484e4c01a6d1f"},
- {file = "google_auth-2.15.0-py2.py3-none-any.whl", hash = "sha256:6897b93556d8d807ad70701bb89f000183aea366ca7ed94680828b37437a4994"},
-]
-
-[package.dependencies]
-cachetools = ">=2.0.0,<6.0" -pyasn1-modules = ">=0.2.1"
-rsa = {version = ">=3.1.4,<5", markers = "python_version>= \"3.6\""}
-six = ">=1.9.0"
-
-[package.extras]
-aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] -enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] -pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"]
-reauth = ["pyu2f (>=0.1.5)"]
-
-[[package]]
-name = "google-auth-httplib2"
-version = "0.1.0"
-description = "Google Authentication Library: httplib2 transport"
-optional = false
-python-versions = "*"
-files = [
- {file = "google-auth-httplib2-0.1.0.tar.gz", hash = "sha256:a07c39fd632becacd3f07718dfd6021bf396978f03ad3ce4321d060015cc30ac"},
- {file = "google_auth_httplib2-0.1.0-py2.py3-none-any.whl", hash = "sha256:31e49c36c6b5643b57e82617cb3e021e3e1d2df9da63af67252c02fa9c1f4a10"},
-]
-
-[package.dependencies]
-google-auth = "*"
-httplib2 = ">=0.15.0"
-six = "*"
-
-[[package]]
-name = "googleapis-common-protos"
-version = "1.57.0"
-description = "Common protobufs used in Google APIs"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "googleapis-common-protos-1.57.0.tar.gz", hash = "sha256:27a849d6205838fb6cc3c1c21cb9800707a661bb21c6ce7fb13e99eb1f8a0c46"},
- {file = "googleapis_common_protos-1.57.0-py2.py3-none-any.whl", hash = "sha256:a9f4a1d7f6d9809657b7f1316a1aa527f6664891531bcfcc13b6696e685f443c"},
-]
-
-[package.dependencies]
-protobuf = ">=3.19.5,<3.20.0 ||>3.20.0,<3.20.1 ||>3.20.1,<4.21.1 ||>4.21.1,<4.21.2 ||>4.21.2,<4.21.3 ||>4.21.3,<4.21.4 ||>4.21.4,<4.21.5 ||>4.21.5,<5.0.0dev" - -[package.extras] -grpc = ["grpcio (>=1.44.0,<2.0.0dev)"] - -[[package]] -name = "httplib2" -version = "0.21.0" -description = "A comprehensive HTTP client library." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-files = [
- {file = "httplib2-0.21.0-py3-none-any.whl", hash = "sha256:987c8bb3eb82d3fa60c68699510a692aa2ad9c4bd4f123e51dfb1488c14cdd01"},
- {file = "httplib2-0.21.0.tar.gz", hash = "sha256:fc144f091c7286b82bec71bdbd9b27323ba709cc612568d3000893bfd9cb4b34"},
-]
-
-[package.dependencies]
-pyparsing = {version = ">=2.4.2,<3.0.0 ||>3.0.0,<3.0.1 ||>3.0.1,<3.0.2 ||>3.0.2,<3.0.3 ||>3.0.3,<4", markers = "python_version> \"3.0\""}
-
-[[package]]
-name = "ibis"
-version = "3.2.0"
-description = "A template engine for people who enjoy the simpler things in life."
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "ibis-3.2.0-py3-none-any.whl", hash = "sha256:2726d42176c52b4f6084db6460176ec88eaf50a52c4dcabf7a01bcbf444f595a"},
- {file = "ibis-3.2.0.tar.gz", hash = "sha256:79a5c3bfd22fde90c36b1b953ce4b5b5a7a8f86cdebf33807891eb925d643ed6"},
-]
-
-[[package]]
-name = "ics"
-version = "0.7.2"
-description = "Python icalendar (rfc5545) parser"
-optional = false
-python-versions = "*"
-files = [
- {file = "ics-0.7.2-py2.py3-none-any.whl", hash = "sha256:5fcf4d29ec6e7dfcb84120abd617bbba632eb77b097722b7df70e48dbcf26103"},
- {file = "ics-0.7.2.tar.gz", hash = "sha256:6743539bca10391635249b87d74fcd1094af20b82098bebf7c7521df91209f05"},
-]
-
-[package.dependencies]
-arrow = ">=0.11"
-attrs = ">=19.1.0"
-python-dateutil = "*"
-six = ">1.5"
-tatsu = ">4.2"
-
-[[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 = "1.1.1"
-description = "iniconfig: brain-dead simple config-ini parsing"
-optional = false
-python-versions = "*"
-files = [
- {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
- {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
-]
-
-[[package]]
-name = "ipdb"
-version = "0.13.9"
-description = "IPython-enabled pdb"
-optional = false
-python-versions = ">=2.7"
-files = [
- {file = "ipdb-0.13.9.tar.gz", hash = "sha256:951bd9a64731c444fd907a5ce268543020086a697f6be08f7cc2c9a752a278c5"},
-]
-
-[package.dependencies]
-decorator = {version = "*", markers = "python_version> \"3.6\""}
-ipython = {version = ">=7.17.0", markers = "python_version> \"3.6\""}
-setuptools = "*"
-toml = {version = ">=0.10.2", markers = "python_version> \"3.6\""}
-
-[[package]]
-name = "ipython"
-version = "8.10.0"
-description = "IPython: Productive Interactive Computing"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "ipython-8.10.0-py3-none-any.whl", hash = "sha256:b38c31e8fc7eff642fc7c597061fff462537cf2314e3225a19c906b7b0d8a345"},
- {file = "ipython-8.10.0.tar.gz", hash = "sha256:b13a1d6c1f5818bd388db53b7107d17454129a70de2b87481d555daede5eb49e"},
-]
-
-[package.dependencies]
-appnope = {version = "*", markers = "sys_platform == \"darwin\""}
-backcall = "*"
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-decorator = "*"
-jedi = ">=0.16"
-matplotlib-inline = "*"
-pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""}
-pickleshare = "*"
-prompt-toolkit = ">=3.0.30,<3.1.0" -pygments = ">=2.4.0"
-stack-data = "*"
-traitlets = ">=5"
-
-[package.extras]
-all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"]
-black = ["black"]
-doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"]
-kernel = ["ipykernel"]
-nbconvert = ["nbconvert"]
-nbformat = ["nbformat"]
-notebook = ["ipywidgets", "notebook"]
-parallel = ["ipyparallel"]
-qtconsole = ["qtconsole"]
-test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] - -[[package]] -name = "isort" -version = "5.10.1" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.6.1,<4.0" -files = [ - {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, - {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, -] - -[package.extras] -colors = ["colorama (>=0.4.3,<0.5.0)"] -pipfile-deprecated-finder = ["pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] - -[[package]] -name = "jedi" -version = "0.18.2" -description = "An autocompletion tool for Python that can be used for text editors." -optional = false -python-versions = ">=3.6"
-files = [
- {file = "jedi-0.18.2-py2.py3-none-any.whl", hash = "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e"},
- {file = "jedi-0.18.2.tar.gz", hash = "sha256:bae794c30d07f6d910d32a7048af09b5a39ed740918da923c6b780790ebac612"},
-]
-
-[package.dependencies]
-parso = ">=0.8.0,<0.9.0" - -[package.extras] -docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["Django (<3.1)", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] - -[[package]] -name = "loguru" -version = "0.6.0" -description = "Python logging made (stupidly) simple" -optional = false -python-versions = ">=3.5"
-files = [
- {file = "loguru-0.6.0-py3-none-any.whl", hash = "sha256:4e2414d534a2ab57573365b3e6d0234dfb1d84b68b7f3b948e6fb743860a77c3"},
- {file = "loguru-0.6.0.tar.gz", hash = "sha256:066bd06758d0a513e9836fd9c6b5a75bfb3fd36841f4b996bc60b547a309d41c"},
-]
-
-[package.dependencies]
-colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
-win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
-
-[package.extras]
-dev = ["Sphinx (>=4.1.1)", "black (>=19.10b0)", "colorama (>=0.3.4)", "docutils (==0.16)", "flake8 (>=3.7.7)", "isort (>=5.1.1)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "tox (>=3.9.0)"]
-
-[[package]]
-name = "matplotlib-inline"
-version = "0.1.6"
-description = "Inline Matplotlib backend for Jupyter"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"},
- {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"},
-]
-
-[package.dependencies]
-traitlets = "*"
-
-[[package]]
-name = "packaging"
-version = "22.0"
-description = "Core utilities for Python packages"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "packaging-22.0-py3-none-any.whl", hash = "sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3"},
- {file = "packaging-22.0.tar.gz", hash = "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3"},
-]
-
-[[package]]
-name = "parso"
-version = "0.8.3"
-description = "A Python Parser"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
- {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
-]
-
-[package.extras]
-qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
-testing = ["docopt", "pytest (<6.0.0)"] - -[[package]] -name = "pexpect" -version = "4.8.0" -description = "Pexpect allows easy control of interactive console applications." -optional = false -python-versions = "*" -files = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, -] - -[package.dependencies] -ptyprocess = ">=0.5"
-
-[[package]]
-name = "pickleshare"
-version = "0.7.5"
-description = "Tiny 'shelve'-like database with concurrency support"
-optional = false
-python-versions = "*"
-files = [
- {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
- {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
-]
-
-[[package]]
-name = "pluggy"
-version = "1.0.0"
-description = "plugin and hook calling mechanisms for python"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
- {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
-]
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-testing = ["pytest", "pytest-benchmark"]
-
-[[package]]
-name = "prompt-toolkit"
-version = "3.0.36"
-description = "Library for building powerful interactive command lines in Python"
-optional = false
-python-versions = ">=3.6.2"
-files = [
- {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"},
- {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"},
-]
-
-[package.dependencies]
-wcwidth = "*"
-
-[[package]]
-name = "protobuf"
-version = "4.21.11"
-description = ""
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "protobuf-4.21.11-cp310-abi3-win32.whl", hash = "sha256:25266bf373ee06d5d66f9eb1ec9d434b243dccce5c32faf151054cfa6f9dcbf1"},
- {file = "protobuf-4.21.11-cp310-abi3-win_amd64.whl", hash = "sha256:260e346927fd4e6fbb49ab545137b19610c24a1d853dc5f29ddf777ab1987211"},
- {file = "protobuf-4.21.11-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:4d01ef83517c181d60ea1c6d0b2f644be250ade740d6554a2f5a021b1ad622e3"},
- {file = "protobuf-4.21.11-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:a5a14b907a191319e7a58b38c583bbf50deb21e002f723a912c5e4f6969a778e"},
- {file = "protobuf-4.21.11-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:553e35c0878f6855e55f01a14561e6bce6df79b6636a5acf83b9d9ac7eab7922"},
- {file = "protobuf-4.21.11-cp37-cp37m-win32.whl", hash = "sha256:4b75c947289a2e9c1f37d21c593f1ef6fb4fed33977dfb2ac84f799eb29a8ff4"},
- {file = "protobuf-4.21.11-cp37-cp37m-win_amd64.whl", hash = "sha256:efb16b16fd3eef25357f84d516062753014b76279ce4e0ec4880badd2fba7370"},
- {file = "protobuf-4.21.11-cp38-cp38-win32.whl", hash = "sha256:d91a47c77b33580024b0271b65bb820c4e0264c25eb49151ad01e691de8fa0b6"},
- {file = "protobuf-4.21.11-cp38-cp38-win_amd64.whl", hash = "sha256:bab4b21a986ded225b9392c07ce21c35d790951f51e1ebfd32e4d443b05c3726"},
- {file = "protobuf-4.21.11-cp39-cp39-win32.whl", hash = "sha256:c3b9e329b4c247dc3ba5c50f60915a84e08278eb6d9e3fa674d0d04ff816bfd7"},
- {file = "protobuf-4.21.11-cp39-cp39-win_amd64.whl", hash = "sha256:85ccb4753ee21de7dc81a7a68a051f25dbe133ffa01a639ac998427d0b223387"},
- {file = "protobuf-4.21.11-py2.py3-none-any.whl", hash = "sha256:4922e3320ed70e81f05060822da36923d09fd9e04e17f411f2d8d8d0070f9f5c"},
- {file = "protobuf-4.21.11-py3-none-any.whl", hash = "sha256:a944dc9550baae276afc7dc8193191d4c2ad660270a1e5ed5a71539817ebe2e2"},
- {file = "protobuf-4.21.11.tar.gz", hash = "sha256:2c6a4d13732d9b094db31b3841986c38b17ac61a3fe05ee26a779d94c4c3fb43"},
-]
-
-[[package]]
-name = "ptyprocess"
-version = "0.7.0"
-description = "Run a subprocess in a pseudo terminal"
-optional = false
-python-versions = "*"
-files = [
- {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
- {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
-]
-
-[[package]]
-name = "pure-eval"
-version = "0.2.2"
-description = "Safely evaluate AST nodes without side effects"
-optional = false
-python-versions = "*"
-files = [
- {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"},
- {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"},
-]
-
-[package.extras]
-tests = ["pytest"]
-
-[[package]]
-name = "pyasn1"
-version = "0.4.8"
-description = "ASN.1 types and codecs"
-optional = false
-python-versions = "*"
-files = [
- {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"},
- {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"},
-]
-
-[[package]]
-name = "pyasn1-modules"
-version = "0.2.8"
-description = "A collection of ASN.1-based protocols modules."
-optional = false
-python-versions = "*"
-files = [
- {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"},
- {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"},
-]
-
-[package.dependencies]
-pyasn1 = ">=0.4.6,<0.5.0" - -[[package]] -name = "pygments" -version = "2.15.0" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.7"
-files = [
- {file = "Pygments-2.15.0-py3-none-any.whl", hash = "sha256:77a3299119af881904cd5ecd1ac6a66214b6e9bed1f2db16993b54adede64094"},
- {file = "Pygments-2.15.0.tar.gz", hash = "sha256:f7e36cffc4c517fbc252861b9a6e4644ca0e5abadf9a113c72d1358ad09b9500"},
-]
-
-[package.extras]
-plugins = ["importlib-metadata"]
-
-[[package]]
-name = "pyparsing"
-version = "3.0.9"
-description = "pyparsing module - Classes and methods to define and execute parsing grammars"
-optional = false
-python-versions = ">=3.6.8"
-files = [
- {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
- {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
-]
-
-[package.extras]
-diagrams = ["jinja2", "railroad-diagrams"]
-
-[[package]]
-name = "pytest"
-version = "7.2.0"
-description = "pytest: simple powerful testing with Python"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"},
- {file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"},
-]
-
-[package.dependencies]
-attrs = ">=19.2.0"
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "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 = "python-decouple"
-version = "3.6"
-description = "Strict separation of settings from code."
-optional = false
-python-versions = "*"
-files = [
- {file = "python-decouple-3.6.tar.gz", hash = "sha256:2838cdf77a5cf127d7e8b339ce14c25bceb3af3e674e039d4901ba16359968c7"},
- {file = "python_decouple-3.6-py3-none-any.whl", hash = "sha256:6cf502dc963a5c642ea5ead069847df3d916a6420cad5599185de6bab11d8c2e"},
-]
-
-[[package]]
-name = "rcssmin"
-version = "1.1.1"
-description = "CSS Minifier"
-optional = false
-python-versions = "*"
-files = [
- {file = "rcssmin-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:d4e263fa9428704fd94c2cb565c7519ca1d225217943f71caffe6741ab5b9df1"},
- {file = "rcssmin-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c7278c1c25bb90d8e554df92cfb3b6a1195004ead50f764653d3093933ee0877"},
- {file = "rcssmin-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f15673e97f0a68b4c378c4d15b088fe96d60bc106d278c88829923118833c20f"},
- {file = "rcssmin-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d0afc6e7b64ef30d6dcde88830ec1a237b9f16a39f920a8fd159928684ccf8db"},
- {file = "rcssmin-1.1.1-cp310-cp310-manylinux1_i686.whl", hash = "sha256:705c9112d0ed54ea40aecf97e7fd29bdf0f1c46d278a32d8f957f31dde90778a"},
- {file = "rcssmin-1.1.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:f7a1fcdbafaacac0530da04edca4a44303baab430ea42e7d59aece4b3f3e9a51"},
- {file = "rcssmin-1.1.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:cf74d7ea5e191f0f344b354eed8b7c83eeafbd9a97bec3a579c3d26edf11b005"},
- {file = "rcssmin-1.1.1-cp311-cp311-manylinux1_i686.whl", hash = "sha256:908fe072efd2432fb0975a61124609a8e05021367f6a3463d45f5e3e74c4fdda"},
- {file = "rcssmin-1.1.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:35da6a6999e9e2c5b0e691b42ed56cc479373e0ecab33ef5277dfecce625e44a"},
- {file = "rcssmin-1.1.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:e923c105100ab70abde1c01d3196ddd6b07255e32073685542be4e3a60870c8e"},
- {file = "rcssmin-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:868215e1fd0e92a6122e0ed5973dfc7bb8330fe1e92274d05b2585253b38c0ca"},
- {file = "rcssmin-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c7728e3b546b1b6ea08cab721e8e21409dbcc11b881d0b87d10b0be8930af2a2"},
- {file = "rcssmin-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:271e3d2f8614a6d4637ed8fff3d90007f03e2a654cd9444f37d888797662ba72"},
- {file = "rcssmin-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:42576d95dfad53d77df2e68dfdec95b89b10fad320f241f1af3ca1438578254a"},
- {file = "rcssmin-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:79421230dd67c37ec61ed9892813d2b839b68f2f48ef55c75f976e81701d60b4"},
- {file = "rcssmin-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:8fcfd10ae2a1c4ce231a33013f2539e07c3836bf17cc945cc25cc30bf8e68e45"},
- {file = "rcssmin-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c30f8bc839747b6da59274e0c6e4361915d66532e26448d589cb2b1846d7bf11"},
- {file = "rcssmin-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ee386bec6d62f8c814d65c011d604a7c82d24aa3f718facd66e850eea8d6a5a1"},
- {file = "rcssmin-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8a26fec3c1e6b7a3765ccbaccc20fbb5c0ed3422cc381e01a2607f08d7621c44"},
- {file = "rcssmin-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:a04d58a2a21e9a089306d3f99c4b12bf5b656a79c198ef2321e80f8fd9afab06"},
- {file = "rcssmin-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:914e589f40573035006913861ed2adc28fbe70082a8b6bff5be7ee430b7b5c2e"},
- {file = "rcssmin-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a417735d4023d47d048a6288c88dbceadd20abaaf65a11bb4fda1e8458057019"},
- {file = "rcssmin-1.1.1.tar.gz", hash = "sha256:4f9400b4366d29f5f5446f58e78549afa8338e6a59740c73115e9f6ac413dc64"},
-]
-
-[[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 = "rsa" -version = "4.9" -description = "Pure-Python RSA implementation" -optional = false -python-versions = ">=3.6,<4" -files = [ - {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, - {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, -] - -[package.dependencies] -pyasn1 = ">=0.1.3"
-
-[[package]]
-name = "setuptools"
-version = "65.6.3"
-description = "Easily download, build, install, upgrade, and uninstall Python packages"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"},
- {file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"},
-]
-
-[package.extras]
-docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
-testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
-
-[[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 = "stack-data"
-version = "0.6.2"
-description = "Extract data from python stack frames and tracebacks for informative displays"
-optional = false
-python-versions = "*"
-files = [
- {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"},
- {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"},
-]
-
-[package.dependencies]
-asttokens = ">=2.1.0"
-executing = ">=1.2.0"
-pure-eval = "*"
-
-[package.extras]
-tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
-
-[[package]]
-name = "tatsu"
-version = "5.8.3"
-description = "TatSu takes a grammar in a variation of EBNF as input, and outputs a memoizing PEG/Packrat parser in Python."
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "TatSu-5.8.3-py2.py3-none-any.whl", hash = "sha256:0a836692e67247cad9f251e083b045b13345cc715e69a7fbc16522beaa0f2163"},
- {file = "TatSu-5.8.3.zip", hash = "sha256:571ecbcdf33b7828c05e5cd95a8e8ad06af111c2c83a6a245be4d8f7c43de7bb"},
-]
-
-[package.extras]
-future-regex = ["regex"]
-
-[[package]]
-name = "toml"
-version = "0.10.2"
-description = "Python Library for Tom's Obvious, Minimal Language"
-optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
-files = [
- {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
- {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
-]
-
-[[package]]
-name = "tomli"
-version = "2.0.1"
-description = "A lil' TOML parser"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
- {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
-]
-
-[[package]]
-name = "traitlets"
-version = "5.7.0"
-description = "Traitlets Python configuration system"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "traitlets-5.7.0-py3-none-any.whl", hash = "sha256:61832ea7b7f910f5745e27e9bb269a181fd15af76027d99560299209d5b17c94"},
- {file = "traitlets-5.7.0.tar.gz", hash = "sha256:bd0fca5c890a09bf66b33cce67ca14156b080429bc39c7ef26b075a4bd4f9fc3"},
-]
-
-[package.extras]
-docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"]
-lint = ["black (>=22.6.0)", "mdformat (>0.7)", "ruff (>=0.0.156)"]
-test = ["pre-commit", "pytest"]
-typing = ["mypy (>=0.990)"]
-
-[[package]]
-name = "uritemplate"
-version = "4.1.1"
-description = "Implementation of RFC 6570 URI Templates"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"},
- {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"},
-]
-
-[[package]]
-name = "urllib3"
-version = "1.26.18"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
-files = [
- {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"},
- {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"},
-]
-
-[package.extras]
-brotli = ["brotli (==1.0.9)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
-secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
-socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - -[[package]] -name = "watchdog" -version = "2.2.0" -description = "Filesystem events monitoring" -optional = false -python-versions = ">=3.6"
-files = [
- {file = "watchdog-2.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ed91c3ccfc23398e7aa9715abf679d5c163394b8cad994f34f156d57a7c163dc"},
- {file = "watchdog-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:76a2743402b794629a955d96ea2e240bd0e903aa26e02e93cd2d57b33900962b"},
- {file = "watchdog-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:920a4bda7daa47545c3201a3292e99300ba81ca26b7569575bd086c865889090"},
- {file = "watchdog-2.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ceaa9268d81205876bedb1069f9feab3eccddd4b90d9a45d06a0df592a04cae9"},
- {file = "watchdog-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1893d425ef4fb4f129ee8ef72226836619c2950dd0559bba022b0818c63a7b60"},
- {file = "watchdog-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e99c1713e4436d2563f5828c8910e5ff25abd6ce999e75f15c15d81d41980b6"},
- {file = "watchdog-2.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a5bd9e8656d07cae89ac464ee4bcb6f1b9cecbedc3bf1334683bed3d5afd39ba"},
- {file = "watchdog-2.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3a048865c828389cb06c0bebf8a883cec3ae58ad3e366bcc38c61d8455a3138f"},
- {file = "watchdog-2.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e722755d995035dd32177a9c633d158f2ec604f2a358b545bba5bed53ab25bca"},
- {file = "watchdog-2.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:af4b5c7ba60206759a1d99811b5938ca666ea9562a1052b410637bb96ff97512"},
- {file = "watchdog-2.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:619d63fa5be69f89ff3a93e165e602c08ed8da402ca42b99cd59a8ec115673e1"},
- {file = "watchdog-2.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1f2b0665c57358ce9786f06f5475bc083fea9d81ecc0efa4733fd0c320940a37"},
- {file = "watchdog-2.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:441024df19253bb108d3a8a5de7a186003d68564084576fecf7333a441271ef7"},
- {file = "watchdog-2.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1a410dd4d0adcc86b4c71d1317ba2ea2c92babaf5b83321e4bde2514525544d5"},
- {file = "watchdog-2.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28704c71afdb79c3f215c90231e41c52b056ea880b6be6cee035c6149d658ed1"},
- {file = "watchdog-2.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2ac0bd7c206bb6df78ef9e8ad27cc1346f2b41b1fef610395607319cdab89bc1"},
- {file = "watchdog-2.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:27e49268735b3c27310883012ab3bd86ea0a96dcab90fe3feb682472e30c90f3"},
- {file = "watchdog-2.2.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:2af1a29fd14fc0a87fb6ed762d3e1ae5694dcde22372eebba50e9e5be47af03c"},
- {file = "watchdog-2.2.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:c7bd98813d34bfa9b464cf8122e7d4bec0a5a427399094d2c17dd5f70d59bc61"},
- {file = "watchdog-2.2.0-py3-none-manylinux2014_i686.whl", hash = "sha256:56fb3f40fc3deecf6e518303c7533f5e2a722e377b12507f6de891583f1b48aa"},
- {file = "watchdog-2.2.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:74535e955359d79d126885e642d3683616e6d9ab3aae0e7dcccd043bd5a3ff4f"},
- {file = "watchdog-2.2.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:cf05e6ff677b9655c6e9511d02e9cc55e730c4e430b7a54af9c28912294605a4"},
- {file = "watchdog-2.2.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:d6ae890798a3560688b441ef086bb66e87af6b400a92749a18b856a134fc0318"},
- {file = "watchdog-2.2.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e5aed2a700a18c194c39c266900d41f3db0c1ebe6b8a0834b9995c835d2ca66e"},
- {file = "watchdog-2.2.0-py3-none-win32.whl", hash = "sha256:d0fb5f2b513556c2abb578c1066f5f467d729f2eb689bc2db0739daf81c6bb7e"},
- {file = "watchdog-2.2.0-py3-none-win_amd64.whl", hash = "sha256:1f8eca9d294a4f194ce9df0d97d19b5598f310950d3ac3dd6e8d25ae456d4c8a"},
- {file = "watchdog-2.2.0-py3-none-win_ia64.whl", hash = "sha256:ad0150536469fa4b693531e497ffe220d5b6cd76ad2eda474a5e641ee204bbb6"},
- {file = "watchdog-2.2.0.tar.gz", hash = "sha256:83cf8bc60d9c613b66a4c018051873d6273d9e45d040eed06d6a96241bd8ec01"},
-]
-
-[package.extras]
-watchmedo = ["PyYAML (>=3.10)"]
-
-[[package]]
-name = "wcwidth"
-version = "0.2.5"
-description = "Measures the displayed width of unicode strings in a terminal"
-optional = false
-python-versions = "*"
-files = [
- {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
- {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
-]
-
-[[package]]
-name = "win32-setctime"
-version = "1.1.0"
-description = "A small Python utility to set file creation time on Windows"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
- {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
-]
-
-[package.extras]
-dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
-
-[metadata]
-lock-version = "2.0"
-python-versions = "^3.10"
-content-hash = "a872ae5818c03fd5b12124697ac7082ca3918c23c294565795413919307d40ed"
diff --git a/pyproject.toml b/pyproject.toml
deleted file mode 100644
index c744d89..0000000
--- a/pyproject.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-[tool.poetry]
-name = "pythonnobrasil"
-version = "0.1.0"
-description = ""
-authors = ["Marco Rougeth "]
-
-[tool.poetry.dependencies]
-python = "^3.10"
-click = "^8.1.3"
-tomli = "^2.0.1"
-attr = "^0.3.2"
-toml = "^0.10.2"
-google-auth = "^2.13.0"
-google-api-python-client = "^2.65.0"
-ics = "^0.7.2"
-python-decouple = "^3.6"
-ibis = "^3.2.0"
-watchdog = "^2.2.0"
-loguru = "^0.6.0"
-rcssmin = "^1.1.1"
-
-[tool.poetry.dev-dependencies]
-ipdb = "^0.13.9"
-ipython = "^8.10.0"
-
-[tool.poetry.scripts]
-pythonnobrasil = 'pythonnobrasil.cli:cli'
-
-[tool.poetry.group.dev.dependencies]
-pytest = "^7.2.0"
-isort = "^5.10.1"
-
-[build-system]
-requires = ["poetry-core>=1.0.0"]
-build-backend = "poetry.core.masonry.api"
diff --git a/pythonnobrasil/__init__.py b/pythonnobrasil/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/pythonnobrasil/build.py b/pythonnobrasil/build.py
deleted file mode 100644
index eb388bb..0000000
--- a/pythonnobrasil/build.py
+++ /dev/null
@@ -1,87 +0,0 @@
-from collections import defaultdict
-from datetime import datetime
-import locale
-from pathlib import Path
-import shutil
-from uuid import uuid4
-
-from rcssmin import cssmin
-
-from pythonnobrasil import config
-from pythonnobrasil.cal import Calendar
-from pythonnobrasil.run import get_template
-
-
-def get_context(calendar):
- # Set locale to pt_BR so that month_abbr uses Portugues
- locale.setlocale(locale.LC_ALL, "pt_BR.UTF-8")
- context = {}
-
- events = {
- "next": [],
- "per_year": defaultdict(list),
- }
-
- now = datetime.today()
-
- for event in sorted(calendar.events, key=lambda e: e.start, reverse=True):
- if event.start> now.date():
- events["next"].append(event)
- else:
- events["per_year"][event.start.year].append(event)
-
- events["next"] = sorted(events["next"], key=lambda e: e.start)
-
- events["per_year"] = {
- year: sorted(events, key=lambda e: e.start)
- for year, events in events["per_year"].items()
- }
-
- context["events"] = events
- context["updated_at"] = now
-
- return context
-
-
-def prepare_build(static_path: Path, build_path: Path):
- shutil.rmtree(build_path, ignore_errors=True)
- shutil.copytree(static_path, build_path)
-
-
-def minify_static_files(build_path: Path):
- minified_files = []
- build_hash = str(uuid4())[:8]
-
- for file in build_path.iterdir():
- if file.suffix != ".css":
- continue
-
- with file.open("r") as fp:
- style = fp.read()
- style_minified = cssmin(style)
-
- minified_filename = f"{file.stem}.{build_hash}{file.suffix}"
- with open(build_path / minified_filename, mode="w") as fp:
- fp.write(style_minified)
- minified_files.append(
- (file.name, minified_filename),
- )
-
- file.unlink()
-
- return minified_files
-
-
-def build_html(calendar: Calendar, build_path: Path):
- context = get_context(calendar)
-
- template = get_template()
- content = template.render(**context)
-
- minified_files = minify_static_files(build_path)
- for filename, minified_filename in minified_files:
- content = content.replace(filename, minified_filename)
-
- index = build_path / "index.html"
- with index.open(mode="w") as index_file:
- index_file.write(content)
diff --git a/pythonnobrasil/cal.py b/pythonnobrasil/cal.py
deleted file mode 100644
index 1003447..0000000
--- a/pythonnobrasil/cal.py
+++ /dev/null
@@ -1,149 +0,0 @@
-from datetime import datetime, timedelta
-
-import attr
-import toml
-from google.oauth2.service_account import Credentials
-from googleapiclient import discovery
-
-from pythonnobrasil import config
-
-DATE_FORMAT = "%Y-%m-%d"
-
-
-def _date_converter(value):
- if not isinstance(value, str):
- return value
-
- return datetime.strptime(value, DATE_FORMAT).date()
-
-
-@attr.s
-class Event:
- name = attr.ib()
- start = attr.ib(converter=_date_converter)
- end = attr.ib(converter=_date_converter)
- location = attr.ib()
- url = attr.ib()
-
- def __sub__(self, other):
- if not isinstance(other, Event):
- raise Exception()
-
- fields = [a.name for a in self.__attrs_attrs__]
-
- different_fields = []
- for field in fields:
- if getattr(self, field) != getattr(other, field):
- different_fields.append(field)
-
- return different_fields
-
- @property
- def display_date(self):
- return self.start.strftime("%b %d")
-
-
-class Calendar:
- def __getitem__(self, key):
- for event in self.events:
- if event.name == key:
- return event
-
- raise KeyError(key)
-
- def get(self, key, value=None):
- try:
- return self[key]
- except KeyError:
- return value
-
-
-class TomlCalendar(Calendar):
- def __init__(self, path):
- self.events = []
- self.fetch(path)
-
- def fetch(self, path):
- events = toml.load(path)["events"]
-
- for event_data in events:
- event = Event(**event_data)
- self.events.append(event)
-
-
-class GoogleCalendar(Calendar):
- GOOGLE_API_SCOPES = ["https://www.googleapis.com/auth/calendar"]
-
- def __init__(self):
- self.events = []
- self.fetch()
-
- @property
- def credentials(self):
- return Credentials.from_service_account_file(
- config.GOOGLE_API_AUTH, scopes=self.GOOGLE_API_SCOPES
- )
-
- @property
- def google_client(self):
- return discovery.build("calendar", "v3", credentials=self.credentials)
-
- def get_google_calendar_events(self):
- client = self.google_client.events()
- events = client.list(calendarId=config.GOOGLE_API_CALENDAR_ID).execute()
- return events["items"]
-
- def fetch(self):
- events = self.get_google_calendar_events()
- for event_data in events:
- if event_data["status"] != "confirmed":
- continue
-
- event = Event(
- name=event_data["summary"],
- start=event_data.get("start").get("date"),
- end=event_data.get("end").get("date"),
- location=event_data.get("location"),
- url=event_data.get("description"),
- )
-
- event.google_id = event_data["id"]
- if event.end:
- event.end = event.end - timedelta(days=1)
-
- self.events.append(event)
-
- def _get_payload(self, event):
- one_day = timedelta(days=1)
- end_date = event.end + one_day
- return {
- "summary": event.name,
- "location": event.location,
- "description": event.url,
- "start": {
- "date": event.start.strftime(DATE_FORMAT),
- },
- "end": {
- "date": end_date.strftime(DATE_FORMAT),
- },
- }
-
- def create_event(self, event):
- client = self.google_client.events()
-
- payload = self._get_payload(event)
- event = client.insert(
- calendarId=config.GOOGLE_API_CALENDAR_ID, body=payload
- ).execute()
- # TODO: log request
-
- def update_event(self, old_event, new_event):
- client = self.google_client.events()
-
- payload = self._get_payload(new_event)
- client.update(
- calendarId=config.GOOGLE_API_CALENDAR_ID,
- eventId=old_event.google_id,
- body=payload,
- ).execute()
- # TODO: log request
diff --git a/pythonnobrasil/cli.py b/pythonnobrasil/cli.py
deleted file mode 100644
index e3692cd..0000000
--- a/pythonnobrasil/cli.py
+++ /dev/null
@@ -1,74 +0,0 @@
-import os
-import tempfile
-from pathlib import Path
-
-import click
-
-from pythonnobrasil import config
-from pythonnobrasil.build import build_html, prepare_build
-from pythonnobrasil.cal import GoogleCalendar, TomlCalendar
-from pythonnobrasil.dev import DevServer
-from pythonnobrasil.run import create_or_update
-
-
-@click.group()
-def cli():
- ...
-
-
-@cli.command()
-@click.option(
- "--output",
- type=click.Path(exists=True, file_okay=False, path_type=Path),
- default=config.BASE_DIR / "output",
-)
-def deploy(output):
- conferencias = config.BASE_DIR.parent / "conferencias.toml"
- static_path = config.BASE_DIR / "static"
- build_path = config.BASE_DIR / "static"
- local_calendar = TomlCalendar(conferencias)
-
- google_calendar = GoogleCalendar(conferencias)
- create_or_update(local_calendar, google_calendar)
-
- prepare_build(static_path, output)
- build_html(local_calendar, output)
-
-
-@cli.command()
-@click.option("--update-external-calendar", is_flag=True)
-@click.option(
- "--output",
- type=click.Path(file_okay=False, path_type=Path),
- default=config.BASE_DIR / "output",
-)
-def build(output: Path, update_external_calendar: bool):
- if not output.exists():
- os.mkdir(output)
-
- conferencias = config.BASE_DIR.parent / "conferencias.toml"
- static_path = config.BASE_DIR / "static"
- local_calendar = TomlCalendar(conferencias)
-
- if update_external_calendar:
- google_calendar = GoogleCalendar()
- create_or_update(local_calendar, google_calendar)
-
- prepare_build(static_path, output)
- build_html(local_calendar, output)
-
-
-@cli.command()
-@click.option("--port", type=int, default=3001)
-def dev(port):
- conferencias = config.BASE_DIR.parent / "conferencias.toml"
- with tempfile.TemporaryDirectory() as tmp_dirname:
- source_path = config.BASE_DIR.parent
- build_path = Path(tmp_dirname)
-
- dev_server = DevServer(conferencias, source_path, build_path, port)
- dev_server.run()
-
-
-if __name__ == "__main__":
- cli()
diff --git a/pythonnobrasil/config.py b/pythonnobrasil/config.py
deleted file mode 100644
index 50ff9b5..0000000
--- a/pythonnobrasil/config.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from pathlib import Path
-
-from decouple import config
-
-BASE_DIR = Path().parent / "pythonnobrasil"
-
-GOOGLE_API_AUTH = config("GOOGLE_API_AUTH", default="google_auth.json")
-GOOGLE_API_CALENDAR_ID = config("GOOGLE_API_CALENDAR_ID")
-
-CONFERENCIAS_PATH = BASE_DIR.parent / "conferencias.toml"
diff --git a/pythonnobrasil/deploy.py b/pythonnobrasil/deploy.py
deleted file mode 100644
index 7fee423..0000000
--- a/pythonnobrasil/deploy.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import io
-from zipfile import ZipFile
-
-import requests
-
-from pythonnobrasil import config
-
-NETLIFY_API = "https://api.netlify.com/api/v1"
-
-
-def make_zip(path):
- build_folder = config.BASE_DIR / path
- filenames = [f for f in build_folder.iterdir() if not f.name.startswith(".")]
-
- buffer = io.BytesIO()
- with ZipFile(buffer, "w") as _zip:
- for filename in filenames:
- _zip.write(str(filename))
-
- buffer.seek(0)
- return buffer
-
-
-def push(zip):
- headers = {
- "Content-Type": "application/zip",
- }
- params = {
- "access_token": config.NETLIFY_TOKEN,
- }
-
- url = "{}/sites/{}/deploys".format(NETLIFY_API, config.NETLIFY_SITE_ID)
- response = requests.post(url, data=zip, headers=headers, params=params)
-
- error = response.json()["error_message"]
- if error:
- print(error)
diff --git a/pythonnobrasil/dev.py b/pythonnobrasil/dev.py
deleted file mode 100644
index 0c62f0b..0000000
--- a/pythonnobrasil/dev.py
+++ /dev/null
@@ -1,74 +0,0 @@
-import time
-from functools import partial
-from http.server import HTTPServer, SimpleHTTPRequestHandler
-from multiprocessing import Process
-from pathlib import Path
-
-from loguru import logger
-from watchdog.events import FileSystemEventHandler
-from watchdog.observers import Observer
-
-from pythonnobrasil.build import build_html, prepare_build
-from pythonnobrasil.cal import TomlCalendar
-from pythonnobrasil import config
-
-
-def start_local_server(port: int, path: Path):
- request_handler = partial(SimpleHTTPRequestHandler, directory=path)
- httpd = HTTPServer(("0.0.0.0", port), request_handler)
- try:
- httpd.serve_forever()
- except KeyboardInterrupt:
- httpd.shutdown()
-
-
-class DevServer(FileSystemEventHandler):
- def __init__(
- self, events_config_file: Path, source_path: Path, build_path: Path, port: int
- ):
- self.server_process = None
- self.server_port = port
- self.build_path = build_path
- self.static_path = str(config.BASE_DIR / "static")
- self.source_path = source_path
- self.events_source_file = events_config_file
-
- def build(self):
- local_calendar = TomlCalendar(self.events_source_file)
- prepare_build(self.static_path, self.build_path)
- build_html(local_calendar, self.build_path)
-
- def start_server(self):
- logger.info(f"Starting http local server. port={self.server_port}")
- self.stop_server()
-
- self.server_process = Process(
- target=start_local_server, args=(self.server_port, self.build_path)
- )
- self.server_process.start()
-
- def stop_server(self):
- if self.server_process:
- self.server_process.terminate()
-
- def on_modified(self, event):
- logger.info("File or directory modified, rebuilding website")
- self.build()
-
- def run(self):
- logger.info(
- f"Running development server. source_path={self.source_path}, build_path={self.build_path}"
- )
- self.build()
- self.start_server()
-
- observer = Observer()
- observer.schedule(self, self.source_path, recursive=True)
- observer.start()
-
- try:
- while True:
- time.sleep(1)
- except KeyboardInterrupt:
- observer.stop()
- observer.join()
diff --git a/pythonnobrasil/run.py b/pythonnobrasil/run.py
deleted file mode 100644
index 7f1508f..0000000
--- a/pythonnobrasil/run.py
+++ /dev/null
@@ -1,94 +0,0 @@
-import locale
-import shutil
-from calendar import month_abbr
-from datetime import datetime
-
-import ibis
-
-from pythonnobrasil import config, deploy
-from pythonnobrasil.cal import GoogleCalendar, TomlCalendar
-
-TODAY = datetime.today()
-
-
-def prepare_build():
- build_path = str(config.BASE_DIR / "build")
- static_path = str(config.BASE_DIR / "static")
-
- shutil.rmtree(build_path, ignore_errors=True)
- shutil.copytree(static_path, build_path)
-
-
-def get_template():
- index = config.BASE_DIR / "static/index.html"
- with index.open() as index_file:
- return ibis.Template(index_file.read())
-
-
-def get_context(calendar):
- # Set locale to pt_BR so that month_abbr uses Portugues
- locale.setlocale(locale.LC_ALL, "pt_BR.UTF-8")
-
- events = {}
- for month_number in range(1, 13):
- events[month_number] = {
- "abbr": month_abbr[month_number],
- "events": [],
- }
-
- for event in calendar.events:
- if event.start.year == TODAY.year:
- month = event.start.month
- events[month]["events"].append(event)
-
- return events
-
-
-def build_html(calendar):
- context = get_context(calendar)
-
- template = get_template()
- content = template.render(
- {
- "calendar": context,
- "today": TODAY,
- }
- )
-
- index = config.BASE_DIR / "build/index.html"
- with index.open(mode="w") as index_file:
- index_file.write(content)
-
-
-def create_or_update(local_calendar, google_calendar):
- for event in local_calendar.events:
- gevent = google_calendar.get(event.name)
-
- if not gevent:
- print("Novo evento: %s" % event.name)
- google_calendar.create_event(event)
- continue
-
- fields_changed = gevent - event
- if fields_changed:
- print("Atualizando %s: %s" % (event.name, fields_changed))
- google_calendar.update_event(gevent, event)
-
-
-def main():
- conferencias = config.BASE_DIR.parent / "conferencias.toml"
-
- local_calendar = TomlCalendar(conferencias)
- google_calendar = GoogleCalendar()
-
- create_or_update(local_calendar, google_calendar)
-
- prepare_build()
- build_html(local_calendar)
-
- zip = deploy.make_zip("build")
- deploy.push(zip)
-
-
-if __name__ == "__main__":
- main()
diff --git a/pythonnobrasil/static/index.html b/pythonnobrasil/static/index.html
deleted file mode 100644
index 98e680f..0000000
--- a/pythonnobrasil/static/index.html
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
- Python no Brasil
-
-
-
-
-
-
- Próximos Eventos
- {% for event in events.next %}
-
-
{{ event.display_date }}
-
-
{{ event.location }}
-
- {% endfor %}
-
-
- {% for year, events in events.per_year.items() %}
-
- {{ year }}
- {% for event in events %}
-
-
{{ event.display_date }}
-
-
{{ event.location }}
-
- {% endfor %}
-
- {% endfor %}
-
-
-
-
diff --git a/pythonnobrasil/static/style.css b/pythonnobrasil/static/style.css
deleted file mode 100644
index b7802fe..0000000
--- a/pythonnobrasil/static/style.css
+++ /dev/null
@@ -1,171 +0,0 @@
-body {
- margin: 0;
- padding: 0;
- color: #1f2937;
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
-}
-
-.highlight,
-.highlight-hover {
- position: relative;
-}
-
-.highlight:before,
-.highlight-hover:hover:before {
- content: "";
- position: absolute;
- width: calc(100% + 4px);
- height: 40%;
- left: -2px;
- bottom: 2px;
- z-index: -1;
-}
-
-.verde {
- color: #064E3B;
-}
-
-.verde:before {
- background-color: #4ADE80;
-}
-
-.amarelo {
- color: #713f12;
-}
-
-.amarelo:before {
- background-color: #FDE047;
-}
-
-.azul {
- color: #1e3a8a;
-}
-
-.azul:before {
- background-color: #93c5fd;
-}
-
-.vermelho:before {
- background-color: #fb7185;
-}
-
-.cinza:before {
- background-color: #d9dee3;
-}
-
-.really-small {
- font-size: 14px;
- vertical-align: top;
-}
-
-header {
- padding: 20px 0 10px 20px;
-}
-
-section {
- margin: 0;
- padding: 6px 0 6px 20px;
-}
-
-h1 {
- max-width: 460px;
- margin: 0;
-}
-
-a {
- text-decoration: none;
- color: black;
-}
-
-nav ul {
- list-style-type: none;
- list-style-position: inside;
- padding: 20px;
-}
-
-nav ul li::marker {
- content: "⁃ ";
-}
-
-.event {
- display: flex;
- flex-direction: column;
- padding-bottom: 10px;
- max-width: 420px;
-}
-
-.event:last-child {
- padding: 0;
-}
-
-.event-date {
- order: 2;
- padding-right: 16px;
- color: rgb(0, 0, 0, 0.6);
- flex-shrink: 0;
-}
-
-.event-name {
- order: 0;
- padding-right: 20px;
-}
-
-.event-name a {
- text-decoration: none;
-}
-
-.event-location {
- order: 1;
- color: rgb(0, 0, 0, 0.6);
- font-style: italic;
- flex-shrink: 0;
-}
-
-@media only screen and (min-width: 960px) {
- header {
- padding: 40px 0 20px 40px;
- }
-
- section {
- margin: 0;
- padding: 10px 0 10px 40px;
- }
-
- h1 {
- max-width: 460px;
- margin: 0;
- }
-
- nav {
- padding: 40px;
- position: fixed;
- top: 0;
- right: 0;
- text-align: right;
- }
-
- nav ul {
- list-style: none;
- }
-
- nav ul li::marker {
- content: "";
- }
-
- .event {
- flex-direction: row;
- max-width: 600px;
- }
-
- .event-date {
- order: 0;
- }
-
- .event-name {
- order: 1;
- }
-
- .event-location {
- order: 2;
- }
-}
\ No newline at end of file
diff --git a/style.2ea5aad2.css b/style.2ea5aad2.css
new file mode 100644
index 0000000..ec9e963
--- /dev/null
+++ b/style.2ea5aad2.css
@@ -0,0 +1 @@
+body{margin:0;padding:0;color:#1f2937;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.highlight,.highlight-hover{position:relative}.highlight:before,.highlight-hover:hover:before{content:"";position:absolute;width:calc(100% + 4px);height:40%;left:-2px;bottom:2px;z-index:-1}.verde{color:#064E3B}.verde:before{background-color:#4ADE80}.amarelo{color:#713f12}.amarelo:before{background-color:#FDE047}.azul{color:#1e3a8a}.azul:before{background-color:#93c5fd}.vermelho:before{background-color:#fb7185}.cinza:before{background-color:#d9dee3}.really-small{font-size:14px;vertical-align:top}header{padding:20px 0 10px 20px}section{margin:0;padding:6px 0 6px 20px}h1{max-width:460px;margin:0}a{text-decoration:none;color:black}nav ul{list-style-type:none;list-style-position:inside;padding:20px}nav ul li::marker{content:"⁃ "}.event{display:flex;flex-direction:column;padding-bottom:10px;max-width:420px}.event:last-child{padding:0}.event-date{order:2;padding-right:16px;color:rgb(0,0,0,0.6);flex-shrink:0}.event-name{order:0;padding-right:20px}.event-name a{text-decoration:none}.event-location{order:1;color:rgb(0,0,0,0.6);font-style:italic;flex-shrink:0}@media only screen and (min-width:960px){header{padding:40px 0 20px 40px}section{margin:0;padding:10px 0 10px 40px}h1{max-width:460px;margin:0}nav{padding:40px;position:fixed;top:0;right:0;text-align:right}nav ul{list-style:none}nav ul li::marker{content:""}.event{flex-direction:row;max-width:600px}.event-date{order:0}.event-name{order:1}.event-location{order:2}}
\ No newline at end of file
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/test_build.py b/tests/test_build.py
deleted file mode 100644
index 11bb2b1..0000000
--- a/tests/test_build.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from datetime import datetime
-from pathlib import Path
-from unittest.mock import patch
-from pythonnobrasil.build import minify_static_files, prepare_build, build_html
-from pythonnobrasil import config
-from pythonnobrasil.cal import Calendar, Event
-
-
-def test_prepare_build(tmp_path: Path):
- old_file = tmp_path / "old-file"
- old_file.open(mode="w").close()
- static_path = config.BASE_DIR / "static"
-
- prepare_build(static_path, tmp_path)
-
- files = list(tmp_path.iterdir())
- assert old_file not in files
- assert len(files) == 3
-
-
-def test_build_html(tmp_path: Path):
- today = datetime.now().date()
- static_path = config.BASE_DIR / "static"
- prepare_build(static_path, tmp_path)
-
- event = Event("Python Brasil 3000", today, today, "Future", "https://localhost")
- calendar = Calendar()
- calendar.events = [event]
-
- build_html(calendar, tmp_path)
-
- files = list(tmp_path.iterdir())
- assert len(files) == 3
- assert event.name in files[0].open().read()
-
-
-@patch("pythonnobrasil.build.uuid4")
-def test_minify_static_files(uuid4_mock, tmp_path: Path):
- uuid4_mock.return_value = "1234567890"
- static_path = config.BASE_DIR / "static"
- prepare_build(static_path, tmp_path)
-
- minified_files = minify_static_files(tmp_path)
-
- css_filename = "style.css"
- minified_css_filename = f"style.{uuid4_mock.return_value[:8]}.css"
- assert minified_files == [
- (css_filename, minified_css_filename),
- ]
- assert not (tmp_path / css_filename).exists()
- assert (tmp_path / minified_css_filename).exists()
diff --git a/tests/test_conferencias.py b/tests/test_conferencias.py
deleted file mode 100644
index 3afaa0f..0000000
--- a/tests/test_conferencias.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import pytest
-import toml
-
-
-@pytest.fixture
-def conferencias():
- filepath = 'conferencias.toml'
- return toml.load(filepath)
-
-
-def test_toml(conferencias):
- assert conferencias
-
-
-def test_toml_ordering(conferencias):
- events = conferencias['events']
- events_sorted_by_start = sorted(events, key=lambda d: d['start'])
-
- assert events == events_sorted_by_start
diff --git a/tests/test_toml_calendar.py b/tests/test_toml_calendar.py
deleted file mode 100644
index 2edf220..0000000
--- a/tests/test_toml_calendar.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from pythonnobrasil import config
-from pythonnobrasil.cal import TomlCalendar
-
-
-def test_toml_calendar():
- calendar = TomlCalendar(config.CONFERENCIAS_PATH)
- assert calendar
- assert calendar.events