Implement migrator
This commit is contained in:
parent
10dbbcd3ff
commit
e91635b6f9
|
@ -10,6 +10,7 @@
|
|||
"dependencies": {
|
||||
"babel": "^5.8.23",
|
||||
"bcrypt": "^0.8.5",
|
||||
"bluebird": "^2.10.1",
|
||||
"body-parser": "^1.14.0",
|
||||
"cheerio": "^0.19.0",
|
||||
"compression": "^1.5.2",
|
||||
|
|
|
@ -69,6 +69,9 @@ export class DatabaseStore {
|
|||
const id = rows[0].id;
|
||||
const substitutions = [];
|
||||
for (const key of Object.keys(data)) {
|
||||
if (typeof data[key] === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
rowCount++;
|
||||
const value = JSON.stringify(data[key]);
|
||||
totalSize += value.length;
|
||||
|
|
|
@ -3,8 +3,24 @@ import Promise from 'bluebird';
|
|||
import db from '../database';
|
||||
import { FileStore } from './filestore';
|
||||
import { DatabaseStore } from './dbstore';
|
||||
import { sanitizeHTML } from '../xss';
|
||||
import { ChannelNotFoundError } from '../errors';
|
||||
|
||||
const QUERY_CHANNEL_NAMES = 'SELECT name FROM channels WHERE 1';
|
||||
const EXPECTED_KEYS = [
|
||||
'chatbuffer',
|
||||
'chatmuted',
|
||||
'css',
|
||||
'emotes',
|
||||
'filters',
|
||||
'js',
|
||||
'motd',
|
||||
'openPlaylist',
|
||||
'opts',
|
||||
'permissions',
|
||||
'playlist',
|
||||
'poll'
|
||||
];
|
||||
|
||||
function queryAsync(query, substitutions) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -22,7 +38,79 @@ function queryAsync(query, substitutions) {
|
|||
}
|
||||
|
||||
function fixOldChandump(data) {
|
||||
return data;
|
||||
const converted = {};
|
||||
for (const key of EXPECTED_KEYS) {
|
||||
converted[key] = data[key];
|
||||
}
|
||||
|
||||
if (data.queue) {
|
||||
converted.playlist = {
|
||||
pl: data.queue.map(item => {
|
||||
return {
|
||||
media: {
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
seconds: item.seconds,
|
||||
duration: item.duration,
|
||||
type: item.type,
|
||||
meta: {}
|
||||
},
|
||||
queueby: item.queueby,
|
||||
temp: item.temp
|
||||
};
|
||||
}),
|
||||
pos: data.position,
|
||||
time: data.currentTime
|
||||
};
|
||||
}
|
||||
|
||||
if (data.hasOwnProperty('openqueue')) {
|
||||
converted.openPlaylist = data.openqueue;
|
||||
}
|
||||
|
||||
if (data.hasOwnProperty('playlistLock')) {
|
||||
converted.openPlaylist = !data.playlistLock;
|
||||
}
|
||||
|
||||
if (data.chatbuffer) {
|
||||
converted.chatbuffer = data.chatbuffer.map(entry => {
|
||||
return {
|
||||
username: entry.username,
|
||||
msg: entry.msg,
|
||||
meta: entry.meta || {
|
||||
addClass: entry.msgclass ? entry.msgclass : undefined
|
||||
},
|
||||
time: entry.time
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
if (data.motd && data.motd.motd) {
|
||||
converted.motd = sanitizeHTML(data.motd.motd).replace(/\n/g, '<br>\n');
|
||||
}
|
||||
|
||||
if (data.opts && data.opts.customcss) {
|
||||
converted.opts.externalcss = data.opts.customcss;
|
||||
}
|
||||
|
||||
if (data.opts && data.opts.customjs) {
|
||||
converted.opts.externaljs = data.opts.customjs;
|
||||
}
|
||||
|
||||
if (data.filters && data.filters.length > 0 && Array.isArray(data.filters[0])) {
|
||||
converted.filters = data.filters.map(filter => {
|
||||
let [source, replace, active] = filter;
|
||||
return {
|
||||
source: source,
|
||||
replace: replace,
|
||||
flags: 'g',
|
||||
active: active,
|
||||
filterlinks: false
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
function migrate(src, dest) {
|
||||
|
@ -34,13 +122,11 @@ function migrate(src, dest) {
|
|||
// uppercase letters in the name.
|
||||
//
|
||||
// If another chandump exists which is all lowercase, then that one is
|
||||
// canonical. Otherwise, it's safe to just lowercase the name and convert
|
||||
// it.
|
||||
// canonical. Otherwise, it's safe to load the existing capitalization,
|
||||
// convert it, and save.
|
||||
if (name !== name.toLowerCase()) {
|
||||
if (names.indexOf(name.toLowerCase()) >= 0) {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
name = name.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +135,8 @@ function migrate(src, dest) {
|
|||
return dest.save(name, data);
|
||||
}).then(() => {
|
||||
console.log(`Migrated /r/${name}`);
|
||||
}).catch(ChannelNotFoundError, err => {
|
||||
console.log(`Skipping /r/${name} (not present in the database)`);
|
||||
}).catch(err => {
|
||||
console.error(`Failed to migrate /r/${name}: ${err.stack}`);
|
||||
});
|
||||
|
@ -62,7 +150,9 @@ function main() {
|
|||
const src = new FileStore();
|
||||
const dest = new DatabaseStore();
|
||||
|
||||
migrate(src, dest).then(() => {
|
||||
Promise.delay(1000).then(() => {
|
||||
return migrate(src, dest);
|
||||
}).then(() => {
|
||||
console.log('Migration complete');
|
||||
process.exit(0);
|
||||
}).catch(err => {
|
||||
|
|
Loading…
Reference in a new issue