feat: asset add/rename/remove + dump action for git and disk modules
This commit is contained in:
parent
73aa870abc
commit
d987058336
@ -91,7 +91,7 @@
|
|||||||
//- LANGUAGES
|
//- LANGUAGES
|
||||||
|
|
||||||
template(v-if='mode === `view` && locales.length > 0')
|
template(v-if='mode === `view` && locales.length > 0')
|
||||||
v-menu(offset-y, bottom, nudge-bottom='30', transition='slide-y-transition')
|
v-menu(offset-y, bottom, transition='slide-y-transition')
|
||||||
template(v-slot:activator='{ on: menu }')
|
template(v-slot:activator='{ on: menu }')
|
||||||
v-tooltip(bottom)
|
v-tooltip(bottom)
|
||||||
template(v-slot:activator='{ on: tooltip }')
|
template(v-slot:activator='{ on: tooltip }')
|
||||||
@ -101,14 +101,14 @@
|
|||||||
v-list(nav)
|
v-list(nav)
|
||||||
template(v-for='(lc, idx) of locales')
|
template(v-for='(lc, idx) of locales')
|
||||||
v-list-item(@click='changeLocale(lc)')
|
v-list-item(@click='changeLocale(lc)')
|
||||||
v-list-item-action: v-chip(:color='lc.code === locale ? `blue` : `grey`', small, label, dark) {{lc.code.toUpperCase()}}
|
v-list-item-action(style='min-width:auto;'): v-chip(:color='lc.code === locale ? `blue` : `grey`', small, label, dark) {{lc.code.toUpperCase()}}
|
||||||
v-list-item-title {{lc.name}}
|
v-list-item-title {{lc.name}}
|
||||||
v-divider(vertical)
|
v-divider(vertical)
|
||||||
|
|
||||||
//- PAGE ACTIONS
|
//- PAGE ACTIONS
|
||||||
|
|
||||||
template(v-if='isAuthenticated && path && mode !== `edit`')
|
template(v-if='isAuthenticated && path && mode !== `edit`')
|
||||||
v-menu(offset-y, bottom, nudge-bottom='30', transition='slide-y-transition')
|
v-menu(offset-y, bottom, transition='slide-y-transition')
|
||||||
template(v-slot:activator='{ on: menu }')
|
template(v-slot:activator='{ on: menu }')
|
||||||
v-tooltip(bottom)
|
v-tooltip(bottom)
|
||||||
template(v-slot:activator='{ on: tooltip }')
|
template(v-slot:activator='{ on: tooltip }')
|
||||||
@ -152,7 +152,7 @@
|
|||||||
|
|
||||||
//- ACCOUNT
|
//- ACCOUNT
|
||||||
|
|
||||||
v-menu(v-if='isAuthenticated', offset-y, bottom, nudge-bottom='30', min-width='300', transition='slide-y-transition')
|
v-menu(v-if='isAuthenticated', offset-y, bottom, min-width='300', transition='slide-y-transition')
|
||||||
template(v-slot:activator='{ on: menu }')
|
template(v-slot:activator='{ on: menu }')
|
||||||
v-tooltip(bottom)
|
v-tooltip(bottom)
|
||||||
template(v-slot:activator='{ on: tooltip }')
|
template(v-slot:activator='{ on: tooltip }')
|
||||||
|
@ -90,7 +90,7 @@ router.post('/u', multer({
|
|||||||
...fileMeta,
|
...fileMeta,
|
||||||
folderId: folderId,
|
folderId: folderId,
|
||||||
assetPath,
|
assetPath,
|
||||||
userId: req.user.id
|
user: req.user
|
||||||
})
|
})
|
||||||
res.send('ok')
|
res.send('ok')
|
||||||
})
|
})
|
||||||
|
@ -123,8 +123,11 @@ module.exports = {
|
|||||||
event: 'renamed',
|
event: 'renamed',
|
||||||
asset: {
|
asset: {
|
||||||
...asset,
|
...asset,
|
||||||
sourcePath: assetSourcePath,
|
path: assetSourcePath,
|
||||||
destinationPath: assetTargetPath
|
destinationPath: assetTargetPath,
|
||||||
|
moveAuthorId: context.req.user.id,
|
||||||
|
moveAuthorName: context.req.user.name,
|
||||||
|
moveAuthorEmail: context.req.user.email
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -146,7 +149,7 @@ module.exports = {
|
|||||||
const asset = await WIKI.models.assets.query().findById(args.id)
|
const asset = await WIKI.models.assets.query().findById(args.id)
|
||||||
if (asset) {
|
if (asset) {
|
||||||
// Check permissions
|
// Check permissions
|
||||||
const assetPath = asset.getAssetPath()
|
const assetPath = await asset.getAssetPath()
|
||||||
if (!WIKI.auth.checkAccess(context.req.user, ['manage:assets'], { path: assetPath })) {
|
if (!WIKI.auth.checkAccess(context.req.user, ['manage:assets'], { path: assetPath })) {
|
||||||
throw new WIKI.Error.AssetDeleteForbidden()
|
throw new WIKI.Error.AssetDeleteForbidden()
|
||||||
}
|
}
|
||||||
@ -158,7 +161,13 @@ module.exports = {
|
|||||||
// Delete from Storage
|
// Delete from Storage
|
||||||
await WIKI.models.storage.assetEvent({
|
await WIKI.models.storage.assetEvent({
|
||||||
event: 'deleted',
|
event: 'deleted',
|
||||||
asset
|
asset: {
|
||||||
|
...asset,
|
||||||
|
path: assetPath,
|
||||||
|
authorId: context.req.user.id,
|
||||||
|
authorName: context.req.user.name,
|
||||||
|
authorEmail: context.req.user.email
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -39,7 +39,7 @@ module.exports = class AssetFolder extends Model {
|
|||||||
*
|
*
|
||||||
* @param {Number} folderId Id of the folder
|
* @param {Number} folderId Id of the folder
|
||||||
*/
|
*/
|
||||||
static async getHierarchy(folderId) {
|
static async getHierarchy (folderId) {
|
||||||
const hier = await WIKI.models.knex.withRecursive('ancestors', qb => {
|
const hier = await WIKI.models.knex.withRecursive('ancestors', qb => {
|
||||||
qb.select('id', 'name', 'slug', 'parentId').from('assetFolders').where('id', folderId).union(sqb => {
|
qb.select('id', 'name', 'slug', 'parentId').from('assetFolders').where('id', folderId).union(sqb => {
|
||||||
sqb.select('a.id', 'a.name', 'a.slug', 'a.parentId').from('assetFolders AS a').join('ancestors', 'ancestors.parentId', 'a.id')
|
sqb.select('a.id', 'a.name', 'a.slug', 'a.parentId').from('assetFolders AS a').join('ancestors', 'ancestors.parentId', 'a.id')
|
||||||
@ -48,4 +48,22 @@ module.exports = class AssetFolder extends Model {
|
|||||||
// The ancestors are from children to grandparents, must reverse for correct path order.
|
// The ancestors are from children to grandparents, must reverse for correct path order.
|
||||||
return _.reverse(hier)
|
return _.reverse(hier)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get full folder paths
|
||||||
|
*/
|
||||||
|
static async getAllPaths () {
|
||||||
|
const all = await WIKI.models.assetFolders.query()
|
||||||
|
let folders = {}
|
||||||
|
all.forEach(fld => {
|
||||||
|
_.set(folders, fld.id, fld.slug)
|
||||||
|
let parentId = fld.parentId
|
||||||
|
while (parentId !== null || parentId > 0) {
|
||||||
|
const parent = _.find(all, ['id', parentId])
|
||||||
|
_.set(folders, fld.id, `${parent.slug}/${_.get(folders, fld.id)}`)
|
||||||
|
parentId = parent.parentId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return folders
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ module.exports = class Asset extends Model {
|
|||||||
mime: opts.mimetype,
|
mime: opts.mimetype,
|
||||||
fileSize: opts.size,
|
fileSize: opts.size,
|
||||||
folderId: opts.folderId,
|
folderId: opts.folderId,
|
||||||
authorId: opts.userId
|
authorId: opts.user.id
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save asset data
|
// Save asset data
|
||||||
@ -119,20 +119,27 @@ module.exports = class Asset extends Model {
|
|||||||
data: fileBuffer
|
data: fileBuffer
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move temp upload to cache
|
||||||
|
await fs.move(opts.path, path.join(process.cwd(), `data/cache/${fileHash}.dat`), { overwrite: true })
|
||||||
|
|
||||||
|
// Add to Storage
|
||||||
|
if (!opts.skipStorage) {
|
||||||
|
await WIKI.models.storage.assetEvent({
|
||||||
|
event: 'uploaded',
|
||||||
|
asset: {
|
||||||
|
...asset,
|
||||||
|
path: await asset.getAssetPath(),
|
||||||
|
data: fileBuffer,
|
||||||
|
authorId: opts.user.id,
|
||||||
|
authorName: opts.user.name,
|
||||||
|
authorEmail: opts.user.email
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
WIKI.logger.warn(err)
|
WIKI.logger.warn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move temp upload to cache
|
|
||||||
await fs.move(opts.path, path.join(process.cwd(), `data/cache/${fileHash}.dat`), { overwrite: true })
|
|
||||||
|
|
||||||
// Add to Storage
|
|
||||||
if (!opts.skipStorage) {
|
|
||||||
await WIKI.models.storage.assetEvent({
|
|
||||||
event: 'uploaded',
|
|
||||||
asset
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getAsset(assetPath, res) {
|
static async getAsset(assetPath, res) {
|
||||||
|
@ -88,12 +88,41 @@ module.exports = {
|
|||||||
|
|
||||||
await fs.move(path.join(this.config.path, sourceFilePath), path.join(this.config.path, destinationFilePath), { overwrite: true })
|
await fs.move(path.join(this.config.path, sourceFilePath), path.join(this.config.path, destinationFilePath), { overwrite: true })
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* ASSET UPLOAD
|
||||||
|
*
|
||||||
|
* @param {Object} asset Asset to upload
|
||||||
|
*/
|
||||||
|
async assetUploaded (asset) {
|
||||||
|
WIKI.logger.info(`(STORAGE/DISK) Creating new file ${asset.path}...`)
|
||||||
|
await fs.outputFile(path.join(this.config.path, asset.path), asset.data)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ASSET DELETE
|
||||||
|
*
|
||||||
|
* @param {Object} asset Asset to delete
|
||||||
|
*/
|
||||||
|
async assetDeleted (asset) {
|
||||||
|
WIKI.logger.info(`(STORAGE/DISK) Deleting file ${asset.path}...`)
|
||||||
|
await fs.remove(path.join(this.config.path, asset.path))
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* ASSET RENAME
|
||||||
|
*
|
||||||
|
* @param {Object} asset Asset to rename
|
||||||
|
*/
|
||||||
|
async assetRenamed (asset) {
|
||||||
|
WIKI.logger.info(`(STORAGE/DISK) Renaming file from ${asset.path} to ${asset.destinationPath}...`)
|
||||||
|
await fs.move(path.join(this.config.path, asset.path), path.join(this.config.path, asset.destinationPath), { overwrite: true })
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HANDLERS
|
* HANDLERS
|
||||||
*/
|
*/
|
||||||
async dump() {
|
async dump() {
|
||||||
WIKI.logger.info(`(STORAGE/DISK) Dumping all content to disk...`)
|
WIKI.logger.info(`(STORAGE/DISK) Dumping all content to disk...`)
|
||||||
|
|
||||||
|
// -> Pages
|
||||||
await pipeline(
|
await pipeline(
|
||||||
WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt').select().from('pages').where({
|
WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt').select().from('pages').where({
|
||||||
isPrivate: false
|
isPrivate: false
|
||||||
@ -105,13 +134,30 @@ module.exports = {
|
|||||||
if (WIKI.config.lang.code !== page.localeCode) {
|
if (WIKI.config.lang.code !== page.localeCode) {
|
||||||
fileName = `${page.localeCode}/${fileName}`
|
fileName = `${page.localeCode}/${fileName}`
|
||||||
}
|
}
|
||||||
WIKI.logger.info(`(STORAGE/DISK) Dumping ${fileName}...`)
|
WIKI.logger.info(`(STORAGE/DISK) Dumping page ${fileName}...`)
|
||||||
const filePath = path.join(this.config.path, fileName)
|
const filePath = path.join(this.config.path, fileName)
|
||||||
await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8')
|
await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8')
|
||||||
cb()
|
cb()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// -> Assets
|
||||||
|
const assetFolders = await WIKI.models.assetFolders.getAllPaths()
|
||||||
|
|
||||||
|
await pipeline(
|
||||||
|
WIKI.models.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(),
|
||||||
|
new stream.Transform({
|
||||||
|
objectMode: true,
|
||||||
|
transform: async (asset, enc, cb) => {
|
||||||
|
const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename
|
||||||
|
WIKI.logger.info(`(STORAGE/DISK) Dumping asset ${filename}...`)
|
||||||
|
await fs.outputFile(path.join(this.config.path, filename), asset.data)
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
WIKI.logger.info('(STORAGE/DISK) All content was dumped to disk successfully.')
|
WIKI.logger.info('(STORAGE/DISK) All content was dumped to disk successfully.')
|
||||||
},
|
},
|
||||||
async backup() {
|
async backup() {
|
||||||
|
@ -283,7 +283,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.git.mv(`./${sourceFilePath}`, `./${destinationFilePath}`)
|
await this.git.mv(`./${sourceFilePath}`, `./${destinationFilePath}`)
|
||||||
await this.git.commit(`docs: rename ${page.path} to ${page.destinationPath}`, destinationFilePath, {
|
await this.git.commit(`docs: rename ${page.path} to ${page.destinationPath}`, [sourceFilePath, destinationFilePath], {
|
||||||
'--author': `"${page.moveAuthorName} <${page.moveAuthorEmail}>"`
|
'--author': `"${page.moveAuthorName} <${page.moveAuthorEmail}>"`
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -295,7 +295,7 @@ module.exports = {
|
|||||||
async assetUploaded (asset) {
|
async assetUploaded (asset) {
|
||||||
WIKI.logger.info(`(STORAGE/GIT) Committing new file ${asset.path}...`)
|
WIKI.logger.info(`(STORAGE/GIT) Committing new file ${asset.path}...`)
|
||||||
const filePath = path.join(this.repoPath, asset.path)
|
const filePath = path.join(this.repoPath, asset.path)
|
||||||
await fs.outputFile(filePath, asset, 'utf8')
|
await fs.outputFile(filePath, asset.data, 'utf8')
|
||||||
|
|
||||||
await this.git.add(`./${asset.path}`)
|
await this.git.add(`./${asset.path}`)
|
||||||
await this.git.commit(`docs: upload ${asset.path}`, asset.path, {
|
await this.git.commit(`docs: upload ${asset.path}`, asset.path, {
|
||||||
@ -321,11 +321,11 @@ module.exports = {
|
|||||||
* @param {Object} asset Asset to upload
|
* @param {Object} asset Asset to upload
|
||||||
*/
|
*/
|
||||||
async assetRenamed (asset) {
|
async assetRenamed (asset) {
|
||||||
WIKI.logger.info(`(STORAGE/GIT) Committing file move from ${asset.sourcePath} to ${asset.destinationPath}...`)
|
WIKI.logger.info(`(STORAGE/GIT) Committing file move from ${asset.path} to ${asset.destinationPath}...`)
|
||||||
|
|
||||||
await this.git.mv(`./${asset.sourcePath}`, `./${asset.destinationPath}`)
|
await this.git.mv(`./${asset.path}`, `./${asset.destinationPath}`)
|
||||||
await this.git.commit(`docs: rename ${asset.sourcePath} to ${asset.destinationPath}`, asset.destinationPath, {
|
await this.git.commit(`docs: rename ${asset.path} to ${asset.destinationPath}`, [asset.path, asset.destinationPath], {
|
||||||
'--author': `"${asset.authorName} <${asset.authorEmail}>"`
|
'--author': `"${asset.moveAuthorName} <${asset.moveAuthorEmail}>"`
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
@ -364,6 +364,7 @@ module.exports = {
|
|||||||
async syncUntracked() {
|
async syncUntracked() {
|
||||||
WIKI.logger.info(`(STORAGE/GIT) Adding all untracked content...`)
|
WIKI.logger.info(`(STORAGE/GIT) Adding all untracked content...`)
|
||||||
|
|
||||||
|
// -> Pages
|
||||||
await pipeline(
|
await pipeline(
|
||||||
WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt').select().from('pages').where({
|
WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt').select().from('pages').where({
|
||||||
isPrivate: false
|
isPrivate: false
|
||||||
@ -375,7 +376,7 @@ module.exports = {
|
|||||||
if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
|
if (WIKI.config.lang.namespacing && WIKI.config.lang.code !== page.localeCode) {
|
||||||
fileName = `${page.localeCode}/${fileName}`
|
fileName = `${page.localeCode}/${fileName}`
|
||||||
}
|
}
|
||||||
WIKI.logger.info(`(STORAGE/GIT) Adding ${fileName}...`)
|
WIKI.logger.info(`(STORAGE/GIT) Adding page ${fileName}...`)
|
||||||
const filePath = path.join(this.repoPath, fileName)
|
const filePath = path.join(this.repoPath, fileName)
|
||||||
await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8')
|
await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8')
|
||||||
await this.git.add(`./${fileName}`)
|
await this.git.add(`./${fileName}`)
|
||||||
@ -383,6 +384,23 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// -> Assets
|
||||||
|
const assetFolders = await WIKI.models.assetFolders.getAllPaths()
|
||||||
|
|
||||||
|
await pipeline(
|
||||||
|
WIKI.models.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(),
|
||||||
|
new stream.Transform({
|
||||||
|
objectMode: true,
|
||||||
|
transform: async (asset, enc, cb) => {
|
||||||
|
const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename
|
||||||
|
WIKI.logger.info(`(STORAGE/GIT) Adding asset ${filename}...`)
|
||||||
|
await fs.outputFile(path.join(this.repoPath, filename), asset.data)
|
||||||
|
await this.git.add(`./${filename}`)
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
await this.git.commit(`docs: add all untracked content`)
|
await this.git.commit(`docs: add all untracked content`)
|
||||||
WIKI.logger.info('(STORAGE/GIT) All content is now tracked.')
|
WIKI.logger.info('(STORAGE/GIT) All content is now tracked.')
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user