mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 03:44:29 +03:00
Merge pull request #1860 from sebgie/issue#1854
This commit is contained in:
commit
80eac65e9b
@ -8,6 +8,59 @@
|
||||
"click .js-delete": "handleDeleteClick"
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
// Disable import button and initizalize BlueImp file upload
|
||||
$('#startupload').prop('disabled', true);
|
||||
$('#importfile').fileupload({
|
||||
url: Ghost.paths.apiRoot + '/db/',
|
||||
limitMultiFileUploads: 1,
|
||||
replaceFileInput: false,
|
||||
headers: {
|
||||
'X-CSRF-Token': $("meta[name='csrf-param']").attr('content')
|
||||
},
|
||||
dataType: 'json',
|
||||
add: function (e, data) {
|
||||
/*jslint unparam:true*/
|
||||
data.context = $('#startupload').prop('disabled', false)
|
||||
.click(function () {
|
||||
$('#startupload').prop('disabled', true);
|
||||
data.context = $('#startupload').text('Importing');
|
||||
data.submit();
|
||||
// unregister click event to allow different subsequent uploads
|
||||
$('#startupload').off('click');
|
||||
});
|
||||
},
|
||||
done: function (e, data) {
|
||||
/*jslint unparam:true*/
|
||||
$('#startupload').text('Import');
|
||||
if (!data.result) {
|
||||
throw new Error('No response received from server.');
|
||||
}
|
||||
if (!data.result.message) {
|
||||
throw new Error('Unknown error');
|
||||
}
|
||||
|
||||
Ghost.notifications.addItem({
|
||||
type: 'success',
|
||||
message: data.result.message,
|
||||
status: 'passive'
|
||||
});
|
||||
},
|
||||
error: function (response) {
|
||||
$('#startupload').text('Import');
|
||||
var responseJSON = response.responseJSON,
|
||||
message = responseJSON && responseJSON.error ? responseJSON.error : 'unknown';
|
||||
Ghost.notifications.addItem({
|
||||
type: 'error',
|
||||
message: ['A problem was encountered while importing new content to your blog. Error: ', message].join(''),
|
||||
status: 'passive'
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
handleMenuClick: function (ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
@ -21,6 +74,7 @@
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
handleDeleteClick: function (ev) {
|
||||
ev.preventDefault();
|
||||
this.addSubview(new Ghost.Views.Modal({
|
||||
|
@ -16,7 +16,7 @@ api.notifications = require('./notifications');
|
||||
api.settings = require('./settings');
|
||||
|
||||
db = {
|
||||
'export': function (req, res) {
|
||||
'exportContent': function (req, res) {
|
||||
/*jslint unparam:true*/
|
||||
return dataExport().then(function (exportedData) {
|
||||
// Save the exported data to the file system for download
|
||||
@ -44,11 +44,10 @@ db = {
|
||||
});
|
||||
});
|
||||
},
|
||||
'import': function (req, res) {
|
||||
var notification,
|
||||
databaseVersion;
|
||||
'importContent': function (options) {
|
||||
var databaseVersion;
|
||||
|
||||
if (!req.files.importfile || !req.files.importfile.path || req.files.importfile.name.indexOf('json') === -1) {
|
||||
if (!options.importfile || !options.importfile.path || options.importfile.name.indexOf('json') === -1) {
|
||||
/**
|
||||
* Notify of an error if it occurs
|
||||
*
|
||||
@ -57,30 +56,17 @@ db = {
|
||||
* - If there is no path
|
||||
* - If the name doesn't have json in it
|
||||
*/
|
||||
return api.notifications.browse().then(function (notifications) {
|
||||
notification = {
|
||||
type: 'error',
|
||||
message: "Must select a .json file to import",
|
||||
status: 'persistent',
|
||||
id: 'per-' + (notifications.length + 1)
|
||||
};
|
||||
|
||||
|
||||
|
||||
return api.notifications.add(notification).then(function () {
|
||||
res.redirect(configPaths().debugPath);
|
||||
});
|
||||
});
|
||||
return when.reject({errorCode: 500, message: 'Please select a .json file to import.'});
|
||||
}
|
||||
|
||||
api.settings.read({ key: 'databaseVersion' }).then(function (setting) {
|
||||
return api.settings.read({ key: 'databaseVersion' }).then(function (setting) {
|
||||
return when(setting.value);
|
||||
}, function () {
|
||||
return when('001');
|
||||
}).then(function (version) {
|
||||
databaseVersion = version;
|
||||
// Read the file contents
|
||||
return nodefn.call(fs.readFile, req.files.importfile.path);
|
||||
return nodefn.call(fs.readFile, options.importfile.path);
|
||||
}).then(function (fileContents) {
|
||||
var importData,
|
||||
error = '',
|
||||
@ -132,32 +118,9 @@ db = {
|
||||
}).then(function importSuccess() {
|
||||
return api.settings.updateSettingsCache();
|
||||
}).then(function () {
|
||||
return api.notifications.browse();
|
||||
}).then(function (notifications) {
|
||||
notification = {
|
||||
type: 'success',
|
||||
message: "Posts, tags and other data successfully imported",
|
||||
status: 'persistent',
|
||||
id: 'per-' + (notifications.length + 1)
|
||||
};
|
||||
|
||||
return api.notifications.add(notification).then(function () {
|
||||
res.redirect(configPaths().debugPath);
|
||||
});
|
||||
return when.resolve({message: 'Posts, tags and other data successfully imported'});
|
||||
}).otherwise(function importFailure(error) {
|
||||
return api.notifications.browse().then(function (notifications) {
|
||||
// Notify of an error if it occurs
|
||||
notification = {
|
||||
type: 'error',
|
||||
message: error.message || error,
|
||||
status: 'persistent',
|
||||
id: 'per-' + (notifications.length + 1)
|
||||
};
|
||||
|
||||
return api.notifications.add(notification).then(function () {
|
||||
res.redirect(configPaths().debugPath);
|
||||
});
|
||||
});
|
||||
return when.reject({errorCode: 500, message: error.message || error});
|
||||
});
|
||||
},
|
||||
'deleteAllContent': function () {
|
||||
|
@ -45,7 +45,7 @@ function cacheInvalidationHeader(req, result) {
|
||||
// takes the API method and wraps it so that it gets data from the request and returns a sensible JSON response
|
||||
requestHandler = function (apiMethod) {
|
||||
return function (req, res) {
|
||||
var options = _.extend(req.body, req.query, req.params),
|
||||
var options = _.extend(req.body, req.files, req.query, req.params),
|
||||
apiContext = {
|
||||
user: req.session && req.session.user
|
||||
};
|
||||
|
@ -233,9 +233,6 @@ module.exports = function (server, dbHash) {
|
||||
expressServer.use(express.json());
|
||||
expressServer.use(express.urlencoded());
|
||||
|
||||
expressServer.use(subdir + '/ghost/upload/', middleware.busboy);
|
||||
expressServer.use(subdir + '/ghost/api/v0.1/db/', middleware.busboy);
|
||||
|
||||
// ### Sessions
|
||||
cookie = {
|
||||
path: subdir + '/ghost',
|
||||
|
@ -43,8 +43,7 @@ module.exports = function (server) {
|
||||
server.get('/ghost/settings*', middleware.auth, admin.settings);
|
||||
server.get('/ghost/debug/', middleware.auth, admin.debug.index);
|
||||
|
||||
// We don't want to register bodyParser globally b/c of security concerns, so use multipart only here
|
||||
server.post('/ghost/upload/', middleware.auth, admin.uploader);
|
||||
server.post('/ghost/upload/', middleware.auth, middleware.busboy, admin.uploader);
|
||||
|
||||
// redirect to /ghost and let that do the authentication to prevent redirects to /ghost//admin etc.
|
||||
server.get(/\/((ghost-admin|admin|wp-admin|dashboard|signin)\/?)$/, function (req, res) {
|
||||
|
@ -24,7 +24,7 @@ module.exports = function (server) {
|
||||
server.del('/ghost/api/v0.1/notifications/:id', middleware.authAPI, api.requestHandler(api.notifications.destroy));
|
||||
server.post('/ghost/api/v0.1/notifications/', middleware.authAPI, api.requestHandler(api.notifications.add));
|
||||
// #### Import/Export
|
||||
server.get('/ghost/api/v0.1/db/', middleware.auth, api.db['export']);
|
||||
server.post('/ghost/api/v0.1/db/', middleware.auth, api.db['import']);
|
||||
server.get('/ghost/api/v0.1/db/', middleware.auth, api.db.exportContent);
|
||||
server.post('/ghost/api/v0.1/db/', middleware.authAPI, middleware.busboy, api.requestHandler(api.db.importContent));
|
||||
server.del('/ghost/api/v0.1/db/', middleware.authAPI, api.requestHandler(api.db.deleteAllContent));
|
||||
};
|
@ -25,13 +25,12 @@
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<form id="settings-import" method="post" action="{{adminUrl}}/api/v0.1/db/" enctype="multipart/form-data">
|
||||
<input type="hidden" name="_csrf" value="{{csrfToken}}" />
|
||||
<form id="settings-import" enctype="multipart/form-data">
|
||||
<fieldset>
|
||||
<div class="form-group">
|
||||
<label>Import</label>
|
||||
<input type="file" class="button-add" name="importfile" />
|
||||
<input type="submit" class="button-save" value="Import" />
|
||||
<input type="file" class="button-add" name="importfile" id="importfile" />
|
||||
<button type="submit" class="button-save" value="Import" id="startupload" >Import</button>
|
||||
<p>Import from another Ghost installation. If you import a user, this will replace the current user & log you out.</p>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
Loading…
Reference in New Issue
Block a user