Hexo 魔改 - 自动随机设置文章头部图片及图片主色调

效果展示

一、 文件创建

themes/anzhiyu/scripts/ 文件夹中创建 getTopImageColor.js 文件,切入一下代码

  1. RANDOM_IMG 为自建的随机图片 api,不确定其他网站能不能使用,需要谨慎使用
  2. 代码以 “—-” 作为分隔符,请确保文章中没有多余的 “—-”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 自动设置文章的 cover 和 main_color 两个字段
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const yaml = require('js-yaml');
const https = require('https'); // Make sure to import this module
const { type } = require('os');

const POSTS_DIR = process.cwd() + '/source/_posts';
const RANDOM_IMG = 'https://random-img.pupper.cn/api';

// Define httpsAgent right after your imports and before the function calls
const httpsAgent = new https.Agent({
rejectUnauthorized: false
});

async function getCoverImage() {
try {
const response = await axios.get(RANDOM_IMG, {
maxRedirects: 0,
validateStatus: status => status === 302,
httpsAgent // Use the agent here
});
return response.headers.location;
} catch (error) {
console.error('Error fetching cover image:', error);
}
}

async function getMainColor(url) {
try {
const response = await axios.get(`${url}?imageAve`);
const mainColorData = response.data.RGB; // Access the RGB field
const mainColor = `#${mainColorData.slice(2)}`;
return mainColor;
} catch (error) {
console.error('Error fetching main color:', error);
}
}

function processFiles(dir) {
const files = fs.readdirSync(dir);

for (const file of files) {
const fullPath = path.join(dir, file);

if (fs.statSync(fullPath).isDirectory()) {
processFiles(fullPath);
} else if (path.extname(fullPath) === '.md') {
addCoverAndMainColor(fullPath);
}
}
}

function formatISO8601ToCustomFormat(isoDateString) {
// 检查输入是否已经是目标格式("yyyy-MM-dd HH:mm:ss")
if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(isoDateString)) {
return -1; // 如果已经是目标格式,则直接返回
}
const date = new Date(isoDateString);

const year = date.getUTCFullYear();
const month = (date.getUTCMonth() + 1).toString().padStart(2, '0');
const day = date.getUTCDate().toString().padStart(2, '0');
const hours = date.getUTCHours().toString().padStart(2, '0');
const minutes = date.getUTCMinutes().toString().padStart(2, '0');
const seconds = date.getUTCSeconds().toString().padStart(2, '0');

return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}


async function addCoverAndMainColor(filePath) {
const content = fs.readFileSync(filePath, 'utf8');
const yamlSection = content.match(/---\n([\s\S]*?)---/);

if (!yamlSection) return;

const data = yaml.load(yamlSection[1]);

let updated = false;

if (data.date) {
const _date = formatISO8601ToCustomFormat(data.date);
if (_date === -1) {
updated = false;
} else {
data.date = _date
updated = true;
}
}

if (data.update) {
const _update = formatISO8601ToCustomFormat(data.update);
if (_update === -1) {
updated = false;
} else {
data.update = _update
updated = true;
}
}

if (!data.cover) {
data.cover = await getCoverImage();
updated = true;
}

if (!data.main_color) {
data.main_color = await getMainColor(data.cover);
updated = true;
}

if (updated) {
const updatedYaml = yaml.dump(data);
const updatedContent = content.replace(yamlSection[1], updatedYaml);
fs.writeFileSync(filePath, updatedContent, 'utf8');
console.log(`Updated: ${filePath}`);
}
}

processFiles(POSTS_DIR);

hexo.on('before_generate', async () => {
console.log('Automatically updating cover and main color...');
await processFiles(POSTS_DIR);
console.log('Cover and main color updated successfully!');
});

二、 执行

在执行 hexo g 构建静态网站时会自动执行,如果需要调试,请注释一下代码

1
2
3
4
5
6
在文件底部添加这段代码
hexo.on('before_generate', async () => {
console.log('Automatically updating cover and main color...');
await processFiles(POSTS_DIR);
console.log('Cover and main color updated successfully!');
});

三、 下班,开溜~~~