折腾

起因

最近搞了博客,然后从hexo里选了个带相册的主题。我lsp了,所以应该会存很多图吧。

考虑到加载速度的原因,因为图片太多,就只能搞个图床,这里选择的是腾讯云的对象存储,然后配上cdn分发网络,速度还算不错。

以后可以快乐的当一个lsp了(并不是

痛苦的开端

由于hexo是静态页面对吧,所以相册的路径都要写死在一个JSON文件里,所以每次更新相册我经历了如下步骤:

  1. 传文件到图床,而且要把名字修改得规规整整,不然手写json的时候写出大问题
  2. 然后开始抄写文件,如果有新相册还要建立对应的页面markdown…

光是听我说估计都有点抓狂,从此欣赏漂亮小姐姐变成了一件痛苦的事。。

解决方案

正好最近痴迷于 解放生产力这个词语,虽然我是个菜b,但也想过的轻松点。永远不尝试造轮子的下场只有一个,我学过很多工具,但仍过不好程序员的一生。

我的思路首先是通过一个api拿到文件路径和文件名之类的信息,打开腾讯云对象存储文档,果不其然,这类的api人家早已备好,多种语言,任君选择。

到目前为止我还是很满意的,我比较熟悉node(并不),就选择node SDK吧。

查看文档,可以看到如下几个api

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cos.getService({
Region: 'COS_REGION',
}, function(err, data) {
console.log(err || data);
});
//通过这个可以拿到存储桶的列表

cos.getBucket({
Bucket: 'examplebucket-1250000000', /* 必须 */
Region: 'COS_REGION', /* 必须 */
Prefix: 'a/', /* 非必须 */
}, function(err, data) {
console.log(err || data.Contents);
});
//通过这个可以拿到想要的文件列表

就我目前的需求来说,这两个api已经足够了,内心狂喜。
解放生产力只有一步之遥了(并不。

但我拿到api返回的数据时,我人都傻了,居然没有层级,只有相对于存储桶url地址路径的字符串,他们是同级的

看到这里我忍不住鼓掌,不愧是你,腾讯。行吧, 只有自己写一个映射层级的函数了呗。由于我的相册文件夹只有一层,因此也没做什么递归,深度遍历的处理。下面上代码。

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
const request = require("request");
const COS = require("cos-nodejs-sdk-v5");
const path = require("path");
const fs = require("fs");
//相册基本结构,用ts写应该更香,奈何我ts模块这一块,拿捏得不到位,草率了
const baseObj = {
name: "",
baseUrl: "example.com/galleries",
cover: "",
description: "",
photos: [],
};

const jsonPath = "xxx/galleries.json";
const Bucket = {};
const galleries = JSON.parse(fs.readFileSync(jsonPath));
//获取Bucket信息
function getBucketInfo() {
return new Promise((res, rej) => {
cos.getService((err, data) => {
err ? rej(err) : res(data.Buckets[0]);
});
});
}
//获取文件列表
async function getFileList() {
try {
let contents = await new Promise((res, rej) => {
cos.getBucket(
{
Bucket: Bucket.Name,
Region: Bucket.Location,
Prefix: "galleries/",
},
(err, data) => {
// console.log(err||data.Contents)
err ? rej(err) : res(data.Contents);
}
);
});
return contents;
} catch (e) {
console.log(e);
}
}
//初始化
async function init() {
try {
Object.assign(Bucket, await getBucketInfo());
refreshGalleries();
} catch (e) {
console.log(e);
}
}
//查询相册是否已经存在
function isEXists(name) {
for (let [index, item] of galleries.entries()) {
console.log(item.name)
console.log(index)
return item.name === name ? index : false;
}
return false
}
//建立对应相册MarkDown
function buildGallery(name) {
let model = fs.readFileSync("./burket/index.md", { encoding: "utf-8" });
model = model.replace("name", name);
fs.mkdirSync(`./source/galleries/${name}`,{recursive:true})
fs.writeFileSync(`./source/galleries/${name}/index.md`, model,{
flag:'w+'
});
}
//更新相册
async function refreshGalleries() {
let contents = await getFileList();
let folders = new Map();
//建立文件夹对应关系
contents.forEach((item) => {
let arr = item.Key.split("/");
if (arr.length === 3 && arr[2]) {
let photos = folders.get(arr[1]);
photos ? photos.unshift(arr[2]) : folders.set(arr[1], []);
}
});
//重写galleries.json
for (let [name, photos] of folders.entries()) {、
//判定是否已经存在此相册
let index = isEXists(name)

if (index !== false) {
galleries[index].photos = photos;
//break; 这里应该是continue,
continue
}
//没有则建立新相册
let gallery = Object.assign({},baseObj, {
name,
baseUrl: `${baseObj.baseUrl}/${name}/`,
photos,
cover: photos[0],
});
galleries.push(gallery);
//根据名字去建立markdown
buildGallery(name);
}
fs.writeFileSync(jsonPath, JSON.stringify(galleries));
}

init();

好了水文一篇,整个todo-list,糊弄下自己

  • 自动上传文件,思路大概是,把要上传的文件丢到某个文件夹,上传后自动删除。

  • 整个远程访问的页面,这样我就可以在手机上写博文,更新相册了。

顺便吐槽一下自己,有这些功夫还用hexo?sorry啊,事逼就是可以为所欲为