User:Username/BlockAbuser.js: Difference between revisions
Jump to navigation
Jump to search
Content deleted Content added
No edit summary |
hopefully this makes my life easier |
||
| Line 1: | Line 1: | ||
mw.loader.using(['mediawiki.util', 'mediawiki.api', 'jquery'], function () { |
mw.loader.using(['mediawiki.util', 'mediawiki.api', 'jquery'], function () { |
||
// Only run on the exact Special:AbuseLog main page |
|||
if (mw.config.get(' |
if (mw.config.get('wgPageName') !== 'Special:AbuseLog') { |
||
return; |
return; |
||
} |
} |
||
| Line 6: | Line 7: | ||
const $content = $('#mw-content-text'); |
const $content = $('#mw-content-text'); |
||
const seenUsers = new Set(); |
const seenUsers = new Set(); |
||
const userData = {}; // username => { latestLogId, extraHits, $li } |
const userData = {}; // username => { latestLogId, extraHits, $li, $userLink } |
||
const ipRegex = /^(?:\d{1,3}\.){3}\d{1,3}$|:/; |
const ipRegex = /^(?:\d{1,3}\.){3}\d{1,3}$|:/; |
||
| Line 17: | Line 18: | ||
} |
} |
||
// |
// Scan all <li> entries (AbuseLog entries) |
||
$content.find('li').each(function () { |
$content.find('li').each(function () { |
||
const $li = $(this); |
const $li = $(this); |
||
// Find user link inside this <li> |
// Find first user link inside this <li> |
||
const $userLink = $li.find('a').filter(function () { |
const $userLink = $li.find('a').filter(function () { |
||
const href = $(this).attr('href') || ''; |
const href = $(this).attr('href') || ''; |
||
| Line 27: | Line 28: | ||
}).first(); |
}).first(); |
||
if ($userLink.length === 0) return; // no user link |
if ($userLink.length === 0) return; // no user link in this li |
||
const username = getUsernameFromHref($userLink.attr('href')); |
const username = getUsernameFromHref($userLink.attr('href')); |
||
| Line 33: | Line 34: | ||
if (ipRegex.test(username)) return; // skip IPs |
if (ipRegex.test(username)) return; // skip IPs |
||
// Find AbuseLog id from details |
// Find AbuseLog id from any 'details' or 'examine' link inside this <li> |
||
let logId = null; |
let logId = null; |
||
$li.find('a').each(function () { |
$li.find('a').each(function () { |
||
| Line 40: | Line 41: | ||
if (match) { |
if (match) { |
||
logId = match[1]; |
logId = match[1]; |
||
return false; // break |
return false; // break loop |
||
} |
} |
||
}); |
}); |
||
| Line 46: | Line 47: | ||
if (!logId) return; |
if (!logId) return; |
||
// |
// Store or update userData with most recent log id |
||
if (!userData[username]) { |
if (!userData[username]) { |
||
userData[username] = { latestLogId: logId, extraHits: 0, $li: $li, $userLink: $userLink }; |
userData[username] = { latestLogId: logId, extraHits: 0, $li: $li, $userLink: $userLink }; |
||
} else { |
} else { |
||
// Update latestLogId if newer |
|||
if (parseInt(logId) > parseInt(userData[username].latestLogId)) { |
if (parseInt(logId) > parseInt(userData[username].latestLogId)) { |
||
userData[username].latestLogId = logId; |
userData[username].latestLogId = logId; |
||
| Line 60: | Line 60: | ||
}); |
}); |
||
// |
// Insert checkboxes once per user, inside their latest abuse log <li> before username link |
||
Object.entries(userData).forEach(([username, data]) => { |
Object.entries(userData).forEach(([username, data]) => { |
||
if (data.$userLink.prev('.blockabuser-checkbox').length) |
if (data.$userLink.prev('.blockabuser-checkbox').length) return; // checkbox already exists |
||
return; // already has checkbox |
|||
} |
|||
const $checkbox = $('<input>', { |
const $checkbox = $('<input>', { |
||
type: 'checkbox', |
type: 'checkbox', |
||
| Line 80: | Line 79: | ||
}); |
}); |
||
// |
// Add the control button above the log |
||
const $btn = $('<button>') |
const $btn = $('<button>') |
||
.text('Open selected user AbuseLogs and generate summary') |
.text('Open selected user AbuseLogs and generate summary') |
||
| Line 105: | Line 104: | ||
const extraHits = parseInt($cb.data('extrahits'), 10); |
const extraHits = parseInt($cb.data('extrahits'), 10); |
||
// Open AbuseLog filtered by user |
// Open AbuseLog filtered by user in a new tab |
||
const abuseLogUrl = mw.util.getUrl('Special:AbuseLog', { |
const abuseLogUrl = mw.util.getUrl('Special:AbuseLog', { |
||
wpSearchUser: username |
wpSearchUser: username |
||
Revision as of 02:25, 21 January 2026
mw.loader.using(['mediawiki.util', 'mediawiki.api', 'jquery'], function () {
// Only run on the exact Special:AbuseLog main page
if (mw.config.get('wgPageName') !== 'Special:AbuseLog') {
return;
}
const $content = $('#mw-content-text');
const seenUsers = new Set();
const userData = {}; // username => { latestLogId, extraHits, $li, $userLink }
const ipRegex = /^(?:\d{1,3}\.){3}\d{1,3}$|:/;
// Helper: decode username from URL
function getUsernameFromHref(href) {
const parts = href.split('/wiki/User:');
if (parts.length < 2) return null;
return decodeURIComponent(parts[1]).replace(/_/g, ' ').trim();
}
// Scan all <li> entries (AbuseLog entries)
$content.find('li').each(function () {
const $li = $(this);
// Find first user link inside this <li>
const $userLink = $li.find('a').filter(function () {
const href = $(this).attr('href') || '';
return href.includes('/wiki/User:');
}).first();
if ($userLink.length === 0) return; // no user link in this li
const username = getUsernameFromHref($userLink.attr('href'));
if (!username) return;
if (ipRegex.test(username)) return; // skip IPs
// Find AbuseLog id from any 'details' or 'examine' link inside this <li>
let logId = null;
$li.find('a').each(function () {
const href = $(this).attr('href') || '';
const match = href.match(/Special:AbuseLog\/(\d+)/);
if (match) {
logId = match[1];
return false; // break loop
}
});
if (!logId) return;
// Store or update userData with most recent log id
if (!userData[username]) {
userData[username] = { latestLogId: logId, extraHits: 0, $li: $li, $userLink: $userLink };
} else {
if (parseInt(logId) > parseInt(userData[username].latestLogId)) {
userData[username].latestLogId = logId;
userData[username].$li = $li;
userData[username].$userLink = $userLink;
}
userData[username].extraHits++;
}
});
// Insert checkboxes once per user, inside their latest abuse log <li> before username link
Object.entries(userData).forEach(([username, data]) => {
if (data.$userLink.prev('.blockabuser-checkbox').length) return; // checkbox already exists
const $checkbox = $('<input>', {
type: 'checkbox',
class: 'blockabuser-checkbox',
'data-username': username,
'data-latestlogid': data.latestLogId,
'data-extrahits': data.extraHits
}).css({
marginRight: '6px',
verticalAlign: 'middle',
cursor: 'pointer'
}).attr('title', 'Select this user for block review');
data.$userLink.before($checkbox);
});
// Add the control button above the log
const $btn = $('<button>')
.text('Open selected user AbuseLogs and generate summary')
.css({
margin: '1em 0',
padding: '6px 12px',
cursor: 'pointer'
});
$content.prepend($btn);
$btn.on('click', function () {
const checked = $('.blockabuser-checkbox:checked');
if (!checked.length) {
alert('Please select at least one user.');
return;
}
let summaryLines = [];
checked.each(function () {
const $cb = $(this);
const username = $cb.data('username');
const latestLogId = $cb.data('latestlogid');
const extraHits = parseInt($cb.data('extrahits'), 10);
// Open AbuseLog filtered by user in a new tab
const abuseLogUrl = mw.util.getUrl('Special:AbuseLog', {
wpSearchUser: username
});
window.open(abuseLogUrl, '_blank');
// Compose summary line
let line = `[[Special:AbuseLog/${latestLogId}]]`;
if (extraHits > 0) {
line += ` (+[[Special:AbuseLog/${username}|${extraHits}]])`;
}
summaryLines.push(line);
});
const summaryText =
'Spambot or spam-only accounts detected. Details:\n' +
summaryLines.join('\n');
alert(summaryText);
});
});