-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkarma.js
94 lines (73 loc) · 2.33 KB
/
karma.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
const dirty = require("dirty");
const {Ok, Fail} = require("r-result");
const hour = 3600e3;
const KarmaChangeHistory = function () {
const lastChangeHistory = new Map(); // Map<String, Time>
return {
canChange(changer, topic) {
const now = Date.now();
const key = `${changer.toLowerCase()}\u{0}${topic.toLowerCase()}`;
const lastChange = lastChangeHistory.get(key);
const canChange = !(lastChange && ((now - lastChange) < hour));
if (canChange) {
lastChangeHistory.set(key, now);
}
return canChange;
}
}
};
const KarmaDb = function (databaseLocation) {
const db = dirty.Dirty(databaseLocation);
return {
increment (topic) {
db.update(topic, function (entry) {
return {score: entry ? entry.score + 1 : 1};
});
},
decrement (topic) {
db.update(topic, function (entry) {
return {score: entry ? entry.score - 1 : -1};
});
},
get (topic) {
const entry = db.get(topic);
return entry ? Ok(entry.score) : Fail();
},
top (limit) {
// Inline impl of .entries().
const entries = [];
db.forEach(function (topic, {score}) {
entries.push({topic, score});
});
return entries.sort(function ({score: lhs_score}, {score: rhs_score}) {
return rhs_score - lhs_score;
}).slice(0, limit);
}
};
};
const KarmaServer = function (databaseLocation) {
const db = KarmaDb(databaseLocation);
const changeHistory = KarmaChangeHistory();
return {
increment (changer, topic) {
topic = topic.toLowerCase();
if (changeHistory.canChange(changer, topic)) {
db.increment(topic);
};
},
decrement (changer, topic) {
topic = topic.toLowerCase();
if (changeHistory.canChange(changer, topic)) {
db.decrement(topic);
};
},
get (topic) {
topic = topic.toLowerCase();
return db.get(topic);
},
top (limit) {
return db.top(limit);
}
};
};
module.exports = KarmaServer;