🌳
pt0/ipfsF/ipfsRestoreAI.mts
1import fs from 'fs/promises'
2import path from 'path'
3import type { Knex } from 'knex'
8type IpfsBackupMeta = {
9 mfsRoot: string | null
10 kvKey: string
11 rootCid: string
14const META_FILE = '_meta.json'
16export const restoreIpfsContent = async ({label, db}: {label: string, db: Knex}) => {
17 const client = getIpfsClient()
18 const dirPath = getIpfsBackupDir({label})
19 const summary = {restored: 0, failed: 0}
21 let meta: IpfsBackupMeta | null = null
22 try {
23 const metaRaw = await fs.readFile(path.join(dirPath, META_FILE), 'utf8')
24 meta = JSON.parse(metaRaw)
25 } catch {
26 betLog('ipfsRestoreNoMeta', {label, dirPath})
27 }
29 const mfsRoot = meta?.mfsRoot
30 if (mfsRoot) {
31 await client.files.mkdir(mfsRoot, {parents: true}).catch(() => {})
32 }
34 const files = await fs.readdir(dirPath)
35 const contentFiles = files.filter(f => f !== META_FILE && !f.startsWith('.'))
37 for (const fileName of contentFiles) {
38 const lastDot = fileName.lastIndexOf('.')
39 const ext = lastDot >= 0 ? fileName.slice(lastDot + 1) : 'bin'
40 const fileCid = lastDot >= 0 ? fileName.slice(0, lastDot) : fileName
41 const filePath = path.join(dirPath, fileName)
43 try {
44 const buffer = await fs.readFile(filePath)
45 const newCid = await uploadToIpfs(buffer)
47 if (mfsRoot) {
48 const mfsPath = `${mfsRoot}/${newCid}.${ext}`
49 await client.files.cp(`/ipfs/${newCid}`, mfsPath).catch(() => {})
50 } else {
51 await pinCid(newCid)
52 }
54 summary.restored++
55 betLog('ipfsRestoreFile', {fileName, newCid})
56 } catch (err) {
57 betLog('ipfsRestoreFail', {fileName, errMsg: (err as Error).message})
58 summary.failed++
59 }
60 }
62 if (mfsRoot && meta?.kvKey) {
63 try {
64 const stat = await client.files.stat(mfsRoot)
65 const newRootCid = stat.cid.toString()
66 await pinCid(newRootCid)
68 await db('generic_kvs')
69 .insert({key: meta.kvKey, value: newRootCid})
70 .onConflict('key')
71 .merge({value: newRootCid, updated_at: db.fn.now()})
73 betLog('ipfsRestoreRoot', {mfsRoot, newRootCid})
74 } catch (err) {
75 betLog('ipfsRestoreRootFail', {mfsRoot, errMsg: (err as Error).message})
76 }
77 }
79 betLog('ipfsRestoreResult', summary)
80 return summary