From 02a38a84592dfca13422541b3c462dda1890ff45 Mon Sep 17 00:00:00 2001 From: Shawn Date: Thu, 21 May 2026 22:45:28 -0400 Subject: [PATCH] fix: EXIF data now visible in photo preview card MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - extractExifData() now async — reads real EXIF tags (Make, Model, DateTimeOriginal, ISO, FNumber, ExposureTime, FocalLength, GPS) via exifr.parse() and displays them in the UI - handlePickedPhoto() + reader.onload made async to support this - GPS extraction already auto-triggers on photo pick (tryExtractGpsFromPicked) - Server-side exif_data round-trip already functional (verified) - DNG/RAW-02: .dng allowed, 20MB limit --- static/index.html | 47 +++++++++++++++--- .../0ecfcc9ddda541f8887d621f9219d010.jpg | Bin 0 -> 1072 bytes .../44caeacf8d0b41669e1cc6500f216203.jpg | Bin 0 -> 982 bytes .../557ba8d1223340bf89a0b0b495b0a75e.jpg | Bin 0 -> 2054 bytes .../59dd8174afe644f0804e3a36e45f94fa.jpg | Bin 0 -> 2054 bytes .../74c1bfba3d4f492b8045d61da8a3db06.jpg | Bin 0 -> 982 bytes .../a8c7e55327ec498dadecf408afa224f4.jpg | Bin 0 -> 1917 bytes .../f3c9b6b3522a4980858df80c70bd5a1d.jpg | Bin 0 -> 1028 bytes 8 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 uploads/photos/0ecfcc9ddda541f8887d621f9219d010.jpg create mode 100644 uploads/photos/44caeacf8d0b41669e1cc6500f216203.jpg create mode 100644 uploads/photos/557ba8d1223340bf89a0b0b495b0a75e.jpg create mode 100644 uploads/photos/59dd8174afe644f0804e3a36e45f94fa.jpg create mode 100644 uploads/photos/74c1bfba3d4f492b8045d61da8a3db06.jpg create mode 100644 uploads/photos/a8c7e55327ec498dadecf408afa224f4.jpg create mode 100644 uploads/photos/f3c9b6b3522a4980858df80c70bd5a1d.jpg diff --git a/static/index.html b/static/index.html index ad4251e..ac76173 100644 --- a/static/index.html +++ b/static/index.html @@ -1732,15 +1732,15 @@ } })(); - function handlePickedPhoto(file) { + async function handlePickedPhoto(file) { pickedPhotoFile = file; const reader = new FileReader(); - reader.onload = function(e) { + reader.onload = async function(e) { document.getElementById('pickedPhotoPreview').src = e.target.result; document.getElementById('photoPreviewCard').style.display = 'block'; // Extract EXIF / file metadata - extractExifData(file); + await extractExifData(file); // Auto-extract GPS from the picked photo tryExtractGpsFromPicked(); @@ -1751,13 +1751,44 @@ reader.readAsDataURL(file); } - function extractExifData(file) { + async function extractExifData(file) { const exifDiv = document.getElementById('pickedExifData'); const rows = []; - rows.push({ label: 'File name', value: file.name }); - rows.push({ label: 'File size', value: formatFileSize(file.size) }); - rows.push({ label: 'Type', value: file.type || 'unknown' }); - rows.push({ label: 'Last modified', value: formatDate(new Date(file.lastModified).toISOString()) }); + rows.push({ label: '📄 File name', value: file.name }); + rows.push({ label: '📦 File size', value: formatFileSize(file.size) }); + rows.push({ label: '🏷️ Type', value: file.type || 'unknown' }); + rows.push({ label: '🕐 Modified', value: formatDate(new Date(file.lastModified).toISOString()) }); + + // Try to read actual EXIF tags from the file + try { + const exifData = await exifr.parse(file); + if (exifData) { + if (exifData.Make || exifData.Model) { + rows.push({ label: '📷 Camera', value: [exifData.Make, exifData.Model].filter(Boolean).join(' ') }); + } + if (exifData.DateTimeOriginal) { + const d = new Date(exifData.DateTimeOriginal); + rows.push({ label: '📅 Date taken', value: d.toLocaleString() }); + } + if (exifData.ISO) { + rows.push({ label: '🎯 ISO', value: String(exifData.ISO) }); + } + if (exifData.FNumber) { + rows.push({ label: '🔆 Aperture', value: 'f/' + exifData.FNumber }); + } + if (exifData.ExposureTime) { + rows.push({ label: '⏱️ Shutter', value: exifData.ExposureTime + 's' }); + } + if (exifData.FocalLength) { + rows.push({ label: '🔭 Focal', value: exifData.FocalLength + 'mm' }); + } + if (exifData.GPSLatitude && exifData.GPSLongitude) { + const lat = exifData.latitude || exifData.GPSLatitude; + const lng = exifData.longitude || exifData.GPSLongitude; + rows.push({ label: '📍 GPS', value: typeof lat === 'number' ? `${lat.toFixed(6)}, ${lng.toFixed(6)}` : `${exifData.GPSLatitude.join(' ')} ${exifData.GPSLatitudeRef}, ${exifData.GPSLongitude.join(' ')} ${exifData.GPSLongitudeRef}` }); + } + } + } catch (_) { /* EXIF display is best-effort */ } exifDiv.innerHTML = rows.map(r => `
${esc(r.label)}${esc(r.value)}
` diff --git a/uploads/photos/0ecfcc9ddda541f8887d621f9219d010.jpg b/uploads/photos/0ecfcc9ddda541f8887d621f9219d010.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b14abba040f9c5a941aed0044c2c7f7c5213e7a GIT binary patch literal 1072 zcmex=dlUvm!OeG7&;602vI76PUrqhyZ0XjSP&;tPD)8j0_bFO{|O! ztPBho7}$V@f-Gh71DU|YzzQTmmK_I@VDWH}I160-K9B`;1{i~MgVclg-x=7X8WBV$krWc<7m<~cmy?x}kx@|5Q&&*ZQI?U>FxS*EFf=hSkyp30wJ@^LGd3{-8N$fP z$;rdbBf-lnVWcRdXhbsje}F-dgCT_>g_%)_fk}{&S&;Gn5e9jn|5zEpfB^~^nV4Bv z+1NQaxwwG}wgO{{k(rr^g_)I=1sFGswLp0W7C}}aMMFn6;lM<8r9u&-#)%6#l$|yn z6b-ugLB%+!sELzHOk6@zN>xo=LsQGd)Xdz%(#qMz)y>_*(bPj7;S~%q+;ls%Xe24f* E0O%qtnE(I) literal 0 HcmV?d00001 diff --git a/uploads/photos/44caeacf8d0b41669e1cc6500f216203.jpg b/uploads/photos/44caeacf8d0b41669e1cc6500f216203.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c18b40885273d43087ce92d9b0bd3b4e42c06085 GIT binary patch literal 982 zcmex=1umEXBAa({~ zhJeh9)Evu12(18Q0Hqnh%9;E?@=Oe@K$01VOMxWFNTzTg0aOJO?`2?Xx<^MmBoJCPpAb7&$pPdANBbczGp^ z6lD~RNCy88FbHxmq%fo~Gb%AK2{JMZGX6ipAP)>4Rz@%YdK3&8nV4Bv+1NQaxwwG} zwgSVGk(rr^g_)I=1sIx)wLp0W7C}}aMMFn6;lM<8r9u&-#)%6#l$|yn6b-ugLB%+! zsELzHOk6@zN>xo=LsQGd)Xdz%(#qMz)y>_*(bP zj7;S~%q+;ls%Xe24f*0M6DU<^TWy literal 0 HcmV?d00001 diff --git a/uploads/photos/557ba8d1223340bf89a0b0b495b0a75e.jpg b/uploads/photos/557ba8d1223340bf89a0b0b495b0a75e.jpg new file mode 100644 index 0000000000000000000000000000000000000000..73d23c7fd7d4bc69a192568cf6211c7ea20665bd GIT binary patch literal 2054 zcmex=tOh6VV5UX{lGOz$?Mj+M)Vup~^;u7cl zq5=k>Fe6wQlOIT&iGdYJG6QiUkOXOG3I`HERWR{N1~#b%1_pHj2DWVnz%NAFoEbRS*x1=vIoR3RIXOAFctm)4xVd>Gg@pMFmiHo@^JG=@bXF+Dat4skqrJH zU=ZYBNMW47%&5e`B*@4t$oT&VgFG-;SQ)_p=ut3WWMXDvWn<^ywh= zDOELf4NWZ*Q!{f5ODks=S2uSLPp{yR(6I1`$f)F$)U@=B%&g*)(z5c3%Btp;*0%PJ z&aO$5r%atTea6gLixw|gx@`H1m8&*w-m-Pu_8mKS9XfpE=&|D`PM*4S`O4L6*Kgds z_3+W-Cr_U}fAR9w$4{TXeEs(Q$Io9Ne=#yJL%anfvHD98=r1M~7G@T9kiQt2%7K_! zkcCyzkWI)jkUgH#tN&5O+B}ueKVFPK zt{aPOx|qFd-}?NTT((Wyd_|9+5OLl0G1+>KsKZIFIaBkZ8B&^Tv$_}_*jPTwz8kyc zrT*5^EjwpvyZ0S%Sfe+|yJX^hiF@*s+zs__jdN8$w0z%q zTt{$fe@2C1ZVQ&cnApn{ORg`@Us*Q9}#I^z?A)$T@TO$T0cm zyE0U^?*AtLZQty_`~S}W7W?bl{p~q7_y2aXNv@YXR{QIE_(O|Z&kq|#pD!&`+Ok95$Tz&yYDc zyzZTu#%ZCdWMy@xx#fJbWv?~ovpy-0n!Dzj;g)meF?SD{C3(mf9;w+_#K^Ch;s^#pt9E!@<7C8~)r4_*4~M4D{l*`F|(#&0eE*<7L#`O{yEW zM^}80K3nwrVsN&YT%H$O-4d%wY`kd|{jTjUj>}zD=eXVW^jALHAgQNjbmIIs9|7eV zlP5Xk#n~}LeLbbYe5zEi##GnIRwDZ3YMoi#r%h5@pB?7e7j$CBL*^MyGII}TG8D)1 zx4+p^>-IWq%cZN*4wG(O$=zPG;&Pg^!l{WT1341!FMO4~by0&s4gY@zCH8jvH{!Yf W85T|3zGC>~oZ(UeP~s2!|2F~W_VB3y literal 0 HcmV?d00001 diff --git a/uploads/photos/59dd8174afe644f0804e3a36e45f94fa.jpg b/uploads/photos/59dd8174afe644f0804e3a36e45f94fa.jpg new file mode 100644 index 0000000000000000000000000000000000000000..73d23c7fd7d4bc69a192568cf6211c7ea20665bd GIT binary patch literal 2054 zcmex=tOh6VV5UX{lGOz$?Mj+M)Vup~^;u7cl zq5=k>Fe6wQlOIT&iGdYJG6QiUkOXOG3I`HERWR{N1~#b%1_pHj2DWVnz%NAFoEbRS*x1=vIoR3RIXOAFctm)4xVd>Gg@pMFmiHo@^JG=@bXF+Dat4skqrJH zU=ZYBNMW47%&5e`B*@4t$oT&VgFG-;SQ)_p=ut3WWMXDvWn<^ywh= zDOELf4NWZ*Q!{f5ODks=S2uSLPp{yR(6I1`$f)F$)U@=B%&g*)(z5c3%Btp;*0%PJ z&aO$5r%atTea6gLixw|gx@`H1m8&*w-m-Pu_8mKS9XfpE=&|D`PM*4S`O4L6*Kgds z_3+W-Cr_U}fAR9w$4{TXeEs(Q$Io9Ne=#yJL%anfvHD98=r1M~7G@T9kiQt2%7K_! zkcCyzkWI)jkUgH#tN&5O+B}ueKVFPK zt{aPOx|qFd-}?NTT((Wyd_|9+5OLl0G1+>KsKZIFIaBkZ8B&^Tv$_}_*jPTwz8kyc zrT*5^EjwpvyZ0S%Sfe+|yJX^hiF@*s+zs__jdN8$w0z%q zTt{$fe@2C1ZVQ&cnApn{ORg`@Us*Q9}#I^z?A)$T@TO$T0cm zyE0U^?*AtLZQty_`~S}W7W?bl{p~q7_y2aXNv@YXR{QIE_(O|Z&kq|#pD!&`+Ok95$Tz&yYDc zyzZTu#%ZCdWMy@xx#fJbWv?~ovpy-0n!Dzj;g)meF?SD{C3(mf9;w+_#K^Ch;s^#pt9E!@<7C8~)r4_*4~M4D{l*`F|(#&0eE*<7L#`O{yEW zM^}80K3nwrVsN&YT%H$O-4d%wY`kd|{jTjUj>}zD=eXVW^jALHAgQNjbmIIs9|7eV zlP5Xk#n~}LeLbbYe5zEi##GnIRwDZ3YMoi#r%h5@pB?7e7j$CBL*^MyGII}TG8D)1 zx4+p^>-IWq%cZN*4wG(O$=zPG;&Pg^!l{WT1341!FMO4~by0&s4gY@zCH8jvH{!Yf W85T|3zGC>~oZ(UeP~s2!|2F~W_VB3y literal 0 HcmV?d00001 diff --git a/uploads/photos/74c1bfba3d4f492b8045d61da8a3db06.jpg b/uploads/photos/74c1bfba3d4f492b8045d61da8a3db06.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c18b40885273d43087ce92d9b0bd3b4e42c06085 GIT binary patch literal 982 zcmex=1umEXBAa({~ zhJeh9)Evu12(18Q0Hqnh%9;E?@=Oe@K$01VOMxWFNTzTg0aOJO?`2?Xx<^MmBoJCPpAb7&$pPdANBbczGp^ z6lD~RNCy88FbHxmq%fo~Gb%AK2{JMZGX6ipAP)>4Rz@%YdK3&8nV4Bv+1NQaxwwG} zwgSVGk(rr^g_)I=1sIx)wLp0W7C}}aMMFn6;lM<8r9u&-#)%6#l$|yn6b-ugLB%+! zsELzHOk6@zN>xo=LsQGd)Xdz%(#qMz)y>_*(bP zj7;S~%q+;ls%Xe24f*0M6DU<^TWy literal 0 HcmV?d00001 diff --git a/uploads/photos/a8c7e55327ec498dadecf408afa224f4.jpg b/uploads/photos/a8c7e55327ec498dadecf408afa224f4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..79a302b44710d51740eea1bc66c4cc4ce0378130 GIT binary patch literal 1917 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<| zHF0u@iAzXIsj8`KXlj|5nweWzS~We&gn?hmRgVdHU@6i$mSee*Oaai;;mD;w>Nv@fe!F1cClyVqsxs zVF&q(k*OSrnFU!`6%E;h90S=C3x$=88aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3L7Bz4U6Kt`+W5Zb!Ddy;v*&U|F#a#W5 zD%R$yg#Phj{Bhk_Y}3W;UHjJO*W|Ko+U6^I{Dg?>u8+yqb3`3Za?P2V7tN5;WSiB+ z@W96MQTE-~Eid)AmTuWOOWVEgfWsQSN!}$B?@QdXD=R&r7=HSRT(;7&{|q6Q?Bs5! ze`}np`l03f#^XAIQyU-l$?Ip_{>6JUtQQ2W; zhEbJ)ZwyauJNVt~?#(lA+&B)(9v8XK_IlT`wJRCxOLHE+_1S#uxZ3wE(~BBfIHsqE zOGnO`yGMq}Ki`$1vUUGA`EUDX|K0z0{Uk6B;Hz)l}wN`&8ogcb1KLhq zdgid<#D9j&x#4y1%rs65RV6E{GtDjMn=N~-IiK}OdDPrB*9^CuGmp7@$Slc2zVJxR z#v(=@=023sG{j-wmg9vx?vKJa^0 zMBc&j74?Ut*DP;;Q*!76cT3Y_e>RC{`6@;yg%}R@J>Kx=ZosFi@M54Bx6S`MnQ!(Q zts5_+=5A8mxIMb!d-U0&-xq_k#pLq5*y@&8O=9CstLS%acX3?qsyfH*wx_@H*#=2H zHKP;fzxfC#&zL;PAurC3A?oWX4dzp&f;FbPPPP)!Cs*st>OO6f+WPD;&%U4&J03F6 zaFUsOK$D?3mcRYYmRh&hVOuU;m3EkP>q_qSq7|3ZoE1(@JQ>K5cz@xm?5&F$3~KoQ gGbpjQ+rJUd{m-yy+V&O0C+7^85`Yqa*#Ex?0PDTsUH||9 literal 0 HcmV?d00001 diff --git a/uploads/photos/f3c9b6b3522a4980858df80c70bd5a1d.jpg b/uploads/photos/f3c9b6b3522a4980858df80c70bd5a1d.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e9408265f5ddfc1ed399fc83e3ba512c2dbb7268 GIT binary patch literal 1028 zcmex=<81>};$Y?Ck8EoE%&{BD_4@+&q#(!u%q#Qu1=LQZh0MDthV)N;=9iG8*QZ zItGR&CMNRgmbMl~HhRV;Mj%5NIXO9bxOpUac_oY#WfYA_2LBH*2y!r_Fr+XuDlsq# zGBOJ?{y)MX4|F3dBNzak3kHl#%q*;I>>Qk2+&~3e1sIqZnVFebm|0m_fT7M<3zTPI z5o8roG<0MW4oqZMDikqloVbuf*=gfJ(V&YTRE(2~nmD<{#3dx9RMpfqG__1j&CD$< zt(;w4-P}Dqy@EqR!@?sXqmoln)6z3Cvx-Yf%gQS%tD0L{+uA!iyCzMZGIiSY88c@s zTD)ZGvgIpQuG+MD%hqk%ckJAC=%>Qo!0DZC~g#Z8m literal 0 HcmV?d00001