SSH tunnel

how to open an SSH tunnel through another host:

# ssh -l <user> -L <local_port>:<remote_host>:<remote_port> <host_to_connect>

this can be chained through multiple hosts, e.g.

# ssh -l user1 -L 80:localhost.1234 server1 (type on local machine)
# ssh -l user2 -L 1234:localhost:80 server2 (type on server1)

now server2's port can be reached through http://localhost

Kodi add-ons on Ubuntu 16.01.1 LTS

On latest Ubuntu distributions (based 16.01 LTS) Kodi's add-ons won't connect to the internet due to a bug in the systems python-openssl package, wihich is outdated. They throw following error to the logs:

URLError: <urlopen error [Errno 0] Error>

So uninstalling the system package and upgrading to pyopenssl using pip worked just fine.

# sudo apt-get remove python-openssl
# sudo apt-get install python-setuptools python-pip python-dev libssl-dev
# sudo pip install --upgrade pyopenssl

Add-ons are working afterwards.

OOP in javascript

well explained public, private and protected variables and methods in javascript:

http://phrogz.net/js/classes/OOPinJS.html

function Person(n,race){ 
	this.constructor.population++;

	// ************************************************************************ 
	// PRIVATE VARIABLES AND FUNCTIONS 
	// ONLY PRIVELEGED METHODS MAY VIEW/EDIT/INVOKE 
	// *********************************************************************** 
	var alive=true, age=1;
	var maxAge=70+Math.round(Math.random()*15)+Math.round(Math.random()*15);
	function makeOlder(){ return alive = (++age <= maxAge) } 

	var myName=n?n:"John Doe";
	var weight=1;


	// ************************************************************************ 
	// PRIVILEGED METHODS 
	// MAY BE INVOKED PUBLICLY AND MAY ACCESS PRIVATE ITEMS 
	// MAY NOT BE CHANGED; MAY BE REPLACED WITH PUBLIC FLAVORS 
	// ************************************************************************ 
	this.toString=this.getName=function(){ return myName } 

	this.eat=function(){ 
		if (makeOlder()){ 
			this.dirtFactor++;
			return weight*=3;
		} else alert(myName+" can't eat, he's dead!");
	} 
	this.exercise=function(){ 
		if (makeOlder()){ 
			this.dirtFactor++;
			return weight/=2;
		} else alert(myName+" can't exercise, he's dead!");
	} 
	this.weigh=function(){ return weight } 
	this.getRace=function(){ return race } 
	this.getAge=function(){ return age } 
	this.muchTimePasses=function(){ age+=50; this.dirtFactor=10; } 


	// ************************************************************************ 
	// PUBLIC PROPERTIES -- ANYONE MAY READ/WRITE 
	// ************************************************************************ 
	this.clothing="nothing/naked";
	this.dirtFactor=0;
} 


// ************************************************************************ 
// PUBLIC METHODS -- ANYONE MAY READ/WRITE 
// ************************************************************************ 
Person.prototype.beCool = function(){ this.clothing="khakis and black shirt" } 
Person.prototype.shower = function(){ this.dirtFactor=2 } 
Person.prototype.showLegs = function(){ alert(this+" has "+this.legs+" legs") } 
Person.prototype.amputate = function(){ this.legs-- } 


// ************************************************************************ 
// PROTOTYOPE PROERTIES -- ANYONE MAY READ/WRITE (but may be overridden) 
// ************************************************************************ 
Person.prototype.legs=2;


// ************************************************************************ 
// STATIC PROPERTIES -- ANYONE MAY READ/WRITE 
// ************************************************************************ 
Person.population = 0;