125 lines
3.2 KiB
JavaScript
125 lines
3.2 KiB
JavaScript
|
var _ = require('lodash'),
|
||
|
Events = require(__dirname + '/irc').Events;
|
||
|
|
||
|
function ListCache() {
|
||
|
this.lists = {};
|
||
|
};
|
||
|
|
||
|
// ========================================
|
||
|
// this object manages list caching, in a normal single client
|
||
|
// scenario, grabbing the list on request is fine, but irc-factory
|
||
|
// isnt really designed for single client usage
|
||
|
// the ircanywhere use case requires lists to be available to all, for
|
||
|
// all networks.
|
||
|
|
||
|
ListCache.prototype.requestList = function(ircObject, search, page, limit) {
|
||
|
if (!Events) {
|
||
|
Events = require(__dirname + '/irc').Events;
|
||
|
}
|
||
|
|
||
|
var self = this,
|
||
|
key = ircObject.key;
|
||
|
|
||
|
if (key === '') {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (!this.lists[key]) {
|
||
|
this.createList(ircObject);
|
||
|
ircObject.raw(['LIST']);
|
||
|
|
||
|
Events.once([ircObject.key, 'listend'], function() {
|
||
|
self.filterList(ircObject, search, page, limit);
|
||
|
});
|
||
|
// no cache is available? request one and wait to filter it
|
||
|
} else {
|
||
|
self.filterList(ircObject, search, page, limit);
|
||
|
// looks like we already have a cached list, pass it straight to filter
|
||
|
}
|
||
|
|
||
|
clearTimeout(this.lists[key].deleteTimer);
|
||
|
this.lists[key].deleteTimer = setTimeout(function() {
|
||
|
delete self.lists[key];
|
||
|
}, 600000);
|
||
|
// lets set a timer to trash this data if its not been requested in a while (10min)
|
||
|
// the only reason we cache it is to prevent people doing /list then /list, then /list
|
||
|
// and blocking the process
|
||
|
};
|
||
|
|
||
|
ListCache.prototype.filterList = function(ircObject, search, page, limit) {
|
||
|
var key = ircObject.key,
|
||
|
regex = new RegExp('(' + search + ')', 'i'),
|
||
|
list = this.lists[key];
|
||
|
|
||
|
if (key === '' || !list) {
|
||
|
return false;
|
||
|
}
|
||
|
// make sure the list exists
|
||
|
|
||
|
var output = {
|
||
|
list: [],
|
||
|
raw: [],
|
||
|
search: search.replace(/[-[\]{}()+?.,\\^$|#\s]/g, "\$&").replace(/\(\.\*\)/g, '*'),
|
||
|
page: page,
|
||
|
limit: limit,
|
||
|
time: new Date()
|
||
|
};
|
||
|
|
||
|
var clone = _.cloneDeep(list.list);
|
||
|
var buffer = _.sortBy(clone, function(channel) {
|
||
|
return 0 - channel.users;
|
||
|
});
|
||
|
// sort it
|
||
|
|
||
|
buffer = _.filter(buffer, function(channel) {
|
||
|
return regex.test(channel.channel);
|
||
|
});
|
||
|
// filter via the search parameters
|
||
|
|
||
|
buffer = _.take(_.rest(buffer, (page - 1) * limit), limit);
|
||
|
// paginate
|
||
|
|
||
|
for (var c in buffer) {
|
||
|
var channel = buffer[c];
|
||
|
output.raw.push(channel.raw);
|
||
|
delete buffer[c].raw;
|
||
|
}
|
||
|
// i don't really like this, but we pull .raw from channel objects
|
||
|
// and push it into the output
|
||
|
|
||
|
Events.emit([ircObject.key, 'list'], _.extend(output, {
|
||
|
list: buffer
|
||
|
}));
|
||
|
// emit the list event
|
||
|
};
|
||
|
|
||
|
ListCache.prototype.createList = function(ircObject) {
|
||
|
var key = ircObject.key;
|
||
|
if (key === '' || this.lists[key]) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
this.lists[key] = {
|
||
|
key: key,
|
||
|
requestedAt: new Date(),
|
||
|
deleteTimer: null,
|
||
|
list: []
|
||
|
};
|
||
|
};
|
||
|
|
||
|
ListCache.prototype.insertListData = function(ircObject, message) {
|
||
|
var key = ircObject.key;
|
||
|
if (key !== '' && !this.lists[key]) {
|
||
|
this.createList(key);
|
||
|
}
|
||
|
|
||
|
this.lists[key].list.push({
|
||
|
channel: message.params[1],
|
||
|
users: message.params[2],
|
||
|
topic: message.params[3],
|
||
|
raw: message.raw
|
||
|
});
|
||
|
};
|
||
|
// ========================================
|
||
|
|
||
|
exports.ListCache = new ListCache();
|