Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
38c33c58
Commit
38c33c58
authored
Oct 07, 2019
by
NGPixel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: rebuild page tree worker
parent
2883437a
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
198 additions
and
119 deletions
+198
-119
page-selector.vue
client/components/common/page-selector.vue
+41
-40
data.yml
server/app/data.yml
+7
-3
scheduler.js
server/core/scheduler.js
+4
-3
asset.js
server/graph/resolvers/asset.js
+17
-1
rebuild-tree.js
server/jobs/rebuild-tree.js
+63
-0
sync-git.js
server/jobs/sync-git.js
+0
-69
assets.js
server/models/assets.js
+8
-0
pages.js
server/models/pages.js
+1
-1
storage.js
server/models/storage.js
+11
-0
storage.js
server/modules/storage/git/storage.js
+46
-2
No files found.
client/components/common/page-selector.vue
View file @
38c33c58
...
...
@@ -3,7 +3,7 @@
v-card.page-selector
.dialog-header.is-dark
v-icon.mr-3(color='white') mdi-page-next-outline
span
Select Page Location
.body-1
Select Page Location
v-spacer
v-progress-circular(
indeterminate
...
...
@@ -12,44 +12,44 @@
:width='2'
v-show='searchLoading'
)
//-
.d-flex(style='min-height:400px;')
//- v-flex(xs4).grey(
:class='darkMode ? `darken-4` : `lighten-3`')
//-
v-toolbar(color='grey darken-3', dark, dense, flat)
//-
.body-2 Folders
//-
v-spacer
//-
v-btn(icon): v-icon create_new_folder
//-
v-treeview(
//-
v-model='tree'
//-
:items='treeFolders'
//-
:load-children='fetchFolders'
//-
activatable
//-
open-on-click
//-
hoverable
//-
)
//-
template(slot='prepend', slot-scope='{ item, open, leaf }')
//- v-icon
{{
open
?
'folder_
open'
:
'folder'
}}
//-
v-flex(xs8)
//-
v-toolbar(color='grey darken-2', dark, dense, flat)
//-
.body-2 Pages
//-
v-spacer
//- v-btn(icon): v-icon
forward
//- v-btn(icon): v-icon
delete
//-
v-list(dense)
//-
v-list-item
//- v-list-item-avatar: v-icon insert_drive_file
//-
v-list-item-title File A
//-
v-divider
//-
v-list-item
//- v-list-item-avatar: v-icon insert_drive_file
//-
v-list-item-title File B
//-
v-divider
//-
v-list-item
//- v-list-item-avatar: v-icon insert_drive_file
//-
v-list-item-title File C
//-
v-divider
//-
v-list-item
//- v-list-item-avatar: v-icon insert_drive_file
//-
v-list-item-title File D
.d-flex(style='min-height:400px;')
v-flex.grey(xs4,
:class='darkMode ? `darken-4` : `lighten-3`')
v-toolbar(color='grey darken-3', dark, dense, flat)
.body-2 Folders
//-
v-spacer
//-
v-btn(icon): v-icon create_new_folder
v-treeview(
v-model='tree'
:items='treeFolders'
:load-children='fetchFolders'
activatable
open-on-click
hoverable
)
template(slot='prepend', slot-scope='{ item, open, leaf }')
v-icon mdi-
{{
open
?
'folder-
open'
:
'folder'
}}
v-flex(xs8)
v-toolbar(color='grey darken-2', dark, dense, flat)
.body-2 Pages
v-spacer
v-btn(icon): v-icon mdi-
forward
v-btn(icon): v-icon mdi-
delete
v-list(dense)
v-list-item
v-list-item-icon: v-icon mdi-file-document-box
v-list-item-title File A
v-divider
v-list-item
v-list-item-icon: v-icon mdi-file-document-box
v-list-item-title File B
v-divider
v-list-item
v-list-item-icon: v-icon mdi-file-document-box
v-list-item-title File C
v-divider
v-list-item
v-list-item-icon: v-icon mdi-file-document-box
v-list-item-title File D
v-card-actions.grey.pa-2(:class='darkMode ? `darken-3-d5` : `lighten-1`')
v-select(
solo
...
...
@@ -58,7 +58,7 @@
hide-details
single-line
:items='namespaces'
style='flex: 0 0 100px;'
style='flex: 0 0 100px;
border-radius: 4px 0 0 4px;
'
v-model='currentLocale'
)
v-text-field(
...
...
@@ -68,6 +68,7 @@
v-model='currentPath'
flat
clearable
style='border-radius: 0 4px 4px 0;'
)
v-card-chin
v-spacer
...
...
server/app/data.yml
View file @
38c33c58
...
...
@@ -75,14 +75,18 @@ jobs:
onInit
:
true
schedule
:
PT15M
offlineSkip
:
false
repeat
:
true
syncGraphLocales
:
onInit
:
true
schedule
:
P1D
offlineSkip
:
true
syncGraphUpdates
:
repeat
:
true
rebuildTree
:
onInit
:
true
schedule
:
P1D
offlineSkip
:
true
offlineSkip
:
false
repeat
:
false
immediate
:
true
worker
:
true
groups
:
defaultPermissions
:
-
'
read:pages'
...
...
server/core/scheduler.js
View file @
38c33c58
...
...
@@ -99,12 +99,13 @@ module.exports = {
return
}
const
schedule
=
(
configHelper
.
isValidDurationString
(
queueParams
.
schedule
))
?
queueParams
.
schedule
:
_
.
get
(
WIKI
.
config
,
queueParams
.
schedule
)
const
schedule
=
(
configHelper
.
isValidDurationString
(
queueParams
.
schedule
))
?
queueParams
.
schedule
:
'P1D'
this
.
registerJob
({
name
:
_
.
kebabCase
(
queueName
),
immediate
:
queueParams
.
onInit
,
immediate
:
_
.
get
(
queueParams
,
'onInit'
,
false
)
,
schedule
:
schedule
,
repeat
:
true
repeat
:
_
.
get
(
queueParams
,
'repeat'
,
false
),
worker
:
_
.
get
(
queueParams
,
'worker'
,
false
)
})
})
},
...
...
server/graph/resolvers/asset.js
View file @
38c33c58
...
...
@@ -97,7 +97,7 @@ module.exports = {
}
// Check source asset permissions
const
assetSourcePath
=
(
asset
.
folderId
)
?
hierarchy
.
map
(
h
=>
h
.
slug
).
join
(
'/'
)
+
`/
${
filename
}
`
:
filename
const
assetSourcePath
=
(
asset
.
folderId
)
?
hierarchy
.
map
(
h
=>
h
.
slug
).
join
(
'/'
)
+
`/
${
asset
.
filename
}
`
:
asset
.
filename
if
(
!
WIKI
.
auth
.
checkAccess
(
context
.
req
.
user
,
[
'manage:assets'
],
{
path
:
assetSourcePath
}))
{
throw
new
WIKI
.
Error
.
AssetRenameForbidden
()
}
...
...
@@ -118,6 +118,16 @@ module.exports = {
// Delete old asset cache
await
asset
.
deleteAssetCache
()
// Rename in Storage
await
WIKI
.
models
.
storage
.
assetEvent
({
event
:
'renamed'
,
asset
:
{
...
asset
,
sourcePath
:
assetSourcePath
,
destinationPath
:
assetTargetPath
}
})
return
{
responseResult
:
graphHelper
.
generateSuccess
(
'Asset has been renamed successfully.'
)
}
...
...
@@ -145,6 +155,12 @@ module.exports = {
await
WIKI
.
models
.
assets
.
query
().
deleteById
(
args
.
id
)
await
asset
.
deleteAssetCache
()
// Delete from Storage
await
WIKI
.
models
.
storage
.
assetEvent
({
event
:
'deleted'
,
asset
})
return
{
responseResult
:
graphHelper
.
generateSuccess
(
'Asset has been deleted successfully.'
)
}
...
...
server/jobs/rebuild-tree.js
0 → 100644
View file @
38c33c58
const
_
=
require
(
'lodash'
)
/* global WIKI */
module
.
exports
=
async
(
pageId
)
=>
{
WIKI
.
logger
.
info
(
`Rebuilding page tree...`
)
try
{
WIKI
.
models
=
require
(
'../core/db'
).
init
()
await
WIKI
.
configSvc
.
loadFromDb
()
await
WIKI
.
configSvc
.
applyFlags
()
await
WIKI
.
models
.
knex
.
table
(
'pageTree'
).
truncate
()
const
pages
=
await
WIKI
.
models
.
pages
.
query
().
select
(
'id'
,
'path'
,
'localeCode'
,
'title'
,
'isPrivate'
,
'privateNS'
).
orderBy
([
'localeCode'
,
'path'
])
let
tree
=
[]
let
pik
=
0
for
(
const
page
of
pages
)
{
const
pagePaths
=
page
.
path
.
split
(
'/'
)
let
currentPath
=
''
let
depth
=
0
let
parentId
=
null
for
(
const
part
of
pagePaths
)
{
depth
++
const
isFolder
=
(
depth
<
pagePaths
.
length
)
currentPath
=
currentPath
?
`
${
currentPath
}
/
${
part
}
`
:
part
const
found
=
_
.
find
(
tree
,
{
localeCode
:
page
.
localeCode
,
path
:
currentPath
})
if
(
!
found
)
{
pik
++
tree
.
push
({
id
:
pik
,
localeCode
:
page
.
localeCode
,
path
:
currentPath
,
depth
:
depth
,
title
:
isFolder
?
part
:
page
.
title
,
isFolder
:
isFolder
,
isPrivate
:
!
isFolder
&&
page
.
isPrivate
,
privateNS
:
!
isFolder
?
page
.
privateNS
:
null
,
parent
:
parentId
,
pageId
:
isFolder
?
null
:
page
.
id
})
parentId
=
pik
}
else
{
parentId
=
found
.
id
}
}
}
if
(
tree
.
length
>
0
)
{
await
WIKI
.
models
.
knex
.
table
(
'pageTree'
).
insert
(
tree
)
}
await
WIKI
.
models
.
knex
.
destroy
()
WIKI
.
logger
.
info
(
`Rebuilding page tree: [ COMPLETED ]`
)
}
catch
(
err
)
{
WIKI
.
logger
.
error
(
`Rebuilding page tree: [ FAILED ]`
)
WIKI
.
logger
.
error
(
err
.
message
)
}
}
server/jobs/sync-git.js
deleted
100644 → 0
View file @
2883437a
'use strict'
// /* global WIKI */
// const Promise = require('bluebird')
// const fs = Promise.promisifyAll(require('fs-extra'))
// const klaw = require('klaw')
// const moment = require('moment')
// const path = require('path')
// const entryHelper = require('../helpers/entry')
module
.
exports
=
(
job
)
=>
{
return
true
// return WIKI.git.resync().then(() => {
// // -> Stream all documents
// let cacheJobs = []
// let jobCbStreamDocsResolve = null
// let jobCbStreamDocs = new Promise((resolve, reject) => {
// jobCbStreamDocsResolve = resolve
// })
// klaw(WIKI.REPOPATH).on('data', function (item) {
// if (path.extname(item.path) === '.md' && path.basename(item.path) !== 'README.md') {
// let entryPath = entryHelper.parsePath(entryHelper.getEntryPathFromFullPath(item.path))
// let cachePath = entryHelper.getCachePath(entryPath)
// // -> Purge outdated cache
// cacheJobs.push(
// fs.statAsync(cachePath).then((st) => {
// return moment(st.mtime).isBefore(item.stats.mtime) ? 'expired' : 'active'
// }).catch((err) => {
// return (err.code !== 'EEXIST') ? err : 'new'
// }).then((fileStatus) => {
// // -> Delete expired cache file
// if (fileStatus === 'expired') {
// return fs.unlinkAsync(cachePath).return(fileStatus)
// }
// return fileStatus
// }).then((fileStatus) => {
// // -> Update cache and search index
// if (fileStatus !== 'active') {
// return global.entries.updateCache(entryPath).then(entry => {
// process.send({
// action: 'searchAdd',
// content: entry
// })
// return true
// })
// }
// return true
// })
// )
// }
// }).on('end', () => {
// jobCbStreamDocsResolve(Promise.all(cacheJobs))
// })
// return jobCbStreamDocs
// }).then(() => {
// WIKI.logger.info('Git remote repository sync: DONE')
// return true
// })
}
server/models/assets.js
View file @
38c33c58
...
...
@@ -125,6 +125,14 @@ module.exports = class Asset extends Model {
// 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
)
{
...
...
server/models/pages.js
View file @
38c33c58
...
...
@@ -251,7 +251,7 @@ module.exports = class Page extends Model {
})
// -> Save Tags
if
(
opts
.
tags
.
length
>
0
)
{
if
(
opts
.
tags
&&
opts
.
tags
.
length
>
0
)
{
await
WIKI
.
models
.
tags
.
associateTags
({
tags
:
opts
.
tags
,
page
})
}
...
...
server/models/storage.js
View file @
38c33c58
...
...
@@ -180,6 +180,17 @@ module.exports = class Storage extends Model {
}
}
static
async
assetEvent
({
event
,
asset
})
{
try
{
for
(
let
target
of
this
.
targets
)
{
await
target
.
fn
[
`asset
${
_
.
capitalize
(
event
)}
`
](
asset
)
}
}
catch
(
err
)
{
WIKI
.
logger
.
warn
(
err
)
throw
err
}
}
static
async
executeAction
(
targetKey
,
handler
)
{
try
{
const
target
=
_
.
find
(
this
.
targets
,
[
'key'
,
targetKey
])
...
...
server/modules/storage/git/storage.js
View file @
38c33c58
...
...
@@ -25,6 +25,9 @@ const getContenType = (filePath) => {
}
const
getPagePath
=
(
filePath
)
=>
{
if
(
process
.
platform
===
'win32'
)
{
filePath
=
filePath
.
replace
(
/
\\
/g
,
'/'
)
}
let
meta
=
{
locale
:
'en'
,
path
:
_
.
initial
(
filePath
.
split
(
'.'
)).
join
(
''
)
...
...
@@ -194,7 +197,7 @@ module.exports = {
await
WIKI
.
models
.
pages
.
updatePage
({
id
:
currentPage
.
id
,
title
:
_
.
get
(
pageData
,
'title'
,
currentPage
.
title
),
description
:
_
.
get
(
pageData
,
'description'
,
currentPage
.
description
),
description
:
_
.
get
(
pageData
,
'description'
,
currentPage
.
description
)
||
''
,
isPublished
:
_
.
get
(
pageData
,
'isPublished'
,
currentPage
.
isPublished
),
isPrivate
:
false
,
content
:
pageData
.
content
,
...
...
@@ -209,7 +212,7 @@ module.exports = {
path
:
contentPath
.
path
,
locale
:
contentPath
.
locale
,
title
:
_
.
get
(
pageData
,
'title'
,
_
.
last
(
contentPath
.
path
.
split
(
'/'
))),
description
:
_
.
get
(
pageData
,
'description'
,
''
),
description
:
_
.
get
(
pageData
,
'description'
,
''
)
||
''
,
isPublished
:
_
.
get
(
pageData
,
'isPublished'
,
true
),
isPrivate
:
false
,
content
:
pageData
.
content
,
...
...
@@ -230,6 +233,7 @@ module.exports = {
})
}
else
{
WIKI
.
logger
.
warn
(
`(STORAGE/GIT) Failed to open
${
item
.
file
}
`
)
console
.
error
(
err
)
WIKI
.
logger
.
warn
(
err
)
}
}
...
...
@@ -310,7 +314,47 @@ module.exports = {
'--author'
:
`"
${
page
.
authorName
}
<
${
page
.
authorEmail
}
>"`
})
},
/**
* ASSET UPLOAD
*
* @param {Object} asset Asset to upload
*/
async
assetUploaded
(
asset
)
{
WIKI
.
logger
.
info
(
`(STORAGE/GIT) Committing new file
${
asset
.
path
}
...`
)
const
filePath
=
path
.
join
(
this
.
repoPath
,
asset
.
path
)
await
fs
.
outputFile
(
filePath
,
asset
,
'utf8'
)
await
this
.
git
.
add
(
`./
${
asset
.
path
}
`
)
await
this
.
git
.
commit
(
`docs: upload
${
asset
.
path
}
`
,
asset
.
path
,
{
'--author'
:
`"
${
asset
.
authorName
}
<
${
asset
.
authorEmail
}
>"`
})
},
/**
* ASSET DELETE
*
* @param {Object} asset Asset to upload
*/
async
assetDeleted
(
asset
)
{
WIKI
.
logger
.
info
(
`(STORAGE/GIT) Committing removed file
${
asset
.
path
}
...`
)
await
this
.
git
.
rm
(
`./
${
asset
.
path
}
`
)
await
this
.
git
.
commit
(
`docs: delete
${
asset
.
path
}
`
,
asset
.
path
,
{
'--author'
:
`"
${
asset
.
authorName
}
<
${
asset
.
authorEmail
}
>"`
})
},
/**
* ASSET RENAME
*
* @param {Object} asset Asset to upload
*/
async
assetRenamed
(
asset
)
{
WIKI
.
logger
.
info
(
`(STORAGE/GIT) Committing file move from
${
asset
.
sourcePath
}
to
${
asset
.
destinationPath
}
...`
)
await
this
.
git
.
mv
(
`./
${
asset
.
sourcePath
}
`
,
`./
${
asset
.
destinationPath
}
`
)
await
this
.
git
.
commit
(
`docs: rename
${
asset
.
sourcePath
}
to
${
asset
.
destinationPath
}
`
,
asset
.
destinationPath
,
{
'--author'
:
`"
${
asset
.
authorName
}
<
${
asset
.
authorEmail
}
>"`
})
},
/**
* HANDLERS
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment