Jump to content

User:PSaxena (WMF)/ipinfo-uxtest.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
function showInfo (data,mockData,ip) {
	console.log(data);
	var proxyClass = data.isProxy ? 'green-dot' : 'red-dot';
	var proxyText = data.isProxy ? 'Not a proxy' : 'Known proxy';
	
	var $ltaLink = $('<a>').text('Search LTA').attr('href','https://en.wikipedia.org/wiki/Special:Search?search='+ip+'&prefix=Wikipedia%3ALong-term+abuse&fulltext=Search+all+reports&fulltext=Search&ns0=1');
	var $globalContribsLink = $('<a>').text('Global contributions').attr('href','https://guc.toolforge.org/?by=date&user='+ip);
	var $xtoolsLink = $('<a>').text('XTools').attr('href','https://xtools.wmflabs.org/ec/en.wikipedia.org/'+ip);
	var $blocksLink = $('<a>').text('Block log').attr('href','https://en.wikipedia.org/w/index.php?title=Special:BlockList&ip='+ip);
	
	var $proxyDot = $('<span>').text(' ').addClass('dot').addClass(mockData.proxyColor+'-dot');
	
	var $infoHolder = $('<div>').addClass("ipinfo-container").append([
		addCol().append([
			addInfo('Location', data.addr + ', ' + data.loc),
			addInfo('Organization', data.org),
			addInfo('ISP', $('<code>').text(data.host))
		]),
		addCol().append([
			addInfo('Connection type', mockData.connectionType),
			addInfo('User type', mockData.userType),
			addInfo('Proxy', [$proxyDot, ' ', mockData.proxyType]),
			addInfo('Static / Dynamic', mockData.static + '% static'),
			addInfo('Number of users on IP', mockData.noOfUsers),
		]),
		addCol().append([
			addInfo('Blocks', ['Not blocked', $('<br>'),$blocksLink]),
			addInfo('Contributons', [mockData.edits + ' edits', $('<br>'),$globalContribsLink, $('<br>'),$xtoolsLink]),
			addInfo('', $ltaLink)
		])
	]);
	
	$('#mw-content-text').prepend(
		$('<div>').addClass('ipinfo').append(
			$('<h2>').text('IP Information'),
			$infoHolder,
			addCredits()
		)
	);
};

function addInfo(label,value) {
	var $info = $('<div>').addClass('ipinfo-info');
	$info.append([
		$('<dt>').append(label),
		$('<dd>').append(value),
		]);
	return $info;
}

function addCol() {
	return $('<div>');
}

function addCredits() {
	return $('<div>').addClass('ipinfo-credits').text('The information shown here is dummy data. It is not accurate.');
}

// From https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_.28JavaScript.2FActionScript.2C_etc..29
function lon2tile(lon,zoom1) { 
	tt = Number(lon);
	return (Math.floor((tt+180)/360*Math.pow(2,zoom1)));
}

function lat2tile(lat,zoom2)  { 
    return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom2))); 
}

function getInfo() {
	var hrefArray = window.location.href.split('/');
	var ip = hrefArray[hrefArray.length - 1];
	var mockData = getMockDataFromIP(ip);

	fetch('https://ipinfo.io/'+ip+'/json').then(function(data){
      	return data.json();
      }).then(function(json){
      	var data = {};
      	// From IP Info
      	data.addr = json.city + ' ' + json.postal;
      	data.loc = json.region + ' ' + json.country;
      	data.org = json.org;
      	data.host = json.hostname;
      	
      	// Map
      	var lat = json.loc.split(',')[0];
      	var lon = json.loc.split(',')[1];
      	var x = lon2tile(lon,10);
      	var y = lat2tile(lat,10);
		data.map = 'https://maps.wikimedia.org/osm-intl/10/'+x+'/'+y+'@2x.png'
      	
      	// Dummy data
      	data.isProxy = (parseInt(ip) % 2 === 0);
      	showInfo(data,mockData,ip);
      });
}

$(document).ready(function() {
	if (window.location.href.indexOf('Special:Contributions') > -1 ) {
		getInfo();
	}
});




// See [[mw:Navigation Popups (Restyling and Enhancements)]], by Vibhabamba.
// This is still probably quite buggy.
// Licensed under GPLv2+, CC-BY-SA 3.0, GFDL, and anything else the WMF might find useful.
// from https://en.wikipedia.org/wiki/User:Yair_rand/NavPopupsRestyled.js

$( document ).ready( function( $ ){
  // Messages
  mw.messages.set( {
    "INFO-readmore" : "Read more" // this and the four below allow use of GENDER:$1.
  } );
  
  // Config
  var loadDelay = 150, // number of ms before sending the request
  displayDelay = 500, // minimum number of ms between sending request and displaying
  closeDelay = 800, // time between exiting box and it disappearing
  timer, currentLink, cache = {}, curRequest, 
  $marker = $( "<span>" ).css("vertical-align", "top"), 
  api = new mw.Api(), 
  $box = $( "<div>" ).addClass( "INFObox" ).on( { 
    mouseleave: leaveActive,
    mouseenter: function() {
      setTimeout( function(){ 
        timer && clearTimeout( timer );
      }, 16 ); // don't ask.
    }
  }).appendTo( document.body );
  
  // From https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_.28JavaScript.2FActionScript.2C_etc..29
  function lon2tile(lon,zoom1) { 
	tt = Number(lon);
	return (Math.floor((tt+180)/360*Math.pow(2,zoom1)));
  }

  function lat2tile(lat,zoom2)  { 
    return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom2))); 
  }
  
  // Get domain name
  function getDomainName(hostName){
  	if (!hostName) return hostName;
    return hostName.substring(hostName.lastIndexOf(".", hostName.lastIndexOf(".") - 1) + 1);
  }
  
  // Close box event handler
  function closeBox() {
    $( currentLink ).off( "mouseleave", leaveActive );
    $box.hide();
    timer && clearTimeout( timer );
    currentLink = timer = undefined;
  }
  
  // Leave box event handler
  function leaveActive() {
    timer = setTimeout( closeBox, closeDelay );
  }
  
  // Leave link event handler
  function leaveInactive() {
    $( currentLink ).off( "mouseleave", leaveInactive );
    clearTimeout( timer );
    curRequest && curRequest.abort();
    currentLink = timer = curRequest = undefined;
  }
  
  function createBox($this, href) {
    $marker.prependTo( $this );
    var offset, sploot = cache[ href ], thumbnail = sploot.thumbnail,
    sOffset = $marker.offset(),
    eOffset = $marker.appendTo( $this ).offset(),
    tall = thumbnail && thumbnail.height > thumbnail.width, // todo: fix duplication.
    boxWidth = tall ? 450 : 300;
    if( sOffset.left > eOffset.left ) {
      if( event.pageX > sOffset.left ) { // top half
        offset = sOffset;
      } else { // latter half
        offset = eOffset;
        offset.left += - 40;
      }
      offset.top += $marker.height() + 8;
    } else { // normal situations
      offset = sOffset;
      offset.top += $this.height() + 8;
      offset.left += ( $this.width() / 2 ) - ( 20 );
    }
    var flip = $( window ).width() < boxWidth + offset.left;
    $marker.remove();
    $box
    .children()
    .detach()
    .end()
    [ tall ? "addClass" : "removeClass" ]( "is-tall" )
    [ flip ? "addClass" : "removeClass" ]( "flipped" ) // needs a better class name.
    .css({ // avoid .empty() to keep event handlers
      top: offset.top,
      left: offset.left - ( flip && boxWidth - 40 ),
      "min-height": tall ? thumbnail.height : "initial"
    })
    .append( sploot.box )
    .show();
    $this.off( "mouseleave", leaveInactive ).on( "mouseleave", leaveActive );
  }
  
  // Setup box
  function setupBox($this, href, title) {
    if( cache[ href ] ) {
      timer = setTimeout( function () {
      	createBox($this,href);
      }, displayDelay );
    } else {
      curRequest = undefined;
      var ip = title.split('/')[1];
      var extract, timestamp, timetext, thumbnail, watched, 
      thumbnail = {
        width: 200,
        height: 290,
        source: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/India_Karnataka_location_map.svg/200px-India_Karnataka_location_map.svg.png'
      };
      timestamp = +new Date;
      extract = 'testtest';
      
      var tall = thumbnail && thumbnail.height > thumbnail.width;
      var $bottommessage, $contentbox = $( "<div>" )
      .html( extract )
      .append( 
        $( "<a>" )
        .attr({ href: href, target: "_blank" })
        .text( mw.message( "INFO-readmore", mw.user ).text() ) 
      );
 
      fetch('https://ipinfo.io/'+ip+'/json').then(function(data){
      	return data.json();
      }).then(function(json){
      	var lat = json.loc.split(',')[0];
      	var lon = json.loc.split(',')[1];
      	
      	var x = lon2tile(lon,10);
      	var y = lat2tile(lat,10);
      	thumbnail.source = 'https://maps.wikimedia.org/osm-intl/10/'+x+'/'+y+'@2x.png';
      	
      	var mockData = getMockDataFromIP(ip);
      	var $globalContribsLink = $('<a>').text('Global contributions').attr('href','https://guc.toolforge.org/?by=date&user='+ip);
		var $xtoolsLink = $('<a>').text('XTools').attr('href','https://xtools.wmflabs.org/ec/en.wikipedia.org/'+ip);
		var $blocksLink = $('<a>').text('Block log').attr('href','https://en.wikipedia.org/w/index.php?title=Special:BlockList&ip='+ip);
      	
      	$contentbox.empty().append(
      		/*$("<img>").addClass('flag').attr('src', 'https://www.countryflags.io/'+json.country.toLowerCase()+'/flat/16.png'),
            $("<span>").addClass('shift').text( json.city + ' ' + json.postal ),
            $("<span>").addClass('shift').text( json.region + ', ' + json.country ),
            $("<a>").addClass('hostname').attr('href', 'http://'+getDomainName(json.hostname)).text(json.hostname),
            $("<span>").text(json.org)*/
            addInfo('Blocks', ['Not blocked', $('<br>'),$blocksLink]),
			addInfo('Contributons', [mockData.edits + ' edits', $('<br>'),$globalContribsLink, $('<br>'),$xtoolsLink])
      	);
      	
      	$bottommessage = addCredits();
      	
      	cache[ href ] = {
        box: $( "<div>" ).append( 
          /*thumbnail ? $( "<img>" ).addClass( tall ? "is-tall" : "is-not-tall" ).attr( "src", thumbnail.source ).css( {
            width: thumbnail.width,
            height: thumbnail.height
          } ) : $( "<span>" ), */
          $contentbox,
          $bottommessage
		),
        //thumbnail: thumbnail
      };
      timer === undefined && createBox($this, href);
      });
        
      timer = setTimeout( function() {
        timer = undefined;
        cache[ href ] && createBox($this, href);
      }, displayDelay );
    }
  }
  
  // Setup hover event
  $("#mw-content-text").on("mouseenter", "a.mw-anonuserlink", function( event ){
    var $this = $( this ), href = this.href, 
    title = href && href.split("/wiki/")[ 1 ];
    if( !title || 
      $this.hasClass("extiw") || 
      $this.hasClass("image") || 
      $this.hasClass("new") || 
      href.indexOf("?") !== -1 || 
      href.indexOf( location.href.split("#")[ 0 ] + "#" ) === 0
    ) {
      return;
    }
    if( currentLink === this ) {
      clearTimeout( timer );
      return;
    }
    if( currentLink ) {
      closeBox();
    }
    currentLink = this;
    timer = setTimeout( function () {
      setupBox($this, href, title);
    }, loadDelay );
    $this.on( "mouseleave", leaveInactive ); 
  });
  
  // Remove title attribute from IP links
  $("a.mw-anonuserlink").attr('title','')
});

// Get mock data from IP
function getMockDataFromIP(ip) {
	var num = getNumFromIP(ip);
	var data =  {};
	
	var connectionTypes = ['Dialup', 'Cable/DSL', 'Corporate','Cellular'];
	var userTypes = ['Business', 'Cafe', 'Cellular', 'College', 'Content Delivery Network',
		'Dialup', 'Government', 'Hosting', 'Library', 'Residential', 'School'];
		
	// The colors and types should match
	var proxyTypes = ['Tor exit node', 'Hosting provider','Anonymous VPN','Public proxy','Corporate proxy', 'Residential proxy'];
	var proxyColor = ['red', 'red', 'yellow', 'yellow', 'green', 'green'];
	
	data['static'] = num % 100;
	data['noOfUsers'] = num % 37;
	data['edits'] = num % 72;
	data['connectionType'] = connectionTypes[num % connectionTypes.length];
	data['userType'] = userTypes[num % userTypes.length];
	data['proxyType'] = proxyTypes[num%proxyTypes.length];
	data['proxyColor'] = proxyColor[num%proxyColor.length];
	
	return data;
}


// Get number from IP 
function getNumFromIP(ip) {
	var sha = SHA1(ip);
	var num = parseInt(sha,16);
	num = num / (10 ** 32);
	num = Math.round(num);
	return num;
}

/**
* Secure Hash Algorithm (SHA1)
* http://www.webtoolkit.info/
**/
function SHA1(msg) {
 function rotate_left(n,s) {
 var t4 = ( n<<s ) | (n>>>(32-s));
 return t4;
 };
 function lsb_hex(val) {
 var str='';
 var i;
 var vh;
 var vl;
 for( i=0; i<=6; i+=2 ) {
 vh = (val>>>(i*4+4))&0x0f;
 vl = (val>>>(i*4))&0x0f;
 str += vh.toString(16) + vl.toString(16);
 }
 return str;
 };
 function cvt_hex(val) {
 var str='';
 var i;
 var v;
 for( i=7; i>=0; i-- ) {
 v = (val>>>(i*4))&0x0f;
 str += v.toString(16);
 }
 return str;
 };
 function Utf8Encode(string) {
 string = string.replace(/\r\n/g,'\n');
 var utftext = '';
 for (var n = 0; n < string.length; n++) {
 var c = string.charCodeAt(n);
 if (c < 128) {
 utftext += String.fromCharCode(c);
 }
 else if((c > 127) && (c < 2048)) {
 utftext += String.fromCharCode((c >> 6) | 192);
 utftext += String.fromCharCode((c & 63) | 128);
 }
 else {
 utftext += String.fromCharCode((c >> 12) | 224);
 utftext += String.fromCharCode(((c >> 6) & 63) | 128);
 utftext += String.fromCharCode((c & 63) | 128);
 }
 }
 return utftext;
 };
 var blockstart;
 var i, j;
 var W = new Array(80);
 var H0 = 0x67452301;
 var H1 = 0xEFCDAB89;
 var H2 = 0x98BADCFE;
 var H3 = 0x10325476;
 var H4 = 0xC3D2E1F0;
 var A, B, C, D, E;
 var temp;
 msg = Utf8Encode(msg);
 var msg_len = msg.length;
 var word_array = new Array();
 for( i=0; i<msg_len-3; i+=4 ) {
 j = msg.charCodeAt(i)<<24 | msg.charCodeAt(i+1)<<16 |
 msg.charCodeAt(i+2)<<8 | msg.charCodeAt(i+3);
 word_array.push( j );
 }
 switch( msg_len % 4 ) {
 case 0:
 i = 0x080000000;
 break;
 case 1:
 i = msg.charCodeAt(msg_len-1)<<24 | 0x0800000;
 break;
 case 2:
 i = msg.charCodeAt(msg_len-2)<<24 | msg.charCodeAt(msg_len-1)<<16 | 0x08000;
 break;
 case 3:
 i = msg.charCodeAt(msg_len-3)<<24 | msg.charCodeAt(msg_len-2)<<16 | msg.charCodeAt(msg_len-1)<<8 | 0x80;
 break;
 }
 word_array.push( i );
 while( (word_array.length % 16) != 14 ) word_array.push( 0 );
 word_array.push( msg_len>>>29 );
 word_array.push( (msg_len<<3)&0x0ffffffff );
 for ( blockstart=0; blockstart<word_array.length; blockstart+=16 ) {
 for( i=0; i<16; i++ ) W[i] = word_array[blockstart+i];
 for( i=16; i<=79; i++ ) W[i] = rotate_left(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
 A = H0;
 B = H1;
 C = H2;
 D = H3;
 E = H4;
 for( i= 0; i<=19; i++ ) {
 temp = (rotate_left(A,5) + ((B&C) | (~B&D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
 E = D;
 D = C;
 C = rotate_left(B,30);
 B = A;
 A = temp;
 }
 for( i=20; i<=39; i++ ) {
 temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
 E = D;
 D = C;
 C = rotate_left(B,30);
 B = A;
 A = temp;
 }
 for( i=40; i<=59; i++ ) {
 temp = (rotate_left(A,5) + ((B&C) | (B&D) | (C&D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
 E = D;
 D = C;
 C = rotate_left(B,30);
 B = A;
 A = temp;
 }
 for( i=60; i<=79; i++ ) {
 temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
 E = D;
 D = C;
 C = rotate_left(B,30);
 B = A;
 A = temp;
 }
 H0 = (H0 + A) & 0x0ffffffff;
 H1 = (H1 + B) & 0x0ffffffff;
 H2 = (H2 + C) & 0x0ffffffff;
 H3 = (H3 + D) & 0x0ffffffff;
 H4 = (H4 + E) & 0x0ffffffff;
 }
 var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);

 return temp.toLowerCase();
}