folx-tv/server/cloudinary.ts
sebastjanartic a23ae0bdb7 Published your App
Replit-Commit-Author: Deployment
Replit-Commit-Session-Id: 23852c00-4779-460a-9e0c-d09fee4b6c92
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 2b7650db-b0d4-4415-b9bb-cc11e719c2b7
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/23852c00-4779-460a-9e0c-d09fee4b6c92/ncMMRQ9
Replit-Commit-Deployment-Build-Id: 55db64a6-94a6-4850-b7bf-6b5712a636c3
Replit-Helium-Checkpoint-Created: true
2026-03-06 10:31:27 +00:00

95 lines
2.6 KiB
TypeScript

import { v2 as cloudinary } from "cloudinary";
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});
const GALLERY_FOLDER = "folx-gallery";
export interface CloudinaryGalleryImage {
publicId: string;
fileName: string;
artist: string;
thumb: string;
large: string;
mobile: string;
full: string;
}
function buildUrl(publicId: string, transforms: string): string {
return cloudinary.url(publicId, {
transformation: transforms,
secure: true,
});
}
export function generateImageUrls(publicId: string): { thumb: string; large: string; mobile: string; full: string } {
return {
thumb: buildUrl(publicId, "c_fill,g_face:center,w_300,h_300,q_auto,f_auto"),
mobile: buildUrl(publicId, "c_fill,g_auto,w_600,h_338,q_auto,f_auto"),
large: buildUrl(publicId, "c_fit,w_1200,q_auto,f_auto"),
full: buildUrl(publicId, "c_fit,w_1800,q_auto,f_auto"),
};
}
export async function uploadToCloudinary(imageUrl: string, fileName: string): Promise<string | null> {
const publicId = `${GALLERY_FOLDER}/${fileName.replace(/\.\w+$/, "").replace(/[^a-zA-Z0-9_-]/g, "_")}`;
try {
const existing = await cloudinary.api.resource(publicId).catch(() => null);
if (existing) {
return publicId;
}
} catch {}
try {
const result = await cloudinary.uploader.upload(imageUrl, {
public_id: publicId,
overwrite: false,
resource_type: "image",
});
return result.public_id;
} catch (err: any) {
console.error(`Cloudinary upload failed for ${fileName}:`, err.message);
return null;
}
}
export async function checkCloudinaryImage(publicId: string): Promise<boolean> {
try {
await cloudinary.api.resource(publicId);
return true;
} catch {
return false;
}
}
export async function listCloudinaryGallery(): Promise<string[]> {
try {
const result = await cloudinary.api.resources({
type: "upload",
prefix: GALLERY_FOLDER + "/",
max_results: 500,
resource_type: "image",
});
return result.resources.map((r: any) => r.public_id);
} catch (err: any) {
console.error("Cloudinary list failed:", err.message);
return [];
}
}
export function extractArtistFromPublicId(publicId: string): string {
const name = publicId.replace(`${GALLERY_FOLDER}/`, "").replace(/_/g, " ");
if (/^DSC\d/i.test(name) || /^IMG[\s_]\d/i.test(name)) return "";
const cleaned = name
.replace(/\s*\(\d+\)\s*$/, "")
.replace(/\s*\d+\s*$/, "")
.replace(/\s*\(\d+\)\s*$/, "");
return cleaned.trim();
}
export { cloudinary };