fixed: 现在能显示作者名称
This commit is contained in:
@@ -146,3 +146,67 @@ export function collectPins(): PinData[] {
|
||||
const collector = new PinCollector();
|
||||
return collector.collect();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从花瓣 API 响应中的单个 pin 对象提取 PinData
|
||||
* @param pin - /v3/boards/{id}/pins 返回的 pins 数组元素
|
||||
*/
|
||||
export function extractPinFromApi(pin: any): PinData {
|
||||
return {
|
||||
url: `/pins/${pin.pin_id}/`,
|
||||
imgSmallSrc: pin.file?.url ?? '',
|
||||
imgSrc: (pin.file?.url ?? '').replace(/_fw\d+webp|_png/, ''),
|
||||
imgWidth: pin.file?.width ?? 0,
|
||||
imgHeight: pin.file?.height ?? 0,
|
||||
alt: pin.raw_text ?? '',
|
||||
title: pin.raw_text ?? '',
|
||||
author: parseAuthorFromRawText(pin.raw_text) ?? '',
|
||||
time: formatTimestamp(pin.created_at) ?? '',
|
||||
tags: extractTagsFromText(pin.raw_text),
|
||||
};
|
||||
}
|
||||
|
||||
function formatTimestamp(ts: number): string {
|
||||
if (!ts) return '';
|
||||
const date = new Date(ts * 1000); // API 给的是秒,JS 需要毫秒
|
||||
const now = Date.now();
|
||||
const diff = now - date.getTime();
|
||||
const hours = Math.floor(diff / 3600000);
|
||||
if (hours < 24) return `${hours}小时`;
|
||||
const days = Math.floor(hours / 24);
|
||||
if (days < 30) return `${days}天`;
|
||||
return date.toLocaleDateString('zh-CN'); // 超过30天直接显示日期
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 raw_text 中解析作者名
|
||||
*/
|
||||
function parseAuthorFromRawText(rawText: string): string {
|
||||
if (!rawText) return '';
|
||||
const lines = rawText.split('\n').map(s => s.trim()).filter(Boolean);
|
||||
if (lines.length === 0) return '';
|
||||
const firstLine = lines[0];
|
||||
// 格式: "北道(きたみち)かえる@Aiart" → 去掉 @xxx 后缀
|
||||
const atIndex = firstLine.indexOf('@');
|
||||
if (atIndex > 0) return firstLine.slice(0, atIndex).trim();
|
||||
// 格式: "@无硫火花 的个人主页 - 微博" → 取 @ 后到空格前的用户名
|
||||
if (atIndex === 0) {
|
||||
const username = firstLine.slice(1).split(/\s/)[0];
|
||||
return username || firstLine;
|
||||
}
|
||||
// 格式: "Z3zz_的照片 - 微相册"
|
||||
return firstLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文本中提取 #标签
|
||||
*/
|
||||
export function extractTagsFromText(text: string): string[] {
|
||||
const tags: string[] = [];
|
||||
const tagRegex = /#([\w\u4e00-\u9fff]+)/g;
|
||||
let match;
|
||||
while ((match = tagRegex.exec(text)) !== null) {
|
||||
tags.push(match[1]);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { showPageMarker } from "@/components/page-marker";
|
||||
import { PinCollector } from "#imports";
|
||||
import { AutoLoader } from '@/components/autoLoader';
|
||||
import type { PinData } from '#imports';
|
||||
import { extractPinFromApi } from "@/components/pin-collector";
|
||||
|
||||
let loader: AutoLoader | null = null;
|
||||
|
||||
@@ -57,12 +58,12 @@ export default defineContentScript({
|
||||
}).catch(() => { });
|
||||
},
|
||||
onData: async (items) => {
|
||||
const newPins: PinData[] = items.map((pin: any) => extractPinData(pin));
|
||||
const newPins: PinData[] = items.map((pin: any) => extractPinFromApi(pin));
|
||||
// 读取已有数据,按 pin_id 去重合并
|
||||
const stored = await browser.storage.local.get('collectedPins') as { collectedPins?: PinData[] };
|
||||
const existing: PinData[] = stored.collectedPins || [];
|
||||
const existingIds = new Set(existing.map((p) => p.pinId));
|
||||
const merged = [...existing, ...newPins.filter((p) => !existingIds.has(p.pinId))];
|
||||
const existingUrls = new Set(existing.map((p) => p.url));
|
||||
const merged = [...existing, ...newPins.filter((p) => !existingUrls.has(p.url))];
|
||||
await browser.storage.local.set({ collectedPins: merged });
|
||||
console.log(`[content] 已写入 storage,累计 ${merged.length} 条`);
|
||||
},
|
||||
@@ -91,17 +92,4 @@ function sayHello() {
|
||||
closable: true, // 用户可点击 × 关闭
|
||||
autoRemoveSeconds: 10,
|
||||
});
|
||||
}
|
||||
|
||||
function extractPinData(pin: any): PinData {
|
||||
return {
|
||||
pinId: pin.pin_id ?? '',
|
||||
imgSmallSrc: pin.file?.url ?? '',
|
||||
imgSrc: (pin.file?.url ?? '').replace(/_fw\d+webp|_png/, ''),
|
||||
alt: pin.raw_text ?? '',
|
||||
author: pin.user?.username ?? '',
|
||||
time: pin.created_at ?? '',
|
||||
tags: pin.tags?.map((t: any) => t.tag ?? t) ?? [],
|
||||
url: `/pins/${pin.pin_id}/`,
|
||||
};
|
||||
}
|
||||
@@ -7,8 +7,13 @@ document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
|
||||
<div class="actions">
|
||||
<button id="collectBtn">📥 收集</button>
|
||||
<button id="clearBtn">🗑 清空</button>
|
||||
<button id="start-btn">start-btn</button>
|
||||
<button id="stop-btn">stop-btn</button>
|
||||
<button id="start-btn">▶ 开始加载</button>
|
||||
<button id="stop-btn">⏹ 停止</button>
|
||||
</div>
|
||||
<div class="download-options">
|
||||
<label>
|
||||
并行数: <input type="number" id="concurrency" value="5" min="1" max="20" style="width:50px" />
|
||||
</label>
|
||||
</div>
|
||||
<div id="status"></div>
|
||||
<div id="pinList"></div>
|
||||
|
||||
@@ -4,6 +4,6 @@ import { defineConfig } from 'wxt';
|
||||
export default defineConfig({
|
||||
browser: "firefox",
|
||||
manifest: {
|
||||
permissions: ['storage'],
|
||||
permissions: ['storage', 'downloads'],
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user