├── .coveragerc
├── .flake8
├── .github
└── workflows
│ └── django_project.yml
├── .gitignore
├── .landscape.yml
├── .pyup.yml
├── LICENSE
├── Pipfile
├── Pipfile.lock
├── Procfile
├── README.md
├── conftest.py
├── contrib
└── env-sample
├── docker-compose.yml
├── frontend
├── package.json
└── scss
│ └── custom.scss
├── manage.py
├── pytest.ini
└── pythonpro
├── __init__.py
├── absolute_uri.py
├── celery.py
├── checkout
├── __init__.py
├── apps.py
├── facade.py
├── forms.py
├── migrations
│ ├── 0001_payment_setup.py
│ ├── 0002_webdev_setup.py
│ ├── 0003_data_science_setup.py
│ ├── 0004_bootcamp_setup.py
│ ├── 0005_python_avancado_setup.py
│ ├── 0006_webinar_setup.py
│ ├── 0007_webserie_and_webinar_boleto.py
│ ├── 0008_thiago_avelino_checkouts.py
│ └── __init__.py
├── static
│ ├── checkout
│ │ ├── css
│ │ │ ├── normalize.css
│ │ │ ├── python-pro.webflow.css
│ │ │ └── webflow.css
│ │ ├── images
│ │ │ ├── 62-626208_python-logo-png-transparent-background-python-logo-png.jpg
│ │ │ ├── CAPA_PythonDjango-FRENTESite.jpg
│ │ │ ├── DSC_7555.png
│ │ │ ├── ana-paula-batalha-4.jpg
│ │ │ ├── card-bx.svg
│ │ │ ├── charles-tenorio.jpeg
│ │ │ ├── city-bx.svg
│ │ │ ├── favicon.png
│ │ │ ├── guido-luz.jpeg
│ │ │ ├── home-bx.svg
│ │ │ ├── mail-bx.svg
│ │ │ ├── marcelo-andriolli.jpg
│ │ │ ├── maria-elisa.png
│ │ │ ├── pablo-gabriel.jpeg
│ │ │ ├── phone-bx.svg
│ │ │ ├── python-pro-bg.svg
│ │ │ ├── rafael-ramos.jpeg
│ │ │ ├── regis-santos.jpeg
│ │ │ ├── site_preview.png
│ │ │ ├── user-bx.svg
│ │ │ ├── webclip.png
│ │ │ └── white_bg.svg
│ │ └── js
│ │ │ └── webflow.js
│ └── thanks
│ │ ├── css
│ │ ├── normalize.css
│ │ ├── python-pro.webflow.css
│ │ └── webflow.css
│ │ ├── images
│ │ ├── Camada-8-p-500.png
│ │ ├── Camada-8.png
│ │ ├── NoPath---Copia.png
│ │ ├── NoPath.png
│ │ ├── down-arrow.svg
│ │ ├── error.svg
│ │ ├── favicon.png
│ │ ├── gift-lace.svg
│ │ ├── python-pro-bg.svg
│ │ ├── webclip.png
│ │ ├── white_bg.svg
│ │ ├── white_bg_1.svg
│ │ └── x.svg
│ │ └── js
│ │ └── webflow.js
├── templates
│ ├── checkout
│ │ ├── _bootcamp_lp_payment_block.html
│ │ ├── bootcamp_lp_d1.html
│ │ ├── bootcamp_lp_d2.html
│ │ ├── bootcamp_lp_d3.html
│ │ ├── bootcamp_lp_subscription_closed.html
│ │ ├── bootcamp_lp_subscription_open.html
│ │ ├── webdev_landing_page.html
│ │ ├── webdev_landing_page_50_off.html
│ │ └── webdev_landing_page_oto.html
│ └── django_pagarme
│ │ ├── contact_form.html
│ │ ├── contact_form_errors.html
│ │ ├── pagarme.html
│ │ ├── pagarme_bootcamp.html
│ │ ├── pagarme_bootcamp_35_discount.html
│ │ ├── pagarme_bootcamp_50_discount.html
│ │ ├── pagarme_bootcamp_d1_boleto.html
│ │ ├── pagarme_bootcamp_lista_de_espera.html
│ │ ├── pagarme_bootcamp_lote0.html
│ │ ├── pagarme_bootcamp_lote1_comercial.html
│ │ ├── pagarme_bootcamp_lote1_pagina_de_vendas.html
│ │ ├── pagarme_bootcamp_lote1_whatsapp.html
│ │ ├── pagarme_bootcamp_lote2_comercial.html
│ │ ├── pagarme_bootcamp_lote2_pagina_de_vendas.html
│ │ ├── pagarme_bootcamp_lote2_whatsapp.html
│ │ ├── pagarme_bootcamp_lote3_comercial.html
│ │ ├── pagarme_bootcamp_lote3_pagina_de_vendas.html
│ │ ├── pagarme_bootcamp_lote3_whatsapp.html
│ │ ├── pagarme_bootcamp_webdev.html
│ │ ├── pagarme_bootcamp_webdev_35_discount.html
│ │ ├── pagarme_bootcamp_webdev_50_discount.html
│ │ ├── pagarme_comunidade_devpro.html
│ │ ├── pagarme_django_para_profissionais.html
│ │ ├── pagarme_djangopro.html
│ │ ├── pagarme_djangopro_comercial.html
│ │ ├── pagarme_djangopro_promocao_especial.html
│ │ ├── pagarme_djangopro_promocao_especial_comercial.html
│ │ ├── pagarme_djangopro_promocao_especial_deschamps.html
│ │ ├── pagarme_jrpv_lista_vip.html
│ │ ├── pagarme_jrpv_lista_vip_promocao.html
│ │ ├── pagarme_pacote_proximo_nivel.html
│ │ ├── pagarme_programa_de_aceleracao.html
│ │ ├── pagarme_programa_de_aceleracao_upgrade.html
│ │ ├── pagarme_renovacao_comunidade_devpro.html
│ │ ├── pagarme_webdev.html
│ │ ├── pagarme_webdev_downsell.html
│ │ ├── pagarme_webdev_downsell_boleto.html
│ │ ├── pagarme_webdev_oto.html
│ │ ├── show_boleto_data.html
│ │ ├── thanks.html
│ │ ├── thanks_aps.html
│ │ ├── thanks_bootcamp.html
│ │ ├── thanks_bootcamp_35_discount.html
│ │ ├── thanks_bootcamp_50_discount.html
│ │ ├── thanks_bootcamp_d1_boleto.html
│ │ ├── thanks_bootcamp_webdev_35_discount.html
│ │ ├── thanks_bootcamp_webdev_50_discount.html
│ │ ├── thanks_jrpv_lista_vip.html
│ │ └── unavailable_payment_item.html
├── tests
│ ├── __init__.py
│ ├── conftest.py
│ └── test_payment_setup.py
├── urls.py
└── views.py
├── cohorts
├── __init__.py
├── admin.py
├── apps.py
├── facade.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_liveclass.py
│ ├── 0003_webinar.py
│ ├── 0004_cohortstudent_added.py
│ ├── 0005_auto_20180612_1206.py
│ ├── 0006_auto_20190226_1830.py
│ ├── 0007_auto_20190226_1843.py
│ ├── 0008_auto_20190307_1712.py
│ ├── 0009_increase_webinar_title_length.py
│ ├── 0010_add_memberkit_url_to_cohort_contents.py
│ └── __init__.py
├── models.py
├── tests
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_cohorts.py
│ └── test_live_class_detail.py
├── urls.py
└── views.py
├── core
├── __init__.py
├── admin.py
├── apps.py
├── context_processors.py
├── facade.py
├── forms.py
├── management
│ ├── __init__.py
│ └── commands
│ │ ├── __init__.py
│ │ └── seed_dev_db.py
├── managers.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20180530_1801.py
│ ├── 0003_auto_20180530_1826.py
│ ├── 0004_auto_20180601_1108.py
│ ├── 0005_auto_20180603_2026.py
│ ├── 0006_user_source.py
│ ├── 0007_auto_20190705_0829.py
│ ├── 0008_auto_20190812_1627.py
│ ├── 0009_auto_20191031_1324.py
│ ├── 0010_normalizing_email.py
│ ├── 0011_normalizing_lead_email.py
│ ├── 0012_added_checkout_form_categories.py
│ ├── 0013_auto_webdev_constraints.py
│ ├── 0014_auto_become_data_scientist.py
│ ├── 0015_become_bootcamper.py
│ ├── 0016_become_pythonista.py
│ └── __init__.py
├── models.py
├── roles.py
├── static
│ ├── css
│ │ ├── bootstrap-grid.css
│ │ ├── bootstrap-grid.css.map
│ │ ├── bootstrap-grid.min.css
│ │ ├── bootstrap-grid.min.css.map
│ │ ├── bootstrap-reboot.css
│ │ ├── bootstrap-reboot.css.map
│ │ ├── bootstrap-reboot.min.css
│ │ ├── bootstrap-reboot.min.css.map
│ │ ├── bootstrap.css
│ │ ├── bootstrap.css.map
│ │ ├── bootstrap.min.css
│ │ ├── bootstrap.min.css.map
│ │ ├── client.css
│ │ ├── custom.css
│ │ ├── custom.css.map
│ │ ├── default.css
│ │ ├── python-birds
│ │ │ ├── custom.css
│ │ │ ├── custom.min.css
│ │ │ ├── magnific-popup.min.css
│ │ │ ├── normalize.min.css
│ │ │ ├── owl.carousel.min.css
│ │ │ └── owl.theme.default.min.css
│ │ └── spp
│ │ │ ├── bootstrap.css
│ │ │ ├── custom.css
│ │ │ ├── custom.min.css
│ │ │ ├── magnific-popup.min.css
│ │ │ ├── normalize.min.css
│ │ │ ├── owl.carousel.min.css
│ │ │ └── owl.theme.default.min.css
│ ├── favicon
│ │ ├── python-birds
│ │ │ ├── android-chrome-192x192.png
│ │ │ ├── android-chrome-512x512.png
│ │ │ ├── apple-touch-icon.png
│ │ │ ├── browserconfig.xml
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── favicon.ico
│ │ │ ├── mstile-144x144.png
│ │ │ ├── mstile-150x150.png
│ │ │ ├── mstile-310x150.png
│ │ │ ├── mstile-310x310.png
│ │ │ ├── mstile-70x70.png
│ │ │ ├── safari-pinned-tab.svg
│ │ │ └── site.webmanifest
│ │ └── spp
│ │ │ ├── android-chrome-192x192.png
│ │ │ ├── android-chrome-512x512.png
│ │ │ ├── apple-touch-icon.png
│ │ │ ├── browserconfig.xml
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── favicon.ico
│ │ │ ├── mstile-144x144.png
│ │ │ ├── mstile-150x150.png
│ │ │ ├── mstile-310x150.png
│ │ │ ├── mstile-310x310.png
│ │ │ ├── mstile-70x70.png
│ │ │ ├── safari-pinned-tab.svg
│ │ │ └── site.webmanifest
│ ├── fonts
│ │ ├── Gilroy-Bold.woff
│ │ ├── Gilroy-Heavy.woff
│ │ ├── Gilroy-Light.woff
│ │ ├── Gilroy-Medium.woff
│ │ ├── Gilroy-Regular.woff
│ │ ├── eot
│ │ │ ├── Intelo-900.eot
│ │ │ ├── Titillium-300.eot
│ │ │ ├── Titillium-500.eot
│ │ │ ├── Titillium-700.eot
│ │ │ └── Titillium-900.eot
│ │ ├── otf
│ │ │ ├── Intelo-900.otf
│ │ │ ├── Titillium-300.otf
│ │ │ ├── Titillium-500.otf
│ │ │ ├── Titillium-700.otf
│ │ │ └── Titillium-900.otf
│ │ ├── svg
│ │ │ ├── Intelo-900.svg
│ │ │ ├── Titillium-300.svg
│ │ │ ├── Titillium-500.svg
│ │ │ ├── Titillium-700.svg
│ │ │ └── Titillium-900.svg
│ │ ├── ttf
│ │ │ ├── Intelo-900.ttf
│ │ │ ├── Titillium-300.ttf
│ │ │ ├── Titillium-500.ttf
│ │ │ ├── Titillium-700.ttf
│ │ │ └── Titillium-900.ttf
│ │ ├── woff
│ │ │ ├── Intelo-900.woff
│ │ │ ├── Titillium-300.woff
│ │ │ ├── Titillium-500.woff
│ │ │ ├── Titillium-700.woff
│ │ │ └── Titillium-900.woff
│ │ └── woff2
│ │ │ ├── Intelo-900.woff2
│ │ │ ├── Titillium-300.woff2
│ │ │ ├── Titillium-500.woff2
│ │ │ ├── Titillium-700.woff2
│ │ │ └── Titillium-900.woff2
│ ├── img
│ │ ├── 3.gif
│ │ ├── ajax-loader.gif
│ │ ├── banner-pagarme.png
│ │ ├── compra-segura-1.png
│ │ ├── favicon.ico
│ │ ├── favicon.png
│ │ ├── garantia.png
│ │ ├── instructors
│ │ │ ├── renzo-nuccitelli-300.jpeg
│ │ │ ├── renzo-nuccitelli-300.webp
│ │ │ ├── renzo-nuccitelli.jpeg
│ │ │ └── renzo-nuccitelli.webp
│ │ ├── launch
│ │ │ ├── video1-available.png
│ │ │ ├── video1-unavailable.png
│ │ │ ├── video2-available.png
│ │ │ ├── video2-unavailable.png
│ │ │ ├── video3-available.png
│ │ │ └── video3-unavailable.png
│ │ ├── python-birds
│ │ │ ├── backgrounds
│ │ │ │ └── bg-header.jpg
│ │ │ ├── card-python-de-graca.png
│ │ │ ├── companies
│ │ │ │ ├── companies-detail.png
│ │ │ │ ├── logo-google.jpg
│ │ │ │ ├── logo-nasa.jpg
│ │ │ │ ├── logo-netflix.jpg
│ │ │ │ ├── logo-spotify.jpg
│ │ │ │ ├── logo-uber.jpg
│ │ │ │ └── logo-yahoo.jpg
│ │ │ ├── header
│ │ │ │ ├── header-detail-middle.png
│ │ │ │ ├── header-detail-top-left.jpg
│ │ │ │ ├── header-detail-top-right.jpg
│ │ │ │ ├── header-renzo-bottom-mobile.jpg
│ │ │ │ └── logo-python.png
│ │ │ ├── learning
│ │ │ │ ├── learning-1_vgsvdd_c_scale,w_200.jpg
│ │ │ │ ├── learning-1_vgsvdd_c_scale,w_450.jpg
│ │ │ │ ├── learning-1_vgsvdd_c_scale,w_603.jpg
│ │ │ │ ├── learning-2_ihqj3j_c_scale,w_200.jpg
│ │ │ │ ├── learning-2_ihqj3j_c_scale,w_349.jpg
│ │ │ │ ├── learning-2_ihqj3j_c_scale,w_659.jpg
│ │ │ │ ├── learning-detail-bottom.jpg
│ │ │ │ ├── learning-detail-right.jpg
│ │ │ │ └── learning-detail-top.jpg
│ │ │ ├── noticia-15-profissoes.webp
│ │ │ ├── noticia-9-motivos-conteudo.webp
│ │ │ ├── noticia-9-motivos.webp
│ │ │ ├── noticia-sobram-vagas.webp
│ │ │ ├── noticia-stack-1.webp
│ │ │ ├── noticia-stack-2.webp
│ │ │ ├── noticia-stack-3.webp
│ │ │ ├── testimonials
│ │ │ │ ├── testimonials-detail-top.png
│ │ │ │ ├── thumb-1.jpg
│ │ │ │ ├── thumb-2.jpg
│ │ │ │ ├── thumb-3.jpg
│ │ │ │ ├── thumb-4.jpg
│ │ │ │ ├── thumb-5.jpg
│ │ │ │ ├── thumb-6.jpg
│ │ │ │ ├── thumb-7.jpg
│ │ │ │ └── thumb-8.jpg
│ │ │ └── why
│ │ │ │ ├── logo-computerworld.jpg
│ │ │ │ ├── logo-valor-economico.jpg
│ │ │ │ ├── python-detail-bottom-left.jpg
│ │ │ │ ├── python-detail-bottom-right.jpg
│ │ │ │ ├── python-detail-middle.jpg
│ │ │ │ ├── python-detail-top-left.jpg
│ │ │ │ ├── python-detail-top-right.png
│ │ │ │ ├── why-detail.jpg
│ │ │ │ └── why-paper.jpg
│ │ ├── renzo-thumb.jpg
│ │ ├── renzo-thumb.png
│ │ ├── social-proof
│ │ │ ├── alisson-americo-1.png
│ │ │ ├── alysson.webp
│ │ │ ├── carlos-augusto.png
│ │ │ ├── charles-tenorio.png
│ │ │ ├── diego.webp
│ │ │ ├── fabricio.webp
│ │ │ ├── ferrabras.webp
│ │ │ ├── guido-percu.png
│ │ │ ├── isaac.webp
│ │ │ ├── jasiel.png
│ │ │ ├── jorge-plautz.png
│ │ │ ├── marcelo-andreoli.png
│ │ │ ├── marcelo.webp
│ │ │ ├── marcus-vinicius.png
│ │ │ ├── maria-elisa.png
│ │ │ ├── pablo.png
│ │ │ ├── paulo.png
│ │ │ ├── rafael-ramos.png
│ │ │ ├── regis-silva.png
│ │ │ ├── ricardo-portela.png
│ │ │ ├── ronaldo-oliveira.png
│ │ │ ├── tanio.png
│ │ │ ├── testando-o-mercado.webp
│ │ │ ├── vicente.webp
│ │ │ ├── vinicius-assef.png
│ │ │ └── vinicius.webp
│ │ ├── spp
│ │ │ ├── card-python-pro.png
│ │ │ ├── cards-classes
│ │ │ │ ├── card-1.jpg
│ │ │ │ ├── card-2.jpg
│ │ │ │ ├── image-material.png
│ │ │ │ └── image-telegram.png
│ │ │ ├── countdown
│ │ │ │ └── countdown-detail.png
│ │ │ ├── footer-classes
│ │ │ │ ├── renzo-desktop.png
│ │ │ │ └── renzo-mobile.jpg
│ │ │ ├── footer
│ │ │ │ ├── cpnj.jpg
│ │ │ │ ├── detail-top-footer.png
│ │ │ │ ├── email.jpg
│ │ │ │ ├── footer-group-detail.jpg
│ │ │ │ ├── phone.jpg
│ │ │ │ ├── renzo-nuccitelli-footer-desktop.png
│ │ │ │ ├── renzo-nuccitelli-footer-desktop.webp
│ │ │ │ ├── renzo-nuccitelli-footer.jpg
│ │ │ │ ├── renzo-nuccitelli-footer.webp
│ │ │ │ ├── renzo-nuccitelli-v2.png
│ │ │ │ └── renzo-nuccitelli-v2.webp
│ │ │ ├── garantee-main
│ │ │ │ └── garantee-badge.png
│ │ │ ├── header
│ │ │ │ ├── detail-video-header-main.png
│ │ │ │ ├── detail-video-header-main.webp
│ │ │ │ ├── renzo-nuccitelli-desktop.jpg
│ │ │ │ ├── renzo-nuccitelli-desktop.webp
│ │ │ │ ├── renzo-nuccitelli-mobile.png
│ │ │ │ └── renzo-nuccitelli-mobile.webp
│ │ │ ├── interview-main
│ │ │ │ └── interview-icon.png
│ │ │ ├── pacote-proximo-nivel-mobile.png
│ │ │ ├── pacote-proximo-nivel.png
│ │ │ ├── people-main
│ │ │ │ ├── access-icon.jpg
│ │ │ │ ├── adriano-brasileiro.jpg
│ │ │ │ ├── certificate-icon.jpg
│ │ │ │ ├── eric-gomes.jpg
│ │ │ │ ├── isaac-ferreira.jpg
│ │ │ │ ├── jessica-ferrari1.jpg
│ │ │ │ ├── luiz-vital.jpg
│ │ │ │ ├── people-image-detail.png
│ │ │ │ ├── rodrigo-vaccari.jpg
│ │ │ │ ├── vicente-marcal.jpg
│ │ │ │ └── vinicius-assef.jpg
│ │ │ ├── renzo-main
│ │ │ │ └── renzo-nuccitelli-mobile.png
│ │ │ ├── renzo
│ │ │ │ ├── about-renzo-nuccitelli-desktop.png
│ │ │ │ ├── about-renzo-nuccitelli-desktop.webp
│ │ │ │ ├── about-renzo-nuccitelli-mobile.jpg
│ │ │ │ └── about-renzo-nuccitelli-mobile.webp
│ │ │ ├── summary-main
│ │ │ │ ├── bonus-1-desktop.jpg
│ │ │ │ ├── bonus-1-mobile.jpg
│ │ │ │ ├── bonus-2-desktop.jpg
│ │ │ │ ├── bonus-2-mobile.jpg
│ │ │ │ ├── bonus-3-desktop.jpg
│ │ │ │ ├── bonus-3-mobile.jpg
│ │ │ │ ├── summary-card-1.png
│ │ │ │ ├── summary-card-2.png
│ │ │ │ ├── summary-card-3.png
│ │ │ │ ├── summary-card-4.png
│ │ │ │ └── summary-price-icon.jpg
│ │ │ ├── thank-you
│ │ │ │ ├── backgrounds
│ │ │ │ │ ├── bg-header-desktop.jpg
│ │ │ │ │ └── bg-header-mobile.jpg
│ │ │ │ └── steps
│ │ │ │ │ ├── step-1-desktop.png
│ │ │ │ │ ├── step-1-mobile.jpg
│ │ │ │ │ ├── step-2-desktop.png
│ │ │ │ │ ├── step-2-mobile.jpg
│ │ │ │ │ ├── step-3-desktop.png
│ │ │ │ │ ├── step-3-mobile.jpg
│ │ │ │ │ ├── step-4-desktop.jpg
│ │ │ │ │ └── step-4-mobile.jpg
│ │ │ └── thumbs-testimonials
│ │ │ │ ├── thumb-1.jpg
│ │ │ │ ├── thumb-2.jpg
│ │ │ │ ├── thumb-3.jpg
│ │ │ │ ├── thumb-4.jpg
│ │ │ │ ├── thumb-5.jpg
│ │ │ │ ├── thumb-6.jpg
│ │ │ │ ├── thumb-7.jpg
│ │ │ │ └── thumb-8.jpg
│ │ └── whatsapp-loader.gif
│ ├── js
│ │ ├── bootstrap.bundle.js
│ │ ├── bootstrap.bundle.js.map
│ │ ├── bootstrap.bundle.min.js
│ │ ├── bootstrap.bundle.min.js.map
│ │ ├── bootstrap.js
│ │ ├── bootstrap.js.map
│ │ ├── bootstrap.min.js
│ │ ├── bootstrap.min.js.map
│ │ ├── jquery-3.2.1.min.js
│ │ ├── lazy.js
│ │ ├── python-birds
│ │ │ ├── jquery.min.js
│ │ │ ├── magnific-popup.min.js
│ │ │ ├── main.js
│ │ │ └── owl.carousel.min.js
│ │ ├── sentry.5.3.0.min.js
│ │ └── spp
│ │ │ ├── OneSignalSDKUpdaterWorker.js
│ │ │ ├── OneSignalSDKWorker.js
│ │ │ ├── countdown.js
│ │ │ ├── countdown.min.js
│ │ │ ├── jquery.min.js
│ │ │ ├── magnific-popup.min.js
│ │ │ └── owl.carousel.min.js
│ └── svg
│ │ └── spp
│ │ ├── blue-arrow-icon.svg
│ │ ├── green-arrow-icon.svg
│ │ ├── green-camera-icon.svg
│ │ ├── instagram-logo.svg
│ │ ├── logo-python-pro.svg
│ │ ├── logo-semana-do-programador-profissional.svg
│ │ ├── twitter-logo.svg
│ │ ├── white-camera-icon.svg
│ │ ├── x-price-icon.svg
│ │ └── youtube-logo.svg
├── templates
│ ├── 400.html
│ ├── 403.html
│ ├── 404.html
│ ├── 500.html
│ ├── core
│ │ ├── _scripts.html
│ │ ├── base.html
│ │ ├── base_without_nav.html
│ │ ├── index.html
│ │ ├── instructors.html
│ │ ├── lead_change_password.html
│ │ ├── lead_form.html
│ │ ├── lead_form_errors.html
│ │ ├── lead_landing_lite_page.html
│ │ ├── lead_landing_page.html
│ │ ├── lead_thanks.html
│ │ ├── linktree.html
│ │ ├── password_email.txt
│ │ ├── profile_detail.html
│ │ ├── profile_email.html
│ │ ├── profile_name.html
│ │ ├── profile_password.html
│ │ ├── social_proof.html
│ │ └── unsubscribe.html
│ ├── redirector
│ │ └── redirect.html
│ ├── registration
│ │ ├── login_modal.html
│ │ ├── password_reset_complete.html
│ │ ├── password_reset_confirm.html
│ │ ├── password_reset_done.html
│ │ └── password_reset_form.html
│ └── two_factor
│ │ ├── _base.html
│ │ ├── core
│ │ ├── backup_tokens.html
│ │ ├── login.html
│ │ ├── otp_required.html
│ │ ├── setup.html
│ │ └── setup_complete.html
│ │ └── profile
│ │ └── profile.html
├── tests
│ ├── __init__.py
│ ├── test_admin.py
│ ├── test_api_register_and_subscribe_fellow.py
│ ├── test_email_migration.py
│ ├── test_lead_email_migration.py
│ ├── test_lead_landing_page.py
│ ├── test_linktree.py
│ ├── test_login.py
│ ├── test_password_reset.py
│ ├── test_seed_command.py
│ ├── test_sitemaps_and_robots.py
│ ├── test_user_creation.py
│ ├── test_view_edit_email.py
│ ├── test_view_edit_name.py
│ ├── test_view_edit_password.py
│ ├── test_view_home.py
│ ├── test_view_profile.py
│ └── test_view_unsubscribe.py
├── urls.py
└── views.py
├── dashboard
├── __init__.py
├── admin.py
├── apps.py
├── facade.py
├── forms.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20190812_1627.py
│ ├── 0003_topic_duration_updated_based_on_interaction.py
│ └── __init__.py
├── models.py
├── static
│ └── dashboard
│ │ └── img
│ │ └── assinatura-renzo.jpg
├── templates
│ └── dashboard
│ │ ├── certificate.html
│ │ └── home.html
├── templatetags
│ ├── __init__.py
│ └── dashboard_tags.py
├── tests
│ ├── __init__.py
│ └── test_interaction_creation.py
├── urls.py
└── views.py
├── discord
├── __init__.py
├── admin.py
├── api_client.py
├── apps.py
├── bot.py
├── facade.py
├── management
│ ├── __init__.py
│ └── commands
│ │ ├── __init__.py
│ │ ├── clean_discord_users.py
│ │ └── warn_users_about_subscription_expiration.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_discord_user_created_at_desc_index.py
│ ├── 0003_create_discord_lead.py
│ └── __init__.py
├── models.py
├── tasks.py
├── templates
│ └── discord
│ │ └── access_denied.html
├── tests
│ ├── __init__.py
│ ├── test_api_client.py
│ ├── test_clean_discord_user.py
│ ├── test_commands.py
│ ├── test_discord_integration.py
│ └── test_warn_subscription_expiration.py
├── urls.py
└── views.py
├── discourse
├── __init__.py
├── apps.py
├── facade.py
├── tests
│ ├── __init__.py
│ ├── test_sso.py
│ └── test_sync.py
├── urls.py
└── views.py
├── django_assertions.py
├── domain
├── README.md
├── __init__.py
├── checkout_domain.py
├── content_statistics_domain.py
├── hotzapp_domain.py
├── subscription_domain.py
├── tests
│ ├── __init__.py
│ ├── test_certificate.py
│ ├── test_checkout
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── test_boleto_generation.py
│ │ ├── test_contact_info.py
│ │ ├── test_credit_card_payment.py
│ │ ├── test_hotzapp.py
│ │ ├── test_payment_handler.py
│ │ ├── test_payment_page.py
│ │ ├── test_thanks.py
│ │ └── test_unavailable_product.py
│ ├── test_content_completion.py
│ ├── test_lead.py
│ ├── test_subscriptions_page.py
│ └── test_user_services_sinchronization.py
└── user_domain.py
├── email_marketing
├── __init__.py
├── apps.py
├── facade.py
└── tests
│ ├── test_grant_role.py
│ └── test_user_creation.py
├── launch
├── __init__.py
├── apps.py
├── facade.py
├── forms.py
├── templates
│ └── launch
│ │ ├── _navbar.html
│ │ ├── _whatsapp_widget.html
│ │ ├── cpl.html
│ │ ├── form.html
│ │ ├── landing_page.html
│ │ ├── member_landing_page_subscription_closed.html
│ │ ├── member_landing_page_subscription_open.html
│ │ ├── membership_email.txt
│ │ ├── meteoric_landing_page_open.html
│ │ ├── ty.html
│ │ └── vip-list.html
├── tests
│ ├── __init__.py
│ ├── test_cpl.py
│ ├── test_cpl1.py
│ ├── test_cpl2.py
│ ├── test_cpl3.py
│ ├── test_cpl4.py
│ ├── test_landing_page.py
│ ├── test_launch_status.py
│ ├── test_lead_form.py
│ ├── test_ty.py
│ └── test_vip_list.py
├── urls.py
└── views.py
├── memberkit
├── __init__.py
├── admin.py
├── api.py
├── apps.py
├── facade.py
├── management
│ ├── __init__.py
│ └── commands
│ │ ├── __init__.py
│ │ ├── create_subscriptions_for_roles.py
│ │ ├── fix_inactive_subscriptions.py
│ │ ├── inactivate_expired_subscriptions.py
│ │ └── synchronize_paid_subscriptions.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_create_relationship_with_payment_config_item.py
│ ├── 0003_subscription.py
│ ├── 0004_add_membership_activation_data.py
│ ├── 0005_create_tags_for_discourse_email_marketing_subscription.py
│ ├── 0006_include_cohort_subscription_flag.py
│ ├── 0007_allow_subscripiton_be_saved_without_payment.py
│ ├── 0008_added_days_of_access_field.py
│ ├── 0009_altered_subscription_default_to_one_year.py
│ ├── 0010_added_has_discord_access.py
│ ├── 0011_alter_subscription_status.py
│ ├── 0012_added_subscription_expired_at.py
│ ├── 0013_populate_expired_at.py
│ ├── 0014_alter_subscription_days_of_access_and_more.py
│ └── __init__.py
├── models.py
├── templates
│ └── memberkit
│ │ ├── manual_migration.html
│ │ └── subscriptiontype
│ │ └── synchronize_button.html
├── tests
│ ├── __init__.py
│ ├── test_api.py
│ ├── test_commands.py
│ ├── test_process_expired_subscriptions.py
│ ├── test_subscription_summary.py
│ ├── test_subscription_type_synchronization.py
│ ├── test_subscriptions_expired_at.py
│ ├── test_user_management.py
│ └── test_views.py
└── views.py
├── modules
├── __init__.py
├── admin.py
├── apps.py
├── chapters_urls.py
├── chapters_views.py
├── context_processors.py
├── facade.py
├── fixtures
│ ├── pythonpro_contents.json
│ └── pythonpro_modules.json
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20180314_1122.py
│ ├── 0003_module.py
│ ├── 0004_section_module.py
│ ├── 0005_auto_20180314_1817.py
│ ├── 0006_chapter.py
│ ├── 0007_topic.py
│ ├── 0008_topic_discourse_topic_id.py
│ ├── 0009_auto_20180319_0020.py
│ ├── 0010_auto_20190226_1830.py
│ ├── 0011_created_duration_on_topic.py
│ ├── 0012_create_memberkit_url.py
│ └── __init__.py
├── models.py
├── module_urls.py
├── modules_views.py
├── permissions.py
├── sections_urls.py
├── sections_views.py
├── templates
│ ├── chapters
│ │ └── chapter_detail.html
│ ├── modules
│ │ ├── module_description.html
│ │ ├── module_detail.html
│ │ ├── module_enrol.html
│ │ └── module_index.html
│ ├── sections
│ │ └── section_detail.html
│ └── topics
│ │ └── topic_detail.html
├── tests
│ ├── __init__.py
│ ├── test_chapters_view.py
│ ├── test_module_description_view.py
│ ├── test_module_detail_view.py
│ ├── test_module_index_view.py
│ ├── test_module_index_view_roles_access.py
│ ├── test_next_content.py
│ ├── test_previous_content.py
│ ├── test_sections_view.py
│ └── test_topics_view.py
├── topics_urls.py
└── topics_views.py
├── pages
├── __init__.py
├── apps.py
├── forms.py
├── templates
│ └── pages
│ │ ├── base.html
│ │ ├── base_thank_you.html
│ │ ├── bootcamp_vip_landing_page.html
│ │ ├── bootcamp_vip_thank_you_page.html
│ │ ├── carreira_pro_landing_page.html
│ │ ├── carreira_pro_thank_you_page.html
│ │ ├── ds_webinar_landing_page.html
│ │ ├── ds_webinar_thank_you_page.html
│ │ ├── leads_onboarding_page.html
│ │ ├── pixeling_page.html
│ │ ├── tpp_masterclass_landing_page.html
│ │ ├── tpp_masterclass_thank_you_page.html
│ │ ├── tpp_webiorico_landing_page.html
│ │ ├── tpp_webiorico_landing_page_v2.html
│ │ └── tpp_webiorico_thank_you_page.html
├── tests
│ ├── __init__.py
│ ├── test_bootcamp_vip_landing_page.py
│ ├── test_carreirapro_landing_page.py
│ ├── test_leads_onboarding_page.py
│ └── test_view_base.py
├── urls.py
└── views.py
├── redirector
├── __init__.py
├── admin.py
├── apps.py
├── facade.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20200421_2144.py
│ ├── 0003_redirect_use_javascript.py
│ ├── 0004_redirectlink_total_access.py
│ └── __init__.py
├── models.py
├── tests
│ ├── __init__.py
│ ├── test_redirect_by_headers.py
│ ├── test_redirect_by_javascript.py
│ ├── test_redirect_by_query_string.py
│ └── test_redirect_rotating_links.py
├── urls.py
└── views.py
├── settings.py
├── tests
├── __init__.py
├── test_urls.py
└── test_wsgi.py
├── urls.py
└── wsgi.py
/.coveragerc:
--------------------------------------------------------------------------------
1 | [run]
2 | source=pythonpro
3 |
4 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | max-line-length = 120
3 | exclude=.venv
4 |
--------------------------------------------------------------------------------
/.landscape.yml:
--------------------------------------------------------------------------------
1 | python-targets:
2 | - 3
3 |
4 | uses:
5 | - django
6 |
7 | ignore-paths:
8 | - staticfiles
9 | - pythonpro/core/static
10 | - pythonpro/wsgi.py
11 | - pythonpro/core/migrations
12 | - pythonpro/core/admin.py
--------------------------------------------------------------------------------
/.pyup.yml:
--------------------------------------------------------------------------------
1 | requirements:
2 | - Pipfile
3 | - Pipfile.lock
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | release: python manage.py sync_roles & python manage.py migrate --noinput
2 | web: gunicorn pythonpro.wsgi --log-file -
3 | worker: celery --app pythonpro.celery worker --loglevel=info
4 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.3"
2 |
3 | services:
4 | database:
5 | container_name: pythonpro_database
6 | image: postgres:15.2
7 | volumes:
8 | - ./.pgdata:/var/lib/postgresql/data
9 | environment:
10 | - LC_ALL=C.UTF-8
11 | - POSTGRES_PASSWORD=postgres
12 | - POSTGRES_USER=postgres
13 | ports:
14 | - 5432:5432
15 | celery_broker:
16 | container_name: pythonpro_celery_broker
17 | image: rabbitmq:3.8.2
18 | ports:
19 | - 5672:5672
20 | redis:
21 | container_name: pythonpro_redis
22 | image: redis:5.0.7
23 | ports:
24 | - 6379:6379
25 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pythonpro-website",
3 | "version": "0.1.0",
4 | "description": "Customizing Twitter Bootstrap 4",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "scss": "node-sass -watch scss -o css"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "bootstrap": "^4.0.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/scss/custom.scss:
--------------------------------------------------------------------------------
1 | $green: #9fd25f;
2 | $blue: #178eee;
3 | $yellow: #ffcc29;
4 | @import "../node_modules/bootstrap/scss/bootstrap";
5 |
6 | $theme-colors: (
7 | "primary": #178eee,
8 | "success": #9fd25f,
9 | "warning": #ffcc29
10 | );
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == "__main__":
6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pythonpro.settings")
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError as exc:
10 | raise ImportError(
11 | "Couldn't import Django. Are you sure it's installed and "
12 | "available on your PYTHONPATH environment variable? Did you "
13 | "forget to activate a virtual environment?"
14 | ) from exc
15 | execute_from_command_line(sys.argv)
16 |
--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | DJANGO_SETTINGS_MODULE=pythonpro.settings
3 | python_files=test*.py *tests.py
4 | junit_family=xunit2
5 |
--------------------------------------------------------------------------------
/pythonpro/__init__.py:
--------------------------------------------------------------------------------
1 | from .celery import app as celery_app # noqa
2 |
3 | __all__ = ('celery_app',)
4 |
--------------------------------------------------------------------------------
/pythonpro/absolute_uri.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 |
3 |
4 | def build_absolute_uri(path: str) -> str:
5 | """
6 | Calculate absolute url by extraction first domain from settings.ALLOWED_HOSTS
7 | :param path: string with path
8 | :return: path concatenated with domain
9 | """
10 | first_host = settings.ALLOWED_HOSTS[0]
11 | return f'{first_host}{path}'
12 |
--------------------------------------------------------------------------------
/pythonpro/celery.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from celery import Celery
4 | from django.conf import settings
5 |
6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pythonpro.settings')
7 | app = Celery('pythonpro.celery')
8 | app.config_from_object(settings, namespace='CELERY')
9 | app.autodiscover_tasks()
10 |
--------------------------------------------------------------------------------
/pythonpro/checkout/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/__init__.py
--------------------------------------------------------------------------------
/pythonpro/checkout/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CheckoutConfig(AppConfig):
5 | name = 'pythonpro.checkout'
6 |
--------------------------------------------------------------------------------
/pythonpro/checkout/facade.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from django.utils import timezone
4 |
5 | launch_datetime_begin = timezone.make_aware(datetime(2021, 1, 5, 0, 0, 0))
6 | discount_50_percent_datetime_limit = timezone.make_aware(datetime(2021, 1, 18, 23, 59, 59))
7 | discount_35_percent_datetime_limit = timezone.make_aware(datetime(2021, 1, 19, 23, 59, 59))
8 | launch_datetime_finish = timezone.make_aware(datetime(2021, 1, 20, 23, 59, 59))
9 |
10 |
11 | def is_launch_open():
12 | return launch_datetime_begin <= timezone.now() <= launch_datetime_finish
13 |
14 |
15 | def has_50_percent_discount():
16 | return is_launch_open() and (timezone.now() <= discount_50_percent_datetime_limit)
17 |
18 |
19 | def has_35_percent_discount():
20 | return is_launch_open() and (
21 | discount_50_percent_datetime_limit < timezone.now() <= discount_35_percent_datetime_limit
22 | )
23 |
--------------------------------------------------------------------------------
/pythonpro/checkout/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 |
4 | class WaitingForm(forms.Form):
5 | first_name = forms.CharField(
6 | label="", widget=forms.TextInput(attrs={'placeholder': 'Digite seu nome'})
7 | )
8 | email = forms.EmailField(
9 | label="", widget=forms.EmailInput(attrs={'placeholder': 'Digite seu MELHOR email'})
10 | )
11 | phone = forms.CharField(
12 | label="", widget=forms.TextInput(attrs={'placeholder': 'Digite seu WhatsApp (não se esqueça do DDD)'})
13 | )
14 |
--------------------------------------------------------------------------------
/pythonpro/checkout/migrations/0003_data_science_setup.py:
--------------------------------------------------------------------------------
1 | from django.db import migrations
2 |
3 |
4 | def setup_payment_configs(apps, schema_editor):
5 | PagarmeFormConfig = apps.get_model('django_pagarme', 'PagarmeFormConfig')
6 | PagarmeItemConfig = apps.get_model('django_pagarme', 'PagarmeItemConfig')
7 | print()
8 | setup_payment_configs_function(PagarmeFormConfig, PagarmeItemConfig)
9 |
10 |
11 | def setup_payment_configs_function(PagarmeFormConfig, PagarmeItemConfig):
12 | """"""
13 | config = PagarmeFormConfig.objects.first()
14 |
15 | PagarmeItemConfig(
16 | name='Ciência de Dados',
17 | slug='data-science',
18 | price=49700,
19 | tangible=False,
20 | default_config=config,
21 | ).save()
22 |
23 |
24 | class Migration(migrations.Migration):
25 | dependencies = [
26 | ('checkout', '0002_webdev_setup'),
27 | ]
28 |
29 | operations = [
30 | migrations.RunPython(setup_payment_configs, migrations.RunPython.noop)
31 | ]
32 |
--------------------------------------------------------------------------------
/pythonpro/checkout/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/migrations/__init__.py
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/62-626208_python-logo-png-transparent-background-python-logo-png.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/62-626208_python-logo-png-transparent-background-python-logo-png.jpg
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/CAPA_PythonDjango-FRENTESite.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/CAPA_PythonDjango-FRENTESite.jpg
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/DSC_7555.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/DSC_7555.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/ana-paula-batalha-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/ana-paula-batalha-4.jpg
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/card-bx.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/charles-tenorio.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/charles-tenorio.jpeg
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/city-bx.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/favicon.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/guido-luz.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/guido-luz.jpeg
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/home-bx.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/mail-bx.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/marcelo-andriolli.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/marcelo-andriolli.jpg
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/maria-elisa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/maria-elisa.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/pablo-gabriel.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/pablo-gabriel.jpeg
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/rafael-ramos.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/rafael-ramos.jpeg
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/regis-santos.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/regis-santos.jpeg
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/site_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/site_preview.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/user-bx.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/checkout/static/checkout/images/webclip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/checkout/images/webclip.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/thanks/images/Camada-8-p-500.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/thanks/images/Camada-8-p-500.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/thanks/images/Camada-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/thanks/images/Camada-8.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/thanks/images/NoPath---Copia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/thanks/images/NoPath---Copia.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/thanks/images/NoPath.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/thanks/images/NoPath.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/thanks/images/down-arrow.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/checkout/static/thanks/images/error.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/checkout/static/thanks/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/thanks/images/favicon.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/thanks/images/webclip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/static/thanks/images/webclip.png
--------------------------------------------------------------------------------
/pythonpro/checkout/static/thanks/images/x.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/checkout/bootcamp_lp_d2.html:
--------------------------------------------------------------------------------
1 | {% extends "checkout/bootcamp_lp_subscription_open.html" %}
2 | {% load static %}
3 | {% load django_pagarme %}
4 | {% load bootstrap4 %}
5 |
6 | {% block vsl %}https://www.youtube.com/embed/41DjlWEbT1M{% endblock vsl %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/contact_form_errors.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/contact_form.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_35_discount.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp.html' %}
2 | {% block sidebar %}
3 |
7 | {{ block.super }}
8 |
9 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_50_discount.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp.html' %}
2 | {% block sidebar %}
3 |
7 | {{ block.super }}
8 |
9 | {% endblock sidebar %}
10 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_d1_boleto.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp.html' %}
2 | {% block sidebar %}
3 |
7 | {{ block.super }}
8 |
9 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lista_de_espera.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp_lote3_pagina_de_vendas.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote0.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp.html' %}
2 | {% block sidebar %}
3 |
7 |
11 | {{ block.super }}
12 |
13 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote1_comercial.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp_lote1_pagina_de_vendas.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote1_pagina_de_vendas.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp.html' %}
2 | {% block sidebar %}
3 |
7 | {{ block.super }}
8 |
9 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote1_whatsapp.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp_lote1_pagina_de_vendas.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote2_comercial.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp_lote2_pagina_de_vendas.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote2_pagina_de_vendas.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp.html' %}
2 | {% block sidebar %}
3 |
7 | {{ block.super }}
8 |
9 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote2_whatsapp.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp_lote2_pagina_de_vendas.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote3_comercial.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp_lote3_pagina_de_vendas.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote3_pagina_de_vendas.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_lote3_whatsapp.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp_lote3_pagina_de_vendas.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_webdev.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp.html' %}
2 | {% block sidebar %}
3 |
7 | {{ block.super }}
8 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_webdev_35_discount.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp_35_discount.html' %}
2 | {% block sidebar %}
3 |
7 | {{ block.super }}
8 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_bootcamp_webdev_50_discount.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_bootcamp_50_discount.html' %}
2 | {% block sidebar %}
3 |
7 | {{ block.super }}
8 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_djangopro.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme.html' %}
2 | {% block sidebar %}
3 |
7 |
10 |
14 |
20 |
23 |
26 |
27 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_djangopro_comercial.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_djangopro.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_djangopro_promocao_especial.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_djangopro.html' %}
2 | {% block sidebar %}
3 |
7 | {{ block.super }}
8 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_djangopro_promocao_especial_comercial.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_djangopro_promocao_especial.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_djangopro_promocao_especial_deschamps.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_djangopro_promocao_especial.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_jrpv_lista_vip.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme.html' %}
2 | {% block sidebar %}
3 |
7 |
11 |
15 |
19 |
20 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_jrpv_lista_vip_promocao.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_jrpv_lista_vip.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_pacote_proximo_nivel.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme.html' %}
2 | {% block sidebar %}
3 |
7 |
11 |
14 |
17 |
20 | {% endblock sidebar %}
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_programa_de_aceleracao_upgrade.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_programa_de_aceleracao.html' %}
2 | {% block bonus_block %}1 ano de acesso à Comunidade DevPro{% endblock bonus_block %}
3 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_renovacao_comunidade_devpro.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_comunidade_devpro.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_webdev_downsell.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_webdev.html' %}
2 |
3 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/pagarme_webdev_downsell_boleto.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/pagarme_webdev.html' %}
2 |
3 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/thanks_aps.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Redirecionando APS
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/thanks_bootcamp.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/thanks.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/thanks_bootcamp_35_discount.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/thanks_bootcamp.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/thanks_bootcamp_50_discount.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/thanks_bootcamp.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/thanks_bootcamp_d1_boleto.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/thanks_bootcamp.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/thanks_bootcamp_webdev_35_discount.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/thanks_bootcamp_50_discount.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/thanks_bootcamp_webdev_50_discount.html:
--------------------------------------------------------------------------------
1 | {% extends 'django_pagarme/thanks_bootcamp_50_discount.html' %}
2 |
--------------------------------------------------------------------------------
/pythonpro/checkout/templates/django_pagarme/thanks_jrpv_lista_vip.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base_without_nav.html' %}
2 | {% load django_pagarme %}
3 | {% load static %}
4 | {% block title %}Obrigado por se matricular no {{ payment_item_config.name }}{% endblock %}
5 | {% block styles %}{% endblock %}
6 | {% block body_class %}clean-body{% endblock %}
7 | {% block scripts %}{% endblock scripts %}
8 | {% block head %}
9 |
11 | {% endblock head %}
12 | {% block body %}
13 | O conteúdo desta página foi movido permanentemente para o link:
14 | https://www.python.pro.br/r/jrpv-acesso-vip-obrigado
15 | {% endblock body %}
16 | {% block footer %}{% endblock footer %}
17 |
--------------------------------------------------------------------------------
/pythonpro/checkout/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/checkout/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/cohorts/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/cohorts/__init__.py
--------------------------------------------------------------------------------
/pythonpro/cohorts/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CohortsConfig(AppConfig):
5 | name = 'pythonpro.cohorts'
6 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/migrations/0002_liveclass.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.6 on 2018-06-04 17:53
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('cohorts', '0001_initial'),
11 | ]
12 |
13 | operations = [
14 | migrations.CreateModel(
15 | name='LiveClass',
16 | fields=[
17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18 | ('start', models.DateTimeField()),
19 | ('vimeo_id', models.CharField(blank=True, max_length=11)),
20 | ('cohort', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cohorts.Cohort')),
21 | ],
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/migrations/0004_cohortstudent_added.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.6 on 2018-06-12 15:05
2 |
3 | import datetime
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('cohorts', '0003_webinar'),
11 | ]
12 |
13 | operations = [
14 | migrations.AddField(
15 | model_name='cohortstudent',
16 | name='added',
17 | field=models.DateTimeField(default=datetime.datetime(2018, 6, 12, 0, 0)),
18 | ),
19 | ]
20 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/migrations/0005_auto_20180612_1206.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.6 on 2018-06-12 15:06
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('cohorts', '0004_cohortstudent_added'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='cohortstudent',
15 | name='added',
16 | field=models.DateTimeField(auto_now_add=True),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/migrations/0006_auto_20190226_1830.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.7 on 2019-02-26 21:30
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('cohorts', '0005_auto_20180612_1206'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='webinar',
15 | name='description',
16 | field=models.TextField(default='Alterar'),
17 | ),
18 | migrations.AddField(
19 | model_name='webinar',
20 | name='discourse_topic_id',
21 | field=models.CharField(default=726, max_length=11),
22 | ),
23 | migrations.AddField(
24 | model_name='webinar',
25 | name='image',
26 | field=models.ImageField(null=True, upload_to='webinars/'),
27 | ),
28 | ]
29 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/migrations/0007_auto_20190226_1843.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.7 on 2019-02-26 21:43
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('cohorts', '0006_auto_20190226_1830'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='webinar',
15 | name='description',
16 | field=models.TextField(),
17 | ),
18 | migrations.AlterField(
19 | model_name='webinar',
20 | name='discourse_topic_id',
21 | field=models.CharField(max_length=11),
22 | ),
23 | migrations.AlterField(
24 | model_name='webinar',
25 | name='image',
26 | field=models.ImageField(blank=True, null=True, upload_to='webinars/'),
27 | ),
28 | ]
29 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/migrations/0008_auto_20190307_1712.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.1.7 on 2019-03-07 20:12
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('cohorts', '0007_auto_20190226_1843'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='liveclass',
15 | name='description',
16 | field=models.TextField(blank=True, default='Aula Pendente'),
17 | ),
18 | migrations.AddField(
19 | model_name='liveclass',
20 | name='discourse_topic_id',
21 | field=models.CharField(default='726', max_length=11, null=True),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/migrations/0009_increase_webinar_title_length.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2 on 2021-05-20 13:57
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('cohorts', '0008_auto_20190307_1712'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='webinar',
15 | name='slug',
16 | field=models.SlugField(max_length=128, unique=True),
17 | ),
18 | migrations.AlterField(
19 | model_name='webinar',
20 | name='title',
21 | field=models.CharField(max_length=128),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/migrations/0010_add_memberkit_url_to_cohort_contents.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.4 on 2021-06-03 18:44
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('cohorts', '0009_increase_webinar_title_length'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='liveclass',
15 | name='memberkit_url',
16 | field=models.URLField(blank=True, default='', max_length=1024),
17 | ),
18 | migrations.AddField(
19 | model_name='webinar',
20 | name='memberkit_url',
21 | field=models.URLField(blank=True, default='', max_length=1024),
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/cohorts/migrations/__init__.py
--------------------------------------------------------------------------------
/pythonpro/cohorts/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/cohorts/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/cohorts/tests/conftest.py:
--------------------------------------------------------------------------------
1 | from os import path
2 |
3 | import pytest
4 | from django.core.files.uploadedfile import SimpleUploadedFile
5 | from model_bakery import baker
6 |
7 | from pythonpro import settings
8 | from pythonpro.cohorts.models import Cohort
9 |
10 | img_path = path.join(settings.BASE_DIR, 'pythonpro', 'core', 'static', 'img', 'instructors', 'renzo-nuccitelli.jpeg')
11 |
12 |
13 | @pytest.fixture
14 | def cohort(client, django_user_model):
15 | user = baker.make(django_user_model)
16 | image = SimpleUploadedFile(name='renzo-nuccitelli.jpeg', content=open(img_path, 'rb').read(),
17 | content_type='image/png')
18 | cohort = baker.make(Cohort, slug='guido-van-rossum', title='Guido van Rossum', students=[user], image=image)
19 | return cohort
20 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from pythonpro.cohorts import views
4 |
5 | app_name = 'cohorts'
6 | urlpatterns = [
7 | path('aulas//', views.live_class, name='live_class'),
8 | ]
9 |
--------------------------------------------------------------------------------
/pythonpro/cohorts/views.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.decorators import login_required
2 | from django.shortcuts import redirect
3 | from django.urls import reverse
4 |
5 | from pythonpro.cohorts import facade
6 | from pythonpro.memberkit import facade as memberkit_facade
7 |
8 |
9 | @login_required
10 | def live_class(request, pk):
11 | user = request.user
12 | if memberkit_facade.has_memberkit_account(user):
13 | live_class = facade.find_live_class(pk=pk)
14 | return redirect(live_class.memberkit_url, permanent=True)
15 | if memberkit_facade.has_any_subscription(user):
16 | return redirect(reverse('migrate_to_memberkit'), permanent=True)
17 | return redirect(reverse('checkout:bootcamp_lp'), permanent=False)
18 |
--------------------------------------------------------------------------------
/pythonpro/core/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/__init__.py
--------------------------------------------------------------------------------
/pythonpro/core/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class CoreConfig(AppConfig):
5 | name = 'pythonpro.core'
6 |
--------------------------------------------------------------------------------
/pythonpro/core/context_processors.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 |
3 |
4 | def global_settings(request):
5 | # return any necessary values
6 | dct = {
7 | 'DEFAULT_FROM_EMAIL': settings.DEFAULT_FROM_EMAIL,
8 | 'DISCOURSE_BASE_URL': settings.DISCOURSE_BASE_URL,
9 | 'GOOGLE_TAG_MANAGER_ID': settings.GOOGLE_TAG_MANAGER_ID,
10 | }
11 | return dct
12 |
--------------------------------------------------------------------------------
/pythonpro/core/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/management/__init__.py
--------------------------------------------------------------------------------
/pythonpro/core/management/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/management/commands/__init__.py
--------------------------------------------------------------------------------
/pythonpro/core/migrations/0002_auto_20180530_1801.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.5 on 2018-05-30 21:01
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('core', '0001_initial'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterModelTable(
14 | name='user',
15 | table=None,
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/pythonpro/core/migrations/0004_auto_20180601_1108.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.5 on 2018-06-01 14:08
2 |
3 | from django.db import migrations
4 | import pythonpro.core.managers
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('core', '0003_auto_20180530_1826'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterModelManagers(
15 | name='user',
16 | managers=[
17 | ('objects', pythonpro.core.managers.UserManager()),
18 | ],
19 | ),
20 | migrations.RemoveField(
21 | model_name='user',
22 | name='last_name',
23 | ),
24 | migrations.RemoveField(
25 | model_name='user',
26 | name='username',
27 | ),
28 | ]
29 |
--------------------------------------------------------------------------------
/pythonpro/core/migrations/0005_auto_20180603_2026.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.6 on 2018-06-03 23:26
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('core', '0004_auto_20180601_1108'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='user',
15 | name='first_name',
16 | field=models.CharField(max_length=30, verbose_name='first name'),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/pythonpro/core/migrations/0006_user_source.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.2 on 2019-06-24 19:12
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('core', '0005_auto_20180603_2026'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='user',
15 | name='source',
16 | field=models.CharField(blank=True, max_length=255, null=True, verbose_name='source'),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/pythonpro/core/migrations/0007_auto_20190705_0829.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.2 on 2019-07-05 11:29
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('core', '0006_user_source'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='user',
15 | name='source',
16 | field=models.CharField(default='unknown', max_length=255, verbose_name='source'),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/pythonpro/core/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/migrations/__init__.py
--------------------------------------------------------------------------------
/pythonpro/core/static/css/python-birds/owl.theme.default.min.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Owl Carousel v2.3.4
3 | * Copyright 2013-2018 David Deutsch
4 | * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
5 | */
6 | .owl-theme .owl-dots,.owl-theme .owl-nav{text-align:center;-webkit-tap-highlight-color:transparent}.owl-theme .owl-nav{margin-top:10px}.owl-theme .owl-nav [class*=owl-]{color:#FFF;font-size:14px;margin:5px;padding:4px 7px;background:#D6D6D6;display:inline-block;cursor:pointer;border-radius:3px}.owl-theme .owl-nav [class*=owl-]:hover{background:#869791;color:#FFF;text-decoration:none}.owl-theme .owl-nav .disabled{opacity:.5;cursor:default}.owl-theme .owl-nav.disabled+.owl-dots{margin-top:10px}.owl-theme .owl-dots .owl-dot{display:inline-block;zoom:1}.owl-theme .owl-dots .owl-dot span{width:10px;height:10px;margin:5px 7px;background:#D6D6D6;display:block;-webkit-backface-visibility:visible;transition:opacity .2s ease;border-radius:30px}.owl-theme .owl-dots .owl-dot.active span,.owl-theme .owl-dots .owl-dot:hover span{background:#869791}
--------------------------------------------------------------------------------
/pythonpro/core/static/css/spp/owl.theme.default.min.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Owl Carousel v2.3.4
3 | * Copyright 2013-2018 David Deutsch
4 | * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
5 | */
6 | .owl-theme .owl-dots,.owl-theme .owl-nav{text-align:center;-webkit-tap-highlight-color:transparent}.owl-theme .owl-nav{margin-top:10px}.owl-theme .owl-nav [class*=owl-]{color:#FFF;font-size:14px;margin:5px;padding:4px 7px;background:#D6D6D6;display:inline-block;cursor:pointer;border-radius:3px}.owl-theme .owl-nav [class*=owl-]:hover{background:#869791;color:#FFF;text-decoration:none}.owl-theme .owl-nav .disabled{opacity:.5;cursor:default}.owl-theme .owl-nav.disabled+.owl-dots{margin-top:10px}.owl-theme .owl-dots .owl-dot{display:inline-block;zoom:1}.owl-theme .owl-dots .owl-dot span{width:10px;height:10px;margin:5px 7px;background:#D6D6D6;display:block;-webkit-backface-visibility:visible;transition:opacity .2s ease;border-radius:30px}.owl-theme .owl-dots .owl-dot.active span,.owl-theme .owl-dots .owl-dot:hover span{background:#869791}
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/android-chrome-192x192.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/android-chrome-512x512.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/apple-touch-icon.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #ffffff
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/favicon-16x16.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/favicon-32x32.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/favicon.ico
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/mstile-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/mstile-144x144.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/mstile-150x150.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/mstile-310x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/mstile-310x150.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/mstile-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/mstile-310x310.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/mstile-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/python-birds/mstile-70x70.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/python-birds/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Dev Pro",
3 | "short_name": "Dev Pro",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/android-chrome-192x192.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/android-chrome-512x512.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/apple-touch-icon.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #ffffff
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/favicon-16x16.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/favicon-32x32.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/favicon.ico
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/mstile-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/mstile-144x144.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/mstile-150x150.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/mstile-310x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/mstile-310x150.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/mstile-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/mstile-310x310.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/mstile-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/favicon/spp/mstile-70x70.png
--------------------------------------------------------------------------------
/pythonpro/core/static/favicon/spp/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Dev Pro",
3 | "short_name": "Dev Pro",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/Gilroy-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/Gilroy-Bold.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/Gilroy-Heavy.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/Gilroy-Heavy.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/Gilroy-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/Gilroy-Light.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/Gilroy-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/Gilroy-Medium.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/Gilroy-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/Gilroy-Regular.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/eot/Intelo-900.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/eot/Intelo-900.eot
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/eot/Titillium-300.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/eot/Titillium-300.eot
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/eot/Titillium-500.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/eot/Titillium-500.eot
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/eot/Titillium-700.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/eot/Titillium-700.eot
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/eot/Titillium-900.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/eot/Titillium-900.eot
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/otf/Intelo-900.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/otf/Intelo-900.otf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/otf/Titillium-300.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/otf/Titillium-300.otf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/otf/Titillium-500.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/otf/Titillium-500.otf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/otf/Titillium-700.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/otf/Titillium-700.otf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/otf/Titillium-900.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/otf/Titillium-900.otf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/ttf/Intelo-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/ttf/Intelo-900.ttf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/ttf/Titillium-300.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/ttf/Titillium-300.ttf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/ttf/Titillium-500.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/ttf/Titillium-500.ttf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/ttf/Titillium-700.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/ttf/Titillium-700.ttf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/ttf/Titillium-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/ttf/Titillium-900.ttf
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff/Intelo-900.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff/Intelo-900.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff/Titillium-300.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff/Titillium-300.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff/Titillium-500.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff/Titillium-500.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff/Titillium-700.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff/Titillium-700.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff/Titillium-900.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff/Titillium-900.woff
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff2/Intelo-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff2/Intelo-900.woff2
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff2/Titillium-300.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff2/Titillium-300.woff2
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff2/Titillium-500.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff2/Titillium-500.woff2
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff2/Titillium-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff2/Titillium-700.woff2
--------------------------------------------------------------------------------
/pythonpro/core/static/fonts/woff2/Titillium-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/fonts/woff2/Titillium-900.woff2
--------------------------------------------------------------------------------
/pythonpro/core/static/img/3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/3.gif
--------------------------------------------------------------------------------
/pythonpro/core/static/img/ajax-loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/ajax-loader.gif
--------------------------------------------------------------------------------
/pythonpro/core/static/img/banner-pagarme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/banner-pagarme.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/compra-segura-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/compra-segura-1.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/favicon.ico
--------------------------------------------------------------------------------
/pythonpro/core/static/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/favicon.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/garantia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/garantia.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/instructors/renzo-nuccitelli-300.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/instructors/renzo-nuccitelli-300.jpeg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/instructors/renzo-nuccitelli-300.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/instructors/renzo-nuccitelli-300.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/instructors/renzo-nuccitelli.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/instructors/renzo-nuccitelli.jpeg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/instructors/renzo-nuccitelli.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/instructors/renzo-nuccitelli.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/launch/video1-available.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/launch/video1-available.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/launch/video1-unavailable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/launch/video1-unavailable.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/launch/video2-available.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/launch/video2-available.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/launch/video2-unavailable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/launch/video2-unavailable.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/launch/video3-available.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/launch/video3-available.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/launch/video3-unavailable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/launch/video3-unavailable.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/backgrounds/bg-header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/backgrounds/bg-header.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/card-python-de-graca.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/card-python-de-graca.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/companies/companies-detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/companies/companies-detail.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/companies/logo-google.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/companies/logo-google.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/companies/logo-nasa.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/companies/logo-nasa.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/companies/logo-netflix.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/companies/logo-netflix.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/companies/logo-spotify.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/companies/logo-spotify.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/companies/logo-uber.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/companies/logo-uber.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/companies/logo-yahoo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/companies/logo-yahoo.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/header/header-detail-middle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/header/header-detail-middle.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/header/header-detail-top-left.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/header/header-detail-top-left.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/header/header-detail-top-right.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/header/header-detail-top-right.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/header/header-renzo-bottom-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/header/header-renzo-bottom-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/header/logo-python.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/header/logo-python.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/learning/learning-1_vgsvdd_c_scale,w_200.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/learning/learning-1_vgsvdd_c_scale,w_200.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/learning/learning-1_vgsvdd_c_scale,w_450.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/learning/learning-1_vgsvdd_c_scale,w_450.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/learning/learning-1_vgsvdd_c_scale,w_603.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/learning/learning-1_vgsvdd_c_scale,w_603.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/learning/learning-2_ihqj3j_c_scale,w_200.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/learning/learning-2_ihqj3j_c_scale,w_200.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/learning/learning-2_ihqj3j_c_scale,w_349.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/learning/learning-2_ihqj3j_c_scale,w_349.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/learning/learning-2_ihqj3j_c_scale,w_659.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/learning/learning-2_ihqj3j_c_scale,w_659.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/learning/learning-detail-bottom.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/learning/learning-detail-bottom.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/learning/learning-detail-right.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/learning/learning-detail-right.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/learning/learning-detail-top.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/learning/learning-detail-top.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/noticia-15-profissoes.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/noticia-15-profissoes.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/noticia-9-motivos-conteudo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/noticia-9-motivos-conteudo.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/noticia-9-motivos.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/noticia-9-motivos.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/noticia-sobram-vagas.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/noticia-sobram-vagas.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/noticia-stack-1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/noticia-stack-1.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/noticia-stack-2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/noticia-stack-2.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/noticia-stack-3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/noticia-stack-3.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/testimonials/testimonials-detail-top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/testimonials/testimonials-detail-top.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/testimonials/thumb-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/testimonials/thumb-1.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/testimonials/thumb-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/testimonials/thumb-2.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/testimonials/thumb-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/testimonials/thumb-3.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/testimonials/thumb-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/testimonials/thumb-4.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/testimonials/thumb-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/testimonials/thumb-5.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/testimonials/thumb-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/testimonials/thumb-6.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/testimonials/thumb-7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/testimonials/thumb-7.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/testimonials/thumb-8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/testimonials/thumb-8.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/why/logo-computerworld.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/why/logo-computerworld.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/why/logo-valor-economico.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/why/logo-valor-economico.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/why/python-detail-bottom-left.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/why/python-detail-bottom-left.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/why/python-detail-bottom-right.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/why/python-detail-bottom-right.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/why/python-detail-middle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/why/python-detail-middle.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/why/python-detail-top-left.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/why/python-detail-top-left.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/why/python-detail-top-right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/why/python-detail-top-right.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/why/why-detail.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/why/why-detail.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/python-birds/why/why-paper.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/python-birds/why/why-paper.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/renzo-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/renzo-thumb.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/renzo-thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/renzo-thumb.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/alisson-americo-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/alisson-americo-1.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/alysson.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/alysson.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/carlos-augusto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/carlos-augusto.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/charles-tenorio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/charles-tenorio.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/diego.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/diego.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/fabricio.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/fabricio.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/ferrabras.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/ferrabras.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/guido-percu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/guido-percu.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/isaac.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/isaac.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/jasiel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/jasiel.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/jorge-plautz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/jorge-plautz.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/marcelo-andreoli.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/marcelo-andreoli.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/marcelo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/marcelo.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/marcus-vinicius.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/marcus-vinicius.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/maria-elisa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/maria-elisa.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/pablo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/pablo.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/paulo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/paulo.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/rafael-ramos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/rafael-ramos.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/regis-silva.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/regis-silva.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/ricardo-portela.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/ricardo-portela.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/ronaldo-oliveira.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/ronaldo-oliveira.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/tanio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/tanio.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/testando-o-mercado.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/testando-o-mercado.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/vicente.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/vicente.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/vinicius-assef.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/vinicius-assef.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/social-proof/vinicius.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/social-proof/vinicius.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/card-python-pro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/card-python-pro.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/cards-classes/card-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/cards-classes/card-1.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/cards-classes/card-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/cards-classes/card-2.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/cards-classes/image-material.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/cards-classes/image-material.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/cards-classes/image-telegram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/cards-classes/image-telegram.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/countdown/countdown-detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/countdown/countdown-detail.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer-classes/renzo-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer-classes/renzo-desktop.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer-classes/renzo-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer-classes/renzo-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/cpnj.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/cpnj.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/detail-top-footer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/detail-top-footer.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/email.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/email.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/footer-group-detail.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/footer-group-detail.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/phone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/phone.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-footer-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-footer-desktop.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-footer-desktop.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-footer-desktop.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-footer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-footer.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-footer.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-footer.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-v2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-v2.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-v2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/footer/renzo-nuccitelli-v2.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/garantee-main/garantee-badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/garantee-main/garantee-badge.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/header/detail-video-header-main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/header/detail-video-header-main.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/header/detail-video-header-main.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/header/detail-video-header-main.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/header/renzo-nuccitelli-desktop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/header/renzo-nuccitelli-desktop.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/header/renzo-nuccitelli-desktop.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/header/renzo-nuccitelli-desktop.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/header/renzo-nuccitelli-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/header/renzo-nuccitelli-mobile.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/header/renzo-nuccitelli-mobile.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/header/renzo-nuccitelli-mobile.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/interview-main/interview-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/interview-main/interview-icon.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/pacote-proximo-nivel-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/pacote-proximo-nivel-mobile.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/pacote-proximo-nivel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/pacote-proximo-nivel.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/access-icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/access-icon.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/adriano-brasileiro.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/adriano-brasileiro.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/certificate-icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/certificate-icon.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/eric-gomes.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/eric-gomes.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/isaac-ferreira.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/isaac-ferreira.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/jessica-ferrari1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/jessica-ferrari1.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/luiz-vital.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/luiz-vital.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/people-image-detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/people-image-detail.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/rodrigo-vaccari.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/rodrigo-vaccari.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/vicente-marcal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/vicente-marcal.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/people-main/vinicius-assef.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/people-main/vinicius-assef.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/renzo-main/renzo-nuccitelli-mobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/renzo-main/renzo-nuccitelli-mobile.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/renzo/about-renzo-nuccitelli-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/renzo/about-renzo-nuccitelli-desktop.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/renzo/about-renzo-nuccitelli-desktop.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/renzo/about-renzo-nuccitelli-desktop.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/renzo/about-renzo-nuccitelli-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/renzo/about-renzo-nuccitelli-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/renzo/about-renzo-nuccitelli-mobile.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/renzo/about-renzo-nuccitelli-mobile.webp
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/bonus-1-desktop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/bonus-1-desktop.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/bonus-1-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/bonus-1-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/bonus-2-desktop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/bonus-2-desktop.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/bonus-2-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/bonus-2-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/bonus-3-desktop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/bonus-3-desktop.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/bonus-3-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/bonus-3-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/summary-card-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/summary-card-1.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/summary-card-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/summary-card-2.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/summary-card-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/summary-card-3.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/summary-card-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/summary-card-4.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/summary-main/summary-price-icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/summary-main/summary-price-icon.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/backgrounds/bg-header-desktop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/backgrounds/bg-header-desktop.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/backgrounds/bg-header-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/backgrounds/bg-header-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/steps/step-1-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/steps/step-1-desktop.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/steps/step-1-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/steps/step-1-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/steps/step-2-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/steps/step-2-desktop.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/steps/step-2-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/steps/step-2-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/steps/step-3-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/steps/step-3-desktop.png
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/steps/step-3-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/steps/step-3-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/steps/step-4-desktop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/steps/step-4-desktop.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thank-you/steps/step-4-mobile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thank-you/steps/step-4-mobile.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-1.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-2.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-3.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-4.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-5.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-6.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-7.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/spp/thumbs-testimonials/thumb-8.jpg
--------------------------------------------------------------------------------
/pythonpro/core/static/img/whatsapp-loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/static/img/whatsapp-loader.gif
--------------------------------------------------------------------------------
/pythonpro/core/static/js/python-birds/main.js:
--------------------------------------------------------------------------------
1 | // SMOOTH SCROLL
2 | $('a[href^="#"]').on('click', function (event) {
3 | var target = $(this.getAttribute('href'));
4 | if (target.length) {
5 | event.preventDefault();
6 | $('html, body').stop().animate({
7 | scrollTop: target.offset().top - 100
8 | }, 900);
9 | }
10 | });
11 |
12 | $(document).ready(function () {
13 | $('.owl-carousel').owlCarousel({
14 | autoPlay: 3000,
15 | loop: true,
16 | margin: 10,
17 | responsiveClass: true,
18 | dots: true,
19 | responsive: {
20 | 0: {
21 | items: 1,
22 | nav: true
23 | },
24 | 600: {
25 | items: 3,
26 | nav: false
27 | },
28 | 1000: {
29 | items: 3,
30 | nav: true,
31 | }
32 | }
33 | })
34 | });
35 |
36 | $('.popup-vimeo').magnificPopup({
37 | src: 'https://vimeo.com/398972182',
38 | type: 'iframe'
39 | });
--------------------------------------------------------------------------------
/pythonpro/core/static/js/spp/OneSignalSDKUpdaterWorker.js:
--------------------------------------------------------------------------------
1 | importScripts('https://cdn.onesignal.com/sdks/OneSignalSDKWorker.js');
2 |
--------------------------------------------------------------------------------
/pythonpro/core/static/js/spp/OneSignalSDKWorker.js:
--------------------------------------------------------------------------------
1 | importScripts('https://cdn.onesignal.com/sdks/OneSignalSDKWorker.js');
2 |
--------------------------------------------------------------------------------
/pythonpro/core/static/js/spp/countdown.js:
--------------------------------------------------------------------------------
1 | function initCountDown(countDown) {
2 | const second = 1000,
3 | minute = second * 60,
4 | hour = minute * 60,
5 | day = hour * 24;
6 | x = setInterval(function () {
7 | let now = new Date().getTime(),
8 | distance = countDown - now;
9 |
10 | let data = {
11 | 'days': distance / (day),
12 | 'hours': (distance % (day)) / (hour),
13 | 'minutes': (distance % (hour)) / (minute),
14 | 'seconds': (distance % (minute)) / second
15 | };
16 | for (let prop in data) {
17 | for (let element of document.getElementsByClassName(prop)) {
18 | element.innerText = Math.floor(data[prop]);
19 | }
20 | }
21 |
22 | if (distance < 0) {
23 | clearInterval(x);
24 | 'Tempo esgotado!';
25 | }
26 | }, second)
27 | }
--------------------------------------------------------------------------------
/pythonpro/core/static/js/spp/countdown.min.js:
--------------------------------------------------------------------------------
1 | function initCountDown(e) { x = setInterval(function () { let t = (new Date).getTime(), n = e - t, o = { days: n / 864e5, hours: n % 864e5 / 36e5, minutes: n % 36e5 / 6e4, seconds: n % 6e4 / 1e3 }; for (let e in o) for (let t of document.getElementsByClassName(e)) t.innerText = Math.floor(o[e]); n < 0 && clearInterval(x) }, 1e3) } initCountDown(new Date("Aug 10, 2020 23:59:59").getTime());
--------------------------------------------------------------------------------
/pythonpro/core/static/svg/spp/blue-arrow-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/core/static/svg/spp/green-arrow-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/core/static/svg/spp/green-camera-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/core/static/svg/spp/twitter-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/core/static/svg/spp/white-camera-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/core/static/svg/spp/x-price-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/core/static/svg/spp/youtube-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/400.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}400. Requisição imprópria{% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
10 |
400
11 |
Requisição imprópria
12 |
A requisição enviada não pode ser atendida.
13 |
14 |
15 |
16 | {% endblock body %}
17 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/403.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}403. Proibido{% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
10 |
403
11 |
Proibido
12 |
Você não tem permissão para acessar este endereço.
13 |
14 |
15 |
16 |
17 | {% endblock body %}
18 |
19 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/404.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}404. Página não encontrada{% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
10 |
404
11 |
Página não encontrada
12 |
O endereço que você solicitou não existe.
13 |
14 |
15 |
16 |
17 | {% endblock body %}
18 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/500.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}500. Erro interno inesperado{% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
10 |
500
11 |
Erro interno inesperado
12 |
Desculpe. Ocorreu um erro inesperado.
13 |
Nossa equipe já foi notificada do problema.
14 | Caso necessário entre em contato com suporte@dev.pro.br
16 |
17 |
18 |
19 |
20 | {% endblock body %}
21 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/core/base_without_nav.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% block navbar %}{% endblock %}
3 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/core/lead_landing_lite_page.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/lead_landing_page.html' %}
2 |
3 | {% block extracontent %}{% endblock %}
--------------------------------------------------------------------------------
/pythonpro/core/templates/core/password_email.txt:
--------------------------------------------------------------------------------
1 | Olá {{first_name}},
2 |
3 | A sua senha para acessar o sistema Dev Pro é:
4 |
5 | {{password}}
6 |
7 | Se quiser alterar sua senha, acesse:
8 |
9 | {{change_password_uri}}
10 |
11 | Grande abraço,
12 | Renzo
--------------------------------------------------------------------------------
/pythonpro/core/templates/core/profile_detail.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}Perfil{% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
10 |
Perfil de {{ user.first_name }}
11 |
17 |
Nome
18 |
19 | {{ user.first_name }}
20 |
21 |
Email
22 |
23 | {{ user.email }}
24 |
25 |
26 |
27 |
28 | {% endblock body %}
29 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/core/unsubscribe.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}Descastratamento{% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
10 |
Descadastramento feito com sucesso!
11 |
É uma pena ver você deixar de acompanhar meu conteúdo.
12 |
Mas integridade é o principal valor aqui dentro do Dev Pro. Então respeito completamente sua
13 | decisão.
14 |
E se precisar, você já sabe onde encontrar conteúdo de técnico de qualidade.
15 |
Desejo sucesso em sua jornada.
16 |
Grande Abraço,
17 | Renzo
18 |
19 |
20 |
21 |
22 | {% endblock body %}
23 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/registration/password_reset_complete.html:
--------------------------------------------------------------------------------
1 | {% extends "core/base.html" %}
2 | {% block body %}
3 |
4 |
5 |
6 |
Redefinição de senha completa
7 |
Agora você pode usar sua nova senha para acessar o site
8 |
Entrar
9 |
10 |
11 |
12 | {% endblock body %}
--------------------------------------------------------------------------------
/pythonpro/core/templates/registration/password_reset_done.html:
--------------------------------------------------------------------------------
1 | {% extends "core/base.html" %}
2 |
3 | {% block body %}
4 |
5 |
6 |
7 |
Redefinição de senha enviada
8 |
9 |
Nós te enviamos por e-mail as instruções para redefinição de sua senha, se existir uma conta com o e-mail que
10 | você forneceu. Você receberá a mensagem em breve.
11 |
12 |
Se você não receber um e-mail, por favor verifique se você digitou o endereço que você usou para se
13 | registrar,
14 | e verificar a sua pasta de spam.
15 |
16 |
17 |
18 |
19 |
20 | {% endblock body %}
--------------------------------------------------------------------------------
/pythonpro/core/templates/two_factor/_base.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% block body %}
3 |
4 |
5 |
6 | {% block content %}{% endblock %}
7 |
8 |
9 |
10 |
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/two_factor/core/otp_required.html:
--------------------------------------------------------------------------------
1 | {% extends "two_factor/_base_focus.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 | {% block title %}{% trans "Permission Denied" %}{% endblock %}
6 |
7 | {% blocktrans trimmed %}The page you requested, enforces users to verify using
8 | two-factor authentication for security reasons. You need to enable these
9 | security features in order to access this page.{% endblocktrans %}
10 |
11 | Autenticação em 2 passos não está ativa em sua conta.
12 | Habilite para melhorar a segurança de dua conta.
13 |
14 | {% trans "Go back" %}
16 |
17 | {% trans "Enable Two-Factor Authentication" %}
18 |
19 | {% endblock %}
20 |
--------------------------------------------------------------------------------
/pythonpro/core/templates/two_factor/core/setup_complete.html:
--------------------------------------------------------------------------------
1 | {% extends "two_factor/_base_focus.html" %}
2 | {% load i18n %}
3 |
4 | {% block content %}
5 | {% block title %}{% trans "Enable Two-Factor Authentication" %}{% endblock %}
6 |
7 | Parabéns, você habilitou a autenticação em 2 passos!
8 |
9 | {% if not phone_methods %}
10 | Acessar Dashboard
12 | {% else %}
13 | {% blocktrans trimmed %}However, it might happen that you don't have access to
14 | your primary token device. To enable account recovery, add a phone
15 | number.{% endblocktrans %}
16 |
17 | {% trans "Back to Profile" %}
19 | {% trans "Add Phone Number" %}
21 | {% endif %}
22 |
23 | {% endblock %}
24 |
--------------------------------------------------------------------------------
/pythonpro/core/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/core/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/core/tests/test_linktree.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from django.urls import reverse
3 |
4 |
5 | @pytest.fixture
6 | def resp(client):
7 | return client.get(reverse('core:linktree'))
8 |
9 |
10 | def test_status_code(resp):
11 | assert 200 == resp.status_code
12 |
--------------------------------------------------------------------------------
/pythonpro/core/tests/test_login.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from django.urls import reverse
3 |
4 |
5 | @pytest.fixture
6 | def login_get_resp(client, db):
7 | return client.get(reverse('two_factor:login'))
8 |
9 |
10 | def test_page_status(login_get_resp):
11 | login_get_resp.status = 200
12 |
--------------------------------------------------------------------------------
/pythonpro/core/tests/test_password_reset.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from django.urls import reverse
3 |
4 | from pythonpro.django_assertions import dj_assert_contains
5 |
6 |
7 | @pytest.fixture
8 | def reset_password_resp(client):
9 | return client.get(reverse('password_reset'))
10 |
11 |
12 | def test_email_form_status(reset_password_resp):
13 | reset_password_resp.status = 200
14 |
15 |
16 | @pytest.mark.parametrize(
17 | 'content',
18 | [
19 | ' bool:
7 | """
8 | Indicates if a user has watched any topic
9 | :param: user
10 | :return: boolean
11 | """
12 | return TopicInteraction.objects.filter(user=user).exists()
13 |
--------------------------------------------------------------------------------
/pythonpro/dashboard/forms.py:
--------------------------------------------------------------------------------
1 | from django.forms import ModelForm
2 |
3 | from pythonpro.dashboard.models import TopicInteraction
4 |
5 |
6 | class TopicInteractionForm(ModelForm):
7 | class Meta:
8 | model = TopicInteraction
9 | fields = ('topic', 'user', 'topic_duration', 'total_watched_time', 'max_watched_time')
10 |
--------------------------------------------------------------------------------
/pythonpro/dashboard/migrations/0002_auto_20190812_1627.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.4 on 2019-08-12 19:27
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('dashboard', '0001_initial'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterModelOptions(
14 | name='topicinteraction',
15 | options={'verbose_name': 'Interação', 'verbose_name_plural': 'Interações'},
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/pythonpro/dashboard/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/dashboard/migrations/__init__.py
--------------------------------------------------------------------------------
/pythonpro/dashboard/static/dashboard/img/assinatura-renzo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/dashboard/static/dashboard/img/assinatura-renzo.jpg
--------------------------------------------------------------------------------
/pythonpro/dashboard/templatetags/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/dashboard/templatetags/__init__.py
--------------------------------------------------------------------------------
/pythonpro/dashboard/templatetags/dashboard_tags.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 |
4 | def duration(value):
5 | try:
6 | duration = int(value)
7 | except ValueError:
8 | return ''
9 | else:
10 | minutes, seconds = divmod(duration, 60)
11 | hours, minutes = divmod(minutes, 60)
12 | if hours > 0:
13 | output = f'{hours:02d} hora(s) {minutes:02d} minuto(s)s {seconds:02d} segundo(s)'
14 | else:
15 | output = f'{minutes:02d} minuto(s)s {seconds:02d} segundo(s)'
16 | return output
17 |
18 |
19 | register = template.Library()
20 | register.filter('duration', duration)
21 |
--------------------------------------------------------------------------------
/pythonpro/dashboard/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/dashboard/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/dashboard/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import views
4 |
5 | app_name = 'dashboard'
6 | urlpatterns = [
7 | path('topic_interaction', views.topic_interaction, name='topic_interaction'),
8 | path('', views.home, name='home'),
9 | path('certificados/', views.certificate, name='certificate'),
10 | ]
11 |
--------------------------------------------------------------------------------
/pythonpro/discord/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/discord/__init__.py
--------------------------------------------------------------------------------
/pythonpro/discord/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class DiscordConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'pythonpro.discord'
7 |
--------------------------------------------------------------------------------
/pythonpro/discord/bot.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 |
3 | from pythonpro.discord.api_client import DiscordBotClient
4 |
5 |
6 | class _DevProDiscordBotClient(DiscordBotClient):
7 | """
8 | This class provides data respective to specific seetings for DevPro Discord Guild
9 | """
10 |
11 | def send_to_sales_channel(self, msg: str) -> dict:
12 | return self.create_message(settings.DISCORD_GUILD_SALES_CHANNEL_ID, msg)
13 |
14 | def send_to_checkout_channel(self, msg: str) -> dict:
15 | return self.create_message(settings.DISCORD_GUILD_SALES_CHANNEL_ID, msg)
16 |
17 |
18 | devpro_discord_bot_client = _DevProDiscordBotClient(settings.DISCORD_APP_BOT_TOKEN)
19 |
--------------------------------------------------------------------------------
/pythonpro/discord/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/discord/management/__init__.py
--------------------------------------------------------------------------------
/pythonpro/discord/management/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/discord/management/commands/__init__.py
--------------------------------------------------------------------------------
/pythonpro/discord/management/commands/clean_discord_users.py:
--------------------------------------------------------------------------------
1 | from django.core.management import BaseCommand
2 |
3 | from pythonpro.discord import facade
4 |
5 |
6 | class Command(BaseCommand):
7 | help = 'Sincronizar usuários do Discord com Painel da DevPro'
8 |
9 | def add_arguments(self, parser):
10 | pass
11 |
12 | def handle(self, *args, **options):
13 | facade.clean_discord_users()
14 |
--------------------------------------------------------------------------------
/pythonpro/discord/management/commands/warn_users_about_subscription_expiration.py:
--------------------------------------------------------------------------------
1 | from django.core.management import BaseCommand
2 |
3 | from pythonpro.discord import facade
4 |
5 |
6 | class Command(BaseCommand):
7 | help = 'Sincronizar usuários do Discord com Painel da DevPro'
8 |
9 | def add_arguments(self, parser):
10 | pass
11 |
12 | def handle(self, *args, **options):
13 | facade.warn_users_about_subscription_expiration()
14 |
--------------------------------------------------------------------------------
/pythonpro/discord/migrations/0002_discord_user_created_at_desc_index.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.1.1 on 2022-09-14 10:48
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('discord', '0001_initial'),
9 | ]
10 |
11 | operations = [
12 | migrations.AddIndex(
13 | model_name='discorduser',
14 | index=models.Index(fields=['-created_at'], name='discord_created_at_desc_index'),
15 | ),
16 | ]
17 |
--------------------------------------------------------------------------------
/pythonpro/discord/migrations/0003_create_discord_lead.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.2.10 on 2024-02-28 18:04
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('discord', '0002_discord_user_created_at_desc_index'),
10 | ]
11 |
12 | operations = [
13 | migrations.CreateModel(
14 | name='DiscordLead',
15 | fields=[
16 | ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
17 | ('discord_id', models.CharField(max_length=64, unique=True)),
18 | ('created_at', models.DateTimeField(auto_now_add=True)),
19 | ('updated_at', models.DateTimeField(auto_now=True)),
20 | ('status', models.CharField(choices=[('A', 'Ativa'), ('I', 'Inativa')], default='I', max_length=32)),
21 | ],
22 | ),
23 | ]
24 |
--------------------------------------------------------------------------------
/pythonpro/discord/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/discord/migrations/__init__.py
--------------------------------------------------------------------------------
/pythonpro/discord/templates/discord/access_denied.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}Acesso negado{% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
10 |
Acesso Negado
11 |
Veja como proceder
12 |
Nosso sistema não encontrou acesso válido para sua conta. Entre em contato com o suporte pelo
13 | email {{ DEFAULT_FROM_EMAIL }}.
14 |
15 |
16 |
17 |
18 | {% endblock body %}
--------------------------------------------------------------------------------
/pythonpro/discord/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/discord/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/discord/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from pythonpro.discord import views
4 |
5 | app_name = 'discord'
6 | urlpatterns = [
7 | path('autorize', views.autorize, name='autorize'),
8 | ]
9 |
--------------------------------------------------------------------------------
/pythonpro/discourse/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/discourse/__init__.py
--------------------------------------------------------------------------------
/pythonpro/discourse/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class PromosConfig(AppConfig):
5 | name = 'pythonpro.discourse'
6 | verbose_name = 'Discourse Forum Integration'
7 |
--------------------------------------------------------------------------------
/pythonpro/discourse/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/discourse/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/discourse/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from pythonpro.discourse import views
4 |
5 | app_name = 'discourse'
6 | urlpatterns = [
7 | path('login/', views.sso, name='sso'),
8 | ]
9 |
--------------------------------------------------------------------------------
/pythonpro/discourse/views.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.decorators import login_required
2 | from django.http import HttpResponseRedirect
3 | from django.views.defaults import bad_request
4 |
5 | from pythonpro.discourse.facade import InvalidSOOPayload, generate_discourse_login_url
6 |
7 |
8 | @login_required
9 | def sso(request):
10 | """
11 | Proceed login into discourse
12 |
13 | Code based on https://meta.discourse.org/t/sso-example-for-django/14258
14 | """
15 | payload = request.GET.get('sso')
16 | signature = request.GET.get('sig')
17 | try:
18 | url = generate_discourse_login_url(request.user, payload, signature)
19 | except InvalidSOOPayload as e:
20 | return bad_request(request, e)
21 | else:
22 | return HttpResponseRedirect(url)
23 |
--------------------------------------------------------------------------------
/pythonpro/django_assertions.py:
--------------------------------------------------------------------------------
1 | '''
2 | Module to expose Django's TestCase assertions as functions
3 | '''
4 | from django.test import TestCase
5 |
6 | _dj_testcase = TestCase()
7 |
8 | dj_assert_contains = _dj_testcase.assertContains
9 | dj_assert_not_contains = _dj_testcase.assertNotContains
10 | dj_assert_template_used = _dj_testcase.assertTemplateUsed
11 | dj_assert_redirects = _dj_testcase.assertRedirects
12 |
--------------------------------------------------------------------------------
/pythonpro/domain/README.md:
--------------------------------------------------------------------------------
1 | This package contains all facades containing entire application business rules (domain)
--------------------------------------------------------------------------------
/pythonpro/domain/__init__.py:
--------------------------------------------------------------------------------
1 | from pythonpro.domain import (checkout_domain, content_statistics_domain, user_domain)
2 |
3 | __all__ = [
4 | 'content_statistics_domain',
5 | 'user_domain',
6 | 'checkout_domain'
7 | ]
8 |
--------------------------------------------------------------------------------
/pythonpro/domain/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/domain/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/domain/tests/test_checkout/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/domain/tests/test_checkout/__init__.py
--------------------------------------------------------------------------------
/pythonpro/domain/tests/test_checkout/test_payment_page.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from django.urls import reverse
3 |
4 | from pythonpro.domain.tests.test_checkout.conftest import ALL_PRODUCTS
5 |
6 |
7 | @pytest.mark.parametrize('slug', ALL_PRODUCTS)
8 | def test_all_slugs_available(client, slug):
9 | if not slug.startswith('bootcamp-webdev'):
10 | resp = client.get(reverse('django_pagarme:pagarme', kwargs={'slug': slug}))
11 | assert resp.status_code == 200
12 |
--------------------------------------------------------------------------------
/pythonpro/domain/tests/test_checkout/test_thanks.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from django.urls import reverse
3 |
4 | from pythonpro.domain.tests.test_checkout.conftest import ALL_ACTIVE_PRODUCTS
5 |
6 |
7 | @pytest.mark.parametrize('slug', ALL_ACTIVE_PRODUCTS)
8 | def test_all_slugs_available(client, slug):
9 | resp = client.get(reverse('django_pagarme:thanks', kwargs={'slug': slug}))
10 | assert resp.status_code == 200
11 |
--------------------------------------------------------------------------------
/pythonpro/email_marketing/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/email_marketing/__init__.py
--------------------------------------------------------------------------------
/pythonpro/email_marketing/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class EmailMarketing(AppConfig):
5 | name = 'pythonpro.email_marketing'
6 |
--------------------------------------------------------------------------------
/pythonpro/launch/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/launch/__init__.py
--------------------------------------------------------------------------------
/pythonpro/launch/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class LaunchConfig(AppConfig):
5 | name = 'pythonpro.launch'
6 |
--------------------------------------------------------------------------------
/pythonpro/launch/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from django.forms.utils import ErrorList
3 |
4 |
5 | class LeadForm(forms.Form):
6 | name = forms.CharField(required=True)
7 | email = forms.EmailField(required=True)
8 |
9 | def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=ErrorList,
10 | label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None,
11 | renderer=None):
12 | super().__init__(data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted, field_order,
13 | use_required_attribute, renderer)
14 | self._normalize_email()
15 |
16 | def _normalize_email(self):
17 | self.data = dict(self.data.items())
18 | email = self.data.get('email')
19 | if email is not None:
20 | self.data['email'] = email.lower()
21 |
--------------------------------------------------------------------------------
/pythonpro/launch/templates/launch/membership_email.txt:
--------------------------------------------------------------------------------
1 | Olá {{ user.first_name }},
2 |
3 | Recebemos a confirmação de seu pagamento para a próxima turma Dev Pro.
4 |
5 | Faça login com sua conta e acesse a página de detalhes da turma em {{ cohort_detail_url }} para conferir as datas das atividades.
6 |
7 | Nessa página também existem as informações para vc se apresentar no fórum e também acessar nosso badalado grupo do Telegram!
8 |
9 | Agradecemos imensamente sua confiança em nosso trabalho.
10 |
11 | Grande abraço,
12 | Renzo Nuccitelli
--------------------------------------------------------------------------------
/pythonpro/launch/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/launch/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/launch/tests/test_ty.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from django.urls import reverse
3 |
4 | from pythonpro.django_assertions import dj_assert_contains
5 | from pythonpro.domain.user_domain import find_user_interactions
6 |
7 |
8 | @pytest.fixture
9 | def resp(client, cohort):
10 | return client.get(reverse('launch:ty'))
11 |
12 |
13 | def test_status_code(resp):
14 | assert 200 == resp.status_code
15 |
16 |
17 | @pytest.mark.parametrize(
18 | 'media_link',
19 | [
20 | 'https://twitter.com/renzoprobr',
21 | 'https://www.youtube.com/user/renzonuccitelli',
22 | 'https://instagram.com/renzoprobr',
23 | ]
24 |
25 | )
26 | def test_email_field_is_present(resp, media_link):
27 | dj_assert_contains(resp, media_link)
28 |
29 |
30 | @pytest.fixture
31 | def resp_with_user(client_with_user, cohort):
32 | return client_with_user.get(reverse('launch:ty'))
33 |
34 |
35 | def test_user_interaction(resp_with_user, logged_user):
36 | assert 'LAUNCH_SUBSCRIPTION' in [i.category for i in find_user_interactions(logged_user)]
37 |
--------------------------------------------------------------------------------
/pythonpro/launch/tests/test_vip_list.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from django.urls import reverse
3 |
4 | from pythonpro.django_assertions import dj_assert_contains
5 |
6 |
7 | @pytest.fixture
8 | def resp(client):
9 | return client.get(reverse('launch:vip_list'))
10 |
11 |
12 | def test_status_code(resp):
13 | assert 200 == resp.status_code
14 |
15 |
16 | def test_email_field_is_present(resp):
17 | dj_assert_contains(resp, 'https://python.activehosted.com/f/embed.php?id=2')
18 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/memberkit/__init__.py
--------------------------------------------------------------------------------
/pythonpro/memberkit/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class MemberkitConfig(AppConfig):
5 | default_auto_field = 'django.db.models.BigAutoField'
6 | name = 'pythonpro.memberkit'
7 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/memberkit/management/__init__.py
--------------------------------------------------------------------------------
/pythonpro/memberkit/management/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/memberkit/management/commands/__init__.py
--------------------------------------------------------------------------------
/pythonpro/memberkit/management/commands/inactivate_expired_subscriptions.py:
--------------------------------------------------------------------------------
1 | from django.core.management.base import BaseCommand
2 |
3 | from pythonpro.memberkit import facade
4 |
5 |
6 | class Command(BaseCommand):
7 | help = 'Busca todas assinaturas ativas e inativa as que estão expiradas'
8 |
9 | def add_arguments(self, parser):
10 | pass
11 |
12 | def handle(self, *args, **options):
13 | facade.inactivate_expired_subscriptions()
14 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/management/commands/synchronize_paid_subscriptions.py:
--------------------------------------------------------------------------------
1 | from django.core.management.base import BaseCommand
2 | from django_pagarme import facade as pagarme_facade
3 | from django_pagarme.models import PagarmePayment
4 |
5 | from pythonpro.memberkit import facade
6 |
7 |
8 | class Command(BaseCommand):
9 | help = 'Cria Assinatura para pagamentos que já tiveram status pago'
10 |
11 | def add_arguments(self, parser):
12 | pass
13 |
14 | def handle(self, *args, **options):
15 | for payment in PagarmePayment.objects.filter(notifications__status=pagarme_facade.PAID, subscription=None):
16 | self.stdout.write(self.style.SUCCESS(f'Processando pagamento {payment}'))
17 | facade.create_new_subscription(payment, 'Criado através de comando de sincronização')
18 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.4 on 2021-06-03 20:51
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | initial = True
8 |
9 | dependencies = [
10 | ]
11 |
12 | operations = [
13 | migrations.CreateModel(
14 | name='SubscriptionType',
15 | fields=[
16 | ('id', models.IntegerField(primary_key=True, serialize=False, unique=True)),
17 | ('name', models.CharField(max_length=128)),
18 | ],
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0004_add_membership_activation_data.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.4 on 2021-06-09 17:38
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('memberkit', '0003_subscription'),
9 | ]
10 |
11 | operations = [
12 | migrations.AddField(
13 | model_name='subscription',
14 | name='activated_at',
15 | field=models.DateTimeField(default=None, null=True),
16 | ),
17 | migrations.AddField(
18 | model_name='subscription',
19 | name='memberkit_user_id',
20 | field=models.IntegerField(null=True),
21 | ),
22 | ]
23 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0005_create_tags_for_discourse_email_marketing_subscription.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.4 on 2021-06-10 00:41
2 |
3 | import django.contrib.postgres.fields
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 | dependencies = [
9 | ('memberkit', '0004_add_membership_activation_data'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='subscriptiontype',
15 | name='discourse_groups',
16 | field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=64), default=list,
17 | size=None),
18 | ),
19 | migrations.AddField(
20 | model_name='subscriptiontype',
21 | name='email_marketing_tags',
22 | field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=64), default=list,
23 | size=None),
24 | ),
25 | ]
26 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0006_include_cohort_subscription_flag.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.4 on 2021-06-10 01:14
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('memberkit', '0005_create_tags_for_discourse_email_marketing_subscription'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='subscriptiontype',
15 | name='include_on_cohort',
16 | field=models.BooleanField(default=False, verbose_name='Incluir na última turma'),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0007_allow_subscripiton_be_saved_without_payment.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.4 on 2021-06-10 02:08
2 |
3 | import django.db.models.deletion
4 | from django.db import migrations, models
5 |
6 |
7 | class Migration(migrations.Migration):
8 | dependencies = [
9 | ('django_pagarme', '0005_change_primary_key_to_big_integer'),
10 | ('memberkit', '0006_include_cohort_subscription_flag'),
11 | ]
12 |
13 | operations = [
14 | migrations.AlterField(
15 | model_name='subscription',
16 | name='payment',
17 | field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING,
18 | to='django_pagarme.pagarmepayment'),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0008_added_days_of_access_field.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.7 on 2021-09-15 01:24
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('memberkit', '0007_allow_subscripiton_be_saved_without_payment'),
9 | ]
10 |
11 | operations = [
12 | migrations.AddField(
13 | model_name='subscription',
14 | name='days_of_access',
15 | field=models.IntegerField(default=73000),
16 | ),
17 | migrations.AddField(
18 | model_name='subscriptiontype',
19 | name='days_of_access',
20 | field=models.IntegerField(default=73000),
21 | ),
22 | ]
23 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0009_altered_subscription_default_to_one_year.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.0.4 on 2022-05-26 19:15
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [('memberkit', '0008_added_days_of_access_field')]
8 |
9 | operations = [
10 | migrations.AlterField(
11 | model_name='subscription',
12 | name='days_of_access',
13 | field=models.IntegerField(default=365),
14 | ),
15 | migrations.AlterField(
16 | model_name='subscriptiontype',
17 | name='days_of_access',
18 | field=models.IntegerField(default=365),
19 | ),
20 | ]
21 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0010_added_has_discord_access.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.1 on 2022-09-01 00:13
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('memberkit', '0009_altered_subscription_default_to_one_year'),
9 | ]
10 |
11 | operations = [
12 | migrations.AddField(
13 | model_name='subscriptiontype',
14 | name='has_discord_access',
15 | field=models.BooleanField(default=False),
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0011_alter_subscription_status.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.1.7 on 2023-03-23 02:32
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('memberkit', '0010_added_has_discord_access'),
9 | ]
10 |
11 | operations = [
12 | migrations.AlterField(
13 | model_name='subscription',
14 | name='status',
15 | field=models.CharField(choices=[('A', 'Ativa'), ('I', 'Inativa')], max_length=1),
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0012_added_subscription_expired_at.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.1.7 on 2023-04-12 23:17
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('memberkit', '0011_alter_subscription_status'),
9 | ]
10 |
11 | operations = [
12 | migrations.AddField(
13 | model_name='subscription',
14 | name='expired_at',
15 | field=models.DateField(null=True),
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/0014_alter_subscription_days_of_access_and_more.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 4.1.7 on 2023-04-13 00:58
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('memberkit', '0013_populate_expired_at'),
9 | ]
10 |
11 | operations = [
12 | migrations.AlterField(
13 | model_name='subscription',
14 | name='days_of_access',
15 | field=models.IntegerField(db_column='days_of_access', default=365),
16 | ),
17 | migrations.RenameField(
18 | model_name='subscription',
19 | old_name='days_of_access',
20 | new_name='old_days_of_access',
21 | ),
22 | ]
23 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/memberkit/migrations/__init__.py
--------------------------------------------------------------------------------
/pythonpro/memberkit/templates/memberkit/manual_migration.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base_without_nav.html' %}
2 | {% load static %}
3 |
4 | {% block title %}Migração para nova plataforma{% endblock %}
5 |
6 | {% block body %}
7 |
8 |
9 |
10 |
Migração com problemas
11 |
12 |
Olá {{ request.user.first_name }}.
13 |
Infelizmente a sua migração não aconteceu automaticamente.
14 |
Um email já foi enviado para resolvermos. Mas você pode adiantar o processo entrando em contato com o
15 | Renzo no Telegram e avisando que isso aconteceu. Informe seu email na
16 | mensagem: {{ request.user.email }}.
17 |
18 |
19 |
20 | {% endblock body %}
21 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/templates/memberkit/subscriptiontype/synchronize_button.html:
--------------------------------------------------------------------------------
1 | {% extends 'admin/change_list.html' %}
2 |
3 | {% block object-tools %}
4 |
5 |
9 |
10 |
11 | {{ block.super }}
12 | {% endblock %}
--------------------------------------------------------------------------------
/pythonpro/memberkit/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/memberkit/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/memberkit/tests/test_subscription_summary.py:
--------------------------------------------------------------------------------
1 | from model_bakery import baker
2 |
3 | from pythonpro.memberkit.models import UserSubscriptionsSummary, Subscription
4 |
5 |
6 | def test_user_summary_with_no_subscriptions(logged_user):
7 | summary = UserSubscriptionsSummary(logged_user)
8 | assert not summary.has_active_subscriptions()
9 |
10 |
11 | def test_user_with_active_subscriptions(django_user_model):
12 | active_users = baker.make(django_user_model, 5)
13 | for active_user in active_users:
14 | baker.make(Subscription, status=Subscription.Status.ACTIVE, subscriber=active_user)
15 |
16 | inactive_users = baker.make(django_user_model, 5)
17 | for inactive_user in inactive_users:
18 | baker.make(Subscription, status=Subscription.Status.INACTIVE, subscriber=inactive_user)
19 |
20 | active_user_ids_from_db = set(
21 | UserSubscriptionsSummary.users_with_active_subscriptions().values_list('id', flat=True)
22 | )
23 | assert active_user_ids_from_db == set(active_user.id for active_user in active_users)
24 |
--------------------------------------------------------------------------------
/pythonpro/memberkit/views.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.decorators import login_required
2 | from django.core.mail import mail_admins
3 | from django.shortcuts import redirect, render
4 |
5 | from pythonpro.memberkit import facade
6 |
7 |
8 | @login_required
9 | def migrate_to_memberkit(request):
10 | user = request.user
11 | facade.migrate_when_status_active(user)
12 | try:
13 | login_url = facade.create_login_url(user)
14 | except facade.InactiveUserException:
15 | mail_admins(
16 | f'Verificar migração de {user.email}',
17 | f'Link: https://painel.dev.pro.br/admin/memberkit/subscription/?q={user.email}'
18 | )
19 | return render(request, 'memberkit/manual_migration.html')
20 | else:
21 | return redirect(login_url)
22 |
--------------------------------------------------------------------------------
/pythonpro/modules/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/modules/__init__.py
--------------------------------------------------------------------------------
/pythonpro/modules/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class ModulesConfig(AppConfig):
5 | name = 'pythonpro.modules'
6 |
--------------------------------------------------------------------------------
/pythonpro/modules/chapters_urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from pythonpro.modules import chapters_views
4 |
5 | app_name = 'chapters'
6 | urlpatterns = [
7 | path('/', chapters_views.detail_old, name='detail_old'),
8 | ]
9 |
--------------------------------------------------------------------------------
/pythonpro/modules/chapters_views.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.decorators import login_required
2 | from django.shortcuts import render, redirect
3 |
4 | from pythonpro.modules import facade
5 |
6 |
7 | @login_required
8 | def detail_old(request, chapter_slug):
9 | chapter = facade.get_chapter_with_contents(slug=chapter_slug)
10 | return redirect(chapter.get_absolute_url(), permanent=True)
11 |
12 |
13 | @login_required
14 | def detail(request, module_slug, chapter_slug):
15 | ctx = {'chapter': facade.get_chapter_with_contents(slug=chapter_slug)}
16 | return render(request, 'chapters/chapter_detail.html', context=ctx)
17 |
--------------------------------------------------------------------------------
/pythonpro/modules/context_processors.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 |
3 | from pythonpro.modules.facade import get_all_modules
4 |
5 |
6 | def global_settings(request):
7 | # return any necessary values
8 | if not request.user.is_authenticated:
9 | return {}
10 |
11 | return {
12 | 'ALL_MODULES': get_all_modules(),
13 | 'SENTRY_DSN': settings.SENTRY_DSN,
14 | }
15 |
--------------------------------------------------------------------------------
/pythonpro/modules/migrations/0002_auto_20180314_1122.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.3 on 2018-03-14 14:22
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('modules', '0001_initial'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterModelTable(
14 | name='section',
15 | table=None,
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/pythonpro/modules/migrations/0003_module.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.3 on 2018-03-14 17:38
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('modules', '0002_auto_20180314_1122'),
10 | ]
11 |
12 | operations = [
13 | migrations.CreateModel(
14 | name='Module',
15 | fields=[
16 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
17 | ('order', models.PositiveIntegerField(db_index=True, editable=False)),
18 | ('title', models.CharField(max_length=50)),
19 | ('description', models.TextField()),
20 | ('slug', models.SlugField(unique=True)),
21 | ('objective', models.TextField()),
22 | ('target', models.TextField()),
23 | ],
24 | options={
25 | 'ordering': ('order',),
26 | 'abstract': False,
27 | },
28 | ),
29 | ]
30 |
--------------------------------------------------------------------------------
/pythonpro/modules/migrations/0005_auto_20180314_1817.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.3 on 2018-03-14 21:17
2 |
3 | from django.db import migrations
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('modules', '0004_section_module'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterModelOptions(
14 | name='section',
15 | options={'ordering': ['module', 'order']},
16 | ),
17 | migrations.RemoveField(
18 | model_name='section',
19 | name='_module_slug',
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/pythonpro/modules/migrations/0006_chapter.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.3 on 2018-03-17 16:03
2 |
3 | from django.db import migrations, models
4 | import django.db.models.deletion
5 |
6 |
7 | class Migration(migrations.Migration):
8 |
9 | dependencies = [
10 | ('modules', '0005_auto_20180314_1817'),
11 | ]
12 |
13 | operations = [
14 | migrations.CreateModel(
15 | name='Chapter',
16 | fields=[
17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18 | ('order', models.PositiveIntegerField(db_index=True, editable=False)),
19 | ('title', models.CharField(max_length=50)),
20 | ('description', models.TextField()),
21 | ('slug', models.SlugField(unique=True)),
22 | ('section', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='modules.Section')),
23 | ],
24 | options={
25 | 'ordering': ['section', 'order'],
26 | },
27 | ),
28 | ]
29 |
--------------------------------------------------------------------------------
/pythonpro/modules/migrations/0008_topic_discourse_topic_id.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.3 on 2018-03-19 03:18
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('modules', '0007_topic'),
9 | ]
10 |
11 | operations = [
12 | migrations.AddField(
13 | model_name='topic',
14 | name='discourse_topic_id',
15 | field=models.CharField(default='1', max_length=11),
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/pythonpro/modules/migrations/0009_auto_20180319_0020.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.0.3 on 2018-03-19 03:20
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('modules', '0008_topic_discourse_topic_id'),
9 | ]
10 |
11 | operations = [
12 | migrations.AlterField(
13 | model_name='topic',
14 | name='discourse_topic_id',
15 | field=models.CharField(max_length=11),
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/pythonpro/modules/migrations/0011_created_duration_on_topic.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0.2 on 2020-01-31 11:53
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('modules', '0010_auto_20190226_1830'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='topic',
15 | name='duration',
16 | field=models.IntegerField(default=0),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/pythonpro/modules/migrations/0012_create_memberkit_url.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.2.3 on 2021-05-26 23:54
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 | dependencies = [
8 | ('modules', '0011_created_duration_on_topic'),
9 | ]
10 |
11 | operations = [
12 | migrations.AddField(
13 | model_name='topic',
14 | name='memberkit_url',
15 | field=models.URLField(blank=True, default='', max_length=1024),
16 | ),
17 | ]
18 |
--------------------------------------------------------------------------------
/pythonpro/modules/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/modules/migrations/__init__.py
--------------------------------------------------------------------------------
/pythonpro/modules/module_urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from . import modules_views, sections_views, topics_views, chapters_views
4 |
5 | app_name = 'modules'
6 | urlpatterns = [
7 | path('', modules_views.index, name='index'),
8 | path('/', modules_views.detail, name='detail'),
9 | path('enrol//', modules_views.enrol, name='enrol'),
10 | path('/topicos/', topics_views.detail, name='topic_detail'),
11 | path('/secoes/', sections_views.detail, name='section_detail'),
12 | path('/capitulos/', chapters_views.detail, name='chapter_detail'),
13 | path('descricao//', modules_views.description, name='description'),
14 | ]
15 |
--------------------------------------------------------------------------------
/pythonpro/modules/permissions.py:
--------------------------------------------------------------------------------
1 | from rolepermissions.permissions import register_object_checker
2 |
3 | from pythonpro.modules.models import Content
4 |
5 |
6 | @register_object_checker()
7 | def access_content(role, user, content: Content) -> bool:
8 | module_slug = content.module_slug()
9 | return module_slug == 'python-birds'
10 |
--------------------------------------------------------------------------------
/pythonpro/modules/sections_urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from pythonpro.modules import sections_views
4 |
5 | app_name = 'sections'
6 | urlpatterns = [
7 | path('/', sections_views.detail_old, name='detail_old'),
8 | ]
9 |
--------------------------------------------------------------------------------
/pythonpro/modules/sections_views.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.decorators import login_required
2 | from django.shortcuts import redirect, render
3 |
4 | from pythonpro.modules import facade
5 |
6 |
7 | @login_required
8 | def detail_old(request, slug):
9 | section = facade.get_section_with_contents(slug=slug)
10 | return redirect(section.get_absolute_url(), permanent=True)
11 |
12 |
13 | @login_required
14 | def detail(request, module_slug, section_slug):
15 | ctx = {'section': facade.get_section_with_contents(slug=section_slug)}
16 | return render(request, 'sections/section_detail.html', ctx)
17 |
--------------------------------------------------------------------------------
/pythonpro/modules/templates/modules/module_enrol.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 | {% load static %}
3 |
4 | {% block title %}Começar metas do módulo {{ module.title }}{% endblock %}
5 | {% block description %}Expliação de sistema de metas do módulo {{ topic.description }}{% endblock %}
6 | {% block body %}
7 |
8 |
9 |
10 |
Metas ativadas para o módulo {{ module.title }}
11 |
Você receberá emails semanais para te ajudar a terminar esse módulo. Serão 4 semanas no total
12 |
Em instantes você já receberá o primeiro. Confira sua caixa de spam
13 |
14 |
15 |
16 | {% endblock body %}
17 |
--------------------------------------------------------------------------------
/pythonpro/modules/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/modules/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/modules/topics_urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from pythonpro.modules import topics_views
4 |
5 | app_name = 'topics'
6 | urlpatterns = [
7 | path('/', topics_views.old_detail, name='detail_old'),
8 | ]
9 |
--------------------------------------------------------------------------------
/pythonpro/pages/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/pages/__init__.py
--------------------------------------------------------------------------------
/pythonpro/pages/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class PagesConfig(AppConfig):
5 | name = 'pythonpro.pages'
6 |
--------------------------------------------------------------------------------
/pythonpro/pages/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 |
4 | class NameEmailForm(forms.Form):
5 | name = forms.CharField(label='', widget=forms.TextInput(attrs={'placeholder': 'Insira seu Nome'}))
6 | email = forms.EmailField(label='', widget=forms.TextInput(attrs={'placeholder': 'Insira seu Email'}))
7 |
8 |
9 | class NameEmailPhoneForm(NameEmailForm):
10 | phone = forms.CharField(
11 | label='',
12 | widget=forms.TextInput(attrs={'placeholder': 'Insira seu WhatsApp (não se esqueça do DDD)'})
13 | )
14 |
15 | def clean_phone(self):
16 | phone = self.cleaned_data['phone']
17 | phone = phone.replace('(', '')
18 | phone = phone.replace(')', '')
19 | phone = phone.replace(' ', '')
20 | phone = phone.replace('-', '')
21 | return phone
22 |
--------------------------------------------------------------------------------
/pythonpro/pages/templates/pages/pixeling_page.html:
--------------------------------------------------------------------------------
1 | {% extends 'core/base.html' %}
2 |
3 | {% block navbar %}{% endblock %}
4 | {% block footer %}{% endblock %}
5 |
6 |
--------------------------------------------------------------------------------
/pythonpro/pages/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/pages/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/pages/tests/test_leads_onboarding_page.py:
--------------------------------------------------------------------------------
1 | from django.urls import reverse
2 |
3 |
4 | def test_should_return_200_when_load_invite_page(client):
5 | resp = client.get(reverse('pages:leads_onboarding_page'))
6 | assert resp.status_code == 200
7 |
--------------------------------------------------------------------------------
/pythonpro/redirector/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/redirector/__init__.py
--------------------------------------------------------------------------------
/pythonpro/redirector/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from django.utils.html import format_html
3 |
4 | from pythonpro.redirector.models import Redirect, RedirectLink
5 |
6 |
7 | class RedirectLinkAdmin(admin.TabularInline):
8 | model = RedirectLink
9 | extra = 1
10 | readonly_fields = ['total_access', ]
11 | exclude = ['created', 'updated']
12 |
13 |
14 | @admin.register(Redirect)
15 | class RedirectorAdmin(admin.ModelAdmin):
16 | list_display = ['slug', 'created', 'get_redirect_link']
17 | list_filter = ['use_javascript', 'created']
18 | inlines = (RedirectLinkAdmin, )
19 | exclude = ['created', 'updated']
20 | ordering = ['-updated', '-created', 'slug']
21 |
22 | def get_redirect_link(self, obj):
23 | return format_html(
24 | f"""
25 | Link Gerado
26 | """)
27 |
28 | get_redirect_link.short_description = 'Links'
29 |
--------------------------------------------------------------------------------
/pythonpro/redirector/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class RedirectorConfig(AppConfig):
5 | name = 'pythonpro.redirector'
6 |
--------------------------------------------------------------------------------
/pythonpro/redirector/facade.py:
--------------------------------------------------------------------------------
1 | def _count_access_in_link(link):
2 | link.total_access += 1
3 | link.save()
4 |
5 |
6 | def get_redirect_url(redirect):
7 | if redirect.links.exists():
8 | link = redirect.links.order_by('total_access', 'id').first()
9 | _count_access_in_link(link)
10 | return link.url
11 |
12 | return redirect.url
13 |
--------------------------------------------------------------------------------
/pythonpro/redirector/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0.4 on 2020-03-26 03:09
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | initial = True
9 |
10 | dependencies = [
11 | ]
12 |
13 | operations = [
14 | migrations.CreateModel(
15 | name='Redirect',
16 | fields=[
17 | ('url', models.URLField()),
18 | ('slug', models.SlugField(primary_key=True, serialize=False)),
19 | ],
20 | ),
21 | ]
22 |
--------------------------------------------------------------------------------
/pythonpro/redirector/migrations/0003_redirect_use_javascript.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0.4 on 2020-04-22 00:49
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('redirector', '0002_auto_20200421_2144'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='redirect',
15 | name='use_javascript',
16 | field=models.BooleanField(default=False),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/pythonpro/redirector/migrations/0004_redirectlink_total_access.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 3.0.4 on 2020-04-22 01:05
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('redirector', '0003_redirect_use_javascript'),
10 | ]
11 |
12 | operations = [
13 | migrations.AddField(
14 | model_name='redirectlink',
15 | name='total_access',
16 | field=models.BigIntegerField(default=0),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/pythonpro/redirector/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/redirector/migrations/__init__.py
--------------------------------------------------------------------------------
/pythonpro/redirector/models.py:
--------------------------------------------------------------------------------
1 | from django.utils import timezone
2 | from django.db import models
3 |
4 |
5 | class Redirect(models.Model):
6 | created = models.DateTimeField("Criado em", default=timezone.now)
7 | updated = models.DateTimeField("Alterado em", auto_now=True)
8 | slug = models.SlugField(primary_key=True)
9 | url = models.URLField(null=True, blank=True)
10 | use_javascript = models.BooleanField(default=False)
11 |
12 | def __str__(self):
13 | return self.slug
14 |
15 | def get_absolute_url(self):
16 | return f'/r/{self.slug}'
17 |
18 |
19 | class RedirectLink(models.Model):
20 | created = models.DateTimeField("Criado em", default=timezone.now)
21 | updated = models.DateTimeField("Alterado em", auto_now=True)
22 | redirect = models.ForeignKey(Redirect, on_delete=models.PROTECT, related_name='links')
23 | url = models.URLField()
24 | total_access = models.BigIntegerField(default=0)
25 |
--------------------------------------------------------------------------------
/pythonpro/redirector/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/redirector/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/redirector/tests/test_redirect_by_headers.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from django.urls import reverse
3 | from model_bakery import baker
4 |
5 | from pythonpro.redirector.models import Redirect
6 |
7 |
8 | @pytest.fixture
9 | def redirect(db):
10 | return baker.make(Redirect, url='https://google.com')
11 |
12 |
13 | @pytest.fixture
14 | def resp(client, redirect):
15 | return client.get(reverse('redirector:redirect', kwargs={'slug': redirect.slug}))
16 |
17 |
18 | def test_status_code_should_return_302(resp):
19 | assert resp.status_code == 302
20 |
--------------------------------------------------------------------------------
/pythonpro/redirector/tests/test_redirect_by_javascript.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from django.urls import reverse
3 | from model_bakery import baker
4 |
5 | from pythonpro.django_assertions import dj_assert_contains
6 | from pythonpro.redirector.models import Redirect
7 | from pythonpro.redirector.facade import get_redirect_url
8 |
9 |
10 | @pytest.fixture
11 | def redirect(db):
12 | return baker.make(Redirect, url='https://google.com', use_javascript=True)
13 |
14 |
15 | def test_should_redirect_url_in_redirect_object(redirect):
16 | assert get_redirect_url(redirect) == redirect.url
17 |
18 |
19 | @pytest.fixture
20 | def resp(client, redirect):
21 | return client.get(reverse('redirector:redirect', kwargs={'slug': redirect.slug}))
22 |
23 |
24 | def test_status_code_should_return_200(resp):
25 | assert resp.status_code == 200
26 |
27 |
28 | def test_should_redirect_js_contains_redirect_url(resp, redirect):
29 | dj_assert_contains(resp, f'window.location.replace("{redirect.url}")')
30 |
--------------------------------------------------------------------------------
/pythonpro/redirector/urls.py:
--------------------------------------------------------------------------------
1 | from django.urls import path
2 |
3 | from pythonpro.redirector import views
4 |
5 | app_name = 'redirector'
6 | urlpatterns = [
7 | path('', views.redirect, name='redirect'),
8 | ]
9 |
--------------------------------------------------------------------------------
/pythonpro/redirector/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render, redirect as redirect_url
2 |
3 | from pythonpro.redirector.models import Redirect
4 | from pythonpro.redirector.facade import get_redirect_url
5 |
6 |
7 | def redirect(request, slug: str):
8 | redirect = Redirect.objects.get(slug=slug)
9 | url = get_redirect_url(redirect)
10 |
11 | if '?' in url and request.GET:
12 | url = f'{url}&{request.GET.urlencode()}'
13 | elif request.GET:
14 | url = f'{url}?{request.GET.urlencode()}'
15 |
16 | if redirect.use_javascript is False:
17 | return redirect_url(url)
18 |
19 | ctx = {'url': url}
20 | return render(request, 'redirector/redirect.html', ctx)
21 |
--------------------------------------------------------------------------------
/pythonpro/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pythonprobr/pythonpro-website/cbef22a6e5435fd00200d5481c1378995d562e16/pythonpro/tests/__init__.py
--------------------------------------------------------------------------------
/pythonpro/tests/test_urls.py:
--------------------------------------------------------------------------------
1 | from pythonpro.urls import urlpatterns
2 |
3 |
4 | def test_urls_len():
5 | assert 16 <= len(urlpatterns)
6 |
--------------------------------------------------------------------------------
/pythonpro/tests/test_wsgi.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from django.core.handlers.wsgi import WSGIHandler
4 |
5 | from pythonpro.wsgi import application
6 |
7 |
8 | def test_wsgi_default_settings():
9 | assert 'pythonpro.settings' == os.environ["DJANGO_SETTINGS_MODULE"]
10 |
11 |
12 | def test_application_instace():
13 | assert isinstance(application, WSGIHandler)
14 |
--------------------------------------------------------------------------------
/pythonpro/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for pythonpro project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pythonpro.settings')
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------