Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

listModerationBy #87

Merged
3 commits merged into from
May 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,22 @@ The objects in the output have the same form as `listByFlag()`.

Optionally collect results into `cb(err, rows)`.

#### cabal.moderation.listModerationBy(key, cb)

Return a readable object stream of moderation documents authored by `key`.

Each `row` object in the output is a document used for adding, removing, and
setting flags.

* `row.type` - `"flags/add"`, `"flags/set"`, or `"flags/remove"`
* `row.content.id` - string key target of this moderation operation
* `row.content.flags` - array of string flags for this operation
* `row.content.reason` - array of string flags for this operation
* `row.content.channel` - string channel name this operation applies to
* `row.timestamp` - number, when this action was made in milliseconds since 1970

Optionally collect results into `cb(err, rows)`.

#### cabal.moderation.getFlags({ id, channel }, cb)

Get a list of flags set for the user identified by `id` in `channel` as
Expand Down
9 changes: 6 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ var MEMBERSHIPS = 'j' // j for joined memberships..? :3
var MESSAGES = 'm'
var TOPICS = 't'
var USERS = 'u'
var MODERATION = 'x'
var MODERATION_AUTH = 'x'
var MODERATION_INFO = 'y'

module.exports = Cabal
module.exports.databaseVersion = DATABASE_VERSION
Expand Down Expand Up @@ -93,8 +94,10 @@ function Cabal (storage, key, opts) {
this.kcore.use('users', createUsersView(
sublevel(this.db, USERS, { valueEncoding: json })))
this.kcore.use('moderation', createModerationView(
this, sublevel(this.db, MODERATION, { valueEncoding: json }))
)
this,
sublevel(this.db, MODERATION_AUTH, { valueEncoding: json }),
sublevel(this.db, MODERATION_INFO, { valueEncoding: json })
))

this.messages = this.kcore.api.messages
this.channels = this.kcore.api.channels
Expand Down
55 changes: 45 additions & 10 deletions views/moderation.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ var collect = require('collect-stream')
var duplexify = require('duplexify')
var { nextTick } = process

module.exports = function (cabal, db) {
const MOD = 'm!'

module.exports = function (cabal, authDb, infoDb) {
var events = new EventEmitter()
var auth = mauth(db)
var auth = mauth(authDb)
auth.on('update', function (update) {
events.emit('update', update)
})
Expand Down Expand Up @@ -159,6 +161,22 @@ module.exports = function (cabal, db) {
if (cb) collect(ro, cb)
return ro
}),
listModerationBy: function (core, key, cb) {
var r = infoDb.createReadStream({
gt: MOD + key + '@',
lt: MOD + key + '@\uffff'
})
var out = through.obj(function (row, enc, next) {
cabal.getMessage(row.key.slice(MOD.length), function (err, doc) {
if (err) return next(err)
next(null, doc)
})
})
pump(r, out)
var ro = readonly(out)
if (cb) collect(ro, cb)
return ro
},
// ^--- queries above | updates below ---v
setFlags: function (core, opts, cb) {
publishFlagUpdate(core, 'set', opts, cb)
Expand Down Expand Up @@ -237,12 +255,20 @@ module.exports = function (cabal, db) {
function map (rows, next) {
next = once(next)
var batch = []
var infoBatch = []
var pending = 1
rows.forEach(function (row) {
if (!row.value || !row.value.content) return
var id = row.value.content.id
if (!id) return
if (/^flags\/(set|add|remove)$/.test(row.value.type)) {
infoBatch.push({
type: 'put',
key: MOD + row.key + '@' + row.seq,
value: ''
})
}
if (row.value.type === 'flags/set') {
var id = row.value.content.id
if (!id) return
var group = row.value.content.channel || '@'
var flags = checkLocal(
id, group, row.key,
Expand All @@ -257,8 +283,6 @@ module.exports = function (cabal, db) {
flags
})
} else if (row.value.type === 'flags/add') {
var id = row.value.content.id
if (!id) return
var group = row.value.content.channel || '@'
pending++
auth.getFlags({ group, id }, function (err, prevFlags) {
Expand All @@ -280,8 +304,6 @@ module.exports = function (cabal, db) {
if (--pending === 0) done()
})
} else if (row.value.type === 'flags/remove') {
var id = row.value.content.id
if (!id) return
var group = row.value.content.channel || '@'
pending++
auth.getFlags({ group, id }, function (err, flags) {
Expand All @@ -308,9 +330,22 @@ module.exports = function (cabal, db) {
})
if (--pending === 0) done()
function done () {
var pending = 1
if (batch.length > 0) {
auth.batch(batch, { skip: true }, next)
} else next()
pending++
auth.batch(batch, { skip: true }, function (err) {
if (err) next(err)
else if (--pending === 0) next()
})
}
if (infoBatch.length > 0) {
pending++
infoDb.batch(infoBatch, function (err) {
if (err) next(err)
else if (--pending === 0) next()
})
}
if (--pending === 0) next()
}
}

Expand Down