fix(migration): fix errors after dry run

- avoid content-type is not a string, by checking if there is a mimeType
  or giving it a default 'image/jpeg'
- check if the file exists before trying to upload it (maybe this is
  only an issue locally, but about half the files didn't exist in the
file system.
This commit is contained in:
mattwr18 2020-03-26 14:03:21 +01:00
parent 8a90bf1642
commit bde6bfc5fa
2 changed files with 25 additions and 26 deletions

View File

@ -1,5 +1,5 @@
import { getDriver } from '../../db/neo4j'
import { createReadStream } from 'fs'
import { existsSync, createReadStream } from 'fs'
import path from 'path'
import { S3 } from 'aws-sdk'
import mime from 'mime-types'
@ -32,39 +32,38 @@ export async function up(next) {
try {
// Implement your migration here.
const { records } = await transaction.run('MATCH (image:Image) RETURN image.url as url')
let urls = records.map(r => r.get('url'))
urls = urls.filter(url => url.startsWith('/uploads'))
let urls = records.map((r) => r.get('url'))
urls = urls.filter((url) => url.startsWith('/uploads'))
const locations = await Promise.all(
urls
.map(url => {
.map((url) => {
return async () => {
const { pathname } = new URL(url, 'http://example.org')
const fileLocation = path.join(__dirname, `../../../public/${pathname}`)
const s3Location = `original${pathname}`
const mimeType = mime.lookup(fileLocation)
if (existsSync(fileLocation)) {
const mimeType = mime.lookup(fileLocation)
const params = {
Bucket,
Key: s3Location,
ACL: 'public-read',
ContentType: mimeType || 'image/jpeg',
Body: createReadStream(fileLocation),
}
const params = {
Bucket,
Key: s3Location,
ACL: 'public-read',
ContentType: mimeType,
Body: createReadStream(fileLocation),
const data = await s3.upload(params).promise()
const { Location: spacesUrl } = data
const updatedRecord = await transaction.run(
'MATCH (image:Image {url: $url}) SET image.url = $spacesUrl RETURN image.url as url',
{ url, spacesUrl },
)
const [updatedUrl] = updatedRecord.records.map((record) => record.get('url'))
return updatedUrl
}
const data = await s3.upload(params).promise()
const { Location: spacesUrl } = data
const updatedRecord = await transaction.run(
'MATCH (image:Image {url: $url}) SET image.url = $spacesUrl RETURN image.url as url',
{ url, spacesUrl },
)
const [updatedUrl] = updatedRecord.records.map(record => record.get('url'))
// eslint-disable-next-line no-console
// https://image-upload.fra1.digitaloceanspaces.com/original/uploads/05b6cb85-deec-45f2-8e34-44111dceb743-avatar.png
return updatedUrl
}
})
.map(p => p()),
.map((p) => p()),
)
// eslint-disable-next-line no-console
console.log('this is locations', locations)

View File

@ -136,12 +136,12 @@ const s3Upload = async ({ createReadStream, uniqueFilename, mimetype }) => {
return Location
}
const localFileDelete = async url => {
const localFileDelete = async (url) => {
const location = `public${url}`
if (existsSync(location)) unlinkSync(location)
}
const s3Delete = async url => {
const s3Delete = async (url) => {
const s3 = new S3({ region, endpoint })
let { pathname } = new URL(url, 'http://example.org') // dummy domain to avoid invalid URL error
pathname = pathname.substring(1) // remove first character '/'