From 691c8cd5a97ec958a98486b5f59d4c295495a6d8 Mon Sep 17 00:00:00 2001 From: Sebastian Gierlinger Date: Wed, 25 Dec 2013 01:05:20 +0100 Subject: [PATCH] Delete all content (posts and tags) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #1445 - added delete button to ‚ugly debug tools‘ - added api call to delete all content - added /db to cache invalidation routes --- core/client/views/debug.js | 66 +++++++++++++++++++++++++- core/server/api/db.js | 33 ++++++++----- core/server/api/index.js | 2 +- core/server/middleware/ghost-busboy.js | 3 +- core/server/models/index.js | 20 +++++++- core/server/routes/api.js | 1 + core/server/views/debug.hbs | 9 ++++ 7 files changed, 117 insertions(+), 17 deletions(-) diff --git a/core/client/views/debug.js b/core/client/views/debug.js index 21839a8aa0..eaa12ade95 100644 --- a/core/client/views/debug.js +++ b/core/client/views/debug.js @@ -4,7 +4,8 @@ Ghost.Views.Debug = Ghost.View.extend({ events: { - "click .settings-menu a": "handleMenuClick" + "click .settings-menu a": "handleMenuClick", + "click .js-delete": "handleDeleteClick" }, handleMenuClick: function (ev) { @@ -19,7 +20,68 @@ this.$("#debug-" + $target.attr("class")).show(); 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?' + } + } + })); } }); - }()); \ No newline at end of file diff --git a/core/server/api/db.js b/core/server/api/db.js index 03875e6ca8..dcb7b14264 100644 --- a/core/server/api/db.js +++ b/core/server/api/db.js @@ -1,15 +1,16 @@ -var dataExport = require('../data/export'), - dataImport = require('../data/import'), - apiNotifications = require('./notifications'), - apiSettings = require('./settings'), - fs = require('fs-extra'), - path = require('path'), - when = require('when'), - nodefn = require('when/node/function'), - _ = require('underscore'), - schema = require('../data/schema'), - config = require('../config'), - debugPath = config.paths().webroot + '/ghost/debug/', +var dataExport = require('../data/export'), + dataImport = require('../data/import'), + dataProvider = require('../models'), + apiNotifications = require('./notifications'), + apiSettings = require('./settings'), + fs = require('fs-extra'), + path = require('path'), + when = require('when'), + nodefn = require('when/node/function'), + _ = require('underscore'), + schema = require('../data/schema'), + config = require('../config'), + debugPath = config.paths().webroot + '/ghost/debug/', 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}); + }); } }; diff --git a/core/server/api/index.js b/core/server/api/index.js index fce51a45c2..6612019562 100644 --- a/core/server/api/index.js +++ b/core/server/api/index.js @@ -26,7 +26,7 @@ function invalidateCache(req, res, result) { jsonResult = result.toJSON ? result.toJSON() : result; if (method === 'POST' || method === 'PUT' || method === 'DELETE') { - if (endpoint === 'settings' || endpoint === 'users') { + if (endpoint === 'settings' || endpoint === 'users' || endpoint === 'db') { cacheInvalidate = "/*"; } else if (endpoint === 'posts') { cacheInvalidate = "/, /page/*, /rss/, /rss/*"; diff --git a/core/server/middleware/ghost-busboy.js b/core/server/middleware/ghost-busboy.js index fc9246cfda..20fcbc6883 100644 --- a/core/server/middleware/ghost-busboy.js +++ b/core/server/middleware/ghost-busboy.js @@ -11,7 +11,8 @@ function ghostBusBoy(req, res, next) { tmpDir, 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(); } diff --git a/core/server/models/index.js b/core/server/models/index.js index 8b633f0bd4..a01f51af1b 100644 --- a/core/server/models/index.js +++ b/core/server/models/index.js @@ -1,4 +1,5 @@ -var migrations = require('../data/migration'); +var migrations = require('../data/migration'), + _ = require('underscore'); module.exports = { Post: require('./post').Post, @@ -18,6 +19,23 @@ module.exports = { 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) { return jsonData.hasOwnProperty('html') && jsonData.hasOwnProperty('markdown') && jsonData.hasOwnProperty('title') && jsonData.hasOwnProperty('slug'); diff --git a/core/server/routes/api.js b/core/server/routes/api.js index 3f99d73c55..6b39b002e6 100644 --- a/core/server/routes/api.js +++ b/core/server/routes/api.js @@ -26,4 +26,5 @@ module.exports = function (server) { // #### 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.del('/ghost/api/v0.1/db/', middleware.authAPI, middleware.disableCachedResult, api.requestHandler(api.db.deleteAllContent)); }; \ No newline at end of file diff --git a/core/server/views/debug.hbs b/core/server/views/debug.hbs index e276c3e033..b5b1b6af11 100644 --- a/core/server/views/debug.hbs +++ b/core/server/views/debug.hbs @@ -36,6 +36,15 @@ +
+
+
+ + Delete +

Delete all posts and tags from the database.

+
+
+