You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
4.7 KiB

  1. const Model = require('objection').Model
  2. const fs = require('fs-extra')
  3. const path = require('path')
  4. const _ = require('lodash')
  5. const yaml = require('js-yaml')
  6. const commonHelper = require('../helpers/common')
  7. /* global WIKI */
  8. /**
  9. * CommentProvider model
  10. */
  11. module.exports = class CommentProvider extends Model {
  12. static get tableName() { return 'commentProviders' }
  13. static get idColumn() { return 'key' }
  14. static get jsonSchema () {
  15. return {
  16. type: 'object',
  17. required: ['key', 'isEnabled'],
  18. properties: {
  19. key: {type: 'string'},
  20. isEnabled: {type: 'boolean'}
  21. }
  22. }
  23. }
  24. static get jsonAttributes() {
  25. return ['config']
  26. }
  27. static async getProvider(key) {
  28. return WIKI.models.commentProviders.query().findOne({ key })
  29. }
  30. static async getProviders(isEnabled) {
  31. const providers = await WIKI.models.commentProviders.query().where(_.isBoolean(isEnabled) ? { isEnabled } : {})
  32. return _.sortBy(providers, ['key'])
  33. }
  34. static async refreshProvidersFromDisk() {
  35. let trx
  36. try {
  37. const dbProviders = await WIKI.models.commentProviders.query()
  38. // -> Fetch definitions from disk
  39. const commentDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/comments'))
  40. let diskProviders = []
  41. for (let dir of commentDirs) {
  42. const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/comments', dir, 'definition.yml'), 'utf8')
  43. diskProviders.push(yaml.safeLoad(def))
  44. }
  45. WIKI.data.commentProviders = diskProviders.map(provider => ({
  46. ...provider,
  47. props: commonHelper.parseModuleProps(provider.props)
  48. }))
  49. let newProviders = []
  50. for (let provider of WIKI.data.commentProviders) {
  51. if (!_.some(dbProviders, ['key', provider.key])) {
  52. newProviders.push({
  53. key: provider.key,
  54. isEnabled: provider.key === 'default',
  55. config: _.transform(provider.props, (result, value, key) => {
  56. _.set(result, key, value.default)
  57. return result
  58. }, {})
  59. })
  60. } else {
  61. const providerConfig = _.get(_.find(dbProviders, ['key', provider.key]), 'config', {})
  62. await WIKI.models.commentProviders.query().patch({
  63. config: _.transform(provider.props, (result, value, key) => {
  64. if (!_.has(result, key)) {
  65. _.set(result, key, value.default)
  66. }
  67. return result
  68. }, providerConfig)
  69. }).where('key', provider.key)
  70. }
  71. }
  72. if (newProviders.length > 0) {
  73. trx = await WIKI.models.Objection.transaction.start(WIKI.models.knex)
  74. for (let provider of newProviders) {
  75. await WIKI.models.commentProviders.query(trx).insert(provider)
  76. }
  77. await trx.commit()
  78. WIKI.logger.info(`Loaded ${newProviders.length} new comment providers: [ OK ]`)
  79. } else {
  80. WIKI.logger.info(`No new comment providers found: [ SKIPPED ]`)
  81. }
  82. } catch (err) {
  83. WIKI.logger.error(`Failed to scan or load new comment providers: [ FAILED ]`)
  84. WIKI.logger.error(err)
  85. if (trx) {
  86. trx.rollback()
  87. }
  88. }
  89. }
  90. static async initProvider() {
  91. const commentProvider = await WIKI.models.commentProviders.query().findOne('isEnabled', true)
  92. if (commentProvider) {
  93. WIKI.data.commentProvider = {
  94. ..._.find(WIKI.data.commentProviders, ['key', commentProvider.key]),
  95. head: '',
  96. bodyStart: '',
  97. bodyEnd: '',
  98. main: '<comments></comments>'
  99. }
  100. if (WIKI.data.commentProvider.codeTemplate) {
  101. const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/comments', commentProvider.key, 'code.yml'), 'utf8')
  102. let code = yaml.safeLoad(def)
  103. code.head = _.defaultTo(code.head, '')
  104. code.body = _.defaultTo(code.body, '')
  105. code.main = _.defaultTo(code.main, '')
  106. _.forOwn(commentProvider.config, (value, key) => {
  107. code.head = _.replace(code.head, new RegExp(`{{${key}}}`, 'g'), value)
  108. code.body = _.replace(code.body, new RegExp(`{{${key}}}`, 'g'), value)
  109. code.main = _.replace(code.main, new RegExp(`{{${key}}}`, 'g'), value)
  110. })
  111. WIKI.data.commentProvider.head = code.head
  112. WIKI.data.commentProvider.body = code.body
  113. WIKI.data.commentProvider.main = code.main
  114. } else {
  115. WIKI.data.commentProvider = {
  116. ...WIKI.data.commentProvider,
  117. ...require(`../modules/comments/${commentProvider.key}/comment`),
  118. config: commentProvider.config
  119. }
  120. await WIKI.data.commentProvider.init()
  121. }
  122. WIKI.data.commentProvider.config = commentProvider.config
  123. }
  124. }
  125. }