mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-27 17:16:14 +01:00
feat: remove uid:<uid>:ignored:cids (#7099)
use cid:<cid>:ignorers instead
This commit is contained in:
committed by
GitHub
parent
7a9299f374
commit
263c918088
@@ -80,7 +80,8 @@ Categories.isIgnored = function (cids, uid, callback) {
|
|||||||
if (parseInt(uid, 10) <= 0) {
|
if (parseInt(uid, 10) <= 0) {
|
||||||
return setImmediate(callback, null, cids.map(() => false));
|
return setImmediate(callback, null, cids.map(() => false));
|
||||||
}
|
}
|
||||||
db.isSortedSetMembers('uid:' + uid + ':ignored:cids', cids, callback);
|
const keys = cids.map(cid => 'cid:' + cid + ':ignorers');
|
||||||
|
db.isMemberOfSortedSets(keys, uid, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Categories.getAllCidsFromSet = function (key, callback) {
|
Categories.getAllCidsFromSet = function (key, callback) {
|
||||||
|
|||||||
@@ -339,8 +339,8 @@ module.exports = function (db, module) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.isMemberOfSortedSets = function (keys, value, callback) {
|
module.isMemberOfSortedSets = function (keys, value, callback) {
|
||||||
if (!Array.isArray(keys)) {
|
if (!Array.isArray(keys) || !keys.length) {
|
||||||
return callback();
|
return setImmediate(callback, null, []);
|
||||||
}
|
}
|
||||||
value = helpers.valueToString(value);
|
value = helpers.valueToString(value);
|
||||||
db.collection('objects').find({ _key: { $in: keys }, value: value }, { projection: { _id: 0, score: 0 } }).toArray(function (err, results) {
|
db.collection('objects').find({ _key: { $in: keys }, value: value }, { projection: { _id: 0, score: 0 } }).toArray(function (err, results) {
|
||||||
|
|||||||
@@ -473,8 +473,8 @@ SELECT z."value" v
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.isMemberOfSortedSets = function (keys, value, callback) {
|
module.isMemberOfSortedSets = function (keys, value, callback) {
|
||||||
if (!Array.isArray(keys)) {
|
if (!Array.isArray(keys) || !keys.length) {
|
||||||
return callback();
|
return setImmediate(callback, null, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = helpers.valueToString(value);
|
value = helpers.valueToString(value);
|
||||||
|
|||||||
@@ -206,6 +206,9 @@ module.exports = function (redisClient, module) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.isMemberOfSortedSets = function (keys, value, callback) {
|
module.isMemberOfSortedSets = function (keys, value, callback) {
|
||||||
|
if (!Array.isArray(keys) || !keys.length) {
|
||||||
|
return setImmediate(callback, null, []);
|
||||||
|
}
|
||||||
helpers.execKeysValue(redisClient, 'batch', 'zscore', keys, value, function (err, results) {
|
helpers.execKeysValue(redisClient, 'batch', 'zscore', keys, value, function (err, results) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var async = require('async');
|
const async = require('async');
|
||||||
|
const _ = require('lodash');
|
||||||
|
|
||||||
var db = require('../database');
|
const db = require('../database');
|
||||||
var privileges = require('../privileges');
|
const privileges = require('../privileges');
|
||||||
var user = require('../user');
|
const user = require('../user');
|
||||||
var meta = require('../meta');
|
const categories = require('../categories');
|
||||||
var plugins = require('../plugins');
|
const meta = require('../meta');
|
||||||
|
const plugins = require('../plugins');
|
||||||
|
|
||||||
module.exports = function (Topics) {
|
module.exports = function (Topics) {
|
||||||
Topics.getSortedTopics = function (params, callback) {
|
Topics.getSortedTopics = function (params, callback) {
|
||||||
@@ -117,6 +119,8 @@ module.exports = function (Topics) {
|
|||||||
const filter = params.filter;
|
const filter = params.filter;
|
||||||
const uid = params.uid;
|
const uid = params.uid;
|
||||||
|
|
||||||
|
let topicData;
|
||||||
|
let topicCids;
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
if (filter === 'watched') {
|
if (filter === 'watched') {
|
||||||
@@ -133,35 +137,29 @@ module.exports = function (Topics) {
|
|||||||
privileges.topics.filterTids('read', tids, uid, next);
|
privileges.topics.filterTids('read', tids, uid, next);
|
||||||
},
|
},
|
||||||
function (tids, next) {
|
function (tids, next) {
|
||||||
|
Topics.getTopicsFields(tids, ['uid', 'tid', 'cid'], next);
|
||||||
|
},
|
||||||
|
function (_topicData, next) {
|
||||||
|
topicData = _topicData;
|
||||||
|
topicCids = _.uniq(topicData.map(topic => topic.cid)).filter(Boolean);
|
||||||
|
|
||||||
async.parallel({
|
async.parallel({
|
||||||
ignoredCids: function (next) {
|
ignoredCids: function (next) {
|
||||||
if (filter === 'watched' || meta.config.disableRecentCategoryFilter) {
|
if (filter === 'watched' || meta.config.disableRecentCategoryFilter) {
|
||||||
return next(null, []);
|
return next(null, []);
|
||||||
}
|
}
|
||||||
user.getIgnoredCategories(uid, next);
|
categories.isIgnored(topicCids, uid, next);
|
||||||
},
|
|
||||||
topicData: function (next) {
|
|
||||||
Topics.getTopicsFields(tids, ['uid', 'tid', 'cid'], next);
|
|
||||||
},
|
},
|
||||||
|
filtered: async.apply(user.blocks.filter, uid, topicData),
|
||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (results, next) {
|
function (results, next) {
|
||||||
user.blocks.filter(uid, results.topicData, function (err, filtered) {
|
const isCidIgnored = _.zipObject(topicCids, results.ignoredCids);
|
||||||
if (err) {
|
topicData = results.filtered;
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
results.topicData = filtered;
|
|
||||||
next(null, results);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function (results, next) {
|
|
||||||
const cids = params.cids && params.cids.map(String);
|
const cids = params.cids && params.cids.map(String);
|
||||||
tids = results.topicData.filter(function (topic) {
|
tids = topicData.filter(function (topic) {
|
||||||
if (topic && topic.cid) {
|
return topic && topic.cid && !isCidIgnored[topic.cid] && (!cids || (cids.length && cids.includes(topic.cid.toString())));
|
||||||
return !results.ignoredCids.includes(topic.cid.toString()) && (!cids || (cids.length && cids.includes(topic.cid.toString())));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}).map(topic => topic.tid);
|
}).map(topic => topic.tid);
|
||||||
plugins.fireHook('filter:topics.filterSortedTids', { tids: tids, params: params }, next);
|
plugins.fireHook('filter:topics.filterSortedTids', { tids: tids, params: params }, next);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ module.exports = function (Topics) {
|
|||||||
db.sortedSetScores('uid:' + uid + ':followed_tids', tids, next);
|
db.sortedSetScores('uid:' + uid + ':followed_tids', tids, next);
|
||||||
},
|
},
|
||||||
ignoredCids: function (next) {
|
ignoredCids: function (next) {
|
||||||
user.getIgnoredCategories(uid, next);
|
categories.isIgnored(cids, uid, next);
|
||||||
},
|
},
|
||||||
readableCids: function (next) {
|
readableCids: function (next) {
|
||||||
privileges.categories.filterCids('read', cids, uid, next);
|
privileges.categories.filterCids('read', cids, uid, next);
|
||||||
@@ -205,6 +205,7 @@ module.exports = function (Topics) {
|
|||||||
function (results, next) {
|
function (results, next) {
|
||||||
cid = cid && cid.map(String);
|
cid = cid && cid.map(String);
|
||||||
results.readableCids = results.readableCids.map(String);
|
results.readableCids = results.readableCids.map(String);
|
||||||
|
const isCidIgnored = _.zipObject(cids, results.ignoredCids);
|
||||||
|
|
||||||
topicData.forEach(function (topic, index) {
|
topicData.forEach(function (topic, index) {
|
||||||
function cidMatch(topicCid) {
|
function cidMatch(topicCid) {
|
||||||
@@ -213,7 +214,7 @@ module.exports = function (Topics) {
|
|||||||
|
|
||||||
if (topic && topic.cid && cidMatch(topic.cid) && !blockedUids.includes(parseInt(topic.uid, 10))) {
|
if (topic && topic.cid && cidMatch(topic.cid) && !blockedUids.includes(parseInt(topic.uid, 10))) {
|
||||||
topic.tid = parseInt(topic.tid, 10);
|
topic.tid = parseInt(topic.tid, 10);
|
||||||
if ((results.isTopicsFollowed[index] || !results.ignoredCids.includes(String(topic.cid)))) {
|
if ((results.isTopicsFollowed[index] || !isCidIgnored[topic.cid])) {
|
||||||
counts[''] += 1;
|
counts[''] += 1;
|
||||||
tidsByFilter[''].push(topic.tid);
|
tidsByFilter[''].push(topic.tid);
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/upgrades/1.11.1/remove_ignored_cids_per_user.js
Normal file
21
src/upgrades/1.11.1/remove_ignored_cids_per_user.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var db = require('../../database');
|
||||||
|
|
||||||
|
var batch = require('../../batch');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'Remove uid:<uid>:ignored:cids',
|
||||||
|
timestamp: Date.UTC(2018, 11, 11),
|
||||||
|
method: function (callback) {
|
||||||
|
const progress = this.progress;
|
||||||
|
|
||||||
|
batch.processSortedSet('users:joindate', function (uids, next) {
|
||||||
|
progress.incr(uids.length);
|
||||||
|
const keys = uids.map(uid => 'uid:' + uid + ':ignored:cids');
|
||||||
|
db.deleteAll(keys, next);
|
||||||
|
}, {
|
||||||
|
progress: this.progress,
|
||||||
|
}, callback);
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -10,7 +10,19 @@ module.exports = function (User) {
|
|||||||
if (parseInt(uid, 10) <= 0) {
|
if (parseInt(uid, 10) <= 0) {
|
||||||
return setImmediate(callback, null, []);
|
return setImmediate(callback, null, []);
|
||||||
}
|
}
|
||||||
db.getSortedSetRange('uid:' + uid + ':ignored:cids', 0, -1, callback);
|
let cids;
|
||||||
|
async.waterfall([
|
||||||
|
function (next) {
|
||||||
|
categories.getAllCidsFromSet('categories:cid', next);
|
||||||
|
},
|
||||||
|
function (_cids, next) {
|
||||||
|
cids = _cids;
|
||||||
|
db.isMemberOfSortedSets(cids.map(cid => 'cid:' + cid + ':ignorers'), uid, next);
|
||||||
|
},
|
||||||
|
function (isMembers, next) {
|
||||||
|
next(null, cids.filter((cid, index) => isMembers[index]));
|
||||||
|
},
|
||||||
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
User.getWatchedCategories = function (uid, callback) {
|
User.getWatchedCategories = function (uid, callback) {
|
||||||
@@ -46,9 +58,7 @@ module.exports = function (User) {
|
|||||||
if (!exists) {
|
if (!exists) {
|
||||||
return next(new Error('[[error:no-category]]'));
|
return next(new Error('[[error:no-category]]'));
|
||||||
}
|
}
|
||||||
db.sortedSetAdd('uid:' + uid + ':ignored:cids', Date.now(), cid, next);
|
|
||||||
},
|
|
||||||
function (next) {
|
|
||||||
db.sortedSetAdd('cid:' + cid + ':ignorers', Date.now(), uid, next);
|
db.sortedSetAdd('cid:' + cid + ':ignorers', Date.now(), uid, next);
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
@@ -67,9 +77,7 @@ module.exports = function (User) {
|
|||||||
if (!exists) {
|
if (!exists) {
|
||||||
return next(new Error('[[error:no-category]]'));
|
return next(new Error('[[error:no-category]]'));
|
||||||
}
|
}
|
||||||
db.sortedSetRemove('uid:' + uid + ':ignored:cids', cid, next);
|
|
||||||
},
|
|
||||||
function (next) {
|
|
||||||
db.sortedSetRemove('cid:' + cid + ':ignorers', uid, next);
|
db.sortedSetRemove('cid:' + cid + ':ignorers', uid, next);
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ module.exports = function (User) {
|
|||||||
'uid:' + uid + ':chats', 'uid:' + uid + ':chats:unread',
|
'uid:' + uid + ':chats', 'uid:' + uid + ':chats:unread',
|
||||||
'uid:' + uid + ':chat:rooms', 'uid:' + uid + ':chat:rooms:unread',
|
'uid:' + uid + ':chat:rooms', 'uid:' + uid + ':chat:rooms:unread',
|
||||||
'uid:' + uid + ':upvote', 'uid:' + uid + ':downvote',
|
'uid:' + uid + ':upvote', 'uid:' + uid + ':downvote',
|
||||||
'uid:' + uid + ':ignored:cids', 'uid:' + uid + ':flag:pids',
|
'uid:' + uid + ':flag:pids',
|
||||||
'uid:' + uid + ':sessions', 'uid:' + uid + ':sessionUUID:sessionId',
|
'uid:' + uid + ':sessions', 'uid:' + uid + ':sessionUUID:sessionId',
|
||||||
];
|
];
|
||||||
db.deleteAll(keys, next);
|
db.deleteAll(keys, next);
|
||||||
|
|||||||
@@ -627,6 +627,15 @@ describe('Sorted Set methods', function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return empty array if keys is empty array', function (done) {
|
||||||
|
db.isMemberOfSortedSets([], 'value2', function (err, isMembers) {
|
||||||
|
assert.ifError(err);
|
||||||
|
assert.equal(arguments.length, 2);
|
||||||
|
assert.deepEqual(isMembers, []);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getSortedSetsMembers', function () {
|
describe('getSortedSetsMembers', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user