wikijs-fork/server/models/storage.js

125 lines
3.5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const Model = require('objection').Model
const path = require('path')
const fs = require('fs-extra')
const _ = require('lodash')
const yaml = require('js-yaml')
const commonHelper = require('../helpers/common')
/* global WIKI */
let targets = []
/**
* Storage model
*/
module.exports = class Storage extends Model {
static get tableName() { return 'storage' }
static get idColumn() { return 'key' }
static get jsonSchema () {
return {
type: 'object',
required: ['key', 'isEnabled'],
properties: {
key: {type: 'string'},
isEnabled: {type: 'boolean'},
mode: {type: 'string'},
config: {type: 'object'}
}
}
}
static async getTargets() {
return WIKI.models.storage.query()
}
static async refreshTargetsFromDisk() {
let trx
try {
const dbTargets = await WIKI.models.storage.query()
// -> Fetch definitions from disk
const storageDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/storage'))
let diskTargets = []
for (let dir of storageDirs) {
const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/storage', dir, 'definition.yml'), 'utf8')
diskTargets.push(yaml.safeLoad(def))
}
WIKI.data.storage = diskTargets.map(target => ({
...target,
isAvailable: _.get(target, 'isAvailable', false),
props: commonHelper.parseModuleProps(target.props)
}))
// -> Insert new targets
let newTargets = []
for (let target of WIKI.data.storage) {
if (!_.some(dbTargets, ['key', target.key])) {
newTargets.push({
key: target.key,
isEnabled: false,
mode: target.defaultMode || 'push',
config: _.transform(target.props, (result, value, key) => {
_.set(result, key, value.default)
return result
}, {})
})
} else {
const targetConfig = _.get(_.find(dbTargets, ['key', target.key]), 'config', {})
await WIKI.models.storage.query().patch({
config: _.transform(target.props, (result, value, key) => {
if (!_.has(result, key)) {
_.set(result, key, value.default)
}
return result
}, targetConfig)
}).where('key', target.key)
}
}
if (newTargets.length > 0) {
trx = await WIKI.models.Objection.transaction.start(WIKI.models.knex)
for (let target of newTargets) {
await WIKI.models.storage.query(trx).insert(target)
}
await trx.commit()
WIKI.logger.info(`Loaded ${newTargets.length} new storage targets: [ OK ]`)
} else {
WIKI.logger.info(`No new storage targets found: [ SKIPPED ]`)
}
} catch (err) {
WIKI.logger.error(`Failed to scan or load new storage providers: [ FAILED ]`)
WIKI.logger.error(err)
if (trx) {
trx.rollback()
}
}
}
static async initTargets() {
targets = await WIKI.models.storage.query().where('isEnabled', true)
try {
for(let target of targets) {
target.fn = require(`../modules/storage/${target.key}/storage`)
target.fn.config = target.config
target.fn.mode = target.mode
await target.fn.init()
}
} catch (err) {
WIKI.logger.warn(err)
throw err
}
}
static async pageEvent({ event, page }) {
try {
for(let target of targets) {
await target.fn[event](page)
}
} catch (err) {
WIKI.logger.warn(err)
throw err
}
}
}