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.

134 lines
3.3 KiB

  1. const qs = require('querystring')
  2. const _ = require('lodash')
  3. const crypto = require('crypto')
  4. const path = require('path')
  5. const localeSegmentRegex = /^[A-Z]{2}(-[A-Z]{2})?$/i
  6. const localeFolderRegex = /^([a-z]{2}(?:-[a-z]{2})?\/)?(.*)/i
  7. const contentToExt = {
  8. markdown: 'md',
  9. html: 'html'
  10. }
  11. const extToContent = _.invert(contentToExt)
  12. /* global WIKI */
  13. module.exports = {
  14. /**
  15. * Parse raw url path and make it safe
  16. */
  17. parsePath (rawPath, opts = {}) {
  18. let pathObj = {
  19. locale: WIKI.config.lang.code,
  20. path: 'home',
  21. private: false,
  22. privateNS: '',
  23. explicitLocale: false
  24. }
  25. // Clean Path
  26. rawPath = _.trim(qs.unescape(rawPath))
  27. if (_.startsWith(rawPath, '/')) { rawPath = rawPath.substring(1) }
  28. if (rawPath === '') { rawPath = 'home' }
  29. // Extract Info
  30. let pathParts = _.filter(_.split(rawPath, '/'), p => !_.isEmpty(p))
  31. if (pathParts[0].length === 1) {
  32. pathParts.shift()
  33. }
  34. if (localeSegmentRegex.test(pathParts[0])) {
  35. pathObj.locale = pathParts[0]
  36. pathObj.explicitLocale = true
  37. pathParts.shift()
  38. }
  39. // Strip extension
  40. if (opts.stripExt && pathParts.length > 0) {
  41. const lastPart = _.last(pathParts)
  42. if (lastPart.indexOf('.') > 0) {
  43. pathParts.pop()
  44. const lastPartMeta = path.parse(lastPart)
  45. pathParts.push(lastPartMeta.name)
  46. }
  47. }
  48. pathObj.path = _.join(pathParts, '/')
  49. return pathObj
  50. },
  51. /**
  52. * Generate unique hash from page
  53. */
  54. generateHash(opts) {
  55. return crypto.createHash('sha1').update(`${opts.locale}|${opts.path}|${opts.privateNS}`).digest('hex')
  56. },
  57. /**
  58. * Inject Page Metadata
  59. */
  60. injectPageMetadata(page) {
  61. let meta = [
  62. ['title', page.title],
  63. ['description', page.description],
  64. ['published', page.isPublished.toString()],
  65. ['date', page.updatedAt],
  66. ['tags', '']
  67. ]
  68. const inject = {
  69. 'markdown': '---\n' + meta.map(mt => `${mt[0]}: ${mt[1]}`).join('\n') + '\n---\n\n' + page.content,
  70. 'html': '<!--\n' + meta.map(mt => `${mt[0]}: ${mt[1]}`).join('\n') + '\n-->\n\n' + page.content
  71. }
  72. return _.get(inject, page.contentType, page.content)
  73. },
  74. /**
  75. * Check if path is a reserved path
  76. */
  77. isReservedPath(rawPath) {
  78. const firstSection = _.head(rawPath.split('/'))
  79. if (firstSection.length <= 1) {
  80. return true
  81. } else if (localeSegmentRegex.test(firstSection)) {
  82. return true
  83. } else if (
  84. _.some(WIKI.data.reservedPaths, p => {
  85. return p === firstSection
  86. })) {
  87. return true
  88. } else {
  89. return false
  90. }
  91. },
  92. /**
  93. * Get file extension from content type
  94. */
  95. getFileExtension(contentType) {
  96. return _.get(contentToExt, contentType, 'txt')
  97. },
  98. /**
  99. * Get content type from file extension
  100. */
  101. getContentType (filePath) {
  102. const ext = _.last(filePath.split('.'))
  103. return _.get(extToContent, ext, false)
  104. },
  105. /**
  106. * Get Page Meta object from disk path
  107. */
  108. getPagePath (filePath) {
  109. let fpath = filePath
  110. if (process.platform === 'win32') {
  111. fpath = filePath.replace(/\\/g, '/')
  112. }
  113. let meta = {
  114. locale: WIKI.config.lang.code,
  115. path: _.initial(fpath.split('.')).join('')
  116. }
  117. const result = localeFolderRegex.exec(meta.path)
  118. if (result[1]) {
  119. meta = {
  120. locale: result[1],
  121. path: result[2]
  122. }
  123. }
  124. return meta
  125. }
  126. }