diff --git a/2021/5-30-SMS-api/README.md b/2021/5-30-SMS-api/README.md new file mode 100644 index 0000000..5fa5a32 --- /dev/null +++ b/2021/5-30-SMS-api/README.md @@ -0,0 +1,87 @@ + +# 接收短信验证码 + +- 视频 + - [【推荐】怎样在电脑上接收短信?绿芽-短信转发微信-介绍](https://www.bilibili.com/video/BV1wh411e7rv/) + - [【编程】编写puppeteer机器人自动登录网站,绿芽-短信转发微信-回调api](https://www.bilibili.com/video/BV1yv411V7XB/) + +## 需求 +- 网站登录,需要手机验证码 + - 例如 拼多多 login + +``` +绿芽“短信转发微信”软件 +可以将备用手机中的短信息自动转发到用户的微信上。 +本软件主要应用于以下用户场景: +1、国外旅居或临时出国的用户,希望身在国外时,也能方便的收取到重要的手机短信息(如临时登录网银等处理个人业务等)。 +2、同时拥有多张不同用途的手机卡,某些手机卡并不随身携带在身边,但又希望能需要时方便的收取到手机上的短信息。 +3、需要将短信息同时转发给多人(团队)以方便信息沟通或业务处理的情况。 +4、其它需要将手机短信与微信贯通的情况。 +``` +- 官网 https://www.lvyatech.com/hp/products.jsp +- 小米 安装 + - https://app.mi.com/details?id=com.lvyatech.wxapp.smstowx&ref=search + +## 微信,扫二维码,关注公众号 +``` +恭喜!Xiaomi Redmi Note 7 {代码140582940} 已订阅成功!此后的新短信,将会自动转发到现在这个微信上。 + + 短信转发到微信不会产生短信费啦!快发一条短信试试吧? + + 绿芽是工信部、公安部双备案的正规平台哦,请放心使用吧! +鲁ICP备16006100号 +鲁公网安备 37020302371321号 + + 另外,绿芽平台是无人值守的全自动平台,全年无休哦!所有业务您都可以自助办理的。 + + 如需人工客服,欢迎联系: +微信客服:lvyapay +QQ客服:3455203506 +``` + +## 软件设置 +- 只接收【验证码类短信】 +- 权限设置 + - 发送短信 + - 读取短信 + - 通知类短信 + - 获取手机信息 + - 始终允许 + - 不能设置【空白通行证】,会获取不到卡槽编号,导致不能关联对应的手机号 + - 常驻通知 + - 省电策略为无限制 + +## 接收短信 +``` +155041。【拼多多】您正在登录拼多多,验证码是155041。请于5分钟内完成验证,若非本人操作,请忽略本短信。 +→时间:21-5-25 11:37 +→来自:106551951134188859 + +→转发自:Xiaomi Redmi Note 7 {代码140582940} +``` + +## 费用 +``` +第三方转发是付费的,65元/年,不限量。 +或100元/一万次转发 +测试接口 https://www.tianapi.com/gethttp/ +``` + +## 回调api +- 本手机是红米Note 7 Pro,双卡双待 +- 问题 + - 不能直接获取手机号 + - 通过【设备ID】+【卡槽编号】匹配-手机号 + - 例如 18612345678 安装在卡槽2 + - 接收到回调,js["dId"],js["slt"] + +```json +{"bd":"【拼多多】您正在登录拼多多,验证码是237435。请于5分钟内完成验证,若非本人操作,请忽略本短信。", +"ph":"10693022345860828", +"tm":"1621920486662", +"slt":"1", +"dId":"140582940"} +``` + +- 回调地址 + - https://play4fun.pythonanywhere.com/sms \ No newline at end of file diff --git a/2021/5-30-SMS-api/sms_server.py b/2021/5-30-SMS-api/sms_server.py new file mode 100644 index 0000000..eeccd81 --- /dev/null +++ b/2021/5-30-SMS-api/sms_server.py @@ -0,0 +1,133 @@ +# -*- encoding: utf-8 -*- +''' +@File : sms_server.py +@Time : 2021/05/25 12:26:42 +@Author : HG +@Desc : +''' + +import re +import json +from flask import Flask, request, jsonify +from urllib.parse import unquote, quote + +app = Flask(__name__) + +smsD = dict() # TODO 持久化 + + +@app.route('/get_verify', methods=['GET']) +def get_verify(): + ''' + 请求验证码 + http://192.168.4.237:8097/get_verify?phone= + http://192.168.4.14:8097/get_verify + https://play4fun.pythonanywhere.com/get_verify?phone=6505551212 + + 更新 + https://play4fun.pythonanywhere.com/get_verify?dID=140582940&slt=1 + https://play4fun.pythonanywhere.com/get_verify?dID=140582940&slt=1&source=拼多多 + http://0.0.0.0:8097/get_verify?dID=140582940&slt=1&source=拼多多 + http://0.0.0.0:8097/get_verify?dID=140582940&slt=1 + ''' + rt = { + 'status': 404 # 找不到 + } + p = request.args.get('dID', "") + slt = request.args.get('slt', "") + source = request.args.get('source', "") + if p: + # print(smsD) + # ph = f"{p}-{slt}-{source}" + ph = p+'-'+slt # +'-'+source + # print(ph) + if ph in smsD: + rt['status'] = 200 + rt['data'] = smsD[ph] + + return jsonify(rt) + pass + + +@app.route('/sms', methods=['GET']) # , 'POST' +def sms(): + ''' + http://192.168.4.237:8097/sms? + https://play4fun.pythonanywhere.com/sms + + 测试 + js={ + "bd":"【拼多多】您正在登录拼多多,验证码是790892。请于5分钟内完成验证,若非本人操作,请忽略本短信。", + "ph":"106551951134188852", + "tm":"1621923596617", + "slt":"1", + "dId":"140582940" + } + p=quote(json.dumps(js)) + url='https://play4fun.pythonanywhere.com/sms?p='+p + url='http://0.0.0.0:8097/sms?p='+p + curl url + ''' + # print('args: ', request.args) + # print('form: ', request.form) + rt = { + 'status': 404 + } + + p = request.args.get('p', "") + print('paramer:', p) + if p: + js = json.loads(unquote(p)) + ''' + { + "bd":"【拼多多】您正在登录拼多多,验证码是790892。请于5分钟内完成验证,若非本人操作,请忽略本短信。", + "ph":"106551951134188852", + "tm":"1621923596617", + "slt":"1", + "dId":"140582940" + } + ''' + # print(js) + # dId:发出端设备ID;slt:发出端卡槽号; ph :短信号码;bd:短信内容;tm:短信时间戳 + # print('短信号码', js['ph']) + # print('短信内容', js['bd']) + # print('时间戳', js['tm']) + ''' 日志 + 2021-05-25 05:15:15 短信号码 6505551212 + 2021-05-25 05:15:15 短信内容 lvya test 02 + 2021-05-25 05:15:15 时间戳 1576215934956 + ''' + + content = js['bd'] # 正则 + rs = re.findall('【(.*)】', content) # 哪个网站 + source = rs[0] + rs = re.findall(r'\d{4,6}', content) # 验证码 + vfCode = rs[0] + # ph = f"{js['dId']}-{js['slt']}-{source}" + ph = js['dId']+'-'+js['slt'] # +'-'+source + sd = { + 'timestamp': int(js['tm']), + 'content': content, + 'source': source, + 'vfCode': vfCode, + } + smsD[ph] = sd + # print(sd) + # rt['status'] = 200 + return 'OK' # 他们要求 + + return jsonify(rt) + pass + + +@app.route('/', methods=['GET']) # , 'POST' +def index(): + rt = { + 'status': 200 + } + return jsonify(rt) + pass + + +if __name__ == "__main__": + app.run(debug=True, host='0.0.0.0', port=8097) diff --git a/2021/5-30-puppeteer-REPL/README.md b/2021/5-30-puppeteer-REPL/README.md new file mode 100644 index 0000000..f61e772 --- /dev/null +++ b/2021/5-30-puppeteer-REPL/README.md @@ -0,0 +1,26 @@ + +# 在命令行使用REPL执行puppeteer爬虫和抓包 + +- 视频 B站 [【编程】在命令行使用REPL执行Puppeteer爬虫和抓包,调试代码](https://www.bilibili.com/video/BV1Nq4y1j71W/) +## 什么是REPL ? +- Python + - [为什么解释器的交互模式又叫 REPL](https://zhuanlan.zhihu.com/p/107266796) + - Read Eval Print Loop + - Read,读取用户输入 + - Eval, 执行输入内容 + - Print,打印输出结果 + - Loop, 不断循环以上步骤 + +- Node.js + +## puppeteer 和 REPL +- 参考 + - [puppeteer 调试工具——puppeteer-debug](https://zhuanlan.zhihu.com/p/34970878) + - 不好用,没有更新? + - 最近研究了下用 puppeteer 写爬虫,很好很强大。唯一不太满意的地方就是调试起来有点麻(dan)烦(teng),每调试一步都要重启 + - [puppeteer-extra-plugin-repl](https://www.npmjs.com/package/puppeteer-extra-plugin-repl?activeTab=readme) + - 好用 + - npm i -g puppeteer-extra-plugin-repl + - [Feature request: REPL in puppeteer](https://github.com/puppeteer/puppeteer/issues/3391) + - 最好用 + - 请看 DEMO.JS \ No newline at end of file diff --git "a/2021/5-30-puppeteer-REPL/\345\234\250\345\221\275\344\273\244\350\241\214\351\207\214REPL/DEMO.JS" "b/2021/5-30-puppeteer-REPL/\345\234\250\345\221\275\344\273\244\350\241\214\351\207\214REPL/DEMO.JS" new file mode 100644 index 0000000..5f792b3 --- /dev/null +++ "b/2021/5-30-puppeteer-REPL/\345\234\250\345\221\275\344\273\244\350\241\214\351\207\214REPL/DEMO.JS" @@ -0,0 +1,57 @@ +/** +* @File : DEMO.JS +* @Time : 2021/05/09 18:33:02 +* @Author : HG +* @Desc : +参考 + +没用? +https://shuaiber.medium.com/interactive-puppeteer-setup-822f5ed2a874 + +可行 Feature request: REPL in puppeteer #3391 +https://github.com/puppeteer/puppeteer/issues/3391 +*/ + + + +let browser +let page +async function run(params) {//不行 + browser = await puppeteer.launch({ + args: ["--no-sandbox"], + headless: false + }) + page = await browser.newPage() + await page.goto("https://www.google.com") +} + +//从这里开始 +//在命令行里REPL +const conf = { + headless: false, + executablePath: '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome', + ignoreDefaultArgs: ['--enable-automation'], + defaultViewport: { + width: 1300, + height: 900 + }, + slowMo: 30 +} +pptr = require('puppeteer'); +pptr.launch(conf).then(b => global.browser = b); // to assign to global variable +const ps = await browser.pages(); +browser.pages().then(p => global.page = p[0]); //当前窗口 +// browser.newPage().then(p => global.page = p); + +// 没有意义 没效果 +await page.setJavaScriptEnabled(false); +let gotoURL = 'http://mobile.pinduoduo.com/goods.html?goods_id=218055778729' +page.goto(gotoURL).then(res => console.log(res.url())) + +page.goto('https://www.bing.com/').then(res => console.log(res.url())) +page.waitForSelector('#sb_form_q').then(hdl => { hdl.click(); global.hdl = hdl }) +hdl.type('love') +// page.waitForSelector('#sb_go_par').then(hd => { hd.click() }).then() +// page.waitForSelector('#sb_go_par').then(hd => console.log(res.url())) +page.$('#sb_go_par').then(hd => { hd.click() }).then(console.log('OK ?'))//可以了 +// page.click('#sb_go_par') diff --git "a/2021/5-30-puppeteer-REPL/\345\234\250\345\221\275\344\273\244\350\241\214\351\207\214REPL/debug.js" "b/2021/5-30-puppeteer-REPL/\345\234\250\345\221\275\344\273\244\350\241\214\351\207\214REPL/debug.js" new file mode 100644 index 0000000..5131615 --- /dev/null +++ "b/2021/5-30-puppeteer-REPL/\345\234\250\345\221\275\344\273\244\350\241\214\351\207\214REPL/debug.js" @@ -0,0 +1,47 @@ +/** +* @File : debug.js +* @Time : 2021/05/09 18:40:56 +* @Author : HG +* @Desc : +puppeteer 调试工具—— puppeteer-debug +https://zhuanlan.zhihu.com/p/34970878 +npm i -g puppeteer-debug + +还可以使用 +VS Code 的断点调试 + +*/ + +const conf = { + headless: false, + executablePath: '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome', + ignoreDefaultArgs: ['--enable-automation'], + defaultViewport: { + width: 1300, + height: 900 + }, + slowMo: 30 +} +const puppeteer = require('puppeteer-debug')//不好 +// let page//不行 +async function run() { + const browser = await puppeteer.launch(conf) + let page = await browser.newPage() + // this.page = page //不行 + // global.page = page//不行 + // await puppeteer.debug() // or: await puppeteer.debug({ browser, page, ... }), pass initial context to REPL. + await page.goto('https://www.bing.com/') + await page.waitForTimeout(2000) + // let producttype = (await page.$('#idProductType')) || ""; + let producttype = (await page.waitForSelector('#idProductType')) || ""; //不行 + console.log('producttype:', producttype, '|', typeof producttype2); + // let producttype2 = (await page.$('#sb_form_q')) || ""; + let producttype2 = (await page.waitForSelector('#sb_form_q')) || ""; + console.log('producttype:', typeof producttype2); + + await puppeteer.debug({ browser, page })// 可以 + await browser.close() + page.goto('https://www.bing.com/') + page.waitForSelector('#sb_form_q').then(hdl => { hdl.click(); hdl.type('love') }) +} +run() \ No newline at end of file diff --git "a/2021/5-30-puppeteer-REPL/\345\234\250\345\221\275\344\273\244\350\241\214\351\207\214REPL/puppeteer-extra-plugin-repl.js" "b/2021/5-30-puppeteer-REPL/\345\234\250\345\221\275\344\273\244\350\241\214\351\207\214REPL/puppeteer-extra-plugin-repl.js" new file mode 100644 index 0000000..8c90ccc --- /dev/null +++ "b/2021/5-30-puppeteer-REPL/\345\234\250\345\221\275\344\273\244\350\241\214\351\207\214REPL/puppeteer-extra-plugin-repl.js" @@ -0,0 +1,25 @@ +/** +* @File : puppeteer-extra-plugin-repl.js +* @Time : 2021/05/09 19:08:11 +* @Author : HG +* @Desc : 更好 +https://www.npmjs.com/package/puppeteer-extra-plugin-repl?activeTab=readme + +npm i -g puppeteer-extra-plugin-repl + +*/ + +const puppeteer = require('puppeteer-extra') +puppeteer.use(require('puppeteer-extra-plugin-repl')()) + +puppeteer.launch({ headless: true }).then(async browser => { + const page = await browser.newPage() + await page.goto('https://example.com') + + // Start an interactive REPL here with the `page` instance. + await page.repl() + // Afterwards start REPL with the `browser` instance. + await browser.repl() + + await browser.close() +}) \ No newline at end of file diff --git a/2021/6-19-list-groupby/README.md b/2021/6-19-list-groupby/README.md new file mode 100644 index 0000000..c933c46 --- /dev/null +++ b/2021/6-19-list-groupby/README.md @@ -0,0 +1,10 @@ + +# python list groupby +- python 列表 排序+分组 + - 需求: 按字段排序,然后分组 +- 视频 [【编程】一行代码!Python 列表 排序+分组 sorted groupby Counter](https://www.bilibili.com/video/BV1LM4y1g7Vu/) + +- 参考 + - [B站搜索](https://search.bilibili.com/all?keyword=python%20list%20groupby&from_source=web_search) + - [Python list列表groupby分组用法](https://blog.csdn.net/xiaoc100200/article/details/111402566) + - 注意: 分组之前应先使用分组字段先排好序 \ No newline at end of file diff --git a/2021/6-19-list-groupby/groupby.py b/2021/6-19-list-groupby/groupby.py new file mode 100644 index 0000000..abb9f0a --- /dev/null +++ b/2021/6-19-list-groupby/groupby.py @@ -0,0 +1,68 @@ +# -*- encoding: utf-8 -*- +''' +@File : groupby.py +@Time : 2021/06/19 09:38:40 +@Author : GH +@Desc : https://blog.csdn.net/xiaoc100200/article/details/111402566 +python 列表 排序+分组 +需求: 按字段排序,然后分组 +''' + +from itertools import groupby +# from collections import Counter# 统计 + +user_list = [ + {"uid": 1, "sex": "男", "age": 10}, + {"uid": 3, "sex": "男", "age": 20}, + {"uid": 4, "sex": "女", "age": 20}, + {"uid": 4, "sex": "女", "age": 31}, + {"uid": 2, "sex": "男", "age": 10} +] +user_sort = sorted(user_list, key=lambda x: (x["sex"], x["age"])) # 必须排序 +[{'uid': 4, 'sex': '女', 'age': 20}, + {'uid': 4, 'sex': '女', 'age': 31}, + {'uid': 1, 'sex': '男', 'age': 10}, + {'uid': 2, 'sex': '男', 'age': 10}, + {'uid': 3, 'sex': '男', 'age': 20}] + +# 手写代码 +outD = {} +for d in user_list: + tl = outD.get(d['sex'], []) + tl.append(d) + outD[d['sex']] = tl +# print(outD) +for k, v in outD.items(): + print(k, ':', v) + +# 使用系统库 +# 一行代码 +user_group = groupby(user_sort, key=lambda x: (x["sex"], x["age"])) +for key, group in user_group: + print(key, list(group)) + +# ('女', 20) [{'uid': 4, 'sex': '女', 'age': 20}] +# ('女', 31) [{'uid': 4, 'sex': '女', 'age': 31}] +# ('男', 10) [{'uid': 1, 'sex': '男', 'age': 10}, {'uid': 2, 'sex': '男', 'age': 10}] +# ('男', 20) [{'uid': 3, 'sex': '男', 'age': 20}] + +print('-'*30) + + +def g(x): # 自定义分组key + if (x['age'] > 0) and (x['age'] <= 10): + return 'small' # 儿童 + elif (x['age'] > 10) and (x['age'] <= 20): + return 'mid' # 少年 + else: + return 'max' # 大人 + + +user_group = groupby(user_sort, key=g) +for key, group in user_group: + print(key, list(group)) + +# mid[{'uid': 4, 'sex': '女', 'age': 20}] +# max[{'uid': 4, 'sex': '女', 'age': 31}] +# small[{'uid': 1, 'sex': '男', 'age': 10}, {'uid': 2, 'sex': '男', 'age': 10}] +# mid[{'uid': 3, 'sex': '男', 'age': 20}] diff --git a/2021/7-11-Flask-Pydantic/README.md b/2021/7-11-Flask-Pydantic/README.md new file mode 100644 index 0000000..34ea3de --- /dev/null +++ b/2021/7-11-Flask-Pydantic/README.md @@ -0,0 +1,18 @@ + +## Flask-Pydantic Flask使用Pydantic + +- 视频 [【编程】Flask使用Pydantic进行数据校验,Python fastapi](https://www.bilibili.com/video/bv16f4y1L7Rm) + +- 安装 + - https://pypi.org/project/Flask-Pydantic/ + - pip install Flask-Pydantic + - 源代码 https://github.com/bauerji/flask_pydantic + +- 参考 + - [如何评价最近爆红的FastAPI?](https://www.zhihu.com/question/424133076) + - [请不要把 Flask 和 FastAPI 放到一起比较](https://zhuanlan.zhihu.com/p/369591096) + - [用它5分钟以后,我放弃用了四年的 Flask](https://juejin.cn/post/6844904051327369224) + +- 注意 + - @validate() 接口参数字段,必须是body,或 query + - 否则报错 \ No newline at end of file diff --git a/2021/7-11-Flask-Pydantic/fastapi_pydantic1.py b/2021/7-11-Flask-Pydantic/fastapi_pydantic1.py new file mode 100644 index 0000000..ad5e0ac --- /dev/null +++ b/2021/7-11-Flask-Pydantic/fastapi_pydantic1.py @@ -0,0 +1,31 @@ +# -*- encoding: utf-8 -*- +''' +@File : fastapi_pydantic1.py +@Time : 2021/07/11 11:02:05 +@Author : GH +@Desc : +参考 +https://juejin.cn/post/6844904051327369224 + +运行 +uvicorn fastapi_pydantic1:app --port 5000 +''' + +from fastapi import FastAPI +from pydantic import BaseModel + +app = FastAPI() + + +class People(BaseModel): + name: str + age: int + # address: str + # salary: float + + +@app.post('/insert') +def insert(people: People): + age_after_10_years = people.age + 10 + msg = f'此人名字叫做:{people.name},十年后此人年龄:{age_after_10_years}' + return {'success': True, 'msg': msg} diff --git a/2021/7-11-Flask-Pydantic/flask_pydantic1.py b/2021/7-11-Flask-Pydantic/flask_pydantic1.py new file mode 100644 index 0000000..f575584 --- /dev/null +++ b/2021/7-11-Flask-Pydantic/flask_pydantic1.py @@ -0,0 +1,85 @@ +# -*- encoding: utf-8 -*- +''' +@File : flask_pydantic1.py +@Time : 2021/07/11 10:53:01 +@Author : GH +@Desc : + +命令行 +curl -v -H "Content-Type: application/json" -XPOST http://localhost:5000/insert -d '{ +"name" : "werl", +"age" : 5 +}' +# 把age改为字符串 报错 +curl -v -H "Content-Type: application/json" -XPOST http://localhost:5000/insert -d '{ +"name" : "werl", +"age" : "5" +}' + +# 使用pydantic +curl -v -H "Content-Type: application/json" -XPOST "http://localhost:5000/insert?name=fjks&age=35" -d '{ +"name" : "werl", +"age" : "5" +}' + +''' + +from flask import Flask, request +from pydantic import BaseModel +from flask_pydantic import validate + +app = Flask("__main__") + + +class QueryModel(BaseModel): + name: str + age: int + + +class People(BaseModel): + name: str + age: int + # address: str + # salary: float + + +@app.route('/insert', methods=['POST']) +@validate(body=People) +def insert(body: People, query: QueryModel): + print('body:', body) # body: name='werl' age=5 + print('query:', query) # query: name='fjks' age=35 + age_after_10_years = body.age + 10 + msg = f'此人名叫:{body.name},10年后,此人年龄:{age_after_10_years}' + return {'success': True, 'msg': msg} + + +@app.route('/insert0', methods=['POST']) +def insert0(): + info = request.json + name = info['name'] + age = info['age'] + age_after_10_years = age + 10 + msg = f'此人名叫:{name},10年后,此人年龄:{age_after_10_years}' + return {'success': True, 'msg': msg} + + +@app.route('/insert2', methods=['POST']) +def insert2(): + info = request.json + name = info.get('name', '') + if not name: + return {'success': False, 'msg': 'name 参数不可省略,不可为空!'} + age = info.get('age', 0) + if not isinstance(age, int): + return {'success': False, 'msg': 'age参数不是数字!'} + age_after_10_years = age + 10 + msg = f'此人名叫:{name},10年后,此人年龄:{age_after_10_years}' + return {'success': True, 'msg': msg} + + +def main(): + pass + + +if __name__ == "__main__": + app.run(debug=True) diff --git a/2021/7-25-Lorca/README.MD b/2021/7-25-Lorca/README.MD new file mode 100644 index 0000000..586a73f --- /dev/null +++ b/2021/7-25-Lorca/README.MD @@ -0,0 +1,58 @@ + +- 视频 [【编程】Lorca-Go语言-跨平台-桌面应用开发框架-比Electron好用,在 Go + HTML5 中构建跨平台的现代桌面应用程序](https://www.bilibili.com/video/BV1Tg411779a/) + +## 什么是Lorca? +Go语言的桌面应用开发框架 + +- 对比Electron + - Go语言,执行效率快。二进制程序 + - Node.js 需要V8引擎 Chome + - 结构简单 + - 代码加密,很难破解 + - 还可以加壳 + - Electron可以混扰代码,增加阅读难度,但是代码可以恢复,只要花点时间 assr + - 打包方便,一个文件搞定 + - 文件很小,不到10M + - Electron即使是最小应用,也有100M + - Electron会打包 node_modules + - 跨平台方便 + - 唯一的问题 + - Lorca依赖Chrome浏览器,需要在系统里提前安装 + +- 特征 + - 带有非常简单的 API 的纯 Go 库(无 cgo) + - 小应用程序大小(通常 5-10MB) + - 两全其美 - HTML/CSS 的全部力量使您的 UI 看起来不错,结合 Go 性能和易于开发 + - 公开 Go 函数/方法并从 JavaScript 调用它们 + - 从 Go 调用任意 JavaScript 代码 + - 两种语言的 UI 和主应用程序之间的异步流(async/await 和 Goroutines) + - 支持从本地 Web 服务器或通过数据 URL 加载 Web UI + - 支持在无头模式下使用 UI 测试您的应用 + - 支持多个应用程序窗口 + - 支持包装和品牌(例如自定义应用程序图标)。可以使用 GOOS 和 GOARCH 变量在一台机器上完成所有三个操作系统的打包。 +- 此外,设计限制: + - 需要安装 Chrome/Chromium >= 70。 + - 尚无法控制 Chrome 窗口(例如,您无法移除边框、使其透明、控制位置或大小)。 + - 没有窗口菜单(托盘菜单和本机操作系统对话框仍然可以通过 3rd-party 库) + + + +网址 ? +https://github.com/zserge/lorca/tree/master/examples +https://github.com/zserge/lorca/tree/master/examples/counter + + +错误 +go run main.go +build command-line-arguments: cannot load embed: malformed module path "embed": missing dot in first path element + +需要安装 Go 1.16 RC1 才能运行它。 + +运行 +go1.16 mod init counter +go1.16 get github.com/zserge/lorca +go1.16 run main.go + +chmod -R 777 Example.app/ +go1.16 build -o Example.app/Contents/MacOS/lorca-example +编译Windows CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go1.16 build -v -o counter_win10 main.go \ No newline at end of file diff --git a/2021/7-25-Lorca/examples/counter/Example.app/Contents/Info.plist b/2021/7-25-Lorca/examples/counter/Example.app/Contents/Info.plist new file mode 100755 index 0000000..d8046f1 --- /dev/null +++ b/2021/7-25-Lorca/examples/counter/Example.app/Contents/Info.plist @@ -0,0 +1,12 @@ + + + + + CFBundleExecutable + lorca-example + CFBundleIconFile + icon.icns + CFBundleIdentifier + com.zserge.lorca.example + + diff --git a/2021/7-25-Lorca/examples/counter/Example.app/Contents/MacOS/lorca-example b/2021/7-25-Lorca/examples/counter/Example.app/Contents/MacOS/lorca-example new file mode 100755 index 0000000..d26ac33 Binary files /dev/null and b/2021/7-25-Lorca/examples/counter/Example.app/Contents/MacOS/lorca-example differ diff --git a/2021/7-25-Lorca/examples/counter/Example.app/Contents/Resources/icon.icns b/2021/7-25-Lorca/examples/counter/Example.app/Contents/Resources/icon.icns new file mode 100755 index 0000000..58689ff Binary files /dev/null and b/2021/7-25-Lorca/examples/counter/Example.app/Contents/Resources/icon.icns differ diff --git a/2021/7-25-Lorca/examples/counter/build-linux.sh b/2021/7-25-Lorca/examples/counter/build-linux.sh new file mode 100755 index 0000000..6d6a619 --- /dev/null +++ b/2021/7-25-Lorca/examples/counter/build-linux.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +APP=lorca-example +APPDIR=${APP}_1.0.0 + +mkdir -p $APPDIR/usr/bin +mkdir -p $APPDIR/usr/share/applications +mkdir -p $APPDIR/usr/share/icons/hicolor/1024x1024/apps +mkdir -p $APPDIR/usr/share/icons/hicolor/256x256/apps +mkdir -p $APPDIR/DEBIAN + +go build -o $APPDIR/usr/bin/$APP + +cp icons/icon.png $APPDIR/usr/share/icons/hicolor/1024x1024/apps/${APP}.png +cp icons/icon.png $APPDIR/usr/share/icons/hicolor/256x256/apps/${APP}.png + +cat > $APPDIR/usr/share/applications/${APP}.desktop << EOF +[Desktop Entry] +Version=1.0 +Type=Application +Name=$APP +Exec=$APP +Icon=$APP +Terminal=false +StartupWMClass=Lorca +EOF + +cat > $APPDIR/DEBIAN/control << EOF +Package: ${APP} +Version: 1.0-0 +Section: base +Priority: optional +Architecture: amd64 +Maintainer: Serge Zaitsev +Description: Example for Lorca GUI toolkit +EOF + +dpkg-deb --build $APPDIR diff --git a/2021/7-25-Lorca/examples/counter/build-macos.sh b/2021/7-25-Lorca/examples/counter/build-macos.sh new file mode 100755 index 0000000..997591c --- /dev/null +++ b/2021/7-25-Lorca/examples/counter/build-macos.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +APP="Example.app" +mkdir -p $APP/Contents/{MacOS,Resources} +go1.16 build -o $APP/Contents/MacOS/lorca-example +cat > $APP/Contents/Info.plist << EOF + + + + + CFBundleExecutable + lorca-example + CFBundleIconFile + icon.icns + CFBundleIdentifier + com.zserge.lorca.example + + +EOF +cp icons/icon.icns $APP/Contents/Resources/icon.icns +find $APP diff --git a/2021/7-25-Lorca/examples/counter/build-windows.bat b/2021/7-25-Lorca/examples/counter/build-windows.bat new file mode 100644 index 0000000..4d7043c --- /dev/null +++ b/2021/7-25-Lorca/examples/counter/build-windows.bat @@ -0,0 +1,3 @@ +@echo off +go generate +go build -ldflags "-H windowsgui" -o lorca-example.exe diff --git a/2021/7-25-Lorca/examples/counter/counter.gif b/2021/7-25-Lorca/examples/counter/counter.gif new file mode 100644 index 0000000..2497ed5 Binary files /dev/null and b/2021/7-25-Lorca/examples/counter/counter.gif differ diff --git a/2021/7-25-Lorca/examples/counter/counter_win10 b/2021/7-25-Lorca/examples/counter/counter_win10 new file mode 100755 index 0000000..f4fcdb5 Binary files /dev/null and b/2021/7-25-Lorca/examples/counter/counter_win10 differ diff --git a/2021/7-25-Lorca/examples/counter/go.mod b/2021/7-25-Lorca/examples/counter/go.mod new file mode 100644 index 0000000..d80355a --- /dev/null +++ b/2021/7-25-Lorca/examples/counter/go.mod @@ -0,0 +1,5 @@ +module counter + +go 1.16 + +require github.com/zserge/lorca v0.1.10 // indirect diff --git a/2021/7-25-Lorca/examples/counter/go.sum b/2021/7-25-Lorca/examples/counter/go.sum new file mode 100644 index 0000000..67e500c --- /dev/null +++ b/2021/7-25-Lorca/examples/counter/go.sum @@ -0,0 +1,9 @@ +github.com/zserge/lorca v0.1.9 h1:vbDdkqdp2/rmeg8GlyCewY2X8Z+b0s7BqWyIQL/gakc= +github.com/zserge/lorca v0.1.9/go.mod h1:bVmnIbIRlOcoV285KIRSe4bUABKi7R7384Ycuum6e4A= +github.com/zserge/lorca v0.1.10 h1:f/xBJ3D3ipcVRCcvN8XqZnpoKcOXV8I4vwqlFyw7ruc= +github.com/zserge/lorca v0.1.10/go.mod h1:bVmnIbIRlOcoV285KIRSe4bUABKi7R7384Ycuum6e4A= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0 h1:MsuvTghUPjX762sGLnGsxC3HM0B5r83wEtYcYR8/vRs= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/2021/7-25-Lorca/examples/counter/icons/icon-256.png b/2021/7-25-Lorca/examples/counter/icons/icon-256.png new file mode 100644 index 0000000..7c0fccf Binary files /dev/null and b/2021/7-25-Lorca/examples/counter/icons/icon-256.png differ diff --git a/2021/7-25-Lorca/examples/counter/icons/icon.icns b/2021/7-25-Lorca/examples/counter/icons/icon.icns new file mode 100644 index 0000000..58689ff Binary files /dev/null and b/2021/7-25-Lorca/examples/counter/icons/icon.icns differ diff --git a/2021/7-25-Lorca/examples/counter/icons/icon.png b/2021/7-25-Lorca/examples/counter/icons/icon.png new file mode 100644 index 0000000..418861d Binary files /dev/null and b/2021/7-25-Lorca/examples/counter/icons/icon.png differ diff --git a/2021/7-25-Lorca/examples/counter/main.go b/2021/7-25-Lorca/examples/counter/main.go new file mode 100644 index 0000000..81e0448 --- /dev/null +++ b/2021/7-25-Lorca/examples/counter/main.go @@ -0,0 +1,98 @@ +/** +* @File : main.go +* @Time : 2021/07/22 11:51:17 +* @Author : GH +* @Desc : +*/ + + + +package main + +import ( + "embed" + "fmt" + "log" + "net" + "net/http" + "os" + "os/signal" + "runtime" + "sync" + + "github.com/zserge/lorca" +) + +//go:embed www +var fs embed.FS + +// Go types that are bound to the UI must be thread-safe, because each binding +// is executed in its own goroutine. In this simple case we may use atomic +// operations, but for more complex cases one should use proper synchronization. +type counter struct { + sync.Mutex + count int +} + +func (c *counter) Add(n int) { + c.Lock() + defer c.Unlock() + c.count = c.count + n +} + +func (c *counter) Value() int { + c.Lock() + defer c.Unlock() + return c.count +} + +func main() { + args := []string{} + if runtime.GOOS == "linux" { + args = append(args, "--class=Lorca") + } + ui, err := lorca.New("", "", 480, 320, args...) + if err != nil { + log.Fatal(err) + } + defer ui.Close() + + // A simple way to know when UI is ready (uses body.onload event in JS) + ui.Bind("start", func() { + log.Println("UI is ready") + }) + + // Create and bind Go object to the UI + c := &counter{} + ui.Bind("counterAdd", c.Add) + ui.Bind("counterValue", c.Value) + + // Load HTML. + // You may also use `data:text/html,` approach to load initial HTML, + // e.g: ui.Load("data:text/html," + url.PathEscape(html)) + + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + log.Fatal(err) + } + defer ln.Close() + go http.Serve(ln, http.FileServer(http.FS(fs))) + ui.Load(fmt.Sprintf("http://%s/www", ln.Addr())) + + // You may use console.log to debug your JS code, it will be printed via + // log.Println(). Also exceptions are printed in a similar manner. + ui.Eval(` + console.log("Hello, world!"); + console.log('Multiple values:', [1, false, {"x":5}]); + `) + + // Wait until the interrupt signal arrives or browser window is closed + sigc := make(chan os.Signal) + signal.Notify(sigc, os.Interrupt) + select { + case <-sigc: + case <-ui.Done(): + } + + log.Println("exiting...") +} diff --git a/2021/7-25-Lorca/examples/counter/www/favicon.png b/2021/7-25-Lorca/examples/counter/www/favicon.png new file mode 100644 index 0000000..82ff856 Binary files /dev/null and b/2021/7-25-Lorca/examples/counter/www/favicon.png differ diff --git a/2021/7-25-Lorca/examples/counter/www/index.html b/2021/7-25-Lorca/examples/counter/www/index.html new file mode 100644 index 0000000..467b8dc --- /dev/null +++ b/2021/7-25-Lorca/examples/counter/www/index.html @@ -0,0 +1,51 @@ + + + + Counter + + + + + +
+
+
+
+1
+
-1
+
+
+ + + + + diff --git a/2021/7-25-Lorca/examples/hello/hello_win10 b/2021/7-25-Lorca/examples/hello/hello_win10 new file mode 100755 index 0000000..264e467 Binary files /dev/null and b/2021/7-25-Lorca/examples/hello/hello_win10 differ diff --git a/2021/7-25-Lorca/examples/hello/main.go b/2021/7-25-Lorca/examples/hello/main.go new file mode 100644 index 0000000..9594465 --- /dev/null +++ b/2021/7-25-Lorca/examples/hello/main.go @@ -0,0 +1,40 @@ +/** +* @File : main.go +* @Time : 2021/07/22 14:20:03 +* @Author : GH +* @Desc : + +编译windows +CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -v -o hello_win10 main.go + +*/ + + +package main + +import ( + "log" + "net/url" + + "github.com/zserge/lorca" +) + +func main() { + // Create UI with basic HTML passed via data URI + ui, err := lorca.New("data:text/html,"+url.PathEscape(` + + Hello +

Hello, world!

+ + `), "", 480, 320) + if err != nil { + log.Fatal(err) + } + defer ui.Close() + + ui.Bind("addUp", func(a, b int) int { return a + b }) + // let x=await addUp(34534342,23748374823) + + // Wait until UI window is closed + <-ui.Done() +} diff --git a/2021/7-25-Lorca/examples/hello/main_macOS b/2021/7-25-Lorca/examples/hello/main_macOS new file mode 100755 index 0000000..3601a8e Binary files /dev/null and b/2021/7-25-Lorca/examples/hello/main_macOS differ diff --git a/2021/7-25-Lorca/examples/stopwatch/main.go b/2021/7-25-Lorca/examples/stopwatch/main.go new file mode 100644 index 0000000..04f3548 --- /dev/null +++ b/2021/7-25-Lorca/examples/stopwatch/main.go @@ -0,0 +1,69 @@ +/** +* @File : main.go +* @Time : 2021/07/22 14:58:21 +* @Author : GH +* @Desc : + +编译windows +CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -v -o stopwatch_win10 main.go + +*/ + + +package main + +import ( + "fmt" + "log" + "net/url" + "sync/atomic" + "time" + + "github.com/zserge/lorca" +) + +func main() { + ui, err := lorca.New("计时器", "", 480, 320) + if err != nil { + log.Fatal(err) + } + defer ui.Close() + + // Data model: number of ticks + ticks := uint32(0) + // Channel to connect UI events with the background ticking goroutine + togglec := make(chan bool) + // Bind Go functions to JS + ui.Bind("toggle", func() { togglec <- true }) + ui.Bind("reset", func() { + atomic.StoreUint32(&ticks, 0) + ui.Eval(`document.querySelector('.timer').innerText = '0'`) + ui.Eval(`console.log("reset ....")`)// 打印日志 + }) + + // Load HTML after Go functions are bound to JS + ui.Load("data:text/html," + url.PathEscape(` + + + +
+ + + + `)) + + // Start ticker goroutine + go func() { + t := time.NewTicker(100 * time.Millisecond) + for { + select { + case <-t.C: // Every 100ms increate number of ticks and update UI + ui.Eval(fmt.Sprintf(`document.querySelector('.timer').innerText = 0.1*%d`, + atomic.AddUint32(&ticks, 1))) + case <-togglec: // If paused - wait for another toggle event to unpause + <-togglec + } + } + }() + <-ui.Done() +} diff --git a/2021/7-25-Lorca/examples/stopwatch/main_macOS b/2021/7-25-Lorca/examples/stopwatch/main_macOS new file mode 100755 index 0000000..e9a67ee Binary files /dev/null and b/2021/7-25-Lorca/examples/stopwatch/main_macOS differ diff --git a/2021/7-25-Lorca/examples/stopwatch/stopwatch_win10 b/2021/7-25-Lorca/examples/stopwatch/stopwatch_win10 new file mode 100755 index 0000000..37f1133 Binary files /dev/null and b/2021/7-25-Lorca/examples/stopwatch/stopwatch_win10 differ diff --git a/2021/7-4-diskcache/README.md b/2021/7-4-diskcache/README.md new file mode 100644 index 0000000..943d7bb --- /dev/null +++ b/2021/7-4-diskcache/README.md @@ -0,0 +1,22 @@ + +# diskcache本地缓存持久化 + +- 视频 [【编程】Python : diskcache 本地缓存持久化,一行代码](https://www.bilibili.com/video/BV1dv411H77k/) + +- 缓存考虑 + - Redis 数据库 + - memcache + +- 临时缓存 + - lru_cache 服务器使用 + - from functools import lru_cache + +- 推荐使用 + - [diskcache](https://pypi.org/project/diskcache/) + + +- 教程 + - 安装 https://pypi.org/project/diskcache/ + - 教程 http://www.grantjenks.com/docs/diskcache/tutorial.html + - 问题 https://stackoverflow.com/questions/16463582/memoize-to-disk-python-persistent-memoization + diff --git a/2021/7-4-diskcache/diskcache1.py b/2021/7-4-diskcache/diskcache1.py new file mode 100644 index 0000000..9bf7df7 --- /dev/null +++ b/2021/7-4-diskcache/diskcache1.py @@ -0,0 +1,33 @@ +# -*- encoding: utf-8 -*- +''' +@File : diskcache1.py +@Time : 2021/07/04 12:47:38 +@Author : GH +@Desc : +''' +import requests +from functools import lru_cache + +from diskcache import Cache +cache = Cache('cachedir') + + +# @lru_cache() # Flask 服务器使用,才行 +@cache.memoize() +def get_ip(a): # 需要很多计算,计算一次就可以了 + print('不使用缓存') + url = 'https://httpbin.org/ip' + rs = requests.get(url) + print('get IP:', rs.text) + + return rs.json()['origin'] + + +def main(): + ip = get_ip(a=1) + print(ip) + pass + + +if __name__ == "__main__": + main() diff --git a/2021/8-1-deta-fastapi/README.md b/2021/8-1-deta-fastapi/README.md new file mode 100644 index 0000000..ad0f9ad --- /dev/null +++ b/2021/8-1-deta-fastapi/README.md @@ -0,0 +1,55 @@ + +- 视频 ?? + +- 文档 + - 部署到Deta[Deploy FastAPI on Deta](https://fastapi.tiangolo.com/zh/deployment/deta/) + - 开始启动[Getting Started](https://docs.deta.sh/docs/micros/getting_started/) + +- 安装 +```bash +(.py39) pro:~ play$ curl -fsSL https://get.deta.dev/cli.sh | sh +########################################################################################## 100.0% +Archive: /Users/play/.deta/bin/deta.zip + inflating: deta + inflating: ._deta +Deta was installed successfully to /Users/play/.deta/bin/deta +Run 'deta --help' in a new shell to get started +``` +- 登录 +```bash +(.py39) pro:~ play$ /Users/play/.deta/bin/deta login +Please, log in from the web page. Waiting.. +https://web.deta.sh/cli/52934 +Logged in successfully. +``` +- 新建 +```bash +(.py39) pro:app play$ /Users/play/.deta/bin/deta new +Successfully created a new micro +{ + "name": "app", + "runtime": "python3.7", + "endpoint": "https://zba3nl.deta.dev", + "visor": "enabled", + "http_auth": "disabled" +} +Adding dependencies... +Collecting fastapi + Downloading https://files.pythonhosted.org/packages/52/be/2a26007dc86c51e87d70021f6c1b3442726c5918fe57d27927badf687122/fastapi-0.67.0-py3-none-any.whl (51kB) +Collecting starlette==0.14.2 + Downloading https://files.pythonhosted.org/packages/15/34/db1890f442a1cd3a2c761f4109a0eb4e63503218d70a8c8e97faa09a5500/starlette-0.14.2-py3-none-any.whl (60kB) +Collecting pydantic!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<2.0.0,>=1.6.2 + Downloading https://files.pythonhosted.org/packages/9f/f2/2d5425efe57f6c4e06cbe5e587c1fd16929dcf0eb90bd4d3d1e1c97d1151/pydantic-1.8.2-cp37-cp37m-manylinux2014_x86_64.whl (10.1MB) +Collecting typing-extensions>=3.7.4.3 + Downloading https://files.pythonhosted.org/packages/2e/35/6c4fff5ab443b57116cb1aad46421fb719bed2825664e8fe77d66d99bcbc/typing_extensions-3.10.0.0-py3-none-any.whl +Installing collected packages: starlette, typing-extensions, pydantic, fastapi +Successfully installed fastapi-0.67.0 pydantic-1.8.2 starlette-0.14.2 typing-extensions-3.10.0.0 +``` +- 更新 +``` + +``` + +## 数据库 + +## 文件存储 \ No newline at end of file diff --git a/2021/8-15-Marp-ppt/IMG_20210715_122251.jpg b/2021/8-15-Marp-ppt/IMG_20210715_122251.jpg new file mode 100755 index 0000000..6dd7964 Binary files /dev/null and b/2021/8-15-Marp-ppt/IMG_20210715_122251.jpg differ diff --git a/2021/8-15-Marp-ppt/IMG_20210806_092900.jpg b/2021/8-15-Marp-ppt/IMG_20210806_092900.jpg new file mode 100755 index 0000000..c56c3c3 Binary files /dev/null and b/2021/8-15-Marp-ppt/IMG_20210806_092900.jpg differ diff --git a/2021/8-15-Marp-ppt/README.MD b/2021/8-15-Marp-ppt/README.MD new file mode 100644 index 0000000..be584bc --- /dev/null +++ b/2021/8-15-Marp-ppt/README.MD @@ -0,0 +1,53 @@ +--- +marp: true +--- + +# Marp:用 Markdown「写」PPT 的新选择 +- Marp + - Markdown --> PPT + +--- +# 需求 +- 制作视频之前,写文案 + - 工作量少,简单 + - 不想写一堆代码 + - 翻页效果,即可。 + - 有动画更好 +- 简洁,清晰明了 + - 不想做得花里胡哨 +- 视频 [【新技能】Marp 使用 Markdown 制作 PPT , 电脑不用安装PowerPoint](https://www.bilibili.com/video/BV17v411T7wH/) +--- +- 参考 + - [Marp:用 Markdown「写」PPT 的新选择](https://sspai.com/post/55718) + - 前往 VSCode 的网站 下载并安装 VSCode 本体, + - 然后在左侧的插件栏中搜索并安装 Marp for VS Code。 + - 为了获得更好的 Markdown 编辑体验,大家不妨再安装一个叫做 Markdown All in One 的插件,然后就可以开始愉快地使用 Marp 了。 + - 使用 Markdown 预览功能,确认无误后,再导出 + - toggle打开或关闭特效 + - marp: true + - 缺点,没有动画特效 +- Demo + - https://yhatt-marp-cli-example.netlify.app/#1 + - 代码 https://github.com/yhatt/marp-cli-example + +# reveal.js 官网 https://revealjs.com/ +--- +编辑完成后,通过编辑器右上角的 Marp 图标按钮就可以调出 Export slide deck 命令并导出幻灯片了。Marp 插件目前支持导出 HTML 和 PDF 格式,另外可以将首页导出为 PNG 或 JPEG 格式的图片。 + +需要注意的是,目前导出 PDF 或者图片时需要依赖 Chromium 内核的浏览器。最终的导出效果与预览时看到的相同。 + +--- +# 1号标题123 +## 2号标题1234 +- 1 测试 + - 2 + - 3 + +# reveal.js + +--- + +## 2号标题 1235 +- 4 测试 + - 2 + - 3 \ No newline at end of file diff --git a/2021/8-15-Marp-ppt/README.html b/2021/8-15-Marp-ppt/README.html new file mode 100644 index 0000000..1ab153d --- /dev/null +++ b/2021/8-15-Marp-ppt/README.html @@ -0,0 +1,98 @@ +
+

Marp:用 Markdown「写」PPT 的新选择

+
    +
  • Marp +
      +
    • Markdown --> PPT
    • +
    +
  • +
+
+
+

需求

+
    +
  • 制作视频之前,写文案 +
      +
    • 工作量少,简单 +
        +
      • 不想写一堆代码
      • +
      +
    • +
    • 翻页效果,即可。 +
        +
      • 有动画更好
      • +
      +
    • +
    +
  • +
  • 简洁,清晰明了 +
      +
    • 不想做得花里胡哨
    • +
    +
  • +
+
+
+
    +
  • 参考 +
      +
    • Marp:用 Markdown「写」PPT 的新选择 +
        +
      • 前往 VSCode 的网站 下载并安装 VSCode 本体,
      • +
      • 然后在左侧的插件栏中搜索并安装 Marp for VS Code。
      • +
      • 为了获得更好的 Markdown 编辑体验,大家不妨再安装一个叫做 Markdown All in One 的插件,然后就可以开始愉快地使用 Marp 了。
      • +
      +
    • +
    • 使用 Markdown 预览功能,确认无误后,再导出
    • +
    • toggle打开或关闭特效 +
        +
      • marp: true
      • +
      +
    • +
    • 缺点,没有动画特效
    • +
    +
  • +
+

reveal.js

+
+
+

编辑完成后,通过编辑器右上角的 Marp 图标按钮就可以调出 Export slide deck 命令并导出幻灯片了。Marp 插件目前支持导出 HTML 和 PDF 格式,另外可以将首页导出为 PNG 或 JPEG 格式的图片。

+

需要注意的是,目前导出 PDF 或者图片时需要依赖 Chromium 内核的浏览器。最终的导出效果与预览时看到的相同。

+
+
+

1号标题123

+

2号标题1234

+
    +
  • 1 测试 +
      +
    • 2
    • +
    • 3
    • +
    +
  • +
+

reveal.js

+
+
+

2号标题 1235

+
    +
  • 4 测试 +
      +
    • 2
    • +
    • 3
    • +
    +
  • +
+
+
\ No newline at end of file diff --git "a/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\220.html" "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\220.html" new file mode 100644 index 0000000..ac5d26c --- /dev/null +++ "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\220.html" @@ -0,0 +1,127 @@ +
+

程序员的996,每天工作安排

+
+
+

上午

+
    +
  • +

    9:00

    +
      +
    • 上班打卡,企业微信
    • +
    • 开早会
    • +
    +
  • +
  • +

    9:15

    +
      +
    • 敏捷开发管理系统
    • +
    • 领取工作内容
    • +
    +
  • +
  • +

    9:30

    +
      +
    • 开始工作
    • +
    • 和产品经理沟通,battle 打嘴仗
    • +
    +
  • +
  • +

    10:00

    +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
  • +

    11:00

    +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
+
+
+

中午

+
    +
  • 11:55 +
      +
    • 提前去食堂,避免排队
    • +
    +
  • +
  • 12:30 +
      +
    • 吃完
    • +
    • 回公司吹牛
    • +
    +
  • +
  • 13:00-->14:00 +
      +
    • 叹空调,睡午觉
    • +
    +
  • +
+
+
+

下午

+
    +
  • 14:00 +
      +
    • 闹钟吵醒,洗脸上班
    • +
    +
  • +
  • 16:00 +
      +
    • 非常困倦
    • +
    • 摸鱼
    • +
    +
  • +
  • 18:00 +
      +
    • 准点离开公司
    • +
    • 吃饭
    • +
    • 散步
    • +
    +
  • +
+
+
+

晚上

+
    +
  • 19:00 +
      +
    • 加班
    • +
    +
  • +
  • 20:45 +
      +
    • 敏捷开发管理系统 +
        +
      • 提交工作进度
      • +
      +
    • +
    +
  • +
  • 21:00 +
      +
    • 下班打卡,企业微信
    • +
    • 准点离开公司
    • +
    +
  • +
+
+
\ No newline at end of file diff --git "a/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\220.md" "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\220.md" new file mode 100644 index 0000000..33fd298 --- /dev/null +++ "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\220.md" @@ -0,0 +1,67 @@ +--- +marp: true +--- + +# 程序员的996,每天工作安排 + +--- + + +# 上午 +- 9:00 + - 上班打卡,企业微信 + - 开早会 +- 9:15 + - 敏捷开发管理系统 + - 领取工作内容 +--- +- 9:30 + - 开始工作 + - 和产品经理沟通,battle 打嘴仗 +![](IMG_20210806_092900.jpg) +--- + +- 10:00 + - 摸鱼时间 + - 上厕所 + - 刷微博 +- 11:00 + - 摸鱼时间 + - 上厕所 + - 刷微博 +--- + +## 中午 +- 11:55 + - 提前去食堂,避免排队 + ![11](IMG_20210715_122251.jpg) +--- + +- 12:30 + - 吃完 + - 回公司吹牛 +- 13:00-->14:00 + - 叹空调,睡午觉 +--- + +# 下午 +- 14:00 + - 闹钟吵醒,洗脸上班 +- 16:00 + - 非常困倦 + - 摸鱼 +- 18:00 + - 准点离开公司 + - 吃饭 + - 散步 +--- + +# 晚上 +- 19:00 + - 加班 +- 20:45 + - 敏捷开发管理系统 + - 提交工作进度 +- 21:00 + - 下班打卡,企业微信 + - 准点离开公司 \ No newline at end of file diff --git "a/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2202.html" "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2202.html" new file mode 100644 index 0000000..1fe4d57 --- /dev/null +++ "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2202.html" @@ -0,0 +1,127 @@ +
+

程序员的996,每天工作安排

+
+
+

上午

+
    +
  • +

    9:00

    +
      +
    • 上班打卡,企业微信
    • +
    • 开早会
    • +
    +
  • +
  • +

    9:15

    +
      +
    • 敏捷开发管理系统
    • +
    • 领取工作内容
    • +
    +
  • +
  • +

    9:30

    +
      +
    • 开始工作
    • +
    • 和产品经理沟通,battle 打嘴仗
    • +
    +
  • +
  • +

    10:00

    +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
  • +

    11:00

    +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
+
+
+

中午

+
    +
  • 11:55 +
      +
    • 提前去食堂,避免排队
    • +
    +
  • +
  • 12:30 +
      +
    • 吃完
    • +
    • 回公司吹牛
    • +
    +
  • +
  • 13:00-->14:00 +
      +
    • 叹空调,睡午觉
    • +
    +
  • +
+
+
+

下午

+
    +
  • 14:00 +
      +
    • 闹钟吵醒,洗脸上班
    • +
    +
  • +
  • 16:00 +
      +
    • 非常困倦
    • +
    • 摸鱼
    • +
    +
  • +
  • 18:00 +
      +
    • 准点离开公司
    • +
    • 吃饭
    • +
    • 散步
    • +
    +
  • +
+
+
+

晚上

+
    +
  • 19:00 +
      +
    • 加班
    • +
    +
  • +
  • 20:45 +
      +
    • 敏捷开发管理系统 +
        +
      • 提交工作进度
      • +
      +
    • +
    +
  • +
  • 21:00 +
      +
    • 下班打卡,企业微信
    • +
    • 准点离开公司
    • +
    +
  • +
+
+

$backgroundColor: orange

\ No newline at end of file diff --git "a/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2203.html" "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2203.html" new file mode 100644 index 0000000..babcabe --- /dev/null +++ "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2203.html" @@ -0,0 +1,127 @@ +
+

程序员的996,每天工作安排

+
+
+

上午

+
    +
  • +

    9:00

    +
      +
    • 上班打卡,企业微信
    • +
    • 开早会
    • +
    +
  • +
  • +

    9:15

    +
      +
    • 敏捷开发管理系统
    • +
    • 领取工作内容
    • +
    +
  • +
  • +

    9:30

    +
      +
    • 开始工作
    • +
    • 和产品经理沟通,battle 打嘴仗
    • +
    +
  • +
  • +

    10:00

    +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
  • +

    11:00

    +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
+
+
+

中午

+
    +
  • 11:55 +
      +
    • 提前去食堂,避免排队
    • +
    +
  • +
  • 12:30 +
      +
    • 吃完
    • +
    • 回公司吹牛
    • +
    +
  • +
  • 13:00-->14:00 +
      +
    • 叹空调,睡午觉
    • +
    +
  • +
+
+
+

下午

+
    +
  • 14:00 +
      +
    • 闹钟吵醒,洗脸上班
    • +
    +
  • +
  • 16:00 +
      +
    • 非常困倦
    • +
    • 摸鱼
    • +
    +
  • +
  • 18:00 +
      +
    • 准点离开公司
    • +
    • 吃饭
    • +
    • 散步
    • +
    +
  • +
+
+
+

晚上

+
    +
  • 19:00 +
      +
    • 加班
    • +
    +
  • +
  • 20:45 +
      +
    • 敏捷开发管理系统 +
        +
      • 提交工作进度
      • +
      +
    • +
    +
  • +
  • 21:00 +
      +
    • 下班打卡,企业微信
    • +
    • 准点离开公司
    • +
    +
  • +
+
+
\ No newline at end of file diff --git "a/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2204.html" "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2204.html" new file mode 100644 index 0000000..5d93123 --- /dev/null +++ "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2204.html" @@ -0,0 +1,127 @@ +
+

程序员的996,每天工作安排

+
+
+

上午

+
    +
  • +

    9:00

    +
      +
    • 上班打卡,企业微信
    • +
    • 开早会
    • +
    +
  • +
  • +

    9:15

    +
      +
    • 敏捷开发管理系统
    • +
    • 领取工作内容
    • +
    +
  • +
  • +

    9:30

    +
      +
    • 开始工作
    • +
    • 和产品经理沟通,battle 打嘴仗
    • +
    +
  • +
  • +

    10:00

    +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
  • +

    11:00

    +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
+
+
+

中午

+
    +
  • 11:55 +
      +
    • 提前去食堂,避免排队
    • +
    +
  • +
  • 12:30 +
      +
    • 吃完
    • +
    • 回公司吹牛
    • +
    +
  • +
  • 13:00-->14:00 +
      +
    • 叹空调,睡午觉
    • +
    +
  • +
+
+
+

下午

+
    +
  • 14:00 +
      +
    • 闹钟吵醒,洗脸上班
    • +
    +
  • +
  • 16:00 +
      +
    • 非常困倦
    • +
    • 摸鱼
    • +
    +
  • +
  • 18:00 +
      +
    • 准点离开公司
    • +
    • 吃饭
    • +
    • 散步
    • +
    +
  • +
+
+
+

晚上

+
    +
  • 19:00 +
      +
    • 加班
    • +
    +
  • +
  • 20:45 +
      +
    • 敏捷开发管理系统 +
        +
      • 提交工作进度
      • +
      +
    • +
    +
  • +
  • 21:00 +
      +
    • 下班打卡,企业微信
    • +
    • 准点离开公司
    • +
    +
  • +
+
+

fit

fit

\ No newline at end of file diff --git "a/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2205.html" "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2205.html" new file mode 100644 index 0000000..a5c2f33 --- /dev/null +++ "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2205.html" @@ -0,0 +1,136 @@ +
+

程序员的996,每天工作安排

+
+
+

上午

+
    +
  • 9:00 +
      +
    • 上班打卡,企业微信
    • +
    • 开早会
    • +
    +
  • +
  • 9:15 +
      +
    • 敏捷开发管理系统
    • +
    • 领取工作内容
    • +
    +
  • +
+
+
+
    +
  • 9:30 +
      +
    • 开始工作
    • +
    • 和产品经理沟通,battle 打嘴仗
      +
    • +
    +
  • +
+
+
+
    +
  • 10:00 +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
  • 11:00 +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
+
+
+

中午

+
    +
  • 11:55 +
      +
    • 提前去食堂,避免排队
      +11
    • +
    +
  • +
+
+
+
    +
  • 12:30 +
      +
    • 吃完
    • +
    • 回公司吹牛
    • +
    +
  • +
  • 13:00-->14:00 +
      +
    • 叹空调,睡午觉
    • +
    +
  • +
+
+
+

下午

+
    +
  • 14:00 +
      +
    • 闹钟吵醒,洗脸上班
    • +
    +
  • +
  • 16:00 +
      +
    • 非常困倦
    • +
    • 摸鱼
    • +
    +
  • +
  • 18:00 +
      +
    • 准点离开公司
    • +
    • 吃饭
    • +
    • 散步
    • +
    +
  • +
+
+
+

晚上

+
    +
  • 19:00 +
      +
    • 加班
    • +
    +
  • +
  • 20:45 +
      +
    • 敏捷开发管理系统 +
        +
      • 提交工作进度
      • +
      +
    • +
    +
  • +
  • 21:00 +
      +
    • 下班打卡,企业微信
    • +
    • 准点离开公司
    • +
    +
  • +
+
+

fit

fit

\ No newline at end of file diff --git "a/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2206.html" "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2206.html" new file mode 100644 index 0000000..95a00c5 --- /dev/null +++ "b/2021/8-15-Marp-ppt/demo-\345\256\214\346\210\2206.html" @@ -0,0 +1,136 @@ +
+

程序员的996,每天工作安排

+
+
+

上午

+
    +
  • 9:00 +
      +
    • 上班打卡,企业微信
    • +
    • 开早会
    • +
    +
  • +
  • 9:15 +
      +
    • 敏捷开发管理系统
    • +
    • 领取工作内容
    • +
    +
  • +
+
+
+
    +
  • 9:30 +
      +
    • 开始工作
    • +
    • 和产品经理沟通,battle 打嘴仗
      +
    • +
    +
  • +
+
+
+
    +
  • 10:00 +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
  • 11:00 +
      +
    • 摸鱼时间
    • +
    • 上厕所
    • +
    • 刷微博
    • +
    +
  • +
+
+
+

中午

+
    +
  • 11:55 +
      +
    • 提前去食堂,避免排队
      +11
    • +
    +
  • +
+
+
+
    +
  • 12:30 +
      +
    • 吃完
    • +
    • 回公司吹牛
    • +
    +
  • +
  • 13:00-->14:00 +
      +
    • 叹空调,睡午觉
    • +
    +
  • +
+
+
+

下午

+
    +
  • 14:00 +
      +
    • 闹钟吵醒,洗脸上班
    • +
    +
  • +
  • 16:00 +
      +
    • 非常困倦
    • +
    • 摸鱼
    • +
    +
  • +
  • 18:00 +
      +
    • 准点离开公司
    • +
    • 吃饭
    • +
    • 散步
    • +
    +
  • +
+
+
+

晚上

+
    +
  • 19:00 +
      +
    • 加班
    • +
    +
  • +
  • 20:45 +
      +
    • 敏捷开发管理系统 +
        +
      • 提交工作进度
      • +
      +
    • +
    +
  • +
  • 21:00 +
      +
    • 下班打卡,企业微信
    • +
    • 准点离开公司
    • +
    +
  • +
+
+

fit

\ No newline at end of file diff --git a/2021/8-15-Marp-ppt/demo.md b/2021/8-15-Marp-ppt/demo.md new file mode 100644 index 0000000..a3af722 --- /dev/null +++ b/2021/8-15-Marp-ppt/demo.md @@ -0,0 +1,51 @@ + +# 程序员的996,每天工作安排 +## 上午 +- 9:00 + - 上班打卡,企业微信 + - 开早会 +- 9:15 + - 敏捷开发管理系统 + - 领取工作内容 +- 9:30 + - 开始工作 + - 和产品经理沟通,battle 打嘴仗 + +- 10:00 + - 摸鱼时间 + - 上厕所 + - 刷微博 +- 11:00 + - 摸鱼时间 + - 上厕所 + - 刷微博 + +## 中午 +- 11:55 + - 提前去食堂,避免排队 +- 12:20 + - 吃完 + - 回公司吹牛 +- 13:00-->14:00 + - 叹空调,睡午觉 + +## 下午 +- 14:00 + - 闹钟吵醒,洗脸上班 +- 16:00 + - 非常困倦 + - 摸鱼 +- 18:00 + - 准点离开公司 + - 吃饭 + - 散步 + +## 晚上 +- 19:00 + - 加班 +- 20:45 + - 敏捷开发管理系统 + - 提交工作进度 +- 21:00 + - 下班打卡,企业微信 + - 准点离开公司 \ No newline at end of file diff --git a/2021/9-3-Deta-Base/BaseDemo/config.py b/2021/9-3-Deta-Base/BaseDemo/config.py new file mode 100644 index 0000000..1a6f620 --- /dev/null +++ b/2021/9-3-Deta-Base/BaseDemo/config.py @@ -0,0 +1,9 @@ +# -*- encoding: utf-8 -*- +''' +@File : config.py +@Time : 2021/09/03 09:47:46 +@Author : GH +@Desc : +''' + +project_key = "xxx" diff --git a/2021/9-3-Deta-Base/BaseDemo/main.py b/2021/9-3-Deta-Base/BaseDemo/main.py new file mode 100644 index 0000000..331d816 --- /dev/null +++ b/2021/9-3-Deta-Base/BaseDemo/main.py @@ -0,0 +1,64 @@ +# -*- encoding: utf-8 -*- +''' +@File : main.py +@Time : 2021/08/01 16:26:39 +@Author : GH +@Desc : + +执行 +uvicorn main:app + +''' +from typing import Optional +from fastapi.params import Body +from pydantic import BaseModel +from fastapi import FastAPI +from deta import Deta +from config import project_key + +deta = Deta(project_key) +db = deta.Base("baseItem") + +app = FastAPI() + + +class Item(BaseModel): + key: Optional[str] = None + name: Optional[str] = None + age: Optional[int] = None + + +@app.get("/") +def read_root(): + return {"Hello": "World, great day! 数据库NoSQL"} + + +@app.put("/items/") +def put_item(item: Item): + print("item_id:", item) + # TODO 存入数据库 + del item.key + rs = db.put(item.dict()) + return {"item": item, 'put': rs} + + +@app.get("/items/{key}") +def read_item(key: str): # 1orwum5g2grm + print("item_id:", key) + rs = db.get(key) + return {"item": rs} + + +@app.put("/items/update") +def update_item(item: Item): + + # rs = db.update({'age': item.age, 'name': item.name}, key=item.key) + rs = db.put(item.dict()) # 直接更新 + + return {"update": rs} + + +@app.delete("/items/{key}") +def delete_item(key: str): + rs = db.delete(key) + return {"delete": rs} diff --git a/2021/9-3-Deta-Base/BaseDemo/requirements.txt b/2021/9-3-Deta-Base/BaseDemo/requirements.txt new file mode 100644 index 0000000..6b0b939 --- /dev/null +++ b/2021/9-3-Deta-Base/BaseDemo/requirements.txt @@ -0,0 +1 @@ +fastapi diff --git a/2021/9-3-Deta-Base/README.md b/2021/9-3-Deta-Base/README.md new file mode 100644 index 0000000..ad5dc79 --- /dev/null +++ b/2021/9-3-Deta-Base/README.md @@ -0,0 +1,10 @@ + + + +## Deta.sh 免费数据库NoSQL : Base + + +- 文档 + - https://docs.deta.sh/docs/base/sdk/ + +- 视频 ? \ No newline at end of file