Skip to content

Commit 37078a6

Browse files
0marSalahdmitrizagidulin
authored andcommittedDec 12, 2024
Add media download functionality to exportActorProfile
1 parent 4cf72d0 commit 37078a6

File tree

1 file changed

+68
-11
lines changed

1 file changed

+68
-11
lines changed
 

‎src/index.ts

+68-11
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,28 @@ import YAML from 'yaml'
77
import { Readable } from 'stream'
88
import { ActorProfileOptions } from './index.d'
99

10-
export function exportActorProfile({
10+
const downloadMedia = async (mediaUrl: string) => {
11+
if (!mediaUrl) {
12+
return null
13+
}
14+
15+
try {
16+
const response = await fetch(mediaUrl)
17+
if (!response.ok) {
18+
throw new Error(`Failed to fetch media: ${response.statusText}`)
19+
}
20+
21+
return {
22+
buffer: await response.arrayBuffer(),
23+
contentType: response.headers.get('Content-Type')
24+
} // Binary data
25+
} catch (error) {
26+
console.error(`Error downloading media from ${mediaUrl}:`, error)
27+
return null
28+
}
29+
}
30+
31+
export async function exportActorProfile({
1132
actorProfile,
1233
outbox,
1334
followers,
@@ -18,16 +39,14 @@ export function exportActorProfile({
1839
blockedAccounts,
1940
blockedDomains,
2041
mutedAccounts
21-
}: ActorProfileOptions): tar.Pack {
22-
const pack: Pack = tar.pack() // pack is a stream
42+
}: ActorProfileOptions & { media?: File[] }): Promise<tar.Pack> {
43+
const pack: Pack = tar.pack()
2344

2445
const manifest: any = {
25-
// Universal Backup Container spec version
2646
'ubc-version': '0.1',
2747
meta: {
2848
createdBy: {
2949
client: {
30-
// URL to the client that generated this export file
3150
url: 'https://github.com/interop-alliance/wallet-export-ts'
3251
}
3352
}
@@ -36,17 +55,19 @@ export function exportActorProfile({
3655
'manifest.yml': {
3756
url: 'https://w3id.org/fep/6fcd#manifest-file'
3857
},
39-
// Directory with ActivityPub-relevant exports
4058
activitypub: {
4159
contents: {}
60+
},
61+
media: {
62+
contents: {}
4263
}
4364
}
4465
}
4566

4667
pack.entry({ name: 'activitypub', type: 'directory' })
68+
pack.entry({ name: 'media', type: 'directory' })
4769

4870
if (actorProfile) {
49-
// Serialized ActivityPub Actor profile
5071
manifest.contents.activitypub.contents['actor.json'] = {
5172
url: 'https://www.w3.org/TR/activitypub/#actor-objects'
5273
}
@@ -57,7 +78,6 @@ export function exportActorProfile({
5778
}
5879

5980
if (outbox) {
60-
// ActivityStreams OrderedCollection representing the contents of the actor's Outbox
6181
manifest.contents.activitypub.contents['outbox.json'] = {
6282
url: 'https://www.w3.org/TR/activitystreams-core/#collections'
6383
}
@@ -68,7 +88,6 @@ export function exportActorProfile({
6888
}
6989

7090
if (followers) {
71-
// ActivityStreams OrderedCollection representing the actor's Followers
7291
manifest.contents.activitypub.contents['followers.json'] = {
7392
url: 'https://www.w3.org/TR/activitystreams-core/#collections'
7493
}
@@ -79,7 +98,6 @@ export function exportActorProfile({
7998
}
8099

81100
if (likes) {
82-
// ActivityStreams OrderedCollection representing Activities and Objects the actor liked
83101
manifest.contents.activitypub.contents['likes.json'] = {
84102
url: 'https://www.w3.org/TR/activitystreams-core/#collections'
85103
}
@@ -90,7 +108,6 @@ export function exportActorProfile({
90108
}
91109

92110
if (bookmarks) {
93-
// ActivityStreams OrderedCollection representing the actor's Bookmarks
94111
manifest.contents.activitypub.contents['bookmarks.json'] = {
95112
url: 'https://www.w3.org/TR/activitystreams-core/#collections'
96113
}
@@ -150,6 +167,46 @@ export function exportActorProfile({
150167
)
151168
}
152169

170+
if (outbox) {
171+
for (const post of outbox) {
172+
if (!post.media_attachments) continue
173+
174+
for (const media of post.media_attachments) {
175+
try {
176+
const mediaData = await downloadMedia(media.url)
177+
if (!mediaData) {
178+
console.warn(`Skipping media due to download failure: ${media.url}`)
179+
continue
180+
}
181+
182+
const extension = mediaData.contentType?.split('/')[1]
183+
184+
const mediaName = `${media.id}.${extension}`
185+
const mediaType = media.type
186+
187+
pack.entry(
188+
{
189+
name: `media/${mediaName}`,
190+
size: mediaData.buffer.byteLength
191+
},
192+
Buffer.from(mediaData.buffer)
193+
)
194+
195+
// Step 6: Add metadata to manifest
196+
manifest.contents.media.contents[mediaName] = {
197+
type: mediaType,
198+
size: mediaData.buffer.byteLength,
199+
lastModified: new Date().toISOString(),
200+
meta: media.meta || {},
201+
description: media.description || null
202+
}
203+
} catch (error) {
204+
console.error(`Failed to process media: ${media.url}`, error)
205+
}
206+
}
207+
}
208+
}
209+
153210
pack.entry({ name: 'manifest.yaml' }, YAML.stringify(manifest))
154211
pack.finalize()
155212

0 commit comments

Comments
 (0)
Please sign in to comment.