UNPKG

cky-image-public

Version:

public image to public host

468 lines (389 loc) 10.1 kB
const path = require('path'); const async = require('async'); const fs = require('fs'); const _ = require('lodash'); const debug = require('debug'); const ImgBB = require('./lib/imgbb'); const Imgur = require('./lib/imgur'); const Filestack = require('./lib/filestack'); const Dropbox = require('./lib/dropbox'); const Drive = require('./lib/drive'); const Pinterest = require('./lib/pinterest'); const Postimg = require('./lib/postimg'); const Imageshack = require('./lib/imageshack'); const Dropshots = require('./lib/dropshots'); const Imgbox = require('./lib/imgbox'); const Cloudinary = require('./lib/cloudinary'); const Imgeto = require('./lib/imgeto'); const Imggmi = require('./lib/imggmi'); let log = debug('CKY-IMAGE-PUBLIC') let __defaultOpts = { imgbb: {}, imgur: { access_token: '', }, filestack: { api_key: '' }, dropbox: { token: '' }, drive: { access_token: '' }, pinterest: { token: '' }, postimg: {}, imageshack: { api_key: '' }, imgeto: {}, imggmi: {}, cloudinary: { cloud_name: '', api_key: '', api_secret: '' }, dropshots: { user_name: '' }, imgbox: {} } let ERROR_CODE = { EUPLOADTYPE: 'Unsupport this type', EFILEPATH: 'Invalid File path for upload', EFILENOTEXISTS: 'File is not exists', EHOSTNOTSUPPORT: 'Host is not support', EHOSTNOTINIT: 'Host was not init', } function roundRobin (arr) { var _tmp = arr.shift(); arr.push(_tmp); return _tmp; } let HOSTS = { imgbb: 'IMGBB', imgur: 'IMGUR', filestack: 'FILESTACK', dropbox: 'DROPBOX', drive: 'DRIVE', pinterest: 'PINTEREST', postimg: 'POSTIMG', imageshack: 'IMAGESHACK', dropshots: 'DROPSHOTS', imgbox: 'IMGBOX', cloudinary: 'CLOUDINARY', imgeto: 'IMGETO', imggmi: 'IMGGMI', } let _resAdapter = (host, res) => { log('_resAdapter host=', host); log('_resAdapter res= %o', res); let response = res; let direct_url = ''; let image_url = ''; let urls = []; try { switch (host) { case 'CLOUDINARY': direct_url = res.url; image_url = res.url; urls.push(res.url, res.secure_url); break; case 'DRIVE': direct_url = res.urlShare; image_url = res.urlShare; urls.push(res.urlShare); break; case 'DROPBOX': direct_url = res.url; image_url = res.url; urls.push(res.url); break; case 'DRIVE': direct_url = res.url; image_url = res.url; urls.push(res.url); break; case 'FILESTACK': direct_url = res.url; image_url = res.url; urls.push(res.url); break; case 'IMAGESHACK': direct_url = res.links.image_link; image_url = res.links.done; urls.push(res.links.image_link, res.links.done, res.links.thumb_link); break; case 'IMGBB': direct_url = res.image.url; image_url = res.image.url_viewer; urls.push(res.image.url, res.image.url_viewer, res.image.thumb.url); break; case 'IMGBOX': direct_url = res.files[0].original_url; image_url = res.files[0].original_url; urls.push(res.files[0].original_url, res.files[0].thumbnail_url, res.files[0].square_url); break; case 'IMGETO': direct_url = res.image.url; image_url = res.image.url_viewer; urls.push( res.image.url, res.image.url_viewer ); if (res.image.thumb && res.image.thumb.url) urls.push(res.image.thumb.url); if (res.image.medium && res.image.medium.url) urls.push(res.image.medium.url); break; case 'IMGGMI': direct_url = res.viewerLink; image_url = res.viewerLink; urls.push(res.viewerLink, res.previewLink); break; case 'IMGUR': direct_url = `https://imgur.com/${res.data.hash}${res.data.ext}`; image_url = `https://imgur.com/${res.data.hash}${res.data.ext}`; urls.push(`https://imgur.com/${res.data.hash}${res.data.ext}`); break; case 'PINTEREST': direct_url = res.image_url; image_url = res.image_url; urls.push(res.image_url); break; case 'POSTIMG': direct_url = res.linkDirect; image_url = res.link; urls.push( res.linkDirect, res.link, res.url, res.linkThumbnail ); break; } } catch (ex) { log('EX= %o', ex); } return { direct_url, image_url, urls, response }; } let _fn = (hostName, fnUpload, imgPath, callback) => { log(`start ${hostName} ...`); fnUpload.upload(imgPath, (err, result) => { log(`done ${hostName}!`); if (err) return callback(null, { error: err, result: result }); let res = _resAdapter(hostName, result); return callback(null, res); }); } class ImgPublic { constructor (options = {}) { let { imgbb, imgur, filestack, dropbox, drive, pinterest, postimg, imageshack, dropshots, imgbox, cloudinary, imgeto, imggmi } = options; this.useHosts = []; if (imgbb) { this.imgbb = new ImgBB(); this.useHosts.push(HOSTS.imgbb); } if (imgur) { let { access_token } = imgur; this.imgur = new Imgur({ access_token, }); this.useHosts.push(HOSTS.imgur); } if (filestack) { let { api_key } = filestack; this.filestack = new Filestack({ api_key }); this.useHosts.push(HOSTS.filestack); } if (dropbox) { let { token } = dropbox; this.dropbox = new Dropbox({ token }) this.useHosts.push(HOSTS.dropbox); } if (drive) { let { access_token, client_id, client_secret, redirect_uris } = drive; this.drive = new Drive({ access_token, client_id, client_secret, redirect_uris }) this.useHosts.push(HOSTS.drive); } if (pinterest) { let { token } = pinterest; this.pinterest = new Pinterest({ token }) this.useHosts.push(HOSTS.pinterest); } if (postimg) { this.postimg = new Postimg(); this.useHosts.push(HOSTS.postimg); } if (imageshack) { let { api_key } = imageshack; this.imageshack = new Imageshack({ api_key }) this.useHosts.push(HOSTS.imageshack); } if (dropshots) { let { user_name } = dropshots; this.dropshots = new Dropshots({ user_name }) this.useHosts.push(HOSTS.dropshots); } if (imgbox) { this.imgbox = new Imgbox(); this.useHosts.push(HOSTS.imgbox); } if (cloudinary) { let { cloud_name, api_key, api_secret } = cloudinary; this.cloudinary = new Cloudinary({ cloud_name, api_key, api_secret }) this.useHosts.push(HOSTS.cloudinary); } if (imgeto) { this.imgeto = new Imgeto(); this.useHosts.push(HOSTS.imgeto); } if (imggmi) { let { cookie } = imggmi; this.imggmi = new Imggmi({ cookie }); this.useHosts.push(HOSTS.imggmi); } // shuffle this.useHosts = _.shuffle(this.useHosts); } supported () { return Object.values(HOSTS); } upload (opts = {}, callback) { let { type, filePath, hosts } = opts; if (!filePath) return callback('EFILEPATH', ERROR_CODE.EFILEPATH); let isExists = fs.existsSync(filePath); if (!isExists) return callback('EFILENOTEXISTS', ERROR_CODE.EFILENOTEXISTS); type = type || 'ALL'; switch (type) { case 'ALL': return this.uploadAll(filePath, callback, hosts); case 'FALLBACK': return this.uploadFallback(filePath, callback, hosts); case 'RANDOM': return this.uploadRandom(filePath, callback, hosts); case 'ROUNDROBIN': return this.uploadRoundRobin(filePath, callback, hosts); default: return callback('EUPLOADTYPE', ERROR_CODE.EUPLOADTYPE); } } uploadAll (filePath, callback, hosts) { let _task = {}; let _tmpHosts = this.useHosts; if (hosts && hosts.length > 0) _tmpHosts = hosts; log('_tmpHosts= %o', _tmpHosts); _tmpHosts.forEach((h) => { if (this.supported().includes(h)) { let key = h.toLowerCase(); if (this[key]) { _task[key] = async.apply(_fn, h, this[key], filePath); } } }) async.parallel(_task, callback); } uploadFallback (filePath, callback, hosts) { let _tmpHosts = this.useHosts; if (hosts && hosts.length > 0) _tmpHosts = hosts; let index = 0; let done = false; let _result = null let _test = (cb) => { let isRunning = true; if (index >= _tmpHosts.length || done) isRunning = false; return cb(null, isRunning); } let _iter = (cb) => { let host = _tmpHosts[index]; log('_iter host= %s', host); if (!this.supported().includes(host)) cb('EHOSTNOTSUPPORT', ERROR_CODE.EHOSTNOTSUPPORT); let key = host.toLowerCase(); if (!this[key]) return cb('EHOSTNOTINIT', ERROR_CODE.EHOSTNOTINIT); this[key].upload(filePath, (err, result) => { if (err) { index++; done = false; return cb(err); } log('_iter result= %o', result); _result = result; done = true; return cb(null); }); } async.whilst(_test, _iter, (err, result) => { if (err) return callback(err); _result = _resAdapter(_tmpHosts[index], _result); return callback(null, _result); }); } uploadRoundRobin (filePath, callback, hosts) { let _tmpHosts = this.useHosts; if (hosts && hosts.length > 0) _tmpHosts = hosts; let host = roundRobin(_tmpHosts); if (!this.supported().includes(host)) return callback('EHOSTNOTSUPPORT', ERROR_CODE.EHOSTNOTSUPPORT); let key = host.toLowerCase(); if (!this[key]) return callback('EHOSTNOTINIT', ERROR_CODE.EHOSTNOTINIT); return this[key].upload(filePath, (err, result) => { if (err) return callback(err, result); let res = _resAdapter(host, result); return callback(null, res); }); } uploadRandom (filePath, callback, hosts) { let _tmpHosts = this.useHosts; if (hosts && hosts.length > 0) _tmpHosts = hosts; let host = _.sample(_tmpHosts); if (!this.supported().includes(host)) return callback('EHOSTNOTSUPPORT', ERROR_CODE.EHOSTNOTSUPPORT); let key = host.toLowerCase(); if (!this[key]) return callback('EHOSTNOTINIT', ERROR_CODE.EHOSTNOTINIT); return this[key].upload(filePath, (err, result) => { if (err) return callback(err, result); let res = _resAdapter(host, result); return callback(null, res); }); } } module.exports = { ImgPublic, ImgBB, Imgur, Filestack, Dropbox, Drive, Pinterest, Postimg, Imageshack, Dropshots, Imgbox, Cloudinary, Imgeto, Imggmi, };