Add YouTube cache table

This commit is contained in:
Calvin Montgomery 2020-02-06 21:55:47 -08:00
parent 46311bd661
commit b80a532f9e
5 changed files with 89 additions and 2 deletions

View File

@ -2,7 +2,7 @@
"author": "Calvin Montgomery", "author": "Calvin Montgomery",
"name": "CyTube", "name": "CyTube",
"description": "Online media synchronizer and chat", "description": "Online media synchronizer and chat",
"version": "3.67.2", "version": "3.68.0",
"repository": { "repository": {
"url": "http://github.com/calzoneman/sync" "url": "http://github.com/calzoneman/sync"
}, },

View File

@ -3,6 +3,7 @@ var tables = require("./database/tables");
import * as Metrics from './metrics/metrics'; import * as Metrics from './metrics/metrics';
import knex from 'knex'; import knex from 'knex';
import { GlobalBanDB } from './db/globalban'; import { GlobalBanDB } from './db/globalban';
import { MetadataCacheDB } from './database/metadata_cache';
import { Summary, Counter } from 'prom-client'; import { Summary, Counter } from 'prom-client';
const LOGGER = require('@calzoneman/jsli')('database'); const LOGGER = require('@calzoneman/jsli')('database');
@ -84,6 +85,9 @@ module.exports.init = function (newDB) {
.then(() => { .then(() => {
require('./database/update').checkVersion(); require('./database/update').checkVersion();
module.exports.loadAnnouncement(); module.exports.loadAnnouncement();
require('cytube-mediaquery/lib/provider/youtube').setCache(
new MetadataCacheDB(db)
);
}).catch(error => { }).catch(error => {
LOGGER.error(error.stack); LOGGER.error(error.stack);
process.exit(1); process.exit(1);

View File

@ -0,0 +1,69 @@
import { createMySQLDuplicateKeyUpdate } from '../util/on-duplicate-key-update';
const Switches = require('../switches');
const Media = require('cytube-mediaquery/lib/media');
// TODO: these fullname-vs-shortcode hacks really need to be abolished
function mediaquery2cytube(type) {
switch (type) {
case 'youtube':
return 'yt';
default:
throw new Error(`mediaquery2cytube: no mapping for ${type}`);
}
}
function cytube2mediaquery(type) {
switch (type) {
case 'yt':
return 'youtube';
default:
throw new Error(`cytube2mediaquery: no mapping for ${type}`);
}
}
class MetadataCacheDB {
constructor(db) {
this.db = db;
}
async put(media) {
if (!Switches.isActive('ytCache')) return;
media = new Media(media);
media.type = mediaquery2cytube(media.type);
return this.db.runTransaction(async tx => {
let insert = tx.table('media_metadata_cache')
.insert({
id: media.id,
type: media.type,
metadata: JSON.stringify(media)
});
let update = tx.raw(createMySQLDuplicateKeyUpdate(
['metadata']
));
return tx.raw(insert.toString() + update.toString());
});
}
async get(id, type) {
if (!Switches.isActive('ytCache')) return null;
return this.db.runTransaction(async tx => {
let row = await tx.table('media_metadata_cache')
.where({ id, type })
.first();
if (row === undefined || row === null) {
return null;
}
let metadata = JSON.parse(row.metadata);
metadata.type = cytube2mediaquery(metadata.type);
return new Media(metadata);
});
}
}
export { MetadataCacheDB };

View File

@ -142,4 +142,17 @@ export async function initTables() {
t.timestamps(/* useTimestamps */ true, /* defaultToNow */ true); t.timestamps(/* useTimestamps */ true, /* defaultToNow */ true);
t.index('created_at'); t.index('created_at');
}); });
await ensureTable('media_metadata_cache', t => {
// The types of id and type are chosen for compatibility
// with the existing channel_libraries table.
// TODO in the future schema, revisit the ID layout for different media types.
t.string('id', 255).notNullable();
t.string('type', 2).notNullable();
t.text('metadata').notNullable();
t.timestamps(/* useTimestamps */ true, /* defaultToNow */ true);
t.primary(['type', 'id']);
t.index('updated_at');
});
} }

View File

@ -1,5 +1,6 @@
const switches = { const switches = {
plDirtyCheck: true plDirtyCheck: true,
ytCache: true
}; };
export function isActive(switchName) { export function isActive(switchName) {