Digital Fashion

Rien de grand ne se fit jamais sans enthousiasme.

To content | To menu | To search

Keyword - rigolo

Entries feed - Comments feed

Le tourisme expérimental

Vu que je me fais un peu chier en ce moment, je pense de plus en plus a partir un peu à l'aventure, voyager, toussa. En farfouillant un peu sur le net, j'ai découvert le tourisme expérimental qui propose des règles d'organisation de voyage souvent rigolotes, et toujours originales. Je ne pouvais donc décemment pas ne pas vous faire partager cette découverte qui va conditionner je pense une bonne partie de mes prochaines vacances a venir.

D'ailleurs, tant que j'y suis, je cherche un ou des compères susceptibles de m'accompagner dans des expéditions de plus ou moins une semaine a faible ou moyen budget et pas trop organisées dans des pays comme la suède, le royaume uni (angleterre / écosse / irlande), la hollande, le danemark, et généralement les pays scandinaves et anglo-saxons. Partir avec quelqu'un(s) que je ne connais pas ou peu fait parti du trip (jeu de mot ahah), donc n'hésitez pas à me contacter (à geoffrey+trip@zubrowka.org) si ça vous tente.

Google Reader + Wii

Google Reader dispose d'une interface dédiée à la wii (sur laquelle on tombe automatiquement quand on s'y rend avec opera4wii) et optimisé pour la wiimote.

via

Quand je serais grand...

...je veux faire comme lui.

Éviter les appels de fonction en double en javascript

Dans un accès de désespoir vu l'activité débordante de ce blog en ce moment, je me lance et je vous propose cette petite librairie javascript qui va vous permettre d'éviter les appels de fonction en double:

var Defer = {
	config: {
		defaultTimeout: 1000
	},
	stack: {},
	schedule: function(id, fn, timeout) {
		if (typeof(timeout) == 'undefined') {
			timeout = Defer.config.defaultTimeout;
		}
		if (typeof(Defer.stack[id]) == 'undefined') {
			Defer.stack[id] = {defer: false, fn: fn, timeout: timeout };
			window.setTimeout('Defer.execute(\'' + id + '\')', timeout);
		} else {
			Defer.stack[id].defer = true;
		}
	},
	execute: function(id) {
		if (typeof(Defer.stack[id]) != 'undefined' && !Defer.stack[id].defer) {
			Defer.stack[id].fn();
			Defer.stack[id] = undefined;
		} else {
			Defer.stack[id].defer = false;
			window.setTimeout('Defer.execute(\'' + id + '\')', Defer.stack[id].timeout);
		}
	},
};

On peut l'utiliser ainsi par exemple (jquery requis):

$(document).ready(function() {
	$('#nickname').keyup(function() {
		Defer.schedule('chknickname', function() {
			$.get('/account/check_nickname.php', { nickname: $('#nickname').val() }, function(data) {
				data = eval(data);
				$('#nickname_availability').html(data ? 'Pseudo disponible' : 'Pseudo indisponible');
			});
		}, 2000);
	});
});

Concrétement, ce bout de code attache à un input un événement qui ne sera executé que s'il n'est pas répété avant une certaine période (2 secondes ici). C'est à dire qu'on évite de faire une requête xmlhttp à chaque keyup, on attend plutot que l'utilisateur arrête de taper un moment avant de balancer la sauce. A noter que de par la méthode utiliser, l'espace de nommage d'execution de la fonction change (par exemple ici, on ne peut pas utiliser this pour accéder a l'input).

Voila voila.

Collections, Object Chaining, et la vérité sur le Père Noël

Aujourd'hui je vais vous parler de deux concepts que j'aime beaucoup et que j'ai (re)découverts en travaillant sur mon projet personnel de conquête de l'univers: les Collections d'objets et l'Object Chaining.

Les collections, qui sont peut-être finalement un design pattern connu sous un autre nom, permettent d'executer aisément des méthodes sur plusieurs objets (une collection d'objets quoi). Concrétement, disons qu'on à une classe My_Collection, qui implémente les interfaces Iterator (et Countable tant qu'a faire) de la SPL, ainsi que la fonction magique __call suivante (je vous fait grace du docblock):

class My_Collection implements Iterator, Countable {
	public function __call($method, $args) {
		$calls = 0;
		foreach($this as $item) {
			if (method_exists($item, $method)) {
				call_user_func_array(array($item, $method), $args);
				$calls++;
			}
		}
		if ($calls > 0) {
			return $this;
		} else {
			throw new My_Collection_Exception('Method catched but could not be called: '.$method);
		}
	}
}

Ce dispositif permet d'utiliser le genre de code suivant (si les objets de la collection le permettent, bien évidemment, et disons qu'ici ce sont des objets représentant des images, supportant les méthodes move et createThumbnail):

# $array contient les objets My_Image
$collection = new My_Collection($array);
$collection->move('/new/path/')->createThumbnail();

Ce qui, comme vous l'aurez deviné, déplacera les fichiers de la collection vers /new/path, puis en créera des miniatures.

Deuxième chose, l'Object Chaining. On vient de le voir en fait, ça consiste à chainer les appels de méthodes grâce à un subtil return $this;, qui retourne donc une référence à l'objet courant. Exemple pratique, dans le Zend Framework, en étendant Zend_View:

class My_View extends Zend_View {
	public function assign($spec) {
		$args = func_get_args();
		call_user_func_array(array('parent', 'assign'), $args);
		return $this;
	}
}

Ce qui autorise le genre de code suivant (en admettant que vous ayiez une instance de My_View dans le registre):

Zend::registry('view')
	->assign('foo', $foo)
	->assign('foo', $bar)
	->render('template.php');

Et là c'est fort, parceque ça rejoint fortement quelque chose dont je parlais en janvier dernier (le truc qui parle de with), et donc j'en déduis une chose formidable: Le père noël existe, et il m'a entendu. Merci Santa Copain.

Relayer un stream audio avec icecast2

Pour économiser la bande passante au boulot, j'ai décidé de relayer le stream Club ! de 1.fm sur le LAN. Après avoir vainement tenté d'utiliser streamripper (on verra plus tard pourquoi vainement), j'ai sorti l'artillerie lourde: icecast2:

sudo apt-get install icecast2

Si on sait un peu lire, le script de post-configuration nous incite à aller fourrer notre nez dans /etc/default/icecast2, où l'on apprend (vers la fin) que icecast est désactivé par défaut à cause de la directive ENABLED=false. C'est en fait une feinte pour nous pousser à configurer le bousin (de toute façon si on le configure pas, il marchera pas). Direction /etc/icecast2/icecast.xml donc, pour un brin de configuration (les explications qui suivent se basent sur le fichier par défaut d'une installation sur une ubuntu).

La première partie qui nous interresse s'intitule authentication (vers la ligne 23). Elle contient les informations d'authentification pour les clients qui se connectent en tant que source (source-password), les serveurs qui se connectent en tant que slave (relay-password, en fait je ne suis pas sur à 100%, c'est une déduction) et pour l'interface d'administration (admin-user et admin-password). Une fois ces informations modifiées, direction la directive hostname, qu'on remplira avec au choix, le nom de la machine, son ip, etc. J'ai personellement mis l'ip privée de ma machine (172.16.x.y), pour que ça correspondent à la prochaine directive qui nous interresse: listen-socket. Ici on définit le port et l'ip sur laquelle icecast va écouter. En gros, si vous spécifier 127.0.0.1, votre serveur de streaming ne sera accessible qu'en local. On y met donc en général la même chose que dans hostname (172.16.x.y par exemple), avec un port qui va bien, libre de préférence (8000 par défaut).

Maintenant on passe a la partie qui nous interresse vraiment, la section relay. Rien de bien compliqué ici. Le stream que je souhaite relayer se trouve là: http://64.62.253.223:8060/, or icecast nous demande un server, un port, un point de montage (mount) et un point de montage local (local-mount). Vous avez déjà compris qu'on arrive a cette configuration:

   <relay>
       <server>64.62.253.223</server>
       <port>8060</port>
       <mount>/</mount>
       <local-mount>/1.fm</local-mount>
       <on-demand>0</on-demand>
       <relay-shoutcast-metadata>1</relay-shoutcast-metadata>
   </relay>

Ainsi parés, il ne nous reste plus qu'a lancer modifier la directive ENABLED=false en ENABLED=true dans /etc/default/icecast2 et à lancer icecast:

sudo /etc/init.d/icecast2 start

Si vous avez bien tout fait, vous devriez pouvoir streamer depuis http://172.16.x.y:8000/1.fm, et vos collègues également ! Vous pouvez avoir une vue d'ensemble du serveur ainsi que quelques options d'administration en vous rendant sur l'interface d'admin: http://172.16.x.y:8000/ et en utilisant admin-user et admin-password pour vous authentifier.

A cela on peut ajouter un petit streamripper:

streamripper http://172.16.x.y:8000/1.fm -d ~/streamripped

Pour enregistrer. En parlant de streamripper, j'avais tenté au début de relayer avec streamripper -r, mais malgrès les apparences du netstat -pl (*:8000 LISTEN), il ne bind qu'en local, donc impossible d'en faire profiter les collègues :-)

Vous prendrez bien un peu de ssh avec votre tunnel ?

Il arrive des fois où on aimerait pouvoir relier directment deux machines appartenant a deux réseaux distincts. C'est par exemple mon cas quand j'ai besoin (envie on va dire) d'accéder à ma machine du boulot depuis une machine non connectée au VPN. Dans ce genre de cas, il existe en général une machine qui possède des interfaces susceptibles d'accéder à chacune des machines (le concentrateur VPN par exemple). Nous appellerons cette machine relay, car elle servira de relai au tunnel. Pour éviter les sempiternelles appellations A et B qui embrouillent plus qu'autre chose, les machines s'appelleront startpoint pour la machine sur laquelle on a la main et endpoint pour la machine à laquelle on souhaite accéder.

Postulats de base:

  • relay possède un serveur SSH qui tourne
  • startpoint possède un client SSH capable de créer un tunnel (ssh, par exemple)
  • relay est accessible depuis startpoint et peut se connecter à endpoint

Bien, allons y franchement, la commande, à executer depuis startpoint, permettant de créer un tunnel SSH entre startpoint et endpoint est la suivante:

ssh -L 2222:endpoint:22 relay

Qu'avons nous fait là ? L'option -L de SSH sert à binder un port de la machine locale (startpoint donc), à un autre port (ou le même) de la machine distante (endpoint). Ici, on associe le port local 2222 (22 étant déjà pris par mon serveur SSH, mais on pourrait utiliser le port 22 si aucun serveur ne tournait, à la différence près qu'il faudrait lancer la commande en root pour pouvoir binder un port inférieur à 1024 (c'est comme ça)) au port 22 de endpoint, c'est à dire le serveur SSH. Il nous est dès lors possible d'ouvrir une connection SSH sur endpoint en se connectant au port 2222 de notre machine locale:

ssh -p 2222 localhost

Magique non ? Bien sur, il est possible de forwarder n'importe quel port au travers du tunnel:

ssh -L 8080:endpoint:80 relay

Faire pointer votre navigateur sur http://localhost:8080/ vous ammenera sur le serveur web de endpoint.

Mais un tunnel ne se limite pas à joindre deux machines d'un réseau différents. On peut également imaginer un tunnel entre deux machines dans l'unique but de sécuriser une transmission, par exemple, des échanges de mails. Imaginons que votre serveur mail preferré, pop.example.com, ne propose pas de connection POP sécurisée. Vous pouvez remédier à ce manque flagrant de confidentialité en créant un tunnel SSH:

ssh -L 1100:localhost:110 pop.example.com

Bien sur, ce cas de figure nécessite d'avoir un compte permettant une connexion SSH sur pop.example.com, ce qui n'est pas forcément le cas. Pour remédier a ceci, deux solutions: utiliser un relay qui possède un serveur SSH, ou installer un serveur SSH sur startpoint pour s'en servir comme relai (sudo apt-get install openssh-server sur toute distribution debian-like qui se respecte):

ssh -L 1100:pop.example.com:110 localhost

And voila, il n'y a plus qu'a indiquer à notre client mail que le pop se situe sur localhost au port 1100, et le tour est joué :-)

Coca-Cola et Minute Maid

Non je ne vous dirai pas que Minute Maid appartient à Coca-Cola, tout le monde le sait déjà. Le truc qu'on ne sait pas forcément, et ce surtout grâce au célèbre mantra coca == sucre, c'est qu'un Coca-Cola est moins calorique et contient moins de glucides qu'un Minute Maid Tropicale. Qui l'eut-cru ?

Faute de frappe coquace

22:43 <@*****> jai ça si vous ovulez

Polymorphisme et PHP

Ou presque ! Je vois déjà vos têtes ahuries devant un tel titre, et pourtant je ne suis pas fou non, j'ai juste décidé d'avoir un titre qui ment par ommission :-) Bref, pour ceux qui ne savent pas ce qu'est le polymorphisme, c'est tout simplement le fait d'avoir plusieurs fonctions qui portent le même nom, mais dont les arguments différent, et pour ceux qui ne comprennet pas pourquoi Polymorphisme et PHP est un drole de titre, et bien sachez que le PHP est un langage non typé (ou faiblement typé selon la personne a qui vous parlez), et qu'il n'est donc pas possible de faire usage du Type Hinting dans la définition d'une fonction (pas sur les types de base en tout cas, mais PHP5.x introduit le type hinting sur les objets, ce qui ne change rien a notre histoire), ce qui fait que PHP ne peut pas gérer le polymorphisme brut.

Continue reading...

A propos de Phoenix Wright

Comme promis précédemment, voilà un petit billet explicatif sur Phoenix Wright. C'est un jeu sorti sur la dernière console portable de Nintendo, la DS. Mais pas n'importe quel jeu ! Phoenix Wright: Ace Attorney, puisque c'est son nom complet, vous met dans la peau d'un Avocat fraichement diplomé qui va devoir s'occuper d'affaire pour le moins ardue en tant qu'avocat de la défense. De votre premier procès où vous devrez prouver l'innocence de votre ami d'enfance au dernier procès du jeu dans lequel même l'accusé est persudadé d'être coupable, vous aurez fort à faire pour vous imposer et faire régner la justice !

Phoenix Wright reprend un concept de jeu vieux comme le monde: le Point and Click RPG. Le jeu se compose d'une succession d'écrans plus ou moins fixes, et le gros de l'action est constitué de dialogues et chaque procès se retrouve divisé en deux phases distinctes: l'enquête et l'audience. L'humour est omniprésent, et les personnages, récurrents au fil des procès pour la plupart, possèdent tous leurs traits de caractères qui font d'eux ce qu'ils sont (je sais ça veut rien dire), et on se retrouve rapidement addicté à ce jeu qui, de premier abord, ne paie pas de mine.

Bref, vous l'aurez compris, je suis complètement fan de ce jeu, et j'attends avec impatience la sortie en europe du second volet: Phoenix Wright: Ace Attorney, Justice For All :-)

Conqueror Of Shamballa

Pris d'une frénésie japanimophile, j'ai expédié ce soir la grosse quinzaine d'épisodes qu'il me restait de Full Metal Alchemist pour terminer en beauté par le film: Conqueror of Shamballa. Bien que le film m'ait un peu déçu, l'émotion est au rendez-vous. FMA, c'est un de ces anime qui vous font aimer les anime. Un subtil mélange de violence, d'humour, de sentiments, de beauté, etc., un mélange donc, qui détonne, qui surprend parfois, qui fait rire souvent, mais surtout, et c'est ce que je retiendrais de tout ça, qui émeut.

Voilà, a présent il ne me reste plus qu'a me re-plonger dans le manga, ou à commencer un autre anime (ou les deux finalement).

Huhu

Désolé pour le titre hautement philosophique de ce billet, mais c'est tout ce que ça m'inspire :-)

Nudist Trampolining

Et pour patienter en attendant les sous-cités articles, pourquoi ne pas faire une petite séance de nudist trampolining ? :)

Crawley kids in a tilgate park

Il fallait y penser

Edit: la vidéo a été retirée par l'utilisateur, mais vous pouvez toujours aller lire la suite de l'histoire (merci barjakounet) qui explique le début :)

Les vidéos extraordinaire de Totoro: House of Dominos

J'ai un collègue au bureau, que nous appellerons Totoro pour son anonymat, qui, chaque jour, nous gratifie d'au moins une vidéo extraordinaire trouvée lors de ses pérégrinations sur youtube. J'ai donc décidé de vous faire partager le meilleur de ces vidéos.

On commence avec BakuTen - house of dominos.

Irrécupérable...

Le début de la fin:

(12:01:00) Thibs: tu kiff toi alors le ZF ?
(12:01:11) Hubert de Mirmoxor: j'ai fais une fois
(12:01:13) Hubert de Mirmoxor: en pickup
(12:01:19) Hubert de Mirmoxor: avec un drood au heal
(12:01:22) Hubert de Mirmoxor: et pas de wawa
(12:01:31) Thibs: le ZendFramwork :P

Continue reading...

Zinedine Zidrame: l'inexplicable expliqué

Mise en contexte: sur une possibilité de contre des français, l'italien (j'ai oublié son nom) marque Zidane en lui tirant le maillot.

Zidane: oh tu m'as tiré le maillot là lolool !
L'italien: ma qué ! yénépaféexprès !
Zidane: geeeeenre mdrrrrrr !
L'italien: par contre, yé tiré ta mère
Zidane: ...

Et c'est le (Zi)Drame.

Promis j'arrette le foot.

Une explication possible

Pour le geste de Zidane:

22:27 <@gre> <zidane> baisse les yeux
22:27 <@gre> <italien> non !
22:27 <@gre> <zidane> tiens prends ça

Trop utiliser VIM peut rendre dépendant.

geoffrey@PROD000005:~$ ls
bin   Desktop      helloworld.jpg     openvpn      tmp   xml
code  Documents    Network            public_html  tmp2
dc2   Extractions  OnRefaitMatch.xml  tests        :w

Ce n'est pas un fake. Et pour ceux qui ne comprennent pas, tant pis pour vous.

- page 1 of 2