const _ = require("lodash"); const logger = require("../utils/logger"); const client = require("../graphql-client/graphql-client").client; const determineFileType = require("./util/determineFileType"); const { DELETE_MEDIA_DOCUMENTS } = require("../graphql-client/queries"); const cloudinary = require("cloudinary").v2; cloudinary.config(process.env.CLOUDINARY_URL); /** * @description Creates a signed upload URL for Cloudinary. * @param req * @param res */ const createSignedUploadURL = (req, res) => { logger.log("media-signed-upload", "DEBUG", req.user.email, null, null); res.send(cloudinary.utils.api_sign_request(req.body, process.env.CLOUDINARY_API_SECRET)); }; /** * @description Downloads files from Cloudinary. * @param req * @param res */ const downloadFiles = (req, res) => { const { ids } = req.body; logger.log("media-bulk-download", "DEBUG", req.user.email, ids, null); const url = cloudinary.utils.download_zip_url({ public_ids: ids, flatten_folders: true }); res.send(url); }; /** * @description Deletes files from Cloudinary and Apollo. * @param req * @param res * @returns {Promise} */ const deleteFiles = async (req, res) => { const { ids } = req.body; const types = _.groupBy(ids, (x) => determineFileType(x.type)); logger.log("media-bulk-delete", "DEBUG", req.user.email, ids, null); const returns = []; if (types.image) { //delete images returns.push( await cloudinary.api.delete_resources( types.image.map((x) => x.key), { resource_type: "image" } ) ); } if (types.video) { returns.push( await cloudinary.api.delete_resources( types.video.map((x) => x.key), { resource_type: "video" } ) ); } if (types.raw) { returns.push( await cloudinary.api.delete_resources( types.raw.map((x) => `${x.key}.${x.extension}`), { resource_type: "raw" } ) ); } // Delete it on apollo. const successfulDeletes = []; returns.forEach((resType) => { Object.keys(resType.deleted).forEach((key) => { if (resType.deleted[key] === "deleted" || resType.deleted[key] === "not_found") { successfulDeletes.push(key.replace(/\.[^/.]+$/, "")); } }); }); try { const result = await client.request(DELETE_MEDIA_DOCUMENTS, { ids: ids.filter((i) => successfulDeletes.includes(i.key)).map((i) => i.id) }); res.send({ returns, result }); } catch (error) { logger.log("media-delete-error", "ERROR", req.user.email, null, [ { ids, error: error.message || JSON.stringify(error) } ]); res.json({ error }); } }; /** * @description Renames keys in Cloudinary and updates the database. * @param req * @param res * @returns {Promise} */ const renameKeys = async (req, res) => { const { documents, tojobid } = req.body; logger.log("media-bulk-rename", "DEBUG", req.user.email, null, documents); const proms = []; documents.forEach((d) => { proms.push( (async () => { try { return { id: d.id, ...(await cloudinary.uploader.rename(d.from, d.to, { resource_type: determineFileType(d.type) })) }; } catch (error) { return { id: d.id, from: d.from, error: error }; } })() ); }); let result; result = await Promise.all(proms); const errors = []; result .filter((d) => d.error) .forEach((d) => { errors.push(d); }); let mutations = ""; result .filter((d) => !d.error) .forEach((d, idx) => { //Create mutation text mutations = mutations + ` update_doc${idx}:update_documents_by_pk(pk_columns: { id: "${d.id}" }, _set: {key: "${d.public_id}", jobid: "${tojobid}"}){ id } `; }); if (mutations !== "") { const mutationResult = await client.request(`mutation { ${mutations} }`); res.json({ errors, mutationResult }); } else { res.json({ errors: "No images were successfully moved on remote server. " }); } }; module.exports = { createSignedUploadURL, downloadFiles, deleteFiles, renameKeys };