当前位置:网站首页>I'm a programmer, and I remember history in this way

I'm a programmer, and I remember history in this way

2020-12-07 19:19:32 InfoQ

{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"War Of Resistance Live","attrs":{}},{"type":"text","text":": Record 14 Day and night of the war of resistance against Japan ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Open source address ","attrs":{}},{"type":"text","text":":","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/kokohuang/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"https://github.com/kokohuang/WarOfResistanceLive","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Preview address ","attrs":{}},{"type":"text","text":":","attrs":{}},{"type":"link","attrs":{"href":"https://kokohuang.github.io/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"https://kokohuang.github.io/WarOfResistanceLive","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Preface ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" In the current impetuous Internet Environment , It's not hard to do a good thing , The hard part is continuity 8 To do something meaningful .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" There is such a blogger on Weibo , from 2012 year 7 month 7 The day begins , Up to 2020 year 9 month 2 Japan ,","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@ Live broadcast of the Anti Japanese War ","attrs":{}}]},{"type":"text","text":" In graphic form , Recorded from ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1937 year 7 month 7 solstice 1945 year 8 month 15 Japan ","attrs":{}},{"type":"text","text":" The history of the Chinese nation's all-round war of resistance against Japan .","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"2980","attrs":{}},{"type":"text","text":" God , Uninterrupted , Average daily ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"12","attrs":{}},{"type":"text","text":" strip , Cumulative ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"35214","attrs":{}},{"type":"text","text":" piece .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2020 year 9 month 18 Japan 7 Time zero 7 branch , Silent for half a month ","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@ Live broadcast of the Anti Japanese War ","attrs":{}}]},{"type":"text","text":" Restore updates , They will continue to record in graphic form ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1931 year 9 month 18 solstice 1937 year 7 month 7 Japan ","attrs":{}},{"type":"text","text":" The six-year history of the war of resistance against Japan .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" next ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"6","attrs":{}},{"type":"text","text":" year , They are already on their way .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" History can't be forgotten .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" As a programmer, I , In front of history , What can I do ?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Admiration except ","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@ Live broadcast of the Anti Japanese War ","attrs":{}}]},{"type":"text","text":" So many years of persistence , I want to do something meaningful that I can do .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" After getting the blogger ","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@ Live broadcast of the Anti Japanese War ","attrs":{}}]},{"type":"text","text":" After the permission and support of , So there was the birth of this project .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"War Of Resistance Live","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"├── .github/workflows # Workflow configuration file \n├── resources # Microblog data \n├── site # Blog source code \n└── spider # Micro blog crawler ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://github.com/kokohuang/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"WarOfResistanceLive","attrs":{}}]},{"type":"text","text":" Is a major result of ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Python","attrs":{}}],"attrs":{}},{"type":"text","text":" Reptiles + ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" Blog + ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" Open source project composed of continuous integration services , Open source in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GitHub","attrs":{}}],"attrs":{}},{"type":"text","text":" On , And deployed in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Pages","attrs":{}}],"attrs":{}},{"type":"text","text":". Currently it includes the following functions :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Automatically and automatically update the data every day ","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" View all of the blogger's current microblog data ","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Support ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RSS","attrs":{}}],"attrs":{}},{"type":"text","text":" Subscribe to the function ","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" be based on ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" Continuous integration services ","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"...","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Next , I will briefly introduce some of the core logic and implementation of the project .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Python Reptiles ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The crawler used in this project is based on ","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/dataabc/weibo-crawler","title":""},"content":[{"type":"text","text":"weibo-crawler","attrs":{}}]},{"type":"text","text":" Project simplification and modification implementation (","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" For research purposes only ","attrs":{}},{"type":"text","text":"), Thanks to the author [dataabc](https://github.com/dataabc).","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Realization principle ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Bypass the login verification by visiting the mobile version of Weibo , You can view most of the microblog data of a blogger , Such as :","attrs":{}},{"type":"link","attrs":{"href":"https://m.weibo.cn/u/2896390104","title":""},"content":[{"type":"text","text":"https://m.weibo.cn/u/2896390104","attrs":{}}]}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Through the developer tool to see , adopt ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"json","attrs":{}}],"attrs":{}},{"type":"text","text":" Interface ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"https://m.weibo.cn/api/container/getIndex","attrs":{}}],"attrs":{}},{"type":"text","text":" You can get the microblog data list :","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" ```python","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" def get_json(self, params):","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" \"\"\" Get the web page json data \"\"\"","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" url = 'https://m.weibo.cn/api/container/getIndex?'","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" r = requests.get(url,","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" params=params,","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" headers=self.headers,","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" verify=False)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" return r.json()","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" ```","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" How to use ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Installation dependency :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"pip3 install -r requirements.txt","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Use :","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"python weibo.py","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" matters needing attention ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Too fast is easy to be limited by the system : Random logic can be added by waiting , It can reduce the risk of being limited by the system ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Can't get all microblog data : By adding ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"cookie","attrs":{}}],"attrs":{}},{"type":"text","text":" Logic gets all the data ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" More on ","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/dataabc/weibo-crawler","title":""},"content":[{"type":"text","text":"weibo-crawler","attrs":{}}]},{"type":"text","text":".","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Hexo","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" After some choice , Final choice ","attrs":{}},{"type":"link","attrs":{"href":"https://hexo.io/zh-cn/","title":""},"content":[{"type":"text","text":"Hexo","attrs":{}}]},{"type":"text","text":" + [Next](https://github.com/theme-next/hexo-theme-next) Theme as the blog framework of this project .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" It's based on ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Node.js","attrs":{}}],"attrs":{}},{"type":"text","text":" Static blog framework of , Less dependence, easy to install and use , Can easily generate static web hosting in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GitHub Pages","attrs":{}}],"attrs":{}},{"type":"text","text":" On , There are plenty of topics to choose from . About how to install and use ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" You can check the official documents in detail :","attrs":{}},{"type":"link","attrs":{"href":"https://hexo.io/zh-cn/docs/","title":""},"content":[{"type":"text","text":"https://hexo.io/zh-cn/docs/","attrs":{}}]},{"type":"text","text":".","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" that , How to achieve ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RSS","attrs":{}}],"attrs":{}},{"type":"text","text":" What about the subscription function ?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Thanks to the ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" Rich plug-in features ,","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/hexojs/hexo-generator-feed","title":""},"content":[{"type":"text","text":"hexo-generator-feed","attrs":{}}]},{"type":"text","text":" It can be very convenient for us to achieve .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" First , Install the plug-in under the root directory of the blog :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"$ npm install hexo-generator-feed --save","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" next , In the blog root directory ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"_config.yml","attrs":{}}],"attrs":{}},{"type":"text","text":" Add relevant configuration to the file :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"feed:\n enable: true # Is plug-in enabled \n type: atom # Feed The type of , Support atom and rss2, Default atom\n path: atom.xml # Path to build file \n limit: 30 # Maximum number of articles generated , If 0 or false Then generate all the articles \n content: true # If true Show all the contents of the article \n content_limit: # The length of the content presented in the article , Only when the content by false It works \n order_by: -date # Sort by date \n template: # Custom template path ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Last , Under the theme root ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"_config.yml","attrs":{}}],"attrs":{}},{"type":"text","text":" Add... To the file ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RSS","attrs":{}}],"attrs":{}},{"type":"text","text":" Subscription portal :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"menu:\n RSS: /atom.xml || fa fa-rss # atom.xml File path address and icon settings ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" such , We can add ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RSS","attrs":{}}],"attrs":{}},{"type":"text","text":" Subscribe to the function .","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/kokohuang/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"WarOfResistanceLive","attrs":{}}]},{"type":"text","text":" Your subscription address is :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"https://kokohuang.github.io/WarOfResistanceLive/atom.xml","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Github Actions Continuous integration ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" By ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github","attrs":{}}],"attrs":{}},{"type":"text","text":" On ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"2018 year 10 month ","attrs":{}}],"attrs":{}},{"type":"text","text":" Continuous integration services , Before that , We may use more ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Travis CI","attrs":{}}],"attrs":{}},{"type":"text","text":" To achieve continuous integration services . In my personal sense ,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" Very powerful , Than ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Travis CI","attrs":{}}],"attrs":{}},{"type":"text","text":" More playable ,","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" Rich in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"action","attrs":{}}],"attrs":{}},{"type":"text","text":" market , Will these ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"action","attrs":{}}],"attrs":{}},{"type":"text","text":" combined , We can do a lot of interesting things very simply .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Let's take a look first ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" Some basic concepts of :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"workflow","attrs":{}},{"type":"text","text":": Workflow . That is, the process of continuous integration into one operation . The document is stored in the warehouse ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":".github/workflows","attrs":{}}],"attrs":{}},{"type":"text","text":" Directory , Can contain more than one ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"job","attrs":{}},{"type":"text","text":": Mission . One ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"workflow","attrs":{}}],"attrs":{}},{"type":"text","text":" May contain one or more ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"jobs","attrs":{}}],"attrs":{}},{"type":"text","text":", It represents an integrated operation , It can accomplish one or more tasks ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"step","attrs":{}},{"type":"text","text":": step . One ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"job","attrs":{}}],"attrs":{}},{"type":"text","text":" By multiple ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" form , It represents the steps needed to complete a task ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"action","attrs":{}},{"type":"text","text":": action . Every ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" It can contain one or more ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"action","attrs":{}}],"attrs":{}},{"type":"text","text":", That means within a step , Can execute multiple ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"action","attrs":{}}],"attrs":{}},{"type":"text","text":" action .","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I understand ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" After these basic concepts , Let's see ","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/kokohuang/WarOfResistanceLive","title":""},"content":[{"type":"text","text":"WarOfResistanceLive","attrs":{}}]},{"type":"text","text":" How is the continuous integration service implemented for , The following is used in this project ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"workflow","attrs":{}}],"attrs":{}},{"type":"text","text":" Complete implementation :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"# workflow The name of \nname: Spider Bot\n\n# Set time zone \nenv:\n TZ: Asia/Shanghai\n\n# Set workflow trigger mode .\non:\n # Timing trigger , stay 8:00-24:00 Every 2 Update every hour (https://crontab.guru)\n # because cron The set time is UTC Time , therefore +8 Beijing time \n schedule:\n - cron: \"0 0-16/2 * * *\"\n\n # Allow manual triggering Actions\n workflow_dispatch:\n\njobs:\n build:\n # Use ubuntu-latest As the operating environment \n runs-on: ubuntu-latest\n\n # The sequence of tasks to be performed \n steps:\n # Check out warehouse \n - name: Checkout Repository\n uses: actions/checkout@v2\n\n # Set up Python Environmental Science \n - name: Setup Python\n uses: actions/setup-python@v2\n with:\n python-version: \"3.x\"\n\n # cache pip rely on \n - name: Cache Pip Dependencies\n id: pip-cache\n uses: actions/cache@v2\n with:\n path: ~/.cache/pip\n key: ${{ runner.os }}-pip-${{ hashFiles('./spider/requirements.txt') }}\n restore-keys: |\n ${{ runner.os }}-pip-\n \n # install pip rely on \n - name: Install Pip Dependencies\n working-directory: ./spider\n run: |\n python -m pip install --upgrade pip\n pip install flake8 pytest\n if [ -f requirements.txt ]; then pip install -r requirements.txt; fi\n\n # Run the crawler script \n - name: Run Spider Bot\n working-directory: ./spider # assign work directory , Only on run The order comes into effect \n run: python weibo.py\n\n # Get the current time of the system \n - name: Get Current Date\n id: date\n run: echo \"::set-output name=date::$(date +'%Y-%m-%d %H:%M')\"\n\n # Commit changes \n - name: Commit Changes\n uses: EndBug/add-and-commit@v5\n with:\n author_name: Koko Huang\n author_email: huangjianke@vip.163.com\n message: \" The latest data has been synchronized (${{steps.date.outputs.date}})\"\n add: \"./\"\n env:\n GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n # Push the far end \n - name: Push Changes\n uses: ad-m/github-push-action@master\n with:\n branch: main\n github_token: ${{ secrets.GITHUB_TOKEN }}\n\n # Set up Node.js Environmental Science \n - name: Use Node.js 12.x\n uses: actions/setup-node@v1\n with:\n node-version: \"12.x\"\n\n # cache NPM rely on \n - name: Cache NPM Dependencies\n id: npm-cache\n uses: actions/cache@v2\n with:\n path: ~/.npm\n key: ${{ runner.os }}-node-${{ hashFiles('./site/package-lock.json') }}\n restore-keys: |\n ${{ runner.os }}-node-\n\n # install NPM rely on \n - name: Install NPM Dependencies\n working-directory: ./site\n run: npm install\n\n # structure Hexo\n - name: Build Hexo\n working-directory: ./site # assign work directory , Only on run The order comes into effect \n run: npm run build\n\n # Release Github Pages\n - name: Deploy Github Pages\n uses: peaceiris/actions-gh-pages@v3\n with:\n github_token: ${{ secrets.GITHUB_TOKEN }}\n publish_dir: ./site/public # Specify the path address to be published \n publish_branch: gh-pages # Specify the remote branch name ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"workflow","attrs":{}}],"attrs":{}},{"type":"text","text":" There are many configuration fields in the file , Detailed comments are also given in the configuration file . Next , Let's mainly look at the following more important configurations :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" How workflow is triggered ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"yaml"},"content":[{"type":"text","text":"# Set workflow trigger mode .\non:\n # Timing trigger , stay 8:00-24:00 Every 2 Update every hour (https://crontab.guru)\n # because cron The set time is UTC Time , therefore +8 Beijing time \n schedule:\n - cron: \"0 0-16/2 * * *\"\n\n # Allows manual triggering of workflow \n workflow_dispatch:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" We can use ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"on","attrs":{}}],"attrs":{}},{"type":"text","text":" Workflow syntax configures a workflow to run for one or more events . Support automatic and manual trigger .","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"schedule","attrs":{}}],"attrs":{}},{"type":"text","text":" Events allow us to trigger workflow at a planned time , We can use ","attrs":{}},{"type":"link","attrs":{"href":"https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag2025_07","title":""},"content":[{"type":"text","text":"POSIX cron grammar ","attrs":{}}]},{"type":"text","text":" To schedule the workflow to run at a specific time .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The scheduled task syntax has five fields , Space between , Each field represents a time unit :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"┌───────────── minute (0 - 59)\n│ ┌───────────── hour (0 - 23)\n│ │ ┌───────────── day of the month (1 - 31)\n│ │ │ ┌───────────── month (1 - 12 or JAN-DEC)\n│ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)\n│ │ │ │ │ \n│ │ │ │ │\n│ │ │ │ │\n* * * * *","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" We can use ","attrs":{}},{"type":"link","attrs":{"href":"https://crontab.guru","title":""},"content":[{"type":"text","text":"https://crontab.guru","attrs":{}}]},{"type":"text","text":" To generate the scheduled task syntax , You can also check out more [crontab guru Example ](https://crontab.guru/examples.html).","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" in addition , We can also configure ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"workflow_dispatch","attrs":{}}],"attrs":{}},{"type":"text","text":" and ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"repository_dispatch","attrs":{}}],"attrs":{}},{"type":"text","text":" Field to trigger workflow manually .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"on","attrs":{}}],"attrs":{}},{"type":"text","text":" Fields can also be configured as ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"push","attrs":{}}],"attrs":{}},{"type":"text","text":", The warehouse has ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"push","attrs":{}}],"attrs":{}},{"type":"text","text":" When the operation is performed, the execution of the workflow is triggered , Detailed trigger workflow configuration can be viewed ","attrs":{}},{"type":"link","attrs":{"href":"https://docs.github.com/cn/free-pro-team@latest/actions/reference/events-that-trigger-workflows# Configure workflow Events ","title":""},"content":[{"type":"text","text":" Configure workflow Events ","attrs":{}}]},{"type":"text","text":".","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":" Sequence of steps ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" From the configuration file, we can see that , A continuous integration run of the project includes the following steps :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c9/c9e9f5749753b67a57fd516b989c4978.jpeg","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Check out warehouse --> Set up ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Python","attrs":{}}],"attrs":{}},{"type":"text","text":" Environmental Science --> cache ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"pip","attrs":{}}],"attrs":{}},{"type":"text","text":" rely on --> install ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"pip","attrs":{}}],"attrs":{}},{"type":"text","text":" rely on --> Run the crawler script --> Get the current time --> Commit changes --> Push the far end --> Set up ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Node.js","attrs":{}}],"attrs":{}},{"type":"text","text":" Environmental Science --> cache ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"NPM","attrs":{}}],"attrs":{}},{"type":"text","text":" rely on --> install ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"NPM","attrs":{}}],"attrs":{}},{"type":"text","text":" rely on --> structure ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":" --> Release ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github Pages","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" This project ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"workflow","attrs":{}}],"attrs":{}},{"type":"text","text":" The main points are as follows :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Running environment ","attrs":{}},{"type":"text","text":": The whole workflow runs in a virtual environment ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ubuntu-latest","attrs":{}}],"attrs":{}},{"type":"text","text":". You can also specify other virtual environments , Such as ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Windows Server","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"macOS","attrs":{}}],"attrs":{}},{"type":"text","text":" etc. ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Cache dependency ","attrs":{}},{"type":"text","text":": By caching dependencies , It can speed up the installation of related dependencies . For specific use, please see :","attrs":{}},{"type":"link","attrs":{"href":"https://docs.github.com/cn/free-pro-team@latest/actions/guides/caching-dependencies-to-speed-up-workflows","title":""},"content":[{"type":"text","text":" Cache dependencies to speed up workflow ","attrs":{}}]},{"type":"text","text":";","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Get the current time ","attrs":{}},{"type":"text","text":": follow-up ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Commit changes ","attrs":{}},{"type":"text","text":" In the step ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"commit message","attrs":{}}],"attrs":{}},{"type":"text","text":" In this step, the current time is obtained , Here is the use of ","attrs":{}},{"type":"link","attrs":{"href":"https://docs.github.com/cn/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions#steps- Context ","title":""},"content":[{"type":"text","text":"step Context ","attrs":{}}]},{"type":"text","text":" Related concepts of , We can ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" To specify a ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"id","attrs":{}}],"attrs":{}},{"type":"text","text":", follow-up ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" We can go through ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"steps..outputs","attrs":{}}],"attrs":{}},{"type":"text","text":" To get information about the steps that have been run ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"** structure ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Hexo","attrs":{}}],"attrs":{}},{"type":"text","text":"**: The perform ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"hexo generate","attrs":{}}],"attrs":{}},{"type":"text","text":" Command to generate a static web page ;","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Authentication in workflow ","attrs":{}},{"type":"text","text":": Submit push and publish steps require authentication .","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GitHub","attrs":{}}],"attrs":{}},{"type":"text","text":" Provide a token , Can be used to represent ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GitHub Actions","attrs":{}}],"attrs":{}},{"type":"text","text":" Authentication . All we need to do is create a named ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GITHUB_TOKEN","attrs":{}}],"attrs":{}},{"type":"text","text":" The token . The specific steps are as follows :","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Settings","attrs":{}}],"attrs":{}},{"type":"text","text":" --> ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Developer settings","attrs":{}}],"attrs":{}},{"type":"text","text":" --> ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Personal access tokens","attrs":{}}],"attrs":{}},{"type":"text","text":" --> ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Generate new token","attrs":{}}],"attrs":{}},{"type":"text","text":", Name it ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GITHUB_TOKEN","attrs":{}}],"attrs":{}},{"type":"text","text":" , And check the permissions you need , And then you can do it in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"step","attrs":{}}],"attrs":{}},{"type":"text","text":" Through the use of ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"${{ secrets.GITHUB_TOKEN }}","attrs":{}}],"attrs":{}},{"type":"text","text":" Authentication .","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" more ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Action","attrs":{}}],"attrs":{}},{"type":"text","text":" Can be found in ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Github","attrs":{}}],"attrs":{}},{"type":"text","text":" ","attrs":{}},{"type":"link","attrs":{"href":"https://github.com/marketplace?type=actions","title":""},"content":[{"type":"text","text":" Official market ","attrs":{}}]},{"type":"text","text":" see .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Conclusion ","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Last , Quote bloggers ","attrs":{}},{"type":"link","attrs":{"href":"https://weibo.com/kzzb","title":""},"content":[{"type":"text","text":"@ Live broadcast of the Anti Japanese War ","attrs":{}}]},{"type":"text","text":" A passage from :","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“ We broadcast the Anti Japanese War live , Not to stir up negative emotions like hatred , It's about moderately evoking forgetfulness , When we always remember the sufferings of our ancestors 、 Fear and humiliation ; When we appreciate how our ancestors abandoned the past when the nation was in danger , When national reconciliation is achieved , When we see how our ancestors have gone to death with ease and generosity , When the body is sacrificed for this country , I believe that we will have more mature and rational thinking about reality .”","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Remember the history , Sheer endeavour .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" Not forget national humiliation , We are self-improvement .","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/202012071916432990.html

随机推荐