diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..4d4e890
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "livePreview.defaultPreviewPath": "/exemplos/day1/pagina.html"
+}
\ No newline at end of file
diff --git a/exemplos/day1/blog/blog.db b/exemplos/day1/blog/blog.db
new file mode 100644
index 0000000..6b440c4
Binary files /dev/null and b/exemplos/day1/blog/blog.db differ
diff --git a/exemplos/day1/blog/database.py b/exemplos/day1/blog/database.py
new file mode 100644
index 0000000..06d244d
--- /dev/null
+++ b/exemplos/day1/blog/database.py
@@ -0,0 +1,54 @@
+# 1 - conectamos ao banco de dados
+from sqlite3 import connect
+
+conn = connect("blog.db")
+cursor = conn.cursor()
+
+# 2 - Criamos a tabela caso não exista
+conn.execute(
+ """\
+ CREATE TABLE if not exists post (
+ id integer PRIMARY KEY AUTOINCREMENT,
+ title varchar UNIQUE NOT NULL,
+ content varchar NOT NULL,
+ author varchar NOT NULL
+ );
+ """
+)
+
+# 3 - Criamos os posts iniciais para alimentar o banco de dados
+posts = [
+ {
+ "title": "Python é eleita a linguagem mais popular",
+ "content": """\
+ A linguem Python foi eleita a linguagem mais popular pela revista
+ tech masters e segue dominando o mundo.
+ """,
+ "author": "Satoshi Namamoto",
+ },
+ {
+ "title": "Como criar um blog utilizando Python",
+ "content": """\
+ Neste tutorial você aprenderá como criar um blog utilizando Python.
+
import make_a_blog
+ """,
+ "author": "Guido Van Rossum",
+ },
+]
+
+
+# 4 - Inserimos os posts caso o banco de dados esteja vazio
+count = cursor.execute("SELECT * FROM post;").fetchall()
+if not count:
+ cursor.executemany(
+ """\
+ INSERT INTO post (title, content, author)
+ VALUES (:title, :content, :author);
+ """,
+ posts,
+ )
+ conn.commit()
+
+# 5 - Verificamos que foi realmente inserido
+posts = cursor.execute("SELECT * FROM post;").fetchall()
+assert len(posts) >= 2
diff --git a/exemplos/day1/blog/form.template.html b/exemplos/day1/blog/form.template.html
new file mode 100644
index 0000000..aa1daf6
--- /dev/null
+++ b/exemplos/day1/blog/form.template.html
@@ -0,0 +1,19 @@
+
+
+
+
+ Blog
+
+
+ New Post
+
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog/list.template.html b/exemplos/day1/blog/list.template.html
new file mode 100644
index 0000000..fb57226
--- /dev/null
+++ b/exemplos/day1/blog/list.template.html
@@ -0,0 +1,13 @@
+
+
+
+
+ Blog
+
+
+ Blog Posts:
+
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog/post.template.html b/exemplos/day1/blog/post.template.html
new file mode 100644
index 0000000..6aa3ac6
--- /dev/null
+++ b/exemplos/day1/blog/post.template.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Blog
+
+
+ {post[title]}
+
+
+ {post[content]}
+
+
+ {post[author]}
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog/render.py b/exemplos/day1/blog/render.py
new file mode 100644
index 0000000..5c65c5e
--- /dev/null
+++ b/exemplos/day1/blog/render.py
@@ -0,0 +1,38 @@
+from pathlib import Path
+from database import conn
+
+# 1 - Obtemos os posts do banco de dados e deserializamos em um dict
+cursor = conn.cursor()
+fields = ("id", "title", "content", "author")
+results = cursor.execute("SELECT * FROM post;")
+posts = [dict(zip(fields, post)) for post in results]
+
+# 2 - Criamos a pasta de destino do site
+site_dir = Path("site")
+site_dir.mkdir(exist_ok=True)
+
+# 3 - Criamos uma função capaz de gerar a url de um post
+def get_post_url(post):
+ slug = post["title"].lower().replace(" ", "-")
+ return f"{slug}.html"
+
+
+# 3 - Renderizamos o a página `index.html` a partir do template.
+index_template = Path("list.template.html").read_text()
+index_page = site_dir / Path("index.html")
+post_list = [
+ f"{post['title']} "
+ for post in posts
+]
+index_page.write_text(index_template.format(post_list="\n".join(post_list)))
+
+# 4 - Renderizamos todas as páginas para cada post partir do template.
+for post in posts:
+ post_template = Path("post.template.html").read_text()
+ post_page = site_dir / Path(get_post_url(post))
+ post_page.write_text(post_template.format(post=post))
+
+print("Site generated at", site_dir)
+
+# 5 - fechamos a conexão
+conn.close()
diff --git a/exemplos/day1/blog/site/como-criar-um-blog-utilizando-python..html b/exemplos/day1/blog/site/como-criar-um-blog-utilizando-python..html
new file mode 100644
index 0000000..51ede2b
--- /dev/null
+++ b/exemplos/day1/blog/site/como-criar-um-blog-utilizando-python..html
@@ -0,0 +1,18 @@
+
+
+
+
+ Blog
+
+
+ Como criar um blog utilizando Python.
+
+
+ Neste tutorial você aprenderá como criar um blog utilizando Python.
+
import make_a_blog
+
+
+
+ Guido Van Rossum
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog/site/index.html b/exemplos/day1/blog/site/index.html
new file mode 100644
index 0000000..6778573
--- /dev/null
+++ b/exemplos/day1/blog/site/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+ Blog
+
+
+ Blog Posts:
+
+
+
\ No newline at end of file
diff --git "a/exemplos/day1/blog/site/python-\303\251-eleita-a-linguagem-mais-popular..html" "b/exemplos/day1/blog/site/python-\303\251-eleita-a-linguagem-mais-popular..html"
new file mode 100644
index 0000000..87ad542
--- /dev/null
+++ "b/exemplos/day1/blog/site/python-\303\251-eleita-a-linguagem-mais-popular..html"
@@ -0,0 +1,18 @@
+
+
+
+
+ Blog
+
+
+ Python é eleita a linguagem mais popular.
+
+
+ A linguem Python foi eleita a linguagem mais popular pela revista
+ tech masters e segue dominando o mundo.
+
+
+
+ Satoshi Namamoto
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog/wsgi.py b/exemplos/day1/blog/wsgi.py
new file mode 100644
index 0000000..079e307
--- /dev/null
+++ b/exemplos/day1/blog/wsgi.py
@@ -0,0 +1,86 @@
+import cgi
+from pathlib import Path
+from database import conn
+
+
+def add_new_post(post):
+ cursor = conn.cursor()
+ cursor.execute(
+ """\
+ INSERT INTO post (title, content, author)
+ VALUES (:title, :content, :author);
+ """,
+ post,
+ )
+ conn.commit()
+
+
+def render_template(template_name, **context):
+ template = Path(template_name).read_text()
+ return template.format(**context).encode("utf-8")
+
+
+def get_posts_from_database(post_id=None):
+ cursor = conn.cursor()
+ fields = ("id", "title", "content", "author")
+
+ if post_id:
+ results = cursor.execute("SELECT * FROM post WHERE id = ?;", post_id)
+ else:
+ results = cursor.execute("SELECT * FROM post;")
+
+ return [dict(zip(fields, post)) for post in results]
+
+
+def get_post_list(posts):
+ post_list = [
+ f"""{post['title']} """
+ for post in posts
+ ]
+ return "\n".join(post_list)
+
+
+def application(environ, start_response):
+ path = environ["PATH_INFO"]
+ method = environ["REQUEST_METHOD"]
+ body = b"Content Not Found"
+ status = "404 Not Found"
+
+ if path == "/" and method == "GET":
+ posts = get_posts_from_database()
+ body = render_template(
+ "list.template.html", post_list=get_post_list(posts)
+ )
+ status = "200 OK"
+
+ elif path.split("/")[-1].isdigit() and method == "GET":
+ post_id = path.split("/")[-1]
+ body = render_template(
+ "post.template.html",
+ post=get_posts_from_database(post_id=post_id)[0],
+ )
+ status = "200 OK"
+
+ elif path == "/new" and method == "POST":
+ form = cgi.FieldStorage(
+ fp=environ["wsgi.input"], environ=environ, keep_blank_values=1
+ )
+ post = {item.name: item.value for item in form.list}
+ add_new_post(post)
+ body = b"New post Created with Success!"
+ status = "201 Created"
+
+ elif path == "/new" and method == "GET":
+ body = render_template("form.template.html")
+ status = "200 OK"
+
+ headers = [("Content-type", "text/html")]
+ start_response(status, headers)
+ return [body]
+
+
+if __name__ == "__main__":
+ from wsgiref.simple_server import make_server
+
+ server = make_server("0.0.0.0", 8000, application)
+ server.serve_forever()
diff --git a/exemplos/day1/blog_framework/blog.db b/exemplos/day1/blog_framework/blog.db
new file mode 100644
index 0000000..4c4ad4d
Binary files /dev/null and b/exemplos/day1/blog_framework/blog.db differ
diff --git a/exemplos/day1/blog_framework/database.py b/exemplos/day1/blog_framework/database.py
new file mode 100644
index 0000000..06d244d
--- /dev/null
+++ b/exemplos/day1/blog_framework/database.py
@@ -0,0 +1,54 @@
+# 1 - conectamos ao banco de dados
+from sqlite3 import connect
+
+conn = connect("blog.db")
+cursor = conn.cursor()
+
+# 2 - Criamos a tabela caso não exista
+conn.execute(
+ """\
+ CREATE TABLE if not exists post (
+ id integer PRIMARY KEY AUTOINCREMENT,
+ title varchar UNIQUE NOT NULL,
+ content varchar NOT NULL,
+ author varchar NOT NULL
+ );
+ """
+)
+
+# 3 - Criamos os posts iniciais para alimentar o banco de dados
+posts = [
+ {
+ "title": "Python é eleita a linguagem mais popular",
+ "content": """\
+ A linguem Python foi eleita a linguagem mais popular pela revista
+ tech masters e segue dominando o mundo.
+ """,
+ "author": "Satoshi Namamoto",
+ },
+ {
+ "title": "Como criar um blog utilizando Python",
+ "content": """\
+ Neste tutorial você aprenderá como criar um blog utilizando Python.
+ import make_a_blog
+ """,
+ "author": "Guido Van Rossum",
+ },
+]
+
+
+# 4 - Inserimos os posts caso o banco de dados esteja vazio
+count = cursor.execute("SELECT * FROM post;").fetchall()
+if not count:
+ cursor.executemany(
+ """\
+ INSERT INTO post (title, content, author)
+ VALUES (:title, :content, :author);
+ """,
+ posts,
+ )
+ conn.commit()
+
+# 5 - Verificamos que foi realmente inserido
+posts = cursor.execute("SELECT * FROM post;").fetchall()
+assert len(posts) >= 2
diff --git a/exemplos/day1/blog_framework/erik.py b/exemplos/day1/blog_framework/erik.py
new file mode 100644
index 0000000..7689820
--- /dev/null
+++ b/exemplos/day1/blog_framework/erik.py
@@ -0,0 +1,93 @@
+import cgi
+import json
+import re
+from wsgiref.simple_server import make_server
+
+from jinja2 import Environment, FileSystemLoader
+
+
+class Erik:
+ def __init__(self):
+ self.url_map = []
+ self.template_folder = "templates"
+ self.env = Environment(loader=FileSystemLoader("templates"))
+
+ def route(self, rule, method="GET", template=None):
+ def decorator(view):
+ self.url_map.append((rule, method, view, template))
+ return view
+
+ return decorator
+
+ def render_template(self, template_name, **context):
+ template = self.env.get_template(template_name)
+ return template.render(**context).encode("utf-8")
+
+ def __call__(self, environ, start_response):
+ path = environ["PATH_INFO"]
+ request_method = environ["REQUEST_METHOD"]
+ body = b"Content Not Found"
+ status = "404 Not Found"
+ ctype = "text/html"
+
+ for rule, method, view, template in self.url_map:
+ match = re.match(rule, path)
+ if match:
+ if method != request_method:
+ continue
+ view_args = match.groupdict()
+ if method == "POST":
+ view_args["form"] = cgi.FieldStorage(
+ fp=environ["wsgi.input"],
+ environ=environ,
+ keep_blank_values=1,
+ )
+ view_result = view(**view_args)
+
+ if isinstance(view_result, tuple):
+ view_result, status, ctype = view_result
+ else:
+ status = "200 OK"
+
+ if template:
+ body = self.render_template(template, **view_result)
+ elif (
+ isinstance(view_result, dict)
+ and ctype == "application/json"
+ ):
+ body = json.dumps(view_result).encode("utf-8")
+ else:
+ body = str(view_result).encode("utf-8")
+
+ start_response(status, [("Content-type", ctype)])
+ return [body]
+
+ def run(self, host="0.0.0.0", port=8000):
+ server = make_server(host, port, self)
+ server.serve_forever()
+
+
+if __name__ == "__main__":
+
+ app = Erik()
+
+ @app.route("^/$")
+ def foo():
+ return "Hello"
+
+ @app.route("^/(?P\d{1,})$")
+ def foo2(id):
+ return f"Hello {id}", 400, "foo"
+
+ print(
+ app(
+ {"PATH_INFO": "/1234", "REQUEST_METHOD": "GET"},
+ lambda *args: print(args),
+ )
+ )
+ print(
+ app(
+ {"PATH_INFO": "/", "REQUEST_METHOD": "GET"},
+ lambda *args: print(args),
+ )
+ )
diff --git a/exemplos/day1/blog_framework/templates/base.template.html b/exemplos/day1/blog_framework/templates/base.template.html
new file mode 100644
index 0000000..d3a8213
--- /dev/null
+++ b/exemplos/day1/blog_framework/templates/base.template.html
@@ -0,0 +1,53 @@
+
+
+
+
+ Blog
+ {% block style %}
+
+
+
+
+
+ {% endblock %}
+
+
+ {% block headline %}{% endblock %}
+
+ {% block content %}{% endblock %}
+
+ {%block footer %}Copyright 2022{% endblock %}
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog_framework/templates/form.template.html b/exemplos/day1/blog_framework/templates/form.template.html
new file mode 100644
index 0000000..b90ec8d
--- /dev/null
+++ b/exemplos/day1/blog_framework/templates/form.template.html
@@ -0,0 +1,23 @@
+{% extends 'base.template.html' %}
+
+{% block headline %}
+ New Post
+{% endblock %}
+
+{% macro field(name, type="input") %}
+{{name | capitalize}}:
+{% if type == "input" %}
+
+{% elif type == "textarea" %}
+
+{% endif %}
+{% endmacro %}
+
+{% block content %}
+
+ {{ field("title") }}
+ {{ field("content", type="textarea") }}
+ {{ field("author") }}
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/exemplos/day1/blog_framework/templates/list.template.html b/exemplos/day1/blog_framework/templates/list.template.html
new file mode 100644
index 0000000..38e4075
--- /dev/null
+++ b/exemplos/day1/blog_framework/templates/list.template.html
@@ -0,0 +1,13 @@
+{% extends 'base.template.html' %}
+
+{% block headline %}
+ Blog Posts:
+{% endblock %}
+
+{% block content %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/exemplos/day1/blog_framework/templates/post.template.html b/exemplos/day1/blog_framework/templates/post.template.html
new file mode 100644
index 0000000..9fb6f13
--- /dev/null
+++ b/exemplos/day1/blog_framework/templates/post.template.html
@@ -0,0 +1,15 @@
+{% extends 'base.template.html' %}
+
+{% block headline %}
+ {{ post.title }}
+{% endblock %}
+
+{% block content %}
+
+ {{ post.content }}
+
+{% endblock %}
+
+{% block footer %}
+ {{ post.author }}
+{% endblock %}
\ No newline at end of file
diff --git a/exemplos/day1/blog_framework/wsgi.py b/exemplos/day1/blog_framework/wsgi.py
new file mode 100644
index 0000000..7b931ed
--- /dev/null
+++ b/exemplos/day1/blog_framework/wsgi.py
@@ -0,0 +1,56 @@
+from database import conn
+from erik import Erik
+
+app = Erik()
+
+
+@app.route("^/$", template="list.template.html")
+def post_list():
+ posts = get_posts_from_database()
+ return {"post_list": posts}
+
+
+@app.route("^/(?P\d{1,})$", template="post.template.html")
+def post_detail(id):
+ post = get_posts_from_database(post_id=id)[0]
+ return {"post": post}
+
+
+@app.route("^/new$", template="form.template.html")
+def new_post_form():
+ return {}
+
+
+@app.route("^/new$", method="POST")
+def new_post_add(form):
+ post = {item.name: item.value for item in form.list}
+ add_new_post(post)
+ return "New post Created with Success!", "201 Created", "text/plain"
+
+
+def get_posts_from_database(post_id=None):
+ cursor = conn.cursor()
+ fields = ("id", "title", "content", "author")
+
+ if post_id:
+ results = cursor.execute("SELECT * FROM post WHERE id = ?;", post_id)
+ else:
+ results = cursor.execute("SELECT * FROM post;")
+
+ return [dict(zip(fields, post)) for post in results]
+
+
+def add_new_post(post):
+ cursor = conn.cursor()
+ cursor.execute(
+ """\
+ INSERT INTO post (title, content, author)
+ VALUES (:title, :content, :author);
+ """,
+ post,
+ )
+ conn.commit()
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/exemplos/day1/blog_jinja/blog.db b/exemplos/day1/blog_jinja/blog.db
new file mode 100644
index 0000000..b12cdf3
Binary files /dev/null and b/exemplos/day1/blog_jinja/blog.db differ
diff --git a/exemplos/day1/blog_jinja/database.py b/exemplos/day1/blog_jinja/database.py
new file mode 100644
index 0000000..06d244d
--- /dev/null
+++ b/exemplos/day1/blog_jinja/database.py
@@ -0,0 +1,54 @@
+# 1 - conectamos ao banco de dados
+from sqlite3 import connect
+
+conn = connect("blog.db")
+cursor = conn.cursor()
+
+# 2 - Criamos a tabela caso não exista
+conn.execute(
+ """\
+ CREATE TABLE if not exists post (
+ id integer PRIMARY KEY AUTOINCREMENT,
+ title varchar UNIQUE NOT NULL,
+ content varchar NOT NULL,
+ author varchar NOT NULL
+ );
+ """
+)
+
+# 3 - Criamos os posts iniciais para alimentar o banco de dados
+posts = [
+ {
+ "title": "Python é eleita a linguagem mais popular",
+ "content": """\
+ A linguem Python foi eleita a linguagem mais popular pela revista
+ tech masters e segue dominando o mundo.
+ """,
+ "author": "Satoshi Namamoto",
+ },
+ {
+ "title": "Como criar um blog utilizando Python",
+ "content": """\
+ Neste tutorial você aprenderá como criar um blog utilizando Python.
+ import make_a_blog
+ """,
+ "author": "Guido Van Rossum",
+ },
+]
+
+
+# 4 - Inserimos os posts caso o banco de dados esteja vazio
+count = cursor.execute("SELECT * FROM post;").fetchall()
+if not count:
+ cursor.executemany(
+ """\
+ INSERT INTO post (title, content, author)
+ VALUES (:title, :content, :author);
+ """,
+ posts,
+ )
+ conn.commit()
+
+# 5 - Verificamos que foi realmente inserido
+posts = cursor.execute("SELECT * FROM post;").fetchall()
+assert len(posts) >= 2
diff --git a/exemplos/day1/blog_jinja/form.template.html b/exemplos/day1/blog_jinja/form.template.html
new file mode 100644
index 0000000..aa1daf6
--- /dev/null
+++ b/exemplos/day1/blog_jinja/form.template.html
@@ -0,0 +1,19 @@
+
+
+
+
+ Blog
+
+
+ New Post
+
+ Title:
+
+ Content:
+
+ Author:
+
+
+
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog_jinja/list.template.html b/exemplos/day1/blog_jinja/list.template.html
new file mode 100644
index 0000000..5aa643c
--- /dev/null
+++ b/exemplos/day1/blog_jinja/list.template.html
@@ -0,0 +1,15 @@
+
+
+
+
+ Blog
+
+
+ Blog Posts:
+
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog_jinja/post.template.html b/exemplos/day1/blog_jinja/post.template.html
new file mode 100644
index 0000000..ad42027
--- /dev/null
+++ b/exemplos/day1/blog_jinja/post.template.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Blog
+
+
+ {{ post.title }}
+
+
+ {{ post.content }}
+
+
+ {{ post.author }}
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog_jinja/wsgi.py b/exemplos/day1/blog_jinja/wsgi.py
new file mode 100644
index 0000000..af563a2
--- /dev/null
+++ b/exemplos/day1/blog_jinja/wsgi.py
@@ -0,0 +1,78 @@
+import cgi
+from database import conn
+from jinja2 import Environment, FileSystemLoader
+
+env = Environment(loader=FileSystemLoader("."))
+
+
+def add_new_post(post):
+ cursor = conn.cursor()
+ cursor.execute(
+ """\
+ INSERT INTO post (title, content, author)
+ VALUES (:title, :content, :author);
+ """,
+ post,
+ )
+ conn.commit()
+
+
+def render_template(template_name, **context):
+ template = env.get_template(template_name)
+ return template.render(**context).encode("utf-8")
+
+
+def get_posts_from_database(post_id=None):
+ cursor = conn.cursor()
+ fields = ("id", "title", "content", "author")
+
+ if post_id:
+ results = cursor.execute("SELECT * FROM post WHERE id = ?;", post_id)
+ else:
+ results = cursor.execute("SELECT * FROM post;")
+
+ return [dict(zip(fields, post)) for post in results]
+
+
+def application(environ, start_response):
+ path = environ["PATH_INFO"]
+ method = environ["REQUEST_METHOD"]
+ body = b"Content Not Found"
+ status = "404 Not Found"
+
+ if path == "/" and method == "GET":
+ posts = get_posts_from_database()
+ body = render_template("list.template.html", post_list=posts)
+ status = "200 OK"
+
+ elif path.split("/")[-1].isdigit() and method == "GET":
+ post_id = path.split("/")[-1]
+ body = render_template(
+ "post.template.html",
+ post=get_posts_from_database(post_id=post_id)[0],
+ )
+ status = "200 OK"
+
+ elif path == "/new" and method == "POST":
+ form = cgi.FieldStorage(
+ fp=environ["wsgi.input"], environ=environ, keep_blank_values=1
+ )
+ post = {item.name: item.value for item in form.list}
+ add_new_post(post)
+ body = b"New post Created with Success!"
+ status = "201 Created"
+
+ elif path == "/new" and method == "GET":
+ body = render_template("form.template.html")
+ status = "200 OK"
+
+ headers = [("Content-type", "text/html")]
+ start_response(status, headers)
+ return [body]
+
+
+if __name__ == "__main__":
+ from wsgiref.simple_server import make_server
+
+ server = make_server("0.0.0.0", 8000, application)
+ server.serve_forever()
diff --git a/exemplos/day1/blog_jinja_blocks/blog.db b/exemplos/day1/blog_jinja_blocks/blog.db
new file mode 100644
index 0000000..b14fcea
Binary files /dev/null and b/exemplos/day1/blog_jinja_blocks/blog.db differ
diff --git a/exemplos/day1/blog_jinja_blocks/database.py b/exemplos/day1/blog_jinja_blocks/database.py
new file mode 100644
index 0000000..06d244d
--- /dev/null
+++ b/exemplos/day1/blog_jinja_blocks/database.py
@@ -0,0 +1,54 @@
+# 1 - conectamos ao banco de dados
+from sqlite3 import connect
+
+conn = connect("blog.db")
+cursor = conn.cursor()
+
+# 2 - Criamos a tabela caso não exista
+conn.execute(
+ """\
+ CREATE TABLE if not exists post (
+ id integer PRIMARY KEY AUTOINCREMENT,
+ title varchar UNIQUE NOT NULL,
+ content varchar NOT NULL,
+ author varchar NOT NULL
+ );
+ """
+)
+
+# 3 - Criamos os posts iniciais para alimentar o banco de dados
+posts = [
+ {
+ "title": "Python é eleita a linguagem mais popular",
+ "content": """\
+ A linguem Python foi eleita a linguagem mais popular pela revista
+ tech masters e segue dominando o mundo.
+ """,
+ "author": "Satoshi Namamoto",
+ },
+ {
+ "title": "Como criar um blog utilizando Python",
+ "content": """\
+ Neste tutorial você aprenderá como criar um blog utilizando Python.
+ import make_a_blog
+ """,
+ "author": "Guido Van Rossum",
+ },
+]
+
+
+# 4 - Inserimos os posts caso o banco de dados esteja vazio
+count = cursor.execute("SELECT * FROM post;").fetchall()
+if not count:
+ cursor.executemany(
+ """\
+ INSERT INTO post (title, content, author)
+ VALUES (:title, :content, :author);
+ """,
+ posts,
+ )
+ conn.commit()
+
+# 5 - Verificamos que foi realmente inserido
+posts = cursor.execute("SELECT * FROM post;").fetchall()
+assert len(posts) >= 2
diff --git a/exemplos/day1/blog_jinja_blocks/templates/base.template.html b/exemplos/day1/blog_jinja_blocks/templates/base.template.html
new file mode 100644
index 0000000..152bfc1
--- /dev/null
+++ b/exemplos/day1/blog_jinja_blocks/templates/base.template.html
@@ -0,0 +1,52 @@
+
+
+
+
+ Blog
+ {% block style %}
+
+
+
+
+ {% endblock %}
+
+
+ {% block headline %}{% endblock %}
+
+ {% block content %}{% endblock %}
+
+ {%block footer %}Copyright 2022{% endblock %}
+
+
\ No newline at end of file
diff --git a/exemplos/day1/blog_jinja_blocks/templates/form.template.html b/exemplos/day1/blog_jinja_blocks/templates/form.template.html
new file mode 100644
index 0000000..b90ec8d
--- /dev/null
+++ b/exemplos/day1/blog_jinja_blocks/templates/form.template.html
@@ -0,0 +1,23 @@
+{% extends 'base.template.html' %}
+
+{% block headline %}
+ New Post
+{% endblock %}
+
+{% macro field(name, type="input") %}
+{{name | capitalize}}:
+{% if type == "input" %}
+
+{% elif type == "textarea" %}
+
+{% endif %}
+{% endmacro %}
+
+{% block content %}
+
+ {{ field("title") }}
+ {{ field("content", type="textarea") }}
+ {{ field("author") }}
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/exemplos/day1/blog_jinja_blocks/templates/list.template.html b/exemplos/day1/blog_jinja_blocks/templates/list.template.html
new file mode 100644
index 0000000..38e4075
--- /dev/null
+++ b/exemplos/day1/blog_jinja_blocks/templates/list.template.html
@@ -0,0 +1,13 @@
+{% extends 'base.template.html' %}
+
+{% block headline %}
+ Blog Posts:
+{% endblock %}
+
+{% block content %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/exemplos/day1/blog_jinja_blocks/templates/post.template.html b/exemplos/day1/blog_jinja_blocks/templates/post.template.html
new file mode 100644
index 0000000..9fb6f13
--- /dev/null
+++ b/exemplos/day1/blog_jinja_blocks/templates/post.template.html
@@ -0,0 +1,15 @@
+{% extends 'base.template.html' %}
+
+{% block headline %}
+ {{ post.title }}
+{% endblock %}
+
+{% block content %}
+
+ {{ post.content }}
+
+{% endblock %}
+
+{% block footer %}
+ {{ post.author }}
+{% endblock %}
\ No newline at end of file
diff --git a/exemplos/day1/blog_jinja_blocks/wsgi.py b/exemplos/day1/blog_jinja_blocks/wsgi.py
new file mode 100644
index 0000000..045a39c
--- /dev/null
+++ b/exemplos/day1/blog_jinja_blocks/wsgi.py
@@ -0,0 +1,87 @@
+import json
+import cgi
+from database import conn
+from jinja2 import Environment, FileSystemLoader
+
+env = Environment(loader=FileSystemLoader("templates"))
+
+
+def add_new_post(post):
+ cursor = conn.cursor()
+ cursor.execute(
+ """\
+ INSERT INTO post (title, content, author)
+ VALUES (:title, :content, :author);
+ """,
+ post,
+ )
+ conn.commit()
+
+
+def render_template(template_name, **context):
+ template = env.get_template(template_name)
+ return template.render(**context).encode("utf-8")
+
+
+def get_posts_from_database(post_id=None):
+ cursor = conn.cursor()
+ fields = ("id", "title", "content", "author")
+
+ if post_id:
+ results = cursor.execute("SELECT * FROM post WHERE id = ?;", post_id)
+ else:
+ results = cursor.execute("SELECT * FROM post;")
+
+ return [dict(zip(fields, post)) for post in results]
+
+
+def application(environ, start_response):
+ path = environ["PATH_INFO"]
+ method = environ["REQUEST_METHOD"]
+ body = b"Content Not Found"
+ status = "404 Not Found"
+
+ if path == "/" and method == "GET":
+ posts = get_posts_from_database()
+ body = render_template("list.template.html", post_list=posts)
+ status = "200 OK"
+
+ elif path.split("/")[-1].isdigit() and method == "GET":
+ post_id = path.split("/")[-1]
+ body = render_template(
+ "post.template.html",
+ post=get_posts_from_database(post_id=post_id)[0],
+ )
+ status = "200 OK"
+
+ elif path == "/new" and method == "POST":
+ form = cgi.FieldStorage(
+ fp=environ["wsgi.input"], environ=environ, keep_blank_values=1
+ )
+ post = {item.name: item.value for item in form.list}
+ add_new_post(post)
+ body = b"New post Created with Success!"
+ status = "201 Created"
+
+ elif path == "/new" and method == "GET":
+ body = render_template("form.template.html")
+ status = "200 OK"
+
+ elif path == "/api" and method == "GET":
+ headers = [("Content-type", "application/json")]
+ posts = get_posts_from_database()
+ status = "200 OK"
+ start_response(status, headers)
+ body = {"posts": posts}
+ return [json.dumps(body).encode("utf-8")]
+
+ headers = [("Content-type", "text/html")]
+ start_response(status, headers)
+ return [body]
+
+
+if __name__ == "__main__":
+ from wsgiref.simple_server import make_server
+
+ server = make_server("0.0.0.0", 8000, application)
+ server.serve_forever()
diff --git a/exemplos/day1/cgi-bin/envia.py b/exemplos/day1/cgi-bin/envia.py
new file mode 100755
index 0000000..a48cdca
--- /dev/null
+++ b/exemplos/day1/cgi-bin/envia.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+import cgi
+
+form = cgi.FieldStorage()
+nome = form.getvalue("nome")
+mensagem = form.getvalue("mensagem")
+
+print("Content-type:text/html\r\n\r\n")
+print("")
+print("")
+print("Enviado ")
+print("")
+print("")
+print("Enviado com sucesso! ")
+print(f"{nome} - {mensagem} ")
+print("")
+print("")
diff --git a/exemplos/day1/client.py b/exemplos/day1/client.py
new file mode 100644
index 0000000..7826a05
--- /dev/null
+++ b/exemplos/day1/client.py
@@ -0,0 +1,14 @@
+import socket
+
+client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+client.connect(("example.com", 80))
+cmd = "GET http://example.com/index.html HTTP/1.0\r\n\r\n".encode()
+client.send(cmd)
+
+while True:
+ data = client.recv(512)
+ if len(data) < 1:
+ break
+ print(data.decode(), end="")
+
+client.close()
diff --git a/exemplos/day1/contato.html b/exemplos/day1/contato.html
new file mode 100644
index 0000000..e956071
--- /dev/null
+++ b/exemplos/day1/contato.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Contato
+
+
+
+ Nome:
+
+ Mensagem:
+
+
+
+
+
\ No newline at end of file
diff --git a/exemplos/day1/email.template.txt b/exemplos/day1/email.template.txt
new file mode 100644
index 0000000..36e5978
--- /dev/null
+++ b/exemplos/day1/email.template.txt
@@ -0,0 +1,11 @@
+Olá , {{ name }}
+
+Estes são os produtos em promoção:
+
+{% for product in products -%}
+ - {{ product.name | capitalize }} - R$ {{ "%.3f" | format(product.price) }}
+{% endfor %}
+
+{%- if special_customer %}
+E você tem {{ "20%" | addhearts }} de desconto por ser cliente especial!
+{% endif %}
diff --git a/exemplos/day1/estilo.css b/exemplos/day1/estilo.css
new file mode 100644
index 0000000..32d4e7f
--- /dev/null
+++ b/exemplos/day1/estilo.css
@@ -0,0 +1,20 @@
+body {
+ background-color: lightyellow;
+}
+
+h1 {
+ color: blue;
+}
+
+h2 {
+ color: lightblue;
+}
+
+p {
+ border: 1px dashed black;
+}
+
+img {
+ border-radius: 50%;
+ width: 100px;
+}
\ No newline at end of file
diff --git a/exemplos/day1/http_client.py b/exemplos/day1/http_client.py
new file mode 100644
index 0000000..b1a941a
--- /dev/null
+++ b/exemplos/day1/http_client.py
@@ -0,0 +1,14 @@
+import socket
+
+client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+client.connect(("localhost", 9000))
+cmd = "GET http://example.com/index.html HTTP/1.0\r\n\r\n".encode()
+client.send(cmd)
+
+while True:
+ data = client.recv(512)
+ if len(data) < 1:
+ break
+ print(data.decode(), end="")
+
+client.close()
diff --git a/exemplos/day1/http_libs.py b/exemplos/day1/http_libs.py
new file mode 100644
index 0000000..d7c82ef
--- /dev/null
+++ b/exemplos/day1/http_libs.py
@@ -0,0 +1,11 @@
+import requests
+
+result = requests.get("http://example.com/index.html")
+print(result.status_code)
+print(result.content)
+
+import httpx
+
+result = httpx.get("http://example.com/index.html")
+print(result.status_code)
+print(result.content)
diff --git a/exemplos/day1/pagina.html b/exemplos/day1/pagina.html
new file mode 100644
index 0000000..fe168e4
--- /dev/null
+++ b/exemplos/day1/pagina.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ Título do texto
+ Subtítulo
+
+ Texto em Negrito
+
+ Mais texto no parágrafo.
+
+ Clique para ir a outro local
+
+
+
+
+
+
\ No newline at end of file
diff --git a/exemplos/day1/render_message.py b/exemplos/day1/render_message.py
new file mode 100644
index 0000000..ad318d2
--- /dev/null
+++ b/exemplos/day1/render_message.py
@@ -0,0 +1,22 @@
+from jinja2 import Environment, FileSystemLoader
+
+env = Environment(loader=FileSystemLoader("."))
+template = env.get_template("email.template.txt")
+
+
+def addhearts(text):
+ return f"❤️ {text} ❤️"
+
+
+env.filters["addhearts"] = addhearts
+
+data = {
+ "name": "Bruno",
+ "products": [
+ {"name": "iphone", "price": 13000.320},
+ {"name": "ferrari", "price": 900000.430},
+ ],
+ "special_customer": True,
+}
+
+print(template.render(**data))
diff --git a/exemplos/day1/script.js b/exemplos/day1/script.js
new file mode 100644
index 0000000..8b86569
--- /dev/null
+++ b/exemplos/day1/script.js
@@ -0,0 +1,6 @@
+function emite_alerta() {
+ alert("Python Rocks!");
+};
+
+logo = document.getElementsByTagName("img")[0];
+logo.onclick = emite_alerta;
\ No newline at end of file
diff --git a/exemplos/day1/server.py b/exemplos/day1/server.py
new file mode 100644
index 0000000..e63d010
--- /dev/null
+++ b/exemplos/day1/server.py
@@ -0,0 +1,18 @@
+import socket
+
+server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+server.bind(("localhost", 9000))
+server.listen()
+
+try:
+ while True:
+ client, address = server.accept()
+ data = client.recv(5000).decode()
+ print(data)
+
+ client.sendall(
+ "HTTP/1.0 200 OK\r\nHello World\r\n\r\n".encode()
+ )
+ client.shutdown(socket.SHUT_WR)
+except:
+ server.close()
diff --git a/exemplos/day1/ssr.py b/exemplos/day1/ssr.py
new file mode 100644
index 0000000..0fb537b
--- /dev/null
+++ b/exemplos/day1/ssr.py
@@ -0,0 +1,22 @@
+# carregar os dados
+dados = [
+ {"nome": "Bruno", "cidade": "Viana"},
+ {"nome": "Guido", "cidade": "Amsterdan"}
+]
+
+# processar
+template = """\
+
+
+
+ Nome: {dados[nome]}
+ Cidade: {dados[cidade]}
+
+
+
+"""
+
+# renderizar
+
+for item in dados:
+ print(template.format(dados=item))
diff --git a/exemplos/day1/urlopen.py b/exemplos/day1/urlopen.py
new file mode 100644
index 0000000..6d2e8c4
--- /dev/null
+++ b/exemplos/day1/urlopen.py
@@ -0,0 +1,4 @@
+from urllib.request import urlopen
+
+result = urlopen("http://example.com/index.html")
+print(result.read().decode("utf-8"))
diff --git a/exemplos/day1/wsgi_simples.py b/exemplos/day1/wsgi_simples.py
new file mode 100644
index 0000000..4f24a9c
--- /dev/null
+++ b/exemplos/day1/wsgi_simples.py
@@ -0,0 +1,13 @@
+def application(environ, start_response):
+ body = b"Hello world! "
+ status = "200 OK"
+ headers = [("Content-type", "text/html")]
+ start_response(status, headers)
+ return [body]
+
+
+if __name__ == "__main__":
+ from wsgiref.simple_server import make_server
+
+ server = make_server("0.0.0.0", 8000, application)
+ server.serve_forever()