├── .gitignore ├── README.rst ├── ajuda └── python-anywhere.md ├── antigo ├── djangogirls │ ├── .cache │ │ └── v │ │ │ └── cache │ │ │ └── lastfailed │ └── mysite │ │ ├── .cache │ │ └── v │ │ │ └── cache │ │ │ └── lastfailed │ │ ├── blog │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-36.pyc │ │ │ ├── admin.cpython-36.pyc │ │ │ ├── models.cpython-36.pyc │ │ │ ├── urls.cpython-36.pyc │ │ │ └── views.cpython-36.pyc │ │ ├── admin.py │ │ ├── apps.py │ │ ├── jinja2 │ │ │ ├── base.html │ │ │ ├── post_detail.html │ │ │ └── post_list.html │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── __init__.py │ │ │ └── __pycache__ │ │ │ │ ├── 0001_initial.cpython-36.pyc │ │ │ │ └── __init__.cpython-36.pyc │ │ ├── models.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ │ ├── db.sqlite3 │ │ ├── manage.py │ │ ├── mysite │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-36.pyc │ │ │ ├── jinja2.cpython-36.pyc │ │ │ ├── settings.cpython-36.pyc │ │ │ ├── urls.cpython-36.pyc │ │ │ └── wsgi.cpython-36.pyc │ │ ├── jinja2.py │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py │ │ └── tests │ │ ├── __pycache__ │ │ └── test_post.cpython-36-PYTEST.pyc │ │ └── test_post.py └── trabalhos │ ├── EP1.rst │ ├── EP2.rst │ ├── EP3.rst │ ├── EP4.rst │ └── issues-summaeh.rst ├── aulas └── html.md ├── bak └── djangogirls │ ├── __pycache__ │ └── blog.cpython-36.pyc │ ├── db.sqlite3 │ ├── djangogirls │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── settings.cpython-36.pyc │ │ ├── urls.cpython-36.pyc │ │ └── wsgi.cpython-36.pyc │ ├── settings.py │ └── urls.py │ ├── manage.py │ ├── micro │ ├── __init__.py │ ├── __main__.py │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── __main__.cpython-36.pyc │ │ ├── app.cpython-36.pyc │ │ ├── settings.cpython-36.pyc │ │ ├── urls.cpython-36.pyc │ │ └── wsgi.cpython-36.pyc │ ├── app.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ └── old_blog │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-36.pyc │ ├── admin.cpython-36.pyc │ ├── forms.cpython-36.pyc │ ├── models.cpython-36.pyc │ ├── urls.cpython-36.pyc │ └── views.cpython-36.pyc │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ ├── 0001_initial.py │ ├── 0002_blogpost_date.py │ ├── 0003_auto_20180410_1333.py │ ├── __init__.py │ └── __pycache__ │ │ ├── 0001_initial.cpython-36.pyc │ │ ├── 0002_blogpost_date.cpython-36.pyc │ │ ├── 0003_auto_20180410_1333.cpython-36.pyc │ │ └── __init__.cpython-36.pyc │ ├── models.py │ ├── static │ └── css │ │ └── blog.css │ ├── templates │ └── blog │ │ ├── base.html │ │ ├── post_detail.html │ │ ├── post_edit.html │ │ └── post_list.html │ └── tests.py ├── djangogirls-micro ├── blog │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── admin.cpython-36.pyc │ │ ├── forms.cpython-36.pyc │ │ ├── models.cpython-36.pyc │ │ ├── urls.cpython-36.pyc │ │ └── views.cpython-36.pyc │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_blogpost_date.py │ │ ├── 0003_auto_20180410_1333.py │ │ ├── __init__.py │ │ └── __pycache__ │ │ │ ├── 0001_initial.cpython-36.pyc │ │ │ ├── 0002_blogpost_date.cpython-36.pyc │ │ │ ├── 0003_auto_20180410_1333.cpython-36.pyc │ │ │ └── __init__.cpython-36.pyc │ ├── static │ │ └── css │ │ │ └── blog.css │ └── templates │ │ └── blog │ │ ├── base.html │ │ ├── post_detail.html │ │ ├── post_edit.html │ │ └── post_list.html ├── db.sqlite3 ├── djangogirls │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── settings.cpython-36.pyc │ │ ├── urls.cpython-36.pyc │ │ └── wsgi.cpython-36.pyc │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py ├── djangogirls └── djangogirls │ ├── blog │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── admin.cpython-36.pyc │ │ ├── forms.cpython-36.pyc │ │ ├── models.cpython-36.pyc │ │ ├── urls.cpython-36.pyc │ │ └── views.cpython-36.pyc │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_blogpost_date.py │ │ ├── 0003_auto_20180410_1333.py │ │ ├── __init__.py │ │ └── __pycache__ │ │ │ ├── 0001_initial.cpython-36.pyc │ │ │ ├── 0002_blogpost_date.cpython-36.pyc │ │ │ ├── 0003_auto_20180410_1333.cpython-36.pyc │ │ │ └── __init__.cpython-36.pyc │ ├── models.py │ ├── static │ │ └── css │ │ │ └── blog.css │ ├── templates │ │ └── blog │ │ │ ├── base.html │ │ │ ├── post_detail.html │ │ │ ├── post_edit.html │ │ │ └── post_list.html │ ├── tests.py │ ├── urls.py │ └── views.py │ ├── db.sqlite3 │ ├── djangogirls │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── settings.cpython-36.pyc │ │ ├── urls.cpython-36.pyc │ │ └── wsgi.cpython-36.pyc │ ├── settings.py │ ├── urls.py │ └── wsgi.py │ └── manage.py ├── exemplos └── css │ ├── flex.css │ ├── flex.html │ ├── page.html │ ├── style.css │ ├── style.css.map │ └── style.scss ├── private ├── prova1.html ├── prova1.md └── prova1.pdf └── provas └── prova1 └── pastebin ├── db.sqlite3 ├── manage.py ├── pastebin ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-36.pyc │ ├── admin.cpython-36.pyc │ ├── models.cpython-36.pyc │ ├── urls.cpython-36.pyc │ └── views.cpython-36.pyc ├── admin.py ├── apps.py ├── jinja2 │ └── pastebin │ │ ├── index.jinja2 │ │ ├── paste-detail.jinja2 │ │ └── paste-language.jinja2 ├── migrations │ ├── __init__.py │ └── __pycache__ │ │ └── __init__.cpython-36.pyc ├── models.py ├── tests.py ├── urls.py └── views.py └── pastebin_project ├── __init__.py ├── __pycache__ ├── __init__.cpython-36.pyc ├── jinja2.cpython-36.pyc ├── settings.cpython-36.pyc ├── urls.cpython-36.pyc ├── views.cpython-36.pyc └── wsgi.cpython-36.pyc ├── jinja2.py ├── jinja2 ├── base.jinja2 └── static.jinja2 ├── settings.py ├── static ├── css │ └── main.css └── js │ └── main.js ├── urls.py ├── views.py └── wsgi.py /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache 2 | djangogirls/myenv/ 3 | exemplos/wagtail/env/ 4 | private/ -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | =============== 2 | Programação Web 3 | =============== 4 | 5 | Este é o repositório da disciplina de Programação Web para o semestre 1/2018 na Faculdade do Gama/UnB. Este arquivo contêm informações básicas sobre a disciplina e o plano de ensino do semestre. 6 | 7 | 8 | Informações básicas 9 | =================== 10 | 11 | Curso: 12 | Engenharia de Software 13 | Professor: 14 | Fábio Macêdo Mendes 15 | Disciplina: 16 | Programação Web 17 | Semestre/ano: 18 | 01/2018 19 | Carga horária: 20 | 60 h 21 | Créditos: 22 | 04 23 | 24 | 25 | Ementa 26 | ====== 27 | 28 | * Conceitos básicos de tecnologia Web 29 | * HTML5, Javascript e CSS 30 | * Frameworks para desenvolvimento e MVC 31 | * Servidores de aplicação 32 | * APIs e interoperabilidade 33 | * Testes em aplicações Web 34 | 35 | 36 | Horário das aulas e atendimento 37 | =============================== 38 | 39 | Aulas teóricas e de exercícios: terças e quintas-feiras às 16h 40 | Atendimento e monitoria: a definir 41 | 42 | 43 | Metodologia 44 | =========== 45 | 46 | O método básico aplicado é o de aulas práticas em laboratório de computação voltadas à implementação de funcionalidades dentro de um projeto compartilhado port toda a turma. As aulas podem conter partes expositivas orientadas à discussão da teoria e ferramentas utilizadas. As aulas também serão complementadas com atividades de exercícios e demandas extra-classe. Os alunos devem se cadastrar no Github e acompanhar o repositório da turma (https://github.com/fabiommendes/progweb). 47 | 48 | Este semestre (1/2018) será dedicado a implementar um microframework baseado em Django. 49 | 50 | 51 | Critérios de avaliação 52 | ====================== 53 | 54 | Cada aluno será avaliado com uma nota numérica onde a conversão entre a pontuação e a menção final é feita da forma usual: 9,0pts+: SS, 7,0pts+: MS, 5,0pts+: MM, 3,0pts+: MI e < 3,0 pts II. A distribuição de pontos ao longo do curso segue a fórmula:: 55 | 56 | NotaFinal = 0.15 * P1 + 0.30 * P2 + 0.15 * ME + 0.40 * MT 57 | 58 | onde P1 e P2 consistem na nota das provas 1 e 2; ME representa a média dos exercícios individuais (feitos em casa); MT representa a média dos testes realizados em sala de aula. Os testes serão resolvidos em grupos de tamanho e composição variávies e consistem em tarefas esporádicas realizadas durante a aula e na nota da "Hackaton" de Programação Web, que será executada em duas edições. 59 | 60 | Gamificação 61 | ----------- 62 | 63 | O aluno poderá fazer algumas tarefas opcionais que dão direito a "poderes especiais" e outras vantagens ao longo do curso. Estes "poderes" podem modificar a nota final, abonar faltas, entre outros. Esta seção lista as tarefas disponíveis e os poderes associados. 64 | 65 | Django girls 66 | ~~~~~~~~~~~~ 67 | 68 | O aluno que participar como *coach* do Django-Girls ganha o direito de converter a menor nota de teste em 10. Não pode ser aplicado na nota da Hackaton. 69 | 70 | 71 | Prova substitutiva e faltas 72 | --------------------------- 73 | 74 | O curso não inclui prova substitutiva. Caso o aluno possua uma falta justificada no dia da primeira prova, deverá apresentar um comprovante na aula seguinte à prova ou quando terminar a licença médica. Esta justificativa não abona falta, mas dá direito ao aluno utilizar a segunda prova como prova substitutiva. 75 | 76 | O aluno pode faltar até 7 vezes em um semestre. Faltas com justificativa médica não serão abonadas, exceto em casos excepcionais. Os alunos reprovados por falta ficarão com uma menção igual a SR. 77 | 78 | 79 | Código de ética e conduta 80 | ------------------------- 81 | 82 | Algumas avaliações serão realizadas com auxílio do computador no laboratório de informática. Todas as submissões serão processadas por um programa de detecção de plágio. Qualquer atividade onde for detectada a presença de plágio será anulada sem a possibilidade de substituição. Não será feita qualquer distinção entre o aluno que forneceu a resposta para cópia e o aluno que obteve a mesma. 83 | 84 | As mesmas considerações também se aplicam às provas teóricas que serão respondidas à mão. 85 | 86 | 87 | Informações importantes 88 | ======================== 89 | 90 | Este curso utiliza GitHub + Github Classroom e o Google classroom para gerenciar o curso. A comunicação com a turma é feita através do Google Classroom ou por issues no repositório do Github. Habilite a funcionalidade "Watch" no repositório para receber notificações sobre atualizações. 91 | 92 | Google Classroom: 93 | http://classroom.google.com/ - Código de inscrição: nllue7 94 | Github: 95 | http://github.com/fabiommendes/progweb/ 96 | Github Classroom: 97 | http://github.com/programacao-web/ 98 | 99 | 100 | Prepare-se 101 | ========== 102 | 103 | Ao longo do curso abordaremos uma série de tecnologias em diferentes níveis de profundidade. Recomenda-se que cada aluno providencie a instalação de todos os pacotes o mais rapidamente o possível. O curso subentende um ambiente de desenvolvimento Linux funcional para realizar as atividades propostas no curso. É possível desenvolver em outras plataformas (ex. Windows e Mac), mas o curso assume que as entregas utilizem algum container Docker especificado pelo professor. Isto, naturalmente, exige ao menos algum nível de emulação do Linux utilizando o Docker machine, Vagrant ou similar. 104 | 105 | Docker + docker-compose: 106 | O curso disponibilizará algumas imagens Docker configuradas com as ferramentas essenciais utilizadas no curso (o link segue em breve). Todos os trabalhos serão testados em containers baseados nestas imagens. Ainda que o Docker contenha as ferramentas de desenvolvimento essenciais, recomenda-se a instalação local dos pacotes abaixo. 107 | Python 3.6+: 108 | É necessário um ambiente Python 3.6 ou superior com todos os pacotes de desenvolvimento instalados. No Ubuntu/Debian precisamos do python3-dev, python3-pip, python3-virtualenv 109 | Node.js e npm (ou Yarn): 110 | Certifique-se que é possível baixar pacotes do Node.js para o frontend. Vários desenvolvedores preferem o Yarn como alternativa ao NPM. 111 | Sass (ou Ruby): 112 | Se a distribuição não possui o pacote do Sass, instale o Ruby e digite ``sudo gem install sass``. 113 | Nginx, Postgres: 114 | Servidor de arquivos e banco. Não é necessário/recomendável fazer a instalação local, mas já se adiante e para baixar a imagem do docker hub: ``sudo docker pull nginx`` e ``sudo docker pull postgres`` 115 | Git, editor de código, conta no github: 116 | Kit básico ;) 117 | Versão atualizada do Chrome: 118 | Algumas partes do curso poderão utilizar funcionalidades que (atualmente) estão implementadas somente no Google Chrome. Certifique que seu computador possui uma versão atualizada deste navegador. 119 | Outros: 120 | Virtualenvwrapper (``sudo apt-get install virtualenvwrapper``), Pytest (``pip3 install pytest --user``), Invoke (``pip3 install invoke --user``), Webpack (``sudo npm install -g webpack``) 121 | Sugestões de editor de código: 122 | Utilize o seu favorito. Caso precise de uma recomendação, seguem algumas: 123 | 124 | * PyCharm Educacional - IDE com ótimos recursos de introspecção e refatoração que adora memória RAM. Possui versão livre e versão profissional gratuita para estudantes. 125 | * VSCode - um bom meio termo entre uma IDE e um editor de código leve. Criado para Javascript, mas possui plugins para Python e várias outras linguagens. 126 | * Vi/Vim - herança dos anos 70 que nunca morre. Instale os plugins para Python e Javascript. 127 | 128 | 129 | Cronograma de atividades 130 | ======================== 131 | 132 | +--------+-------+------------------------------------------------------------+ 133 | | Semana | Data | Aula | 134 | +========+=======+============================================================+ 135 | | 1 | 06/03 | Início das aulas – Apresentação do curso e tecnologias Web | 136 | | | | | 137 | | | | * HTML5 e XML | 138 | | | | * Marcação de text e hipertexto | 139 | | | | * CSS | 140 | | | | * Javascript | 141 | +--------+-------+------------------------------------------------------------+ 142 | | | 08/03 | HTML | 143 | | | | | 144 | | | | * Histórico: SGML, HTML, XML, XHTML, HTML5, etc | 145 | | | | * HTML semântico | 146 | | | | * Estruturando um hipertexto | 147 | | | | * Design progressivo | 148 | | | | * Tags personalizadas, divs e spans | 149 | | | | * Formatos XML embutidos (SVG, MathML) | 150 | +--------+-------+------------------------------------------------------------+ 151 | | 2 | 13/03 | CSS | 152 | | | | | 153 | | | | * Propriedades básicas | 154 | | | | * Seletores | 155 | | | | * Cascata e prioridades de seletores | 156 | | | | * Sass e pré-compiladores CSS | 157 | +--------+-------+------------------------------------------------------------+ 158 | | | 15/03 | Design responsivo | 159 | | | | | 160 | | | | * Media queries | 161 | | | | * Flex boxes | 162 | | | | * “Mobile first/responsive design” | 163 | | | | * Frameworks (e.g.: Twitter Bootstrap) | 164 | +--------+-------+------------------------------------------------------------+ 165 | | 3 | 20/03 | JavaScript | 166 | | | | | 167 | | | | * História | 168 | | | | * Sintaxe | 169 | | | | * Tipos básicos e estruturas de dados | 170 | | | | * Herança de protótipo | 171 | | | | * "The good parts" | 172 | +--------+-------+------------------------------------------------------------+ 173 | | | 22/03 | Javascript no navegador | 174 | | | | | 175 | | | | * Ferramentas de depuração e inspeção | 176 | | | | * DOM e modelo de dados | 177 | | | | * APIs básicas Manipulação da DOM | 178 | | | | * jQuery vs nativo | 179 | +--------+-------+------------------------------------------------------------+ 180 | | 4 | 27/03 | Web components | 181 | | | | | 182 | | | | * Templates | 183 | | | | * Custom elements | 184 | | | | * Shadow DOM | 185 | | | | * HTML Imports | 186 | | | | * Bibliotecas e interpretações | 187 | +--------+-------+------------------------------------------------------------+ 188 | | | 29/03 | Stencil.js (ou outra biblioteca de Web Components) | 189 | | | | | 190 | | | | * Criação de componentes e decoradores | 191 | | | | * Typescript | 192 | | | | * JSX | 193 | | | | * Compilação e distribuição | 194 | +--------+-------+------------------------------------------------------------+ 195 | | 5 | 03/04 | Arquitetura e ferramentas Django | 196 | | | | | 197 | | | | * Preparação de ambiente | 198 | | | | * Ferramentas | 199 | | | | * Apps/Projetos (https://djangopackages.org/) | 200 | | | | * Arquitetura MVC (ou MTV) | 201 | | | | * Views, requests, responses e middlewares | 202 | +--------+-------+------------------------------------------------------------+ 203 | | | 05/04 | Templates vs pseudo-DOM | 204 | | | | | 205 | | | | * Linguagens de template e views | 206 | | | | * Jinja2 + Django | 207 | | | | * ELM, Hyperapp, JSX, Python bricks | 208 | +--------+-------+------------------------------------------------------------+ 209 | | 6 | 10/04 | ORM do Django | 210 | | | | | 211 | | | | * Relação com o banco de dados | 212 | | | | * Criação/remoção de objetos | 213 | | | | * Validação | 214 | | | | * Busca de elementos | 215 | +--------+-------+------------------------------------------------------------+ 216 | | | 12/04 | Managers e QuerySets | 217 | | | | | 218 | | | | * Querysets e SQL | 219 | | | | * Problema N + 1 e eficiência do ORM | 220 | | | | * Personalizando QuerySets para um modelo | 221 | +--------+-------+------------------------------------------------------------+ 222 | | 7 | 17/04 | AJAX | 223 | | | | | 224 | | | | * JSON | 225 | | | | * Gerando JSON em Python e Javascript | 226 | | | | * Método Fetch | 227 | | | | * Servindo JSON | 228 | | | | * Django REST Framework | 229 | +--------+-------+------------------------------------------------------------+ 230 | | | 19/04 | Arquitetura REST | 231 | | | | | 232 | | | | * API | 233 | | | | * Verbos HTTP | 234 | | | | * Interface REST | 235 | | | | * Alternativas ao REST | 236 | +--------+-------+------------------------------------------------------------+ 237 | | 8 | 24/04 | Arquitetura microframework | 238 | | | | | 239 | | | | * Flask | 240 | | | | * Blog em Flask | 241 | +--------+-------+------------------------------------------------------------+ 242 | | | 26/04 | Dojo - Micro Django | 243 | | | | | 244 | +--------+-------+------------------------------------------------------------+ 245 | | 9 | 01/05 | *Feriado - Dia do Trabalho* | 246 | | | | | 247 | +--------+-------+------------------------------------------------------------+ 248 | | | 03/05 | **Prova I** | 249 | | | | | 250 | +--------+-------+------------------------------------------------------------+ 251 | | 10 | 08/05 | Testes unitários | 252 | | | | | 253 | | | | * Biblioteca “pytest” | 254 | | | | * Casos de teste e classes de teste | 255 | | | | * Fixtures e conftest.py | 256 | | | | * Especificidades de testes em ambiente Django/web | 257 | | | | * Utilizando dados falsos | 258 | +--------+-------+------------------------------------------------------------+ 259 | | | 10/05 | Testes funcionais | 260 | | | | | 261 | | | | * Selenium | 262 | | | | * Controlando o navegador | 263 | | | | * Testes em JavaScript | 264 | +--------+-------+------------------------------------------------------------+ 265 | | 11 | 17/05 | Micro Django - views | 266 | | | | | 267 | | | | * Tipos de rotas | 268 | | | | * Verbos HTTP | 269 | | | | * Decoradores | 270 | | | | * Type hints e introspecção de assinatura | 271 | +--------+-------+------------------------------------------------------------+ 272 | | | 19/05 | Micro Django - Dojo | 273 | | | | | 274 | +--------+-------+------------------------------------------------------------+ 275 | | 12 | 22/05 | Docker | 276 | | | | | 277 | | | | * Isolamento de ambiente: containers e imagens | 278 | | | | * Sistema de arquivos | 279 | | | | * Dockerfile | 280 | | | | * Docker compose | 281 | +--------+-------+------------------------------------------------------------+ 282 | | | 24/05 | Empacotamento e gerência de configuração | 283 | | | | | 284 | | | | * Setuptools e PIP | 285 | | | | * Invoke | 286 | | | | * Tox e integração contínua | 287 | +--------+-------+------------------------------------------------------------+ 288 | | 13 | 29/05 | Micro Django - API | 289 | | | | | 290 | | | | * Roteadores e end-points | 291 | | | | * Construção automática de end-points | 292 | +--------+-------+------------------------------------------------------------+ 293 | | | 31/05 | *Feriado - Corpus Christi* | 294 | | | | | 295 | +--------+-------+------------------------------------------------------------+ 296 | | 14 | 05/06 | Micro Django - ORM | 297 | | | | | 298 | | | | * Revisitando declarações | 299 | | | | * Type hints | 300 | | | | * Metaclasses | 301 | +--------+-------+------------------------------------------------------------+ 302 | | | 07/06 | Micro Django - Dojo | 303 | | | | | 304 | +--------+-------+------------------------------------------------------------+ 305 | | 15 | 12/06 | Micro Django - QuerySet | 306 | | | | | 307 | | | | * Revisitando a sintaxe de filtros | 308 | | | | * API Pydata | 309 | | | | * Active Record: pattens e anti-patterns | 310 | +--------+-------+------------------------------------------------------------+ 311 | | | 14/06 | Micro Django - Dojo | 312 | | | | | 313 | +--------+-------+------------------------------------------------------------+ 314 | | 16 | 19/06 | Permissões e autorização | 315 | | | | | 316 | | | | * Permissões | 317 | | | | * Autenticação e autorização | 318 | | | | * Django-rules | 319 | +--------+-------+------------------------------------------------------------+ 320 | | | 21/06 | Segurança na rede | 321 | | | | | 322 | | | | * Injeção de SQL | 323 | | | | * CSRF | 324 | | | | * XSS | 325 | | | | * DoS | 326 | +--------+-------+------------------------------------------------------------+ 327 | | 17 | 26/06 | Formulários | 328 | | | | | 329 | | | | * Inputs em HTML | 330 | | | | * GET e POST | 331 | | | | * Classes do tipo “Form” | 332 | | | | * Formulários baseados em modelos | 333 | | | | * Apresentando um formulário | 334 | +--------+-------+------------------------------------------------------------+ 335 | | | 28/06 | **Prova II** | 336 | | | | | 337 | +--------+-------+------------------------------------------------------------+ 338 | | 18 | 03/07 | Livre | 339 | | | | | 340 | +--------+-------+------------------------------------------------------------+ 341 | | | 05/07 | Revisão de nota | 342 | | | | | 343 | +--------+-------+------------------------------------------------------------+ 344 | 345 | Obs.: O cronograma está sujeito a alterações. 346 | -------------------------------------------------------------------------------- /ajuda/python-anywhere.md: -------------------------------------------------------------------------------- 1 | PythonAnywhere 2 | ============== 3 | 4 | PythonAnywhere é um serviço de hospedagem de applicações Python gratuito com 5 | opções pagas de upgrade. Ele possui opções de hospedagem de applicações Django, 6 | Flask, entre outros. 7 | 8 | Instruções para instalar seu app Django 9 | --------------------------------------- 10 | 11 | Crie uma conta em https://www.pythonanywhere.com. O serviço disponibiliza uma 12 | máquina com Linux e um ambiente Python pré-configurado. 13 | -------------------------------------------------------------------------------- /antigo/djangogirls/.cache/v/cache/lastfailed: -------------------------------------------------------------------------------- 1 | { 2 | "myenv/lib/python3.6/site-packages/django/contrib/admindocs/tests/test_fields.py": true, 3 | "myenv/lib64/python3.6/site-packages/django/contrib/admindocs/tests/test_fields.py": true 4 | } -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/.cache/v/cache/lastfailed: -------------------------------------------------------------------------------- 1 | { 2 | "tests/test_post.py": true 3 | } -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/blog/__init__.py -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/blog/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/__pycache__/admin.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/blog/__pycache__/admin.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/__pycache__/models.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/blog/__pycache__/models.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/__pycache__/urls.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/blog/__pycache__/urls.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/__pycache__/views.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/blog/__pycache__/views.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Post 4 | 5 | admin.site.register(Post) 6 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BlogConfig(AppConfig): 5 | name = 'blog' 6 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/jinja2/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% block styles %} 4 | 11 | {% endblock %} 12 | 13 | {% block scripts %} 14 | {% endblock %} 15 | 16 | {% block title -%} 17 | {%- if title -%} 18 | {{ title }} 19 | {%- else -%} 20 | Django Girls Blog 21 | {%- endif -%} 22 | {%- endblock -%} 23 | 24 | 25 | 26 | {% block body %} 27 | 30 |
31 | {% block content %} 32 | {% endblock %} 33 |
34 | {% endblock %} 35 | 36 | 37 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/jinja2/post_detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |

5 | {{ my_dict['foo'] }} 6 | {{ foo.answer() }} 7 | {{ foo.ham }} 8 | {{ the_answer() }} 9 | {{ "hello"|UPPER }} 10 | {{ 40 | plus(2) }} 11 |

12 | 13 |
14 |

published: {{ post.published_date }}

15 |

{{post.title}}

16 |

{{ post.text }}

17 |
18 | {% endblock content %} -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/jinja2/post_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block styles %} 4 | {{ block.super }} 5 | 8 | {% endblock %} 9 | 10 | {% block content %} 11 | {% for post in posts %} 12 |
13 |

published: {{ post.published_date }}

14 |

{{post.title}}

15 |

{{post.text|linebreaksbr}}

16 |
17 | {% endfor %} 18 | {% endblock content %} 19 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.6 on 2017-03-22 19:44 3 | from __future__ import unicode_literals 4 | 5 | from django.conf import settings 6 | from django.db import migrations, models 7 | import django.db.models.deletion 8 | import django.utils.timezone 9 | 10 | 11 | class Migration(migrations.Migration): 12 | 13 | initial = True 14 | 15 | dependencies = [ 16 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 17 | ] 18 | 19 | operations = [ 20 | migrations.CreateModel( 21 | name='Post', 22 | fields=[ 23 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 24 | ('title', models.CharField(max_length=200)), 25 | ('text', models.TextField()), 26 | ('created_date', models.DateTimeField(default=django.utils.timezone.now)), 27 | ('published_date', models.DateTimeField(blank=True, null=True)), 28 | ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 29 | ], 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/blog/migrations/__init__.py -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/migrations/__pycache__/0001_initial.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/blog/migrations/__pycache__/0001_initial.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/migrations/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/blog/migrations/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.utils import timezone 3 | 4 | 5 | class Post(models.Model): 6 | author = models.ForeignKey('auth.User', 7 | on_delete=models.CASCADE) 8 | title = models.CharField(max_length=200) 9 | text = models.TextField() 10 | created_date = models.DateTimeField(default=timezone.now) 11 | published_date = models.DateTimeField(blank=True, null=True) 12 | 13 | def publish(self): 14 | self.published_date = timezone.now() 15 | self.save() 16 | 17 | def __str__(self): 18 | return self.title 19 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import include, url 2 | from . import views 3 | 4 | urlpatterns = [ 5 | url(r'^$', views.post_list), 6 | url(r'^post/(?P[0-9]+)/$', views.post_detail, name='post_detail'), 7 | ] 8 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/blog/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, get_object_or_404 2 | from .models import Post 3 | from django.utils import timezone 4 | 5 | 6 | def post_list(request): 7 | posts = Post.objects.filter(published_date__lte=timezone.now()).order_by("published_date") 8 | return render(request, 'post_list.html', {'posts': posts}) 9 | 10 | 11 | class Foo: 12 | ham = 'spam' 13 | 14 | def answer(self): 15 | return 42 16 | 17 | def post_detail(request, pk): 18 | post = get_object_or_404(Post, pk=pk) 19 | ctx = { 20 | 'post' : post, 21 | 'my_dict': {'foo': 'bar', 'answer': 42}, 22 | 'foo': Foo() 23 | } 24 | return render(request, 'post_detail.html', ctx) 25 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/db.sqlite3 -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/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", "mysite.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/mysite/__init__.py -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/mysite/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/__pycache__/jinja2.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/mysite/__pycache__/jinja2.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/__pycache__/settings.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/mysite/__pycache__/settings.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/__pycache__/urls.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/mysite/__pycache__/urls.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/__pycache__/wsgi.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/mysite/__pycache__/wsgi.cpython-36.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/jinja2.py: -------------------------------------------------------------------------------- 1 | from django.contrib.staticfiles.storage import staticfiles_storage 2 | from django.urls import reverse 3 | 4 | from jinja2 import Environment 5 | 6 | 7 | def environment(**options): 8 | env = Environment(**options) 9 | env.globals.update({ 10 | 'static': staticfiles_storage.url, 11 | 'url': reverse, 12 | 'the_answer': lambda: 42, 13 | }) 14 | env.filters.update({ 15 | 'UPPER': lambda x: x.upper(), 16 | 'plus': lambda x, y: x + y, 17 | 18 | }) 19 | return env -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for mysite project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.10.6. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.10/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'espyz4*e3b8sy_r+hl5^nn_0@w=09t=iv8dq&2o8!k-j9kt' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'blog', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'mysite.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.jinja2.Jinja2', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'environment': 'mysite.jinja2.environment', 62 | }, 63 | }, 64 | { 65 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 66 | 'DIRS': [], 67 | 'APP_DIRS': True, 68 | 'OPTIONS': { 69 | 'context_processors': [ 70 | 'django.template.context_processors.debug', 71 | 'django.template.context_processors.request', 72 | 'django.contrib.auth.context_processors.auth', 73 | 'django.contrib.messages.context_processors.messages', 74 | ], 75 | }, 76 | }, 77 | 78 | ] 79 | 80 | WSGI_APPLICATION = 'mysite.wsgi.application' 81 | 82 | 83 | # Database 84 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 85 | 86 | DATABASES = { 87 | 'default': { 88 | 'ENGINE': 'django.db.backends.sqlite3', 89 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 90 | } 91 | } 92 | 93 | 94 | # Password validation 95 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 96 | 97 | AUTH_PASSWORD_VALIDATORS = [ 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 100 | }, 101 | { 102 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 103 | }, 104 | { 105 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 106 | }, 107 | { 108 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 109 | }, 110 | ] 111 | 112 | 113 | # Internationalization 114 | # https://docs.djangoproject.com/en/1.10/topics/i18n/ 115 | 116 | LANGUAGE_CODE = 'pt-br' 117 | 118 | TIME_ZONE = 'America/Sao_Paulo' 119 | 120 | USE_I18N = True 121 | 122 | USE_L10N = True 123 | 124 | USE_TZ = True 125 | 126 | 127 | # Static files (CSS, JavaScript, Images) 128 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 129 | 130 | STATIC_URL = '/static/' 131 | STATIC_ROOT = os.path.join(BASE_DIR, 'static') 132 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/urls.py: -------------------------------------------------------------------------------- 1 | """mysite URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.10/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url, include 17 | from django.contrib import admin 18 | 19 | 20 | urlpatterns = [ 21 | url(r'^admin/', admin.site.urls), 22 | url(r'', include('blog.urls')) 23 | ] 24 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/mysite/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mysite 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/1.10/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", "mysite.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/tests/__pycache__/test_post.cpython-36-PYTEST.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/antigo/djangogirls/mysite/tests/__pycache__/test_post.cpython-36-PYTEST.pyc -------------------------------------------------------------------------------- /antigo/djangogirls/mysite/tests/test_post.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.models import User 2 | from blog.models import Post 3 | import pytest 4 | 5 | 6 | @pytest.fixture 7 | def user(db): 8 | user = User(username='foo', email='foo@bar.com', first_name='joao', 9 | last_name='silva') 10 | 11 | 12 | def test_can_make_post(db, user): 13 | post = Post( 14 | user=user, 15 | title='teset', 16 | text='dsfsdf sdfs d', 17 | ) 18 | post.save() 19 | -------------------------------------------------------------------------------- /antigo/trabalhos/EP1.rst: -------------------------------------------------------------------------------- 1 | Hello Django 2 | ============ 3 | 4 | Trabalho: EP1 5 | Nota: 0,5 pts 6 | Integrantes: trabalho individual 7 | Data de entrega: 29/03/2017 8 | 9 | Descrição 10 | --------- 11 | 12 | O trabalho consiste em implementar um aplicativo Django simples em nível de 13 | tutorial. O aluno pode escolher algumas das opções abaixo (ou sugerir uma 14 | alternativa combinada com antecedência com o professor): 15 | 16 | * Sistema de votações (estilo o app polls no tutorial do Django) 17 | * Microblog 18 | * Cadastro/pesquisa de produtos 19 | * Aplicação tipo pastebin 20 | * ... 21 | 22 | O aplicativo inicial será avaliado em algumas frentes. Neste momento não 23 | avaliaremos frontend, portanto HTML/CSS/Javascript valem 0 pontos. Faça somente 24 | um frontend mínimo que mostre a funcionalidade, não precisa ser bonito :) 25 | 26 | O aplicativo deve implementar as funcionalidades abaixo: 27 | 28 | * 0,1 pts - Definição de modelos no ORM do Django 29 | * 0,1 pts - Utilização de templates para reaproveitar HTML (Django ou Jinja2) 30 | * 0,1 pts - Interface de admnistração 31 | * 0,1 pts - Urls e views públicas para usuários comuns 32 | * 0,1 pts - Qualidade geral do código (docstrings, estilo, boas práticas, etc) 33 | 34 | Cada aspecto será avaliado como bom (0,1 pts), médio (0,05 pts) ou ruim (0,0 pts). 35 | Os aplicativos devem ser impementados na última versão do Django (1.10) e em 36 | Python 3. Todos os trabalhos serão públicos no respositório da disciplina. 37 | 38 | Entrega 39 | ------- 40 | 41 | A entrega será feita em conjunto no Moodle, Github e PythonAnywhere. Cada aluno 42 | deve possuir uma conta nestes três serviços. O código deve estar disponível em 43 | um repositório público do Github e executando no PythonAnywhere. O Moodle é 44 | utilizado apenas para registrar a entrega do trabalho e apontar os links para 45 | o repositório do Github e o endereço no PythonAnywhere. 46 | 47 | -------------------------------------------------------------------------------- /antigo/trabalhos/EP2.rst: -------------------------------------------------------------------------------- 1 | Testes e manutenção 2 | =================== 3 | 4 | Trabalho: EP2 5 | Nota: 0,5 pts 6 | Integrantes: trabalho individual 7 | Data de entrega: 17/05/2017 8 | 9 | 10 | Descrição 11 | --------- 12 | 13 | O trabalho consiste em montar uma suite de testes + integração contínua para um 14 | projeto Django simples. Idealmente, o projeto escolhido deve ser o mesmo do EP1, 15 | mas você pode mudar de projeto se achar adequado. 16 | 17 | O aplicativo deve implementar as funcionalidades abaixo: 18 | 19 | * 0,1 pts - Implementação de alguns (5+) testes unitários (recomendo utilizar o 20 | pytest, mas vocês podem utilizar outra biblioteca, se preferirem). 21 | * 0,1 pts - Implementar pelo menos 2 testes de aceitação alguma biblioteca de 22 | automação como o Selenium, Letuce, ou Sulfur. 23 | * 0,1 pts - Uso de factories (Factory Boy, Model Mommy, Mommy's Boy, etc) 24 | * 0,1 pts - Configuração do tox + análise de estilo (ex.: flake8) 25 | * 0,1 pts - Cobertura de testes com mais de 85%. (70% ou mais para 0.05 pts). 26 | 27 | Cada aspecto será avaliado como bom (0,1 pts), médio (0,05 pts) ou ruim (0,0 pts). 28 | Os aplicativos devem ser impementados nas últimas versões do Django (1.10+) e em 29 | Python 3. Todos os trabalhos serão públicos no respositório da disciplina. 30 | 31 | 32 | Pontuação extra (estrelas) 33 | -------------------------- 34 | 35 | * 1 estrela - pré-hook de comit que impeça comit de código que quebre algum 36 | teste. Qualquer pré-hook vale a estrela, mas a boa prática diz 37 | para apenas rodar a parte *rápida* da sua suite de 38 | testes. Isto normalmente exclui as partes que interagem com banco 39 | de dados e certamente exclui a parte com os testes de aceitação. 40 | * 2 estrelas - Zero erros do flake8 (pode ignorar testes, migrações e arquivos 41 | __init__.py que façam apenas imports). 42 | * 1 estrela - Utilizar a biblioteca Mock para evitar consultas desnecessárias 43 | ao banco de dados. Deve conter pelo menos 3 testes com mocks. 44 | 45 | Entrega 46 | ------- 47 | 48 | A entrega será feita em conjunto no Moodle, Github. Cada aluno deve possuir uma 49 | nestes três serviços. O código deve estar disponível em 50 | um repositório público do Github e executando no PythonAnywhere. O README do 51 | repositório deve conter a badge do Travis e Codecov (ou serviços equivalentes). 52 | O Moodle é utilizado apenas para registrar a entrega do trabalho e apontar os links para 53 | o repositório do Github e o endereço no PythonAnywhere. 54 | 55 | -------------------------------------------------------------------------------- /antigo/trabalhos/EP3.rst: -------------------------------------------------------------------------------- 1 | Tecnologias de cliente 2 | ====================== 3 | 4 | Trabalho: EP3 5 | Nota: 0,5 pts 6 | Integrantes: trabalho em dupla 7 | Data de entrega: 07/06/2017 8 | 9 | 10 | Descrição 11 | --------- 12 | 13 | O trabalho consiste criar um tutorial para desenvolver um aplicativo simples 14 | utilizando alguma tecnologia de frontend. Tecnologias mais novas serão 15 | compensadas com estrelas. O aplicativo deve ser algo na linha do próximo programa 16 | depois do "Hello World". Dou algumas sugestões abaixo (ou talvez você queira 17 | escolher algo que complemente o EP1): 18 | 19 | * TODO: aplicativo com uma lista de coisas "para fazer". 20 | * Lista de elementos ou tabela reordenável. 21 | * Carrosel de imagens. 22 | * Campo 33 | 34 | 35 | 36 | 37 |
38 |
39 |

About us

40 |

41 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 42 | Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 43 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur 44 | sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 45 |

46 |
47 | 48 |
49 |

Our values

50 |
    51 |
  • 52 | build 53 |

    Tool!

    54 |

    Lorem ipsum dolor sit amet...

    55 |
  • 56 |
  • 57 | face 58 |

    Face

    59 |

    Lorem ipsum dolor sit amet...

    60 |
  • 61 |
  • 62 | fingerprint 63 |

    CSI

    64 |

    Lorem ipsum dolor sit amet...

    65 |
  • 66 |
  • 67 | flight 68 |

    Aero (?)

    69 |

    Lorem ipsum dolor sit amet...

    70 |
  • 71 |
72 |
73 | 74 |
75 |

Testimonials

76 | chevron_left 77 |
    78 |
  • 79 |
    A great company!
    80 |

    John smith

    81 |
  • 82 | 83 |
  • 84 |
    I love their products!
    85 |

    Mary Smith

    86 |
  • 87 | 88 |
  • 89 |
    I will say something so good that you won't believe it is not just marketing!
    90 |

    Smith Son

    91 |
  • 92 | 93 |
94 | chevron_right 95 |
96 |
97 | 98 | 109 | 110 | 111 | 122 | 123 | -------------------------------------------------------------------------------- /exemplos/css/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Links: 4 | - https://css-tricks.com/specifics-on-css-specificity/ 5 | - https://css-tricks.com/snippets/css/a-guide-to-flexbox/ 6 | 7 | */ 8 | .navbar { 9 | background: #34cb2f; 10 | color: white; } 11 | .navbar ul, .navbar li { 12 | list-style: none; 13 | display: inline; } 14 | .navbar .link.foo { 15 | text-decoration: underline; 16 | background: cyan; } 17 | .navbar a { 18 | text-decoration: none; 19 | background: magenta !important; } 20 | .navbar .logo { 21 | font-size: 2em; 22 | font-family: 'Josefin Slab'; } 23 | 24 | .hero { 25 | background: #34cb2f; 26 | text-align: center; } 27 | .hero h1 { 28 | font-family: 'Pacifico', cursive; } 29 | 30 | .remember-me { 31 | background: #2F9CCB; 32 | font-family: 'Pacifico', cursive; 33 | font-family: 'Josefin Slab', serif; 34 | font-family: 'Open Sans', sans-serif; } 35 | 36 | /*# sourceMappingURL=style.css.map */ 37 | -------------------------------------------------------------------------------- /exemplos/css/style.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA;;;;;;GAMG;AAKH,OAAQ;EACJ,UAAU,EAHK,OAAgB;EAI/B,KAAK,EAAE,KAAK;EAEZ,sBAAO;IACH,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,MAAM;EAGnB,iBAAU;IACN,eAAe,EAAE,SAAS;IAC1B,UAAU,EAAE,IAAI;EAGpB,SAAE;IACE,eAAe,EAAE,IAAI;IACrB,UAAU,EAAE,kBAAkB;EAKlC,aAAM;IACF,SAAS,EAAE,GAAG;IACd,WAAW,EAAE,cAAc;;AAInC,KAAM;EACF,UAAU,EA9BK,OAAgB;EA+B/B,UAAU,EAAE,MAAM;EAElB,QAAG;IACC,WAAW,EAAE,mBAAmB;;AAOxC,YAAa;EACT,UAAU,EAAE,OAAO;EACnB,WAAW,EAAE,mBAAmB;EAChC,WAAW,EAAE,qBAAqB;EAClC,WAAW,EAAE,uBAAuB", 4 | "sources": ["style.scss"], 5 | "names": [], 6 | "file": "style.css" 7 | } -------------------------------------------------------------------------------- /exemplos/css/style.scss: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Links: 4 | - https://css-tricks.com/specifics-on-css-specificity/ 5 | - https://css-tricks.com/snippets/css/a-guide-to-flexbox/ 6 | 7 | */ 8 | 9 | // Cor de fundo 10 | $background-color: rgb(52, 203, 47); 11 | 12 | .navbar { 13 | background: $background-color; 14 | color: white; 15 | 16 | ul, li { 17 | list-style: none; 18 | display: inline; 19 | } 20 | 21 | .link.foo { 22 | text-decoration: underline; 23 | background: cyan; 24 | } 25 | 26 | a { 27 | text-decoration: none; 28 | background: magenta !important; 29 | } 30 | 31 | 32 | 33 | .logo { 34 | font-size: 2em; 35 | font-family: 'Josefin Slab'; 36 | } 37 | } 38 | 39 | .hero { 40 | background: $background-color; 41 | text-align: center; 42 | 43 | h1 { 44 | font-family: 'Pacifico', cursive; 45 | } 46 | } 47 | 48 | 49 | 50 | 51 | .remember-me { 52 | background: #2F9CCB; 53 | font-family: 'Pacifico', cursive; 54 | font-family: 'Josefin Slab', serif; 55 | font-family: 'Open Sans', sans-serif; 56 | } -------------------------------------------------------------------------------- /private/prova1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Made with Remarkable! 7 | 8 | 9 | 12 | 13 | 14 |

15 | Prova 1 - Programação Web 16 |

17 |

18 | Questão 1 19 |

20 |

21 | Um dos principais elementos do Django é o seu ORM (Object Relational Mapper) que abstrai o banco de dados e expõe as linhas de uma tabela no banco como um objeto Python. Os modelos abaixo implementam uma aplicação simples do tipo "Twitter" 22 |

23 |
from django.db import models
 24 | 
 25 | class User(models.Model):
 26 |     name = models.CharField(max_size=50)
 27 |     email = models.EmailField()
 28 | 
 29 | class Tweet(models.Model):
 30 |     user = models.ForeignKey(User, related_name='tweets')
 31 |     text = models.TextField()
 32 |     created = models.DateTimeField()
 33 | 
34 |

35 | Responda: 36 |

37 |
    38 |
  1. 39 | Faça um esboço de como seriam as tabelas criadas no banco de dados para os dois modelos acima. Coloque alguns exemplos de usuários e tweets. 40 |
  2. 41 |
  3. 42 | O que significa o campo ForeignKey() utilizado no objeto Tweet? Discuta as vantagens/desvantagens em se utilizar uma chave estrangeira em comparação a uma referência manual ao índice de User utilizando IntegerField, por exemplo. 43 |
  4. 44 |
45 |

46 | Questão 2 47 |

48 |

49 | Responda as questões a respeito de busca em banco de dados: 50 |

51 |
    52 |
  1. 53 | O que são os 54 | 55 | QuerySets 56 | 57 | no Django? 58 |
  2. 59 |
  3. 60 | Como seria a busca de todos os tweets produzidos por um determinado usuário? (Assuma que o usuário em questão é conhecido e salvo na variável 61 | 62 | user 63 | 64 | .) 65 |
  4. 66 |
  5. 67 | Como seria uma busca por todos os tweets de um determinado usuário a partir de uma determinada data? Explique a notação utilizada para fazer isto no Django. (Assuma que tanto o usuário quanto a data já estão disponíveis nas variáveis 68 | 69 | user 70 | 71 | e 72 | 73 | datetime 74 | 75 | .) 76 |
  6. 77 |
78 |

79 | Questão 3 80 |

81 |

82 | Acesso ao banco de dados é um dos principais fatores que influenciam na performance de uma aplicação Web. Suponha que queremos extrair os nomes dos autores e textos dos tweets para cada tweet do banco. As duas buscas abaixo realizam esta operação, mas possuem características de performance diferentes. Discuta qual é a mais eficiente e porquê. 83 |

84 |
# Query 1
 85 | L = [(tweet.user.name, tweet.text) for tweet in Tweet.objects.all()]
 86 | 
 87 | # Query 2
 88 | L = list(Tweet.objects.values_list('user__name', 'text'))
 89 | 
90 |

91 | Questão 4 92 |

93 |

94 | Explique o que são as "views" do Django e como elas se relacionam com as URLs de sua aplicação. Esboce uma view típica que extrai um objeto do banco de dados e renderize uma página correspondente em HTML. 95 |

96 |

97 | Questão 5 98 |

99 |

100 | Uma requisição HTTP é formada por uma linha de verbo + url, cabeçalhos e corpo da mensagem. Explique a distinção entre os verbos GET e POST e descreva algumas situações onde é preferível utilizar um ao outro. 101 |

102 |

103 | Questão 6 104 |

105 |

106 | Defina e explique sucintamente o que são cada uma das tecnologias abaixo e como elas são utilizadas no desenvolvimento de uma aplicação Web. 107 |

108 |
    109 |
  1. 110 | HTML 111 |
  2. 112 |
  3. 113 | CSS 114 |
  4. 115 |
  5. 116 | JavaScript 117 |
  6. 118 |
  7. 119 | HTTP e HTTPS 120 |
  8. 121 |
  9. 122 | SQL 123 |
  10. 124 |
125 |

126 | Questão 7 127 |

128 |

129 | O que são testes unitários? Descreva os principais desafios de escrever testes unitários para aplicações Web. 130 |

131 | 133 | 136 | 138 | 141 | 142 | -------------------------------------------------------------------------------- /private/prova1.md: -------------------------------------------------------------------------------- 1 | Prova 1 - Programação Web 2 | ========================= 3 | 4 |
UnB/Gama - 10/05/2017
5 | 6 | **Nome:** 7 | **Matrícula:** 8 | 9 | ## Questão 1 10 | 11 | Um dos principais elementos do Django é o seu ORM (Object Relational Mapper) que abstrai o banco de dados e expõe as linhas de uma tabela no banco como um objeto Python. Os modelos abaixo implementam uma aplicação simples do tipo "Twitter" 12 | 13 | ```python 14 | from django.db import models 15 | 16 | class User(models.Model): 17 | name = models.CharField(max_size=50) 18 | email = models.EmailField() 19 | 20 | class Tweet(models.Model): 21 | user = models.ForeignKey(User, related_name='tweets') 22 | text = models.TextField() 23 | created = models.DateTimeField() 24 | ``` 25 | 26 | Responda: 27 | 28 | 1. Faça um esboço de como seriam as tabelas criadas no banco de dados para os dois modelos acima. Coloque alguns exemplos de usuários e tweets. 29 | 2. O que significa o campo ForeignKey() utilizado no objeto Tweet? Discuta as vantagens/desvantagens em se utilizar uma chave estrangeira em comparação a uma referência manual ao índice de User utilizando IntegerField, por exemplo. 30 | 31 | 32 | ## Questão 2 33 | 34 | Responda as questões a respeito de busca em banco de dados: 35 | 36 | 1. O que são os `QuerySets` no Django? 37 | 2. Como seria a busca de todos os tweets produzidos por um determinado usuário? (Assuma que o usuário em questão é conhecido e salvo na variável `user`.) 38 | 3. Como seria uma busca por todos os tweets de um determinado usuário a partir de uma determinada data? Explique a notação utilizada para fazer isto no Django. (Assuma que tanto o usuário quanto a data já estão disponíveis nas variáveis `user` e `datetime`.) 39 | 40 | 41 | ## Questão 3 42 | 43 | Acesso ao banco de dados é um dos principais fatores que influenciam na performance de uma aplicação Web. Suponha que queremos extrair os nomes dos autores e textos dos tweets para cada tweet do banco. As duas buscas abaixo realizam esta operação, mas possuem características de performance diferentes. Discuta qual é a mais eficiente e porquê. 44 | 45 | ```python 46 | # Query 1 47 | L = [(tweet.user.name, tweet.text) for tweet in Tweet.objects.all()] 48 | 49 | # Query 2 50 | L = list(Tweet.objects.values_list('user__name', 'text')) 51 | ``` 52 | 53 | 54 | ## Questão 4 55 | 56 | Explique o que são as "views" do Django e como elas se relacionam com as URLs de sua aplicação. Esboce uma view típica que extrai um objeto do banco de dados e renderize uma página correspondente em HTML. 57 | 58 | 59 | ## Questão 5 60 | 61 | Uma requisição HTTP é formada por uma linha de verbo + url, cabeçalhos e corpo da mensagem. Explique a distinção entre os verbos GET e POST e descreva algumas situações onde é preferível utilizar um ao outro. 62 | 63 | 64 | ## Questão 6 65 | 66 | Defina e explique sucintamente o que são cada uma das tecnologias abaixo e como elas são utilizadas no desenvolvimento de uma aplicação Web. 67 | 68 | 1. HTML 69 | 2. CSS 70 | 3. JavaScript 71 | 4. HTTP e HTTPS 72 | 5. SQL 73 | 74 | 75 | ## Questão 7 76 | 77 | O que são testes unitários? Descreva os principais desafios de escrever testes unitários para aplicações Web. -------------------------------------------------------------------------------- /private/prova1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/private/prova1.pdf -------------------------------------------------------------------------------- /provas/prova1/pastebin/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/db.sqlite3 -------------------------------------------------------------------------------- /provas/prova1/pastebin/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", "pastebin_project.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 | -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin/__init__.py -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/__pycache__/admin.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin/__pycache__/admin.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/__pycache__/models.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin/__pycache__/models.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/__pycache__/urls.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin/__pycache__/urls.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/__pycache__/views.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin/__pycache__/views.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class PastebinConfig(AppConfig): 5 | name = 'pastebin' 6 | -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/jinja2/pastebin/index.jinja2: -------------------------------------------------------------------------------- 1 | {% extends 'base.jinja2' %} 2 | 3 | {% block header %} 4 |
5 |

{{ title }}

6 |
7 | {% endblock %} 8 | 9 | {% block main %} 10 |
11 |

Questao 1

12 |

Deve mostrar um formulário em que o usuário pode criar um novo 13 | paste.

14 |

Cada paste deve conter um título, uma linguagem e o conteúdo.

15 |

Linguagens reconhecidas: Python, Javascript e Outros

16 |

Existem questões ocultas! Procure no código

17 |
18 | {% endblock %} -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/jinja2/pastebin/paste-detail.jinja2: -------------------------------------------------------------------------------- 1 | {% extends 'base.jinja2' %} 2 | 3 | {% block header %} 4 |
5 |

{{ title }}

6 |
7 | {% endblock %} 8 | 9 | {% block main %} 10 |
11 |

Questão 2

12 |

Conteúdo do Paste.

13 | 18 |
19 | {% endblock %} -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/jinja2/pastebin/paste-language.jinja2: -------------------------------------------------------------------------------- 1 | {% extends 'base.jinja2' %} 2 | 3 | {% block header %} 4 |
5 |

Lista de pastes ({{ language }})

6 |
7 | {% endblock %} 8 | 9 | {% block main %} 10 |
11 |

Lista de pastes

12 | 17 |

Questão 6

18 |

O template está pronto! Corrija a view e as models!

19 |

Deve mostrar todos os pastes da mesma linguagem

20 |
21 | {% endblock %} -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin/migrations/__init__.py -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/migrations/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin/migrations/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | 5 | urlpatterns = [ 6 | path('', views.index, name='pastebin-index'), 7 | path('/', views.language_list, name='pastebin-language'), 8 | path('pastes//', views.paste, name='pastebin-detail'), 9 | ] 10 | -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render, get_object_or_404 2 | 3 | 4 | def index(request): 5 | ctx = {} 6 | return render(request, 'pastebin/index.jinja2', ctx) 7 | 8 | 9 | def paste(request, id): 10 | ctx = {} 11 | return render(request, 'pastebin/paste-detail.jinja2', ctx) 12 | 13 | 14 | def language_list(request, language): 15 | ctx = {'pastes': []} 16 | return render(request, 'pastebin/paste-language.jinja2', ctx) -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin_project/__init__.py -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin_project/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/__pycache__/jinja2.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin_project/__pycache__/jinja2.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/__pycache__/settings.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin_project/__pycache__/settings.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/__pycache__/urls.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin_project/__pycache__/urls.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/__pycache__/views.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin_project/__pycache__/views.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/__pycache__/wsgi.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin_project/__pycache__/wsgi.cpython-36.pyc -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/jinja2.py: -------------------------------------------------------------------------------- 1 | from django.contrib.staticfiles.storage import staticfiles_storage 2 | from django.urls import reverse 3 | 4 | from jinja2 import Environment 5 | 6 | 7 | def environment(**options): 8 | env = Environment(**options) 9 | env.globals.update({ 10 | 'static': staticfiles_storage.url, 11 | 'url': reverse, 12 | }) 13 | return env 14 | -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/jinja2/base.jinja2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {% block title %}{{ title|default('Pastebin') }}{% endblock %} 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | {% block header %} 22 |
23 |

Hello world! Please override the header block in your Jinja2 template!

24 |

25 | {% endblock %} 26 | 27 | {% block breadcrumbs %} 28 |
29 | Python 30 | Javascript 31 | Outros 32 |
33 | {% endblock%} 34 | 35 | {% block main %} 36 |
37 |

Hello world! Please override the content block in your Jinja2 template!

38 |
39 | {% endblock %} 40 | 41 | {% block footer %} 42 |
43 |

Footer que deve aparecer apenas no modo desktop!

44 |
45 | {% endblock %} 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/jinja2/static.jinja2: -------------------------------------------------------------------------------- 1 | {% extends 'base.jinja2' %} 2 | 3 | {% block header %} 4 |
5 |

Questão {{ number }}

6 |
7 | {% endblock %} 8 | 9 | {% block main %} 10 |
11 |

{{ title }}

12 |
{{text}}
13 | 14 |

Dica: Salve um paste com o título {{ paste_title }} no banco da sua 15 | aplicação. Esta é a resposta! (não coloque o banco no gitignore)

16 | 17 |

Solução: {{ paste_title }}

18 |
{{ paste_data }}
19 |
20 | {% endblock %} -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 4 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 5 | 6 | 7 | # Quick-start development settings - unsuitable for production 8 | # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ 9 | 10 | # SECURITY WARNING: keep the secret key used in production secret! 11 | SECRET_KEY = '=ipva^%0u%anld)vw*#r6&yq9r6+@vleu87jj8x=%gr_x7#h02' 12 | 13 | # SECURITY WARNING: don't run with debug turned on in production! 14 | DEBUG = True 15 | 16 | ALLOWED_HOSTS = [] 17 | 18 | 19 | # Application definition 20 | 21 | INSTALLED_APPS = [ 22 | 'pastebin', 23 | 'django.contrib.admin', 24 | 'django.contrib.auth', 25 | 'django.contrib.contenttypes', 26 | 'django.contrib.sessions', 27 | 'django.contrib.messages', 28 | 'django.contrib.staticfiles', 29 | ] 30 | 31 | MIDDLEWARE = [ 32 | 'django.middleware.security.SecurityMiddleware', 33 | 'django.contrib.sessions.middleware.SessionMiddleware', 34 | 'django.middleware.common.CommonMiddleware', 35 | 'django.middleware.csrf.CsrfViewMiddleware', 36 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 37 | 'django.contrib.messages.middleware.MessageMiddleware', 38 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 39 | ] 40 | 41 | ROOT_URLCONF = 'pastebin_project.urls' 42 | 43 | TEMPLATES = [ 44 | { 45 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 46 | 'DIRS': [], 47 | 'APP_DIRS': True, 48 | 'OPTIONS': { 49 | 'context_processors': [ 50 | 'django.template.context_processors.debug', 51 | 'django.template.context_processors.request', 52 | 'django.contrib.auth.context_processors.auth', 53 | 'django.contrib.messages.context_processors.messages', 54 | ], 55 | }, 56 | }, 57 | { 58 | 'BACKEND': 'django.template.backends.jinja2.Jinja2', 59 | 'DIRS': ['pastebin_project/jinja2/'], 60 | 'APP_DIRS': True, 61 | 'OPTIONS': { 62 | 'environment': 'pastebin_project.jinja2.environment', 63 | }, 64 | }, 65 | ] 66 | 67 | WSGI_APPLICATION = 'pastebin_project.wsgi.application' 68 | 69 | 70 | # Database 71 | # https://docs.djangoproject.com/en/2.0/ref/settings/#databases 72 | 73 | DATABASES = { 74 | 'default': { 75 | 'ENGINE': 'django.db.backends.sqlite3', 76 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 77 | } 78 | } 79 | 80 | 81 | # Password validation 82 | # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators 83 | 84 | AUTH_PASSWORD_VALIDATORS = [ 85 | { 86 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 87 | }, 88 | { 89 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 90 | }, 91 | { 92 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 93 | }, 94 | { 95 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 96 | }, 97 | ] 98 | 99 | 100 | # Internationalization 101 | # https://docs.djangoproject.com/en/2.0/topics/i18n/ 102 | 103 | LANGUAGE_CODE = 'pt-br' 104 | 105 | TIME_ZONE = 'America/Sao_Paulo' 106 | 107 | USE_I18N = True 108 | 109 | USE_L10N = True 110 | 111 | USE_TZ = True 112 | 113 | 114 | # Static files (CSS, JavaScript, Images) 115 | # https://docs.djangoproject.com/en/2.0/howto/static-files/ 116 | 117 | STATIC_URL = '/static/' 118 | STATIC_ROOT = os.path.join(BASE_DIR, 'collect') 119 | STATICFILES_DIRS = [ 120 | os.path.join(BASE_DIR, 'pastebin_project', 'static'), 121 | '/var/www/static/', 122 | ] -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/static/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: white; 3 | margin: 0; 4 | padding: 9; 5 | font-family: Roboto, sans; 6 | min-height: 100vh; 7 | display: flex; 8 | flex-flow: column; 9 | align-items: stretch; 10 | } 11 | 12 | 13 | header h1 { 14 | font-size: 1.5em; 15 | font-weight: bold; 16 | background: rgb(21, 207, 198); 17 | color: white; 18 | box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.2); 19 | padding: 15px; 20 | margin: 0 0 30px 0; 21 | } 22 | 23 | main { 24 | flex-grow: 1; 25 | } 26 | 27 | .paste-detail { 28 | font-family: monospace; 29 | padding: 20px; 30 | max-width: 800px; 31 | margin: 0 auto; 32 | } 33 | 34 | footer { 35 | background: rgb(21, 207, 198); 36 | box-shadow: 0 -2px 5px 0 rgba(0, 0, 0, 0.2); 37 | color: white; 38 | padding: 30px; 39 | text-align: center; 40 | } 41 | 42 | @media only screen and (max-width: 500px) { 43 | footer { 44 | display: none; 45 | } 46 | } -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/static/js/main.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fabiommendes/progweb/2fbca21fbe361ef4a0e1d63999d56fe21475e79a/provas/prova1/pastebin/pastebin_project/static/js/main.js -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import path, include 3 | from django.conf import settings 4 | from django.conf.urls.static import static 5 | from . import views 6 | 7 | 8 | urlpatterns = [ 9 | path('admin/', admin.site.urls), 10 | path('questao/', views.question_view), 11 | path('', include('pastebin.urls')), 12 | ] 13 | 14 | urlpatterns.extend( 15 | static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) 16 | ) 17 | -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | 4 | def question_view(request, i): 5 | paste_title = 'questao_%s' % i 6 | ctx = { 7 | 'number': i, 8 | 'text': questions[i]['text'], 9 | 'title': questions[i]['title'], 10 | 'paste_title': paste_title, 11 | } 12 | try: 13 | from pastebin.models import Paste 14 | paste = Paste.objects.get(title=paste_title) 15 | ctx['paste_data'] = paste.title 16 | except: 17 | ctx['paste_data'] = ('Seu model deve se chamar Paste e você deve fazer ' 18 | 'um paste com o título %r.' % paste_title) 19 | return render(request, 'static.jinja2', ctx) 20 | 21 | 22 | questions = { 23 | 3: { 24 | 'title': 'CSS', 25 | 'text': ''' 26 | (a) Discuta o que significa a filosofia de desenvolvimento "Mobile First". 27 | Discuta os aspectos técnicos com relação às implicações no HTML, CSS e 28 | Javascript. 29 | 30 | (b) Nosso site possui um footer responsivo. Ele é mobile first? Justifique. 31 | Caso não seja, explique como consertaríamos o problema. 32 | ''', 33 | }, 34 | 35 | 4: { 36 | 'title': 'Problema N + 1', 37 | 'text': ''' 38 | (a) O que é o problema N + 1 que aparece comumente em ORMs? Todos os ORMs estão 39 | necessariamente sujeitos a este problema ou existem meios de contorná-los? 40 | 41 | (b) Nosso app não está vulnerável ao problema porque não utiliza de nenhuma 42 | chave estrangeira. Suponha que o modelo de Paste possua uma referência para 43 | User. Como o problema apareceria e como poderíamos contorná-lo? 44 | ''', 45 | }, 46 | 47 | 48 | 5: { 49 | 'title': 'Converta de Python para Javascript', 50 | 'text': ''' 51 | 52 | class Person: 53 | def __init__(self, name, age): 54 | self.name = name 55 | self.age = age 56 | 57 | def is_adult(self): 58 | return self.age >= 18 59 | 60 | people = [Person('Joao', 21), Person('Maria', 20), Person('Zé', 8)] 61 | adults = [x for x in people if x.is_adult()] 62 | mean_age = sum(x.age for x in adults) / len(adults) 63 | ''', 64 | }, 65 | } -------------------------------------------------------------------------------- /provas/prova1/pastebin/pastebin_project/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for pastebin 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/2.0/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", "pastebin.settings") 15 | 16 | application = get_wsgi_application() 17 | --------------------------------------------------------------------------------