V1.0
This commit is contained in:
parent
d679afc59d
commit
a791ee8d95
53
.github/workflows/Gmeek.yml
vendored
Normal file
53
.github/workflows/Gmeek.yml
vendored
Normal 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
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
__pycache__
|
||||
nohup.out
|
||||
.git-credentials
|
||||
venv/
|
||||
169
Gmeek.py
Normal file
169
Gmeek.py
Normal 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
12
config.json
Normal 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
129
docs/static/github-light.css
vendored
Normal 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
12
docs/static/icon.js
vendored
Normal 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
184
plist_example.html
Normal 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
142
post_example.html
Normal 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
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
||||
PyGithub
|
||||
requests
|
||||
xpinyin
|
||||
Loading…
Reference in New Issue
Block a user