import { S3Client, ListObjectsV2Command, GetObjectCommand } from "@aws-sdk/client-s3"; import exifReader from "exif-reader"; import { NextResponse } from "next/server"; import { diff, sift } from "radash"; import sharp from "sharp"; import PhotoDataSource from "@/data-source"; import { Photo } from "@/entity/photo"; import { auth } from "@/lib/auth"; export type GetPhotosUpdate = { status: number, s3Photos: string[] } export const GET = auth(async function GET(req): Promise { if (!req.auth) { return NextResponse.json({ message: "Not authenticated" }, { status: 401 }) } const dataSource = await PhotoDataSource.dataSource; const photoRepository = dataSource.getRepository(Photo); const currentSources = (await photoRepository.find({ select: { src: true } })).map((photo) => photo.src); const s3Client = new S3Client(); const listObjCmd = new ListObjectsV2Command({ Bucket: "joemonk-photos" }); const s3Res = await s3Client.send(listObjCmd); if (!s3Res.Contents) { return NextResponse.json({ status: 500 }) } const s3Photos = sift(s3Res.Contents.map((obj) => { if (!obj.Key?.endsWith('/')) { return `https://fly.storage.tigris.dev/joemonk-photos/${obj.Key}`; } else { return null; } })); const newPhotos = diff(s3Photos, currentSources); const imageData = newPhotos.map(async (fileName: string) => { const getImageCmd = new GetObjectCommand({ Bucket: "joemonk-photos", Key: fileName.replace("https://fly.storage.tigris.dev/joemonk-photos/", "") }) const imgRes = await s3Client.send(getImageCmd); const image = await imgRes.Body?.transformToByteArray(); const { width, height, exif } = await sharp(image).metadata(); const blur = await sharp(image) .resize({ width: 12, height: 12, fit: 'inside' }) .toBuffer(); const exifData = exif ? exifReader(exif) : undefined; const photo = new Photo(); photo.src = fileName; photo.width = width ?? 10; photo.height = height ?? 10; photo.blur = `data:image/jpeg;base64,${blur.toString('base64')}` as `data:image/${string}`; photo.camera = exifData?.Image?.Model ?? null; photo.exposureBiasValue = exifData?.Photo?.ExposureBiasValue ?? null; photo.fNumber = exifData?.Photo?.FNumber ?? null; photo.isoSpeedRatings = exifData?.Photo?.ISOSpeedRatings ?? null; photo.focalLength = exifData?.Photo?.FocalLength ?? null; photo.dateTimeOriginal = exifData?.Photo?.DateTimeOriginal ?? null; photo.lensModel = exifData?.Photo?.LensModel ?? null; return photo; }); const images = await Promise.all(imageData); await photoRepository.save(images); return NextResponse.json({ status: 200, s3Photos: newPhotos }); });