/**
* @file IP Address Report builder
* @author Andrew Sayers
* @summary Build an IP address report
*/
/**
* @summary IP Address Report builder
* @constructor
* @param {Object} args report arguments
* @example
*
* var ip_report = new IPAddressReport({
* users: { username: ..., user_id: ... }, // user to apply action to
* bb : bb, // BulletinBoard object
* });
*/
function IPAddressReport(args) {
this.bb = args.bb;
this._users = args.users;
this._cache_timeout = 0;
this._cache_bbcode = '';
this._cache_html = '';
}
IPAddressReport.prototype = Object.create(null, {
bb : { writable: true, configurable: false },
_users : { writable: true, configurable: false },
_cache_timeout: { writable: true, configurable: false },
_cache_bbcode : { writable: true, configurable: false },
_cache_html : { writable: true, configurable: false },
});
IPAddressReport.prototype.constructor = IPAddressReport;
/**
* @summary Set the time after which the report will need to be redownloaded
* @param {Number} timeout (Epoch) time when the cache will expire
* @description the special values 0 and Infinity set the cache to
* immediately/never expire.
*/
IPAddressReport.prototype.cache_timeout = function(timeout) { this._cache_timeout = timeout }
/**
* @summary Set the list of affected users
* @param {Array.<Object>} users list of users
*/
IPAddressReport.prototype.users = function(users) { this._users = users }
/**
* @summary Get the report BBCode
* @return {jQuery.Promise}
*/
IPAddressReport.prototype.bbcode = function() { var report = this; return this.action().fire().then(function() { return report._cache_bbcode }) }
/**
* @summary Get the report HTML
* @return {jQuery.Promise}
*/
IPAddressReport.prototype.html = function() { var report = this; return this.action().fire().then(function() { return report._cache_html }) }
/**
* @summary Create an Action to download the report
* @return {Action} download the report and define the 'ip address report' key
*/
IPAddressReport.prototype.action = function() {
var report = this;
function user_link_bbcode(user) {
return (
( user.registration_ip ? '[b]' : '' ) +
'[URL="' + location.origin + report.bb.url_for.user_show({ user_id: user.user_id }) + '"]' + user.username + '[/URL]' +
( user.registration_ip ? '[/b]' : '' )
);
}
function user_link_html(user) {
return (
( user.registration_ip ? '<strong title="account was registered from this address">' : '' ) +
'<a href="' + location.origin + report.bb.url_for.user_show({ user_id: user.user_id }) + '">' + user.username + '</a>' +
( user.registration_ip ? '</a>' : '' )
);
}
var skip, ips, target_ids;
return new Action(
'IP address report',
new Action(
'IP address report: download',
{
fire: function() {
skip = report._cache_timeout > new Date().getTime();
ips = {};
target_ids = {};
report._users.forEach(function(user) { target_ids[user.user_id] = true });
}
},
new Action(
'IP address report: download one user',
this._users.map(function(user) {
return {
description: function() { return [{ type: 'user IPs', target: user }] },
fire : function(keys) {
if ( skip ) return;
return report.bb.user_ips(user).then(function(data) {
var ip_requests = [];
var registration_ip_seen = false;
function add_ip(ip) {
user = {
registration_ip: ip == data.registration_ip,
username: user.username,
user_id : user.user_id
};
registration_ip_seen |= user.registration_ip;
if ( ips.hasOwnProperty(ip) ) {
ips[ip].targets.push(user);
} else {
ips[ip] = { targets: [ user ], ip: ip };
ip_requests.push(
report.bb.ip_users( ip ).then(function(data) {
ips[ip].domain_name = data.domain_name;
ips[ip].non_targets = data.users.filter(function(user) { return !target_ids.hasOwnProperty(user.user_id) });
})
);
}
}
data.used_ips.forEach(add_ip);
if ( !registration_ip_seen ) add_ip(data.registration_ip);
return $.when.apply( $, ip_requests );
})
},
}
})
)
).then(
new Action(
'IP address report: build',
{
fire: function() {
if ( !skip ) {
report._cache_bbcode =
'[table]' +
'[tr][th]IP address[/th][th]Target accounts for address[/th][th]Non-target accounts for this address[/th][/tr]\n' +
Object.keys(ips).sort().map(function(ip) {
ip = ips[ip];
return '[tr][td][URL="' + location.origin + report.bb.url_for.moderation_ipsearch({ ip_address: ip.ip }) + '"]' + ( ip.domain_name || ip.ip ) + '[/URL][/td]' +
'[td]' + ip. targets.map(user_link_bbcode).join(', ') + '[/td]' +
'[td]' + ip.non_targets.map(user_link_bbcode).join(', ') + '[/td]' +
'[/tr]\n'
}).join('') +
'[/table]\n' +
'([b]Names in bold[/b] were registered from this address)\n';
report._cache_html =
'<table>' +
'<tr><th>IP address</th><th>Target accounts for address</th><th>Non-target accounts for this address</th></tr>\n' +
Object.keys(ips).sort().map(function(ip) {
ip = ips[ip];
return '<tr><td><a href="' + report.bb.url_for.moderation_ipsearch({ ip_address: ip.ip }) + '">' + ( ip.domain_name || ip.ip ) + '</a></td>' +
'<td>' + ip. targets.map(user_link_html).join(', ') + '</td>' +
'<td>' + ip.non_targets.map(user_link_html).join(', ') + '</td>' +
'</tr>\n'
}).join('') +
'<caption style="caption-side: bottom">(<strong>names in bold</strong> were registered from this address</caption>\n' +
'</table>\n';
report._cache_timeout = new Date().getTime() + 60000; // one minute
}
return $.Deferred().resolve({ keys: { 'ip address report': report._cache_bbcode } }).promise();
}
}
)
)
);
}