storage.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. const fs = require('fs-extra')
  2. const path = require('path')
  3. const tar = require('tar-fs')
  4. const zlib = require('zlib')
  5. const stream = require('stream')
  6. const Promise = require('bluebird')
  7. const pipeline = Promise.promisify(stream.pipeline)
  8. const pageHelper = require('../../../helpers/page.js')
  9. const moment = require('moment')
  10. /* global WIKI */
  11. module.exports = {
  12. async activated() {
  13. // not used
  14. },
  15. async deactivated() {
  16. // not used
  17. },
  18. async init() {
  19. WIKI.logger.info('(STORAGE/DISK) Initializing...')
  20. await fs.ensureDir(this.config.path)
  21. WIKI.logger.info('(STORAGE/DISK) Initialization completed.')
  22. },
  23. async sync({ manual } = { manual: false }) {
  24. if (this.config.createDailyBackups || manual) {
  25. const dirPath = path.join(this.config.path, manual ? '_manual' : '_daily')
  26. await fs.ensureDir(dirPath)
  27. const dateFilename = moment().format(manual ? 'YYYYMMDD-HHmmss' : 'DD')
  28. WIKI.logger.info(`(STORAGE/DISK) Creating backup archive...`)
  29. await pipeline(
  30. tar.pack(this.config.path, {
  31. ignore: (filePath) => {
  32. return filePath.indexOf('_daily') >= 0 || filePath.indexOf('_manual') >= 0
  33. }
  34. }),
  35. zlib.createGzip(),
  36. fs.createWriteStream(path.join(dirPath, `wiki-${dateFilename}.tar.gz`))
  37. )
  38. WIKI.logger.info('(STORAGE/DISK) Backup archive created successfully.')
  39. }
  40. },
  41. async created(page) {
  42. WIKI.logger.info(`(STORAGE/DISK) Creating file ${page.path}...`)
  43. let fileName = `${page.path}.${page.getFileExtension()}`
  44. if (WIKI.config.lang.code !== page.localeCode) {
  45. fileName = `${page.localeCode}/${fileName}`
  46. }
  47. const filePath = path.join(this.config.path, fileName)
  48. await fs.outputFile(filePath, page.injectMetadata(), 'utf8')
  49. },
  50. async updated(page) {
  51. WIKI.logger.info(`(STORAGE/DISK) Updating file ${page.path}...`)
  52. let fileName = `${page.path}.${page.getFileExtension()}`
  53. if (WIKI.config.lang.code !== page.localeCode) {
  54. fileName = `${page.localeCode}/${fileName}`
  55. }
  56. const filePath = path.join(this.config.path, fileName)
  57. await fs.outputFile(filePath, page.injectMetadata(), 'utf8')
  58. },
  59. async deleted(page) {
  60. WIKI.logger.info(`(STORAGE/DISK) Deleting file ${page.path}...`)
  61. let fileName = `${page.path}.${page.getFileExtension()}`
  62. if (WIKI.config.lang.code !== page.localeCode) {
  63. fileName = `${page.localeCode}/${fileName}`
  64. }
  65. const filePath = path.join(this.config.path, fileName)
  66. await fs.unlink(filePath)
  67. },
  68. async renamed(page) {
  69. WIKI.logger.info(`(STORAGE/DISK) Renaming file ${page.sourcePath} to ${page.destinationPath}...`)
  70. let sourceFilePath = `${page.sourcePath}.${page.getFileExtension()}`
  71. let destinationFilePath = `${page.destinationPath}.${page.getFileExtension()}`
  72. if (WIKI.config.lang.code !== page.localeCode) {
  73. sourceFilePath = `${page.localeCode}/${sourceFilePath}`
  74. destinationFilePath = `${page.localeCode}/${destinationFilePath}`
  75. }
  76. await fs.move(path.join(this.config.path, sourceFilePath), path.join(this.config.path, destinationFilePath), { overwrite: true })
  77. },
  78. /**
  79. * HANDLERS
  80. */
  81. async dump() {
  82. WIKI.logger.info(`(STORAGE/DISK) Dumping all content to disk...`)
  83. await pipeline(
  84. WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt').select().from('pages').where({
  85. isPrivate: false
  86. }).stream(),
  87. new stream.Transform({
  88. objectMode: true,
  89. transform: async (page, enc, cb) => {
  90. let fileName = `${page.path}.${page.getFileExtension()}`
  91. if (WIKI.config.lang.code !== page.localeCode) {
  92. fileName = `${page.localeCode}/${fileName}`
  93. }
  94. WIKI.logger.info(`(STORAGE/DISK) Dumping ${fileName}...`)
  95. const filePath = path.join(this.config.path, fileName)
  96. await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8')
  97. cb()
  98. }
  99. })
  100. )
  101. WIKI.logger.info('(STORAGE/DISK) All content was dumped to disk successfully.')
  102. },
  103. async backup() {
  104. return this.sync({ manual: true })
  105. }
  106. }