Life is short, You need Python!
+From 72162b7166ada13e5ac258af91fe2a72173adafc Mon Sep 17 00:00:00 2001 From: 100gle <569590461@qq.com> Date: Thu, 1 Dec 2022 18:43:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=8A=80=E8=83=BD?= =?UTF-8?q?=E6=89=A9=E5=B1=95N7=E4=B8=80=E7=AB=A0=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B=E6=BA=90=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/newsletter/N7/cli.py | 56 +++ code/newsletter/N7/quickstart.ipynb | 397 ++++++++++++++++++ .../N7/templates/inheritance/base.md | 11 + .../N7/templates/inheritance/bug_report.md | 15 + .../N7/templates/project/__init__.py.jinja2 | 0 .../N7/templates/project/main.py.jinja2 | 18 + .../N7/templates/project/views.py.jinja2 | 8 + code/newsletter/N7/templates/web/base.html | 36 ++ code/newsletter/N7/templates/web/index.html | 13 + code/newsletter/N7/templates/web/user.html | 33 ++ code/newsletter/N7/templates/word/base.docx | Bin 0 -> 13695 bytes .../N7/templates/word/mars-cover.jpg | Bin 0 -> 416169 bytes code/newsletter/N7/web.py | 42 ++ code/newsletter/N7/word.py | 34 ++ 14 files changed, 663 insertions(+) create mode 100644 code/newsletter/N7/cli.py create mode 100644 code/newsletter/N7/quickstart.ipynb create mode 100644 code/newsletter/N7/templates/inheritance/base.md create mode 100644 code/newsletter/N7/templates/inheritance/bug_report.md create mode 100644 code/newsletter/N7/templates/project/__init__.py.jinja2 create mode 100644 code/newsletter/N7/templates/project/main.py.jinja2 create mode 100644 code/newsletter/N7/templates/project/views.py.jinja2 create mode 100644 code/newsletter/N7/templates/web/base.html create mode 100644 code/newsletter/N7/templates/web/index.html create mode 100644 code/newsletter/N7/templates/web/user.html create mode 100644 code/newsletter/N7/templates/word/base.docx create mode 100644 code/newsletter/N7/templates/word/mars-cover.jpg create mode 100644 code/newsletter/N7/web.py create mode 100644 code/newsletter/N7/word.py diff --git a/code/newsletter/N7/cli.py b/code/newsletter/N7/cli.py new file mode 100644 index 0000000..986b833 --- /dev/null +++ b/code/newsletter/N7/cli.py @@ -0,0 +1,56 @@ +import argparse +import pathlib + +import jinja2 + +ROOT = pathlib.Path(__file__).parent +TEMPLATE = ROOT / "templates/project" + +env = jinja2.Environment( + trim_blocks=True, + loader=jinja2.FileSystemLoader(TEMPLATE), +) + + +def setup_cli(): + parser = argparse.ArgumentParser() + subparser = parser.add_subparsers() + + startapp = subparser.add_parser("startapp") + startapp.add_argument( + "name", + type=str, + help="the app name", + ) + return parser + + +def build_layout(name: str): + app_dir = ROOT.joinpath(f"{name}") + if app_dir.exists(): + print(f"{name} directory has exists!") + return + else: + app_dir.mkdir() + + for base in TEMPLATE.iterdir(): + basename = base.stem + fpath = app_dir.joinpath(f"{basename}") + if basename == "__init__.py": + fpath.write_text("") + continue + + with open(fpath, mode="w+", encoding="utf-8") as f: + content = env.get_template(base.name).render(app_name=name) + f.write(content) + + +def main(): + parser = setup_cli() + args = parser.parse_args() + print(args) + build_layout(name=args.name) + + +if __name__ == '__main__': + main() diff --git a/code/newsletter/N7/quickstart.ipynb b/code/newsletter/N7/quickstart.ipynb new file mode 100644 index 0000000..7c2be67 --- /dev/null +++ b/code/newsletter/N7/quickstart.ipynb @@ -0,0 +1,397 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import jinja2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# variables" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "your variable value: 100gle\n", + "\n", + "inner set variable value: author\n" + ] + } + ], + "source": [ + "tpl = \"\"\"\\\n", + "your variable value: {{ name }}\n", + "{% set badge=\"author\" %}\n", + "inner set variable value: {{ badge }}\n", + "\"\"\"\n", + "\n", + "template = jinja2.Template(tpl)\n", + "s = template.render(name=\"100gle\")\n", + "print(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# comment" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Hello, world\\n'" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tpl = \"\"\"\\\n", + "Hello, world\n", + "{# this line wouldn't be rendered. #}\n", + "\"\"\"\n", + "\n", + "template = jinja2.Template(tpl)\n", + "template.render()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# for loop" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " * Reading\n", + " * Home Work\n", + " * Exercise\n", + "\n" + ] + } + ], + "source": [ + "tpl = \"\"\"\\\n", + "{# use for-loop in jinja2 #}\n", + "{% for todo in todolist %}\n", + " * {{ todo }}\n", + "{% endfor %}\n", + "\"\"\"\n", + "\n", + "todolist = [\"Reading\", \"Home Work\", \"Exercise\"]\n", + "template = jinja2.Template(tpl, trim_blocks=True)\n", + "s = template.render(todolist=todolist)\n", + "print(s)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " name: Reading\n", + " priority: 2\n", + " name: Home Work\n", + " priority: 0\n", + " name: Exercise\n", + " priority: 1\n", + "\n" + ] + } + ], + "source": [ + "tpl = \"\"\"\\\n", + "{# use for-loop in jinja2 #}\n", + "{% for todo in todolist %}\n", + " {% for key, value in todo.items() %}\n", + " {{ key }}: {{ value }}\n", + " {% endfor %}\n", + "{% endfor %}\n", + "\"\"\"\n", + "\n", + "todolist = [\n", + " dict(name=\"Reading\", priority=2),\n", + " dict(name=\"Home Work\", priority=0),\n", + " dict(name=\"Exercise\", priority=1),\n", + "]\n", + "template = jinja2.Template(tpl, trim_blocks=True, lstrip_blocks=True)\n", + "s = template.render(todolist=todolist)\n", + "print(s)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# if-else" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Reading**\n", + " Home Work\n", + " Exercise*\n", + "\n" + ] + } + ], + "source": [ + "tpl = \"\"\"\\\n", + "{% for todo in todolist %}\n", + " {% if todo.priority == 2 %}\n", + " {{ todo.name }}**\n", + " {% elif todo.priority == 1 %}\n", + " {{ todo.name }}*\n", + " {% else %}\n", + " {{ todo.name }}\n", + " {% endif %}\n", + "{% endfor %}\n", + "\"\"\"\n", + "\n", + "todolist = [\n", + " dict(name=\"Reading\", priority=2),\n", + " dict(name=\"Home Work\", priority=0),\n", + " dict(name=\"Exercise\", priority=1),\n", + "]\n", + "\n", + "template = jinja2.Template(tpl, lstrip_blocks=True, trim_blocks=True)\n", + "s = template.render(todolist=todolist)\n", + "print(s)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# macros" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " Reading**\n", + " Home Work\n", + " Exercise*\n", + "\n" + ] + } + ], + "source": [ + "tpl = \"\"\"\\\n", + "{% macro show_todo(name, priority) -%}\n", + " {% set marker=\"\" %}\n", + " {% if priority == 2 %}\n", + " {% set marker = \"**\" %}\n", + " {% elif priority == 1 %}\n", + " {% set marker = \"*\" %}\n", + " {% endif %}\n", + " {{ name }}{{ marker }}\n", + "{%- endmacro %}\n", + "\n", + "{% for todo in todolist %}\n", + " {{ show_todo(todo.name, todo.priority) }}\n", + "{% endfor %}\n", + "\"\"\"\n", + "\n", + "todolist = [\n", + " dict(name=\"Reading\", priority=2),\n", + " dict(name=\"Home Work\", priority=0),\n", + " dict(name=\"Exercise\", priority=1),\n", + "]\n", + "\n", + "template = jinja2.Template(tpl, trim_blocks=True, lstrip_blocks=True)\n", + "s = template.render(todolist=todolist)\n", + "print(s)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# filter" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " - before: $10.99, after: 10.99\n", + " - before: €0.99, after: 0.99\n", + " - before: ¥100, after: 100\n", + "\n" + ] + } + ], + "source": [ + "def remove_currerncy(val: str):\n", + " currencies = set(\"$€¥\")\n", + " if val[0] in currencies:\n", + " return val[1:]\n", + " return val\n", + "\n", + "tpl = \"\"\"\\\n", + "{% for value in money %}\n", + " - before: {{ value }}, after: {{ value|remove_currency}}\n", + "{% endfor %}\n", + "\"\"\"\n", + "\n", + "money = [\"$10.99\", \"€0.99\", \"¥100\"]\n", + "\n", + "\n", + "env = jinja2.Environment(trim_blocks=True)\n", + "env.filters[\"remove_currency\"] = remove_currerncy\n", + "\n", + "template = env.from_string(tpl)\n", + "s = template.render(money=money)\n", + "print(s)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# inheritance" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# bug: TemplateNotFound error should be fixed.\n", + "\n", + "Your environment:\n", + "\n", + " - python version: 3.9\n", + " - jinja2: 3.2.x\n", + " \n", + "---\n", + "\n", + "Bug detail:\n", + "\n", + "More description here:\n", + "\n", + " ```python\n", + " ...\n", + " ```\n", + "\n" + ] + } + ], + "source": [ + "env = jinja2.Environment(\n", + " trim_blocks=True,\n", + " loader=jinja2.FileSystemLoader(\"./templates/inheritance/\"),\n", + ")\n", + "\n", + "template = env.get_template(\"bug_report.md\")\n", + "s = template.render(\n", + " title=\"bug: TemplateNotFound error should be fixed.\",\n", + " setup=[\n", + " dict(name=\"python version\", detail=3.9),\n", + " dict(name=\"jinja2\", detail=\"3.2.x\"),\n", + " ],\n", + " description=\"\"\"\\\n", + "More description here:\n", + "\n", + " ```python\n", + " ...\n", + " ```\n", + " \"\"\".strip()\n", + ")\n", + "print(s)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.0 ('pandas-startup')", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.0" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "13977d4cc82dee5f9d9535ceb495bd0ab12a43c33c664e5f0d53c24cf634b67f" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/code/newsletter/N7/templates/inheritance/base.md b/code/newsletter/N7/templates/inheritance/base.md new file mode 100644 index 0000000..fad90bb --- /dev/null +++ b/code/newsletter/N7/templates/inheritance/base.md @@ -0,0 +1,11 @@ +# {% block title %}{% endblock %} + +Your environment: + +{% block environment %}{% endblock %} + +--- + +Bug detail: + +{% block description %}{% endblock %} diff --git a/code/newsletter/N7/templates/inheritance/bug_report.md b/code/newsletter/N7/templates/inheritance/bug_report.md new file mode 100644 index 0000000..fd09f6f --- /dev/null +++ b/code/newsletter/N7/templates/inheritance/bug_report.md @@ -0,0 +1,15 @@ +{% extends "base.md" %} + +{% block title %} +{{ title }} +{% endblock %} + +{% block environment %} + {% for item in setup %} + - {{ item.name }}: {{ item.detail }} + {% endfor %} +{% endblock %} + +{% block description %} +{{ description }} +{% endblock %} diff --git a/code/newsletter/N7/templates/project/__init__.py.jinja2 b/code/newsletter/N7/templates/project/__init__.py.jinja2 new file mode 100644 index 0000000..e69de29 diff --git a/code/newsletter/N7/templates/project/main.py.jinja2 b/code/newsletter/N7/templates/project/main.py.jinja2 new file mode 100644 index 0000000..2db12a4 --- /dev/null +++ b/code/newsletter/N7/templates/project/main.py.jinja2 @@ -0,0 +1,18 @@ +import uvicorn +from fastapi import FastAPI + +from {{ app_name }}.views import router + +app = FastAPI() + + +@app.get("/") +async def index(): + return {"msg": "index"} + + +app.include_router(router) + + +if __name__ == '__main__': + uvicorn.run(app) diff --git a/code/newsletter/N7/templates/project/views.py.jinja2 b/code/newsletter/N7/templates/project/views.py.jinja2 new file mode 100644 index 0000000..2ebd167 --- /dev/null +++ b/code/newsletter/N7/templates/project/views.py.jinja2 @@ -0,0 +1,8 @@ +from fastapi import APIRouter + +router = APIRouter(prefix="/{{ app_name }}/api") + + +@router.get("/") +async def index(): + return {"msg": "Hello, world"} diff --git a/code/newsletter/N7/templates/web/base.html b/code/newsletter/N7/templates/web/base.html new file mode 100644 index 0000000..1ba1483 --- /dev/null +++ b/code/newsletter/N7/templates/web/base.html @@ -0,0 +1,36 @@ + + +
+ + + +👋 Halo! Welcome to my website!
+ {% block body %}{% endblock %} +Life is short, You need Python!
+Users:
+| Id | +Name | +
|---|---|
| {{ user.id }} | +{{ user.name }} | +
Whoops! Do you not seem to add any user?
+ {% endif%} +buc|si ZMdG!}!aZa&u>${qqYVt3qqmCM4FLAtOpt
zHY|?EnzbW3)6#_U)BVxr+>&P`@5>1S!Z#}~Zg!CGN;rz6a&IB#n@i7JDP7 pgJQa^dZv8%?Ac?|H
zi;AKb^?=`t12V|1v%q@D#alh&cSA+h_f2UAMg?;M1?gd^g20t6Ygp*m*ruX7Zsuzo
zt60WT%I(lldenN%uG>%`x}j-%vZ8cFJ>|OvWOA0wmBFLf&c!pD9M;!1yQg9l73bu!
z21&eK>@(8vNTqSf(?AHrzT{S?qJLE1?nBI;sCm$~C`rvbm;Ji^<@~Hcc~$@x_?x%t
z#N?7ViTtLQaj?dA`sF)Tw^Nn4vCRz8x90Leia=X|n|Tv*myAg_OF@(GtTPL?=yL@e
zc>tnL$KFuVxbJ-z#II$OePsC0)X1Tx$!5Xx>K)y;Pk-lSG_4#GdA{umu Cd=$Y
zrp~9gr?S4wlFq7G4^#FEaijoj!0WhnxOcaZdgATgA1(^X%GW2WYa}{sf4~3J8wtjJ
zOx?$vNwxKi4OPm1E|Gs90`BWFcu*XJm49LbtD8PIY_h66)cxH7WUTx5|-U)J1%YflFtM9DV3*KxGeayT>z>iyYmJ$kT
zNZJ0_2r6K9)W_`>U_O(u6C`?|nSL3VRpQ|tP}iFb85ypt$(bKH
*@$NA0*2Q5n%+b4)oavZR+-Oi#@lw=w_b89GiZO-V{F>LV|F1@P@LwuL%oxiB^*Jlq|Hi
zkjyX%7>Uuov6g_Mzv&nKz0B;}P&aD@z~!lhvL#c!^*b*|f~URcu`h!@{Z1X;`rzgF
zfs+Fp5-?n$71HJgBK%7W?->{Ki_@
zrtIp2hswa=z7uyEu^S6ptRs|{N@403O$Yu{BU7Aa3$6N%?h&$?clZBtUCi?NiPHYW
zn*)3hn@io_FWP-0xb(gM<2<*gJcbzberm9@(`Kf;QBxg=(I{+_t{Xc*--
zXcN*vNrhuU4sGhM+m@qyp|dmydAe{0`#Iwlt@9GRay3jMv!x}{nE0w1X@8wZm;3J@
z!v8$(6hOKDUHj#gV`bATQZ7M4PfX>p@e;Z<1!}ZgDOyte_y2BkO=|sjbHu;J-#;__
zU@HfUw@39@ort}pE#hrsr#3y2uTtie%xBx|=gS^A#@hpSp7cbOq{}Cm7Dnyq&P>j#
zqK(DuvoDpp9)w|ot|#{TAH0HK??p!BS|xEp9K#ZR4O0nm7uN$(elxd<+QW)YE+osB
z1#XvSpx!+xA(t26wCqFa)z()FacXYV^4Lh>cMvpY9SJ=}!f02FQ4c1<#+UknKn3@H
zYJAlf`(dU0+N