mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Added ability to delete existing files through storage adapters
refs https://github.com/TryGhost/Toolbox/issues/120 - When editing an uploaded media thumbnail file there'a need to remove existing thumbnail to keep media files:thumbnails 1:1. - Because the API client only has a public URL under which the resource is served it can only provide that as an API input, the `urlToPath` was also added to the base class of LocalStorageAdapter (it might be moved up to the BaseAdapter in the future if we see a need)
This commit is contained in:
parent
ce63b87b2e
commit
2a7ef77a7b
5 changed files with 67 additions and 7 deletions
|
@ -1,4 +1,4 @@
|
|||
// # Local File System Video Storage module
|
||||
// # Local File System Storage module
|
||||
// The (default) module for storing media, using the local file system
|
||||
const config = require('../../../shared/config');
|
||||
const constants = require('@tryghost/constants');
|
||||
|
@ -8,6 +8,7 @@ class LocalFilesStorage extends LocalStorageBase {
|
|||
constructor() {
|
||||
super({
|
||||
storagePath: config.getContentPath('files'),
|
||||
siteUrl: config.getSiteUrl(),
|
||||
staticFileURLPrefix: constants.STATIC_FILES_URL_PREFIX
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ class LocalImagesStorage extends LocalStorageBase {
|
|||
super({
|
||||
storagePath: config.getContentPath('images'),
|
||||
staticFileURLPrefix: urlUtils.STATIC_IMAGE_URL_PREFIX,
|
||||
siteUrl: config.getSiteUrl(),
|
||||
errorMessages: messages
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// # Local File System Video Storage module
|
||||
// # Local File System Media Storage module
|
||||
// The (default) module for storing media, using the local file system
|
||||
const config = require('../../../shared/config');
|
||||
const constants = require('@tryghost/constants');
|
||||
|
@ -15,6 +15,7 @@ class LocalMediaStore extends LocalStorageBase {
|
|||
super({
|
||||
storagePath: config.getContentPath('media'),
|
||||
staticFileURLPrefix: constants.STATIC_MEDIA_URL_PREFIX,
|
||||
siteUrl: config.getSiteUrl(),
|
||||
errorMessages: messages
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ const StorageBase = require('ghost-storage-base');
|
|||
const messages = {
|
||||
notFound: 'File not found',
|
||||
notFoundWithRef: 'File not found: {file}',
|
||||
cannotRead: 'Could not read file: {file}'
|
||||
cannotRead: 'Could not read file: {file}',
|
||||
invalidUrlParameter: `The URL "{url}" is not a valid URL for this site.`
|
||||
};
|
||||
|
||||
class LocalStorageBase extends StorageBase {
|
||||
|
@ -24,17 +25,20 @@ class LocalStorageBase extends StorageBase {
|
|||
*
|
||||
* @param {Object} options
|
||||
* @param {String} options.storagePath
|
||||
* @param {String} options.siteUrl
|
||||
* @param {String} [options.staticFileURLPrefix]
|
||||
* @param {Object} [options.errorMessages]
|
||||
* @param {String} [options.errorMessages.notFound]
|
||||
* @param {String} [options.errorMessages.notFoundWithRef]
|
||||
* @param {String} [options.errorMessages.cannotRead]
|
||||
*/
|
||||
constructor({storagePath, staticFileURLPrefix, errorMessages}) {
|
||||
constructor({storagePath, staticFileURLPrefix, siteUrl, errorMessages}) {
|
||||
super();
|
||||
|
||||
this.storagePath = storagePath;
|
||||
this.staticFileURLPrefix = staticFileURLPrefix;
|
||||
this.siteUrl = siteUrl;
|
||||
this.staticFileUrl = `${siteUrl}${staticFileURLPrefix}`;
|
||||
this.errorMessages = errorMessages || messages;
|
||||
}
|
||||
|
||||
|
@ -71,6 +75,26 @@ class LocalStorageBase extends StorageBase {
|
|||
return fullUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} url full url under which the stored content is served, result of save method
|
||||
* @returns {String} path under which the content is stored
|
||||
*/
|
||||
urlToPath(url) {
|
||||
let filePath;
|
||||
|
||||
if (url.match(this.staticFileUrl)) {
|
||||
filePath = url.replace(this.staticFileUrl, '');
|
||||
filePath = path.join(this.storagePath, filePath);
|
||||
} else {
|
||||
throw new errors.IncorrectUsageError({
|
||||
message: tpl(messages.invalidUrlParameter, {url})
|
||||
});
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
exists(fileName, targetDir) {
|
||||
const filePath = path.join(targetDir || this.storagePath, fileName);
|
||||
|
||||
|
@ -132,11 +156,12 @@ class LocalStorageBase extends StorageBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Not implemented.
|
||||
* @param {String} filePath
|
||||
* @returns {Promise.<*>}
|
||||
*/
|
||||
delete() {
|
||||
return Promise.reject('not implemented');
|
||||
async delete(fileName, targetDir) {
|
||||
const filePath = path.join(targetDir, fileName);
|
||||
return await fs.remove(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
32
test/unit/server/adapters/storage/LocalBaseStorage.test.js
Normal file
32
test/unit/server/adapters/storage/LocalBaseStorage.test.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
const should = require('should');
|
||||
const LocalStorageBase = require('../../../../../core/server/adapters/storage/LocalStorageBase');
|
||||
|
||||
describe('Local Storage Base', function () {
|
||||
describe('urlToPath', function () {
|
||||
it('returns path from url', function () {
|
||||
let localStorageBase = new LocalStorageBase({
|
||||
storagePath: '/media-storage/path/',
|
||||
staticFileURLPrefix: 'content/media',
|
||||
siteUrl: 'http://example.com/blog/'
|
||||
});
|
||||
|
||||
localStorageBase.urlToPath('http://example.com/blog/content/media/2021/11/media.mp4')
|
||||
.should.eql('/media-storage/path/2021/11/media.mp4');
|
||||
});
|
||||
|
||||
it('throws if the url does not match current site', function () {
|
||||
let localStorageBase = new LocalStorageBase({
|
||||
storagePath: '/media-storage/path/',
|
||||
staticFileURLPrefix: 'content/media',
|
||||
url: 'http://example.com/blog/'
|
||||
});
|
||||
|
||||
try {
|
||||
localStorageBase.urlToPath('http://anothersite.com/blog/content/media/2021/11/media.mp4');
|
||||
should.fail('urlToPath when urls do not match');
|
||||
} catch (error) {
|
||||
error.message.should.eql('The URL "http://anothersite.com/blog/content/media/2021/11/media.mp4" is not a valid URL for this site.');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue