Compare commits

...

65 Commits
v2.17 ... main

Author SHA1 Message Date
Meekdai 77a8aaa2b1 Update GmeekVercount.js 2026-02-05 13:27:12 +08:00
Meekdai 93dd93bd31 Update GmeekBSZ.js 2026-02-05 13:25:17 +08:00
Meekdai 50d14d40e7
Merge pull request #303 from MaxLHy0424/main
修复witdh拼写错误和页脚添加空格
2026-02-05 10:34:35 +08:00
MaxLHy0424 027908eda8
更正语法错误 2026-02-04 23:39:28 +08:00
MaxLHy0424 3626570590
fix bug 2026-02-04 23:29:47 +08:00
Meekdai ac556c5cba 修复评论按钮多次点击导致的BUG 2024-11-12 09:04:07 +08:00
Meekdai 35263fd99d 修改首页h1标签为div 2024-08-16 12:07:27 +08:00
Meekdai f7ea52be7f 修复关闭状态的issue编辑后会被抓取的BUG 2024-08-15 18:19:40 +08:00
Meekdai 8beb6d388a Update plist.html 2024-08-14 14:15:36 +08:00
Meekdai 9f02e2620b Update post.html 2024-08-11 22:17:33 +08:00
Meekdai 6722f61728 Update GmeekTOC.js 2024-08-06 18:41:23 +08:00
Meekdai 2e78ea21dc Update GmeekTOC.js 2024-08-06 17:11:16 +08:00
Meekdai f2916398ce 添加代码复制按钮 2024-08-02 16:45:35 +08:00
Meekdai 1ff10bc070 Update GmeekVercount.js 2024-07-31 08:53:37 +08:00
Meekdai 82cd2aee91 Create GmeekVercount.js 2024-07-31 08:50:28 +08:00
Meekdai 15d5ea1e7d 如果文章中没有标题属性,则不创建TOC 2024-07-29 10:15:23 +08:00
Meekdai f733212c4b
Merge pull request #157 from tiengming/patch-1
Update lightbox.js
2024-07-26 20:46:27 +08:00
tiengming 841223f4f3
Update lightbox.js
1. 对于超大图完全显示
2. 按住ctrl+鼠标滚轮实现缩放。
3. 优化表格内图片显示不全问题。
4. 透明背景+高斯模糊,实现兼容不同主题。
2024-07-26 08:23:59 +08:00
Meekdai 72df0007a9 修复新增label无颜色的BUG 2024-07-25 16:40:16 +08:00
Meekdai 1efcf279d5
Merge pull request #151 from tiengming/main
新增灯箱插件
2024-07-24 22:29:08 +08:00
Meekdai ee38206dbb
Update static.yml 2024-07-24 22:23:45 +08:00
Meekdai b3ad18e700
Update static.yml 2024-07-24 22:18:36 +08:00
Meekdai 94fbc885b4
Update static.yml 2024-07-24 22:17:32 +08:00
Meekdai caeccdb4ce
Update static.yml 2024-07-24 22:14:19 +08:00
Meekdai 5016b545de
Update static.yml 2024-07-24 22:05:43 +08:00
Meekdai fb5cedb23e
Create static.yml 2024-07-24 21:56:40 +08:00
tiengming a2daa78448
Update lightbox.js 2024-07-24 19:24:43 +08:00
tiengming a2e40e84d4
Create lightbox.js
来个灯箱插件,预览看看:https://code.buxiantang.top/post/ji-yu-CloudFlare%20workers-ying-yong-jin-xing-AI-hui-tu.html
2024-07-24 19:09:30 +08:00
Meekdai 0e2ba5db7a 添加修改一些TOC插件 2024-07-24 14:55:37 +08:00
Meekdai 148a6aaf78 Update Gmeek.py 2024-07-19 15:40:24 +08:00
Meekdai 30e09c6aab 添加head配置,用于配置自定义文章页head内容 2024-07-19 15:17:21 +08:00
Meekdai a23cfe26be 添加allHead配置,用于自定义所有页面的head标签 2024-07-19 15:06:27 +08:00
Meekdai 1bb985b92e 优化底部信息 2024-07-19 14:41:03 +08:00
Meekdai 39ae055491 添加不蒜子插件 2024-07-19 14:29:14 +08:00
Meekdai ffd230c109 修复只有标题没有文章内容导致的获取字数失败的BUG 2024-07-11 09:15:58 +08:00
Meekdai bd7ec11c32 修改底部a标签空格的BUG 2024-07-06 21:25:36 +08:00
Meekdai 0841323a0d Update GmeekTOC.js 2024-07-03 18:31:27 +08:00
Meekdai 78ce8e048b Update GmeekTOC.js 2024-07-02 17:25:06 +08:00
Meekdai 6affa0c5e1 Create GmeekTOC.js 2024-07-02 16:07:39 +08:00
Meekdai fdfbf2a42e Update Gmeek.py 2024-07-01 22:17:51 +08:00
Meekdai 600898f139 修改static文件拷贝策略 2024-07-01 22:12:28 +08:00
Meekdai 4d9fe5ac8f needComment用于配置是否需要评论功能 2024-07-01 16:49:30 +08:00
Meekdai e93fd1b946 Update Gmeek.py 2024-07-01 16:42:20 +08:00
Meekdai ad55a2b0c0 Update Gmeek.py 2024-07-01 16:39:12 +08:00
Meekdai 00574fa648 添加static文件夹,用于存放用户自定义文件 2024-07-01 16:29:46 +08:00
Meekdai 4341f82b5d Update Gmeek.py 2024-07-01 16:01:53 +08:00
Meekdai f24c0743e9 Update Gmeek.py 2024-07-01 15:58:31 +08:00
Meekdai 49a4a46eb0 通过primerCSS自定义CDN的地址
默认使用南科大 https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/Primer/21.0.7/primer.css
2024-07-01 15:46:38 +08:00
Meekdai 9eaeb4ad9f Create LICENSE 2024-07-01 15:29:51 +08:00
Meekdai 8e6813fd7c Update Gmeek.py 2024-05-31 14:30:20 +08:00
Meekdai 4b25932edc Update Gmeek.py 2024-05-31 14:12:00 +08:00
Meekdai 7c3232fcb1 Update README.md 2024-05-30 16:20:38 +08:00
Meekdai 245d9af1ca change img 2024-05-30 16:16:33 +08:00
Meekdai 1ed8b84565 use html 2024-05-29 09:13:48 +08:00
Meekdai 1636f68819 Update Gmeek.py 2024-05-28 22:22:44 +08:00
Meekdai f8fcd03fdb add beautifulsoup4 2024-05-28 22:19:03 +08:00
Meekdai b3c7e297c4 Update Gmeek.py 2024-05-28 22:15:49 +08:00
Meekdai 61d2309b2a Update Gmeek.py 2024-05-28 21:42:03 +08:00
Meekdai a7e4e685c0 Update Gmeek.py 2024-05-28 21:40:26 +08:00
Meekdai 88e434cb26 添加文章页自定义html标签
##{"html":""}##
2024-05-28 18:13:41 +08:00
Meekdai be545404f2 Update Gmeek.py 2024-05-28 17:20:52 +08:00
Meekdai e0c5923dcb 添加5种alerts功能样式
具体可参考下面的链接
https://docs.github.com/zh/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts
2024-05-28 17:16:53 +08:00
Meekdai 0cc2674a4d 添加赞赏码 2024-05-28 09:13:35 +08:00
Meekdai 52a9d3b67c 添加首页script和style自定义功能
通过indexScript和indexStyle来配置
2024-05-22 09:18:01 +08:00
Meekdai 8131149b55 修复文章description里包含双引号导致的BUG 2024-05-20 09:36:03 +08:00
15 changed files with 968 additions and 45 deletions

43
.github/workflows/static.yml vendored Normal file
View File

@ -0,0 +1,43 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages
on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
# Upload entire repository
path: '.'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

100
Gmeek.py
View File

@ -8,6 +8,7 @@ import shutil
import urllib
import requests
import argparse
import html
from github import Github
from xpinyin import Pinyin
from feedgen.feed import FeedGenerator
@ -15,9 +16,9 @@ from jinja2 import Environment, FileSystemLoader
from transliterate import translit
from collections import OrderedDict
######################################################################################
i18n={"Search":"Search","switchTheme":"switch theme","home":"home","comments":"comments","run":"run ","days":" days","Previous":"Previous","Next":"Next"}
i18nCN={"Search":"搜索","switchTheme":"切换主题","home":"首页","comments":"评论","run":"网站运行","days":"","Previous":"上一页","Next":"下一页"}
i18nRU={"Search":"Поиск","switchTheme": "Сменить тему","home":"Главная","comments":"Комментарии","run":"работает ","days":" дней","Previous":"Предыдущая","Next":"Следующая"}
i18n={"Search":"Search","switchTheme":"switch theme","home":"home","comments":"comments","run":"run ","days":" day(s)","Previous":"Previous","Next":"Next"}
i18nCN={"Search":"搜索","switchTheme":"切换主题","home":"首页","comments":"评论","run":"网站运行 ","days":" ","Previous":"上一页","Next":"下一页"}
i18nRU={"Search":"Поиск","switchTheme": "Сменить тему","home":"Главная","comments":"Комментарии ","run":" работает ","days":" дней","Previous":"Предыдущая","Next":"Следующая"}
IconBase={
"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",
@ -29,7 +30,9 @@ IconBase={
"upload":"M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z M11.78 4.72a.749.749 0 1 1-1.06 1.06L8.75 3.811V9.5a.75.75 0 0 1-1.5 0V3.811L5.28 5.78a.749.749 0 1 1-1.06-1.06l3.25-3.25a.749.749 0 0 1 1.06 0l3.25 3.25Z",
"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",
"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",
"sync":"M1.705 8.005a.75.75 0 0 1 .834.656 5.5 5.5 0 0 0 9.592 2.97l-1.204-1.204a.25.25 0 0 1 .177-.427h3.646a.25.25 0 0 1 .25.25v3.646a.25.25 0 0 1-.427.177l-1.38-1.38A7.002 7.002 0 0 1 1.05 8.84a.75.75 0 0 1 .656-.834ZM8 2.5a5.487 5.487 0 0 0-4.131 1.869l1.204 1.204A.25.25 0 0 1 4.896 6H1.25A.25.25 0 0 1 1 5.75V2.104a.25.25 0 0 1 .427-.177l1.38 1.38A7.002 7.002 0 0 1 14.95 7.16a.75.75 0 0 1-1.49.178A5.5 5.5 0 0 0 8 2.5Z"
"sync":"M1.705 8.005a.75.75 0 0 1 .834.656 5.5 5.5 0 0 0 9.592 2.97l-1.204-1.204a.25.25 0 0 1 .177-.427h3.646a.25.25 0 0 1 .25.25v3.646a.25.25 0 0 1-.427.177l-1.38-1.38A7.002 7.002 0 0 1 1.05 8.84a.75.75 0 0 1 .656-.834ZM8 2.5a5.487 5.487 0 0 0-4.131 1.869l1.204 1.204A.25.25 0 0 1 4.896 6H1.25A.25.25 0 0 1 1 5.75V2.104a.25.25 0 0 1 .427-.177l1.38 1.38A7.002 7.002 0 0 1 14.95 7.16a.75.75 0 0 1-1.49.178A5.5 5.5 0 0 0 8 2.5Z",
"copy":"M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z",
"check":"M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"
}
######################################################################################
class GMEEK():
@ -37,6 +40,7 @@ class GMEEK():
self.options=options
self.root_dir='docs/'
self.static_dir='static/'
self.post_folder='post/'
self.backup_dir='backup/'
self.post_dir=self.root_dir+self.post_folder
@ -50,7 +54,6 @@ class GMEEK():
for label in self.repo.get_labels():
self.labelColorDict[label.name]='#'+label.color
print(self.labelColorDict)
self.defaultConfig()
def cleanFile(self):
@ -71,8 +74,21 @@ class GMEEK():
os.mkdir(self.root_dir)
os.mkdir(self.post_dir)
if os.path.exists(self.static_dir):
for item in os.listdir(self.static_dir):
src = os.path.join(self.static_dir, item)
dst = os.path.join(self.root_dir, item)
if os.path.isfile(src):
shutil.copy(src, dst)
print(f"Copied {item} to docs")
elif os.path.isdir(src):
shutil.copytree(src, dst)
print(f"Copied directory {item} to docs")
else:
print("static does not exist")
def defaultConfig(self):
dconfig={"singlePage":[],"startSite":"","filingNum":"","onePageListNum":15,"commentLabelColor":"#006b75","yearColorList":["#bc4c00", "#0969da", "#1f883d", "#A333D0"],"i18n":"CN","themeMode":"manual","dayTheme":"light","nightTheme":"dark","urlMode":"pinyin","script":"","style":"","bottomText":"","showPostSource":1,"iconList":{},"UTC":+8,"rssSplit":"sentence","exlink":{}}
dconfig={"singlePage":[],"startSite":"","filingNum":"","onePageListNum":15,"commentLabelColor":"#006b75","yearColorList":["#bc4c00", "#0969da", "#1f883d", "#A333D0"],"i18n":"CN","themeMode":"manual","dayTheme":"light","nightTheme":"dark","urlMode":"pinyin","script":"","style":"","head":"","indexScript":"","indexStyle":"","bottomText":"","showPostSource":1,"iconList":{},"UTC":+8,"rssSplit":"sentence","exlink":{},"needComment":1,"allHead":""}
config=json.loads(open('config.json', 'r', encoding='utf-8').read())
self.blogBase={**dconfig,**config}.copy()
self.blogBase["postListJson"]=json.loads('{}')
@ -87,6 +103,9 @@ class GMEEK():
if "ogImage" not in self.blogBase:
self.blogBase["ogImage"]=self.blogBase["avatarUrl"]
if "primerCSS" not in self.blogBase:
self.blogBase["primerCSS"]="<link href='https://mirrors.sustech.edu.cn/cdnjs/ajax/libs/Primer/21.0.7/primer.css' rel='stylesheet' />"
if "homeUrl" not in self.blogBase:
if str(self.repo.name).lower() == (str(self.repo.owner.login) + ".github.io").lower():
self.blogBase["homeUrl"] = f"https://{self.repo.name}"
@ -138,6 +157,29 @@ class GMEEK():
post_body=re.sub(r'</math-renderer>','',post_body)
issue["script"]=issue["script"]+'<script>MathJax = {tex: {inlineMath: [["$", "$"]]}};</script><script async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>'
if '<p class="markdown-alert-title">' in post_body:
issue["style"]=issue["style"]+'<style>.markdown-alert{padding:0.5rem 1rem;margin-bottom:1rem;border-left:.25em solid var(--borderColor-default,var(--color-border-default));}.markdown-alert .markdown-alert-title {display:flex;font-weight:var(--base-text-weight-medium,500);align-items:center;line-height:1;}.markdown-alert>:first-child {margin-top:0;}.markdown-alert>:last-child {margin-bottom:0;}</style>'
alerts = {
'note': 'accent',
'tip': 'success',
'important': 'done',
'warning': 'attention',
'caution': 'danger'
}
for alert, style in alerts.items():
if f'markdown-alert-{alert}' in post_body:
issue["style"] += (
f'<style>.markdown-alert.markdown-alert-{alert} {{'
f'border-left-color:var(--borderColor-{style}-emphasis, var(--color-{style}-emphasis));'
f'background-color:var(--color-{style}-subtle);}}'
f'.markdown-alert.markdown-alert-{alert} .markdown-alert-title {{'
f'color: var(--fgColor-{style},var(--color-{style}-fg));}}</style>'
)
if '<code class="notranslate">Gmeek-html' in post_body:
post_body = re.sub(r'<code class="notranslate">Gmeek-html(.*?)</code>', lambda match: html.unescape(match.group(1)), post_body, flags=re.DOTALL)
postBase["postTitle"]=issue["postTitle"]
postBase["postUrl"]=self.blogBase["homeUrl"]+"/"+issue["postUrl"]
postBase["description"]=issue["description"]
@ -146,19 +188,24 @@ class GMEEK():
postBase["commentNum"]=issue["commentNum"]
postBase["style"]=issue["style"]
postBase["script"]=issue["script"]
postBase["head"]=issue["head"]
postBase["top"]=issue["top"]
postBase["postSourceUrl"]=issue["postSourceUrl"]
postBase["repoName"]=options.repo_name
if "highlight" in post_body:
postBase["highlight"]=1
else:
postBase["highlight"]=0
if issue["labels"][0] in self.blogBase["singlePage"]:
postBase["bottomText"]=''
keys=['sun','moon','sync','home','github']
if '<pre class="notranslate">' in post_body:
keys=['sun','moon','sync','home','github','copy','check']
if '<div class="highlight' in post_body:
postBase["highlight"]=1
else:
postBase["highlight"]=2
else:
keys=['sun','moon','sync','home','github']
postBase["highlight"]=0
postIcon=dict(zip(keys, map(IconBase.get, keys)))
self.renderHtml('post.html',postBase,{},issue["htmlDir"],postIcon)
print("create postPage title=%s file=%s " % (issue["postTitle"],issue["htmlDir"]))
@ -279,17 +326,17 @@ class GMEEK():
self.blogBase[listJsonName][postNum]=json.loads('{}')
self.blogBase[listJsonName][postNum]["htmlDir"]=gen_Html
self.blogBase[listJsonName][postNum]["labels"]=[label.name for label in issue.labels]
# self.blogBase[listJsonName][postNum]["labelColor"]=self.labelColorDict[issue.labels[0].name]
self.blogBase[listJsonName][postNum]["postTitle"]=issue.title
self.blogBase[listJsonName][postNum]["postUrl"]=urllib.parse.quote(gen_Html[len(self.root_dir):])
self.blogBase[listJsonName][postNum]["postSourceUrl"]="https://github.com/"+options.repo_name+"/issues/"+str(issue.number)
self.blogBase[listJsonName][postNum]["commentNum"]=issue.get_comments().totalCount
self.blogBase[listJsonName][postNum]["wordCount"]=len(issue.body)
if issue.body==None:
self.blogBase[listJsonName][postNum]["description"]=''
self.blogBase[listJsonName][postNum]["wordCount"]=0
else:
self.blogBase[listJsonName][postNum]["wordCount"]=len(issue.body)
if self.blogBase["rssSplit"]=="sentence":
if self.blogBase["i18n"]=="CN":
period=""
@ -297,7 +344,7 @@ class GMEEK():
period="."
else:
period=self.blogBase["rssSplit"]
self.blogBase[listJsonName][postNum]["description"]=issue.body.split(period)[0]+period
self.blogBase[listJsonName][postNum]["description"]=issue.body.split(period)[0].replace("\"", "\'")+period
self.blogBase[listJsonName][postNum]["top"]=0
for event in issue.get_events():
@ -328,6 +375,11 @@ class GMEEK():
else:
self.blogBase[listJsonName][postNum]["script"]=self.blogBase["script"]
if "head" in postConfig:
self.blogBase[listJsonName][postNum]["head"]=self.blogBase["head"]+str(postConfig["head"])
else:
self.blogBase[listJsonName][postNum]["head"]=self.blogBase["head"]
if "ogImage" in postConfig:
self.blogBase[listJsonName][postNum]["ogImage"]=postConfig["ogImage"]
else:
@ -370,11 +422,14 @@ class GMEEK():
def runOne(self,number_str):
print("====== start create static html ======")
issue=self.repo.get_issue(int(number_str))
listJsonName=self.addOnePostJson(issue)
self.createPostHtml(self.blogBase[listJsonName]["P"+number_str])
self.createPlistHtml()
self.createFeedXml()
print("====== create static html end ======")
if issue.state == "open":
listJsonName=self.addOnePostJson(issue)
self.createPostHtml(self.blogBase[listJsonName]["P"+number_str])
self.createPlistHtml()
self.createFeedXml()
print("====== create static html end ======")
else:
print("====== issue is closed ======")
def createFileName(self,issue,useLabel=False):
if useLabel==True:
@ -416,8 +471,8 @@ else:
oldBlogBase=json.loads(f.read())
for key, value in oldBlogBase.items():
blog.blogBase[key] = value
f.close()
blog.blogBase["labelColorDict"]=blog.labelColorDict
blog.runOne(options.issue_number)
listFile=open("blogBase.json","w")
@ -438,6 +493,9 @@ for i in blog.blogBase["postListJson"]:
del blog.blogBase["postListJson"][i]["top"]
del blog.blogBase["postListJson"][i]["ogImage"]
if 'head' in blog.blogBase["postListJson"][i]:
del blog.blogBase["postListJson"][i]["head"]
if 'commentNum' in blog.blogBase["postListJson"][i]:
commentNumSum=commentNumSum+blog.blogBase["postListJson"][i]["commentNum"]
del blog.blogBase["postListJson"][i]["commentNum"]

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Meekdai
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -34,6 +34,12 @@
- 评论系统引入[utteranc.es](https://utteranc.es/)
- 使用`jinja2`对html进行渲染可通过模板自定义UI主题
### 赞赏
如果本项目对你有帮助,可以用微信赞赏一下作者,让项目有继续更新维护下去的动力,谢谢!
![赞赏码](img/赞赏码.jpg)
### 鸣谢
- [jinja2](https://jinja.palletsprojects.com/)
- [utteranc.es](https://utteranc.es/)
@ -43,3 +49,4 @@
### License
请保留页面底部和console界面版权信息谢谢

BIN
img/赞赏码.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

16
plugins/GmeekBSZ.js Normal file
View File

@ -0,0 +1,16 @@
function createBSZ() {
var postBody = document.getElementById('postBody');
if (postBody){
postBody.insertAdjacentHTML('afterend','<div id="busuanzi_container_page_pv" style="display:none;float:left;margin-top:8px;font-size:small;">本文浏览量 <span id="busuanzi_value_page_pv"></span> 次</div>');
}
var runday = document.getElementById('runday');
runday.insertAdjacentHTML('afterend', '<div id="busuanzi_container_site_pv" style="display:none;">总浏览量 <span id="busuanzi_value_site_pv"></span> 次 • </div>');
}
document.addEventListener("DOMContentLoaded", function() {
createBSZ();
var element = document.createElement('script');
element.src = '//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js';
document.head.appendChild(element);
console.log("\n %c GmeekBSZ Plugins https://github.com/Meekdai/Gmeek \n","padding:5px 0;background:#bc4c00;color:#fff");
});

100
plugins/GmeekTOC.js Normal file
View File

@ -0,0 +1,100 @@
function createTOC() {
var tocElement = document.createElement('div');
tocElement.className = 'toc';
var contentContainer = document.getElementById('content');
const headings = contentContainer.querySelectorAll('h1, h2, h3, h4, h5, h6');
if (headings.length === 0) {
return; // 如果没有标题元素则不创建TOC
}
tocElement.insertAdjacentHTML('afterbegin', '<div class="toc-title">文章目录</div>');
headings.forEach(heading => {
if (!heading.id) {
heading.id = heading.textContent.trim().replace(/\s+/g, '-').toLowerCase();
}
const link = document.createElement('a');
link.href = '#' + heading.id;
link.textContent = heading.textContent;
link.className = 'toc-link';
link.style.paddingLeft = `${(parseInt(heading.tagName.charAt(1)) - 1) * 10}px`;
tocElement.appendChild(link);
});
tocElement.insertAdjacentHTML('beforeend', '<a class="toc-end" onclick="window.scrollTo({top:0,behavior: \'smooth\'});">Top</a>');
contentContainer.prepend(tocElement);
}
document.addEventListener("DOMContentLoaded", function() {
createTOC();
var css = `
.toc {
position:fixed;
top:130px;
left:50%;
transform: translateX(50%) translateX(320px);
width:200px;
border: 1px solid #e1e4e8;
border-radius: 6px;
padding: 10px;
overflow-y: auto;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
max-height: 70vh;
}
.toc-title{
font-weight: bold;
text-align: center;
border-bottom: 1px solid #ddd;
padding-bottom: 8px;
}
.toc-end{
font-weight: bold;
text-align: center;
cursor: pointer;
visibility: hidden;
}
.toc a {
display: block;
color: var(--color-diff-blob-addition-num-text);
text-decoration: none;
padding: 5px 0;
font-size: 14px;
line-height: 1.5;
border-bottom: 1px solid #e1e4e8;
}
.toc a:last-child {
border-bottom: none;
}
.toc a:hover {
background-color:var(--color-select-menu-tap-focus-bg);
}
@media (max-width: 1249px)
{
.toc{
position:static;
top:auto;
left:auto;
transform:none;
padding:10px;
margin-bottom:20px;
}
}`;
const style = document.createElement('style');
style.textContent = css;
document.head.appendChild(style);
window.onscroll = function() {
const backToTopButton = document.querySelector('.toc-end');
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
backToTopButton.style="visibility: visible;"
} else {
backToTopButton.style="visibility: hidden;"
}
};
console.log("\n %c GmeekTOC Plugins https://github.com/Meekdai/Gmeek \n","padding:5px 0;background:#C333D0;color:#fff");
});

59
plugins/GmeekTocBot.js Normal file
View File

@ -0,0 +1,59 @@
function loadResource(type, attributes, callback) {
var element;
if (type === 'script') {
element = document.createElement('script');
element.src = attributes.src;
element.onload = callback;
} else if (type === 'link') {
element = document.createElement('link');
element.rel = attributes.rel;
element.href = attributes.href;
} else if (type === 'style') {
element = document.createElement('style');
element.rel = 'stylesheet';
element.appendChild(document.createTextNode(attributes.css));
}
document.head.appendChild(element);
}
function createTOC() {
var tocElement = document.createElement('div');
tocElement.className = 'toc';
var contentContainer = document.getElementById('content');
if (contentContainer.firstChild) {
contentContainer.insertBefore(tocElement, contentContainer.firstChild);
} else {
contentContainer.appendChild(tocElement);
}
}
document.addEventListener("DOMContentLoaded", function() {
createTOC();
var css = '.toc {position:fixed;top:130px;left:50%;transform: translateX(50%) translateX(300px);width:200px;padding-left:30px;}@media (max-width: 1249px) {.toc{position:static;top:auto;left:auto;transform:none;padding:10px;margin-bottom:20px;background-color:var(--color-open-muted);}}';
loadResource('style', {css: css});
loadResource('script', { src: 'https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.27.4/tocbot.min.js' }, function() {
tocbot.init({
tocSelector: '.toc',
contentSelector: '.markdown-body',
headingSelector: 'h1, h2, h3, h4, h5, h6',
scrollSmooth: true,
scrollSmoothOffset: -10,
headingsOffset: 10,
});
});
loadResource('link', { rel: 'stylesheet', href: 'https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.27.4/tocbot.css' });
const headings = document.querySelectorAll('.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6');
headings.forEach((heading) => {
if (!heading.id) {
heading.id = heading.textContent.trim().replace(/\s+/g, '-');
}
});
var footerPlaceholder = document.createElement('div');
footerPlaceholder.style.height = window.innerHeight + 'px';
document.body.appendChild(footerPlaceholder);
console.log("\n %c GmeekTocBot Plugins https://github.com/Meekdai/Gmeek \n","padding:5px 0;background:#C333D0;color:#fff");
});

16
plugins/GmeekVercount.js Normal file
View File

@ -0,0 +1,16 @@
function createVercount() {
var postBody = document.getElementById('postBody');
if (postBody){
postBody.insertAdjacentHTML('afterend','<div id="busuanzi_container_page_pv" style="display:none;float:left;margin-top:8px;font-size:small;">本文浏览量 <span id="busuanzi_value_page_pv"></span> 次</div>');
}
var runday = document.getElementById('runday');
runday.insertAdjacentHTML('afterend', '<span id="busuanzi_container_site_pv" style="display:none">总浏览量 <span id="busuanzi_value_site_pv"></span> 次 • </span>');
}
document.addEventListener("DOMContentLoaded", function() {
createVercount();
var element = document.createElement('script');
element.src = 'https://vercount.one/js';
document.head.appendChild(element);
console.log("\n %c GmeekVercount Plugins https://github.com/Meekdai/Gmeek \n","padding:5px 0;background:#bc4c00;color:#fff");
});

158
plugins/articletoc.js Normal file
View File

@ -0,0 +1,158 @@
function loadResource(type, attributes) {
if (type === 'style') {
const style = document.createElement('style');
style.textContent = attributes.css;
document.head.appendChild(style);
}
}
function createTOC() {
const tocElement = document.createElement('div');
tocElement.className = 'toc';
const contentContainer = document.querySelector('.markdown-body');
contentContainer.appendChild(tocElement);
const headings = contentContainer.querySelectorAll('h1, h2, h3, h4, h5, h6');
headings.forEach(heading => {
if (!heading.id) {
heading.id = heading.textContent.trim().replace(/\s+/g, '-').toLowerCase();
}
const link = document.createElement('a');
link.href = '#' + heading.id;
link.textContent = heading.textContent;
link.className = 'toc-link';
link.style.paddingLeft = `${(parseInt(heading.tagName.charAt(1)) - 1) * 10}px`;
tocElement.appendChild(link);
});
}
function toggleTOC() {
const tocElement = document.querySelector('.toc');
const tocIcon = document.querySelector('.toc-icon');
if (tocElement) {
tocElement.classList.toggle('show');
tocIcon.classList.toggle('active');
tocIcon.textContent = tocElement.classList.contains('show') ? '✖' : '☰';
}
}
document.addEventListener("DOMContentLoaded", function() {
createTOC();
const css = `
:root {
--toc-bg: #fff;
--toc-border: #e1e4e8;
--toc-text: #24292e;
--toc-hover: #f6f8fa;
--toc-icon-bg: #fff;
--toc-icon-color: #ad6598;
--toc-icon-active-bg: #813c85;
--toc-icon-active-color: #fff;
}
@media (prefers-color-scheme: dark) {
:root {
--toc-bg: #2d333b;
--toc-border: #444c56;
--toc-text: #adbac7;
--toc-hover: #373e47;
--toc-icon-bg: #22272e;
--toc-icon-color: #ad6598;
--toc-icon-active-bg: #813c85;
--toc-icon-active-color: #adbac7;
}
}
.toc {
position: fixed;
bottom: 60px;
right: 20px;
width: 250px;
max-height: 70vh;
background-color: var(--toc-bg);
border: 1px solid var(--toc-border);
border-radius: 6px;
padding: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
overflow-y: auto;
z-index: 1000;
opacity: 0;
visibility: hidden;
transform: translateY(20px) scale(0.9);
transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s;
}
.toc.show {
opacity: 1;
visibility: visible;
transform: translateY(0) scale(1);
}
.toc a {
display: block;
color: var(--toc-text);
text-decoration: none;
padding: 5px 0;
font-size: 14px;
line-height: 1.5;
border-bottom: 1px solid var(--toc-border);
transition: background-color 0.2s ease, padding-left 0.2s ease;
}
.toc a:last-child {
border-bottom: none;
}
.toc a:hover {
background-color: var(--toc-hover);
padding-left: 5px;
}
.toc-icon {
position: fixed;
bottom: 20px;
right: 20px;
cursor: pointer;
font-size: 24px;
background-color: var(--toc-icon-bg);
color: var(--toc-icon-color);
border: 2px solid var(--toc-icon-color);
border-radius: 50%;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 1px 3px rgba(0,0,0,0.12);
z-index: 1001;
transition: all 0.3s ease;
user-select: none;
-webkit-tap-highlight-color: transparent;
outline: none;
}
.toc-icon:hover {
transform: scale(1.1);
}
.toc-icon:active {
transform: scale(0.9);
}
.toc-icon.active {
background-color: var(--toc-icon-active-bg);
color: var(--toc-icon-active-color);
border-color: var(--toc-icon-active-bg);
transform: rotate(90deg);
}
`;
loadResource('style', {css: css});
const tocIcon = document.createElement('div');
tocIcon.className = 'toc-icon';
tocIcon.textContent = '☰';
tocIcon.onclick = (e) => {
e.stopPropagation();
toggleTOC();
};
document.body.appendChild(tocIcon);
document.addEventListener('click', (e) => {
const tocElement = document.querySelector('.toc');
if (tocElement && tocElement.classList.contains('show') && !tocElement.contains(e.target) && !e.target.classList.contains('toc-icon')) {
toggleTOC();
}
});
});

357
plugins/lightbox.js Normal file
View File

@ -0,0 +1,357 @@
(function() {
class Lightbox {
constructor(options = {}) {
this.options = Object.assign({
animationDuration: 300,
closeOnOverlayClick: true,
onOpen: null,
onClose: null,
onNavigate: null
}, options);
this.images = [];
this.currentIndex = 0;
this.isOpen = false;
this.zoomLevel = 1;
this.touchStartX = 0;
this.touchEndX = 0;
this.wheelTimer = null;
this.preloadedImages = {};
this.init();
}
init() {
this.createStyles();
this.createLightbox();
this.bindEvents();
}
createStyles() {
const style = document.createElement('style');
style.textContent = `
.lb-lightbox-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
backdrop-filter: blur(5px);
display: flex;
justify-content: center;
align-items: center;
opacity: 0;
transition: opacity ${this.options.animationDuration}ms ease;
pointer-events: none;
z-index: 10000;
}
.lb-lightbox-overlay.active {
pointer-events: auto;
opacity: 1;
}
.lb-lightbox-content-wrapper {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.lb-lightbox-container {
width: 100%;
height: 100%;
position: relative;
transition: transform ${this.options.animationDuration}ms cubic-bezier(0.25, 0.1, 0.25, 1);
overflow: hidden;
}
.lb-lightbox-image-wrapper {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
}
.lb-lightbox-image {
max-width: 100%;
max-height: 100%;
height: auto;
object-fit: contain;
border-radius: 16px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
transition: transform ${this.options.animationDuration}ms cubic-bezier(0.25, 0.1, 0.25, 1), opacity ${this.options.animationDuration}ms ease;
opacity: 0;
}
.lb-lightbox-nav, .lb-lightbox-close {
position: absolute;
background-color: rgba(255, 255, 255, 0.8);
color: #333;
border: none;
border-radius: 50%;
cursor: pointer;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
width: 50px;
height: 50px;
font-size: 30px;
z-index: 2;
transition: transform 0.2s ease;
}
.lb-lightbox-nav:hover {
transform: scale(1.1);
}
.lb-lightbox-prev {
left: 20px;
top: calc(50% - 25px);
}
.lb-lightbox-next {
right: 20px;
top: calc(50% - 25px);
}
.lb-lightbox-close {
top: 20px;
right: 20px;
}
@media (max-width: 768px) {
.lb-lightbox-nav, .lb-lightbox-close {
width: 40px;
height: 40px;
font-size: 20px;
}
}
`;
document.head.appendChild(style);
}
createLightbox() {
this.overlay = document.createElement('div');
this.overlay.className = 'lb-lightbox-overlay';
this.contentWrapper = document.createElement('div');
this.contentWrapper.className = 'lb-lightbox-content-wrapper';
this.container = document.createElement('div');
this.container.className = 'lb-lightbox-container';
this.imageWrapper = document.createElement('div');
this.imageWrapper.className = 'lb-lightbox-image-wrapper';
this.image = document.createElement('img');
this.image.className = 'lb-lightbox-image';
this.prevButton = document.createElement('button');
this.prevButton.className = 'lb-lightbox-nav lb-lightbox-prev';
this.prevButton.innerHTML = '&#10094;';
this.nextButton = document.createElement('button');
this.nextButton.className = 'lb-lightbox-nav lb-lightbox-next';
this.nextButton.innerHTML = '&#10095;';
this.closeButton = document.createElement('button');
this.closeButton.className = 'lb-lightbox-close';
this.closeButton.innerHTML = '&times;';
this.imageWrapper.appendChild(this.image);
this.container.appendChild(this.imageWrapper);
this.contentWrapper.appendChild(this.container);
this.contentWrapper.appendChild(this.prevButton);
this.contentWrapper.appendChild(this.nextButton);
this.contentWrapper.appendChild(this.closeButton);
this.overlay.appendChild(this.contentWrapper);
document.body.appendChild(this.overlay);
this.closeButton.addEventListener('click', this.close.bind(this));
}
bindEvents() {
document.addEventListener('click', this.handleImageClick.bind(this), true);
this.overlay.addEventListener('click', this.handleOverlayClick.bind(this));
this.prevButton.addEventListener('click', this.showPreviousImage.bind(this));
this.nextButton.addEventListener('click', this.showNextImage.bind(this));
this.closeButton.addEventListener('click', this.close.bind(this));
document.addEventListener('keydown', this.handleKeyDown.bind(this));
this.overlay.addEventListener('wheel', this.handleWheel.bind(this));
this.overlay.addEventListener('touchstart', this.handleTouchStart.bind(this));
this.overlay.addEventListener('touchmove', this.handleTouchMove.bind(this));
this.overlay.addEventListener('touchend', this.handleTouchEnd.bind(this));
}
handleImageClick(event) {
const clickedImage = event.target.closest('img');
if (clickedImage && !this.isOpen) {
event.preventDefault();
event.stopPropagation();
this.images = Array.from(document.querySelectorAll('.markdown-body img, table img'));
this.currentIndex = this.images.indexOf(clickedImage);
this.open();
}
}
handleOverlayClick(event) {
if (event.target === this.overlay && this.options.closeOnOverlayClick) {
this.close();
}
}
handleKeyDown(event) {
if (!this.isOpen) return;
switch (event.key) {
case 'ArrowLeft':
this.showPreviousImage();
break;
case 'ArrowRight':
this.showNextImage();
break;
case 'Escape':
this.close();
break;
}
}
handleWheel(event) {
event.preventDefault();
if (event.ctrlKey) {
this.zoomLevel += event.deltaY > 0 ? -0.1 : 0.1;
this.zoomLevel = Math.max(1, this.zoomLevel);
this.image.style.transform = `scale(${this.zoomLevel})`;
} else {
clearTimeout(this.wheelTimer);
this.wheelTimer = setTimeout(() => {
const delta = Math.sign(event.deltaY);
if (delta > 0) {
this.showNextImage();
} else {
this.showPreviousImage();
}
}, 50);
}
}
handleTouchStart(event) {
this.touchStartX = event.touches[0].clientX;
}
handleTouchMove(event) {
this.touchEndX = event.touches[0].clientX;
}
handleTouchEnd() {
const difference = this.touchStartX - this.touchEndX;
if (Math.abs(difference) > 50) {
difference > 0 ? this.showNextImage() : this.showPreviousImage();
}
}
open() {
this.isOpen = true;
this.overlay.classList.add('active');
this.showImage(this.images[this.currentIndex].src);
document.body.style.overflow = 'hidden';
if (typeof this.options.onOpen === 'function') {
this.options.onOpen();
}
}
close() {
document.body.style.overflow = '';
this.overlay.classList.remove('active');
this.isOpen = false;
this.clearPreloadedImages();
if (typeof this.options.onClose === 'function') {
this.options.onClose();
}
this.unbindEvents();
}
showPreviousImage() {
if (this.currentIndex > 0) {
this.currentIndex--;
this.showImage(this.images[this.currentIndex].src);
this.resetButtonScale(this.prevButton);
}
}
showNextImage() {
if (this.currentIndex < this.images.length - 1) {
this.currentIndex++;
this.showImage(this.images[this.currentIndex].src);
this.resetButtonScale(this.nextButton);
}
}
resetButtonScale(button) {
button.style.transform = 'scale(1.1)';
setTimeout(() => {
button.style.transform = 'scale(1)';
}, 200);
}
showImage(imgSrc) {
const newImage = new Image();
newImage.src = imgSrc;
newImage.onload = () => {
this.image.style.transition = `opacity ${this.options.animationDuration}ms ease`;
this.image.style.transform = 'scale(1)';
this.image.src = imgSrc;
this.image.style.opacity = '1';
this.preloadImages();
this.prevButton.style.display = this.currentIndex === 0 ? 'none' : 'block';
this.nextButton.style.display = this.currentIndex === this.images.length - 1 ? 'none' : 'block';
};
newImage.onerror = () => {
console.error('Failed to load image:', imgSrc);
};
}
preloadImages() {
const preloadNext = this.currentIndex + 1;
const preloadPrev = this.currentIndex - 1;
if (preloadNext < this.images.length) {
this.preloadedImages[preloadNext] = new Image();
this.preloadedImages[preloadNext].src = this.images[preloadNext].src;
}
if (preloadPrev >= 0) {
this.preloadedImages[preloadPrev] = new Image();
this.preloadedImages[preloadPrev].src = this.images[preloadPrev].src;
}
}
clearPreloadedImages() {
Object.keys(this.preloadedImages).forEach(key => {
this.preloadedImages[key].src = '';
});
this.preloadedImages = {};
}
unbindEvents() {
document.removeEventListener('click', this.handleImageClick.bind(this), true);
this.overlay.removeEventListener('click', this.handleOverlayClick.bind(this));
this.prevButton.removeEventListener('click', this.showPreviousImage.bind(this));
this.nextButton.removeEventListener('click', this.showNextImage.bind(this));
this.closeButton.removeEventListener('click', this.close.bind(this));
document.removeEventListener('keydown', this.handleKeyDown.bind(this));
this.overlay.removeEventListener('wheel', this.handleWheel.bind(this));
this.overlay.removeEventListener('touchstart', this.handleTouchStart.bind(this));
this.overlay.removeEventListener('touchmove', this.handleTouchMove.bind(this));
this.overlay.removeEventListener('touchend', this.handleTouchEnd.bind(this));
}
}
window.Lightbox = Lightbox;
document.addEventListener('DOMContentLoaded', () => {
new Lightbox();
});
})();

View File

@ -4,7 +4,8 @@
<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="//cdn.staticfile.net/Primer/21.0.7/primer.css" rel="stylesheet" />
{{ blogBase['primerCSS'] }}
{{ blogBase['allHead'] }}
<link rel="icon" href="{{ blogBase['faviconUrl'] }}">
{%- if blogBase['themeMode']=='manual' -%}
<script>
@ -57,9 +58,8 @@ function utterancesTheme(theme){
}
if(themeSettings[theme]){changeTheme(...themeSettings[theme]);}
{%- endif %}
console.log("\n %c Gmeek {{ blogBase['GMEEK_VERSION'] }} https://github.com/Meekdai/Gmeek \n\n","padding:5px 0;background:#02d81d;color:#fff");
console.log("\n %c Gmeek {{ blogBase['GMEEK_VERSION'] }} https://github.com/Meekdai/Gmeek \n","padding:5px 0;background:#02d81d;color:#fff");
</script>
{% block script %}{% endblock %}
{{ blogBase['script'] }}
</html>

View File

@ -1,20 +1,19 @@
Copyright © <span id="year"></span><a href="{{ blogBase['homeUrl'] }}"> {{ blogBase['title'] }} </a>
<p>
{%- if blogBase['filingNum']!='' -%}
<a href="https://beian.miit.gov.cn/" target="_blank">{{ blogBase['filingNum'] }}</a>
{%- endif %}
<span id="runday"></span>Powered by <a href="https://meekdai.com/Gmeek.html" target="_blank">Gmeek</a>
</p>
<div id="footer1">Copyright © <span id="copyrightYear"></span> <a href="{{ blogBase['homeUrl'] }}">{{ blogBase['title'] }}</a></div>
<div id="footer2">
{%- if blogBase['filingNum']!='' -%}
<span id="filingNum"><a href="https://beian.miit.gov.cn/" target="_blank">{{ blogBase['filingNum'] }}</a></span>
{%- endif %}
<span id="runday"></span><span>Powered by <a href="https://meekdai.com/Gmeek.html" target="_blank">Gmeek</a></span>
</div>
<script>
var now=new Date();
document.getElementById("copyrightYear").innerHTML=now.getFullYear();
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();
if("{{ blogBase['filingNum'] }}"!=""){document.getElementById("runday").innerHTML=" • "+"{{ i18n['run'] }}"+diffDay+"{{ i18n['days'] }}"+" • ";}
else{document.getElementById("runday").innerHTML="{{ i18n['run'] }}"+diffDay+"{{ i18n['days'] }}"+" • ";}
document.getElementById("runday").innerHTML="{{ i18n['run'] }}"+diffDay+"{{ i18n['days'] }}"+" • ";
}
</script>

View File

@ -13,7 +13,7 @@
<style>
.avatar {transition: 0.8s;width:64px;height:64px;object-fit: cover;}
.avatar:hover{transform: scale(1.15) rotate(360deg);}
#header h1 a{color:inherit;text-decoration:none;vertical-align: bottom;font-size:40px;font-family:Monaco;margin-left:8px;}
.title-left a{color:inherit;text-decoration:none;vertical-align: bottom;font-size:40px;font-weight: bold;font-family:Monaco;margin-left:8px;}
.title-right{display:flex;margin:auto 0 0 auto;}
.title-right button{margin-right:8px;padding:16px;}
.title-right .circle{padding: 14px 16px;}
@ -34,17 +34,18 @@
.LabelTime{display:none;}
}
</style>
{{ blogBase['indexStyle'] }}
{% endblock %}
{% block header %}
<h1>
<div class="title-left">
<img src="{{ blogBase['avatarUrl'] }}" class="avatar circle" id="avatarImg" alt="avatar">
{%- if blogBase['displayTitle']=='eekdai' -%}
<a class="blogTitle" href="https://meekdai.com">{{ blogBase['displayTitle'] }}</a>
{%- if blogBase['displayTitle']=='Meekdai' -%}
<a class="blogTitle" href="https://meekdai.com"><span style="font-size:0;">M</span>eekdai</a>
{% else -%}
<a class="blogTitle">{{ blogBase['displayTitle'] }}</a>
{%- endif -%}
</h1>
</div>
<div class="title-right">
<a href="{{ blogBase['homeUrl'] }}/tag.html" id="buttonSearch" class="btn btn-invisible circle" title="{{ i18n['Search'] }}">
<svg class="octicon" width="16" height="16" >
@ -84,7 +85,7 @@
{% for num in postListJson -%}
<a class="SideNav-item d-flex flex-items-center flex-justify-between" href="{{ postListJson[num]['postUrl']|e }}">
<div class="d-flex flex-items-center">
<svg class="SideNav-icon octicon" style="witdh:16px;height:16px"><path class="svgTop{{ postListJson[num]['top'] }}" d=""></path>
<svg class="SideNav-icon octicon" style="width:16px;height:16px"><path class="svgTop{{ postListJson[num]['top'] }}" d=""></path>
</svg>
<span class="listTitle">{{ postListJson[num]['postTitle']|e }}</span>
</div>
@ -140,4 +141,5 @@ document.getElementById("{{ key }}").setAttribute("d",value=IconList["{{ key }}"
document.getElementById("{{ blogBase['singeListJson'][num]['postTitle'] }}").setAttribute("d",value=IconList["{{ blogBase['singeListJson'][num]['labels'][0] }}"]);
{%- endfor %}
</script>
{{ blogBase['indexScript'] }}
{% endblock %}

View File

@ -9,6 +9,7 @@
<meta property="og:image" content="{{ blogBase['ogImage'] }}">
<title>{{ blogBase['postTitle'] }}</title>
{% if blogBase['highlight']==1 %}<link href="//unpkg.com/@wooorm/starry-night@2.1.1/style/both.css" rel="stylesheet" />{% endif %}
{{ blogBase['head'] }}
{% endblock %}
{% block style %}
@ -25,6 +26,18 @@
body {padding: 8px;}
.postTitle{font-size:24px;}
}
{% if blogBase['highlight']!=0 -%}
.copy-feedback {
display: none;
position: absolute;
top: 10px;
right: 50px;
color: var(--color-fg-on-emphasis);
background-color: var(--color-fg-muted);
border-radius: 3px;
padding: 5px 8px;
font-size: 12px;
}{% endif %}
</style>
{{ blogBase['style'] }}
@ -57,14 +70,16 @@
{% block content %}
<div class="markdown-body" id="postBody">{{ blogBase['postBody'] }}</div>
<div style="font-size:small;margin-top:8px;float:right;">{{ blogBase['bottomText'] }}</div>
{% if blogBase['needComment']==1 %}
<button class="btn btn-block" type="button" onclick="openComments()" id="cmButton">{{ i18n['comments'] }}</button>
<div class="comments" id="comments"></div>
{% endif %}
{% endblock %}
{% block script %}
<script>
document.getElementById("pathHome").setAttribute("d",IconList["home"]);
document.getElementById("pathIssue").setAttribute("d",IconList["github"]);
{% if blogBase['showPostSource']==1 %}document.getElementById("pathIssue").setAttribute("d",IconList["github"]);{% endif %}
{% if blogBase['commentNum']>0 -%}
cmButton=document.getElementById("cmButton");
span=document.createElement("span");
@ -72,9 +87,12 @@ document.getElementById("pathIssue").setAttribute("d",IconList["github"]);
span.innerHTML="{{ blogBase['commentNum'] }}";
cmButton.appendChild(span);
{%- endif %}
{% if blogBase['needComment']==1 %}
function openComments(){
cm=document.getElementById("comments");
cmButton=document.getElementById("cmButton");
cmButton.disabled=true;
cmButton.innerHTML="loading";
span=document.createElement("span");
span.setAttribute("class","AnimatedEllipsis");
@ -109,6 +127,75 @@ function iFrameLoading(){
}
}
}
</script>
{%- endif %}
{% if blogBase['highlight']!=0 -%}
document.addEventListener('DOMContentLoaded', () => {
const createClipboardHTML = (codeContent, additionalClasses = '') => `
<pre class="notranslate"><code class="notranslate">${codeContent}</code></pre>
<div class="clipboard-container position-absolute right-0 top-0 ${additionalClasses}">
<clipboard-copy class="ClipboardButton btn m-2 p-0" role="button" style="display: inherit;">
<svg height="16" width="16" class="octicon octicon-copy m-2"><path d="${IconList["copy"]}"></path></svg>
<svg height="16" width="16" class="octicon octicon-check color-fg-success m-2 d-none"><path d="${IconList["check"]}"></path></svg>
</clipboard-copy>
<div class="copy-feedback">Copied!</div>
</div>
`;
const handleCodeElements = (selector = '') => {
document.querySelectorAll(selector).forEach(codeElement => {
const codeContent = codeElement.innerHTML;
const newStructure = document.createElement('div');
newStructure.className = 'snippet-clipboard-content position-relative overflow-auto';
newStructure.innerHTML = createClipboardHTML(codeContent);
const parentElement = codeElement.parentElement;
if (selector.includes('highlight')) {
parentElement.insertBefore(newStructure, codeElement.nextSibling);
parentElement.removeChild(codeElement);
} else {
parentElement.parentElement.replaceChild(newStructure, parentElement);
}
});
};
handleCodeElements('pre.notranslate > code.notranslate');
handleCodeElements('div.highlight > pre.notranslate');
let currentFeedback = null;
document.querySelectorAll('clipboard-copy').forEach(copyButton => {
copyButton.addEventListener('click', () => {
const codeContent = copyButton.closest('.snippet-clipboard-content').innerText;
const tempTextArea = document.createElement('textarea');
tempTextArea.value = codeContent;
document.body.appendChild(tempTextArea);
tempTextArea.select();
document.execCommand('copy');
document.body.removeChild(tempTextArea);
const copyIcon = copyButton.querySelector('.octicon-copy');
const checkIcon = copyButton.querySelector('.octicon-check');
const copyFeedback = copyButton.nextElementSibling;
if (currentFeedback && currentFeedback !== copyFeedback) {currentFeedback.style.display = 'none';}
currentFeedback = copyFeedback;
copyIcon.classList.add('d-none');
checkIcon.classList.remove('d-none');
copyFeedback.style.display = 'block';
copyButton.style.borderColor = 'var(--color-success-fg)';
setTimeout(() => {
copyIcon.classList.remove('d-none');
checkIcon.classList.add('d-none');
copyFeedback.style.display = 'none';
copyButton.style.borderColor = '';
}, 2000);
});
});
});
{%- endif %}
</script>
{{ blogBase['script'] }}
{% endblock %}