损坏的 Typecho 备份处理为 JSON
友站 Typecho 备份数据损坏了(从头开始 – 林林杂语),搜了下似乎并不是个例。
本来要了份存档想帮忙试下修复下,不过拖延症了几天,站长自己修复了。留份 Typecho dat 文件转 json 的代码以备后用吧
(转完再处理成对应的博客系统的备份格式就行了)
吐槽下 Typecho 的备份格式挺怪的,感觉不是一个人写出来的……
我一个 Go 开发,写一半 Go 突然顿悟切 JS 写,效率反而暴增。论处理 JSON 时 JS 的优越性
const fs = require('fs'); const path = 'typecho.dat'; function splitBuffer(b, splitWith) { const ret = []; let s = 0; let i = b.indexOf(splitWith, s); while (i >= 0) { if (i >= 0) { ret.push(b.slice(s, i)); } s = i + 1; i = b.indexOf(splitWith, s); } ret.push(b.slice(s)); return ret; } function parsePost(buf) { // 忽略头部的字符 buf = buf.slice(5); // 解析 header var jsonLeft = 0; var jsonRight = buf.indexOf('}'); if (jsonLeft == -1 || jsonRight == -1) { return undefined; } var jsonPart = buf.slice(jsonLeft, jsonRight + 1).toString(); const header = JSON.parse(jsonPart); // 处理内容 buf = buf.slice(jsonRight + 1); const readBytes = (n) => { if (!!n) { const result = buf.slice(0, n).toString(); buf = buf.slice(n); const num = parseInt(result); return isNaN(num) ? result : num; } else { return ''; } }; const post = Object.keys(header) .map((key) => ({ key, value: readBytes(header[key]) })) .reduce((pre, cur) => ({ ...pre, [cur.key]: cur.value }), {}); return post; } function main() { var buf = fs.readFileSync(path); // 删除前面的 Waring 数据 buf = buf.slice(buf.indexOf('%TYPECHO_BACKUP_FILE%')); // 文章分割 var posts = splitBuffer(buf, '\x01\x00'); console.log('post length', posts.length); posts = posts.map(parsePost); const failed = posts.filter((item) => !item).length; if (failed > 1) { console.log('read filed', failed - 1); } fs.writeFileSync( 'data.json', JSON.stringify( posts.filter((item) => !!item), undefined, 4 ) ); } main();