Skip to content

Commit

Permalink
chore: adds batched image upload
Browse files Browse the repository at this point in the history
  • Loading branch information
JohanHjelsethStorstad committed Oct 10, 2024
1 parent ddc6c9f commit 2a755b4
Showing 1 changed file with 59 additions and 28 deletions.
87 changes: 59 additions & 28 deletions src/prisma/prismaservice/src/dobbelOmega/migrateImages.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { vevenIdToPnId, type IdMapper } from './IdMapper'
import manifest from '@/src/logger'
import { imageSizes, imageStoreLocation } from '@/src/seedImages'
import { v4 as uuid } from 'uuid'
import { writeFile, mkdir } from 'fs/promises'
Expand Down Expand Up @@ -70,22 +71,30 @@ export default async function migrateImages(
}
})

// Find what the profile collection is on veven
const vevenProfileCollection = await vevenPrisma.imageGroups.findFirstOrThrow({
where: {
name: 'Profilbilder',
},
})

manifest.info(`Before filter: ${images.length} images`)
const imagesWithCollection = images.map(image => {
let collectionId = vevenIdToPnId(migrateImageCollectionIdMap, image.ImageGroupId)
if (image.Ombul.length) {
collectionId = ombulCollection.id
} else if (image.UserId) {
collectionId = profileCollection.id
} else if (!collectionId) {
collectionId = garbageCollection.id
} else if (image.ImageGroupId === vevenProfileCollection.id) {
collectionId = profileCollection.id
}
return {
...image,
collectionId,
}
}).filter(image => {
//Apply limits
if (!limits.numberOffFullImageCollections) return true
if (limits.numberOffFullImageCollections === null) return true
if (image.Ombul.length) return true
if (image.Articles.length) return true
if (image.Events.length) return true
Expand All @@ -94,32 +103,9 @@ export default async function migrateImages(
if (image.ImageGroupId && image.ImageGroupId < limits.numberOffFullImageCollections) return true
return false
})
manifest.info(`After filter: ${imagesWithCollection.length} images`)

const imagesWithCollectionAndFs = await Promise.all(imagesWithCollection.map(async (image) => {
const ext = image.originalName.split('.').pop() || ''
const fsLocationDefaultOldVev = `${process.env.VEVEN_STORE_URL}/image/default/${image.name}`
+ `?url=/store/images/${image.name}.${ext}`
const fsLocationMediumOldVev = `${process.env.VEVEN_STORE_URL}/image/resize/${imageSizes.medium}/`
+ `${imageSizes.medium}/${image.name}?url=/store/images/${image.name}.${ext}`
const fsLocationSmallOldVev = `${process.env.VEVEN_STORE_URL}/image/resize/${imageSizes.small}/`
+ `${imageSizes.small}/${image.name}?url=/store/images/${image.name}.${ext}`
const [fsLocationSmallSize, fsLocationMediumSize, fsLocation] = await Promise.all([
fetchImageAndUploadToStore(fsLocationSmallOldVev),
fetchImageAndUploadToStore(fsLocationMediumOldVev),
fetchImageAndUploadToStore(fsLocationDefaultOldVev)
])
if (!fsLocation || !fsLocationMediumSize || !fsLocationSmallSize) {
console.error(`Failed to fetch image from ${fsLocationDefaultOldVev}`)
return null
}

return {
...image,
fsLocationSmallSize,
fsLocationMediumSize,
fsLocation
}
}))
const imagesWithCollectionAndFs = await fetchAllImagesAndUploadToStore(imagesWithCollection)

//correct names if there are duplicates
const namesTaken: { name: string, times: number }[] = []
Expand Down Expand Up @@ -173,6 +159,51 @@ export default async function migrateImages(
return migrateImageIdMap
}

async function fetchAllImagesAndUploadToStore<X extends {
originalName: string,
name: string,
id: number
}>(images: X[]): Promise<((X & { fsLocation: string, fsLocationSmallSize: string, fsLocationMediumSize: string }) | null)[]> {
const ret: ((X & { fsLocation: string, fsLocationSmallSize: string, fsLocationMediumSize: string }) | null)[] = []
let imageCounter = 1
const batchSize = 1200
const imageBatches = images.reduce((acc, image) => {
if (acc[acc.length - 1].length >= batchSize) {
acc.push([image])
} else {
acc[acc.length - 1].push(image)
}
return acc
}, [[]] as X[][])
for (const imageBatch of imageBatches) {
await Promise.all(imageBatch.map(async image => {
manifest.info(`Migrating image number ${imageCounter++} of ${images.length}`)
const ext = image.originalName.split('.').pop() || ''
const fsLocationDefaultOldVev = `${process.env.VEVEN_STORE_URL}/image/default/${image.name}`
+ `?url=/store/images/${image.name}.${ext}`
const fsLocationMediumOldVev = `${process.env.VEVEN_STORE_URL}/image/resize/${imageSizes.medium}/`
+ `${imageSizes.medium}/${image.name}?url=/store/images/${image.name}.${ext}`
const fsLocationSmallOldVev = `${process.env.VEVEN_STORE_URL}/image/resize/${imageSizes.small}/`
+ `${imageSizes.small}/${image.name}?url=/store/images/${image.name}.${ext}`
const fsLocation = await fetchImageAndUploadToStore(fsLocationDefaultOldVev)
const fsLocationMediumSize = await fetchImageAndUploadToStore(fsLocationMediumOldVev)
const fsLocationSmallSize = await fetchImageAndUploadToStore(fsLocationSmallOldVev)
if (!fsLocation || !fsLocationMediumSize || !fsLocationSmallSize) {
console.error(`Failed to fetch image from ${fsLocationDefaultOldVev}`)
ret.push(null)
} else {
ret.push({
...image,
fsLocationSmallSize,
fsLocationMediumSize,
fsLocation
})
}
}))
}
return ret
}

/**
* fetches an image from the Veven store and uploads it to the PN store (does NOT store the image
* in the database, only the file on the server). Note that veven will often fail when we make a
Expand Down

0 comments on commit 2a755b4

Please sign in to comment.