MediaWiki:RCStats.js

// Script: RCStats // Author: User:DuckeyD

/* global $, mw, Chart */ window.rcstats = { init: function init { mw.hook('rcstats.init').fire window.rcstats.createLink

if (mw.config.get('wgCanonicalSpecialPageName') === 'Blankpage' && $.getUrlVar('blankspecial') === 'rcstats') { mw.util.addCSS('#rcstats{display:flex;justify-content:space-between}#rcstats canvas{user-select:none}.rcsection{flex-basis:30%}.rcsection:before{float:left;content:\'\';padding-top:100%}.rcsection h2{margin:0;padding:0;border:none;text-align:center;height:10%}.rccanvaswrapper{box-sizing:border-box;width:100%;height:90%;position:relative}') mw.loader.using(['rcstats.dependencies'], function {        window.rcstats.generateStatsPage        new mw.Api.get({ action: 'query', list: 'recentchanges', rclimit: 500, rcprop: ['user', 'timestamp', 'title'].join('|') }).done(function (data) { var fullData = data.query.recentchanges.reverse

fullData = fullData.filter(function (item) {           return new Date(item.timestamp).getTime > (new Date(new Date.setHours(24, 0, 0, 0)).getTime - 1000 * 60 * 60 * 24 * 7)          })

window.rcstats.data = fullData window.rcstats.createCharts })     })    }  },  createLink: function createLink  { var text = window.rcstats.i18n.msg('shortName').plain var href = mw.util.getUrl('Special:Blankpage', { 'blankspecial': 'rcstats' }) var elem = $('').append(     $('', { text: text, href: href })   ).appendTo('.wds-community-header__wiki-buttons > .wds-dropdown > .wds-dropdown__content > .wds-list') mw.hook('rcstats.link').fire({     elem: elem,      text: text,      href: href    }) }, generateStatsPage: function generateStatsPage  { $('#PageHeader .page-header__title').text(window.rcstats.i18n.msg('name').plain) $('title').html(window.rcstats.i18n.msg('name').plain + ' | ' + mw.config.get('wgSiteName')) $('#mw-content-text').empty.append(     $(' ', { id: 'rcstats' }).append( $(' ', { 'class': 'rcsection' }).append(         $(' ').text(window.rcstats.i18n.msg('users').plain),          $(' ', { 'class': 'rccanvaswrapper' }).append( $(' ', { id: 'rcstats-users', width: 10, height: 9 }) )       ),        $(' ', { 'class': 'rcsection' }).append(          $(' ').text(window.rcstats.i18n.msg('days').plain),          $(' ', { 'class': 'rccanvaswrapper' }).append( $(' ', { id: 'rcstats-days', width: 10, height: 9 }) )       ),        $(' ', { 'class': 'rcsection' }).append(          $(' ').text(window.rcstats.i18n.msg('pages').plain),          $(' ', { 'class': 'rccanvaswrapper' }).append( $(' ', { id: 'rcstats-pages', width: 10, height: 9 }) )       )      )    )

mw.loader.using('mediawiki.api', function {      new mw.Api.get({ action: 'parse', text: '', prop: 'text' }).done(function (data) { var elem = $(data.parse.text['*']) elem.find('.editsection').remove $('#mw-content-text').append(elem) })   })  },  createCharts: function createCharts  { var editsByUsers = {} var editsByDays = {} var editsByType = {}

for (var i = 0; i < window.rcstats.data.length; i++) { if (editsByUsers[window.rcstats.data[i].user]) { editsByUsers[window.rcstats.data[i].user] += 1 } else { editsByUsers[window.rcstats.data[i].user] = 1 }

var date = new Date(window.rcstats.data[i].timestamp) var day = date.getFullYear + '-' + ('0' + date.getMonth).slice(-2) + '-' + ('0' + date.getDate).slice(-2)

if (editsByDays[day]) { editsByDays[day].edits += 1 if (editsByDays[day].users.indexOf(window.rcstats.data[i].user) === -1) { editsByDays[day].users.push(window.rcstats.data[i].user) }     } else { var weekday = date.toLocaleString(window.navigator.language || 'en-EN', {weekday: 'long'}) editsByDays[day] = { edits: 1, day: weekday.charAt(0).toUpperCase + weekday.slice(1), users: [window.rcstats.data[i].user] }     }

if (editsByType[window.rcstats.getPageType(window.rcstats.data[i].title)]) { editsByType[window.rcstats.getPageType(window.rcstats.data[i].title)] += 1 } else { editsByType[window.rcstats.getPageType(window.rcstats.data[i].title)] = 1 }   }

// USERS var usersData = [] var usersLabels = [] var usersColors = [] var usersHoverColors = [] var usersBorders = window.sassParams['color-page']

Object.entries(editsByUsers).sort(function (a, b) {     return a[1] < b[1]    }).forEach(function (e) {      usersData.push(e[1])      usersLabels.push(e[0])      var hue = Math.random * 360      usersColors.push('hsl(' + hue + ', 80%, 50%)')      usersHoverColors.push('hsl(' + hue + ', 80%, 25%)')    })

window.rcstats.charts.users = new Chart($('#rcstats-users')[0].getContext('2d'), {     type: 'doughnut',      data: {        datasets: [{          data: usersData,          backgroundColor: usersColors,          hoverBackgroundColor: usersHoverColors,          borderColor: usersBorders,          hoverBorderColor: usersBorders        }],        labels: usersLabels      },      options: {        legend: {          display: false        },        tooltips: {          displayColors: false        }      }    })

// DAYS var daysEditsData = [] var daysUsersData = [] var daysLabels = []

Object.values(editsByDays).forEach(function (v) {     daysEditsData.push(v.edits)      daysUsersData.push(v.users.length)      daysLabels.push(v.day)    })

window.rcstats.charts.days = new Chart($('#rcstats-days')[0].getContext('2d'), {     type: 'line',      data: {        datasets: [{          label: window.rcstats.i18n.msg('edits').plain,          data: daysEditsData,          backgroundColor: '#00d6d6',          borderColor: '#00d6d6',          fill: false        }, {          label: window.rcstats.i18n.msg('users').plain,          data: daysUsersData,          backgroundColor: '#ff6a64',          borderColor: '#ff6a64',          fill: false        }],        labels: daysLabels      },      options: {        scales: {          xAxes: [{            ticks: {              autoSkip: false            }          }],          yAxes: [{            ticks: {              beginAtZero: true            }          }]        },        tooltips: {          mode: 'index',          intersect: false        },        hover: {          mode: 'nearest' }     }    })

// PAGES var typeEditsData = [] var typeEditsLabels = []

Object.entries(editsByType).sort(function (a, b) {     return a[1] > b[1]    }).forEach(function (e) {      typeEditsData.push(e[1])      typeEditsLabels.push(window.rcstats.i18n.msg(e[0]).plain)    })

window.rcstats.charts.pages = new Chart($('#rcstats-pages')[0].getContext('2d'), {     type: 'bar',      data: {        datasets: [{          label: window.rcstats.i18n.msg('edits').plain,          data: typeEditsData,          backgroundColor: '#5df2ae'        }],        labels: typeEditsLabels      },      options: {        tooltips: {          displayColors: false        },        scales: {          xAxes: [{            ticks: {              autoSkip: false            }          }],          yAxes: [{            ticks: {              beginAtZero: true            }          }]        }      }    }) }, getPageType: function getPageType (title) { var namespace = title.split(':').length === 2 ? title.split(':')[0].toLowerCase.split(' ').join('_') : '' var keys = Object.keys(mw.config.get('wgNamespaceIds')) function pageInNs (ns) { return keys.filter(function (k) {       return ns.includes(mw.config.get('wgNamespaceIds')[k])      }).includes(namespace) }   if (pageInNs([0, 4, 5, 14, 15])) { return 'article' } else if (pageInNs([-2, 6, 7])) { return 'media' } else if (pageInNs([8, 9, 10, 11, 828, 829])) { return 'code' } else if (pageInNs([1, 3, 110, 111, 500, 501, 502, 503, 1200, 1201, 2000, 2001, 2002])) { return 'social' } else if (pageInNs([2, 1202])) { return 'user' } else { return 'other' } },  charts: { users: null, days: null, pages: null }, data: {} }

$(function {  if (window.rcstatsloaded) {    return  }  window.rcstatsloaded = true  if (mw.config.get('wgCanonicalSpecialPageName') === 'Blankpage' && $.getUrlVar('blankspecial') === 'rcstats') {    $('#mw-content-text').html('  ')  }

mw.loader.implement('rcstats.i18n', [   '/load.php?mode=articles&only=scripts&articles=u:dev:I18n-js/code.js'  ], {}, {}) mw.loader.implement('rcstats.dependencies', [   '/load.php?mode=articles&only=scripts&articles=u:dev:MediaWiki:Chart.js'  ], {}, {})

mw.loader.using(['rcstats.i18n', 'mediawiki.api', 'mediawiki.util'], function {    window.dev.i18n.loadMessages('RCStats').done(function (i18n) { window.rcstats.i18n = i18n window.rcstats.init }) }) })