From 567e02a6cda2138bc666220145670029cd267c3b Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Wed, 11 May 2022 19:11:43 +0000 Subject: [PATCH 1/7] day 1 --- .vscode/settings.json | 3 + exemplos/day1/blog/blog.db | Bin 0 -> 16384 bytes exemplos/day1/blog/database.py | 53 ++++++++++++++++++ exemplos/day1/blog/list.template.html | 13 +++++ exemplos/day1/blog/post.template.html | 16 ++++++ exemplos/day1/blog/render.py | 40 +++++++++++++ ...como-criar-um-blog-utilizando-python..html | 18 ++++++ exemplos/day1/blog/site/index.html | 14 +++++ ...251-eleita-a-linguagem-mais-popular..html" | 18 ++++++ exemplos/day1/cgi-bin/envia.py | 16 ++++++ exemplos/day1/client.py | 14 +++++ exemplos/day1/contato.html | 16 ++++++ exemplos/day1/estilo.css | 20 +++++++ exemplos/day1/http_libs.py | 9 +++ exemplos/day1/pagina.html | 21 +++++++ exemplos/day1/script.js | 6 ++ exemplos/day1/urlopen.py | 3 + 17 files changed, 280 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 exemplos/day1/blog/blog.db create mode 100644 exemplos/day1/blog/database.py create mode 100644 exemplos/day1/blog/list.template.html create mode 100644 exemplos/day1/blog/post.template.html create mode 100644 exemplos/day1/blog/render.py create mode 100644 exemplos/day1/blog/site/como-criar-um-blog-utilizando-python..html create mode 100644 exemplos/day1/blog/site/index.html create mode 100644 "exemplos/day1/blog/site/python-\303\251-eleita-a-linguagem-mais-popular..html" create mode 100755 exemplos/day1/cgi-bin/envia.py create mode 100644 exemplos/day1/client.py create mode 100644 exemplos/day1/contato.html create mode 100644 exemplos/day1/estilo.css create mode 100644 exemplos/day1/http_libs.py create mode 100644 exemplos/day1/pagina.html create mode 100644 exemplos/day1/script.js create mode 100644 exemplos/day1/urlopen.py 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 0000000000000000000000000000000000000000..0bf5b9761dc2522a2dc0c555ed995e423a2be2f6 GIT binary patch literal 16384 zcmeI(zfaph6bJCLgHk{Ow?mYn%i9X#M}<07ptb>76>2aLk|L()aE|0u+ZXIJYP(eM zpLC=BH<&tA>ehdx>ey!kk)Wy?Rbr{Wr<@)8-n*PXo}R7j?KZVlbY#+4T6!Yx3&#;J zh=dR>_X+OT&EYS%kFUr6w0Fhw^Y1g>Pf?luBD{y*SKgsP00Izz00bZa0SG_<0uX=z z1pZxMr&6siEI0>N9!4rVj<~ArX6iUsNqGBkVx#3Z+CH@#>rJ0-#m*%%R*RfDf4bt_ ztJiAInP1L1G?^{Bdn3CzLvz!_P4`GAR`pd%JFU&FM(coH`3KbKw6`|{PTKN=_F@@n zwT%>=$TS?tlsduYZpWu!yG=o-*}M!14NsNWQP9m%ncIO$e;b^hf89-7orEZ?ZE?3N2ydt8i+;$G&Om-1RB)G}F?$EWK~ zRmigkOP8yoi%+B?rL81Mkxu%#?5mh3)EN!UFpp$9x`4)I01sc~9vS_&WE!eSQmRgL zX60y6R)qup4faSgQk1EFuBc~Xos@8f;+z4ONAY{onrxsckg<%7HPd`wUGH3Y=iaxw zxy6_j0uX=z1Rwwb2tWV=5P$##AOL}J1?DUJ&REY#+@*?~8vltz@&4cOehB`cK>z{} efB*y_009U<00Izz00bcLUkOY)m6}ujnc)`&LJ_q9 literal 0 HcmV?d00001 diff --git a/exemplos/day1/blog/database.py b/exemplos/day1/blog/database.py new file mode 100644 index 0000000..9c1fd2a --- /dev/null +++ b/exemplos/day1/blog/database.py @@ -0,0 +1,53 @@ +# 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/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..99180fb --- /dev/null +++ b/exemplos/day1/blog/render.py @@ -0,0 +1,40 @@ +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(f"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/cgi-bin/envia.py b/exemplos/day1/cgi-bin/envia.py new file mode 100755 index 0000000..3ed2a84 --- /dev/null +++ b/exemplos/day1/cgi-bin/envia.py @@ -0,0 +1,16 @@ +#!/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("") \ No newline at end of file diff --git a/exemplos/day1/client.py b/exemplos/day1/client.py new file mode 100644 index 0000000..e58ea22 --- /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() \ No newline at end of file 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 + + +
    +
    +
    +
    +
    + +
    + + \ No newline at end of file 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_libs.py b/exemplos/day1/http_libs.py new file mode 100644 index 0000000..e0ce7dd --- /dev/null +++ b/exemplos/day1/http_libs.py @@ -0,0 +1,9 @@ +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/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/urlopen.py b/exemplos/day1/urlopen.py new file mode 100644 index 0000000..48f8c0e --- /dev/null +++ b/exemplos/day1/urlopen.py @@ -0,0 +1,3 @@ +from urllib.request import urlopen +result = urlopen("http://example.com/index.html") +print(result.read().decode("utf-8")) \ No newline at end of file From b3b8cf319ac0887150340d80b4c06d0b52c8d917 Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Thu, 12 May 2022 15:53:41 +0000 Subject: [PATCH 2/7] cgi e wsgi --- exemplos/day1/blog/blog.db | Bin 16384 -> 16384 bytes exemplos/day1/blog/database.py | 1 + exemplos/day1/blog/form.template.html | 19 ++++++ exemplos/day1/blog/render.py | 2 +- exemplos/day1/blog/wsgi.py | 87 ++++++++++++++++++++++++++ exemplos/day1/cgi-bin/envia.py | 7 ++- exemplos/day1/client.py | 8 +-- exemplos/day1/http_libs.py | 2 + exemplos/day1/urlopen.py | 3 +- exemplos/day1/wsgi_simples.py | 13 ++++ 10 files changed, 133 insertions(+), 9 deletions(-) create mode 100644 exemplos/day1/blog/form.template.html create mode 100644 exemplos/day1/blog/wsgi.py create mode 100644 exemplos/day1/wsgi_simples.py diff --git a/exemplos/day1/blog/blog.db b/exemplos/day1/blog/blog.db index 0bf5b9761dc2522a2dc0c555ed995e423a2be2f6..6b440c4635d6420b64166e548dc5e5c386e563e4 100644 GIT binary patch delta 134 zcmZo@U~Fh$oFL7}JWr=n6IGblefBXM)RTq`3NGyg0G{uTVQ_%Cf1 XROsR7<7Jj-gd4@Yd4+zs03$O1L&hiT delta 59 zcmZo@U~Fh$oFL7}G*QNxk!fSX5`GRQzIq0JYrgu;f(pfao9pFT89A8vS1|Ce;J>t4 P&|nV#<`w$k0*p)m*ya!Y diff --git a/exemplos/day1/blog/database.py b/exemplos/day1/blog/database.py index 9c1fd2a..7876cf5 100644 --- a/exemplos/day1/blog/database.py +++ b/exemplos/day1/blog/database.py @@ -1,5 +1,6 @@ # 1 - conectamos ao banco de dados from sqlite3 import connect + conn = connect("blog.db") cursor = conn.cursor() 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/render.py b/exemplos/day1/blog/render.py index 99180fb..3c828a5 100644 --- a/exemplos/day1/blog/render.py +++ b/exemplos/day1/blog/render.py @@ -4,7 +4,7 @@ # 1 - Obtemos os posts do banco de dados e deserializamos em um dict cursor = conn.cursor() fields = ("id", "title", "content", "author") -results = cursor.execute(f"SELECT * FROM post;") +results = cursor.execute("SELECT * FROM post;") posts = [dict(zip(fields, post)) for post in results] # 2 - Criamos a pasta de destino do site diff --git a/exemplos/day1/blog/wsgi.py b/exemplos/day1/blog/wsgi.py new file mode 100644 index 0000000..a6e2548 --- /dev/null +++ b/exemplos/day1/blog/wsgi.py @@ -0,0 +1,87 @@ +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/cgi-bin/envia.py b/exemplos/day1/cgi-bin/envia.py index 3ed2a84..a48cdca 100755 --- a/exemplos/day1/cgi-bin/envia.py +++ b/exemplos/day1/cgi-bin/envia.py @@ -1,8 +1,9 @@ #!/usr/bin/env python import cgi + form = cgi.FieldStorage() -nome = form.getvalue('nome') -mensagem = form.getvalue('mensagem') +nome = form.getvalue("nome") +mensagem = form.getvalue("mensagem") print("Content-type:text/html\r\n\r\n") print("") @@ -13,4 +14,4 @@ print("

    Enviado com sucesso!

    ") print(f"

    {nome} - {mensagem}

    ") print("") -print("") \ No newline at end of file +print("") diff --git a/exemplos/day1/client.py b/exemplos/day1/client.py index e58ea22..7826a05 100644 --- a/exemplos/day1/client.py +++ b/exemplos/day1/client.py @@ -1,14 +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.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='') + print(data.decode(), end="") -client.close() \ No newline at end of file +client.close() diff --git a/exemplos/day1/http_libs.py b/exemplos/day1/http_libs.py index e0ce7dd..d7c82ef 100644 --- a/exemplos/day1/http_libs.py +++ b/exemplos/day1/http_libs.py @@ -1,9 +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/urlopen.py b/exemplos/day1/urlopen.py index 48f8c0e..6d2e8c4 100644 --- a/exemplos/day1/urlopen.py +++ b/exemplos/day1/urlopen.py @@ -1,3 +1,4 @@ from urllib.request import urlopen + result = urlopen("http://example.com/index.html") -print(result.read().decode("utf-8")) \ No newline at end of file +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..e2d7e81 --- /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() \ No newline at end of file From 0af716c59bb3a50553b09e27074762e5d79f8381 Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Fri, 13 May 2022 19:37:21 +0000 Subject: [PATCH 3/7] Jinja --- exemplos/day1/blog_jinja/blog.db | Bin 0 -> 16384 bytes exemplos/day1/blog_jinja/database.py | 54 +++++++++++ exemplos/day1/blog_jinja/form.template.html | 19 ++++ exemplos/day1/blog_jinja/list.template.html | 13 +++ exemplos/day1/blog_jinja/post.template.html | 16 ++++ exemplos/day1/blog_jinja/render.py | 40 ++++++++ ...como-criar-um-blog-utilizando-python..html | 18 ++++ exemplos/day1/blog_jinja/site/index.html | 14 +++ ...251-eleita-a-linguagem-mais-popular..html" | 18 ++++ exemplos/day1/blog_jinja/wsgi.py | 89 ++++++++++++++++++ exemplos/day1/email.template.txt | 11 +++ exemplos/day1/render_message.py | 19 ++++ 12 files changed, 311 insertions(+) create mode 100644 exemplos/day1/blog_jinja/blog.db create mode 100644 exemplos/day1/blog_jinja/database.py create mode 100644 exemplos/day1/blog_jinja/form.template.html create mode 100644 exemplos/day1/blog_jinja/list.template.html create mode 100644 exemplos/day1/blog_jinja/post.template.html create mode 100644 exemplos/day1/blog_jinja/render.py create mode 100644 exemplos/day1/blog_jinja/site/como-criar-um-blog-utilizando-python..html create mode 100644 exemplos/day1/blog_jinja/site/index.html create mode 100644 "exemplos/day1/blog_jinja/site/python-\303\251-eleita-a-linguagem-mais-popular..html" create mode 100644 exemplos/day1/blog_jinja/wsgi.py create mode 100644 exemplos/day1/email.template.txt create mode 100644 exemplos/day1/render_message.py diff --git a/exemplos/day1/blog_jinja/blog.db b/exemplos/day1/blog_jinja/blog.db new file mode 100644 index 0000000000000000000000000000000000000000..6b440c4635d6420b64166e548dc5e5c386e563e4 GIT binary patch literal 16384 zcmeI(&rcIU6bJCxE><9c)kDL<126F)1gIeKxrkMnxP%qiMu;xceYV4 z2L23g-qe4ClP42z{v*btZwoX5BNF4ud?%gmk9lu8``OdmO?S4d+A2CQNhB>j5_g2- zi04E?2$%Z^_lxH6&eh|KvEOZ7QGWJq!uuiI$h<}Raj+R2H}l0d7xVADwja&0C%C(lYrewdF8Plb{a)z_(&!$n!u>hf=}N0O4F zRCO{%Z4>Eu0B0!57_dBy-;vg&T}^?EWMr%v=ez29C&K&Sop@ibyTurT00bZa0SG_< z0uX=z1Rwwb2teT93rx7v&hUAPJL~Q`H+n`=Sa9Xo&7Vl*@Bba|yWkHR1Rwwb2tWV= a5P$##AOHafKmY>&mB6UumYl)=0Dc0wF)3vL literal 0 HcmV?d00001 diff --git a/exemplos/day1/blog_jinja/database.py b/exemplos/day1/blog_jinja/database.py new file mode 100644 index 0000000..7876cf5 --- /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

    +
    +
    +
    +
    +
    +
    +
    + +
    + + \ 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..fb57226 --- /dev/null +++ b/exemplos/day1/blog_jinja/list.template.html @@ -0,0 +1,13 @@ + + + + + Blog + + +

    Blog Posts:

    +
      + {post_list} +
    + + \ 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..6aa3ac6 --- /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/render.py b/exemplos/day1/blog_jinja/render.py new file mode 100644 index 0000000..3c828a5 --- /dev/null +++ b/exemplos/day1/blog_jinja/render.py @@ -0,0 +1,40 @@ +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_jinja/site/como-criar-um-blog-utilizando-python..html b/exemplos/day1/blog_jinja/site/como-criar-um-blog-utilizando-python..html new file mode 100644 index 0000000..51ede2b --- /dev/null +++ b/exemplos/day1/blog_jinja/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_jinja/site/index.html b/exemplos/day1/blog_jinja/site/index.html new file mode 100644 index 0000000..6778573 --- /dev/null +++ b/exemplos/day1/blog_jinja/site/index.html @@ -0,0 +1,14 @@ + + + + + Blog + + +

    Blog Posts:

    + + + \ No newline at end of file diff --git "a/exemplos/day1/blog_jinja/site/python-\303\251-eleita-a-linguagem-mais-popular..html" "b/exemplos/day1/blog_jinja/site/python-\303\251-eleita-a-linguagem-mais-popular..html" new file mode 100644 index 0000000..87ad542 --- /dev/null +++ "b/exemplos/day1/blog_jinja/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_jinja/wsgi.py b/exemplos/day1/blog_jinja/wsgi.py new file mode 100644 index 0000000..5fa7f36 --- /dev/null +++ b/exemplos/day1/blog_jinja/wsgi.py @@ -0,0 +1,89 @@ +import cgi +from pathlib import Path +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) + + +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/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/render_message.py b/exemplos/day1/render_message.py new file mode 100644 index 0000000..3815a0f --- /dev/null +++ b/exemplos/day1/render_message.py @@ -0,0 +1,19 @@ +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)) \ No newline at end of file From 47c3a6a4a70a0a6862e34307ad0e3d8fd4859a02 Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Mon, 16 May 2022 22:02:07 +0000 Subject: [PATCH 4/7] Jinja blog --- exemplos/day1/blog/database.py | 2 +- exemplos/day1/blog_jinja/blog.db | Bin 16384 -> 16384 bytes exemplos/day1/blog_jinja/database.py | 2 +- exemplos/day1/blog_jinja/list.template.html | 4 +- exemplos/day1/blog_jinja/post.template.html | 6 +- exemplos/day1/blog_jinja/render.py | 40 --------- ...como-criar-um-blog-utilizando-python..html | 18 ---- exemplos/day1/blog_jinja/site/index.html | 14 --- ...251-eleita-a-linguagem-mais-popular..html" | 18 ---- exemplos/day1/blog_jinja/wsgi.py | 12 +-- exemplos/day1/blog_jinja_blocks/blog.db | Bin 0 -> 16384 bytes exemplos/day1/blog_jinja_blocks/database.py | 54 ++++++++++++ .../templates/base.template.html | 14 +++ .../templates/form.template.html | 17 ++++ .../templates/list.template.html | 13 +++ .../templates/post.template.html | 15 ++++ exemplos/day1/blog_jinja_blocks/wsgi.py | 81 ++++++++++++++++++ 17 files changed, 204 insertions(+), 106 deletions(-) delete mode 100644 exemplos/day1/blog_jinja/render.py delete mode 100644 exemplos/day1/blog_jinja/site/como-criar-um-blog-utilizando-python..html delete mode 100644 exemplos/day1/blog_jinja/site/index.html delete mode 100644 "exemplos/day1/blog_jinja/site/python-\303\251-eleita-a-linguagem-mais-popular..html" create mode 100644 exemplos/day1/blog_jinja_blocks/blog.db create mode 100644 exemplos/day1/blog_jinja_blocks/database.py create mode 100644 exemplos/day1/blog_jinja_blocks/templates/base.template.html create mode 100644 exemplos/day1/blog_jinja_blocks/templates/form.template.html create mode 100644 exemplos/day1/blog_jinja_blocks/templates/list.template.html create mode 100644 exemplos/day1/blog_jinja_blocks/templates/post.template.html create mode 100644 exemplos/day1/blog_jinja_blocks/wsgi.py diff --git a/exemplos/day1/blog/database.py b/exemplos/day1/blog/database.py index 7876cf5..06d244d 100644 --- a/exemplos/day1/blog/database.py +++ b/exemplos/day1/blog/database.py @@ -51,4 +51,4 @@ # 5 - Verificamos que foi realmente inserido posts = cursor.execute("SELECT * FROM post;").fetchall() -assert len(posts) == 2 +assert len(posts) >= 2 diff --git a/exemplos/day1/blog_jinja/blog.db b/exemplos/day1/blog_jinja/blog.db index 6b440c4635d6420b64166e548dc5e5c386e563e4..b12cdf311b083446aa61adb2491148c2250cca9c 100644 GIT binary patch delta 104 zcmZo@U~Fh$oFL7}GEv5vk!54T5`G>QK3xWWYrc9ucRt;Xjk0`F5-h9?;_~7isX00M ze)(nj3IX}WB~C@9dHI{&<@Pf2u<%b{;9tQ%fqxeNrOkp04g6f3%;Jn-8A=X GvH$>bP#akQ delta 62 zcmZo@U~Fh$oFL7}JW=42L diff --git a/exemplos/day1/blog_jinja/database.py b/exemplos/day1/blog_jinja/database.py index 7876cf5..06d244d 100644 --- a/exemplos/day1/blog_jinja/database.py +++ b/exemplos/day1/blog_jinja/database.py @@ -51,4 +51,4 @@ # 5 - Verificamos que foi realmente inserido posts = cursor.execute("SELECT * FROM post;").fetchall() -assert len(posts) == 2 +assert len(posts) >= 2 diff --git a/exemplos/day1/blog_jinja/list.template.html b/exemplos/day1/blog_jinja/list.template.html index fb57226..5aa643c 100644 --- a/exemplos/day1/blog_jinja/list.template.html +++ b/exemplos/day1/blog_jinja/list.template.html @@ -7,7 +7,9 @@

    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 index 6aa3ac6..ad42027 100644 --- a/exemplos/day1/blog_jinja/post.template.html +++ b/exemplos/day1/blog_jinja/post.template.html @@ -5,12 +5,12 @@ Blog -

    {post[title]}

    +

    {{ post.title }}


    - {post[content]} + {{ post.content }}


    - {post[author]} + {{ post.author }} \ No newline at end of file diff --git a/exemplos/day1/blog_jinja/render.py b/exemplos/day1/blog_jinja/render.py deleted file mode 100644 index 3c828a5..0000000 --- a/exemplos/day1/blog_jinja/render.py +++ /dev/null @@ -1,40 +0,0 @@ -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_jinja/site/como-criar-um-blog-utilizando-python..html b/exemplos/day1/blog_jinja/site/como-criar-um-blog-utilizando-python..html deleted file mode 100644 index 51ede2b..0000000 --- a/exemplos/day1/blog_jinja/site/como-criar-um-blog-utilizando-python..html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - 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_jinja/site/index.html b/exemplos/day1/blog_jinja/site/index.html deleted file mode 100644 index 6778573..0000000 --- a/exemplos/day1/blog_jinja/site/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Blog - - -

    Blog Posts:

    - - - \ No newline at end of file diff --git "a/exemplos/day1/blog_jinja/site/python-\303\251-eleita-a-linguagem-mais-popular..html" "b/exemplos/day1/blog_jinja/site/python-\303\251-eleita-a-linguagem-mais-popular..html" deleted file mode 100644 index 87ad542..0000000 --- "a/exemplos/day1/blog_jinja/site/python-\303\251-eleita-a-linguagem-mais-popular..html" +++ /dev/null @@ -1,18 +0,0 @@ - - - - - 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_jinja/wsgi.py b/exemplos/day1/blog_jinja/wsgi.py index 5fa7f36..f1489c5 100644 --- a/exemplos/day1/blog_jinja/wsgi.py +++ b/exemplos/day1/blog_jinja/wsgi.py @@ -19,7 +19,7 @@ def add_new_post(post): def render_template(template_name, **context): template = env.get_template(template_name) - return template.render(**context) + return template.render(**context).encode("utf-8") def get_posts_from_database(post_id=None): @@ -34,14 +34,6 @@ def get_posts_from_database(post_id=None): 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"] @@ -52,7 +44,7 @@ def application(environ, start_response): posts = get_posts_from_database() body = render_template( "list.template.html", - post_list=get_post_list(posts) + post_list=posts ) status = "200 OK" diff --git a/exemplos/day1/blog_jinja_blocks/blog.db b/exemplos/day1/blog_jinja_blocks/blog.db new file mode 100644 index 0000000000000000000000000000000000000000..b12cdf311b083446aa61adb2491148c2250cca9c GIT binary patch literal 16384 zcmeI&Pfrs;6aes1*7-R1Ff}6Z?T-(0i%^qLXTvmJXea8FAoYEKO-SNKSh8hWw011!)36KB@kN^pg z011!)3H-glwo|MuEbu)e_CuK-hFH~hQhAukxO@4~U2FRFmJhA^YQu+1v2(GAOekR_lI}nx&<-|s+CBtZEeP6;##u;L<4~~~2VFcXGBeQ0A19~h?-h!b;0zwt{Gtrk34yaPR{b3f0WPAhlvj9AOo_nCxRmm`v zp@2k=RBFU{Qbu+Mcn$POQjn0!ekP%(BNgXx8lnsVYvcG`VRSlB5Qs=b+URL~s$K7d zc^|zK@4fep9&!>O0TLhq5+DH*AOR8}0TLhq5+H$pFEHg)c>aFHopEOQ_II%4YjZzSyZfA0NY_@hPwBtQZrKmsH{0wh2JBtQZrKmsK2UkOZdr_AktGTdLr CKQs&g literal 0 HcmV?d00001 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..60d8d14 --- /dev/null +++ b/exemplos/day1/blog_jinja_blocks/templates/base.template.html @@ -0,0 +1,14 @@ + + + + + Blog + + +

    {% 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..b19cbcd --- /dev/null +++ b/exemplos/day1/blog_jinja_blocks/templates/form.template.html @@ -0,0 +1,17 @@ +{% extends 'base.template.html' %} + +{% block headline %} + New Post +{% endblock %} + +{% block content %} +
    +
    +
    +
    +
    +
    +
    + +
    +{% 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..33a4f4d --- /dev/null +++ b/exemplos/day1/blog_jinja_blocks/wsgi.py @@ -0,0 +1,81 @@ +import cgi +from pathlib import Path +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" + + 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() From f3f638db3734fb2c54321ac64d642c60195f9494 Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Tue, 17 May 2022 12:57:05 +0000 Subject: [PATCH 5/7] Criamos um framework --- exemplos/day1/blog_framework/blog.db | Bin 0 -> 16384 bytes exemplos/day1/blog_framework/database.py | 54 ++++++++++ exemplos/day1/blog_framework/erik.py | 94 ++++++++++++++++++ .../templates/base.template.html | 53 ++++++++++ .../templates/form.template.html | 23 +++++ .../templates/list.template.html | 13 +++ .../templates/post.template.html | 15 +++ exemplos/day1/blog_framework/wsgi.py | 56 +++++++++++ exemplos/day1/blog_jinja/wsgi.py | 1 - exemplos/day1/blog_jinja_blocks/blog.db | Bin 16384 -> 16384 bytes .../templates/base.template.html | 38 +++++++ .../templates/form.template.html | 20 ++-- exemplos/day1/blog_jinja_blocks/wsgi.py | 10 +- 13 files changed, 368 insertions(+), 9 deletions(-) create mode 100644 exemplos/day1/blog_framework/blog.db create mode 100644 exemplos/day1/blog_framework/database.py create mode 100644 exemplos/day1/blog_framework/erik.py create mode 100644 exemplos/day1/blog_framework/templates/base.template.html create mode 100644 exemplos/day1/blog_framework/templates/form.template.html create mode 100644 exemplos/day1/blog_framework/templates/list.template.html create mode 100644 exemplos/day1/blog_framework/templates/post.template.html create mode 100644 exemplos/day1/blog_framework/wsgi.py diff --git a/exemplos/day1/blog_framework/blog.db b/exemplos/day1/blog_framework/blog.db new file mode 100644 index 0000000000000000000000000000000000000000..4c4ad4d0e7b10eadc2399ceb12cb8cac63ae4e86 GIT binary patch literal 16384 zcmeI%Pfrs;6aes9mafpGtRAo$54?nf5NJ&$F;R$G$Oef}ptKSalV&JGnXtQ4W@k~n z82AJx-n@BJzXm5yB;NcY#-neyPy@t3Ja8ay(q;e5o7p!%dU?~8<#}lYY$_da0~72f zvn=);fHCIa(Tm4Pv+&~V{Yl@y&JHU+`ZgCCu%G`3@gUVtJD)ssKPDoSXRH5kxo$lqa*;4vkXLj^{kCUGq zw3rMx#M|SQVX#W?8%eT_Qu5bE=)MFyhli8<$lS?+_XD#7h1?O|P$K~nAOR8}0TLhq z5+DH*AORA%3V|n1hE2@oD{5E4rp9XYjndoTX}MhwAUyrF%{7OmJ*)=9X&r~^b;e<( z{rte68Rb*~B({0rgx zDot+*OUbnBk)2^fv%~4b)BVFo-d2`HqJh>Uf34q{>cOC0&Zax)ulcu&bJf-+;HZz^Ydteg<6i#gnC#crx1* z4txqSXe(_X;M=0X8)*Vl50aj4+-xi{l~+83s*0jG*q^o>#t&{4I{pc*@P#xSIQTMb z#k_@}0hbZ}FWRxsb$0>fP5^cvkKI)AqQTG>J_jv!Wn_3aDI=O&_zvXO5eSGxD;BV! z0vV=o3W68`i{1DYZd9}-p~3?mD5J9Yjdonl+%N72m%E?bAMV~&e97q@BtQZrKmsH{ z0wh2JBtQZrKmsIitpxJ+gq3cKoZiZDZrdg6{4PzV-_Bd<{z`Ao9_kEC_D<|kd)2zs z9!XEZ=KYu7kw||3x7=S0Kh#Ko1W14cNPq-LfCNZ@1W14cNPq;cl|Y|m4_e8-g7XI{ CM|M#F literal 0 HcmV?d00001 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..9a7b482 --- /dev/null +++ b/exemplos/day1/blog_framework/erik.py @@ -0,0 +1,94 @@ +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") %} +
    +{% 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/wsgi.py b/exemplos/day1/blog_jinja/wsgi.py index f1489c5..587ca5a 100644 --- a/exemplos/day1/blog_jinja/wsgi.py +++ b/exemplos/day1/blog_jinja/wsgi.py @@ -1,5 +1,4 @@ import cgi -from pathlib import Path from database import conn from jinja2 import Environment, FileSystemLoader diff --git a/exemplos/day1/blog_jinja_blocks/blog.db b/exemplos/day1/blog_jinja_blocks/blog.db index b12cdf311b083446aa61adb2491148c2250cca9c..b14fcea5a2c6229a7a3560af528b6ff301b2e694 100644 GIT binary patch delta 189 zcmZo@U~Fh$oFL7}I#I@%k#%Fj5`I2b-t!Fn)_nDR?tHqu=QlR)<&BGBWn(aGTF%&s9h*F3HTvR|e6k3WrxJlw!#7a`AHMDrAQE6Vj u!e(8$>x_J?{FMy+EBGhy&*HztU%6ROA)Q}bjM17+C>*CO0ks delta 66 zcmV-I0KNZ!fB}Gj0gxL31d$v=0R*vNqz?=P4lMu=I}U#iM-DBqfgKLBEgsha3 Blog + {% block style %} + + + + + {% endblock %}

    {% block headline %}{% endblock %}

    diff --git a/exemplos/day1/blog_jinja_blocks/templates/form.template.html b/exemplos/day1/blog_jinja_blocks/templates/form.template.html index b19cbcd..b90ec8d 100644 --- a/exemplos/day1/blog_jinja_blocks/templates/form.template.html +++ b/exemplos/day1/blog_jinja_blocks/templates/form.template.html @@ -3,15 +3,21 @@ {% block headline %} New Post {% endblock %} - + +{% macro field(name, type="input") %} +
    +{% 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/wsgi.py b/exemplos/day1/blog_jinja_blocks/wsgi.py index 33a4f4d..3a67033 100644 --- a/exemplos/day1/blog_jinja_blocks/wsgi.py +++ b/exemplos/day1/blog_jinja_blocks/wsgi.py @@ -1,5 +1,5 @@ +import json import cgi -from pathlib import Path from database import conn from jinja2 import Environment, FileSystemLoader @@ -69,6 +69,14 @@ def application(environ, start_response): 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] From 19e6b6abaf172b1cd05b5559f5333f587ce694ff Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Thu, 19 May 2022 20:39:02 +0000 Subject: [PATCH 6/7] add socket based server --- exemplos/day1/blog/render.py | 4 +--- exemplos/day1/blog/wsgi.py | 3 +-- exemplos/day1/blog_framework/erik.py | 1 - exemplos/day1/blog_jinja/wsgi.py | 6 ++---- exemplos/day1/blog_jinja_blocks/wsgi.py | 6 ++---- exemplos/day1/http_client.py | 14 ++++++++++++++ exemplos/day1/render_message.py | 9 ++++++--- exemplos/day1/server.py | 18 ++++++++++++++++++ exemplos/day1/wsgi_simples.py | 2 +- 9 files changed, 45 insertions(+), 18 deletions(-) create mode 100644 exemplos/day1/http_client.py create mode 100644 exemplos/day1/server.py diff --git a/exemplos/day1/blog/render.py b/exemplos/day1/blog/render.py index 3c828a5..5c65c5e 100644 --- a/exemplos/day1/blog/render.py +++ b/exemplos/day1/blog/render.py @@ -24,9 +24,7 @@ def get_post_url(post): f"
  • {post['title']}
  • " for post in posts ] -index_page.write_text( - index_template.format(post_list="\n".join(post_list)) -) +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: diff --git a/exemplos/day1/blog/wsgi.py b/exemplos/day1/blog/wsgi.py index a6e2548..079e307 100644 --- a/exemplos/day1/blog/wsgi.py +++ b/exemplos/day1/blog/wsgi.py @@ -49,8 +49,7 @@ def application(environ, start_response): if path == "/" and method == "GET": posts = get_posts_from_database() body = render_template( - "list.template.html", - post_list=get_post_list(posts) + "list.template.html", post_list=get_post_list(posts) ) status = "200 OK" diff --git a/exemplos/day1/blog_framework/erik.py b/exemplos/day1/blog_framework/erik.py index 9a7b482..7689820 100644 --- a/exemplos/day1/blog_framework/erik.py +++ b/exemplos/day1/blog_framework/erik.py @@ -91,4 +91,3 @@ def foo2(id): lambda *args: print(args), ) ) - diff --git a/exemplos/day1/blog_jinja/wsgi.py b/exemplos/day1/blog_jinja/wsgi.py index 587ca5a..af563a2 100644 --- a/exemplos/day1/blog_jinja/wsgi.py +++ b/exemplos/day1/blog_jinja/wsgi.py @@ -4,6 +4,7 @@ env = Environment(loader=FileSystemLoader(".")) + def add_new_post(post): cursor = conn.cursor() cursor.execute( @@ -41,10 +42,7 @@ def application(environ, start_response): if path == "/" and method == "GET": posts = get_posts_from_database() - body = render_template( - "list.template.html", - post_list=posts - ) + body = render_template("list.template.html", post_list=posts) status = "200 OK" elif path.split("/")[-1].isdigit() and method == "GET": diff --git a/exemplos/day1/blog_jinja_blocks/wsgi.py b/exemplos/day1/blog_jinja_blocks/wsgi.py index 3a67033..045a39c 100644 --- a/exemplos/day1/blog_jinja_blocks/wsgi.py +++ b/exemplos/day1/blog_jinja_blocks/wsgi.py @@ -5,6 +5,7 @@ env = Environment(loader=FileSystemLoader("templates")) + def add_new_post(post): cursor = conn.cursor() cursor.execute( @@ -42,10 +43,7 @@ def application(environ, start_response): if path == "/" and method == "GET": posts = get_posts_from_database() - body = render_template( - "list.template.html", - post_list=posts - ) + body = render_template("list.template.html", post_list=posts) status = "200 OK" elif path.split("/")[-1].isdigit() and method == "GET": 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/render_message.py b/exemplos/day1/render_message.py index 3815a0f..ad318d2 100644 --- a/exemplos/day1/render_message.py +++ b/exemplos/day1/render_message.py @@ -1,11 +1,14 @@ 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 + +env.filters["addhearts"] = addhearts data = { "name": "Bruno", @@ -13,7 +16,7 @@ def addhearts(text): {"name": "iphone", "price": 13000.320}, {"name": "ferrari", "price": 900000.430}, ], - "special_customer": True + "special_customer": True, } -print(template.render(**data)) \ No newline at end of file +print(template.render(**data)) 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/wsgi_simples.py b/exemplos/day1/wsgi_simples.py index e2d7e81..4f24a9c 100644 --- a/exemplos/day1/wsgi_simples.py +++ b/exemplos/day1/wsgi_simples.py @@ -10,4 +10,4 @@ def application(environ, start_response): from wsgiref.simple_server import make_server server = make_server("0.0.0.0", 8000, application) - server.serve_forever() \ No newline at end of file + server.serve_forever() From c647209dca8607fe5f6bd09417233cc579d20917 Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Mon, 13 Jun 2022 19:13:03 +0100 Subject: [PATCH 7/7] Create ssr.py --- exemplos/day1/ssr.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 exemplos/day1/ssr.py 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))