lundi, novembre 27, 2006

Balle populaire

(à propos de : http://www.map-site.fr/sitev02/ministere_des_affaires_populaires.html)
MAP, le ministère des affaires populaires, est un groupe du ch'nord qu'il est bien. Ils me font penser à IAM (période Ombres et Lumières plus précisément), à Zebda et Sinsémilia. En semblant plus engagés que leurs aînés.

C'est exactement ce dont j'avais besoin pour sortir du marasme électoral et hivernal : un groupe pêchu, optimiste et engagé.
Une seule et même musique, un seul et même bon son, bon sang de bon soir, ça fleure bon la révolution, que les choses bougent enfin, que les gens se bougent ensemble, la connerie humaine divise quand notre musique rassemble !

mercredi, octobre 25, 2006

La nausée

(à propos de : http://www.dailymotion.com/video/xeyth_sarko-demago)

Sarko démago
envoyé par pcfie

dimanche, octobre 08, 2006

Telltale Games

(à propos de : http://www.telltalegames.com/home)
Je ne suis plus un joueur (video s'entend), comme beaucoup. La plupart des jeux demande un investissement en temps bien trop important et ne fournissent pas les repères permettant au joueur épisodique de se remettre dans le bain, de rapidement se remémorer la situation dans laquelle il se trouvait lors de sa dernière partie.
J'avais fondé beaucoup d'espoirs en Fahrenheit (de Quantic Dreams) qui devait initialement (comprendre : deux ou trois ans avant sa sortie) être vendu en ligne sous forme d'épisodes. Mais, hélas, trois fois hélas, le dégonflement de la bulle 1.0 a eu raison de ce modèle économique et fahrenheit a été produit et édité de manière classique.
En passant sur Canard+ je découvre que le nouveau Sam'n'Max sera une mini série vendue à l'épisode. Le premier épisode étant pour la fin du mois. Chic, chic : la suite d'un jeu d'aventure culte (comme tous les point'n'click de chez Lucas Arts) et un mode de distribution intéressant. Il ne reste plus qu'à espérer que ce soit du bon boulot.
Le studio s'appelle Telltale Games et il édite aussi CSI: les experts et Bone d'après la bédé du même nom (et non je n'ai pas dit éponyme !). Il y a déjà deux épisodes pour Bone. Le tarif de Bone est plus cher que celui annoncé pour Sam'n'Max (13$ pour Bone, 9$ pour Sam'n'Max) avec un rabais pour ceux qui paieront par avance pour toute la saison (6 épisodes).
Pour juger sur pièce j'ai donc téléchargé la démo puis acheté le premier épisode de Bone. C'est donc un bon jeu d'aventure mais malheureusement court : sans me presser il a duré deux heures. 13$ (soit un peu plus de 10€) pour deux heures de divertissement c'est plus cher que le cinoche.
La baisse de prix pour Sam'n'Max se trouve peut-être être un ajustement pour trouver le prix du marché. A 9$ (plus ou moins 7€) pour deux heures de jeu une fois par mois, je suis client. A 13$, moins.
Les jeux étant (au moins pour Bone et Sam'n'Max) des point'n'click leur linéarité se prête bien au découpage en épisodes. Et le découpage en épisode permet de rappeler le contexte au joueur au début de chaque partie.
Bref, ça me plaît : cette année je jouerai au moins à un jeu et ce sera Sam'n'Max !

jeudi, juillet 27, 2006

A mettre entre toutes les mains (à partir de 16 ans)

(à propos de : http://www.lesimpressionsnouvelles.com/fraise_et_chocolat.htm)
Je viens de finir Fraise et chocolat d'Aurélia Aurita. Héhé !
Joli récit érotique, décomplexé (on est loin des bancs publics, bancs publics) et écrit par une femme de ses premières semaines de passion avec Frédéric Boilet.
Comme dit Sfar (à propos de Sfar, du Japon -- l'action de Fraise et Chcocolat se passe au Japon -- et de Frédéric Boilet, il y a le carnet Japon) : ça devrait être distribué en pharmacie aux amoureux (sauf que ce n'est pas très safe sex : pas l'ombre d'une capote de tout le livre).

dimanche, juin 25, 2006

Cassandre

Pour information, et je devais cette information à quelques personnes, le dernier Krach immobilier date, en France, de 1991.

Sinon, petite collection de liens :

Alors, Cassandre ou pas ? Faites-vous votre avis...

vendredi, juin 23, 2006

SEL, Sol, troc et services

(à propos de : http://www.troc-services.com/)
Via Libération :
Un site d'échanges de services par internet, www.troc-services.com, innove en créant une monnaie virtuelle qui permet de troquer à plusieurs


C'est marrant l'article ne fait pas mention du fait qu'il s'agit du premier (?) SEL virtuel.

Sauf que, trouvé dans la FAQ :
Les échanges entre les adhérents sont valorisés par des Sols. Le moyen d'obtenir des Sols est de réaliser des services ou d'utiliser ceux offerts lors de l'adhésion. L'option Paypal d'achat de Sols a pour but de permettre aux personnes qui sont pressées et qui n'ont pu donner de services ou s'en faire acheter d'obtenir des Sols immédiatement à travers un paiement Paypal. Ces mêmes Sols (ainsi que ceux qui sont offerts lors de l'abonnement) ne sont ni transmissibles ni convertibles.

Mais aussi :
L'abonnement annuel durant la phase de lancement est gratuit, il est possible qu'il n'y ait jamais d'abonnement à payer.


Ouch ! C'est peut-être pas tant un SEL que ça ce site.

Ces mêmes sols ne sont ni transmissibles ni convertibles, non convertibles je comprends mais non transmissible, je ne comprends pas ! A quoi sert une monnaie si elle ne peut être transmise ? Il suffit de créer un service bidon pour transmettre cet argent.

Ensuite, autant je comprends l'intérêt du crédit initial de 20 Sols (pour amorcer la pompe) autant j'ai des doutes sur l'achat de Sols. En effet, cela est équivalent a la possibilité pour tout un chacun de faire marcher la planche à billets, de se fabriquer du crédit temps (à 10€ l'heure) et donc d'augmenter artificiellement la quantité de temps dans le marché (alors que le temps est une ressource rare).

Du coup, un acteur non impliqué (c'est à dire pas à 100% dans le système) peut être favorisé car il a la possibilité de transformer sa richesse du système capitaliste en richesse du système de troc.

Par ailleurs, il est intéressant de constater que les promoteurs de cette monnaie disent qu'elle permet de recréer du lien social alors que, de l'avis de certains, la monnaie a détruit le lien social dand l'échange.

mercredi, juin 21, 2006

Commentaires

Un rudimentaire flux des commentaires est dispo.

Fête de la musique

HUMAN?FLy
A partir de 22H
Rue de la TREILLE (brin d' zinc) si le temps le permet...
Clermont-Ferrand

(via Eric)

Sunday, October 08, 2006

IE Png Transparency Fix Fix

(à propos de : http://homepage.ntlworld.com/bobosola/index.htm)
I was experiencing a random bug of shrinking pictures with pngfix.js. I finally tackled it! You have to wait til the image is loaded (img.complete == true) before measuring it. So if the image isn't yet loaded, wait for img.onload before fixing the transparency.
Download pngfix.js!

Thursday, July 06, 2006

Architecture web moderne, le nerf de la guerre : les données (1)

Bon, suite de mes visions architecturales pacorabiennes. Cette fois cela va être plus concret. Le sujet du jours est : les données.

Ma position est assez simple : la couche d'accès aux données (DAL) doit être directement exposée sur le web. (Ce qui ne signifie qu'elle doit être en lecture/écriture ni même en lecture pour tout le monde ; l'authentification étant gérée par ce que fournissent http et https en standard, pas de sessions.)

Chaque ressource correspond à un objet, une entité (biffez la mention inutile). Les relations sont remplacées par des hyperliens.

Pour les cas simples, une table/une vue peut directement être mappée sous le chemin : /nom-de-la-table/valeur-de-la-clé-primaire et renvoyer (après négociation du type de la représentation, ici du javascript) :
{
id: 'abcdef',
champ1: 3.14,
champ2: Date(1978, 10, 11),
relation1: Ref('table2/189'),
relation2: [Ref('table1/234'), Ref('table1/567')]
}


Le minimum nécessaire de types de représentations est : html, xml et js pour permettre, respectivement, de :
  • naviguer à travers les données depuis un simple navigateur,
  • maximiser l'interopérabilité (à part le locomotive basic tous les environnements de dev sont à présents équipés de librairies correctes pour traiter ce bon vieil xml)
  • accélérer le développement d'applis webs modernes.


Bon, bien sûr cela ne couvre que la lecture (et encore je n'ai pas insité sur le fait que les headers ETag et Last-Modified doivent être utilisés). Pour l'écriture distinguons les 3 opérations de modification : création, modification et suppression. Mais je ne vais pas mapper ces opérations sur les méthodes http PUT, POST et DELETE. Pas complètement. Je n'aime pas la sémantique du PUT qui consiste à laisser l'initiative du nommage au client ce qui est, pour moi, une abération.
Donc pas de PUT mais un POST de la ressource sur une url "factory" (typiquement /nom-de-la-table) qui redirigera (header "Location:") sur l'adresse de la ressource nouvellement créée après avoir répondu 201 Created.
Reste le DELETE qui est parfait mais ne fait pas partie de Lo-Rest, il faut donc penser à proposer au client une alternative Lo-Rest au DELETE de la ressource. C'est facile, il est juste nécessaire d'y penser).
NB : En Ajax il est possible d'être Hi-Rest. PUT et DELETE sont disponibles.
Pour les simples modifications, il suffit de poster une représentation de la ressource modifiée à sa propre adresse.

Facile n'est-il pas ?

Pour les prochains billets il me reste à couvrir : comment imposer les intégrités métiers (sous-titre : "Sur le web personne ne sait que vous êtes une procédure stockée.") et comment gérer les transactions.
Ensuite, c'en sera fini de la couche d'accès aux données et je traiterai de la couche logique et de la couche présentation.

Friday, June 23, 2006

L'UTF m'a tuer

J'ajoute un feed (atom 1.0) pour suivre les commentaires de ce blog bifide, généré à partir d'un petit CGI en Python, construit en se basant sur une source sûre. J'itère jusqu'à ce que mon système fonctionne et que le feed valide.

Tout va bien tout est en UTF-8. Facile. Je suis trop fort.

Tiens, on me signale que mon flux s'affiche mal avec des problèmes sur les accents. Allons donc ! Ca marche très bien ! D'ailleurs ça valide... pas !

Le titre d'une entrée de blog est obligatoire et le formulaire de saisie n'a pas de champ titre. J'avais choisi de tronquer le commentaire à 20 caractères pour créer le titre... seulement la chaîne fournie par le module CGI est une chaîne de caractères codés sur un octet ! Donc mes caractères accentués tenaient sur deux "caractères" (oui ça commence à ressembler du Raymond Devos) et un caractère malheureux se trouvait à cheval sur la frontière du 20ème octet. Chlac ! Coupé en deux le caractère. Du coup, ça ne veut plus rien dire, ce n'est plus de l'utf-8 et les lecteurs de feed retombent en mode "ascii" (un caractère par octet) montrant deux caractères cabalistiques à la place de mes jolis caractères accentuées...

J'ai alors patiemment protégé toutes mes entrées en les décodant selon utf-8 et toutes mes sorties en les encodant (en utf-8 toujours). Comme ça, entre les deux, je manipule des chaînes de caractères et pas des chaînes d'octets qui se prennent pour des caractères ! Quelle vilaine vieille habitude de confondre octet et caractère...

Wednesday, June 21, 2006

Architecture web moderne : introduction

J'initie une série d'articles, en français !, sur ma perception actuelle de comment doit se construire une application web -- dans le but avoué de rationaliser mes idées.

Le web est avant tout un grand référentiel. Personne ne se marche sur les pieds grâce aux noms de domaines qui permettent de partitionner l'espace des références.

Un nombre limité d'opérations est possible sur ce référentiel et deux seulement d'entre elles sont d'usage courant (GET et POST) que l'on peut résumer à, respectivement, consultation et modification.

Le web est prévu pour l'intermédiation : entre deux machines, il peut toujours y en avoir une troisième

Tuesday, June 06, 2006

And now for something completely different

(à propos de : http://cgrand.net/lasoupe/)
Switching to another blog : la soupe à la grimace.

Bon appétit !

Tuesday, February 21, 2006

If I were a golden fish, I would stick PostIt notes everywhere

To connect to a full remote X desktop using cygwin: go and copy /usr/X11R6/bin/startxdmcp.bat and change SET REMOTE_HOST=10.0.0.1 to match the server you try to connect to.
If all you get is a grey screen, ssh to your server go and set "Enable=true" in the [xdmcp] section of /etc/gdm/gdm.conf (if you're not using gdm, rtfm).

Tuesday, February 07, 2006

Web apps and scopes

In a classical webapp (ie not using continuations) there's three scopes : application, session and request. The application scope is not that much used except for architectural purposes and the request scope is only useful for data only relevant to the computation at hand. We are left with one single choice: session scope. Consequently we cram in session scope everything not worth of being stored in database.
Too much shared state!
Okay, alternatively you can store the state in the client. There's two ways:
  • on the one hand, hidden fields and form submissions (through post methods); as far as I know, it's the current design of JSF and Asp.Net (Eric, Olivier? someone to confirm?).
  • on the other hand, use the url stupid!... and end up passing 3k urls to the user.

So what?

Here, on Eric's request, I'm going to document an idea of design which I've never written down: webthreads.

A webthread is the succession of pages accessed through forward browsing. A webthread can be forked (eg by opening a link in a new tab).
First of all, I have to offer a solution to the state storage responsibility problem. The state is stored on the server but an id identifying the state is stored in the browser. Where to store this id? Url or hidden form field? (Cookies aren't an option, they are shared between windows.) My bet goes on the url.
So I propose to use pathes of the following form: /[state-id]/[applicative-path].

My core design idea is to link states and, hence, when looking up for a property you have to look in the current state and, if the property is not found, you follow the links 'til you find the property... or the end of the webthread.

How to link the states? Two solutions: use the Referer http header or rewrite (client-side or server-side) all the urls in the served page.
(I'll let the reader to develop the url rewriting way-of-link as an exercise.)

Synopsis

The client is at /0001/home where (0001 is the state id) and requests /preferences.
The server receives the /preferences request with /0001/home as a referer. The server creates a new state (0002), and links 0002 to 0001 (0002 "inherits" all the properties of 0001). The server redirects (302) the client to /0002/preferences.
The client requests /0002/preferences.
The server does the actual requested processing and returns its response.
Rinse and repeat.

(If you request /preferences from /0001/home again, you'll be redirected to /0003/preferences)

Et voilà! You've got webthreads and their associated scopes!

Ajax (and other page refreshing solutions) bonus

The internal processing (ajax and reloads) of a page can benefit from having a persistent state associated to the page: all such requests take place in the same state, internal requests MUST NOT spawn new states.

Here you go Eric, you've got the "interactive page" scope we talked about some times ago!

Now it's up to the implementer to refine this mechanism and to define a state invalidation policy (a hard job).

Monday, February 06, 2006

Double Proxy Pattern

Here, I document a behavioral pattern which I often (not very often but quite often) use and which doesn't seem to be much used except by me. Maybe it's an anti-pattern.
Here is a classical implementation of the lazy-loading proxy:
interface Banana {
boolean isRipe();
}
interface BananaLoader {
Banana loadBanana();
}
class LazyBanana implements Banana {
private Banana banana;
private BananaLoader bananaLoader;

LazyBanana(BananaLoader bananaLoader) {
this.bananaLoader = bananaLoader;
}

boolean isRipe() {
if (banana == null) {
banana = loader.loadBanana();
}
return banana.isRipe();
}
}

Which i use like this:
Banana bananaNumberOne = new LazyBanana(new BananaLoader() {
Banana loadBanana() {
return myBananaStore.getById(1);
}
});
print(bananaNumberOne.isRipe()); // loading occurs now
print(bananaNumberOne.isRipe()); // no more loading

(The use of a closure-style anonymous class instance is, maybe, not so classical.)
The if bugs me (it feels awkward and out of place) so I found a way to code around it:
interface BananaReference {
Banana getBanana();
void setBanana(Banana banana);
}
class BananaLazySwapper implements Banana {
private BananaLoader bananaLoader;
private BananaReference bananaReference;

BananaLoader(BananaLoader bananaLoader, BananaReference bananaReference) {
this.bananaLoader = bananaLoader;
this.bananaReference = bananaReference;
}

boolean isRipe() {
Banana banana = bananaLoader.loadBanana();
bananaReference.set(banana);
return banana.isRipe();
}
}

class LazyBanana2 implements Banana, BananaReference {
private Banana banana;

LazyBanana2(BananaLoader bananaLoader) {
this.banana = new BananaLazySwapper(bananaLoader, this)
}

boolean isRipe() {
return banana.isRipe();
}

Banana getBanana() {
return banana;
}
void setBanana(Banana banana) {
this.banana = banana;
}
}

(In such a case (lazy loading), BananaReference can be avoided using anonymous inner class)

So I've got rid of the if which bugged me. I've traded it for a method lookup. I prefer that code smell.
Basically, the front-end proxy is a brain-dead proxy whose the proxied object can be replaced at runtime. The back-end proxy performs the actual loading and replace itself (in the first proxy) by the loaded value.
Over-architecturing?
The Double Proxy Pattern goes far beyond lazy objects. I've first used it while writting a recursive descent parser with memoization (à la Packrat plus fixed point detection).
Now, I'm using it to manage the lifecycle of persistent objects. A persistent object can have several states: transient, untouched, dirty, stub. There's two distinct lifecycles (depending on whether the object was already persistent) :
  • transient -> untouched -> dirty -> untouched -> dirty -> ...
  • stub -> untouched -> dirty -> stub -> untouched -> dirty -> ...
(In stub state the persistent object can not be in memory yet (lazy loading) or anymore (reclaimed by the garbage collector).)
For managing these lifecycles I use the DDP with four back-end proxies (one per state).

This is some actual muscle flexing!

Yeah!

(à propos de : http://www.amazon.com/gp/product/B00008R104/sr=1-2/qid=1139255936/ref=sr_1_2/002-8353008-2771261?%5Fencoding=UTF8)
Today, the postman brought me this. More info, here (beware: flash required).

Tuesday, January 31, 2006

What if...

Having just explained to a friend what I have learnt using the Spring framework, one thought came to me: an object's methods are divided into three groups. These groups are:
  • methods which are part of an interface implementation,
  • methods which express depedencies,
  • ancillary methods which matter only for the inner workings of the object at hand (and of its hierarchy).
So, what if these three groups where used instead of the classic visibility modifiers (public, protected, private, package etc.)?