Delete all content (posts and tags)

closes #1445
- added delete button to ‚ugly debug tools‘
- added api call to delete all content
- added /db to cache invalidation routes
This commit is contained in:
Sebastian Gierlinger 2013-12-25 01:05:20 +01:00
parent aec94f2ad1
commit 691c8cd5a9
7 changed files with 117 additions and 17 deletions

View File

@ -4,7 +4,8 @@
Ghost.Views.Debug = Ghost.View.extend({ Ghost.Views.Debug = Ghost.View.extend({
events: { events: {
"click .settings-menu a": "handleMenuClick" "click .settings-menu a": "handleMenuClick",
"click .js-delete": "handleDeleteClick"
}, },
handleMenuClick: function (ev) { handleMenuClick: function (ev) {
@ -19,7 +20,68 @@
this.$("#debug-" + $target.attr("class")).show(); this.$("#debug-" + $target.attr("class")).show();
return false; return false;
},
handleDeleteClick: function (ev) {
ev.preventDefault();
this.addSubview(new Ghost.Views.Modal({
model: {
options: {
close: true,
confirm: {
accept: {
func: function () {
$.ajax({
url: Ghost.paths.apiRoot + '/db/',
type: 'DELETE',
headers: {
'X-CSRF-Token': $("meta[name='csrf-param']").attr('content')
},
success: function onSuccess(response) {
if (!response) {
throw new Error('No response received from server.');
}
if (!response.message) {
throw new Error(response.detail || 'Unknown error');
}
Ghost.notifications.addItem({
type: 'success',
message: response.message,
status: 'passive'
});
},
error: function onError(response) {
var responseText = JSON.parse(response.responseText),
message = responseText && responseText.error ? responseText.error : 'unknown';
Ghost.notifications.addItem({
type: 'error',
message: ['A problem was encountered while deleting content from your blog. Error: ', message].join(''),
status: 'passive'
});
}
});
},
text: "Yes"
},
reject: {
func: function () {
return true;
},
text: "No"
}
},
type: "action",
style: ["wide", "centered"],
animation: 'fade'
},
content: {
template: 'blank',
title: 'Would you really like to delete all content from your blog?'
}
}
}));
} }
}); });
}()); }());

View File

@ -1,15 +1,16 @@
var dataExport = require('../data/export'), var dataExport = require('../data/export'),
dataImport = require('../data/import'), dataImport = require('../data/import'),
apiNotifications = require('./notifications'), dataProvider = require('../models'),
apiSettings = require('./settings'), apiNotifications = require('./notifications'),
fs = require('fs-extra'), apiSettings = require('./settings'),
path = require('path'), fs = require('fs-extra'),
when = require('when'), path = require('path'),
nodefn = require('when/node/function'), when = require('when'),
_ = require('underscore'), nodefn = require('when/node/function'),
schema = require('../data/schema'), _ = require('underscore'),
config = require('../config'), schema = require('../data/schema'),
debugPath = config.paths().webroot + '/ghost/debug/', config = require('../config'),
debugPath = config.paths().webroot + '/ghost/debug/',
db; db;
@ -158,6 +159,14 @@ db = {
}); });
}); });
}); });
},
'deleteAllContent': function () {
return when(dataProvider.deleteAllContent())
.then(function () {
return when.resolve({message: 'Successfully deleted all content from your blog.'});
}, function (error) {
return when.reject({errorCode: 500, message: error.message || error});
});
} }
}; };

View File

@ -26,7 +26,7 @@ function invalidateCache(req, res, result) {
jsonResult = result.toJSON ? result.toJSON() : result; jsonResult = result.toJSON ? result.toJSON() : result;
if (method === 'POST' || method === 'PUT' || method === 'DELETE') { if (method === 'POST' || method === 'PUT' || method === 'DELETE') {
if (endpoint === 'settings' || endpoint === 'users') { if (endpoint === 'settings' || endpoint === 'users' || endpoint === 'db') {
cacheInvalidate = "/*"; cacheInvalidate = "/*";
} else if (endpoint === 'posts') { } else if (endpoint === 'posts') {
cacheInvalidate = "/, /page/*, /rss/, /rss/*"; cacheInvalidate = "/, /page/*, /rss/, /rss/*";

View File

@ -11,7 +11,8 @@ function ghostBusBoy(req, res, next) {
tmpDir, tmpDir,
hasError = false; hasError = false;
if (req.method && req.method.match(/get/i)) { // busboy is only used for POST requests
if (req.method && !req.method.match(/post/i)) {
return next(); return next();
} }

View File

@ -1,4 +1,5 @@
var migrations = require('../data/migration'); var migrations = require('../data/migration'),
_ = require('underscore');
module.exports = { module.exports = {
Post: require('./post').Post, Post: require('./post').Post,
@ -18,6 +19,23 @@ module.exports = {
return migrations.init(); return migrations.init();
}); });
}, },
// ### deleteAllContent
// Delete all content from the database (posts, tags, tags_posts)
deleteAllContent: function () {
var self = this;
return self.Post.browse().then(function (posts) {
_.each(posts.toJSON(), function (post) {
self.Post.destroy(post.id);
});
}).then(function () {
self.Tag.browse().then(function (tags) {
_.each(tags.toJSON(), function (tag) {
self.Tag.destroy(tag.id);
});
});
});
},
isPost: function (jsonData) { isPost: function (jsonData) {
return jsonData.hasOwnProperty('html') && jsonData.hasOwnProperty('markdown') return jsonData.hasOwnProperty('html') && jsonData.hasOwnProperty('markdown')
&& jsonData.hasOwnProperty('title') && jsonData.hasOwnProperty('slug'); && jsonData.hasOwnProperty('title') && jsonData.hasOwnProperty('slug');

View File

@ -26,4 +26,5 @@ module.exports = function (server) {
// #### Import/Export // #### Import/Export
server.get('/ghost/api/v0.1/db/', middleware.auth, api.db['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.post('/ghost/api/v0.1/db/', middleware.auth, api.db['import']);
server.del('/ghost/api/v0.1/db/', middleware.authAPI, middleware.disableCachedResult, api.requestHandler(api.db.deleteAllContent));
}; };

View File

@ -36,6 +36,15 @@
</div> </div>
</fieldset> </fieldset>
</form> </form>
<form id="settings-resetdb">
<fieldset>
<div class="form-group">
<label>Delete all Content</label>
<a href="javascript:void(0);" class="button-delete js-delete">Delete</a>
<p>Delete all posts and tags from the database.</p>
</div>
</fieldset>
</form>
</section> </section>
</section> </section>
</div> </div>