User:DreamRimmer/adminnewslettertools.js: Difference between revisions

Content deleted Content added
no luck (DR)
add convenient-discussions tag (DR)
 
(10 intermediate revisions by the same user not shown)
Line 7:
*/
$(document).ready(function() {
// Simple cache for API results
var apiCache = {};
var CACHE_DURATION = 10 * 60 * 1000; // 10 minutes
Line 56 ⟶ 55:
min: 2005,
max: new Date().getFullYear() + 1,
step: 1,
}).$element.css('width', '80px'), showButtons: true
}),
sectionSelect = new OO.ui.DropdownWidget({
menu: {
Line 614:
format: 'json'
}).then(revisions => {
const filtered = revisions.filter(rev => rev.tags && (rev.tags.includes('discussiontools-newtopic') || rev.tags.includes('convenient-discussions')));
return createEditTable('ArbCom topics', filtered, true);
});
Line 815:
return promise.then(results => {
return fetchPageBatch(batch).then(batchResults => {
// Add delay between batches except for the last one
if (index < batches.length - 1) {
return new Promise(resolve => {
Line 836 ⟶ 835:
function parseRfCs(wikitext, topicName) {
const rfcs = [];
const rfcEntryPattern = /'''\[\[([^\]|]+)(?:\|([^\]]+))?\]\]'''[\s\S]*?\{\{rfcquote\|text=((?:[^{}]|\s\S{[^{]*?)\}|\}[\s\S^}]*?(|\d{2}:\d{2(?:[^{}, ]|\d{1,2[^{]|\} [^}])*\w+ \d{4} \(UTC\})*)\}\}/ggi;
const now = new Date();
const currentUtcYear = now.getUTCFullYear();
Line 849:
let pageName, anchor, displayTitle;
const link = match[1];
displayTitle = match[2] || (anchor ? `${link}#${anchor}` : link);
if (link.includes('#')) {
[pageName, anchor] = link.split('#');
Line 857:
}
const timestampStrrfcText = match[43];
let timestampStr = null;
let daysDiff = null;
if (timestampStr) {
const tsMatchtimestampMatch = timestampStrrfcText.match(/(\d{2}):(\d{2}), (\d{1,2}) (\w+) (\d{4}) \(UTC\)/);
if (tsMatchtimestampMatch) {
const [_fullMatch, hour, minute, day, monthText, year] = tsMatchtimestampMatch;
const monthstimestampStr = [fullMatch;

const months = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
const monthNum = months.indexOf(monthText);

if (monthNum !== -1) {
const tsDate = new Date(Date.UTC(
parseInt(year, 10),
monthNum,
parseInt(day, 10),
parseInt(hour, 10),
parseInt(minute, 10),
0, 0
));
daysDiff = Math.floor((currentUtc - tsDate) / (1000 * 60 * 60 * 24));
}const timeDiff = currentUtc.getTime() - tsDate.getTime();
daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
if (daysDiff < 0) daysDiff = 0;
}
}
Line 890 ⟶ 898:
url: url,
daysOld: daysDiff,
timestamp: timestampStr || "unavailable"
});
}
return rfcs;
}
Line 905 ⟶ 914:
const ageOptions = [3, 7, 10, 15, 20, 25, 30];
const topicNamesrfcMap = [new Map();
'Biographies', 'Economy, trade, and companies', 'History and geography',
rfcs.forEach(rfc => {
'Language and linguistics', 'Maths, science, and technology',
const uniqueKey = `${rfc.url}|${rfc.title}`;
'Art, architecture, literature, and media', 'Politics, government, and law',
if (rfcMap.has(uniqueKey)) {
'Religion and philosophy', 'Society, sports, and culture',
'Wikipedia style and naming', 'Wikipediaconst policiesexisting and= guidelines',rfcMap.get(uniqueKey);
if (!existing.topics.includes(rfc.topic)) {
'WikiProjects and collaborations', 'Wikipedia technical issues and templates',
'Wikipedia proposals', 'Unsorted', 'User names' existing.topics.push(rfc.topic);
]; }
} else {
 
rfcMap.set(uniqueKey, {
...rfc,
topics: [rfc.topic]
});
}
});
const deduplicatedRfcs = Array.from(rfcMap.values());
let html = `<p><small>Current date: ${currentDate}</small></p>`;
html += `<p>Age filter: <select id="rfc-age-filter">`;
Line 925 ⟶ 943:
function renderRfCTable(filteredRfcs) {
if (filteredRfcs.length > 0) {
let table = '<h4>Current RfCs</h4><table class="wikitable sortable"><thead><tr><th>Topic</th><th>TitleRfC</th><th>Days Old</th><th>Started</th></tr></thead><tbody>';
filteredRfcs.sort((a, b) => a.daysOld - b.daysOld).forEach((rfc, index) => {
let topicDisplay;
table += `<tr><td>${rfc.topic}</td><td><a href="${rfc.url}" target="_blank">${rfc.title}</a></td><td>${rfc.daysOld}</td><td>${rfc.timestamp}</td></tr>`;
if (rfc.topics.length === 1) {
topicDisplay = rfc.topics[0];
} else {
const mainTopic = rfc.topics[0];
const additionalCount = rfc.topics.length - 1;
const additionalTopics = rfc.topics.slice(1).join(', ');
topicDisplay = `
<span class="main-topic">${mainTopic}</span>
<span class="additional-topics" style="color: #0645ad; cursor: pointer; text-decoration: underline;"
onclick="toggleTopics('topics-${index}')"
title="${additionalTopics}">
(+${additionalCount} more)
// Add delay between batches except for the last one</span>
<div id="topics-${index}" style="display: none; margin-top: 5px; font-size: 0.9em; color: #666;">
${rfc.topics.slice(1).map(topic => `<div>• ${topic}</div>`).join('')}
</div>
`;
}
table += `<tr><td>${rfc.topictopicDisplay}</td><td><a href="${rfc.url}" target="_blank">${rfc.title}</a></td><td>${rfc.daysOld}</td><td>${rfc.timestamp}</td></tr>`;
});
table += '</tbody></table>';
Line 939 ⟶ 978:
html += '<p><a href="https://en.wikipedia.org/wiki/Wikipedia:Requests_for_comment/All" target="_blank">All open RfCs</a></p>';
html += `<script>
window._rfcs = ${JSON.stringify(rfcsdeduplicatedRfcs)};
window._ageOptions = ${JSON.stringify(ageOptions)};
function toggleTopics(elementId) {
var element = document.getElementById(elementId);
if (element.style.display === 'none') {
element.style.display = 'block';
} else {
element.style.display = 'none';
}
}
function updateRfCTable() {
var rfcs = window._rfcs;
Line 949 ⟶ 998:
document.getElementById('rfc-list-table').innerHTML = (${renderRfCTable.toString()})(filteredRfcs);
}
document.getElementById('rfc-age-filter').addEventListener('change', updateRfCTable);
updateRfCTable();
</script>`;
 
return html;
}