mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Created Media Importer Handler package
refs https://github.com/TryGhost/Toolbox/issues/523 - We need media file imports. Media handler is one of the pre-processing parts that need to be done during the import process - Media import handler is handling import files with following extensions: ".mp4",".webm", ".ogv", ".mp3", ".wav", ".ogg", ".m4a" - The implementation is largely a copy-paste with class syntax adjustments from the "/core/server/data/importer/handles/image.js" module - There are a lot of code similarities between media and image import handlers. The new "ImporterMedia" class could serve as a generic base class for file-storage-related imports
This commit is contained in:
parent
b768e710f1
commit
9347e996f8
10 changed files with 180 additions and 11 deletions
1
ghost/importer-handler-media/index.js
Normal file
1
ghost/importer-handler-media/index.js
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module.exports = require('./lib/ImporterMediaHandler');
|
65
ghost/importer-handler-media/lib/ImporterMediaHandler.js
Normal file
65
ghost/importer-handler-media/lib/ImporterMediaHandler.js
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
const _ = require('lodash');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
class ImporterMediaHandler {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Object} deps dependencies
|
||||||
|
* @param {Object} deps.storage storage adapter instance
|
||||||
|
* @param {Object} deps.config config instance
|
||||||
|
* @param {object} deps.urlUtils urlUtils instance
|
||||||
|
*/
|
||||||
|
constructor(deps) {
|
||||||
|
this.storage = deps.storage;
|
||||||
|
this.config = deps.config;
|
||||||
|
this.urlUtils = deps.urlUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = 'media';
|
||||||
|
|
||||||
|
get extensions() {
|
||||||
|
return this.config.get('uploads').media.extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
get contentTypes() {
|
||||||
|
return this.config.get('uploads').media.contentTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
directories = ['media', 'content'];
|
||||||
|
|
||||||
|
async loadFile(files, baseDir) {
|
||||||
|
const baseDirRegex = baseDir ? new RegExp('^' + baseDir + '/') : new RegExp('');
|
||||||
|
|
||||||
|
const mediaFolderRegexes = _.map(this.storage.staticFileURLPrefix.split('/'), function (dir) {
|
||||||
|
return new RegExp('^' + dir + '/');
|
||||||
|
});
|
||||||
|
|
||||||
|
// normalize the directory structure
|
||||||
|
const mediaContentPath = this.config.getContentPath('media');
|
||||||
|
files = _.map(files, function (file) {
|
||||||
|
const noBaseDir = file.name.replace(baseDirRegex, '');
|
||||||
|
let noGhostDirs = noBaseDir;
|
||||||
|
|
||||||
|
_.each(mediaFolderRegexes, function (regex) {
|
||||||
|
noGhostDirs = noGhostDirs.replace(regex, '');
|
||||||
|
});
|
||||||
|
|
||||||
|
file.originalPath = noBaseDir;
|
||||||
|
file.name = noGhostDirs;
|
||||||
|
file.targetDir = path.join(mediaContentPath, path.dirname(noGhostDirs));
|
||||||
|
return file;
|
||||||
|
});
|
||||||
|
|
||||||
|
const self = this;
|
||||||
|
return Promise.all(files.map(function (image) {
|
||||||
|
return self.storage.getUniqueFileName(image, image.targetDir).then(function (targetFilename) {
|
||||||
|
image.newPath = self.urlUtils.urlJoin('/', self.urlUtils.getSubdir(), self.storage.staticFileURLPrefix,
|
||||||
|
path.relative(self.config.getContentPath('media'), targetFilename));
|
||||||
|
|
||||||
|
return image;
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ImporterMediaHandler;
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@tryghost/importer-media",
|
"name": "@tryghost/importer-handler-media",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"repository": "https://github.com/TryGhost/Ghost/tree/main/packages/importer-media",
|
"repository": "https://github.com/TryGhost/Ghost/tree/main/packages/importer-handler-media",
|
||||||
"author": "Ghost Foundation",
|
"author": "Ghost Foundation",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.js",
|
"main": "index.js",
|
112
ghost/importer-handler-media/test/ImporterMediaHandler.test.js
Normal file
112
ghost/importer-handler-media/test/ImporterMediaHandler.test.js
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
const assert = require('assert');
|
||||||
|
const sinon = require('sinon');
|
||||||
|
const ImporterMedia = require('../index');
|
||||||
|
|
||||||
|
describe('ImporterMediaHandler', function () {
|
||||||
|
it('creates an instance', function () {
|
||||||
|
const mediaImporter = new ImporterMedia({
|
||||||
|
storage: {},
|
||||||
|
config: {},
|
||||||
|
urlUtils: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.ok(mediaImporter);
|
||||||
|
assert.equal(mediaImporter.type, 'media');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns configured extensions', function () {
|
||||||
|
const mediaImporter = new ImporterMedia({
|
||||||
|
storage: {},
|
||||||
|
config: {
|
||||||
|
get: () => ({
|
||||||
|
media: {
|
||||||
|
extensions: ['mp4']
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
urlUtils: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.deepEqual(mediaImporter.extensions, ['mp4']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns configured contentTypes', function () {
|
||||||
|
const mediaImporter = new ImporterMedia({
|
||||||
|
storage: {},
|
||||||
|
config: {
|
||||||
|
get: () => ({
|
||||||
|
media: {
|
||||||
|
contentTypes: ['video/mp4']
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
urlUtils: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.deepEqual(mediaImporter.contentTypes, ['video/mp4']);
|
||||||
|
});
|
||||||
|
|
||||||
|
// @NOTE: below tests need more work, they are just covering the basics
|
||||||
|
// the cases are based on a fact that the implementation was a copy
|
||||||
|
// from the image importer and the tests were adapted to the media importer
|
||||||
|
describe('loadFile', function () {
|
||||||
|
it('loads files and decorates them with newPath with subdirectory', async function () {
|
||||||
|
const mediaImporter = new ImporterMedia({
|
||||||
|
storage: {
|
||||||
|
staticFileURLPrefix: 'content/media',
|
||||||
|
getUniqueFileName: (file, targetDir) => Promise.resolve(targetDir + '/' + file.name)
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
getContentPath: sinon.stub()
|
||||||
|
.withArgs('media')
|
||||||
|
.returns('/var/www/ghost/content/media')
|
||||||
|
},
|
||||||
|
urlUtils: {
|
||||||
|
getSubdir: () => 'blog',
|
||||||
|
urlJoin: (...args) => args.join('/')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const files = [{
|
||||||
|
name: 'content/media/1.mp4'
|
||||||
|
}];
|
||||||
|
const subDir = 'blog';
|
||||||
|
|
||||||
|
await mediaImporter.loadFile(files, subDir);
|
||||||
|
|
||||||
|
assert.equal(files[0].name, '1.mp4');
|
||||||
|
assert.equal(files[0].originalPath, 'content/media/1.mp4');
|
||||||
|
assert.equal(files[0].targetDir, '/var/www/ghost/content/media');
|
||||||
|
assert.equal(files[0].newPath, '//blog/content/media/1.mp4');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('loads files and decorates them with newPath with NO subdirectory', async function () {
|
||||||
|
const mediaImporter = new ImporterMedia({
|
||||||
|
storage: {
|
||||||
|
staticFileURLPrefix: 'content/media',
|
||||||
|
getUniqueFileName: (file, targetDir) => Promise.resolve(targetDir + '/' + file.name)
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
getContentPath: sinon.stub()
|
||||||
|
.withArgs('media')
|
||||||
|
.returns('/var/www/ghost/content/media')
|
||||||
|
},
|
||||||
|
urlUtils: {
|
||||||
|
getSubdir: () => 'blog',
|
||||||
|
urlJoin: (...args) => args.join('/')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const files = [{
|
||||||
|
name: 'content/media/1.mp4'
|
||||||
|
}];
|
||||||
|
|
||||||
|
await mediaImporter.loadFile(files);
|
||||||
|
|
||||||
|
assert.equal(files[0].name, '1.mp4');
|
||||||
|
assert.equal(files[0].originalPath, 'content/media/1.mp4');
|
||||||
|
assert.equal(files[0].targetDir, '/var/www/ghost/content/media');
|
||||||
|
assert.equal(files[0].newPath, '//blog/content/media/1.mp4');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1 +0,0 @@
|
||||||
module.exports = require('./lib/importer-media');
|
|
|
@ -1,8 +0,0 @@
|
||||||
const assert = require('assert');
|
|
||||||
|
|
||||||
describe('Hello world', function () {
|
|
||||||
it('Runs a test', function () {
|
|
||||||
// TODO: Write me!
|
|
||||||
assert.ok(require('../index'));
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Add table
Reference in a new issue