commentProviders.js 4.66 KB
Newer Older
NGPixel's avatar
NGPixel committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
const Model = require('objection').Model
const fs = require('fs-extra')
const path = require('path')
const _ = require('lodash')
const yaml = require('js-yaml')
const commonHelper = require('../helpers/common')

/* global WIKI */

/**
 * CommentProvider model
 */
module.exports = class CommentProvider extends Model {
  static get tableName() { return 'commentProviders' }
  static get idColumn() { return 'key' }

  static get jsonSchema () {
    return {
      type: 'object',
      required: ['key', 'isEnabled'],

      properties: {
        key: {type: 'string'},
        isEnabled: {type: 'boolean'}
      }
    }
  }

  static get jsonAttributes() {
    return ['config']
  }

  static async getProvider(key) {
    return WIKI.models.commentProviders.query().findOne({ key })
  }

  static async getProviders(isEnabled) {
    const providers = await WIKI.models.commentProviders.query().where(_.isBoolean(isEnabled) ? { isEnabled } : {})
    return _.sortBy(providers, ['key'])
  }

  static async refreshProvidersFromDisk() {
    let trx
    try {
      const dbProviders = await WIKI.models.commentProviders.query()

      // -> Fetch definitions from disk
48
      const commentDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/comments'))
NGPixel's avatar
NGPixel committed
49
      let diskProviders = []
50
      for (let dir of commentDirs) {
NGPixel's avatar
NGPixel committed
51 52 53
        const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/comments', dir, 'definition.yml'), 'utf8')
        diskProviders.push(yaml.safeLoad(def))
      }
54 55 56
      WIKI.data.commentProviders = diskProviders.map(provider => ({
        ...provider,
        props: commonHelper.parseModuleProps(provider.props)
NGPixel's avatar
NGPixel committed
57 58 59
      }))

      let newProviders = []
60 61
      for (let provider of WIKI.data.commentProviders) {
        if (!_.some(dbProviders, ['key', provider.key])) {
NGPixel's avatar
NGPixel committed
62
          newProviders.push({
63 64 65
            key: provider.key,
            isEnabled: provider.key === 'default',
            config: _.transform(provider.props, (result, value, key) => {
NGPixel's avatar
NGPixel committed
66 67 68 69 70
              _.set(result, key, value.default)
              return result
            }, {})
          })
        } else {
71
          const providerConfig = _.get(_.find(dbProviders, ['key', provider.key]), 'config', {})
NGPixel's avatar
NGPixel committed
72
          await WIKI.models.commentProviders.query().patch({
73
            config: _.transform(provider.props, (result, value, key) => {
NGPixel's avatar
NGPixel committed
74 75 76 77
              if (!_.has(result, key)) {
                _.set(result, key, value.default)
              }
              return result
78 79
            }, providerConfig)
          }).where('key', provider.key)
NGPixel's avatar
NGPixel committed
80 81 82 83
        }
      }
      if (newProviders.length > 0) {
        trx = await WIKI.models.Objection.transaction.start(WIKI.models.knex)
84 85
        for (let provider of newProviders) {
          await WIKI.models.commentProviders.query(trx).insert(provider)
NGPixel's avatar
NGPixel committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99
        }
        await trx.commit()
        WIKI.logger.info(`Loaded ${newProviders.length} new comment providers: [ OK ]`)
      } else {
        WIKI.logger.info(`No new comment providers found: [ SKIPPED ]`)
      }
    } catch (err) {
      WIKI.logger.error(`Failed to scan or load new comment providers: [ FAILED ]`)
      WIKI.logger.error(err)
      if (trx) {
        trx.rollback()
      }
    }
  }
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

  static async initProvider() {
    const commentProvider = await WIKI.models.commentProviders.query().findOne('isEnabled', true)
    if (commentProvider) {
      WIKI.data.commentProvider = {
        ..._.find(WIKI.data.commentProviders, ['key', commentProvider.key]),
        head: '',
        bodyStart: '',
        bodyEnd: '',
        main: '<comments></comments>'
      }

      if (WIKI.data.commentProvider.codeTemplate) {
        const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/comments', commentProvider.key, 'code.yml'), 'utf8')
        let code = yaml.safeLoad(def)
        code.head = _.defaultTo(code.head, '')
        code.body = _.defaultTo(code.body, '')
        code.main = _.defaultTo(code.main, '')

        _.forOwn(commentProvider.config, (value, key) => {
          code.head = _.replace(code.head, new RegExp(`{{${key}}}`, 'g'), value)
          code.body = _.replace(code.body, new RegExp(`{{${key}}}`, 'g'), value)
          code.main = _.replace(code.main, new RegExp(`{{${key}}}`, 'g'), value)
        })

        WIKI.data.commentProvider.head = code.head
        WIKI.data.commentProvider.body = code.body
        WIKI.data.commentProvider.main = code.main
      } else {
        WIKI.data.commentProvider = {
          ...WIKI.data.commentProvider,
131 132
          ...require(`../modules/comments/${commentProvider.key}/comment`),
          config: commentProvider.config
133
        }
134
        await WIKI.data.commentProvider.init()
135 136 137 138
      }
      WIKI.data.commentProvider.config = commentProvider.config
    }
  }
NGPixel's avatar
NGPixel committed
139
}