mirror of https://github.com/Requarks/wiki.git
3 changed files with 264 additions and 172 deletions
Split View
Diff Options
-
168server/modules/storage/disk/common.js
-
126server/modules/storage/disk/storage.js
-
142server/modules/storage/git/storage.js
@ -0,0 +1,168 @@ |
|||
const fs = require('fs-extra') |
|||
const path = require('path') |
|||
const stream = require('stream') |
|||
const Promise = require('bluebird') |
|||
const pipeline = Promise.promisify(stream.pipeline) |
|||
const klaw = require('klaw') |
|||
const mime = require('mime-types').lookup |
|||
const _ = require('lodash') |
|||
|
|||
const pageHelper = require('../../../helpers/page.js') |
|||
|
|||
/* global WIKI */ |
|||
|
|||
module.exports = { |
|||
assetFolders: null, |
|||
async importFromDisk ({ fullPath, moduleName }) { |
|||
const rootUser = await WIKI.models.users.getRootUser() |
|||
|
|||
await pipeline( |
|||
klaw(fullPath, { |
|||
filter: (f) => { |
|||
return !_.includes(f, '.git') |
|||
} |
|||
}), |
|||
new stream.Transform({ |
|||
objectMode: true, |
|||
transform: async (file, enc, cb) => { |
|||
const relPath = file.path.substr(fullPath.length + 1) |
|||
if (file.stats.size < 1) { |
|||
// Skip directories and zero-byte files
|
|||
return cb() |
|||
} else if (relPath && relPath.length > 3) { |
|||
WIKI.logger.info(`(STORAGE/${moduleName}) Processing ${relPath}...`) |
|||
const contentType = pageHelper.getContentType(relPath) |
|||
if (contentType) { |
|||
// -> Page
|
|||
|
|||
try { |
|||
await this.processPage({ |
|||
user: rootUser, |
|||
relPath: relPath, |
|||
fullPath: fullPath, |
|||
contentType: contentType, |
|||
moduleName: moduleName |
|||
}) |
|||
} catch (err) { |
|||
WIKI.logger.warn(`(STORAGE/${moduleName}) Failed to process page ${relPath}`) |
|||
WIKI.logger.warn(err) |
|||
} |
|||
} else { |
|||
// -> Asset
|
|||
|
|||
try { |
|||
await this.processAsset({ |
|||
user: rootUser, |
|||
relPath: relPath, |
|||
file: file, |
|||
contentType: contentType, |
|||
moduleName: moduleName |
|||
}) |
|||
} catch (err) { |
|||
WIKI.logger.warn(`(STORAGE/${moduleName}) Failed to process asset ${relPath}`) |
|||
WIKI.logger.warn(err) |
|||
} |
|||
} |
|||
} |
|||
cb() |
|||
} |
|||
}) |
|||
) |
|||
this.clearFolderCache() |
|||
}, |
|||
|
|||
async processPage ({ user, fullPath, relPath, contentType, moduleName }) { |
|||
const contentPath = pageHelper.getPagePath(relPath) |
|||
const itemContents = await fs.readFile(path.join(fullPath, relPath), 'utf8') |
|||
const pageData = WIKI.models.pages.parseMetadata(itemContents, contentType) |
|||
const currentPage = await WIKI.models.pages.query().findOne({ |
|||
path: contentPath.path, |
|||
localeCode: contentPath.locale |
|||
}) |
|||
if (currentPage) { |
|||
// Already in the DB, can mark as modified
|
|||
WIKI.logger.info(`(STORAGE/${moduleName}) Page marked as modified: ${relPath}`) |
|||
await WIKI.models.pages.updatePage({ |
|||
id: currentPage.id, |
|||
title: _.get(pageData, 'title', currentPage.title), |
|||
description: _.get(pageData, 'description', currentPage.description) || '', |
|||
isPublished: _.get(pageData, 'isPublished', currentPage.isPublished), |
|||
isPrivate: false, |
|||
content: pageData.content, |
|||
user: user, |
|||
skipStorage: true |
|||
}) |
|||
} else { |
|||
// Not in the DB, can mark as new
|
|||
WIKI.logger.info(`(STORAGE/${moduleName}) Page marked as new: ${relPath}`) |
|||
const pageEditor = await WIKI.models.editors.getDefaultEditor(contentType) |
|||
await WIKI.models.pages.createPage({ |
|||
path: contentPath.path, |
|||
locale: contentPath.locale, |
|||
title: _.get(pageData, 'title', _.last(contentPath.path.split('/'))), |
|||
description: _.get(pageData, 'description', '') || '', |
|||
isPublished: _.get(pageData, 'isPublished', true), |
|||
isPrivate: false, |
|||
content: pageData.content, |
|||
user: user, |
|||
editor: pageEditor, |
|||
skipStorage: true |
|||
}) |
|||
} |
|||
}, |
|||
|
|||
async processAsset ({ user, relPath, file, moduleName }) { |
|||
WIKI.logger.info(`(STORAGE/${moduleName}) Asset marked for import: ${relPath}`) |
|||
|
|||
// -> Get all folder paths
|
|||
if (!this.assetFolders) { |
|||
this.assetFolders = await WIKI.models.assetFolders.getAllPaths() |
|||
} |
|||
|
|||
// -> Find existing folder
|
|||
const filePathInfo = path.parse(file.path) |
|||
const folderPath = path.dirname(relPath).replace(/\\/g, '/') |
|||
let folderId = _.toInteger(_.findKey(this.assetFolders, fld => { return fld === folderPath })) || null |
|||
|
|||
// -> Create missing folder structure
|
|||
if (!folderId && folderPath !== '.') { |
|||
const folderParts = folderPath.split('/') |
|||
let currentFolderPath = [] |
|||
let currentFolderParentId = null |
|||
for (const folderPart of folderParts) { |
|||
currentFolderPath.push(folderPart) |
|||
const existingFolderId = _.findKey(this.assetFolders, fld => { return fld === currentFolderPath.join('/') }) |
|||
if (!existingFolderId) { |
|||
const newFolderObj = await WIKI.models.assetFolders.query().insert({ |
|||
slug: folderPart, |
|||
name: folderPart, |
|||
parentId: currentFolderParentId |
|||
}) |
|||
_.set(this.assetFolders, newFolderObj.id, currentFolderPath.join('/')) |
|||
currentFolderParentId = newFolderObj.id |
|||
} else { |
|||
currentFolderParentId = _.toInteger(existingFolderId) |
|||
} |
|||
} |
|||
folderId = currentFolderParentId |
|||
} |
|||
|
|||
// -> Import asset
|
|||
await WIKI.models.assets.upload({ |
|||
mode: 'import', |
|||
originalname: filePathInfo.base, |
|||
ext: filePathInfo.ext, |
|||
mimetype: mime(filePathInfo.base) || 'application/octet-stream', |
|||
size: file.stats.size, |
|||
folderId: folderId, |
|||
path: file.path, |
|||
assetPath: relPath, |
|||
user: user, |
|||
skipStorage: true |
|||
}) |
|||
}, |
|||
|
|||
clearFolderCache () { |
|||
this.assetFolders = null |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save