Browse Source

feat: save page + create event for storage targets

pull/621/head
NGPixel 6 years ago
parent
commit
076e923d48
22 changed files with 158 additions and 89 deletions
  1. 7
      client/components/admin/admin-contribute.vue
  2. 2
      client/components/editor.vue
  3. 1
      client/components/editor/editor-code.vue
  4. 4
      client/graph/editor/create.gql
  5. 13
      client/store/editor.js
  6. 7
      server/app/data.yml
  7. 10
      server/core/queue.js
  8. 20
      server/db/models/pages.js
  9. 15
      server/db/models/storage.js
  10. 1
      server/db/models/users.js
  11. 11
      server/graph/resolvers/page.js
  12. 10
      server/graph/schemas/page.graphql
  13. 20
      server/jobs/sync-storage.js
  14. 14
      server/modules/storage/azure/storage.js
  15. 14
      server/modules/storage/digitalocean/storage.js
  16. 14
      server/modules/storage/disk/storage.js
  17. 14
      server/modules/storage/dropbox/storage.js
  18. 14
      server/modules/storage/gdrive/storage.js
  19. 14
      server/modules/storage/git/storage.js
  20. 14
      server/modules/storage/onedrive/storage.js
  21. 14
      server/modules/storage/s3/storage.js
  22. 14
      server/modules/storage/scp/storage.js

7
client/components/admin/admin-contribute.vue

@ -12,10 +12,15 @@
v-divider.mt-3 v-divider.mt-3
v-subheader {{ $t('admin:contribute.fundOurWork') }} v-subheader {{ $t('admin:contribute.fundOurWork') }}
.body-1.pl-3 {{ $t('admin:contribute.openCollective') }} .body-1.pl-3 {{ $t('admin:contribute.openCollective') }}
v-card-actions.mt-3.ml-2
v-card-actions.ml-2
v-btn(depressed, color='primary', href='https://opencollective.com/wikijs') v-btn(depressed, color='primary', href='https://opencollective.com/wikijs')
v-icon(left) local_atm v-icon(left) local_atm
span {{ $t('admin:contribute.makeADonation') }} span {{ $t('admin:contribute.makeADonation') }}
.body-1.mt-3.pl-3 {{ $t('admin:contribute.tshirts') }}
v-card-actions.ml-2
v-btn(depressed, color='primary', href='https://wikijs.threadless.com')
v-icon(left) shopping_cart
span {{ $t('admin:contribute.shop') }}
v-divider.mt-3 v-divider.mt-3
v-subheader {{ $t('admin:contribute.contribute') }} v-subheader {{ $t('admin:contribute.contribute') }}
.body-1.pl-3 .body-1.pl-3

2
client/components/editor.vue

@ -94,9 +94,11 @@ export default {
const resp = await this.$apollo.mutate({ const resp = await this.$apollo.mutate({
mutation: createPageMutation, mutation: createPageMutation,
variables: { variables: {
content: this.$store.get('editor/content'),
description: this.$store.get('editor/description'), description: this.$store.get('editor/description'),
editor: 'markdown', editor: 'markdown',
locale: this.$store.get('editor/locale'), locale: this.$store.get('editor/locale'),
isPrivate: false,
isPublished: this.$store.get('editor/isPublished'), isPublished: this.$store.get('editor/isPublished'),
path: this.$store.get('editor/path'), path: this.$store.get('editor/path'),
publishEndDate: this.$store.get('editor/publishEndDate'), publishEndDate: this.$store.get('editor/publishEndDate'),

1
client/components/editor/editor-code.vue

@ -220,6 +220,7 @@ export default {
}, },
onCmInput: _.debounce(function (newContent) { onCmInput: _.debounce(function (newContent) {
linesMap = [] linesMap = []
this.$store.set('editor/content', newContent)
this.previewHTML = md.render(newContent) this.previewHTML = md.render(newContent)
this.$nextTick(() => { this.$nextTick(() => {
Prism.highlightAllUnder(this.$refs.editorPreview) Prism.highlightAllUnder(this.$refs.editorPreview)

4
client/graph/editor/create.gql

@ -1,6 +1,6 @@
mutation ($description: String, $editor: String, $isPublished: Boolean!, $locale: String!, $path: String!, $publishEndDate: Date, $publishStartDate: Date, $tags: [String], $title: String!) {
mutation ($content: String!, $description: String!, $editor: String!, $isPrivate: Boolean!, $isPublished: Boolean!, $locale: String!, $path: String!, $publishEndDate: Date, $publishStartDate: Date, $tags: [String]!, $title: String!) {
pages { pages {
create(description: $description, editor: $editor, isPublished: $isPublished, locale: $locale, path: $path, publishEndDate: $publishEndDate, publishStartDate: $publishStartDate, tags: $tags, title: $title) {
create(content: $content, description: $description, editor: $editor, isPrivate: $isPrivate, isPublished: $isPublished, locale: $locale, path: $path, publishEndDate: $publishEndDate, publishStartDate: $publishStartDate, tags: $tags, title: $title) {
responseResult { responseResult {
succeeded succeeded
errorCode errorCode

13
client/store/editor.js

@ -1,15 +1,16 @@
import { make } from 'vuex-pathify' import { make } from 'vuex-pathify'
const state = { const state = {
title: '',
content: '',
description: '', description: '',
tags: [],
path: '',
isPublished: true, isPublished: true,
publishStartDate: '',
publishEndDate: '',
locale: 'en', locale: 'en',
mode: 'create'
mode: 'create',
path: '',
publishEndDate: '',
publishStartDate: '',
tags: [],
title: ''
} }
export default { export default {

7
server/app/data.yml

@ -61,12 +61,19 @@ jobs:
fetchGraphLocale: fetchGraphLocale:
onInit: false onInit: false
cron: false cron: false
concurrency: 0
purgeUploads: purgeUploads:
onInit: true onInit: true
cron: '*/15 * * * *' cron: '*/15 * * * *'
concurrency: 0
syncGraphLocales: syncGraphLocales:
onInit: true onInit: true
cron: '0 0 * * *' cron: '0 0 * * *'
concurrency: 0
syncStorage:
onInit: false
cron: false
concurrency: 1
telemetry: telemetry:
BUGSNAG_ID: 'bb4b324d0675bcbba10025617fd2cec8' BUGSNAG_ID: 'bb4b324d0675bcbba10025617fd2cec8'
BUGSNAG_REMOTE: 'https://notify.bugsnag.com' BUGSNAG_REMOTE: 'https://notify.bugsnag.com'

10
server/core/queue.js

@ -10,10 +10,14 @@ module.exports = {
init() { init() {
_.forOwn(WIKI.data.jobs, (queueParams, queueName) => { _.forOwn(WIKI.data.jobs, (queueParams, queueName) => {
this.job[queueName] = new Bull(queueName, { this.job[queueName] = new Bull(queueName, {
prefix: `q-${WIKI.config.ha.uid}`,
prefix: `queue`,
redis: WIKI.config.redis redis: WIKI.config.redis
}) })
this.job[queueName].process(path.join(WIKI.SERVERPATH, `jobs/${_.kebabCase(queueName)}.js`))
if (queueParams.concurrency > 0) {
this.job[queueName].process(queueParams.concurrency, path.join(WIKI.SERVERPATH, `jobs/${_.kebabCase(queueName)}.js`))
} else {
this.job[queueName].process(path.join(WIKI.SERVERPATH, `jobs/${_.kebabCase(queueName)}.js`))
}
}) })
return this return this
}, },
@ -36,7 +40,7 @@ module.exports = {
return Promise.each(_.keys(WIKI.data.jobs), queueName => { return Promise.each(_.keys(WIKI.data.jobs), queueName => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let keyStream = WIKI.redis.scanStream({ let keyStream = WIKI.redis.scanStream({
match: `q-${WIKI.config.ha.uid}:${queueName}:*`
match: `queue:${queueName}:*`
}) })
keyStream.on('data', resultKeys => { keyStream.on('data', resultKeys => {
if (resultKeys.length > 0) { if (resultKeys.length > 0) {

20
server/db/models/pages.js

@ -1,5 +1,7 @@
const Model = require('objection').Model const Model = require('objection').Model
/* global WIKI */
/** /**
* Pages model * Pages model
*/ */
@ -75,4 +77,22 @@ module.exports = class Page extends Model {
this.createdAt = new Date().toISOString() this.createdAt = new Date().toISOString()
this.updatedAt = new Date().toISOString() this.updatedAt = new Date().toISOString()
} }
static async createPage(opts) {
const page = await WIKI.db.pages.query().insertAndFetch({
authorId: opts.authorId,
content: opts.content,
description: opts.description,
editorKey: opts.editor,
isPrivate: opts.isPrivate,
isPublished: opts.isPublished,
localeCode: opts.locale,
path: opts.path,
publishEndDate: opts.publishEndDate,
publishStartDate: opts.publishStartDate,
title: opts.title
})
await WIKI.db.storage.createPage(page)
return page
}
} }

15
server/db/models/storage.js

@ -86,4 +86,19 @@ module.exports = class Storage extends Model {
WIKI.logger.error(err) WIKI.logger.error(err)
} }
} }
static async createPage(page) {
const targets = await WIKI.db.storage.query().where('isEnabled', true)
if (targets && targets.length > 0) {
_.forEach(targets, target => {
WIKI.queue.job.syncStorage.add({
event: 'created',
target,
page
}, {
removeOnComplete: true
})
})
}
}
} }

1
server/db/models/users.js

@ -193,7 +193,6 @@ module.exports = class User extends Model {
} }
static async login (opts, context) { static async login (opts, context) {
console.info(context)
if (_.has(WIKI.auth.strategies, opts.strategy)) { if (_.has(WIKI.auth.strategies, opts.strategy)) {
_.set(context.req, 'body.email', opts.username) _.set(context.req, 'body.email', opts.username)
_.set(context.req, 'body.password', opts.password) _.set(context.req, 'body.password', opts.password)

11
server/graph/resolvers/page.js

@ -22,16 +22,9 @@ module.exports = {
}, },
PageMutation: { PageMutation: {
async create(obj, args, context) { async create(obj, args, context) {
const page = await WIKI.db.pages.query().insertAndFetch({
path: args.path,
title: args.title,
description: args.description,
const page = await WIKI.db.pages.createPage({
...args,
isPrivate: false, isPrivate: false,
isPublished: args.isPublished,
publishStartDate: args.publishStartDate,
publishEndDate: args.publishEndDate,
localeCode: args.locale,
editorKey: args.editor,
authorId: context.req.user.id authorId: context.req.user.id
}) })
return { return {

10
server/graph/schemas/page.graphql

@ -34,20 +34,22 @@ type PageQuery {
type PageMutation { type PageMutation {
create( create(
description: String
editor: String
content: String!
description: String!
editor: String!
isPublished: Boolean! isPublished: Boolean!
isPrivate: Boolean
isPrivate: Boolean!
locale: String! locale: String!
path: String! path: String!
publishEndDate: Date publishEndDate: Date
publishStartDate: Date publishStartDate: Date
tags: [String]
tags: [String]!
title: String! title: String!
): PageResponse ): PageResponse
update( update(
id: Int! id: Int!
content: String
description: String description: String
editor: String editor: String
isPublished: Boolean isPublished: Boolean

20
server/jobs/sync-storage.js

@ -0,0 +1,20 @@
require('../core/worker')
/* global WIKI */
module.exports = async (job) => {
WIKI.logger.info(`Syncing with storage provider ${job.data.target.title}...`)
try {
const target = require(`../modules/storage/${job.data.target.key}/storage.js`)
target[job.data.event].call({
config: job.data.target.config,
mode: job.data.target.mode,
page: job.data.page
})
WIKI.logger.info(`Syncing with storage provider ${job.data.target.title}: [ COMPLETED ]`)
} catch (err) {
WIKI.logger.error(`Syncing with storage provider ${job.data.target.title}: [ FAILED ]`)
WIKI.logger.error(err.message)
}
}

14
server/modules/storage/azure/storage.js

@ -1,23 +1,23 @@
module.exports = { module.exports = {
async activated(opts) {
async activated() {
}, },
async deactivated(opts) {
async deactivated() {
}, },
async init(opts) {
async init() {
}, },
async created(opts) {
async created() {
}, },
async updated(opts) {
async updated() {
}, },
async deleted(opts) {
async deleted() {
}, },
async renamed(opts) {
async renamed() {
} }
} }

14
server/modules/storage/digitalocean/storage.js

@ -1,23 +1,23 @@
module.exports = { module.exports = {
async activated(opts) {
async activated() {
}, },
async deactivated(opts) {
async deactivated() {
}, },
async init(opts) {
async init() {
}, },
async created(opts) {
async created() {
}, },
async updated(opts) {
async updated() {
}, },
async deleted(opts) {
async deleted() {
}, },
async renamed(opts) {
async renamed() {
} }
} }

14
server/modules/storage/disk/storage.js

@ -1,23 +1,23 @@
module.exports = { module.exports = {
async activated(opts) {
async activated() {
}, },
async deactivated(opts) {
async deactivated() {
}, },
async init(opts) {
async init() {
}, },
async created(opts) {
async created() {
}, },
async updated(opts) {
async updated() {
}, },
async deleted(opts) {
async deleted() {
}, },
async renamed(opts) {
async renamed() {
} }
} }

14
server/modules/storage/dropbox/storage.js

@ -1,23 +1,23 @@
module.exports = { module.exports = {
async activated(opts) {
async activated() {
}, },
async deactivated(opts) {
async deactivated() {
}, },
async init(opts) {
async init() {
}, },
async created(opts) {
async created() {
}, },
async updated(opts) {
async updated() {
}, },
async deleted(opts) {
async deleted() {
}, },
async renamed(opts) {
async renamed() {
} }
} }

14
server/modules/storage/gdrive/storage.js

@ -1,23 +1,23 @@
module.exports = { module.exports = {
async activated(opts) {
async activated() {
}, },
async deactivated(opts) {
async deactivated() {
}, },
async init(opts) {
async init() {
}, },
async created(opts) {
async created() {
}, },
async updated(opts) {
async updated() {
}, },
async deleted(opts) {
async deleted() {
}, },
async renamed(opts) {
async renamed() {
} }
} }

14
server/modules/storage/git/storage.js

@ -1,23 +1,23 @@
module.exports = { module.exports = {
async activated(opts) {
async activated() {
}, },
async deactivated(opts) {
async deactivated() {
}, },
async init(opts) {
async init() {
}, },
async created(opts) {
async created() {
}, },
async updated(opts) {
async updated() {
}, },
async deleted(opts) {
async deleted() {
}, },
async renamed(opts) {
async renamed() {
} }
} }

14
server/modules/storage/onedrive/storage.js

@ -1,23 +1,23 @@
module.exports = { module.exports = {
async activated(opts) {
async activated() {
}, },
async deactivated(opts) {
async deactivated() {
}, },
async init(opts) {
async init() {
}, },
async created(opts) {
async created() {
}, },
async updated(opts) {
async updated() {
}, },
async deleted(opts) {
async deleted() {
}, },
async renamed(opts) {
async renamed() {
} }
} }

14
server/modules/storage/s3/storage.js

@ -1,23 +1,23 @@
module.exports = { module.exports = {
async activated(opts) {
async activated() {
}, },
async deactivated(opts) {
async deactivated() {
}, },
async init(opts) {
async init() {
}, },
async created(opts) {
async created() {
}, },
async updated(opts) {
async updated() {
}, },
async deleted(opts) {
async deleted() {
}, },
async renamed(opts) {
async renamed() {
} }
} }

14
server/modules/storage/scp/storage.js

@ -1,23 +1,23 @@
module.exports = { module.exports = {
async activated(opts) {
async activated() {
}, },
async deactivated(opts) {
async deactivated() {
}, },
async init(opts) {
async init() {
}, },
async created(opts) {
async created() {
}, },
async updated(opts) {
async updated() {
}, },
async deleted(opts) {
async deleted() {
}, },
async renamed(opts) {
async renamed() {
} }
} }
Loading…
Cancel
Save