Skip to content

Commit

Permalink
Refactor exportActorProfile to use a more modular approach for media …
Browse files Browse the repository at this point in the history
…handling and finalize process
  • Loading branch information
0marSalah committed Dec 10, 2024
1 parent dc9b76e commit e646314
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 63 deletions.
102 changes: 40 additions & 62 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,18 @@ import * as tar from 'tar-stream'
import { type Pack } from 'tar-stream'
import YAML from 'yaml'
import { Readable } from 'stream'
import { ActorProfileOptions } from './index.d'

const downloadMedia = async (mediaUrl: string) => {
if (!mediaUrl) {
return null
}

try {
const response = await fetch(mediaUrl)
if (!response.ok) {
throw new Error(`Failed to fetch media: ${response.statusText}`)
}

return {
buffer: await response.arrayBuffer(),
contentType: response.headers.get('Content-Type')
} // Binary data
} catch (error) {
console.error(`Error downloading media from ${mediaUrl}:`, error)
return null
}
export interface ActorProfileOptions {
actorProfile?: any
outbox?: any
followers?: any
followingAccounts?: any
lists?: any
bookmarks?: any
likes?: any
blockedAccounts?: any
blockedDomains?: any
mutedAccounts?: any
}

export async function exportActorProfile({
Expand All @@ -39,7 +30,14 @@ export async function exportActorProfile({
blockedAccounts,
blockedDomains,
mutedAccounts
}: ActorProfileOptions & { media?: File[] }): Promise<tar.Pack> {
}: ActorProfileOptions & { media?: File[] }): Promise<{
addMediaFile: (
fileName: string,
buffer: ArrayBuffer,
contentType: string
) => void
finalize: () => tar.Pack
}> {
const pack: Pack = tar.pack()

const manifest: any = {
Expand Down Expand Up @@ -167,50 +165,30 @@ export async function exportActorProfile({
)
}

if (outbox) {
for (const post of outbox) {
if (!post.media_attachments) continue

for (const media of post.media_attachments) {
try {
const mediaData = await downloadMedia(media.url)
if (!mediaData) {
console.warn(`Skipping media due to download failure: ${media.url}`)
continue
}

const extension = mediaData.contentType?.split('/')[1]

const mediaName = `${media.id}.${extension}`
const mediaType = media.type

pack.entry(
{
name: `media/${mediaName}`,
size: mediaData.buffer.byteLength
},
Buffer.from(mediaData.buffer)
)

// Step 6: Add metadata to manifest
manifest.contents.media.contents[mediaName] = {
type: mediaType,
size: mediaData.buffer.byteLength,
lastModified: new Date().toISOString(),
meta: media.meta || {},
description: media.description || null
}
} catch (error) {
console.error(`Failed to process media: ${media.url}`, error)
}
return {
addMediaFile(fileName: string, buffer: ArrayBuffer, contentType: string) {
pack.entry(
{
name: `media/${fileName}`,
size: buffer.byteLength
},
Buffer.from(buffer)
)

// Add media metadata to the manifest
manifest.contents.media.contents[fileName] = {
type: contentType,
size: buffer.byteLength,
lastModified: new Date().toISOString()
}
},

finalize() {
pack.entry({ name: 'manifest.yaml' }, YAML.stringify(manifest))
pack.finalize()
return pack
}
}

pack.entry({ name: 'manifest.yaml' }, YAML.stringify(manifest))
pack.finalize()

return pack
}

export async function importActorProfile(tarBuffer: Buffer): Promise<any> {
Expand Down
18 changes: 17 additions & 1 deletion test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,25 @@ describe('exportActorProfile', () => {
it('calls function', async () => {
const filename = 'out/test-export-2024-01-01.tar'
const tarball = fs.createWriteStream(filename)
const packStream = await exportActorProfile({ actorProfile, outbox })

// Mock inputs for actor profile and outbox
const actorProfile = { id: 'test-actor', type: 'Person' }
const outbox = [{ id: 'post1', type: 'Note', content: 'Test content' }]

// Initialize export stream
const { finalize } = await exportActorProfile({ actorProfile, outbox })

// Finalize the tarball
const packStream = finalize()

// Pipe the tarball to the file
packStream.pipe(tarball)

// Ensure the tarball finishes writing
await new Promise((resolve, reject) => {
tarball.on('finish', resolve)
tarball.on('error', reject)
})
})
})

Expand Down

0 comments on commit e646314

Please sign in to comment.