精简若干功能,优化slug生成规则
This commit is contained in:
1 parent
05bf116c20
commit
f9b2a0e77b
15 files changed
+76
-41
No files matched your search
@@ -49,6 +49,12 @@ jobs:
|
||||
continue-on-error: true
|
||||
run: node scripts/optimize_images.js
|
||||
|
||||
- name: Fetch AI Greetings
|
||||
continue-on-error: true
|
||||
env:
|
||||
RSS_API_TOKEN: ${{ secrets.RSS_API_TOKEN }}
|
||||
run: node scripts/fetch_greetings.js
|
||||
|
||||
- name: Commit Optimized Images
|
||||
continue-on-error: true
|
||||
run: |
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+3
-3
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: 尝试接入telegram机器人
|
||||
date: '2026-06-01T00:00:00.000Z'
|
||||
slug: 2026-06-01-尝试接入-telegram-机器人
|
||||
title: 尝试接入 telegram 机器人
|
||||
date: '2026-06-02T00:00:00.000Z'
|
||||
slug: '202606021139'
|
||||
draft: false
|
||||
categories:
|
||||
- 生活
|
||||
@@ -219,7 +219,7 @@ hasCJKLanguage = true
|
||||
# 打赏配置 (Reward Configuration)
|
||||
# ----------------------------------------------------------------------------
|
||||
[params.reward]
|
||||
enable = true
|
||||
enable = false
|
||||
wechat = "/image/reward/new.png"
|
||||
# alipay = "/image/reward/alipay.jpg"
|
||||
# qq = "/image/reward/reward.png"
|
||||
|
||||
@@ -58,13 +58,13 @@ async function main() {
|
||||
}
|
||||
});
|
||||
|
||||
// Pick one random greeting per time slot, fall back to generic pool
|
||||
// Keep all greetings per time slot (frontend picks randomly)
|
||||
var timeGreetings = {};
|
||||
timeKeys.forEach(function(key) {
|
||||
var list = byTime[key];
|
||||
if (list.length === 0) list = generic;
|
||||
if (list.length > 0) {
|
||||
timeGreetings[key] = list[Math.floor(Math.random() * list.length)];
|
||||
timeGreetings[key] = list;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -354,17 +354,19 @@ function initInlineSearch() {
|
||||
}
|
||||
// 2. Check Time of Day (if greetings configured)
|
||||
else if (window.searchGreetings) {
|
||||
if (hour >= 6 && hour < 11 && window.searchGreetings.morning) {
|
||||
text = window.searchGreetings.morning;
|
||||
} else if (hour >= 11 && hour < 14 && window.searchGreetings.noon) {
|
||||
text = window.searchGreetings.noon;
|
||||
} else if (hour >= 14 && hour < 18 && window.searchGreetings.afternoon) {
|
||||
text = window.searchGreetings.afternoon;
|
||||
} else if (hour >= 18 && hour < 22 && window.searchGreetings.evening) {
|
||||
text = window.searchGreetings.evening;
|
||||
} else if ((hour >= 22 || hour < 6) && window.searchGreetings.night) {
|
||||
text = window.searchGreetings.night;
|
||||
function pickGreeting(key) {
|
||||
var val = window.searchGreetings[key];
|
||||
if (!val) return null;
|
||||
if (Array.isArray(val)) return val[Math.floor(Math.random() * val.length)];
|
||||
return val;
|
||||
}
|
||||
var picked = null;
|
||||
if (hour >= 6 && hour < 11) picked = pickGreeting('morning');
|
||||
else if (hour >= 11 && hour < 14) picked = pickGreeting('noon');
|
||||
else if (hour >= 14 && hour < 18) picked = pickGreeting('afternoon');
|
||||
else if (hour >= 18 && hour < 22) picked = pickGreeting('evening');
|
||||
else if (hour >= 22 || hour < 6) picked = pickGreeting('night');
|
||||
if (picked) text = picked;
|
||||
}
|
||||
|
||||
var typeInterval;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { deployQueue } from "@/lib/git";
|
||||
import { hugo } from "@/lib/hugo";
|
||||
import { getLanIP, DEFAULT_AUTHOR } from "@/lib/config";
|
||||
import { sendMessage, tg } from "./tg";
|
||||
import { getSession, hasSession, clearSession, saveSession, undoLastChunk } from "./sessions";
|
||||
import { getSession, hasSession, clearSession, saveSession, undoLastChunk, initSessionDir } from "./sessions";
|
||||
import { makeSlug, sessionSummary, truncateText } from "./helpers";
|
||||
import { getCached, setCache, invalidateByPrefix } from "./cache";
|
||||
|
||||
@@ -221,6 +221,7 @@ handlers.new = async (chatId, title) => {
|
||||
s.draft = true;
|
||||
s.author = DEFAULT_AUTHOR;
|
||||
s.chunks = [];
|
||||
initSessionDir(chatId, title);
|
||||
await tg("sendMessage", {
|
||||
chat_id: chatId,
|
||||
text: "📝 开始写:<b>" + title + "</b>\n\n📂 设置分类(可选)",
|
||||
@@ -320,6 +321,7 @@ handlers.edit = async (chatId, slug) => {
|
||||
s.originalSlug = post.frontMatter.slug;
|
||||
s.content = "";
|
||||
s.chunks = [];
|
||||
s.dirPath = post.dirPath;
|
||||
s.categories = (post.frontMatter.categories as string[]) || [];
|
||||
s.tags = (post.frontMatter.tags as string[]) || [];
|
||||
s.author = post.frontMatter.author || DEFAULT_AUTHOR;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import path from "path";
|
||||
import { CONTENT_DIR } from "@/lib/config";
|
||||
|
||||
export function makeSlug(title: string): string {
|
||||
const dateStr = new Date().toISOString().slice(0, 10);
|
||||
const slugPart = (title || "untitled")
|
||||
.replace(/[^\w一-鿿㐀-䶿]+/g, "-")
|
||||
.replace(/^-+|-+$/g, "")
|
||||
.toLowerCase() || "post";
|
||||
return dateStr + "-" + slugPart;
|
||||
const now = new Date();
|
||||
const y = now.getFullYear();
|
||||
const m = String(now.getMonth() + 1).padStart(2, "0");
|
||||
const d = String(now.getDate()).padStart(2, "0");
|
||||
const h = String(now.getHours()).padStart(2, "0");
|
||||
const mi = String(now.getMinutes()).padStart(2, "0");
|
||||
const s = String(now.getSeconds()).padStart(2, "0");
|
||||
return `${y}${m}${d}${h}${mi}${s}`;
|
||||
}
|
||||
|
||||
export function sessionSummary(s: {
|
||||
@@ -26,11 +25,6 @@ export function sessionSummary(s: {
|
||||
return parts.filter(Boolean).join(" · ");
|
||||
}
|
||||
|
||||
export function getArticleDirPath(slug: string): string {
|
||||
const year = slug.slice(0, 4);
|
||||
return path.join(CONTENT_DIR, year, slug);
|
||||
}
|
||||
|
||||
export function truncateText(text: string, maxLen: number): string {
|
||||
if (text.length <= maxLen) return text;
|
||||
return text.slice(0, maxLen) + "\n\n... 前 " + maxLen + " 字";
|
||||
|
||||
@@ -171,11 +171,14 @@ async function handlePhoto(chatId: number, photos: { file_id: string }[], captio
|
||||
try {
|
||||
const fs = await import("fs");
|
||||
const path = await import("path");
|
||||
const { CONTENT_DIR } = await import("@/lib/config");
|
||||
const { getSession } = await import("./sessions");
|
||||
const { getArticleDirPath } = await import("./helpers");
|
||||
|
||||
const s = getSession(chatId);
|
||||
if (!s.dirPath) {
|
||||
await sendMessage(chatId, "❌ 请先发 /new 或 /edit 开始写作");
|
||||
return;
|
||||
}
|
||||
|
||||
const largestPhoto = photos[photos.length - 1];
|
||||
const fileRes = await tg<{ file_path?: string }>("getFile", { file_id: largestPhoto.file_id });
|
||||
if (!fileRes.ok || !fileRes.result?.file_path) return;
|
||||
@@ -185,7 +188,7 @@ async function handlePhoto(chatId: number, photos: { file_id: string }[], captio
|
||||
const imgBuffer = await fetch(fileUrl).then((r) => r.arrayBuffer());
|
||||
|
||||
// Save to article's own folder (Hugo page bundle)
|
||||
const articleDir = getArticleDirPath(s.slug);
|
||||
const articleDir = s.dirPath;
|
||||
if (!fs.existsSync(articleDir)) fs.mkdirSync(articleDir, { recursive: true });
|
||||
|
||||
const ext = filePath.split(".").pop() || "jpg";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createPost, updatePost, getPost } from "@/lib/posts";
|
||||
import { DEFAULT_AUTHOR } from "@/lib/config";
|
||||
import { DEFAULT_AUTHOR, CONTENT_DIR } from "@/lib/config";
|
||||
import path from "path";
|
||||
|
||||
export interface Session {
|
||||
title: string;
|
||||
@@ -11,6 +12,18 @@ export interface Session {
|
||||
draft: boolean;
|
||||
chunks: string[];
|
||||
originalSlug?: string;
|
||||
dirPath: string;
|
||||
}
|
||||
|
||||
function computeDirPath(title: string, date?: string): string {
|
||||
const d = date ? new Date(date) : new Date();
|
||||
const year = d.getFullYear().toString();
|
||||
const dateStr = d.toISOString().slice(0, 10);
|
||||
const titlePart = (title || "untitled")
|
||||
.replace(/[^\w一-鿿㐀-䶿]+/g, "-")
|
||||
.replace(/^-+|-+$/g, "")
|
||||
.toLowerCase() || "post";
|
||||
return path.join(CONTENT_DIR, year, `${dateStr}-${titlePart}`);
|
||||
}
|
||||
|
||||
const sessions = new Map<number, Session>();
|
||||
@@ -26,6 +39,7 @@ export function getSession(chatId: number): Session {
|
||||
author: DEFAULT_AUTHOR,
|
||||
draft: true,
|
||||
chunks: [],
|
||||
dirPath: "",
|
||||
});
|
||||
}
|
||||
return sessions.get(chatId)!;
|
||||
@@ -56,11 +70,19 @@ export function undoLastChunk(chatId: number): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
export function initSessionDir(chatId: number, title: string, date?: string): void {
|
||||
const s = getSession(chatId);
|
||||
if (!s.dirPath) {
|
||||
s.dirPath = computeDirPath(title, date);
|
||||
}
|
||||
}
|
||||
|
||||
export async function saveSession(s: Session, isDraft: boolean): Promise<void> {
|
||||
const dateStr = new Date().toISOString().slice(0, 10);
|
||||
const frontMatter = {
|
||||
title: s.title,
|
||||
slug: s.slug,
|
||||
date: new Date().toISOString().slice(0, 10),
|
||||
date: dateStr,
|
||||
draft: isDraft,
|
||||
categories: s.categories,
|
||||
tags: s.tags,
|
||||
@@ -71,7 +93,9 @@ export async function saveSession(s: Session, isDraft: boolean): Promise<void> {
|
||||
if (existing) {
|
||||
const result = updatePost(s.slug, frontMatter, s.content);
|
||||
if (!result.success) throw new Error("更新文章失败");
|
||||
s.dirPath = result.dirPath;
|
||||
} else {
|
||||
createPost(frontMatter, s.content);
|
||||
const dirPath = createPost(frontMatter, s.content);
|
||||
s.dirPath = dirPath;
|
||||
}
|
||||
}
|
||||
@@ -155,7 +155,7 @@ export function createPost(frontMatter: PostFrontMatter, content: string): strin
|
||||
const date = new Date(frontMatter.date || new Date());
|
||||
const year = date.getFullYear().toString();
|
||||
const dateStr = date.toISOString().slice(0, 10);
|
||||
// Folder name: date + sanitized title (Chinese-friendly)
|
||||
// Folder name: date + sanitized title (human-readable on disk)
|
||||
const titlePart = (frontMatter.title || "untitled")
|
||||
.replace(/[^\w一-鿿㐀-䶿]+/g, "-")
|
||||
.replace(/^-+|-+$/g, "")
|
||||
@@ -202,7 +202,11 @@ export function updatePost(
|
||||
const newDate = new Date(merged.date || post.frontMatter.date);
|
||||
const newYear = newDate.getFullYear().toString();
|
||||
const newDateStr = newDate.toISOString().slice(0, 10);
|
||||
const newDirName = `${newDateStr}-${frontMatter.slug}`;
|
||||
const titlePart = (merged.title || "untitled")
|
||||
.replace(/[^\w一-鿿㐀-䶿]+/g, "-")
|
||||
.replace(/^-+|-+$/g, "")
|
||||
.toLowerCase() || "post";
|
||||
const newDirName = `${newDateStr}-${titlePart}`;
|
||||
const newDirPath = path.join(CONTENT_DIR, newYear, newDirName);
|
||||
|
||||
if (fs.existsSync(newDirPath) && newDirPath !== post.dirPath) {
|
||||
|
||||
Vendored
+2
-2
@@ -1,4 +1,4 @@
|
||||
declare module "marked" {
|
||||
export function marked(src: string): string;
|
||||
export function parse(src: string): string;
|
||||
export function parse(src: string, options?: Record<string, unknown>): string;
|
||||
export const marked: { parse: typeof parse };
|
||||
}
|
||||
Reference in new issue
Block a user