Simplify EXIF data form handling

This commit is contained in:
Sam Becker 2023-11-01 09:57:25 -05:00
parent 8bb5c2990b
commit 0f87bd3b5c
4 changed files with 30 additions and 47 deletions

View File

@ -1,7 +1,8 @@
import PhotoForm from '@/photo/PhotoForm';
import AdminChildPage from '@/components/AdminChildPage';
import { PATH_ADMIN_UPLOADS } from '@/site/paths';
import { extractFormDataFromUploadPath } from '@/photo/server';
import { PATH_ADMIN, PATH_ADMIN_UPLOADS } from '@/site/paths';
import { extractExifDataFromBlobPath } from '@/photo/server';
import { redirect } from 'next/navigation';
interface Params {
params: { uploadPath: string }
@ -10,8 +11,10 @@ interface Params {
export default async function UploadPage({ params: { uploadPath } }: Params) {
const {
blobId,
photoForm,
} = await extractFormDataFromUploadPath(uploadPath);
photoFormExif,
} = await extractExifDataFromBlobPath(uploadPath);
if (!photoFormExif) { redirect(PATH_ADMIN); }
return (
<AdminChildPage
@ -19,9 +22,7 @@ export default async function UploadPage({ params: { uploadPath } }: Params) {
backLabel="Uploads"
breadcrumb={blobId}
>
{photoForm
? <PhotoForm initialPhotoForm={photoForm} />
: null}
<PhotoForm initialPhotoForm={photoFormExif} />
</AdminChildPage>
);
};

View File

@ -11,7 +11,6 @@ import {
import {
PhotoFormData,
convertFormDataToPhotoDbInsert,
convertPhotoFormDataToPhotoDbInsert,
convertPhotoToFormData,
} from './form';
import { redirect } from 'next/navigation';
@ -26,7 +25,7 @@ import {
revalidatePhotosKey,
} from '@/cache';
import { PATH_ADMIN_PHOTOS, PATH_ADMIN_TAGS } from '@/site/paths';
import { extractFormDataFromUploadPath } from './server';
import { extractExifDataFromBlobPath } from './server';
export async function createPhotoAction(formData: FormData) {
const photo = convertFormDataToPhotoDbInsert(formData, true);
@ -98,9 +97,9 @@ export async function getExifDataAction(
): Promise<Partial<PhotoFormData>> {
const { url } = photoFormPrevious;
if (url) {
const { photoForm } = await extractFormDataFromUploadPath(url);
if (photoForm) {
return photoForm;
const { photoFormExif } = await extractExifDataFromBlobPath(url);
if (photoFormExif) {
return photoFormExif;
}
}
return {};
@ -111,11 +110,9 @@ export async function syncPhotoExifDataAction(formData: FormData) {
if (photoId) {
const photo = await getPhoto(photoId);
if (photo) {
const {
photoForm: photoFormExif,
} = await extractFormDataFromUploadPath(photo.url);
const { photoFormExif } = await extractExifDataFromBlobPath(photo.url);
if (photoFormExif) {
const photoFormDbInsert = convertPhotoFormDataToPhotoDbInsert({
const photoFormDbInsert = convertFormDataToPhotoDbInsert({
...convertPhotoToFormData(photo),
...photoFormExif,
});

View File

@ -124,10 +124,12 @@ export const convertExifToFormData = (
});
export const convertFormDataToPhotoDbInsert = (
formData: FormData,
formData: FormData | PhotoFormData,
generateId?: boolean,
): PhotoDbInsert => {
const photoForm = Object.fromEntries(formData) as PhotoFormData;
const photoForm = formData instanceof FormData
? Object.fromEntries(formData) as PhotoFormData
: formData;
// Parse FormData:
// - remove server action ID
@ -178,20 +180,3 @@ export const convertFormDataToPhotoDbInsert = (
hidden: photoForm.hidden === 'true',
};
};
const convertPhotoFormDataToFormData = (
photoFormData: PhotoFormData,
) => {
const formData = new FormData();
for (const key in photoFormData) {
formData.append(key, photoFormData[key as keyof PhotoFormData]);
}
return formData;
};
export const convertPhotoFormDataToPhotoDbInsert = (
photoFormData: PhotoFormData,
) => {
const formData = convertPhotoFormDataToFormData(photoFormData);
return convertFormDataToPhotoDbInsert(formData);
};

View File

@ -8,24 +8,24 @@ import {
import { ExifData, ExifParserFactory } from 'ts-exif-parser';
import { PhotoFormData } from './form';
export const extractFormDataFromUploadPath = async (
uploadPath: string
export const extractExifDataFromBlobPath = async (
blobPath: string
): Promise<{
blobId?: string
photoForm?: Partial<PhotoFormData>
photoFormExif?: Partial<PhotoFormData>
}> => {
const url = decodeURIComponent(uploadPath);
const url = decodeURIComponent(blobPath);
const blobId = getIdFromBlobUrl(url);
const extension = getExtensionFromBlobUrl(url);
const fileBytes = uploadPath
const fileBytes = blobPath
? await fetch(url)
.then(res => res.arrayBuffer())
: undefined;
let exifDataForm: ExifData | undefined;
let exifData: ExifData | undefined;
let filmSimulation: FujifilmSimulation | undefined;
if (fileBytes) {
@ -33,10 +33,10 @@ export const extractFormDataFromUploadPath = async (
// Data for form
parser.enableBinaryFields(false);
exifDataForm = parser.parse();
exifData = parser.parse();
// Capture film simulation for Fujifilm cameras
if (isExifForFujifilm(exifDataForm)) {
if (isExifForFujifilm(exifData)) {
// Parse exif data again with binary fields
// in order to access MakerNote tag
parser.enableBinaryFields(true);
@ -50,11 +50,11 @@ export const extractFormDataFromUploadPath = async (
return {
blobId,
...exifDataForm && {
photoForm: {
...convertExifToFormData(exifDataForm, filmSimulation),
...exifData && {
photoFormExif: {
...convertExifToFormData(exifData, filmSimulation),
extension,
url: decodeURIComponent(uploadPath),
url,
},
},
};