forked from projects/fipamo
back up method restores public blog images, site settings and markdown pages
This commit is contained in:
parent
1fa21322fb
commit
11b93e3451
8 changed files with 86 additions and 67 deletions
|
@ -4,7 +4,6 @@ import Render from '../../data/Render';
|
||||||
import Settings, { SETTINGS_FILE, SETTINGS_FOLKS } from '../../data/Settings';
|
import Settings, { SETTINGS_FILE, SETTINGS_FOLKS } from '../../data/Settings';
|
||||||
import Navigation from '../../data/Navigation';
|
import Navigation from '../../data/Navigation';
|
||||||
import Book from '../../data/Book';
|
import Book from '../../data/Book';
|
||||||
import Utils from '../../data/Utils';
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const multer = require('multer');
|
const multer = require('multer');
|
||||||
|
@ -16,7 +15,6 @@ const render = new Render();
|
||||||
const book = new Book();
|
const book = new Book();
|
||||||
const settings = new Settings();
|
const settings = new Settings();
|
||||||
const nav = new Navigation();
|
const nav = new Navigation();
|
||||||
const utils = new Utils();
|
|
||||||
const uploadPath =
|
const uploadPath =
|
||||||
'./public/assets/images/user/' + moment().format('YYYY') + '/' + moment().format('MM');
|
'./public/assets/images/user/' + moment().format('YYYY') + '/' + moment().format('MM');
|
||||||
|
|
||||||
|
@ -208,51 +206,6 @@ router.post('/add-feature-background', background_upload, (req, res) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/***
|
|
||||||
CREATE BACK UP
|
|
||||||
*/
|
|
||||||
router.post('/create-backup', (req, res) => {
|
|
||||||
auth.authCheck(req)
|
|
||||||
.then(() => {
|
|
||||||
utils
|
|
||||||
.createBackup()
|
|
||||||
.then(() => {
|
|
||||||
res.json({
|
|
||||||
type: DataEvent.API_BACKUP_CREATE,
|
|
||||||
message: "You're backed up. Hi fives"
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
res.json({
|
|
||||||
type: err.type,
|
|
||||||
message: err.message
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
res.json({
|
|
||||||
type: err.type,
|
|
||||||
message: err.message
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/download-backup', (req, res) => {
|
|
||||||
if (req.session.user) {
|
|
||||||
var filePath = 'content/backup.zip'; // Or format the path using the `id` rest param
|
|
||||||
var fileName = 'backup.zip'; // The default name the browser will use
|
|
||||||
|
|
||||||
res.download(filePath, fileName);
|
|
||||||
} else {
|
|
||||||
res.json({
|
|
||||||
type: DataEvent.REQUEST_LAME,
|
|
||||||
message: "You're not logged in, champ"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//Move to route?
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
||||||
function getBookData() {
|
function getBookData() {
|
||||||
|
|
|
@ -51,12 +51,14 @@ var pages = require('./api/v1/pages');
|
||||||
var setting = require('./api/v1/settings');
|
var setting = require('./api/v1/settings');
|
||||||
var mailer = require('./api/v1/mailer');
|
var mailer = require('./api/v1/mailer');
|
||||||
var auth = require('./api/v1/auth');
|
var auth = require('./api/v1/auth');
|
||||||
|
var backup = require('./api/v1/backup');
|
||||||
// API PATHS
|
// API PATHS
|
||||||
|
|
||||||
app.use('/api/v1/page', pages);
|
app.use('/api/v1/page', pages);
|
||||||
app.use('/api/v1/settings', setting);
|
app.use('/api/v1/settings', setting);
|
||||||
app.use('/api/v1/auth', auth);
|
app.use('/api/v1/auth', auth);
|
||||||
app.use('/api/v1/mailer', mailer);
|
app.use('/api/v1/mailer', mailer);
|
||||||
|
app.use('/api/v1/backup', backup);
|
||||||
// PAGES
|
// PAGES
|
||||||
app.use('/@/dashboard', dash);
|
app.use('/@/dashboard', dash);
|
||||||
app.use('/@/dashboard/page', page);
|
app.use('/@/dashboard/page', page);
|
||||||
|
|
|
@ -136,12 +136,12 @@ export default class Utils {
|
||||||
var response;
|
var response;
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
var zip = new AdmZip();
|
var zip = new AdmZip();
|
||||||
zip.addLocalFolder('public', 'public/');
|
zip.addLocalFolder('public/assets/images/blog', 'public/assets/images/blog');
|
||||||
zip.addLocalFolder('content/pages', 'pages/');
|
zip.addLocalFolder('content/pages', 'content/pages/');
|
||||||
zip.addLocalFile('site/folks.json', 'settings/');
|
zip.addLocalFile('site/folks.json', 'settings/');
|
||||||
zip.addLocalFile('site/settings.json', 'settings/');
|
zip.addLocalFile('site/settings.json', 'settings/');
|
||||||
zip.addLocalFile('site/tags.json', 'settings/');
|
zip.addLocalFile('site/tags.json', 'settings/');
|
||||||
zip.writeZip('public/backup.zip');
|
zip.writeZip('content/backup.zip');
|
||||||
fs.readJSON('site/settings.json').then(settings => {
|
fs.readJSON('site/settings.json').then(settings => {
|
||||||
settings.global.last_backup = moment(Date.now()).format();
|
settings.global.last_backup = moment(Date.now()).format();
|
||||||
fs.writeJSON('site/settings.json', settings);
|
fs.writeJSON('site/settings.json', settings);
|
||||||
|
@ -155,4 +155,41 @@ export default class Utils {
|
||||||
resolve(response);
|
resolve(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restoreBackup(file) {
|
||||||
|
//var response;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
var zip = new AdmZip(file.buffer);
|
||||||
|
zip.extractEntryTo('settings/settings.json', 'site', false, true);
|
||||||
|
zip.extractEntryTo('settings/folks.json', 'site', false, true);
|
||||||
|
zip.extractEntryTo('settings/tags.json', 'site', false, true);
|
||||||
|
zip.getEntries().forEach(function (entry) {
|
||||||
|
var entryName = entry.entryName;
|
||||||
|
var list = entryName.split('/');
|
||||||
|
if (list[0] === 'public') {
|
||||||
|
if (list[6]) {
|
||||||
|
zip.extractEntryTo(
|
||||||
|
entryName,
|
||||||
|
'public/assets/images/blog/' + list[4] + '/' + list[5],
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (list[0] === 'content') {
|
||||||
|
if (list[4]) {
|
||||||
|
zip.extractEntryTo(
|
||||||
|
entryName,
|
||||||
|
'content/pages/' + list[2] + '/' + list[3],
|
||||||
|
false,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
zip.extractEntryTo('content/pages/index.md', 'content/pages', false, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,10 +48,13 @@ block main-content
|
||||||
-if(settings.global.last_backup != null)
|
-if(settings.global.last_backup != null)
|
||||||
.backup-meta
|
.backup-meta
|
||||||
| The last back up was created
|
| The last back up was created
|
||||||
a(href='/api/v1/settings/download-backup')= last_backup
|
a(href='/api/v1/backup/download')= last_backup
|
||||||
|
br
|
||||||
-else
|
-else
|
||||||
br
|
br
|
||||||
span No back ups. Frowny face.
|
span No back ups. Frowny face.
|
||||||
|
button#restore-backup(for='backup-upload') RESTORE BACKUP
|
||||||
|
input(id="backup-upload" type="file" name="backup-upload")
|
||||||
#util-2.column
|
#util-2.column
|
||||||
label MAINTENANCE
|
label MAINTENANCE
|
||||||
#option-settings.columns
|
#option-settings.columns
|
||||||
|
|
|
@ -42,6 +42,9 @@ export default class SettingsIndex {
|
||||||
document.getElementById('background').addEventListener('click', () => {
|
document.getElementById('background').addEventListener('click', () => {
|
||||||
document.getElementById('background-upload').click();
|
document.getElementById('background-upload').click();
|
||||||
});
|
});
|
||||||
|
document.getElementById('restore-backup').addEventListener('click', () => {
|
||||||
|
document.getElementById('backup-upload').click();
|
||||||
|
});
|
||||||
document.getElementById('avatar-upload').addEventListener(
|
document.getElementById('avatar-upload').addEventListener(
|
||||||
'change',
|
'change',
|
||||||
e => {
|
e => {
|
||||||
|
@ -56,6 +59,13 @@ export default class SettingsIndex {
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
document.getElementById('backup-upload').addEventListener(
|
||||||
|
'change',
|
||||||
|
e => {
|
||||||
|
self.handleBackup(e);
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
//handle privacy toggle
|
//handle privacy toggle
|
||||||
//document
|
//document
|
||||||
//.getElementById('privacy-toggle')
|
//.getElementById('privacy-toggle')
|
||||||
|
@ -81,7 +91,6 @@ export default class SettingsIndex {
|
||||||
document
|
document
|
||||||
.getElementById('create-backup')
|
.getElementById('create-backup')
|
||||||
.addEventListener('click', e => this.handleBackup(e));
|
.addEventListener('click', e => this.handleBackup(e));
|
||||||
document.getElementById('get-backup').addEventListener('click', e => this.handleBackup(e));
|
|
||||||
}
|
}
|
||||||
//--------------------------
|
//--------------------------
|
||||||
// event handlers
|
// event handlers
|
||||||
|
@ -177,12 +186,8 @@ export default class SettingsIndex {
|
||||||
handleBackup(e) {
|
handleBackup(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
let task;
|
|
||||||
e.target.id === 'create-backup'
|
|
||||||
? (task = { task: 'create_backup' })
|
|
||||||
: (task = { task: 'get_backup' });
|
|
||||||
admin
|
admin
|
||||||
.handleBackup(task)
|
.handleBackup(e.target.id, e.target.files)
|
||||||
.then(r => {
|
.then(r => {
|
||||||
notify.alert(r.message, true);
|
notify.alert(r.message, true);
|
||||||
})
|
})
|
||||||
|
|
|
@ -29,6 +29,7 @@ export const API_PAGE_DELETE = 'erasingPage';
|
||||||
export const API_SETTINGS_WRITE = 'savingSettings';
|
export const API_SETTINGS_WRITE = 'savingSettings';
|
||||||
export const API_BACKUP_CREATE = 'createBackup';
|
export const API_BACKUP_CREATE = 'createBackup';
|
||||||
export const API_BACKUP_DOWNLOAD = 'downloadBackup';
|
export const API_BACKUP_DOWNLOAD = 'downloadBackup';
|
||||||
|
export const API_BACKUP_RESTORE = 'downloadBackup';
|
||||||
export const API_IMAGES_UPLOAD = 'uploadProfileImages';
|
export const API_IMAGES_UPLOAD = 'uploadProfileImages';
|
||||||
export const API_RENDER_PAGES = 'renderPages';
|
export const API_RENDER_PAGES = 'renderPages';
|
||||||
export const API_INIT = 'blogInit';
|
export const API_INIT = 'blogInit';
|
||||||
|
|
|
@ -18,8 +18,9 @@ export const API_UPLOAD_AVATAR = '/api/v1/settings/add-avatar';
|
||||||
export const API_UPLOAD_BACKGROUND = '/api/v1/settings/add-feature-background';
|
export const API_UPLOAD_BACKGROUND = '/api/v1/settings/add-feature-background';
|
||||||
export const API_PUBLISH_PAGES = '/api/v1/settings/publish-pages';
|
export const API_PUBLISH_PAGES = '/api/v1/settings/publish-pages';
|
||||||
export const API_NAV_SYNC = '/api/v1/settings/nav-sync';
|
export const API_NAV_SYNC = '/api/v1/settings/nav-sync';
|
||||||
export const API_CREATE_BACKUP = '/api/v1/settings/create-backup';
|
export const API_CREATE_BACKUP = '/api/v1/backup/create';
|
||||||
export const API_DOWNLOAD_BACKUP = '/api/v1/settings/download-backup';
|
export const API_DOWNLOAD_BACKUP = '/api/v1/backup/download';
|
||||||
|
export const API_RESTORE_BACKUP = '/api/v1/backup/restore';
|
||||||
export const API_SEND_MAIL = '/api/v1/mailer';
|
export const API_SEND_MAIL = '/api/v1/mailer';
|
||||||
import * as DataEvent from '../com/events/DataEvent';
|
import * as DataEvent from '../com/events/DataEvent';
|
||||||
export default class APIUtils {
|
export default class APIUtils {
|
||||||
|
@ -190,19 +191,32 @@ export default class APIUtils {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
handleBackup(data) {
|
handleBackup(id, files) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var url, event, method;
|
var url, event, method, type, data;
|
||||||
if (data.task === 'create_backup') {
|
|
||||||
|
if (id === 'create-backup') {
|
||||||
url = API_CREATE_BACKUP;
|
url = API_CREATE_BACKUP;
|
||||||
event = DataEvent.API_BACKUP_CREATE;
|
event = DataEvent.API_BACKUP_CREATE;
|
||||||
method = REQUEST_TYPE_POST;
|
method = REQUEST_TYPE_POST;
|
||||||
|
type = CONTENT_TYPE_JSON;
|
||||||
|
data = { task: 'create_backup' };
|
||||||
} else {
|
} else {
|
||||||
url = API_DOWNLOAD_BACKUP;
|
url = API_RESTORE_BACKUP;
|
||||||
event = DataEvent.API_BACKUP_DOWNLOAD;
|
event = DataEvent.API_BACKUP_RESTORE;
|
||||||
method = REQUEST_TYPE_GET;
|
method = REQUEST_TYPE_POST;
|
||||||
|
type = CONTENT_TYPE_FORM;
|
||||||
|
data = new FormData();
|
||||||
|
for (var i = 0; i < files.length; i++) {
|
||||||
|
var file = files[i];
|
||||||
|
// Check the file type.
|
||||||
|
if (!file.type.match('application.zip')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
data.append('backup_upload', file, file.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this._request(url, event, method, CONTENT_TYPE_JSON, data)
|
this._request(url, event, method, type, data)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
resolve(result);
|
resolve(result);
|
||||||
})
|
})
|
||||||
|
@ -242,7 +256,8 @@ export default class APIUtils {
|
||||||
eventType === DataEvent.API_SETTINGS_WRITE ||
|
eventType === DataEvent.API_SETTINGS_WRITE ||
|
||||||
eventType === DataEvent.API_PAGE_DELETE ||
|
eventType === DataEvent.API_PAGE_DELETE ||
|
||||||
eventType === DataEvent.API_RENDER_PAGES ||
|
eventType === DataEvent.API_RENDER_PAGES ||
|
||||||
eventType === DataEvent.API_BACKUP_CREATE
|
eventType === DataEvent.API_BACKUP_CREATE ||
|
||||||
|
eventType === DataEvent.API_BACKUP_RESTORE
|
||||||
)
|
)
|
||||||
request.setRequestHeader('x-access-token', self.token);
|
request.setRequestHeader('x-access-token', self.token);
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,9 @@
|
||||||
margin 0 5px 10px 0
|
margin 0 5px 10px 0
|
||||||
height 30px
|
height 30px
|
||||||
padding 10px
|
padding 10px
|
||||||
|
input#backup-upload
|
||||||
|
visibility hidden
|
||||||
|
display none
|
||||||
.backup-meta
|
.backup-meta
|
||||||
background $primary - 60%
|
background $primary - 60%
|
||||||
color $white
|
color $white
|
||||||
|
|
Loading…
Reference in a new issue