plxnner
Version:
An elegant open-source planner for Instagram
152 lines (116 loc) • 3.71 kB
text/typescript
import * as fflate from "fflate"
import { getFileExtension } from "./utilsFile"
import { rebuildRawUserConfig } from "./utilsUserExportRawConfig"
async function fileToArrayBuffer(file: File) {
return new Uint8Array(await file.arrayBuffer())
}
async function prepareMediaForZip(
media: IMedia,
mediaIndex: number,
isAlbumIndex: number = -1,
) {
const mediaFiles = {}
let exportedMedia
let exportedMediaCover
let rawMediaFileName = `${media.collectionSingularized}-${mediaIndex}`
if (isAlbumIndex > -1) rawMediaFileName += `x${isAlbumIndex}`
switch (media.type) {
case "album":
let iAlbumItem = 1
// run rebuildRawMedia for each album item
for await (const albumItemMedia of media.list) {
const albumMediaFiles = await prepareMediaForZip(
albumItemMedia,
mediaIndex,
iAlbumItem,
)
for (const albumMediaFileKey of Object.keys(albumMediaFiles)) {
mediaFiles[albumMediaFileKey] = albumMediaFiles[albumMediaFileKey]
}
iAlbumItem++
}
break
case "iframe":
exportedMedia = await media.exportFiles()
if (media.cover) {
mediaFiles[
`${rawMediaFileName}-cover.${getFileExtension(
exportedMedia.cover.file.name,
)}`
] = [await fileToArrayBuffer(exportedMedia.cover.file), { level: 0 }]
}
break
case "video":
exportedMedia = await media.exportFiles()
if (media.cover) {
mediaFiles[
`${rawMediaFileName}-cover.${getFileExtension(
exportedMedia.cover.file.name,
)}`
] = [await fileToArrayBuffer(exportedMedia.cover.file), { level: 0 }]
}
mediaFiles[
`${rawMediaFileName}.${getFileExtension(exportedMedia.file.name)}`
] = [await fileToArrayBuffer(exportedMedia.file), { level: 0 }]
break
case "image":
exportedMedia = await media.exportFiles()
mediaFiles[
`${rawMediaFileName}.${getFileExtension(exportedMedia.file.name)}`
] = [await fileToArrayBuffer(exportedMedia.file), { level: 0 }]
break
}
return mediaFiles
}
/**
* Prepare user zip config to generate the zip file
*
* @param user
*/
async function prepareUserForZip(user: IUser) {
const userConfigJson = await rebuildRawUserConfig(user)
const username = user.profile.username
const userZip = {}
userZip[username] = {}
if (user.profile.avatar && user.profile.avatar.isSet) {
const avatarFile = await user.profile.avatar.export()
userZip[username][userConfigJson.profile.avatar] = [
await fileToArrayBuffer(avatarFile),
{ level: 0 },
]
}
let i: number
let mediaFiles = {}
// for each media collection
for (const collectionKey of user.media.collectionKeys) {
i = user.media.collections[collectionKey].length
const mediaCollectionItems = [...user.media.collections[collectionKey]]
// for each media in this collection
for (const media of mediaCollectionItems) {
const partialMediaFiles = await prepareMediaForZip(media, i)
mediaFiles = {
...mediaFiles,
...partialMediaFiles,
}
i--
}
}
// define config.json
userZip[username]["config.json"] = fflate.strToU8(
JSON.stringify(userConfigJson, null, 2),
)
// define files in media folder
userZip[username]["media"] = mediaFiles
return userZip
}
/**
* Prepare user zip config from exported user data
* and build the zip file
*
* @param user
*/
export async function makeUserZip(user: IUser) {
const userZipConfig = await prepareUserForZip(user)
const userZip = fflate.zipSync(userZipConfig)
return userZip
}