This commit is contained in:
呆瓜云 2023-07-28 15:45:45 +08:00
parent d679afc59d
commit a791ee8d95
9 changed files with 708 additions and 0 deletions

53
.github/workflows/Gmeek.yml vendored Normal file
View File

@ -0,0 +1,53 @@
name: build Gmeek
on:
workflow_dispatch:
issues:
types: [opened, edited]
env:
GITHUB_NAME: Meekdai
GITHUB_EMAIL: meekdai@163.com
jobs:
sync:
name: Generate blog
runs-on: ubuntu-20.04
if: github.event.repository.owner.id == github.event.sender.id
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: 3.8
- name: Configure pip cache
uses: actions/cache@v1
id: pip-cache
with:
path: venv
key: pip-1-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
if: steps.pip-cache.outputs.cache-hit != 'true'
- name: Generate new html
run: |
source venv/bin/activate
python Gmeek.py ${{ secrets.meblog }} ${{ github.repository }} --issue_number '${{ github.event.issue.number }}'
- name: update html
run: |
git config --local user.email "${{ env.GITHUB_EMAIL }}"
git config --local user.name "${{ env.GITHUB_NAME }}"
git add .
git commit -a -m '🎉auto update by action' || echo "nothing to commit"
git push || echo "nothing to push"

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
__pycache__
nohup.out
.git-credentials
venv/

169
Gmeek.py Normal file
View File

@ -0,0 +1,169 @@
# -*- coding: utf-8 -*-
import os
import json
import time
import datetime
import shutil
import requests
import argparse
from github import Github
from xpinyin import Pinyin
######################################################################################
class GMEEK():
def __init__(self,options):
self.options=options
self.config=json.loads(open('config.json', 'r', encoding='utf-8').read())
self.root_dir='docs/'
self.post_folder='post/'
self.post_dir=self.root_dir+self.post_folder
self.plist_example=open('plist_example.html', 'r', encoding='utf-8').read()
self.post_example=open('post_example.html', 'r', encoding='utf-8').read()
user = Github(self.options.github_token)
self.repo = self.get_repo(user, options.repo_name)
self.labelColorDict=json.loads('{}')
for label in self.repo.get_labels():
self.labelColorDict[label.name]='#'+label.color
print(self.labelColorDict)
self.blogBase=self.config.copy()
self.blogBase["postListJson"]=json.loads('{}')
def cleanFile(self):
if os.path.exists("backup/"):
shutil.rmtree("backup/")
if os.path.exists(self.post_dir):
shutil.rmtree(self.post_dir)
os.mkdir("backup/")
os.mkdir(self.post_dir)
def get_repo(self,user: Github, repo: str):
return user.get_repo(repo)
def markdown2html(self,mdstr):
payload = {"text": mdstr, "mode": "markdown"}
ret=requests.post("https://api.github.com/markdown", json=payload,headers={"Authorzation":"token {}".format(self.options.github_token)})
if ret.status_code==200:
return ret.text
else:
raise Exception("markdown2html error status_code=%d"%(ret.status_code))
def createPostHtml(self,issue):
if issue["label"] in self.blogBase["singlePage"]:
gen_Html = 'docs/{}.html'.format(issue["label"])
else:
gen_Html = self.post_dir+'{}.html'.format(Pinyin().get_pinyin(issue["postTitle"]))
f = open("backup/"+issue["postTitle"]+".md", 'r', encoding='UTF-8')
post_body=self.markdown2html(f.read())
f.close()
postBase=json.loads('{}')
postBase["postTitle"]=issue["postTitle"]
postBase["postBody"]=post_body
postBase["title"]=self.blogBase["title"]
postBase["homeUrl"]=self.blogBase["homeUrl"]
postBase["postSourceUrl"]=issue["postSourceUrl"]
postBase["faviconUrl"]=self.blogBase["faviconUrl"]
postBase["filingNum"]=self.blogBase["filingNum"]
postBase["startSite"]=self.blogBase["startSite"]
postBase["commentNum"]=issue["commentNum"]
postBase["repoName"]=options.repo_name
f = open(gen_Html, 'w', encoding='UTF-8')
f.write(self.post_example % json.dumps(postBase))
f.close()
print("create postPage title=%s file=%s " % (issue["postTitle"],gen_Html))
def creatPlistHtml(self):
self.blogBase["postListJson"]=dict(sorted(self.blogBase["postListJson"].items(),key=lambda x:x[1]["createdAt"],reverse=True))#使列表由时间排序
f = open(self.root_dir+"index.html", 'w', encoding='UTF-8')
f.write(self.plist_example % json.dumps(self.blogBase))
f.close()
print("create docs/index.html")
def addOnePostJson(self,issue):
if len(issue.labels)==1:
postNum="P"+str(issue.number)
self.blogBase["postListJson"][postNum]=json.loads('{}')
self.blogBase["postListJson"][postNum]["label"]=issue.labels[0].name
self.blogBase["postListJson"][postNum]["labelColor"]=self.labelColorDict[issue.labels[0].name]
self.blogBase["postListJson"][postNum]["postTitle"]=issue.title
self.blogBase["postListJson"][postNum]["postUrl"]=self.post_folder+'{}.html'.format(Pinyin().get_pinyin(issue.title))
self.blogBase["postListJson"][postNum]["postSourceUrl"]="https://github.com/"+options.repo_name+"/issues/"+str(issue.number)
self.blogBase["postListJson"][postNum]["commentNum"]=issue.get_comments().totalCount
try:
modifyTime=json.loads(issue.body.split("\r\n")[-1:][0].split("##")[1])
self.blogBase["postListJson"][postNum]["createdAt"]=modifyTime["timestamp"]
except:
self.blogBase["postListJson"][postNum]["createdAt"]=int(time.mktime(issue.created_at.timetuple()))
thisYear=datetime.datetime.fromtimestamp(self.blogBase["postListJson"][postNum]["createdAt"]).year
self.blogBase["postListJson"][postNum]["dateLabelColor"]=self.blogBase["yearColorList"][int(thisYear)%len(self.blogBase["yearColorList"])]
f = open("backup/"+issue.title+".md", 'w', encoding='UTF-8')
f.write(issue.body)
f.close()
def runAll(self):
print("====== start create static html ======")
self.cleanFile()
issues=self.repo.get_issues()
for issue in issues:
self.addOnePostJson(issue)
for issue in self.blogBase["postListJson"].values():
self.createPostHtml(issue)
self.creatPlistHtml()
print("====== create static html end ======")
def runOne(self,number_str):
print("====== start create static html ======")
issue=self.repo.get_issue(int(number_str))
self.addOnePostJson(issue)
self.createPostHtml(self.blogBase["postListJson"]["P"+number_str])
self.creatPlistHtml()
print("====== create static html end ======")
######################################################################################
parser = argparse.ArgumentParser()
parser.add_argument("github_token", help="github_token")
parser.add_argument("repo_name", help="repo_name")
parser.add_argument("--issue_number", help="issue_number", default=0, required=False)
options = parser.parse_args()
blog=GMEEK(options)
if not os.path.exists("blogBase.json"):
print("blogBase is not exists, runAll")
blog.runAll()
else:
if options.issue_number=="0" or options.issue_number=="":
print("issue_number=='0', runAll")
blog.runAll()
else:
f=open("blogBase.json","r")
print("blogBase is exists and issue_number!=0, runOne")
blog.blogBase=json.loads(f.read())
f.close()
blog.runOne(options.issue_number)
listFile=open("blogBase.json","w")
listFile.write(json.dumps(blog.blogBase))
listFile.close()
######################################################################################

12
config.json Normal file
View File

@ -0,0 +1,12 @@
{
"title":"Meekdai",
"subTitle":"童话是一种生活态度,仅此而已。",
"homeUrl":"http://blog.meekdai.com",
"avatarUrl":"http://meekdai.com/avatar.jpg",
"faviconUrl":"http://meekdai.com/favicon.ico",
"startSite":"02/16/2015",
"filingNum":"浙ICP备20023628号",
"singlePage":["link","about"],
"commentLabelColor":"#006b75",
"yearColorList":["#bc4c00", "#0969da", "#1f883d", "#A333D0"]
}

129
docs/static/github-light.css vendored Normal file
View File

@ -0,0 +1,129 @@
/*!
* GitHub Light v0.5.0
* Copyright (c) 2012 - 2017 GitHub, Inc.
* Licensed under MIT (https://github.com/primer/github-syntax-theme-generator/blob/master/LICENSE)
*/
.pl-c /* comment, punctuation.definition.comment, string.comment */ {
color: #6a737d;
}
.pl-c1 /* constant, entity.name.constant, variable.other.constant, variable.language, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header, meta.output */,
.pl-s .pl-v /* string variable */ {
color: #005cc5;
}
.pl-e /* entity */,
.pl-en /* entity.name */ {
color: #6f42c1;
}
.pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */,
.pl-s .pl-s1 /* string source */ {
color: #24292e;
}
.pl-ent /* entity.name.tag, markup.quote */ {
color: #22863a;
}
.pl-k /* keyword, storage, storage.type */ {
color: #d73a49;
}
.pl-s /* string */,
.pl-pds /* punctuation.definition.string, source.regexp, string.regexp.character-class */,
.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,
.pl-sr /* string.regexp */,
.pl-sr .pl-cce /* string.regexp constant.character.escape */,
.pl-sr .pl-sre /* string.regexp source.ruby.embedded */,
.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ {
color: #032f62;
}
.pl-v /* variable */,
.pl-smw /* sublimelinter.mark.warning */ {
color: #e36209;
}
.pl-bu /* invalid.broken, invalid.deprecated, invalid.unimplemented, message.error, brackethighlighter.unmatched, sublimelinter.mark.error */ {
color: #b31d28;
}
.pl-ii /* invalid.illegal */ {
color: #fafbfc;
background-color: #b31d28;
}
.pl-c2 /* carriage-return */ {
color: #fafbfc;
background-color: #d73a49;
}
.pl-c2::before /* carriage-return */ {
content: "^M";
}
.pl-sr .pl-cce /* string.regexp constant.character.escape */ {
font-weight: bold;
color: #22863a;
}
.pl-ml /* markup.list */ {
color: #735c0f;
}
.pl-mh /* markup.heading */,
.pl-mh .pl-en /* markup.heading entity.name */,
.pl-ms /* meta.separator */ {
font-weight: bold;
color: #005cc5;
}
.pl-mi /* markup.italic */ {
font-style: italic;
color: #24292e;
}
.pl-mb /* markup.bold */ {
font-weight: bold;
color: #24292e;
}
.pl-md /* markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted */ {
color: #b31d28;
background-color: #ffeef0;
}
.pl-mi1 /* markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted */ {
color: #22863a;
background-color: #f0fff4;
}
.pl-mc /* markup.changed, punctuation.definition.changed */ {
color: #e36209;
background-color: #ffebda;
}
.pl-mi2 /* markup.ignored, markup.untracked */ {
color: #f6f8fa;
background-color: #005cc5;
}
.pl-mdr /* meta.diff.range */ {
font-weight: bold;
color: #6f42c1;
}
.pl-ba /* brackethighlighter.tag, brackethighlighter.curly, brackethighlighter.round, brackethighlighter.square, brackethighlighter.angle, brackethighlighter.quote */ {
color: #586069;
}
.pl-sg /* sublimelinter.gutter-mark */ {
color: #959da5;
}
.pl-corl /* constant.other.reference.link, string.other.link */ {
text-decoration: underline;
color: #032f62;
}

12
docs/static/icon.js vendored Normal file
View File

@ -0,0 +1,12 @@
var IconList={
"post":"M0 3.75C0 2.784.784 2 1.75 2h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25Zm1.75-.25a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-8.5a.25.25 0 0 0-.25-.25ZM3.5 6.25a.75.75 0 0 1 .75-.75h7a.75.75 0 0 1 0 1.5h-7a.75.75 0 0 1-.75-.75Zm.75 2.25h4a.75.75 0 0 1 0 1.5h-4a.75.75 0 0 1 0-1.5Z",
"link":"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z",
"person":"M10.561 8.073a6.005 6.005 0 0 1 3.432 5.142.75.75 0 1 1-1.498.07 4.5 4.5 0 0 0-8.99 0 .75.75 0 0 1-1.498-.07 6.004 6.004 0 0 1 3.431-5.142 3.999 3.999 0 1 1 5.123 0ZM10.5 5a2.5 2.5 0 1 0-5 0 2.5 2.5 0 0 0 5 0Z",
"github":"M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z",
"sun":"M8 10.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zM8 12a4 4 0 100-8 4 4 0 000 8zM8 0a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0V.75A.75.75 0 018 0zm0 13a.75.75 0 01.75.75v1.5a.75.75 0 01-1.5 0v-1.5A.75.75 0 018 13zM2.343 2.343a.75.75 0 011.061 0l1.06 1.061a.75.75 0 01-1.06 1.06l-1.06-1.06a.75.75 0 010-1.06zm9.193 9.193a.75.75 0 011.06 0l1.061 1.06a.75.75 0 01-1.06 1.061l-1.061-1.06a.75.75 0 010-1.061zM16 8a.75.75 0 01-.75.75h-1.5a.75.75 0 010-1.5h1.5A.75.75 0 0116 8zM3 8a.75.75 0 01-.75.75H.75a.75.75 0 010-1.5h1.5A.75.75 0 013 8zm10.657-5.657a.75.75 0 010 1.061l-1.061 1.06a.75.75 0 11-1.06-1.06l1.06-1.06a.75.75 0 011.06 0zm-9.193 9.193a.75.75 0 010 1.06l-1.06 1.061a.75.75 0 11-1.061-1.06l1.06-1.061a.75.75 0 011.061 0z",
"moon":"M9.598 1.591a.75.75 0 01.785-.175 7 7 0 11-8.967 8.967.75.75 0 01.961-.96 5.5 5.5 0 007.046-7.046.75.75 0 01.175-.786zm1.616 1.945a7 7 0 01-7.678 7.678 5.5 5.5 0 107.678-7.678z",
"search":"M15.7 13.3l-3.81-3.83A5.93 5.93 0 0 0 13 6c0-3.31-2.69-6-6-6S1 2.69 1 6s2.69 6 6 6c1.3 0 2.48-.41 3.47-1.11l3.83 3.81c.19.2.45.3.7.3.25 0 .52-.09.7-.3a.996.996 0 0 0 0-1.41v.01zM7 10.7c-2.59 0-4.7-2.11-4.7-4.7 0-2.59 2.11-4.7 4.7-4.7 2.59 0 4.7 2.11 4.7 4.7 0 2.59-2.11 4.7-4.7 4.7z",
"home":"M6.906.664a1.749 1.749 0 0 1 2.187 0l5.25 4.2c.415.332.657.835.657 1.367v7.019A1.75 1.75 0 0 1 13.25 15h-3.5a.75.75 0 0 1-.75-.75V9H7v5.25a.75.75 0 0 1-.75.75h-3.5A1.75 1.75 0 0 1 1 13.25V6.23c0-.531.242-1.034.657-1.366l5.25-4.2Zm1.25 1.171a.25.25 0 0 0-.312 0l-5.25 4.2a.25.25 0 0 0-.094.196v7.019c0 .138.112.25.25.25H5.5V8.25a.75.75 0 0 1 .75-.75h3.5a.75.75 0 0 1 .75.75v5.25h2.75a.25.25 0 0 0 .25-.25V6.23a.25.25 0 0 0-.094-.195Z",
"email":"M1.75 2h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25v-8.5C0 2.784.784 2 1.75 2ZM1.5 12.251c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V5.809L8.38 9.397a.75.75 0 0 1-.76 0L1.5 5.809v6.442Zm13-8.181v-.32a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25v.32L8 7.88Z"
}

184
plist_example.html Normal file
View File

@ -0,0 +1,184 @@
<html data-color-mode="light" data-dark-theme="dark" data-light-theme="light">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="https://unpkg.com/@primer/css@^21.0.7/dist/primer.css" rel="stylesheet" />
</head>
<style>
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 900px;
margin: 20px auto;
padding: 45px;
font-family: sans-serif;
}
@media (max-width: 767px) {
.markdown-body { padding: 8px;}
.subnav-search form{display:none;}
.subnav-search svg{display:none;}
.SideNav-item .listLabels{display:none;}
}
h1 {display:flex;}
h1 a{margin-left: 4px;margin-top: 16px;}
.title-right{display:flex;margin:auto 0 0 auto;}
.title-right button{margin-right:8px;padding:16px;}
.subnav-search{display:flex;margin-top:8px;margin-right:16px;}
.subnav-search-input{width:160px;border-top-right-radius:0px;border-bottom-right-radius:0px;}
.subnav-search form{margin-bottom:0;}
.subnav-search button{padding:5px 8px;border-top-left-radius:0px;border-bottom-left-radius:0px;}
.avatar {transition: 0.8s;}
.avatar:hover {transform: scale(1.15) rotate(360deg);}
.SideNav{min-width: 360px;}
.SideNav-icon{margin-right: 16px}
.SideNav-item .Label{color: #fff;margin-left:8px;}
.footer {margin: 40px auto; text-align: center;font-size: small;}
</style>
<body>
<div class="markdown-body">
<h1>
<img src='' size="64" height="64" width="64" class="avatar circle" id="avatarImg"><a style="font-family:Monaco;" id="blogTitle"></a>
<div class="title-right">
<div class="subnav-search">
<form action="https://www.google.com/search" method="get" target="_blank"><input type="search" name="q" class="form-control subnav-search-input" aria-label="Search site" value=""><button class="btn" type="submit">Search</button></form>
<svg class="subnav-search-icon octicon octicon-search" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"> <path id="searchSVG" fill-rule="evenodd" d=""></path></svg>
</div>
<button id="buttonLink" style="display: none;" class="btn btn-invisible circle" onclick="window.location.href='/link.html'" title="友情链接"><svg class="octicon" width="16" height="16" ><path fill-rule="evenodd"></path></svg></button>
<button id="buttonAbout" style="display: none;" class="btn btn-invisible circle" onclick="window.location.href='/about.html'" title="关于"><svg class="octicon" width="16" height="16" ><path fill-rule="evenodd"></path></svg></button>
<div><button id="changeTheme" class="btn btn-invisible circle" onclick="modeSwitch()" title="切换主题"><svg class="octicon" width="16" height="16" ><path id="themeSwitch" fill-rule="evenodd"></path></svg></button></div>
</div>
</h1>
<div id="blogSubTitle"></div><p></p>
<nav class="SideNav border"id="navList"></nav>
<div class="footer">Copyright © <span id="year"></span> <a id="footerblogTitle" href=""></a> <p><span id="filingNum"></span><span id="runday"></span>Powered by <a href="https://github.com/Meekdai/Gmeek" target="_blank">Gmeek</a></p></div>
</div>
</body>
<script src="./static/icon.js"></script>
<script>
var blogBase=%s
if(blogBase["startSite"]!=""){
var now=new Date();
var startSite=new Date(blogBase["startSite"]);
var diff=now.getTime()-startSite.getTime();
var diffDay=Math.floor(diff/(1000*60*60*24));
document.getElementById("year").innerHTML=now.getFullYear();
document.getElementById("runday").innerHTML="Blog run "+diffDay+" days • ";
}
var postListJson=blogBase["postListJson"]
document.title=blogBase["title"];
document.getElementById("avatarImg").src=blogBase["avatarUrl"];
document.getElementById("blogTitle").innerHTML=blogBase["title"].substring(1);
document.getElementById("blogSubTitle").innerHTML=blogBase["subTitle"];
if(blogBase["filingNum"]!=""){document.getElementById("filingNum").innerHTML=blogBase["filingNum"]+" • ";}
document.getElementById("footerblogTitle").innerHTML=blogBase["title"];
document.getElementById("footerblogTitle").href=blogBase["homeUrl"];
var navList=document.getElementById("navList");
if(blogBase["faviconUrl"]!=""){
link=document.createElement("link");
link.setAttribute("rel","icon");
link.setAttribute("href",blogBase["faviconUrl"]);
document.head.appendChild(link);
}
for(var num in postListJson){
if(blogBase["singlePage"].indexOf(postListJson[num]["label"])==-1){
SideNavItem=document.createElement("a");
SideNavItem.setAttribute("class", "SideNav-item d-flex flex-items-center flex-justify-between");
SideNavItem.setAttribute("href", postListJson[num]["postUrl"]);
div=document.createElement("div");
svg=document.createElementNS('http://www.w3.org/2000/svg','svg');
path=document.createElementNS("http://www.w3.org/2000/svg","path");
span=document.createElement("span");
div.setAttribute("class","d-flex flex-items-center");
svg.setAttributeNS(null,"class","SideNav-icon octicon");
svg.setAttributeNS(null,"style","witdh:16px;height:16px");
path.setAttributeNS(null, "d", IconList["post"]);
span.innerHTML=postListJson[num]["postTitle"];
svg.appendChild(path);
div.appendChild(svg);
div.appendChild(span);
SideNavItem.appendChild(div);
div=document.createElement("div");
div.setAttribute("class","listLabels");
if(postListJson[num]["commentNum"]>0){
span=document.createElement("span");
span.setAttribute("class","Label");
span.setAttribute("style","background-color:"+blogBase["commentLabelColor"]);
span.innerHTML=postListJson[num]["commentNum"];
div.appendChild(span);
}
span=document.createElement("span");
span.setAttribute("class","Label");
span.setAttribute("style","background-color:"+postListJson[num]["labelColor"]);
span.innerHTML=postListJson[num]["label"];
div.appendChild(span);
span=document.createElement("span");
span.setAttribute("class","Label");
span.setAttribute("style","background-color:"+postListJson[num]["dateLabelColor"]);
date=new Date(postListJson[num]["createdAt"] * 1000);
span.innerHTML=date.getFullYear()+"-"+(date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1)+"-"+(date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate());
div.appendChild(span);
SideNavItem.appendChild(div);
navList.appendChild(SideNavItem);
}
else{
if(postListJson[num]["label"]=="link"){
document.getElementById("buttonLink").childNodes[0].childNodes[0].setAttribute("d",value=IconList["link"]);
document.getElementById("buttonLink").style="display:block";
}
else if(postListJson[num]["label"]=="about"){
document.getElementById("buttonAbout").childNodes[0].childNodes[0].setAttribute("d",value=IconList["person"]);
document.getElementById("buttonAbout").style="display:block";
}
}
}
document.getElementById("searchSVG").setAttribute("d",value=IconList["search"]);
document.getElementById("themeSwitch").setAttribute("d",value=IconList["sun"]);
if(localStorage.getItem("meek_theme")==null){localStorage.setItem("meek_theme","light")}
else if(localStorage.getItem("meek_theme")=="dark"){changeDark();}
else if(localStorage.getItem("meek_theme")=="light"){changeLight();}
function changeDark(){
document.getElementsByTagName("html")[0].attributes.getNamedItem("data-color-mode").value="dark";
document.getElementById("themeSwitch").attributes.getNamedItem("d").value=IconList["moon"];
}
function changeLight(){
document.getElementsByTagName("html")[0].attributes.getNamedItem("data-color-mode").value="light";
document.getElementById("themeSwitch").attributes.getNamedItem("d").value=IconList["sun"];
}
function modeSwitch(){
if(document.getElementsByTagName("html")[0].attributes[0].value=="light"){changeDark();localStorage.setItem("meek_theme","dark");}
else{changeLight();localStorage.setItem("meek_theme","light");}
}
</script>
</html>

142
post_example.html Normal file
View File

@ -0,0 +1,142 @@
<html data-color-mode="light" data-dark-theme="dark" data-light-theme="light">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/github-light.css" rel="stylesheet" />
<link href="https://unpkg.com/@primer/css@^21.0.7/dist/primer.css" rel="stylesheet" />
</head>
<style>
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 900px;
margin: 10px auto;
padding: 45px;
font-family: sans-serif;
}
@media (max-width: 560px) {
.markdown-body { padding: 8px;}
}
.avatar {transition: 0.8s;}
.avatar:hover {transform: scale(1.15) rotate(360deg);}
h1 {display:flex;}
.title-right{display:flex;margin:auto 0 0 auto;}
.title-right button{margin-left:8px;padding:16px;}
.SideNav{min-width: 360px;}
.SideNav-icon{margin-right: 16px}
.comments{border-top: 2px solid var(--color-border-default);margin-top:64px;}
.footer {margin: 40px auto; text-align: center;font-size: small;}
#cmButton{height:48px;margin-top:48px;}
</style>
<body>
<div class="markdown-body">
<h1>
<div id="postTitle"></div>
<div class="title-right">
<button class="btn btn-invisible circle" onclick="window.location.href='/'" title="首页"><svg class="octicon octicon-sun" width="16" height="16"><path id="pathHome" fill-rule="evenodd"></path></svg></button>
<button class="btn btn-invisible circle" onclick="gotoSource()" title="Issue"><svg class="octicon octicon-sun" width="16" height="16"><path id="pathIssue" fill-rule="evenodd"></path></svg></button>
<button class="btn btn-invisible circle" onclick="modeSwitch()" title="切换主题"><svg class="octicon octicon-sun" width="16" height="16"><path id="themeSwitch" fill-rule="evenodd"></path></svg></button>
</div>
</h1>
<div id="postBody"></div>
<button class="btn btn-block" type="button" onclick="openComments()" id="cmButton">Comments </button>
<div class="comments" style="display:none;" id="comments"></div>
<div class="footer">Copyright © <span id="year"></span> <a id="footerblogTitle" href=""></a> <p><span id="filingNum"></span><span id="runday"></span>Powered by <a href="https://github.com/Meekdai/Gmeek" target="_blank">Gmeek</a></p></div>
</div>
</body>
<script src="../static/icon.js"></script>
<script>
var blogBase=%s
if(blogBase["startSite"]!=""){
var now=new Date();
var startSite=new Date(blogBase["startSite"]);
var diff=now.getTime()-startSite.getTime();
var diffDay=Math.floor(diff/(1000*60*60*24));
document.getElementById("year").innerHTML=now.getFullYear();
document.getElementById("runday").innerHTML="Blog run "+diffDay+" days • ";
}
document.title=blogBase["postTitle"];
document.getElementById("postTitle").innerHTML=blogBase["postTitle"];
document.getElementById("postBody").innerHTML=blogBase["postBody"];
if(blogBase["faviconUrl"]!=""){
link=document.createElement("link");
link.setAttribute("rel","icon");
link.setAttribute("href",blogBase["faviconUrl"]);
document.head.appendChild(link);
}
if(blogBase["filingNum"]!=""){document.getElementById("filingNum").innerHTML=blogBase["filingNum"]+" • ";}
document.getElementById("footerblogTitle").innerHTML=blogBase["title"];
document.getElementById("footerblogTitle").href=blogBase["homeUrl"];
function gotoSource(){window.open(blogBase["postSourceUrl"]);}
var utterancesLoad=0
document.getElementById("pathHome").setAttribute("d",value=IconList["home"]);
document.getElementById("pathIssue").setAttribute("d",value=IconList["github"]);
document.getElementById("themeSwitch").setAttribute("d",value=IconList["sun"]);
if(localStorage.getItem("meek_theme")==null){localStorage.setItem("meek_theme","light")}
else if(localStorage.getItem("meek_theme")=="dark"){changeDark();}
else if(localStorage.getItem("meek_theme")=="light"){changeLight();}
function changeDark(){
document.getElementsByTagName("html")[0].attributes.getNamedItem("data-color-mode").value="dark";
document.getElementById("themeSwitch").attributes.getNamedItem("d").value=IconList["moon"];
if(utterancesLoad==1){utterancesTheme("dark-blue");}
}
function changeLight(){
document.getElementsByTagName("html")[0].attributes.getNamedItem("data-color-mode").value="light";
document.getElementById("themeSwitch").attributes.getNamedItem("d").value=IconList["sun"];
if(utterancesLoad==1){utterancesTheme("github-light");}
}
function modeSwitch(){
if(document.getElementsByTagName("html")[0].attributes[0].value=="light"){changeDark();localStorage.setItem("meek_theme","dark");}
else{changeLight();localStorage.setItem("meek_theme","light");}
}
function utterancesTheme(theme){
const message = {type: 'set-theme',theme: theme};
const iframe = document.getElementsByClassName('utterances-frame')[0];
iframe.contentWindow.postMessage(message, 'https://utteranc.es');
}
if(blogBase["commentNum"]>0){
cmButton=document.getElementById("cmButton");
span=document.createElement("span");
span.setAttribute("class","Counter");
span.innerHTML=blogBase["commentNum"];
cmButton.appendChild(span);
}
function openComments(){
cm=document.getElementById("comments");
cmButton=document.getElementById("cmButton");
script=document.createElement("script");
script.setAttribute("src","https://utteranc.es/client.js");
script.setAttribute("repo",blogBase["repoName"]);
script.setAttribute("issue-term","title");
if(localStorage.getItem("meek_theme")=="dark"){script.setAttribute("theme","dark-blue");}
else{script.setAttribute("theme","github-light");}
script.setAttribute("crossorigin","anonymous");
script.setAttribute("async","");
cm.appendChild(script);
cmButton.style.display="none";
cm.style.display="block";
utterancesLoad=1;
}
</script>
</html>

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
PyGithub
requests
xpinyin