Skip to content

Instantly share code, notes, and snippets.

@eexit
Last active August 3, 2023 22:41
Show Gist options
  • Save eexit/8b547c62dd52e0940f8b7e701f861d99 to your computer and use it in GitHub Desktop.
Save eexit/8b547c62dd52e0940f8b7e701f861d99 to your computer and use it in GitHub Desktop.
Upload Ghost local storage images to Cloudinary

Ghost content update

  1. Export your Ghost content (aka backup)
  2. Open in an editor that support Regex find/replace
  3. Search for:
/content/images/\d{4}/(\w{3}|\d{2})/
  1. Replace by:
http://res.cloudinary.com/{cloud-name}/image/upload/{transformations}/{folder}/

It is adived to create a named tranformation in Cloudinary and use it in the URL so if you want to change what the transformation does, you can simply update the named transformation in Cloudinary instead of updating all your Cloudinary URL in your blog.

// Usage:
// $ npm i --no-package-lock --loglevel=error cloudinary glob
// $ CLOUDINARY_URL=cloudinary://xxxx node ghost-image-to-cloudinary.js
const cloudinary = require('cloudinary').v2,
path = require('path'),
glob = require('glob'),
basedir = 'content/images/',
dups = [],
gopts = {
use_filename: true,
unique_filename: false,
overwrite: false
},
getTags = (name) => {
const dpr = name.match(/@(\d)x(?!.*@\dx)/);
return dpr ? ['blog', `dpr${dpr[1]}`] : ['blog', 'dpr1'];
},
findDups = (f, cb) => {
f = path.parse(f);
if (dups.indexOf(f.name) >= 0) {
console.error(new Error(`Found dup with ${f.name}`));
return;
}
dups.push(f.name);
cb(f);
},
upload = (f, cb) => {
const fopt = Object.assign({}, gopts, {
public_id: path.join('blog', f.name),
tags: getTags(f.name)
});
// console.log(fopt); cb(); return;
cloudinary.uploader.upload(path.join(f.dir, f.base), fopt, (err, res) => {
if (err) { throw err; }
console.log(res.url);
cb();
});
};
glob(path.join(basedir, '**/*.jpg'), (err, files) => {
if (err) { throw err; }
let i = 0;
const run = (files) => {
return findDups(files[i], (f) => {
return upload(f, () => {
i++;
if (i < files.length) {
run(files);
}
});
});
}
return run(files);
});
@chinciusan
Copy link

Hi. I found your gist quite useful, as I have a ghost site with thousands of images.
I'd like to make a small change to it. As throwing an error doesn't help me, because it used to happen after a lot of pics from many folders, so restarting the whole process takes a lot of time.
So I modified the script to just show a log and add _duplicate to the file name. That way, when everything's finished, I can manually search in cloudinary for files with duplicate in their name, and deal with them accordingly.

if (dups.indexOf(f.name) >= 0) {
            console.log(`Found dup with ${f.name}.`);
            f.name += `${f.name}_duplicate_${dups.indexOf(f.name)}`
            console.log(`New name is ${f.name}.`);
        } 

@cpuwolf
Copy link

cpuwolf commented Feb 5, 2023

it is really helpful. Thank you guys

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment