diff --git a/server/cloudinary-gallery-map.json b/server/cloudinary-gallery-map.json index abfe73a..41dd794 100644 --- a/server/cloudinary-gallery-map.json +++ b/server/cloudinary-gallery-map.json @@ -6,5 +6,173 @@ "Julia Buchner 2.jpg": "folx-gallery/Julia_Buchner_2", "Julia Buchner 1 .jpg": "folx-gallery/Julia_Buchner_1_", "John Prisco 1.jpg": "folx-gallery/John_Prisco_1", - "Mosaik 4.jpg": "folx-gallery/Mosaik_4" + "Mosaik 4.jpg": "folx-gallery/Mosaik_4", + "Acarina 1 (1).jpg": "folx-gallery/Acarina_1__1_", + "Grazer Spitzbuam 2.jpg": "folx-gallery/Grazer_Spitzbuam_2", + "Maibritt 1 (1).jpg": "folx-gallery/Maibritt_1__1_", + "Sellraintaler Exklusiv 2.jpg": "folx-gallery/Sellraintaler_Exklusiv_2", + "Sellraintaler Exklusiv 2 (1).jpg": "folx-gallery/Sellraintaler_Exklusiv_2__1_", + "Die Partyhirschen 2.jpg": "folx-gallery/Die_Partyhirschen_2", + "Adriana 1.jpg": "folx-gallery/Adriana_1", + "Felix Muhr 1.jpg": "folx-gallery/Felix_Muhr_1", + "Die Strizis 2.jpg": "folx-gallery/Die_Strizis_2", + "Wirbelwind 1.jpg": "folx-gallery/Wirbelwind_1", + "Linda Feller.jpg": "folx-gallery/Linda_Feller", + "Road Chicks 1.jpg": "folx-gallery/Road_Chicks_1", + "Tiroler Schmäh 2.jpg": "folx-gallery/Tiroler_Schm_h_2", + "Landrocker 2.jpg": "folx-gallery/Landrocker_2", + "Linda Feller und Joshville.jpg": "folx-gallery/Linda_Feller_und_Joshville", + "Ulli Bastian.jpg": "folx-gallery/Ulli_Bastian", + "Anita Hofmann.jpg": "folx-gallery/Anita_Hofmann", + "Joshville (2).jpg": "folx-gallery/Joshville__2_", + "Joshville.jpg": "folx-gallery/Joshville", + "DSC06251.jpg": "folx-gallery/DSC06251", + "DSC06296.jpg": "folx-gallery/DSC06296", + "Anita Hofmann (2).jpg": "folx-gallery/Anita_Hofmann__2_", + "Linda Feller (2).jpg": "folx-gallery/Linda_Feller__2_", + "DSC06416.jpg": "folx-gallery/DSC06416", + "DSC06592.jpg": "folx-gallery/DSC06592", + "DSC06679.jpg": "folx-gallery/DSC06679", + "DSC06145.jpg": "folx-gallery/DSC06145", + "DSC07135.jpg": "folx-gallery/DSC07135", + "DSC07000.jpg": "folx-gallery/DSC07000", + "DSC06840.jpg": "folx-gallery/DSC06840", + "DSC07240.jpg": "folx-gallery/DSC07240", + "DSC07522.jpg": "folx-gallery/DSC07522", + "DSC07620.jpg": "folx-gallery/DSC07620", + "DSC07645.jpg": "folx-gallery/DSC07645", + "DSC07594.jpg": "folx-gallery/DSC07594", + "DSC07737.jpg": "folx-gallery/DSC07737", + "DSC07679.jpg": "folx-gallery/DSC07679", + "DSC08216.jpg": "folx-gallery/DSC08216", + "DSC08332.jpg": "folx-gallery/DSC08332", + "DSC08350.jpg": "folx-gallery/DSC08350", + "DSC08547.jpg": "folx-gallery/DSC08547", + "Alpensterne 2 .jpg": "folx-gallery/Alpensterne_2_", + "Jazz Gitti 1.jpg": "folx-gallery/Jazz_Gitti_1", + "Pauline 1.jpg": "folx-gallery/Pauline_1", + "Pauline 2.jpg": "folx-gallery/Pauline_2", + "Hannes Lanz 1.jpg": "folx-gallery/Hannes_Lanz_1", + "D'Oimhittn Musi 2.jpg": "folx-gallery/D_Oimhittn_Musi_2", + "Pfunds-Kerle 2.jpg": "folx-gallery/Pfunds-Kerle_2", + "Hannes Lanz 2.jpg": "folx-gallery/Hannes_Lanz_2", + "Christa Fartek 1.jpg": "folx-gallery/Christa_Fartek_1", + "Christa Fartek 2.jpg": "folx-gallery/Christa_Fartek_2", + "Natalie Holzner 2.jpg": "folx-gallery/Natalie_Holzner_2", + "KulturErben 1.jpg": "folx-gallery/KulturErben_1", + "Die Trattnachtaler 2.jpg": "folx-gallery/Die_Trattnachtaler_2", + "Christa Fartek und Robert F..jpg": "folx-gallery/Christa_Fartek_und_Robert_F_", + "Marie Klee 2.jpg": "folx-gallery/Marie_Klee_2", + "Marie Klee 1.jpg": "folx-gallery/Marie_Klee_1", + "Christa Fartek und Robert F. (1).jpg": "folx-gallery/Christa_Fartek_und_Robert_F___1_", + "Wadltreiber 1.jpg": "folx-gallery/Wadltreiber_1", + "Mosaik 2.jpg": "folx-gallery/Mosaik_2", + "Mosaik 3.jpg": "folx-gallery/Mosaik_3", + "Wadltreiber 2.jpg": "folx-gallery/Wadltreiber_2", + "Trio Musischwung 1.jpg": "folx-gallery/Trio_Musischwung_1", + "Die Tiger 1.jpg": "folx-gallery/Die_Tiger_1", + "Alexander Helmer 1.jpg": "folx-gallery/Alexander_Helmer_1", + "Maibritt 1.jpg": "folx-gallery/Maibritt_1", + "Arina 2.jpg": "folx-gallery/Arina_2", + "Die Tiger 2.jpg": "folx-gallery/Die_Tiger_2", + "Grazer Spitzbuam 1.jpg": "folx-gallery/Grazer_Spitzbuam_1", + "Arina 1.jpg": "folx-gallery/Arina_1", + "Maibritt 2.jpg": "folx-gallery/Maibritt_2", + "Acarina 1.jpg": "folx-gallery/Acarina_1", + "Aufwärts 1.jpg": "folx-gallery/Aufw_rts_1", + "Aufwärts 2.jpg": "folx-gallery/Aufw_rts_2", + "Sellraintaler Exklusiv 1.jpg": "folx-gallery/Sellraintaler_Exklusiv_1", + "Acarina 2.jpg": "folx-gallery/Acarina_2", + "Martin Locher und Band 2.jpg": "folx-gallery/Martin_Locher_und_Band_2", + "Aufwärts 1 (1).jpg": "folx-gallery/Aufw_rts_1__1_", + "Acarina 2 (1).jpg": "folx-gallery/Acarina_2__1_", + "Martin Locher und Band 1.jpg": "folx-gallery/Martin_Locher_und_Band_1", + "Aufwärts 2 (1).jpg": "folx-gallery/Aufw_rts_2__1_", + "Grazer Spitzbuam 2 (1).jpg": "folx-gallery/Grazer_Spitzbuam_2__1_", + "Maibritt 2 (1).jpg": "folx-gallery/Maibritt_2__1_", + "Grazer Spitzbuam 1 (1).jpg": "folx-gallery/Grazer_Spitzbuam_1__1_", + "Martin Locher und Band 1 (1).jpg": "folx-gallery/Martin_Locher_und_Band_1__1_", + "Adriana 2.jpg": "folx-gallery/Adriana_2", + "Sellraintaler Exklusiv 1 (1).jpg": "folx-gallery/Sellraintaler_Exklusiv_1__1_", + "Martin Locher und Band 2 (1).jpg": "folx-gallery/Martin_Locher_und_Band_2__1_", + "Die Strizis 1.jpg": "folx-gallery/Die_Strizis_1", + "Rotzlöffl 1.jpg": "folx-gallery/Rotzl_ffl_1", + "DSC06911.jpg": "folx-gallery/DSC06911", + "DSC06367.jpg": "folx-gallery/DSC06367", + "Petovia Quintett (2).jpg": "folx-gallery/Petovia_Quintett__2_", + "DSC07699.jpg": "folx-gallery/DSC07699", + "DSC07407.jpg": "folx-gallery/DSC07407", + "DSC07217.jpg": "folx-gallery/DSC07217", + "DSC08636.jpg": "folx-gallery/DSC08636", + "Nordwand 2.jpg": "folx-gallery/Nordwand_2", + "Die 3 Kärntner 2.jpg": "folx-gallery/Die_3_K_rntner_2", + "Pfunds-Kerle 1.jpg": "folx-gallery/Pfunds-Kerle_1", + "Die Zwirn 2.jpg": "folx-gallery/Die_Zwirn_2", + "Die Trattnachtaler 1.jpg": "folx-gallery/Die_Trattnachtaler_1", + "Natalie Holzner 1.jpg": "folx-gallery/Natalie_Holzner_1", + "KulturErben 2.jpg": "folx-gallery/KulturErben_2", + "Vollguat 1.jpg": "folx-gallery/Vollguat_1", + "Jelfi 2.jpg": "folx-gallery/Jelfi_2", + "Trio Musischwung 2.jpg": "folx-gallery/Trio_Musischwung_2", + "Petovia Quintett.jpg": "folx-gallery/Petovia_Quintett", + "DSC06195.jpg": "folx-gallery/DSC06195", + "DSC06624.jpg": "folx-gallery/DSC06624", + "DSC07062.jpg": "folx-gallery/DSC07062", + "DSC06795.jpg": "folx-gallery/DSC06795", + "DSC07177.jpg": "folx-gallery/DSC07177", + "DSC07498.jpg": "folx-gallery/DSC07498", + "DSC07438.jpg": "folx-gallery/DSC07438", + "DSC08431.jpg": "folx-gallery/DSC08431", + "DSC08452.jpg": "folx-gallery/DSC08452", + "DSC08456.jpg": "folx-gallery/DSC08456", + "DSC08537.jpg": "folx-gallery/DSC08537", + "DSC08483.jpg": "folx-gallery/DSC08483", + "DSC08504.jpg": "folx-gallery/DSC08504", + "DSC08594.jpg": "folx-gallery/DSC08594", + "DSC08609.jpg": "folx-gallery/DSC08609", + "Alex Reichinger 2.jpg": "folx-gallery/Alex_Reichinger_2", + "DSC08626.jpg": "folx-gallery/DSC08626", + "Alex Reichinger 1.jpg": "folx-gallery/Alex_Reichinger_1", + "Die 3 Kärntner 1.jpg": "folx-gallery/Die_3_K_rntner_1", + "Nordwand 1.jpg": "folx-gallery/Nordwand_1", + "Alpensterne 1.jpg": "folx-gallery/Alpensterne_1", + "Fesch'n Rock 1.jpg": "folx-gallery/Fesch_n_Rock_1", + "Fesch'n Rock 2.jpg": "folx-gallery/Fesch_n_Rock_2", + "Freiheit 1.jpg": "folx-gallery/Freiheit_1", + "Jazz Gitti 2.jpg": "folx-gallery/Jazz_Gitti_2", + "Freiheit 2.jpg": "folx-gallery/Freiheit_2", + "Die Zwirn 1.jpg": "folx-gallery/Die_Zwirn_1", + "John Prisco 2.jpg": "folx-gallery/John_Prisco_2", + "D'Oimhittn Musi 1.jpg": "folx-gallery/D_Oimhittn_Musi_1", + "Wildkogel Buam 1.jpg": "folx-gallery/Wildkogel_Buam_1", + "Wildkogel Buam 2.jpg": "folx-gallery/Wildkogel_Buam_2", + "Do schau her 1.jpg": "folx-gallery/Do_schau_her_1", + "Do schau her 2.jpg": "folx-gallery/Do_schau_her_2", + "Swen Tangl 1.jpg": "folx-gallery/Swen_Tangl_1", + "Swen Tangl 2.jpg": "folx-gallery/Swen_Tangl_2", + "Vollguat 2.jpg": "folx-gallery/Vollguat_2", + "Mosaik 1.jpg": "folx-gallery/Mosaik_1", + "Alexander Helmer 2.jpg": "folx-gallery/Alexander_Helmer_2", + "Jelfi 1.jpg": "folx-gallery/Jelfi_1", + "Rotzlöffl 2.jpg": "folx-gallery/Rotzl_ffl_2", + "Die Partyhirschen 1.jpg": "folx-gallery/Die_Partyhirschen_1", + "Sanny 1.jpg": "folx-gallery/Sanny_1", + "Bodensee Quintett 1.jpg": "folx-gallery/Bodensee_Quintett_1", + "Sanny 2.jpg": "folx-gallery/Sanny_2", + "Bodensee Quintett 2.jpg": "folx-gallery/Bodensee_Quintett_2", + "Felix Muhr 2.jpg": "folx-gallery/Felix_Muhr_2", + "Natascha 2.jpg": "folx-gallery/Natascha_2", + "Natascha 1.jpg": "folx-gallery/Natascha_1", + "Karin & da Hefter 1.jpg": "folx-gallery/Karin___da_Hefter_1", + "Berny Blank 1.jpg": "folx-gallery/Berny_Blank_1", + "Karin & da Hefter 2.jpg": "folx-gallery/Karin___da_Hefter_2", + "Wirbelwind 2.jpg": "folx-gallery/Wirbelwind_2", + "Berny Blank 2.jpg": "folx-gallery/Berny_Blank_2", + "Dir 3 Zwidern 1.jpg": "folx-gallery/Dir_3_Zwidern_1", + "Tiroler Schmäh 1.jpg": "folx-gallery/Tiroler_Schm_h_1", + "Road Chicks 2.jpg": "folx-gallery/Road_Chicks_2", + "Dir 3 Zwidern 2.jpg": "folx-gallery/Dir_3_Zwidern_2", + "Melia 2.jpg": "folx-gallery/Melia_2", + "Melia 1.jpg": "folx-gallery/Melia_1", + "Landrocker 1.jpg": "folx-gallery/Landrocker_1" } \ No newline at end of file diff --git a/server/cloudinary.ts b/server/cloudinary.ts index e12468e..3ff4526 100644 --- a/server/cloudinary.ts +++ b/server/cloudinary.ts @@ -1,4 +1,5 @@ import { v2 as cloudinary } from "cloudinary"; +import sharp from "sharp"; cloudinary.config({ cloud_name: process.env.CLOUDINARY_CLOUD_NAME, @@ -7,6 +8,7 @@ cloudinary.config({ }); const GALLERY_FOLDER = "folx-gallery"; +const MAX_UPLOAD_SIZE = 9 * 1024 * 1024; export interface CloudinaryGalleryImage { publicId: string; @@ -19,10 +21,8 @@ export interface CloudinaryGalleryImage { } function buildUrl(publicId: string, transforms: string): string { - return cloudinary.url(publicId, { - transformation: transforms, - secure: true, - }); + const cloudName = process.env.CLOUDINARY_CLOUD_NAME || "djqxt0pf3"; + return `https://res.cloudinary.com/${cloudName}/image/upload/${transforms}/${publicId}`; } export function generateImageUrls(publicId: string): { thumb: string; large: string; mobile: string; full: string } { @@ -34,6 +34,31 @@ export function generateImageUrls(publicId: string): { thumb: string; large: str }; } +async function downloadAndCompress(imageUrl: string): Promise { + const resp = await fetch(imageUrl); + if (!resp.ok) throw new Error(`Download failed: ${resp.status}`); + const arrayBuffer = await resp.arrayBuffer(); + const buffer = Buffer.from(arrayBuffer); + + if (buffer.length <= MAX_UPLOAD_SIZE) { + return buffer; + } + + const compressed = await sharp(buffer) + .resize({ width: 4000, withoutEnlargement: true }) + .jpeg({ quality: 85 }) + .toBuffer(); + + if (compressed.length > MAX_UPLOAD_SIZE) { + return sharp(buffer) + .resize({ width: 3000, withoutEnlargement: true }) + .jpeg({ quality: 75 }) + .toBuffer(); + } + + return compressed; +} + export async function uploadToCloudinary(imageUrl: string, fileName: string): Promise { const publicId = `${GALLERY_FOLDER}/${fileName.replace(/\.\w+$/, "").replace(/[^a-zA-Z0-9_-]/g, "_")}`; @@ -45,12 +70,22 @@ export async function uploadToCloudinary(imageUrl: string, fileName: string): Pr } catch {} try { - const result = await cloudinary.uploader.upload(imageUrl, { - public_id: publicId, - overwrite: false, - resource_type: "image", + const buffer = await downloadAndCompress(imageUrl); + + return new Promise((resolve, reject) => { + const uploadStream = cloudinary.uploader.upload_stream( + { + public_id: publicId, + overwrite: false, + resource_type: "image", + }, + (error, result) => { + if (error) reject(error); + else resolve(result!.public_id); + } + ); + uploadStream.end(buffer); }); - return result.public_id; } catch (err: any) { console.error(`Cloudinary upload failed for ${fileName}:`, err.message); return null;