0
Fork 0
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:
Naz 2021-11-09 16:05:18 +04:00
parent ce63b87b2e
commit 2a7ef77a7b
5 changed files with 67 additions and 7 deletions

View file

@ -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
});
}

View file

@ -19,6 +19,7 @@ class LocalImagesStorage extends LocalStorageBase {
super({
storagePath: config.getContentPath('images'),
staticFileURLPrefix: urlUtils.STATIC_IMAGE_URL_PREFIX,
siteUrl: config.getSiteUrl(),
errorMessages: messages
});
}

View file

@ -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
});
}

View file

@ -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);
}
/**

View 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.');
}
});
});
});