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 - -![image](https://static.wikia.nocookie.net/bttf/images/d/d5/Time_Circuits_BTTF.png) - -## 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 + + + +
+
+

Eventos Python espalhados pelo Brasil*

+

Última atualização: 2026年01月27日 10:31:52.610475

+
+
+

Próximos Eventos

+ +
+
mai 01
+
+ Python Sul +
+
Londrina-PR
+
+ +
+ + +
+

2025

+ +
+
mai 17
+
+ PyCaxias +
+
Caxias do Sul, RS
+
+ +
+
mai 30
+
+ Python Sudeste +
+
Belo Horizonte, MG
+
+ +
+
jun 19
+
+ Caipyra +
+
Ribeirão Preto, SP
+
+ +
+
jul 31
+
+ Python Cerrado +
+
Brasília, DF
+
+ +
+
out 21
+
+ Python Brasil +
+
São Paulo, SP
+
+ +
+
nov 21
+
+ Python Sul +
+
Porto Alegre, RS
+
+ +
+ +
+

2024

+ +
+
abr 20
+
+ PyCaxias +
+
Caxias do Sul, RS
+
+ +
+
mai 30
+
+ Python Sudeste +
+
São Carlos, SP
+
+ +
+
ago 09
+
+ Python Nordeste +
+
Natal, RN
+
+ +
+
set 13
+
+ Python Sul +
+
Florianópolis, SC
+
+ +
+
set 27
+
+ Python Norte 2024 +
+
Itacoatiara, AM
+
+ +
+
out 16
+
+ Python Brasil +
+
Rio de Janeiro, RJ
+
+ +
+
nov 25
+
+ Python Cerrado 2024 + Plone Conference +
+
Brasilia, DF
+
+ +
+ +
+

2023

+ +
+
mar 11
+
+ PyCaxias 2023 +
+
Caxias do Sul, RS
+
+ +
+
mar 11
+
+ Open Data Day Recife 2023 +
+
Recife, PE
+
+ +
+
mar 16
+
+ #43 Coding Dojo Python @ Arquivei - grupy-sanca +
+
São Carlos, SP
+
+ +
+
abr 19
+
+ PyCON US 2023 +
+
Salt Lake City, Utah
+
+ +
+
set 22
+
+ Python Sul 2023 +
+
Balneário Camboriú, Santa Catarina
+
+ +
+
set 22
+
+ Python Nordeste 2023 +
+
Salvador
+
+ +
+
set 29
+
+ Python Norte 2023 +
+
Manaus, AM
+
+ +
+
out 30
+
+ Python Brasil 2023 +
+
Caxias do Sul, RS
+
+ +
+ +
+

2022

+ +
+
ago 26
+
+ Python Nordeste 2022 +
+
Aracaju, SE
+
+ +
+
set 09
+
+ Python Sul 2022 +
+
Jaraguá do Sul, SC
+
+ +
+
out 15
+
+ Python Brasil 2022 +
+
Manaus, AM
+
+ +
+
nov 26
+
+ Pyjamas 2022 +
+
Online - YouTube
+
+ +
+ +
+

2021

+ +
+
out 11
+
+ Python Brasil 2021 +
+
Online
+
+ +
+ +
+

2020

+ +
+
mar 14
+
+ Django XP +
+
Jundiaí, SP
+
+ +
+
mar 14
+
+ PyCaxias +
+
Caxias do Sul, RS
+
+ +
+
nov 02
+
+ Python Brasil 2020 +
+
Online
+
+ +
+ +
+

2019

+ +
+
jan 26
+
+ PyCommunities Experience +
+
Belo Horizonte, MG
+
+ +
+
abr 26
+
+ Python Sudeste 2019 +
+
Vitória, ES
+
+ +
+
jun 01
+
+ PySM 2019 +
+
Santa Maria, RS
+
+ +
+
jun 07
+
+ Caipyra 2019 +
+
São Carlos, SP
+
+ +
+
jul 19
+
+ Python Nordeste +
+
Recife, PE
+
+ +
+
ago 03
+
+ PyCon Amazônia 2019 +
+
Porto Velho, RO
+
+ +
+
ago 17
+
+ PyCaxias 2019 +
+
Caxias do Sul, RS
+
+ +
+
set 05
+
+ Python Cerrado 2019 +
+
Goiânia, GO
+
+ +
+
out 23
+
+ Python Brasil +
+
Ribeirão Preto, SP
+
+ +
+
nov 09
+
+ justpython +
+
São Paulo, SP
+
+ +
+
nov 09
+
+ PyPOA +
+
Porto Alegre, RS
+
+ +
+
nov 23
+
+ 1o PyQui +
+
Cuiabá, MT
+
+ +
+
nov 30
+
+ PyLadies Recife & PUG-PE apresentam - um pedaço de Recife na PyBR 2019 +
+
Recife, PE
+
+ +
+ +
+

2018

+ +
+
mar 23
+
+ Django Girls Porto Alegre +
+
Porto Alegre, RS
+
+ +
+
mar 30
+
+ Python Sudeste +
+
São Paulo, SP
+
+ +
+
abr 06
+
+ 4° PyData BSB +
+
Brasília, DF
+
+ +
+
abr 06
+
+ Django Girls Santa Maria +
+
Santa Maria, RS
+
+ +
+
abr 06
+
+ Python Sul +
+
Florianópolis, SC
+
+ +
+
mai 04
+
+ Django Girls Canoas +
+
Canoas, RS
+
+ +
+
mai 12
+
+ AfroPython - Palmares +
+
Porto Alegre, RS
+
+ +
+
mai 19
+
+ Django Girls Bento Gonçalves +
+
Bento Gonçalves, RS
+
+ +
+
mai 24
+
+ Python Nordeste +
+
Paraíba, PB
+
+ +
+
jun 08
+
+ Caipyra 2018 +
+
São Carlos, SP
+
+ +
+
jun 16
+
+ Aniversário 2 anos PyLadies Porto Alegre +
+
Porto Alegre, RS
+
+ +
+
jul 04
+
+ 7° PyData BSB +
+
Brasília, DF
+
+ +
+
jul 14
+
+ Just Python +
+
São Paulo, SP
+
+ +
+
jul 21
+
+ TDC SP (Trilha Python) +
+
São Paulo, SP
+
+ +
+
jul 27
+
+ Python do zero +
+
São Paulo, SP
+
+ +
+
jul 28
+
+ Django Girls São Paulo +
+
São Paulo, SP
+
+ +
+
ago 11
+
+ AfroPython - Wakanda +
+
Porto Alegre, RS
+
+ +
+
ago 24
+
+ Flask Conference +
+
São Paulo, SP
+
+ +
+
ago 29
+
+ SciPy LA +
+
Curitiba, PR
+
+ +
+
set 29
+
+ Python Cerrado +
+
Brasília, DF
+
+ +
+
set 29
+
+ Django Girls Passo Fundo +
+
Passo Fundo, RS
+
+ +
+
out 06
+
+ Django Girls Pelotas +
+
Pelotas, RS
+
+ +
+
out 17
+
+ Python Brasil +
+
Natal, RN
+
+ +
+
nov 08
+
+ PyData Porto Alegre +
+
Porto Alegre, RS
+
+ +
+
nov 23
+
+ AfroPython 2018 +
+
Porto Alegre, RS
+
+ +
+
dez 15
+
+ PyData Porto Alegre +
+
Porto Alegre, RS
+
+ +
+ +
+ * e pelo mundo :) +
+ +

AltStyle によって変換されたページ (->オリジナル) /

+ 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 - - - - -
-

Eventos Python espalhados pelo Brasil*

-

Última atualização: {{ updated_at }}

-
-
-

Próximos Eventos

- {% for event in events.next %} -
-
{{ event.display_date }}
-
- {{ event.name }} -
-
{{ event.location }}
-
- {% endfor %} -
- - {% for year, events in events.per_year.items() %} -
-

{{ year }}

- {% for event in events %} -
-
{{ event.display_date }}
-
- {{ event.name }} -
-
{{ event.location }}
-
- {% endfor %} -
- {% endfor %} -
- * e pelo mundo :) -
- - - 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