Участник:Js/whois.js
Перейти к навигации
Перейти к поиску
Страница персонального оформления. У этого JS-кода есть документация: Участник:Js/whois.
После сохранения очистите кэш браузера.
После сохранения очистите кэш браузера.
//see [[user:js/whois]]
//PARAMETERS
// whoisStorageLimit = // in bytes
if( window.localStorage ){
var m, user = ''
if( mw.config.get('wgCanonicalSpecialPageName') == 'Contributions' )
user = $('input[name="target"]').val()
else if( mw.config.get('wgCanonicalSpecialPageName') == 'Block' && !$('#mw-input-wpConfirm').length )
user = document.URL.match(/\/([\d\.]+)$/)[1]
else if( mw.config.get('wgAction') == 'rollback' || /:AbuseLog\//.test(mw.config.get('wgPageName')) ) {
m = $('.mw-userlink').eq(0).attr('href').match(/:Contributions\/(.+)$/);
user = m && m[1]
} else if( mw.config.get('wgNamespaceNumber') == 2 || mw.config.get('wgNamespaceNumber') == 3 )
user = mw.config.get('wgTitle')
if( /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(user) )
showWhois()
}
function showWhois(){
var wsLimit = window.whoisStorageLimit || 200000 //bytes
var ranges
$('<div style="margin-top: -5px;" />')
.append(
$('<a style="color:gray" '
+ 'href="http://toolserver.org/~overlordq/cgi-bin/whois.cgi?lookup='
+ user + '">whois:</a>').click(tools),
'<span id=whois />'
)
.insertAfter('#contentSub')
cache() || request()
return
//---------------------------------
function cache(){
loadCache()
if( !ranges.length ){
fetchCache()
return false
}
var iphex = ip2hex(user)
//quickly search in sorted array by checking the element in the middle
var r1 = 0, r2 = ranges.length - 1, rr //r1 .... rr .... r2
while( r1 < r2 ){
rr = Math.floor( (r2 + r1)/2 ) + 1 //middle item
if( iphex < ranges[rr].substring(0, 8) ) r2 = rr - 1 // ... is below this range
else r1 = rr // ... is above or within this range
}
//check if ip is within this range
var dat = ranges[r1].split('\t')
var n1 = parseInt(dat[0].substring(0, 8), 16)
var n2 = parseInt(dat[0].substring(8), 16) + n1
if( n1 > parseInt(iphex, 16) || parseInt(iphex, 16) > n2 ) return false
//display
display(dat[1], dat[2], dat[3], ipDec(n1) + ' - ' + ipDec(n2) )
$('#whois').append('<span style="color:gray; font-size:smaller">(cached)</span>')
if( window.whoisStats ) stats()
return true
}
function request(){
$('#whois').html('<span style="color:gray"> requesting ...</span>')
window.whois_cb = receive
mw.loader.load(
'https://stat.ripe.net/plugin/whois/data.json?callback=whois_cb&resource=' + user)
}
function receive(d){
if(typeof d !== 'undefined')zd = d
if( !d || !d.data ) return $('#whois').html('empty response')
d = d.data
if( d.records ) d = d.records[0]
else return $('#whois').html( d.messages.toString() ) // a notice, happens...
var w = {}, htm, key
for (var i=0; i<d.length; i++){
key=d[i][0]
if( w[key] ) w[key] += ' / '
else w[key] = ''
w[key] += d[i][1]
}
//display
display(w.country, w.netname, w.descr, w.inetnum)
if( window.whoisDebug ){
//temp display to make sure other info is useless
htm = ''
for (var i=0; i<d.length; i++)
if( !/inetnum|netname|descr|country/.test(d[i][0]) )
htm += d[i][0] + ':\t' + d[i][1] + '<br />'
msg(htm, 'gray')
}
loadCache()
if( !w.country || w.country.toLowerCase() == 'zz' ) return
//save
var rng = range2hex(w.inetnum)
if( !rng ) return //could not parse range
ranges.push( rng + '\t' + w.country + '\t' + w.netname + '\t' + w.descr.replace(/\t/g, ' ') )
saveCache()
}
function display(country, netname, descr, ips){
country = country ? country.toLowerCase() : null;
if(!country) return;
country = '<span '
+ ( country == 'zz' ? 'class=error>' : 'style="font-weight:bold2">' )
+ country + '</span>'
$('#whois').html( ' ' + country + ' ' + netname + ' ' + descr
+ ' <span style="color:gray">' + ips + '</span> ')
}
function tools(e){
e.preventDefault()
if( $('#wh-tools').length ) return $('#wh-tools').remove()
loadCache()
$('<div id=wh-tools style="font-size:smaller" />')
.append(
$('<span style="cursor:pointer">[refresh IP]</span>').click(request),
' ',
$('<span style="cursor:pointer">[edit cache]</span>').click(edit),
' ' + ranges.length + ' lines, '
+ Math.floor(ranges.join('\n').length / 1000)
+ ' KB (max ' + wsLimit / 1000 + ') '
)
.insertAfter('#whois')
}
function edit(){
if( $('#wh-edit').length ) return $('#wh-edit').remove()
$('<div id=wh-edit>'
+ '<textarea rows=15 style="white-space:nowrap;overflow:scroll;" />'
+ '<input type=button value=Save />'
+ '</div'
)
.insertAfter('#wh-tools')
loadCache()
convertRanges()
$('#wh-edit textarea').val( ranges.join('\n') )
$('#wh-edit input').click(function(){
ranges = $('#wh-edit textarea').val().split('\n')
convertRanges(true)
saveCache()
edit() //to remove UI
})
}
function fetchCache(){
$.get('http://ru.wikipedia.org/wiki/Участник:Js/whois/cache?action=raw', function(s){
ranges = s.split('\n')
convertRanges(true)
saveCache()
if( ranges.length ){
msg('Loaded initial cache: ' + ranges.length + ' lines')
}else{
msg('Unable to load initial cache', 'red')
}
})
}
function stats(){ //log how many times range was requested to see the most often used ones
if( mw.config.get('wgCanonicalSpecialPageName') != 'Contributions' ) return
//console.log( 'stats for ' + user, dat[4])
if( typeof dat[4] == 'undefined' ) dat.push(1)
dat[4] = parseInt(dat[4]) + 1
ranges[rangeIdx] = dat.join('\t')
saveCache()
$('#whois').append(' ', '<span style="color:gray">(' + dat[4] + ')')
}
// ------------- AUX functions --------------
function msg(txt, color){
$('#whois').parent().append('<div style="color:' + color + '">' + txt + '</div>')
}
function loadCache(){
ranges = localStorage.getItem('whois')
ranges = ranges ? ranges.split('\n') : []
//console.timeEnd('read cache')
}
function saveCache(){ //from ranges[]
ranges.sort()
//remove duplicates
for( var i=0; i<ranges.length-2; i++ )
if( ranges[i].split('\t')[0] == ranges[i+1].split('\t')[0] )
ranges.splice(i--, 1)
//save
var txt = ranges.join('\n')
if( txt.length > wsLimit )
return msg('cannot save: cache too large now (' + txt.length + ')', 'red' )
try { localStorage.setItem( 'whois', txt ) }
catch(e){ msg('cannot save: ' + e, 'red') }
}
function convertRanges(toHex){
for( var i=0; i<ranges.length; i++){
dat = ranges[i].split('\t')
dat[1] = $.trim(dat[1])
dat[2] = $.trim(dat[2])
dat[3] = $.trim(dat[3])
dat[0] = toHex ? range2hex(dat[0]) : hex2range(dat[0])
if( dat[0] ) ranges[i] = dat.join('\t')
else ranges.splice(i--, 1)
}
}
function range2hex(s){
s = s.replace(/ /g,'')
var lowIP, rngLen
//try x.x.x.x/yy
var r = /^(\d+\.\d+\.\d+\.\d+)\/(\d\d)$/.exec(s)
if( r ){
lowIP = r[1]
rngLen = Math.pow(2, 32 - r[2] ) - 1
}else{ //x.x.x.x-y.y.y.y
r = s.split('-')
if( r.length == 2 ){
lowIP = r[0]
rngLen = ipNum(r[1]) - ipNum(r[0])
}
}
//return
if( lowIP ) return ip2hex( lowIP ) + rngLen.toString(16)
else return // console.debug('bad range: ', s)
}
function hex2range(hex){
var ip1 = parseInt(hex.substring(0,8), 16)
var ip2 = parseInt(hex.substring(8), 16) + ip1
var s = ipDec(ip1) + '-' + ipDec(ip2)
while( s.length < 25 ) s+= ' ' //pretiify for table output assuming tab = 8 spaces
return s
}
function ipNum(ip){ // '1.2.3.255' -> 16909311
ip = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(ip)
if( ip ) return (+ip[1]<<24) + (+ip[2]<<16) + (+ip[3]<<8) + (+ip[4])
else return null
}
function ipMask(i1, i2){
var p = Math.log(ipNum(i2) - ipNum(i1) + 1) / Math.LN2
if( Math.round(p) == p) return 32 - p
else return ''
}
function ip2hex(s){ //'1.2.3.255' -> 010203ff'
return s.replace(/\d+/g, function(s){
t = parseInt(s, 10).toString(16)
if( t.length == 1 ) t = '0' + t
return t
})
.replace(/\./g, '');
}
function ipDec(n){ // 16909311 --> '1.2.3.255'
var d = n % 256
for( var i=0; i < 3; i++){
n = Math.floor(n / 256)
d = n % 256 + '.' + d
}
return d
}
}