99 línies de codi per resoldre les fallades d'Onetab i fer còpia de seguretat de les dades originals
Traduït per IA des de 中文 · Veure l'original
Aquest article s'ha recuperat d'instantànies de l'Internet Archive; algunes imatges es poden haver perdut.
Prefaci
A la universitat, vaig conèixer Onetab gairebé al mateix temps que Chrome; però, com a estudiant, navegar no representava cap càrrega i la feia servir molt poc.
Després de començar a treballar, obrir 100 pestanyes al navegador es va convertir en la norma, i els superiors/companys preguntaven per documentació amb molta freqüència; en aquest moment, Onetab, com a llibreta de notes web, combinat amb Ctrl+f per cercar paraules clau, és senzill i fàcil d'utilitzar.
Per què no utilitzar els marcadors?
El resultat final de l'ús dels marcadors per part de l'autor va ser que, en desplegar la barra de marcadors, aquesta cobreix tota la pantalla.
Per què no utilitzar l'historial?
L'historial també conté altra informació irrellevant, i l'historial de Chrome no és fiable.
Per què no utilitzar altres eines de gestió del coneixement?
- Les aplicacions de notes són massa pesades
- Les aplicacions semblants a Onetab, a causa del costum d'ús arrelat, no han permès trobar un substitut prou lleuger i més eficient
- Onetab ha actualitzat el mode fosc, i la memòria cau de la pestanya endavant/endarrere/actual és realment pràctica
Situació
Fa cinc dies, després que una actualització de Windows reiniciés l'ordinador, vaig tornar a obrir Edge i Onetab va quedar-se en estat de càrrega; aproximadament al cap d'una estona la pàgina va fallar i va mostrar l'error Out of Memory.
- L'autor utilitza Onetab de manera continuada des de principis del 2020, quan va arribar el nou Edge, i té registrades seixanta mil pàgines web; no ha reinstal·lat mai el sistema.
/upload/2022/07/QQ%E6%88%AA%E5%9B%BE20220727131653.pngTres mesures
- Tancar totes les pàgines web i extensions, reiniciar Edge i tornar a obrir Onetab.
Va fallar i va mostrar l'error Out of Memory. - Reiniciar l'ordinador i, amb el segon pla buit, tornar a iniciar Edge i tornar a obrir Onetab.
Va fallar i va mostrar l'error Out of Memory. - Copiar completament la carpeta «C:\User» (el directori de dades d'usuari de Windows) i restaurar-ho en un PC amb Windows 10 recent instal·lat.
Va fallar i va mostrar l'error Out of Memory.
En aquest punt es pot concloure bàsicament que la fallada de l'extensió és deguda a una quantitat de dades massa gran.
- De fet, quan hi havia cinquanta mil registres, ja s'obria molt lentament i calien més de 30 s.
- Només que no m'esperava que Chrome, el devorador de memòria, també limités l'ús de memòria de les seves extensions.

Objectiu
En aquest moment ja s'ha trobat el problema; per sort, les dades no s'han perdut, tot i que se'n desconeix la integritat.
Les dades acumulades durant més de dos anys també tenen una freqüència d'ús diària molt alta, i cal restaurar-les.
- Recuperar tant com sigui possible les dades d'Onetab i exportar-les a un format de dades que puguin reconèixer tant les màquines com les persones
- Sobre la base del punt 1, implementar una eina automatitzada de còpia de seguretat completa d'Onetab
L'exportació integrada d'Onetab és un fitxer txt pur, encara cal copiar-lo manualment i hi manca el camp de la data de creació del grup de pestanyes - Implementar una aplicació compatible amb Onetab, millorar la funció de cerca de dades i que sigui compatible amb el format de dades exportat al punt 1 i amb el format de dades original d'Onetab
Accions
Ara que ja tenim la causa i l'objectiu, posar-ho en pràctica ja no serà com anar a les palpentes.
1. Cercar l'experiència d'altres a Google
Cercar «onetab data location»
Aviat vaig trobar Onetab, o més aviat la ubicació on es desen les dades de les extensions dels navegadors basats en Chromium
/upload/2022/07/QQ%E5%9B%BE%E7%89%8720220727175536.pngDesprés cercar «onetab data export», vaig trobar també una solució de codi obert d'algú que ja ho havia fet, basada en Go.
Originalment pensava que acabaria aquí i seguiria el camí de copiar i enganxar, però hi havia un registre en una incidència que deia que ja no funcionava; l'autor tampoc tenia experiència de depuració amb Go, va mirar el codi, que no arribava a 100 línies, i va decidir implementar-ho ell mateix.
2. Coneixem una mica leveldb
- Base de dades NoSQL de codi obert creada per Google
- Monofil, d'alt rendiment i només amb instàncies locals
- Durant l'execució utilitza intensament la memòria per accelerar-se
Una instància estàndard de base de dades leveldb té la forma d'una carpeta
/upload/2022/07/QQ%E5%9B%BE%E7%89%8720220727190212.png- LOCK: bloqueig de la base de dades
- MANIFEST: fitxer de capçalera
- *.ldb: fitxer principal de dades
A partir de la presentació de la solució de codi obert es pot saber que Onetab utilitza leveldb per desar les dades dels usuaris.
L'autor també havia desenvolupat extensions de Chrome, i recorda que només es podien fer servir les dues API localStorge i indexDB per a la localització, perquè les extensions que s'executen al navegador no tenen capacitat de lectura i escriptura de fitxers ni de connexions TCP.
Entre aquestes, localStorge té un màxim de 5M, i cinquanta mil registres JSON força llargs no hi caben de cap manera; Onetab hauria d'utilitzar indexDB per desar les dades, oi? Què hi fa, doncs, aquest leveldb, i a més el contribuent també és Google.
Després d'una cerca vaig saber que leveldb és la implementació subjacent d'indexDB, i que indexDB en realitat és l'API superior (una sèrie de noms que porten a engany).
Algunes dades que el navegador Chrome desa en Local Storage en format SQLite (fitxers .localstorage) es troben en carpetes.
Algunes altres dades desades a la carpeta IndexedDB (per a cada perfil) utilitzen el format LevelDB. És un format de magatzem clau-valor de codi obert desenvolupat per Google i allotjat a GitHub.
Modificar fitxers en format LevelDB fora de Chrome no és un procés senzill, perquè cal implementar un comparador compatible per verificar la instància Indexed DB leveldb de Chrome.
3. Eines GUI per a leveldb
Després d'entendre'n el context, amb l'objectiu de confirmar (fer un cop d'ull) la situació de les dades, l'autor va buscar primer eines GUI per a leveldb.
És clar que Navicat i DataGrip, els més habituals, no ho admeten; vaig continuar navegant per GitHub.
Una implementació GUI amb Electron que no va compilar
Una altra implementació GUI amb Electron que no va poder llegir les dades
Una implementació GUI amb C++/Qt que va poder llegir les dades correctament
/upload/2022/07/QQ%E6%88%AA%E5%9B%BE20220727183055.pngI es poden veure clarament els noms de les claus que utilitza Onetab.
- Nota: aquest programari és de codi obert sota la GPL v3, però la versió binària és de pagament; els usuaris nous poden provar-lo. Quan l'autor va escriure aquest article, el lloc web oficial va caure i no es podia registrar; es pot descarregar una versió antiga i executar-la sense necessitat de registrar-se ni iniciar sessió.
4. Implementació del codi basada en Node.js 16.15
Tot i que les dues implementacions GUI amb Electron anteriors no van tenir èxit, també vaig descobrir el paquet level del qual depenien, que ofereix una API molt pràctica i es pot utilitzar directament.
- Aquí l'autor va pensar primer a fer-ho amb Python, però la dependència level de Python s'ha de compilar i instal·lar en Linux, així que ho va deixar estar.
$ npm install level
$ npm install mongodb
const {promises: {writeFile, mkdir}} = requir('fs');
const {Level} = requir('level')
const MongoClient = requir('mongodb').MongoClient
// halo有点bug, 出现require会崩溃
const USER_HOME = (process.env.HOME || process.env.USERPROFILE).replaceAll("\\", "/")
const chrome = {
name: "Google/Chrome",
uuid: "chphlpgkkbolifaimnlloiipkdnihall"
}
const edge = {
name: "Microsoft/Edge", // Edge || Edge Beta || Edge Dev || Edge Canary
uuid: "hoimpamkkoehapgenciaoajfkfkpgfop"
}
// const firefox = "" // 火狐的扩展和目录结构与以上两位好兄弟不太一样, 无使用经验, 请自行修改
const winPath = `${USER_HOME}/AppData/Local/${edge.name}/User Data/Default/Local Extension Settings/${edge.uuid}`
// 以下两条为 Copilot 智能添加的代码, 请自行核对路径是否正确
// const macPath = `${USER_HOME}/Library/Application Support/${edge.name}/User Data/Default/Local Extension Settings/${edge.uuid}`
// const linuxPath = `${USER_HOME}/AppData/Local/${edge.name}/User Data/Default/Local Extension Settings/${edge.uuid}`
const ldb = new Level(winPath)
const url = "mongodb://alpha:123456aB@localhost:27017/?authSource=admin"
// 异步读取onetab的leveldb中的数据
const getOnetabData = async () => {
await ldb.open()
const str = await ldb.get('state')
return JSON.parse(JSON.parse(str))
}
// 异步处理数据, 获得一个每条记录的数组
const getItems = async (onetabs) => {
const items = []
onetabs.forEach((ele, index) => {
console.log(ele.id)
ele.tabsMeta.map(ele => items.push(ele))
})
return items
}
// 异步连接mongo
const getMongoDB = async () => {
const db = await MongoClient.connect(url)
return await db
}
// 异步写入tab组
const insertGroups = async (db, onetabs) => {
const dbo = await db.db("onetab")
await dbo.collection("onetab_groups").insertMany(onetabs)
}
// 异步写入每条onetab记录
const insertItems = async (db, items) => {
const dbo = db.db("onetab")
await dbo.collection("onetab_items").insertMany(items)
}
// 生成用于备份的json数据文件和方便查看的CSV文件
const genExtFiles = async (items, onetabs) => {
/*
* 生成表头,\ufeff 是防止乱码
* csv中以 `,` 换列,`\n`换行
*/
let title = Object.keys(items[1])
let csvContent = '\ufeff' + title.join(',') + '\n'
// 添加表体
items.forEach((item, index) => {
let c = Object.values(item).join(',') + '\n'
csvContent += c
})
// 生成文件夹
await mkdir('onetab')
// 生成csv文件
await writeFile('./onetab/tab_items.csv', csvContent)
// 生成JSON
await writeFile('./onetab/tab_ori.json', JSON.stringify(onetabs))
console.log('数据文件生成完毕, 请打开当前目录下的onetab文件夹查看.')
}
// 主函数
const main = async () => {
const json = await getOnetabData()
const db = await getMongoDB()
const items = await getItems(json.tabGroups)
await insertItems(db, items)
await insertGroups(db, json.tabGroups)
await genExtFiles(items, json)
await db.close()
console.log("写入MongoDB完成, 程序执行完毕. ")
}
main()
Resultat
Finalment, l'autor va empaquetar una aplicació d'escriptori binària basada en Tauri, que fa poc és molt popular.
Encara no coneixes Tauri?
Mira aquí Deixa de banda Electron i abraça Tauri, desenvolupat amb Rust
Les funcionalitats que implementa
- Veure totes les dades exportades amb l'estil original d'Onetab
- Ha afegit paginació per fer front a grans quantitats de dades
- Ha afegit filtres per data i paraula clau
S'afegirà properament
- Còpia de seguretat automatitzada implementada en Rust, sense necessitat d'instal·lar Node addicionalment
- Sincronització al núvol WebDAV o altres
- Anàlisi de dades, núvol de paraules, NLP