-
- A aplicação
-
-
- Um sistema de atas de reunião onde as atas
- são arquivos MarkDown, com a data no nome.
-
-
-
-
-
-
- Estrutura de diretórios
-
- ├── ata
+
+
+ Motivação
+
+
+ - Flask é super simples, mas poderoso.
+ - Python é super simples, mas poderoso.
+ - Ninguém fala como é colocar isso em produção.
+
+
+
+
+
+
+
+
+ A aplicação
+
+
+ Um sistema de atas de reunião onde as atas
+ são arquivos MarkDown, com a data no nome.
+
+
+
+
+
+
+ Estrutura de diretórios
+
+ ├── ata
│ ├── defaults.py
│ ├── __init__.py
│ ├── main.py
@@ -164,116 +164,498 @@
├── contents
│ └── 2017-10-31.md
└── requirements.txt
-
-
-
- ├── ata
-
- Módulo/fontes.
-
-
-
-
-
- │ ├── defaults.py
-
- Valores default da aplicação.
-
-
-
-
-
- │ ├── __init__.py
-
-
- __init__.py
é necessário
- para indicar ao Python que o diretório
- pode se lido.
-
-
-
-
- │ ├── main.py
-
- O arquivo inicial da aplicação.
-
-
-
-
-
- │ ├── static
-
-
- Arquivos estáticos.
-
-
-
-
-
-
- │ └── templates
-
-
- Arquivos de template.
-
-
-
-
-
-
- ├── contents
-
-
- Onde o conteúdo a ser apresentado está.
-
-
-
-
-
-
- └── requirements.txt
-
-
- Dependências do projeto.
-
-
-
-
-
+
+
+
+ ├── ata
+
+ Módulo/fontes.
+
+
+
+
+
+ │ ├── defaults.py
+
+ Valores default da aplicação.
+
+
+
+
+
+ │ ├── __init__.py
+
+
+ __init__.py
é necessário
+ para indicar ao Python que o diretório
+ pode se lido.
+
+
+
+
+ │ ├── main.py
+
+ O arquivo inicial da aplicação.
+
+
+
+
+
+ │ ├── static
+
+
+ Arquivos estáticos.
+
+
+
+
+
+
+ │ └── templates
+
+
+ Arquivos de template.
+
+
+
+
+
+
+ ├── contents
+
+
+ Onde o conteúdo a ser apresentado está.
+
+
+
+
+
+
+ └── requirements.txt
+
+
+ Dependências do projeto.
+
+
+
+
+
+
+ main.py
+ Imports
+
+ import os
+import os.path
+
+import markdown
+
+from flask import Flask
+from flask import render_template
+
+
+
+
+
+ main.py
+ A App
+
+ app = Flask(__name__)
+
+
+
+
+
+ main.py
+ Configuração
+
+ app.config.from_object('ata.defaults')
+app.config.from_envvar('ATA_SETTINGS', silent=True)
+
+
+
+
+
+ main.py
+ A primeira rota.
+
+ @app.route('/')
+def index():
+
+
+
+
+
+ main.py
+ O índice
+
+ content = os.listdir(app.config['STORAGE'])
+ data = []
+ for entry in sorted(content, reverse=True):
+ app.logger.debug('Found %s', entry)
+ if not entry.endswith('.md'):
+ continue
+
+ with open(os.path.join(app.config['STORAGE'], entry)) as origin:
+ content = origin.read()
+ output = markdown.markdown(content)
+ try:
+ first_paragraph_end = output.index('')
+ paragraph = output[:first_paragraph_end]
+ except ValuError:
+ paragraph = output
+
+ entry_name = entry[:entry.find('.md')]
+ data.append((entry_name, output))
+
+ return render_template('index.html', data=data)
+
+
+
+
+
+ main.py
+ Entradas específicas
+
+ @app.route('/<entry_name>')
+def show_entry(entry_name):
+ filename = os.path.join(app.config['STORAGE'], entry_name + '.md')
+ with open(filename) as origin:
+ content = origin.read()
+ output = markdown.markdown(content)
+
+ return render_template('entry.html', output=output,
+ entry=entry_name)
+
+
+
+
+
+ main.py
+ Tratamento de erros.
+
+ @app.errorhandler(404)
+def page_not_found():
+ return render_template('page_not_found.html')
+
+
+
+
+
+ main.py
+ Tratamento de erros
+
+ @app.errorhandler(FileNotFoundError)
+def entry_not_found(_):
+ return render_template('entry_not_found.html')
+
+
+
+
+
+ templates
+ layout.html
+
+ <!doctype html>
+<html>
+ <head>
+ <title>Atas de Reunião</title>
+ <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
+ </head>
+
+ <body>
+ <h1 id='header'>
+ Atas de reuniao
+ </h1>
+ {% block maincontent %}{% endblock %}
+ </body>
+</html>
+
+
+
+
+
+ templates
+ index.html
+
+ {% extends "layout.html" %}
+{% block maincontent %}
+ <div class='entry'>
+ {% for entry, text in data %}
+ <a href="{{ url_for('show_entry', entry_name=entry) }}">{{ entry }}</a>
+ {{ text|safe }}
+ {% endfor %}
+ </div>
+{% endblock %}
+
+
+
+
+
+ templates
+ entry.html
+
+ {% extends "layout.html" %}
+{% block maincontent %}
+ <div class="entry">
+ <div class="title">{{ entry }}</div>
+ {{ output|safe }}
+ </div>
+{% endblock %}
+
+
+
+
+
+ templates
+ page_not_found.html
+
+ {% extends "layout.html" %}
+{% block maincontent %}
+ <h2>Page not found</h2>
+{% endblock %}
+
+
+
+
+
+ templates
+ entry_not_found.html
+
+ {% extends "layout.html" %}
+{% block maincontent %}
+ <h2>Entry not found</h2>
+{% endblock %}
+
+
+