mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Added thumbnail upload endpoint to Media API
closes https://github.com/TryGhost/Toolbox/issues/120 - Allows to update and upload brand new thumbnail images for previusly uploaded media resources - The endpoint is available udner alpa flag as part of Admin API at `PUT /media/thumbnail/` - As an input accepts following parameters: - *required* `file` field containing an image file - *required* `url` field containing parent media file URL - *optional* `ref` as a field to put in an ID to reference the resource on the client side - The response has following format: ``` { media: [{ url: 'http://127.0.0.1:2369/content/images/1991/11/nicevideo_thumb.png' ref: 'unique-id-420' }] } ```
This commit is contained in:
parent
2a7ef77a7b
commit
61b82e3ae2
7 changed files with 106 additions and 0 deletions
|
@ -1,3 +1,4 @@
|
|||
const path = require('path');
|
||||
const storage = require('../../adapters/storage');
|
||||
|
||||
module.exports = {
|
||||
|
@ -18,5 +19,24 @@ module.exports = {
|
|||
thumbnailPath
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
uploadThumbnail: {
|
||||
permissions: false,
|
||||
options: [
|
||||
'url'
|
||||
],
|
||||
async query(frame) {
|
||||
const mediaStorage = storage.getStorage('media');
|
||||
const targetDir = path.dirname(mediaStorage.urlToPath(frame.data.url));
|
||||
|
||||
// NOTE: need to cleanup otherwise the parent media name won't match thumb name
|
||||
// due to "unique name" generation during save
|
||||
if (mediaStorage.exists(frame.file.name, targetDir)) {
|
||||
await mediaStorage.delete(frame.file.name, targetDir);
|
||||
}
|
||||
|
||||
return await mediaStorage.save(frame.file, targetDir);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -35,6 +35,10 @@ module.exports = {
|
|||
return require('./members');
|
||||
},
|
||||
|
||||
get media() {
|
||||
return require('./media');
|
||||
},
|
||||
|
||||
get products() {
|
||||
return require('./products');
|
||||
},
|
||||
|
|
8
core/server/api/canary/utils/serializers/input/media.js
Normal file
8
core/server/api/canary/utils/serializers/input/media.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
uploadThumbnail(apiConfig, frame) {
|
||||
const parentFileName = path.basename(frame.data.url, path.extname(frame.data.url));
|
||||
frame.file.name = `${parentFileName}_thumb${frame.file.ext}`;
|
||||
}
|
||||
};
|
|
@ -24,5 +24,14 @@ module.exports = {
|
|||
ref: frame.data.ref || null
|
||||
}]
|
||||
};
|
||||
},
|
||||
|
||||
uploadThumbnail(path, apiConfig, frame) {
|
||||
return frame.response = {
|
||||
media: [{
|
||||
url: getURL(path),
|
||||
ref: frame.data.ref || null
|
||||
}]
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,5 +3,9 @@ const limitService = require('../../../../../services/limits');
|
|||
module.exports = {
|
||||
async upload(apiConfig, frame) {
|
||||
await limitService.errorIfIsOverLimit('uploads', {currentCount: frame.file.size});
|
||||
},
|
||||
|
||||
async uploadThumbnail(apiConfig, frame) {
|
||||
await limitService.errorIfIsOverLimit('uploads', {currentCount: frame.file.size});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -244,6 +244,13 @@ module.exports = function apiRoutes() {
|
|||
apiMw.upload.mediaValidation({type: 'media'}),
|
||||
http(api.media.upload)
|
||||
);
|
||||
router.put('/media/thumbnail/',
|
||||
labs.enabledMiddleware('mediaAPI'),
|
||||
mw.authAdminApi,
|
||||
apiMw.upload.single('file'),
|
||||
apiMw.upload.validation({type: 'images'}),
|
||||
http(api.media.uploadThumbnail)
|
||||
);
|
||||
|
||||
// ## files
|
||||
router.post('/files/upload',
|
||||
|
|
|
@ -87,5 +87,59 @@ describe('Media API', function () {
|
|||
});
|
||||
|
||||
describe('media/thumbnail/:url', function () {
|
||||
it('Can update existing thumbnail', async function () {
|
||||
const res = await request.post(localUtils.API.getApiQuery('media/upload'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.field('purpose', 'video')
|
||||
.field('ref', 'https://ghost.org/sample_640x360.mp4')
|
||||
.attach('file', path.join(__dirname, '/../../utils/fixtures/media/sample_640x360.mp4'))
|
||||
.attach('thumbnail', path.join(__dirname, '/../../utils/fixtures/images/ghost-logo.png'))
|
||||
.expect(201);
|
||||
|
||||
res.body.media[0].ref.should.equal('https://ghost.org/sample_640x360.mp4');
|
||||
|
||||
media.push(res.body.media[0].url.replace(config.get('url'), ''));
|
||||
media.push(res.body.media[0].thumbnail_url.replace(config.get('url'), ''));
|
||||
|
||||
const thumbnailRes = await request.put(localUtils.API.getApiQuery(`media/thumbnail/`))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.field('url', res.body.media[0].url)
|
||||
.field('ref', 'updated_thumbnail')
|
||||
.attach('file', path.join(__dirname, '/../../utils/fixtures/images/ghosticon.jpg'))
|
||||
.expect(200);
|
||||
|
||||
const thumbnailUrl = res.body.media[0].url.replace('.mp4', '_thumb.jpg');
|
||||
thumbnailRes.body.media[0].url.should.equal(thumbnailUrl);
|
||||
thumbnailRes.body.media[0].ref.should.equal('updated_thumbnail');
|
||||
media.push(thumbnailRes.body.media[0].url.replace(config.get('url'), ''));
|
||||
});
|
||||
|
||||
it('Can create new thumbnail based on parent media URL without existing thumbnail', async function () {
|
||||
const res = await request.post(localUtils.API.getApiQuery('media/upload'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.field('purpose', 'video')
|
||||
.field('ref', 'https://ghost.org/sample_640x360.mp4')
|
||||
.attach('file', path.join(__dirname, '/../../utils/fixtures/media/sample_640x360.mp4'))
|
||||
.expect(201);
|
||||
|
||||
media.push(res.body.media[0].url.replace(config.get('url'), ''));
|
||||
|
||||
const thumbnailRes = await request.put(localUtils.API.getApiQuery(`media/thumbnail/`))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.field('url', res.body.media[0].url)
|
||||
.field('ref', 'updated_thumbnail_2')
|
||||
.attach('file', path.join(__dirname, '/../../utils/fixtures/images/ghosticon.jpg'))
|
||||
.expect(200);
|
||||
|
||||
const thumbnailUrl = res.body.media[0].url.replace('.mp4', '_thumb.jpg');
|
||||
thumbnailRes.body.media[0].url.should.equal(thumbnailUrl);
|
||||
thumbnailRes.body.media[0].ref.should.equal('updated_thumbnail_2');
|
||||
|
||||
media.push(thumbnailRes.body.media[0].url.replace(config.get('url'), ''));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue