mirror of
https://github.com/wassname/talk.git
synced 2026-06-28 10:34:10 +08:00
156 lines
3.7 KiB
JavaScript
156 lines
3.7 KiB
JavaScript
const debug = require('debug')('talk:services:karma');
|
|
const UserModel = require('../models/user');
|
|
|
|
/**
|
|
* This will create an object with the property name of the action type as the
|
|
* key and an object as it's value. This will contain a RELIABLE, and UNRELIABLE
|
|
* property with the number of karma points associated with their particular
|
|
* state.
|
|
*
|
|
* If only the RELIABLE variable is provided, then it will also be used as the
|
|
* UNRELIABLE variable.
|
|
*
|
|
* The form of the environment variable is:
|
|
*
|
|
* <name>:<RELIABLE>,<UNRELIABLE>;<name>:<RELIABLE>,<UNRELIABLE>;...
|
|
*
|
|
* The default used is:
|
|
*
|
|
* comment:1,1;flag:-1,-1
|
|
*/
|
|
const parseThresholds = (thresholds) => thresholds
|
|
.split(';')
|
|
.filter((threshold) => threshold && threshold.length > 0)
|
|
.reduce((acc, threshold) => {
|
|
const thresholds = threshold.split(':');
|
|
if (thresholds.length < 2) {
|
|
return acc;
|
|
}
|
|
|
|
let [name, values] = thresholds;
|
|
let [RELIABLE, UNRELIABLE] = values.split(',').map((value) => parseInt(value));
|
|
|
|
if (!(name in acc)) {
|
|
acc[name] = {};
|
|
}
|
|
|
|
if (isNaN(UNRELIABLE) && !isNaN(RELIABLE)) {
|
|
acc[name].RELIABLE = RELIABLE;
|
|
acc[name].UNRELIABLE = RELIABLE;
|
|
} else {
|
|
if (!isNaN(UNRELIABLE)) {
|
|
acc[name].UNRELIABLE = UNRELIABLE;
|
|
}
|
|
|
|
if (!isNaN(RELIABLE)) {
|
|
acc[name].RELIABLE = RELIABLE;
|
|
}
|
|
}
|
|
|
|
return acc;
|
|
}, {
|
|
comment: {
|
|
RELIABLE: -1,
|
|
UNRELIABLE: -1
|
|
},
|
|
flag: {
|
|
RELIABLE: -1,
|
|
UNRELIABLE: -1
|
|
}
|
|
});
|
|
|
|
const THRESHOLDS = parseThresholds(process.env.TRUST_THRESHOLDS || '');
|
|
|
|
debug('using thresholds: ', THRESHOLDS);
|
|
|
|
/**
|
|
* KarmaModel represents the checkable properties of a user and wrapps the
|
|
* KarmaService function `isReliable` to work flexibly with the graph.
|
|
*/
|
|
class KarmaModel {
|
|
constructor(model) {
|
|
this.model = model;
|
|
}
|
|
|
|
get flagger() {
|
|
return KarmaService.isReliable('flag', this.model);
|
|
}
|
|
|
|
get commenter() {
|
|
return KarmaService.isReliable('comment', this.model);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* KarmaService provides interfaces for editing a user's karma.
|
|
*/
|
|
class KarmaService {
|
|
|
|
/**
|
|
* Model returns a KarmaModel based on the passed in user.
|
|
*/
|
|
static model(user) {
|
|
if (user === null || !user.metadata || !user.metadata.trust) {
|
|
return new KarmaModel({});
|
|
}
|
|
|
|
return new KarmaModel(user.metadata.trust);
|
|
}
|
|
|
|
/**
|
|
* Inspects the reliability of a property and returns it if known.
|
|
* @param {String} name - name of the property
|
|
* @param {Object} trust - object possibly containing the propertys
|
|
*/
|
|
static isReliable(name, trust) {
|
|
if (trust && trust[name]) {
|
|
if (trust[name].karma > THRESHOLDS[name].RELIABLE) {
|
|
return true;
|
|
} else if (trust[name].karma < THRESHOLDS[name].UNRELIABLE) {
|
|
return false;
|
|
}
|
|
} else if (THRESHOLDS[name].RELIABLE < 0) {
|
|
return true;
|
|
} else if (THRESHOLDS[name].UNRELIABLE > 0) {
|
|
return false;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* modifyUserKarma updates the user to adjust their karma, for either the `type`
|
|
* of 'comment' or 'flag'. If `multi` is true, then it assumes that `id` is an
|
|
* array of id's.
|
|
*/
|
|
static async modifyUser(id, direction = 1, type = 'comment', multi = false) {
|
|
const key = `metadata.trust.${type}.karma`;
|
|
|
|
let update = {
|
|
$inc: {
|
|
[key]: direction
|
|
}
|
|
};
|
|
|
|
if (multi) {
|
|
|
|
// If it was in multi-mode but there was no user's to adjust, bail.
|
|
if (id.length <= 0) {
|
|
return;
|
|
}
|
|
|
|
return UserModel.update({
|
|
id: {
|
|
$in: id
|
|
}
|
|
}, update, {
|
|
multi: true
|
|
});
|
|
}
|
|
|
|
return UserModel.update({id}, update);
|
|
}
|
|
}
|
|
|
|
module.exports = KarmaService;
|