skip to main | skip to sidebar
Code 18
Manuel du savoir-faire à l'usage des geeks et des curieux
RSS
  • Accueil
  • Le web au Québec
  • Liens
  • Twitter
  • Facebook
  • À propos

mardi 30 juin 2009

Clone de lightbox pour jQuery

Publié par Infinite Loop, à 20 h 46 2 commentaires

Il faut l'avouer, on aime tous le look and feel des diaporamas photos JavaScript comme Lightbox. Depuis, l'idée à été reprise maintes fois en différentes implémentations (dont Lightbox 2, ThickBox, Slimbox 2, pour ne nommer que ceux là) pour Prototype, jQuery et autres frameworks JavaScript.

Le plus complet à ce jour demeure Shadowbox qui est beaucoup plus évolué et qui peut être utilisé sur une base Prototype, jQuery, Mootools, YUI, Dojo ou Ext. Comme il est très professionnel, c'est pour cette raison qu'il est maintenant payant si on veut en faire un usage commercial (rassurez-vous, une licence multi-développeurs ne coûte que 50$ US, sinon c'est gratuit pour les autres types de projets). Fait notable, la librairie Shadowbox a été écrite par un développeur californien du nom de Michael Jackson (à son grand malheur)...

Par contre, je vais délaisser pour aujourd'hui les librairies les plus populaires pour vous introduire à un autre visualiseur d'images et de vidéos, cette fois en tant que plugin de jQuery : prettyPhoto. Pourquoi celui-ci en particulier ? Parce qu'il a été développé ici, par un programmeur de Montréal (Québec) du nom de Stéphane Caron (que je ne connais pas du tout en passant) et je voulais tout simplement saluer son initiative et son excellent travail.

Pour l'installer, suivez ces quelques étapes faciles :

Inclure jQuery et le plugin prettyPhoto

<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/jquery.prettyPhoto.js"></script>
Inclure la feuille de style CSS
<link rel="stylesheet" type="text/css" href="css/prettyPhoto.css" media="screen" />
Ajouter aux liens la référence à prettyImage à l'aide de l'attribut "rel". Si la photo doit s'afficher seule, on indique uniquement rel="prettyPhoto", si c'est dans le contexte d'une galerie, on indiquera entre crochets le nom de référence qui permet le regroupement (comme l'exemple ci-dessous).
<a href="images/fullsize/001.jpg" rel="prettyPhoto[my_slideshow]" title="Description">
<img src="images/thumbnails/001.jpg" alt="Titre" />
</a>

<a href="images/fullsize/002.jpg" rel="prettyPhoto[my_slideshow]" title="Description">
<img src="images/thumbnails/002.jpg" alt="Titre" />
</a>

<a href="images/fullsize/003.jpg" rel="prettyPhoto[my_slideshow]" title="Description">
<img src="images/thumbnails/003.jpg" alt="Titre" />
</a>
Au chargement de la page, initialisez le diaporama avec une configuration semblable à la suivante :
$(document).ready(function(){

$("a[rel^='prettyPhoto']").prettyPhoto({
animationSpeed: 'fast',
padding: 40,
opacity: 0.5,
showTitle: true,
allowresize: true,
counter_separator_label: '/',
theme: 'dark_rounded',
callback: function(){}
});

});
Le plugin prettyPhoto est compatible avec l'affichage de photos, seules ou par galeries, le contenu Flash, iFrame (page externe), vidéos (.mov) et YouTube. Bien que 4 thèmes soient disponibles, le seul défaut que je vois se trouve dans les rares traductions car le texte est contenu dans les images et elles sont exclusivement en anglais (pour l'instant ?). Une amélioration future souhaitée serait d'avoir une version simplifiée avec des icônes seulement, où le texte pourrait être remplacé par des tooltips.


Tags: JavaScript

Nouveautés cette semaine

Publié par Infinite Loop, à 19 h 58 0 commentaire

Vos nouvelles de fin de soirée...

Technologie

  • Lancement officiel de PHP 5.3
  • Sortie officielle de Firefox 3.5
  • Nouvelle version pour l'éditeur Netbeans 6.7
  • 300ème post officiel sur Code 18 :-)
  • J'allais oublier... Prototype 1.6.1 RC3 (compatibilité Chrome, IE8 et PDoc)
Sports
  • Canadiens de Montréal : Christopher Higgins échangé contre Scott Gomez
Météo
  • Orages prévus demain pour la journée officielle du déménagement... et la fête du Canada (au cas où vous auriez oublié). Pour les autres, c'est congé!


Tags: Le coin du geek

lundi 29 juin 2009

Thèmes pour Notepad++

Publié par Infinite Loop, à 20 h 30 4 commentaires

Bien que je travaille principalement avec des éditeurs de code, l'application Notepad++ (gratuite) est tellement pratique que je finis tout le temps par l'utiliser à toutes les sauces.

Un des points qui m'a longtemps agacé, c'est que par défaut, le fond de page est blanc et qu'à force de passer beaucoup de temps à visionner des fichiers textes, on finit par s'arracher les yeux. Bien entendu, on peut utiliser la fenêtre "Style configurator" (menu Settings) pour modifier une à une les différentes propriétés jusqu'à ce qu'elles soient agréables à l'oeil. Mais on peut aussi être paresseux et installer un thème, même si ce n'est pas une fonctionnalité officielle de l'application.

Pour modifier d'un seul coup la thématique :

  1. Choisissez et téléchargez en un dans le répertoire des thèmes pour Textmate
  2. Vous obtiendrez un fichier .tmTheme qui est structuré en XML
  3. Ouvrez le dans un éditeur texte (comme Notepad++) et copier tout le contenu
  4. Comme il s'agit d'un thème originalement créé pour un éditeur de Mac OS X, nous devrons le convertir en utilisant un outil en ligne comme Textmate Theme to Notepad++ Styler
  5. Collez le texte dans la boîte prévue à cet effet, cliquez sur le bouton Download et enregistrez le fichier *.stylers.xml
  6. Au menu Start, lancer Run pour exécuter une commande et entrer ceci (Windows XP et Vista) :

    %appdata%/Notepad++

    Ceci devrait ouvrir un explorateur de fichiers positionné directement dans le répertoire de l'application, par exemple (ou rendez-vous directement en prenant soin de modifier votre nom) :

    C:\Documents and Settings\code18\Application Data\Notepad++

  7. Vous devriez trouver un fichier appellé stylers.xml. Modifiez son nom pour en faire une copie de sauvegarde au cas où vous voudriez revenir au thème original
  8. Prenez le fichier que vous venez de télécharger, renommez le stylers.xml et déposez le dans le répertoire à la place de celui original
  9. Fermez Notepad++ et ouvrez le à nouveau. Le thème devrait être appliqué (ouvrez une page de code pour apprécier les changements).
  10. Pour passer d'une thème à l'autre, il suffira de nommer le thème voulu stylers.xml et redémarrer l'application.
Lequel préférez-vous ?


Tags: Coffre à outils

dimanche 28 juin 2009

Trouver de l'emploi en web au Québec ?

Publié par Infinite Loop, à 11 h 50 1 commentaire

J'ai lu récemment qu'en raison de la récession, le taux de chômage avait grimpé à 9% au Québec. Ça touche beaucoup de gens et les technologies de l'information (TI) ne sont pas épargnées, même si on semble être moins touché comparativement à d'autres domaines spécialisés. De plus, les perspectives d'emploi semblent bonnes car je vois constamment des offres d'emplois à combler en informatique et en programmation.

Si vous avez été directement touchés par la crise économique, que vous êtes en recherche d'emploi ou que vous souhaitez tout simplement tester le marché, j'ai dressé une liste de ressources utiles pour orienter vos recherches. Il s'agit d'une liste non-exaustive allant du plus général au plus spécifique. Si j'en oublie ou si vous en connaissez d'autres, n'hésitez pas à m'en faire part, on en fera profiter tout le monde.

Sites d'emplois généralistes

  • Jobboom.com
  • Monster.ca
  • Workopolis.com
  • Emploi-Québec
Sites spécialisés TI / TIC / NTIC
  • Lien Multimédia (section Emploi)
  • Grenier aux nouvelles (souvent pour des postes d'intégrateurs et designers)
  • Section emploi de PHP Québec
  • Espresso-Jobs
À titre d'information, selon cette enquête salariale 2008 en TI de TECHNOCompétences, le salaire moyen d'un programmeur et d'un intégrateur oscille autour de 50000$, variable selon l'expérience et l'emplacement géographique dans la province.


Tags: Liens, Saviez-vous que

Citation no. 36 sur le silence

Publié par Infinite Loop, à 10 h 03 0 commentaire

Avant d'ouvrir la bouche, assure-toi que ce que tu vas dire est plus beau que le silence.

- Confucius


Tags: Citations

samedi 27 juin 2009

SSH2 : capturer le résultat d'une commande

Publié par Infinite Loop, à 07 h 39 2 commentaires

Dans la journée d'hier, je travaillais sur une application PHP qui devait ouvrir une connexion SSH vers un serveur pour exécuter un script bash. En théorie, je devais simplement capturer le résultat en sortie du script appelé. Je m'en veux un peu car j'ai perdu un peu trop de temps à mon goût à essayer de figurer pourquoi il n'y avait aucun output. Pourtant, selon la documentation, ça semblait assez simple à réaliser. Et ça l'était une fois qu'on connaît les subtilités.

J'ai expérimenté avec les éléments suivants mais je n'ai retenu que la première solution :

  • l'extension PHP Secure Shell 2 de PECL
  • La classe SSH2 for PHP
  • La librairie phpseclib qui contient Net_SSH2
  • Un truc populaire que j'ai trouvé sur plusieurs forums (avec un shell)
Avec l'extension SSH2, pour pouvoir lancer une commande et récupérer l'output, on doit utiliser ssh2_exec() ou ssh2_shell(). La première est plus simple tandis que l'autre lance un shell interactif sur la machine distante où on lance des commandes comme dans un terminal.

La différence majeure est qu'en mode shell, l'environnement semble résoudre lui-même les chemins vers les programmes tandis qu'avec ssh2_exec, on doit spécifier les chemins absolus (la commande "whereis" devient alors très pratique pour les localiser). C'est exactement ce dont je n'ai pas eu le réflexe de tester.

Dans le code ci-dessous, une fois authentifié, il suffit d'indiquer le chemin complet de la commande à ssh2_exec().
// SSH : port 22 par défaut
$conn = ssh2_connect('ip', 22);
ssh2_auth_password($conn, 'username', 'password');

// Exemple 1 - output d'un script
$stream = ssh2_exec($conn, "/dir/get_movie_release_date.sh Gremlins", false);

// Exemple 2 - liste de fichiers
// $stream = ssh2_exec($conn, "/bin/ls ls -l /dir/", false);

// Exemple 3 - exit code d'un script bash
// $stream = ssh2_exec($conn, "/dir/routine.sh;echo $?;", false);

stream_set_blocking($stream, true);
echo stream_get_contents($stream);
Les deux dernières lignes permettent de récupérer le flux (stream) qui correspond uniquement au résultat de la commande (contrairement à ssh2_shell qui capture aussi le prompt). C'est beaucoup plus simple comme ça car sinon, avec le shell, on doit user d'ingéniosité en englobant la commande à l'intérieur de délimiteurs, attendre qu'elle s'exécute (l'utilisation de sleep peut s'avérer nécessaire pour patienter jusqu'à la fin de l'exécution du script), récupérer le texte qui s'est inscrit dans le terminal, extraire le flux de sortie en capturant ce qui se trouve entre les délimiteurs, nettoyer le tout et croiser les doigts pour que ça fonctionne bien à chaque fois.

En conclusion, trois points à retenir :
  • ssh2_exec est plus fiable que ssh2_shell pour capturer le flux de sortie
  • toujours spécifier le chemin complet menant aux commandes ou aux scripts à exécuter
  • depuis la version 0.9, si on ne spécifie pas de pty, il faut ajouter "false" comme troisième argument de ssh2_exec(). Autrement, on obtient rien en sortie


Tags: PHP

vendredi 26 juin 2009

Michael Jackson renaît grâce à son sosie !

Publié par Infinite Loop, à 19 h 03 0 commentaire

J'en ai déjà glissé un mot dans le passé mais comme c'est un sujet d'actualité, je ne peux que partager à nouveau la nouvelle avec vous. Grâce à la magie du web, Michael Jackson pourra poursuivre son rayonnement encore un bout de temps grâce à son sosie indien qui interprète magnifiquement Thriller...

GOLIMAR !!!



Extrait tiré du film Donga de 1985.


Tags: Humour

Personnaliser les extensions de fichiers web

Publié par Infinite Loop, à 16 h 57 0 commentaire

En visitant des sites web d'entreprises immobilières, j'ai fait un détour obligé par RE/MAX, un de plus importants joueurs dans l'industrie. Sur Remax-Québec, j'ai remarqué que les extensions de fichiers avaient été personnalisés par .rmx. Ça ne correspond pas à un langage de programmation qui m'est inconnu, mais bien à une façon de faire du branding et de cacher volontairement l'extension réelle des fichiers (les lettres sont choisies en référence aux consonnes de la marque).

Par exemple, on pourra faire croire visuellement que nos pages sont codées en .NET (.aspx) alors qu'elles sont en PHP, indiquer au serveur que les .html doivent être interprétées par le moteur PHP ou encore inventer de toutes pièces un nouveau type d'extension pour donner une identité propre au site.

Pour cela, la meilleure option consiste à créer physiquement des fichiers nommés selon l'extension désirée. Ensuite, on doit ajouter l'instruction suivante pour Apache :

AddType application/x-httpd-php .rmx

S'il s'agit d'un serveur dédié, on peut se permettre de l'ajouter dans le fichier httpd.conf d'Apache. Sinon, on préférera l'inscrire dans le fichier .htaccess (recommandé).

Dans le cas de Remax, les pages originales sont en JSP (JavaServer Pages). On voit dans les cookies la référence à JSessionID et le site utilise la technique de Url Rewriting pour convertir les extensions de pages .jsp à .rmx :

/fr/agent/invAgent.jsp?ida=12638

est l'équivalent et redirigé à :

/fr/agent/inscriptions/12638.rmx?ida=12638

Si le coeur vous en dit, vous pouvez aussi donner l'instruction à votre serveur Apache sur Linux que les pages PHP qui portent l'extension .exe doivent être interprétées comme du PHP, mais bon, les mauvaises langues diront que ce n'est pas très drôle...

AddType application/x-httpd-php .exe

Si mes souvenirs sont bons, quand Hotmail de Microsoft roulait encore sur Apache, c'était programmé en Perl (au moment de l'acquisition) et je crois qu'ils utilisaient une technique semblable pour faire taire les critiques, le temps de convertir le tout à un environnement Windows. Quelle honte pour eux que de préférer le serveur concurrent au détriment d'IIS, leur produit maison! Encore aujourd'hui, je me demande à quel point tout cela n'est que de la poudre aux yeux.


Tags: Apache

jeudi 25 juin 2009

Remplacer APC par Zend_Cache

Publié par Infinite Loop, à 20 h 48 0 commentaire

Tel que promis, je vous parle ce soir du composant Zend_Cache sorti tout droit du Zend Framework. En quoi est-il meilleur qu'APC ? D'abord, il ne repose pas sur une extension à installer sur le serveur (quoi que c'est aussi un désavantage). Ensuite, parce qu'il est orienté objet, hautement configurable et qu'il est adaptable à plusieurs mécanismes d'enregistrement tels que SQLite, XCache, memcached, APC (!), Zend Platform, etc.

En comparant cet exemple avec celui d'hier, vous remarquerez que contrairement à APC qui enregistre les objets sérialisés dans le répertoire /tmp/ (ou /temp/), Zend_Cache permet de spécifier à quel endroit on les sauvegarde (sinon, ce sera /tmp/ par défaut).

require_once('Zend/Cache.php');

// configuration
$frontendOptions = array(
'lifetime' => 3600, // expiration dans 1 heure
'automatic_serialization' => true
);

$backendOptions = array(
'cache_dir' => '/chemin/vers/projet/.cache/'
);

// frontend : Core
// backend : File
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);

if(!$recordset = $cache->load('unique_id')) {
// récupérer les résultats
$recordset = $conn->query('SELECT * FROM countries INNER JOIN ...');

// enregistrer la variable sous un nom unique
$cache->save($recordset, 'unique_id');
}
else{
// echo "Récupéré de la cache";
}

foreach($recordset as $row){
// loop...
}
En sauvegardant en mode "File" (dans le constructeur de la factory, la variable $backend), on retrouvera les objets sérialisés dans le répertoire .cache du projet, où chaque identificateur se transformera en fichier portant le nom de l'id, par exemple zend_cache---unique_id.

Ensuite, on peut vider une portion de la cache en retirant celle qui correspond à un identificateur précis :
$cache->remove('unique_id');
Enfin, même si on utiliser ce composant découplé de son framework, il a l'avantage d'offrir tout le nécessaire pour se marier à merveille avec l'architecture MVC.


Tags: PHP, Zend Framework

mercredi 24 juin 2009

APC cache pour optimiser la performance

Publié par Infinite Loop, à 10 h 53 1 commentaire

Lorsque vous développez un projet PHP et que vous remarquez qu'un processus est long, c'est probablement le moment de considérer à optimiser la performance en utilisant la mémoire cache. Ceci aura pour effet de retenir pendant un certain temps le résultat du processus et de le réutiliser sans avoir à le reconstruire à chaque fois.

Par exemple, imaginez que vous avez un formulaire où le visiteur doit choisir son pays à l'aide d'une liste déroulante. Cette liste pourrait provenir de la base de données qui retournerait environ 200 résultats. Ce n'est pas volumineux en terme de quantité mais comme on sait qu'il y a peu de chance que cette liste soit modifiée fréquemment, on pourrait la placer en cache pour réduire le nombre d'accès à la base de données, ce qui constitue déjà une amélioration notable. À raison de 1000 visiteurs par jour, seul le premier subira l'attente et les suivants bénéficieront de la version cachée. Ensuite, le résultat pourrait expirer au bout de 24 heures et serait regénéré à nouveau le lendemain.

Pourquoi ne pas tout simplement faire une liste statique me direz-vous ? Effectivement, si votre projet est simple, ce n'est pas nécessaire d'utiliser APC. Par contre, si la liste des pays est obtenue à partir d'une requête SQL qui cumule de façon distincte les pays entrés dans les fiches de 5 millions d'entreprises qui doivent respecter des filtres spécifiques accessibles par des jointures à des tables de références, c'est possible que la requête s'exécute pendant quelques secondes. Pour éviter de faire attendre le visiteur à chaque chargement de page, on peut faire le choix d'améliorer la performance au détriment de l'exactitude des données en temps réel (encore là, ce n'est qu'un exemple fictif pour illustrer mon propos, il existe plusieurs autres stratégies).

Pour en venir au code PHP, si l'extension APC (Alternative PHP Cache) est installée sur le serveur (voir php.ini ou phpinfo), vous pourrez tirer avantage de la mémoire cache. Vous verrez à quel point c'est simple. L'idée est d'assigner un nom/id unique à chaque donnée qu'on veut placer en mémoire cache. C'est à partir de ce tag qu'on pourra récupérer la donnée en mémoire, sinon on fera le travail pour la générer et on l'enregistrera sous ce nom unique.

// essai pour récupérer le contenu enregistré
$recordset = apc_fetch('unique_id');

// non trouvé
if ($recordset === FALSE) {

// on récupère la liste par la base de données
$recordset = $conn->query('SELECT * FROM countries INNER JOIN ...');

// enregistrer le recordset pour 24 heures
apc_store('unique_id', $recordset, 86400); // en secondes
}
else {
// echo 'Récupéré dans la cache!';
}

// continuer normalement
foreach($recordset as $row){
// loop...
}
Dans votre CMS, si vous vous rendez compte que des changements importants ont été apportés à la liste, vous pouvez forcer sa recompilation à la prochaine visite en supprimant l'élément en cache :
apc_delete('unique_id');
Autre fait à noter, vous pouvez récupérer la variable en cache en tout temps et sur n'importe quelle page. Assurez-vous seulement de pouvoir la regénérer facilement si elle est expirée, par exemple en encapsulant le tout dans une fonction.

Autrement, si APC est manquant et que vous êtes dans l'impossibilité de le faire installer, je vous recommande de vous tourner vers Zend_Cache du Zend Framework qui fait l'équivalent mais qui n'est pas dépendant d'une extension externe. J'en parlerai dans les prochains jours.


Tags: PHP

Norton Antivirus expire en direct chez Fox

Publié par Infinite Loop, à 09 h 00 0 commentaire

Un clip vidéo digne de mention tiré de Failblog. Pendant l'annonce des prévisions météo, le logiciel Norton Antivirus expire en direct pour afficher une fenêtre "Expired subscription". C'est de toute beauté de voir le curseur de la souris aller cliquer sur "OK" pour faire disparaître l'alerte.


Tags: Curiosités

mardi 23 juin 2009

Code source du Kindle d'Amazon

Publié par Infinite Loop, à 23 h 42 0 commentaire

Si vous avez l'esprit d'un hacker ou si vous êtes tout simplement curieux, vous serez intéressés d'apprendre qu'Amazon a publié sous licence GPL le code source du Kindle, son lecteur de livres électroniques (ebooks).

Il paraît que le Kindle est basé sur Linux et est constitué des composants open source suivants :

  • ALSA : Advanced Linux Sound Architecture pour le son
  • zlib : librairie de compression
  • Busybox : combine plusieurs utilitaires Unix en un seul exécutable
  • Freetype : pour les polices de caractères
Pour pouvoir consulter des ebooks sans acheter le Kindle, vous pourrez vous tourner vers l'application FBReader, parfait pour votre netbook ou votre portable Google Android.


Tags: Le coin du geek

lundi 22 juin 2009

Netbeans et l'encodage UTF-8

Publié par Infinite Loop, à 20 h 01 11 commentaires

Récemment, j'ai découvert l'éditeur Netbeans IDE qui permet de programmer en PHP (et d'autres langages comme Java, Python, etc) tout en analysant le code et en activant l'auto-complétion. J'ai d'abord été impressionné par sa légèreté car il était moins gourmand en mémoire que d'autres éditeurs que j'avais essayé dans le passé et que contrairement à Zend Studio, il est gratuit et offre beaucoup de fonctionnalités avancées. Après quelques mois d'utilisation active de la version 6.5.1, je dois dire que je ne m'ennuie pas du tout des concurrents et que je n'ai été ralenti en rien dans le développement de mes applications web.

Pourtant, j'ai quand même rencontré deux défauts qui m'ont agacé :

  • aussi curieux que ça puisse paraître, l'impossibilité de renommer les extensions des fichiers à partir de l'éditeur. Il faudra attendre la version 6.7 pour qu'on puisse le faire sans passer par l'explorateur de fichiers du système d'exploitation.
  • lorsque j'ouvrais mes anciens projets créés à l'aide d'autres outils, Netbeans avait de la difficulté à interpréter correctement les fichiers utilisant l'encodage UTF-8.
Heureusement, j'ai trouvé une switch dans la configuration qui permet de corriger le problème définitivement :
  • dans le répertoire d'installation, localisez le répertoire /etc/
  • à l'intérieur, ouvrez le fichier netbeans.conf
  • vous remarquerez une propriété nommée netbeans_default_options
  • ajoutez-y la chaîne de caractères suivante (à la fin, à l'intérieur des "") :

    netbeans_default_options="-J-client -J-Xverify:none -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=true -J-Dfile.encoding=UTF-8"

  • Redémarrez l'éditeur
À chaque lancement, il chargera ces options par défaut.


Tags: Coffre à outils

dimanche 21 juin 2009

Disque dur de 15 mega-octets de Radio Shack

Publié par Infinite Loop, à 12 h 57 0 commentaire

Voici une publicité classique qui circule sur le web. Ceux qui ont acheté ce type de disque dur à l'époque doivent regretter qu'un DVD vierge se détaille aujourd'hui à 0,30$ alors qu'on peut se procurer clé USB de 4 Giga-octets pour 10$.



En parcourant l'archive en ligne des catalogues Radio Shack (oui ça existe!), j'ai découvert à la page 177 de l'édition 1984 une version semblable d'un disque dur de 12 Mo à 2995$.

Ensuite, j'ai retroussé mes manches pour fouiller davantage et j'ai finalement trouvé la publicité originale dans le catalogue 1985!



Les catalogues Radio Shack, que de beaux souvenirs de mon enfance... Bon, ça et Distribution aux consommateurs...


Tags: Vieilles publicités

Filtres de fichiers pour FileZilla FTP

Publié par Infinite Loop, à 11 h 56 0 commentaire

En conclusion à l'article d'hier sur l'exclusion des fichiers de projets dans TortoiseSVN, je suggérais de configurer aussi le client FTP pour éviter que ces fichiers, ainsi que ceux reliés au contrôle de source (.svn), se retrouvent par erreur en ligne.

L'idée étant d'appliquer un filtre pour qu'au moment de transférer les fichiers, on ait pas à sélectionner à chaque fois ceux à exclure (imaginez pousser un projet complet et devoir dans chaque répertoire retirer le dossier .svn...). Autrement dit, ça peut ressembler à la fonction Cloaking Files de Dreamweaver.

Si vous utilisez le très populaire FileZilla (solution FTP gratuite) avec un projet versionné (CVS ou SVN) :

  • Allez au menu View
  • Choisissez Filename filters (raccourci CTRL+I)
  • Du côté de Local filters, cochez CVS and SVN directories
Créer un nouveau filtre :
  • Dans la même fenêtre, cliquez sur Edit filter rules
  • Cliquez New
  • Entrer le nom du filtre, par exemple "Netbeans Directory"
  • Ajouter une condition en cliquant sur Add more
  • Sélectionnez dans les listes déroulantes "Filename", "is equal to" et "nbproject"
  • Vous pouvez ajouter d'autres conditions si le filtre en nécessite davantage
  • Une fois terminé, vous serez de retour à la liste des filtres locaux
  • Cochez Netbeans Directory (ou le nom que vous avez entré)
  • Cliquez OK
Vous verrez dans la liste de gauche qui correspond aux fichiers locaux que le répertoire "nbproject" est exclus. Maintenant, vous n'avez plus aucune raison de vous faire taper sur les doigts parce que vous avez "encore" mis en ligne quelque chose qui n'aurait pas du l'être!


Tags: Programmation

Citation no. 35 sur l'histoire

Publié par Infinite Loop, à 11 h 05 0 commentaire

L’histoire est une suite de mensonges sur lesquels on est d’accord.

- Napoléon 1er


Tags: Citations

samedi 20 juin 2009

Exclure les fichiers de projets avec TortoiseSVN

Publié par Infinite Loop, à 15 h 48 0 commentaire

En programmation, plusieurs éditeurs comme Dreamweaver, Zend Studio, Eclipse et Netbeans créent des fichiers où sont stockés la configuration du projet. Le problème est qu'ils sont sauvegardés à même le répertoire des fichiers sources. Ce qui veut dire que si on ne fait rien, les fichiers seront commis au dépôt du contrôle de sources. Heureusement, si votre client pour Subversion est TortoiseSVN, on peut le configurer pour exclure automatiquement certains types de fichiers. Mieux, Tortoise conserve la configuration de façon globale, donc pour tous les projets!

Vous devrez procéder comme suit :

  • Cliquez sur le bouton droit de la souris dans l'explorateur de fichiers
  • Dans le menu contextuel, choisissez TortoiseSVN et l'option Settings
  • Dans le treeview, sélectionnez General
  • Dans l'encadré Subversion, vous trouverez une boîte de texte nommée Global ignore patterns
  • Saisissez les patterns que vous voulez ignorer :
    • Dreamweaver (Design Notes) : *\_notes
    • Zend Studio : .project .cache .settings
    • Eclipse : .project
    • Netbeans : *\nbproject
Ensuite, on peut faire la même chose avec notre client FTP pour éviter qu'ils se retrouvent en ligne par erreur.


Tags: Programmation

vendredi 19 juin 2009

Mario Lemieux, un fin connaisseur de l'informatique ?

Publié par Infinite Loop, à 17 h 46 0 commentaire

En lisant sur Cyberpresse l'article du party de la coupe Stanley chez Mario Lemieux *, j'ai regardé les photos et j'y ai noté ceci :

  • le domaine de Mario est somptueux
  • sa maison est gigantesque et de bon goût
  • la cave à vin comprend des centaines de bouteilles, dont du Châteauneuf-du-Pape
  • les gens se permettent une folie et profitent de la piscine en compagnie du prestigieux trophée (woohoo!)
  • et enfin, Mario le Magnifique possède un écran LCD de marque Dell dans son bureau.


Même si les travailleurs dans le domaine de l'informatique (et les amateurs) aiment rabaisser la marque, il semble que Mario ait opté pour elle dans ses critères d'excellence et de qualité. Non, pas Viewsonic, LG ou Samsung. Dell! Les sceptiques seront confondus ?

* À mes lecteurs français, Mario Lemieux est un québécois qui a été reconnu pour être un des meilleurs joueurs de hockey de tous les temps, multimillionaire, maintenant propriétaire des Penguins de Pittsburgh, l'équipe par excellence de la saison 2008-2009 dans la Ligue Nationale de Hockey.


Tags: Le coin du geek

jeudi 18 juin 2009

Commentaire sur la création de WSDL en PHP

Publié par Infinite Loop, à 22 h 04 6 commentaires

Aujourd'hui, j'ai reçu sur mon blogue un commentaire anonyme concernant l'article que j'ai écrit le 21 mai dernier intitulé "Créer un WSDL facilement avec Zend Framework". J'ai été un peu surpris par les propos de l'auteur, légèrement agressif, qui ne m'a laissé aucun moyen de le rejoindre directement (aucun nom ni courriel). Autrement, je l'aurais invité à m'envoyer son code et j'aurais été heureux de l'aider car l'exemple que j'avais publié provenait d'un cas réel que j'utilise dans un de mes projets.

Plutôt que d'approuver son commentaire, j'ai décidé de le publier ici et d'y consacrer ma chronique quotidienne. En guise d'introduction, voici le texte intégral:

dsl de te decevoir mais ton machin marche pas!!!!!
J'ai retourné le serveur dans tous les sens, rien à faire j'avais le message : "Couldn't load from...". C'est uniquement quand j'ai enlevé la condition 'if'-'else- que j'ai pu avoir le WSDL.
Quant au client il a l'air simple mais ne fonctionne pas non plus. désolé...

Le titre est attrayant les commentaires bien réalisés mais le résultat est insatisfaisant.

OK, c'est possible que j'aie fait une erreur, elle est humaine. J'ai peut-être mal expliqué un détail ? Ou fait une gaffe en recopiant le code ? Pourtant, je viens de le tester à nouveau et ça marche très bien. Et ça se peut que le programmeur en question ait fait un code 18. Tout porte à croire que c'est le cas.

La preuve est que j'ai su reproduire le bogue en moins d'une minute en introduisant volontairement une erreur d'implémentation. Le message obtenu se trouve dans le tag faultstring du XML et affiche quelque chose qui ressemble à ceci :

SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://localhost/WSDL/service.php?wsdl' : failed to load external entity "http://localhost/WSDL/service.php?wsdl"

Que nous dit cette notice ? Que le service web ne se charge pas correctement. Et si du côté serveur ça ne fonctionne pas, ce n'est pas surprenant que le client n'ait pas plus de succès. Il faut régler le problème à la source.

Une des causes possibles est que "localhost" n'ait pas été modifié pour rediriger vers son propre domaine. Il faut comprendre que mon code est sur mon propre serveur de développement hébergé sur ma machine (127.0.0.1), donc j'utilise localhost pour ma démo. Une autre possibilité est que son service web ne soit pas hébergé dans un répertoire du même nom que le mien ou que le fichier n'ait pas le bon nom.

Si on jete un oeil au code du fichier service.php, le IF/ELSE sert à deux choses. D'abord à générer la définition du WSDL en mode AutoDiscover (lorsqu'on lui passe en query string le paramètre "wsdl"), sinon à prendre en charge les demandes des clients. Donc le même fichier est réutilisé pour deux comportements différents au lieu de séparer le code en deux fichiers PHP sur le disque.

C'est important aussi de remarquer que dans le ELSE, l'objet Zend_Soap_Server prend en paramètre l'URL de la définition du service web, donc le fichier service.php AVEC le paramètre "wsdl". Si on ne fournit pas l'URL correctement ou si on omet de mettre le paramètre wsdl (celui détecté par le $_GET['wsdl'], le message "Couldn't load from 'url'" apparaît. Au moment de prendre en charge la requête du client, le fichier s'appelle lui-même en réclamant la définition pour instancier Zend_Soap_Server.

En résumé :

  • L'accès à la page service.php?wsdl affichera le XML de la définition du service
  • L'accès direct à la page service.php (sans ?wsdl) devrait faire afficher un faultstring Invalid XML car aucune requête à une fonction n'est faite
  • Le client doit appeler le WSDL en utilisant l'URL complet "http://votre-serveur/service.php?wsdl". Ceci a pour effet d'interroger le service pour savoir quelles fonctions il peut appeler.
Ici, je me permets une réflexion. Parfois, je me demande si la nouvelle génération de programmeurs tente vraiment de comprendre ce qu'ils font ou s'ils ne sont pas plutôt à la recherche de code et de solutions toutes prêtes à être copiées/collées à leurs projets. Ai-je besoin de rappeler que "Copier/Coller" ne fait PAS parti de la liste des "Design Pattern" ?

Même en présentant un code fonctionnel dans sa plus simple expression, son exécution a affiché une erreur explicite et le programmeur n'a pas su chercher la solution au bon endroit. Pourtant, ce n'est que quelques lignes de code, alors nul besoin de retourner le serveur dans tous les sens ;-)


Tags: PHP, Programmation, Zend Framework

mercredi 17 juin 2009

Queue de fonctions en JavaScript

Publié par Infinite Loop, à 21 h 11 0 commentaire

Ces dernières années, on a souvent mis l'accent sur l'écriture de code JavaScript à l'aide de librairies qui nous facilitent la vie (jQuery, Prototype, Mootools). Or, sans dénigrer les bénéfices qu'apportent ces frameworks, ça peut être un avantage de connaître aussi certains des mécanismes internes du langage JavaScript pur.

Voici une de ces particularités que vous ne soupçonniez peut-être pas. En général, vous savez que lorsque vous faites appel à une fonction, on écrit quelque chose de semblable à ceci :

function my_function() {
return 1;
}

alert( my_function() );
De façon moins évidente, vous pouvez aussi assigner le call d'une fonction à une variable et exécuter le code avec eval().
var my_fct = 'my_function()';
alert( eval(my_fct) );
Ou encore par une syntaxe alternative, où "this" fait référence à un élément reconnu à l'intérieur de sa portée (sinon il faut utiliser un closure) :
this['my_function']();
Ce qui nous permet d'être créatif et d'implémenter une queue d'exécution. Les noms des fonctions indiquées dans l'array seront exécutées successivement au moment de l'itération.
// déclaration de fonctions
function fct1(){ console.log('Fonction 1'); }
function fct2(){ console.log('Fonction 2'); }
function fct3(){ console.log('Fonction 3'); }
function fct4(){ console.log('Fonction 4'); }
function fct5(){ console.log('Fonction 5'); }

// FIFO / FCFS
var queue = new Array('fct1', 'fct2', 'fct3', 'fct4', 'fct5');

for(var i=0 ; i < queue.length ; i++){
this[queue[i]]();
}
Voilà, sans même le savoir, vous venez de comprendre une partie des secrets qui font la force des frameworks JavaScript!


Tags: JavaScript

mardi 16 juin 2009

Équivalences Ajax avec jQuery et Prototype

Publié par Infinite Loop, à 20 h 54 2 commentaires

Pour avoir utilisé les deux types d'appels Ajax (asynchronous JavaScript and XML) avec les librairies Prototype et jQuery, je dois dire que chacun possède ses avantages et que somme toute, la syntaxe revient pratiquement au même. Je vous décris ici les équivalences présentées pas à pas.

L'appel
À la base, Prototype utilise une fonction de objet Ajax qu'on doit instancier. De son côté, l'appel Ajax de jQuery est simplement une fonction de l'objet principal. Dans les deux cas, on doit passer un array de paramètres qu'on peut définir avant ou à l'intérieur de l'appel.

// prototype
new Ajax.Request('url', options);

// jQuery
$.ajax(options);
Les paramètres
Pour créer une requête Ajax de base, nous avons besoin de différents paramètres :
  • l'URL où doit pointer la requête (toujours sur une page du même domaine)
  • le type de requête (GET / POST)
  • les données
  • les fonctions de succès et d'erreur
On définira les arrays d'options en suivant la syntaxe JSON, où la valeur peut être scalaire, un autre objet JSON imbriqué ou une fonction:
{
propriété: valeur,
propriété: valeur,
propriété: valeur,
propriété: fonction(){}
}
URL
  • En Prototype, l'URL a déjà été spécifié au moment de l'appel.
  • Avec jQuery, c'est un paramètre nommé "url" :
    { url: 'page.php' }
Requête asynchrone
Par défaut, les deux librairies initialisent les requêtes de façon asynchrone (c'est le but de la méthode Ajax).
  • Prototype utilise { asynchronous: true }
  • jQuery préfère l'abrégé { async: true }
Type
Il faut spécifier si on enverra les données en tant que GET ou POST.
  • Prototype s'est inspiré d'un formulaire web en utilisant la propriété "method" : { method: 'POST' }
  • celle de jQuery s'appelle "type" : { type: 'POST' }
Données
Si on veut passer des paramètres au moment de faire la requête Ajax, on doit les inclure à l'intérieur de l'array d'options. Les paramètres eux-mêmes doivent être aussi définis comme un objet JSON, avec la syntaxe entre accolades.
  • Prototype le nomme simplement "parameters" :
    { parameters: { cle: valeur, cle: valeur } }
  • Même chose pour jQuery, sauf que la propriété se nomme "data" : { data: { cle: valeur, cle: valeur } }
Fonctions callback pour succès et erreur
Qu'arrive-t-il lorsque l'appel Ajax réussit ou échoue ? Il faut définir les fonctions callback pour prendre en charge le résultat selon le cas.
  • Avec Prototype, il faut associer une fonction (anonyme ou non) aux propriétés "onSuccess" et "onFailure" (voir exemple complet plus bas)
  • Avec jQuery, c'est encore une fois le même procédé, sauf que les propriétés se nomment simplement "success" et "error"
Valeur de retour
Selon ce que l'URL appellé retournera, on pourra manipuler les données différemment. Dans les deux cas, la fonction de succès recevra automatiquement comme argument l'output généré par la page appelée.
  • Avec Prototype, la documentation suggère de nommer cette variable transport ou "t" et elle contient la propriété responseText, responseXML et responseJSON (exemple: t.responseText)
  • Sous jQuery, on peut spécifier lors de l'appel une propriété qui indiquera comment traiter la réponse. Les choix possibles sont : xml, html, script, json, jsonp et text. Ensuite, on pourra utiliser l'objet directement.
Les modèles de code en exemple
En conclusion, les deux squelettes suivants sont équivalents. Notez aussi comment on peut, dans les deux cas, définir les options dans un objet à part.
// prototype
var options = {
asynchronous: true,
method: 'POST',
parameters: { id: 10, language: 'fr' },
onSuccess: function(transport) {
console.log('Succès');
},
onFailure: function(transport){
console.log('Erreur');
}
}

new Ajax.Request('/dossier/page.php', options);

// jQuery
$.ajax({
url: '/dossier/page.php',
async: true,
type: 'POST',
data: { id: 10, language: 'fr' },
dataType: 'json',
success: function(data){
console.log('Succès');
},
error: function(){
console.log('Erreur');
}
});


Tags: JavaScript

lundi 15 juin 2009

Magazine Maximum PC en PDF

Publié par Infinite Loop, à 20 h 33 0 commentaire

Je viens de découvrir quelque chose de vraiment bien. La revue Maximum PC offre en téléchargement gratuit les archives de ses revues en format PDF, de décembre 2003 à aujourd'hui. Naturellement, la publication la plus récente est offerte un mois après sa sortie, mais bon, qui s'en plaindra ?

Avantages :

  • accès facile à de l'information pertinente
  • 10,99$ de plus dans vos poches pour chaque numéro
  • écologique, aucun papier n'est gaspillé
Un seul inconvénient :
  • difficile à trainer avec soi jusqu'au petit coin (à supposer que c'est un pré-requis pour vous...)
Voyez l'archive PDF de Maximum PC ici.


Tags: Saviez-vous que

dimanche 14 juin 2009

Film Home de Yann Arthus-Bertrand

Publié par Infinite Loop, à 10 h 18 0 commentaire

Aujourd'hui est la dernière journée pour visionner gratuitement sur YouTube le film Home de Yann Arthus-Bertrand. Comme je ne sais pas trop ce qui va arriver passé cette date et que je ne l'avais pas encore regardé au complet (durée 1h30), j'ai pris la décision de le télécharger pour pouvoir le terminer sans me presser.

Téléchargement
Pour télécharger le clip vidéo en Flash, c'est n'est pas aussi évident que de faire "enregistrer sous" pour un fichier normal (à moins d'aller fouiller dans le code source). J'ai donc installé Video DownloadHelper, une petite extension pour Firefox qui extrait le fichier FLV de la page où vous vous trouvez (de nombreuses autres applications de toutes sortes sont disponibles).

Visionnement
Une fois en possession du fichier home.flv (qui pèse 790 Mo), on doit pouvoir lire le fichier pour le zieuter sur son ordinateur. Si vous êtes sur Windows, le Media Player n'est pas adapté pour lire ce format de fichier. C'est pourquoi il est préférable de se tourner vers le très compatible et flexible VLC Media player du projet VideoLan (gratuit et open source comme toujours).

Conversion
Je n'ai pas encore fait mon choix à savoir si j'allais prendre le temps de le regarder sur PC, iPod Touch ou sur DVD. À supposer que je veuille le regarder sur un autre support, je vais devoir le convertir au préalable. Un outil gratuit pour travailler la vidéo s'appelle SUPER. Téléchargez-le ici (recherchez le lien "Download SUPER setup file" ou encore le lien direct. Attention, sur la page, il y a des grandes publicités pour AVS Video Converter alors que le lien pour SUPER est plutôt discret).

Pour le iPod Touch / iPhone, choisissez le format Output "Apple - iPod / iPhone (MP4)" et laissez les autres configurations par défaut. Cliquez Encode (Active Files). Le nouveau fichier (mp4) sera enregistré dans le même répertoire que le fichier source (flv).

On peut aussi convertir au format natif standard DVD (VOB), de même que des dizaines d'autres formats (Zune, PSP, PS3, AVI, MPG, VCD, WMV, etc.).

Enregistrement
Enfin, si on souhaite le conserver sur DVD standard, on peut utiliser Nero Vision Express pour convertir le travail final et le graver sur DVD.

Pour plus de détails sur le travail du photographe Yann Arthus-Bertrand :

  • son site personnel
  • le site officiel du film Home
  • 2000 fonds d'écran à télécharger gratuitement
  • Good Planet, la fondation dont il est le président
  • n'hésitez pas à acheter un de ses livres, ça en vaut le prix (exemple : 365 jours pour réfléchir à notre Terre)


Tags: Club Vidéo, Extensions Firefox

Citation no. 34 sur la responsabilité

Publié par Infinite Loop, à 09 h 19 0 commentaire

Le chef est celui qui prend tout en charge. Il dit : "J'ai été battu".
Il ne dit pas : "Mes soldats ont été battus".

- Antoine de Saint-Exupéry


Tags: Citations

samedi 13 juin 2009

6 destinations vacances aux noms insolites

Publié par Infinite Loop, à 16 h 26 0 commentaire

Cet article n'a rien de techno, si ce n'est que j'ai découvert grâce à Google Maps des destinations vacances surprenantes aux noms loufoques. En planifiant soigneusement votre prochain itinéraire, vous pourrez inmanquablement prévoir un petit détour pour vous faire photographier devant l'écriteau de bienvenue de chaque lieu. Que de souvenirs à raconter!

1. Condom, Midi-Pyrénées, France

Un peu gênant.

Population: 7500 personnes (taux de natalité faible vu la contraception ?)
Attrait touristique : Festival de Bandas et la rivière Baïse (oui oui!)

2. Montcuq, Midi-Pyrénées, France

La ville dont tous se permettent un jeu de mots douteux.

Population: 3600 Montcuquois et Montcuquoises
Attrait touristique : inexistant, mais seulement à seulement 2 heures de route de Condom!

3. Poil, Bourgogne, France

Qu'est-ce qu'il fait bon de vivre à Poil!
Décidément, ils ont de la suite dans les idées ces français...

Population: le village compte moins de 200 Pictiens.

4. Dildo, Terre-Neuve, Canada

OK, on se paye un peu la gueule de nos cousins mais au fond, on les aime bien. À leur tour, s'ils planifient une visite au Canada, ils seront bien reçus lorsqu'ils seront de passage à Dildo, qui compte une industrie touristique grandissante. Allez savoir pourquoi.

5. Perdue, Saskatchewan, Canada

Toujours dans mon beau pays du sirop d'érable, cette fois-ci vers l'ouest, on se dirigera vers le village de Perdue qui compte 364 âmes errantes. Selon les statistiques de Wikipedia, la population est en baisse de 2,2% depuis 2001. C'est donc dire que plusieurs ont su retrouver leur chemin... ou quelque chose comme ça.

6. Vulcan, Alberta, Canada

Je lève mon chapeau pour l'originalité car ceux-ci se sont surpassés pour créer une activité touristique prospère sur la thématique de Star Trek. Ne manquez pas d'aller voir la réplique de l'Enterprise!

Vous avez d'autres lieux amusants à partager, n'hésitez pas à me les soumettre. Sur ce, bonnes vacances!


Tags: Curiosités

vendredi 12 juin 2009

À propos des chargés de projets

Publié par Infinite Loop, à 18 h 30 0 commentaire

Dans ma bibliothèque, j'avais la deuxième édition du livre Peopleware, Productive Projects and Teams que je me promettais de lire depuis longtemps et je l'ai entamé la semaine dernière. Plus j'avance dans la lecture, plus je sens que ma perception de mon travail change et que je suis loin de vivre une situation comme celle décrite ci-dessous (comme beaucoup d'autres programmeurs ou travailleurs de cubicules). Je recopie ici la fin de la page 34 du chapitre 6 et sa conclusion.

This Is Management
In my early years as a developer, I was privileged to work on a project managed by Sharon Weinberg, now president of the Codd and Date Consulting Group. She was a walking example of much of what I now think of as enlightened management. One snowy day, I dragged myself out of a sickbed to pull together our shaky system for a user demo. Sharon came in and found me propped up at the console. She disappeared and came back a few minutes later with a container of soup. After she'd poured it into me and buoyed up my spirits, I asked her how she found time for such things with all the management work she had to do. She gave me her patented grin and said, Tom, this is management."

- Tom DeMarco

Sharon knew what all good instinctive managers know: The manager's function is not to make people work, but to make it possible for people to work.

Bien dit non ? Il me semble que ça serait tellement le monde idéal et pourtant, j'ai souvent des doutes que ça existe. Pourquoi est-ce que les chargés de projets avec lesquels je travaille ne font qu'essayer de mettre de la pression supplémentaire et épier nos moindres gestes, tout cela dans le but que nous soyons plus "productifs" ? Ça ne fonctionne juste pas et c'est tellement démotivant de ne pas se sentir appuyé! La réalité est qu'on rencontre constamment des bogues à régler, qu'on doit répondre à des attentes élevées des patrons et de nos clients et que nous effectuons un travail créatif, donc susceptible à une panne d'inspiration. Un chargé de projet devrait être un complément à l'équipe, un catalyseur qui permet à tous de pousser dans la même direction.

C'est vrai que dans certains cas, c'est à leur avantage de devancer les échéanciers, d'appliquer des contraintes et de nous lancer des défis pour qu'on se surpasse. D'ailleurs, s'ils réussissent, ils auront leur part du gâteau... avant nous. Mais est-ce que ça ne mène pas directement à l'épuisement professionnel ? Où est la relation gagnant-gagnant dans tout ça ? Si vous êtes chef d'équipe, réfléchissez bien à ceci et je vous invite à revoir vos tactiques de gestion. Ce n'est pas une question de hiérarchie ou d'autorité, c'est bel et bien une question d'esprit d'équipe, parce que VOUS en faites partie !


Tags: Lois et principes

jeudi 11 juin 2009

Astuce SQL pour remplacer les sous-requêtes

Publié par Infinite Loop, à 19 h 02 0 commentaire

Ceci intéressera ceux qui travaillent avec les bases de données. Voici une petite astuce pour créer une requête SQL qui permet de compiler des statistiques avec des fonctions d'agrégations (COUNT, SUM, AVG, etc), sans utiliser de sous-requêtes.

Si on imagine la requête SQL suivante qui comptabilise le nombre d'entreprises par province dont la première lettre est A, B ou C, on pourrait écrire l'énoncé SQL suivant :

-- Syntaxe PostgreSQL
SELECT province, COUNT(*) as total,
(
SELECT COUNT(*)
FROM companies as c2
WHERE substr(company_name, 1, 1) = 'A'
AND c1.province = c2.province
) as total_starting_with_a,
(
SELECT COUNT(*)
FROM companies as c2
WHERE substr(company_name, 1, 1) = 'B'
AND c1.province = c2.province
) as total_starting_with_b,
(
SELECT COUNT(*)
FROM companies as c2
WHERE substr(company_name, 1, 1) = 'C'
AND c1.province = c2.province
) as total_starting_with_c
FROM companies as c1
GROUP BY province
ORDER BY province

-- Syntaxe SQL Server
SELECT province, COUNT(*) as total,
(
SELECT COUNT(*)
FROM companies as c2
WHERE left(company_name, 1) = 'A'
AND c1.province = c2.province
) as total_starting_with_a,
(
SELECT COUNT(*)
FROM companies as c2
WHERE left(company_name, 1) = 'B'
AND c1.province = c2.province
) as total_starting_with_b,
(
SELECT COUNT(*)
FROM companies as c2
WHERE left(company_name, 1) = 'C'
AND c1.province = c2.province
) as total_starting_with_c
FROM companies as c1
GROUP BY province
ORDER BY province
Cependant, on pourrait aussi bien l'écrire en éliminant les sous-requêtes, en utilisant simplement une somme selon une condition spécifiée à l'intérieur par un CASE WHEN. Si la condition est respectée, on additionne 1, sinon 0, ce qui revient à l'équivalent d'un COUNT.
-- Syntaxe PostgreSQL
SELECT province, COUNT(*) as total,
SUM(CASE WHEN substr(company_name, 1, 1) = 'A' THEN 1 ELSE 0 END) as starting_with_a,
SUM(CASE WHEN substr(company_name, 1, 1) = 'B' THEN 1 ELSE 0 END) as starting_with_b,
SUM(CASE WHEN substr(company_name, 1, 1) = 'C' THEN 1 ELSE 0 END) as starting_with_c
FROM companies as c1
GROUP BY province
ORDER BY province

-- Syntaxe SQL Server
SELECT province, COUNT(*) as total,
SUM(CASE WHEN left(company_name, 1) = 'A' THEN 1 ELSE 0 END) as starting_with_a,
SUM(CASE WHEN left(company_name, 1) = 'B' THEN 1 ELSE 0 END) as starting_with_b,
SUM(CASE WHEN left(company_name, 1) = 'C' THEN 1 ELSE 0 END) as starting_with_c
FROM companies as c1
GROUP BY province
ORDER BY province
Question performance, j'ai noté que sur 2 millions d'enregistrements, le modèle à sous-requête prenait environ 13 secondes à s'exécuter tandis que celui qui n'en utilisait pas nécessitait un peu moins de 4 secondes.


Tags: PostgreSQL, SQL Server

mercredi 10 juin 2009

Message créatif et original de CD Baby

Publié par Infinite Loop, à 18 h 10 0 commentaire

Faites l'expérience d'achetez un CD sur le site CD Baby et voyez comme leur message de remerciement envoyé suite à l'envoi du colis est créatif et original!

Lorsque j'ai vu la mention sur Digg cette semaine, je me suis rappelé que c'était sur ce site que j'avais déjà commandé le CD du curieux flûtiste à beatbox Greg Pattillo après avoir visionné ce vidéo sur YouTube (excellent soit dit en passant).

Groupe : Project
Album : Winter in June
Achetez en ligne sur CD Baby

En fouillant dans mon web mail, j'ai retrouvé la trace du fameux message (datant de février 2008). Avez-vous déjà reçu un courriel de confirmation aussi drôle suite à un achat ?


Thanks for your order with CD Baby!

Your CD has been gently taken from our CD Baby shelves with sterilized contamination-free gloves and placed onto a satin pillow.

A team of 50 employees inspected your CD and polished it to make sure it was in the best possible condition before mailing.

Our packing specialist from Japan lit a candle and a hush fell over the crowd as he put your CD into the finest gold-lined box that money can buy.

We all had a wonderful celebration afterwards and the whole party marched down the street to the post office where the entire town of Portland waved "Bon Voyage!" to your package, on its way to you, in our private CD Baby jet on this day, Saturday, February 9th.

I hope you had a wonderful time shopping at CD Baby. We sure did. Your picture is on our wall as "Customer of the Year." We're all exhausted but can't wait for you to come back to CDBABY.COM!!

Thank you, thank you, thank you!

Sigh...

--
Derek Sivers, president, CD Baby
the little store with the best new independent music


Tags: Musique

mardi 9 juin 2009

Composant HTML Purifier

Publié par Infinite Loop, à 21 h 43 0 commentaire

En lisant récemment un tutoriel sur les applications web MVC, j'ai découvert le composant HTML Purifier. Il s'agit d'un filtre HTML open source qu'on peut utiliser dans nos applications, qui permet de contrer les faiblesses de la fonction PHP strip_tags() en proposant un filtre avancé hautement configurable. Si vous avez un site web qui autorise les visiteurs à entrer du contenu à l'aide d'un textarea, d'un RTE, ou sur un forum, il est extrêmement recommandé d'utiliser un filtre de ce type.

En comparaison avec HTML Tidy qui accepte n'importe quel markup HTML valide, incluant les balises SCRIPT, HTML Purifier peut non seulement épurer le code et le rendre conforme aux standards, mais aussi retirer tout code malicieux de cross-site scripting (XSS).

Voici un exemple fonctionnel de configuration minimale. Les éléments sont regroupés en différents ensembles : Core, CSS, HTML, AutoFormat, Output, Cache, etc. Voyez la liste complète des propriétés configurables pour HTML Purifier.

require_once('htmlpurifier-3.3.0/library/HTMLPurifier.auto.php');

// 1. définir la configuration
$config = HTMLPurifier_Config::createDefault();

// choisir l'encodage de la page : UTF-8, ISO-8859-1
$config->set('Core', 'Encoding', 'UTF-8');

$config->set('HTML', 'Doctype', 'XHTML 1.0 Strict');
$config->set('HTML', 'TidyLevel', 'heavy');

// les balises autorisées
$config->set('HTML', 'Allowed', 'a[href],strong,i,b,em,p,br');

// ou encore celles interdites
$config->set('HTML', 'ForbiddenElements', 'iframe');

// 2. utilisation
$html = 'html à nettoyer ici';

$purifier = new HTMLPurifier($config);

$clean_html = $purifier->purify($html);

echo $clean_html;
Quelques notes importantes
  • Le DocType sera utilisé pour générer du HTML valide correspondant. Par exemple, <br> sera traduit par <br /> en XHTML Strict
  • En initialisant TidyLevel à la valeur "heavy", le filtre transformera tous les éléments et attributs dépréciés à des normes conformes équivalentes.
  • Dans votre configuration, si magic_quotes est à ON, il y aura des problèmes avec l'interprétation des guillemets simples et doubles dans les attributs HTML (exemple: a href="http://www.ebay.ca/"). Il faudra donc le désactiver temporairement, seulement si vous autorisez l'entrée de balises avec des attributs.
  • À la ligne des balises autorisées, j'ai inscrit a[href]. Certaines personnes se demandent comment autoriser aussi l'attribut target, par exemple target="_blank". Comme j'ai initialisé l'outil au DocType XHTML 1.0 Strict, il n'est pas autorisé. Par contre, on pourra le spécifier en modifiant la configuration pour la suivante :

    $config->set('Attr', 'AllowedFrameTargets', array('_blank') );

    $config->set('HTML', 'Doctype', 'XHTML 1.0 Transitional');

  • Il est conseillé de mettre à jour le composant régulièrement pour bénéficier des derniers ajouts en matière de sécurité


Tags: PHP

lundi 8 juin 2009

Facebook mal programmé ?

Publié par Infinite Loop, à 20 h 01 0 commentaire

Je n'ai pas l'intention de partir de débat à savoir si Facebook est bien programmé ou non mais j'aimerais surtout attirer votre attention sur quelque chose qui m'est sauté aux yeux aujourd'hui. Très souvent, les intégrateurs utilisent des outils pour valider la syntaxe des documents HTML, par exemple l'extension pour Firefox Html Validator (que j'utilise parfois, sans trop de rigueur), Tidy ou le W3C Validator Markup Service.

En visitant (pour une rare fois) mon compte Facebook, j'ai été étonné de voir ceci :


À peine 6084 erreurs de HTML dans la même page (selon le SGML parser). Si les sites de Google et Microsoft s'en permettent quelque unes, là c'était la première fois que j'en voyais autant! Par contre, en basculant en mode Tidy, il en relève nettement moins. Voyez ci-dessous un extrait de la liste des fautes notées (cliquez sur l'image pour l'agrandir) :



Finalement, j'ai soumis le code de Facebook (la page d'accueil suite à la connexion) en analyse au W3C et voici le bilan :



Le document en HTML strict ne compte pas moins de 11754 erreurs et 1256 warnings. Est-ce qu'on peut se permettre d'appeler ça un léger manque de rigueur ?

Tant qu'à parler de Facebook, connaissez-vous Orkut, le réseau social de Google ? Je viens à l'instant d'ouvrir un compte, juste pour le fun car je ne crois pas vraiment l'utiliser. À mes yeux, le buzz est en train de s'estomper...


Tags: Extensions Firefox, Intégration

dimanche 7 juin 2009

Enregistrer des disques vinyls sur son ordinateur

Publié par Infinite Loop, à 10 h 14 5 commentaires

Depuis un bout de temps, mon père avait exprimé le souhait de pouvoir transférer une sélection de sa collection de disques vinyls (33 et 45 tours) vers un format digital comme le mp3, principalement pour pouvoir créer des compilations et conserver une copie des disques plus rares qu'il possède. Avec des certificats cadeaux reçus récemment, il avait songé à se procurer une table-tournante USB du type "tout inclus" (table, graveur, connecteurs, logiciel) pour effectuer le travail mais je l'ai dissuadé sachant que :

  • le prix de ce type d'appareil varie entre 125 et 250$
  • il possède déjà un ordinateur avec un graveur
  • il est propriétaire de 3 tables tournantes de bonne qualité avec des aiguilles neuves
  • il y a plusieurs logiciels gratuits qui permettent l'enregistrement sonore
En vérité, tout ce qu'il avait réellement besoin était le nécessaire pour que les deux appareils puissent communiquer ensemble. J'ai fait quelques recherches puis je suis allé chez Addison-Electronique, un fournisseur de pièces reconnu à Montréal, pour acheter 3 composants à prix ridicule :
  • Un pré-amplificateur audio (le modèle disponible était 19,99$)
  • Un câble RCA triple (mâle à mâle), même si j'ai juste besoin de l'audio (1,99$)
  • Fiche stéréo 3.5mm mâle à double RCA femelle pour le connecter dans le "line in" de la carte de son (1,59$)
Ensuite, j'ai téléchargé un logiciel d'enregistrement et d'édition gratuit : Audacity (sur Sourceforge).

Une fois arrivé chez mes parents, le tout était fonctionnel en quelques minutes seulement :
  1. Branchez les câbles audio RCA rouge et blanc de la table tournante dans le "IN" du pré-ampli (dans les bonnes couleurs si vous voulez conserver le son gauche / droit)
  2. À partir du "OUT" du pré-ampli, raccordez les câbles RCA jusqu'à la fiche 3.5mm (mini jack)
  3. Connectez le mini-jack dans le "line-in" de la carte de son. Derrière la tour, il y a normalement 3 entrées de couleur : rose, vert et bleu. Utilisez le bleu.
  4. Installer le logiciel Audacity, sans oublier le plugin LAME mp3 encoder (page de téléchargement)
  5. Configurez le poste de travail pour que la panneau Volume Control de Windows utilise le Line In dans les propriétés d'enregistrement. Sélectionnez-le et ajustez le volume désiré. Pour ma part, j'ai aussi fait en sorte de lire à partir du line in pour que le son du vinyl sorte des haut-parleurs pour nous aider à savoir à quel moment commencer à enregistrer.
  6. Dans la barre d'outil d'Audacity, il y a une liste déroulante qui indique la source d'enregistrement. Assurez-vous que Line In est sélectionné
  7. Faites un premier test en appuyant sur record pendant que le disque joue
  8. Une fois le son de la pièce musicale capturé, enregistrez-le en format numérique : Fichier / Exporter comme Mp3.
  9. L'application est remplie d'options avancées et d'effets sonores. De quoi explorer et s'amuser pendant des heures.
Avec le matériel qu'on a installé (pour moins de 25$), l'avantage est qu'il pourra aussi capturer le son de vieilles cassettes ou d'autres sources audio, en autant qu'il possède un adaptateur RCA du bon type à brancher dans le pré-amplificateur.


Tags: Musique

Citation no. 33 sur les risques du travail

Publié par Infinite Loop, à 09 h 04 0 commentaire

Travailler dur n'a jamais tué personne, mais pourquoi prendre le risque ?

- Edgar Bergen


Tags: Citations

samedi 6 juin 2009

Full Text Search PostgreSQL

Publié par Infinite Loop, à 09 h 06 0 commentaire

Voici le problème : dans une base de données PostgreSQL, j'ai importé dans une table au-delà de deux millions d'enregistrements qui correspondent à de l'information sur des entreprises. Si je fais une recherche uniquement sur cette table, sans jointure, avec la clause LIKE, la performance est plutôt rapide mais ce ne sont pas tous les noms qui sont trouvés car la comparaison de texte est sensible à la casse.

-- 1016 ms (~ 1 seconde d'exécution)
SELECT *
FROM companies
WHERE company_name LIKE '%steel%';
En utilisant à la place ILIKE, je réussis à en extraire davantage car le I dans ILIKE indique de procéder à la comparaison "Case Insensitive". Cependant, c'est au détriement de la performance:
-- 4781 ms (près de 5 secondes)
SELECT *
FROM companies
WHERE company_name ILIKE '%steel%';
Si je crée un index sur le champ de la table, ça risque d'aller plus vite ? Eh bien non, la même requête prend à peu près le même temps (même légèrement supérieur), en plus d'alourdir la taille de la base de données.
CREATE UNIQUE INDEX name_idx ON companies(company_name);
Supprimons cet index, et remplaçons-le par le Full Text Search (FTS). D'abord, j'ajoute une nouvelle colonne à ma table. À l'avenir, c'est sur celle-ci que je ferai la comparaison texte.
ALTER TABLE companies ADD COLUMN search_idx_company_name tsvector;
J'initialise le nouveau champ à partir de mes données (sur 2 millions d'enregistrements, j'ai patienté environ 2 minutes). Au besoin, vous pouvez spécifier un dictionnaire ("english", "french", etc.) dans to_tsvector(). Pour ma solution, je ne l'indique pas.
UPDATE companies
SET search_idx_company_name = to_tsvector(coalesce(company_name,''));
Pour maintenir l'intégrité des données entre la donnée réelle (champ "company_name") et le champ qui sera indexé (champ vecteur "search_idx_company_name"), il sera nécessaire de placer un trigger qui mettra à jour les données lorsque nécessaire.

Avant même de créer l'index, je vais évaluer la performance en lançant une requête FTS. Pour cela, j'utiliserai l'opérateur @@ et je traduirai le mot clé de recherche avec la fonction to_tsquery().
-- ouch, 17 secondes!
SELECT *
FROM companies
WHERE search_idx_company_name @@ to_tsquery('steel');
Ajoutons l'index (attendre un peu plus de 2 minutes) :
CREATE INDEX textsearch_idx ON companies
USING gin(search_idx_company_name);
Lançons la même requête à nouveau : les résultats sont instantanés (156 millisecondes)! Par contre, il faut noter que le full text search retourne moins de résultats que le ILIKE car il n'effectue pas la comparaison de texte de la même façon. À vrai dire, il se fie sur la similarité des mots plutôt que sur l'exactitude du terme, et tout cela est flexible et configurable (dictionnaire, synonymes, thesaurus, etc). À utiliser dans les cas où la vitesse est prioritaire à la justesse des données.


Tags: PostgreSQL

vendredi 5 juin 2009

Lois du travail de Dilbert

Publié par Infinite Loop, à 17 h 24 1 commentaire

Connaissez-vous les lois du travail de Dilbert ?
Les voici, avec les traductions originales en italique :

  1. Si vous n'arrivez pas à terminer votre travail les 24 premières heures, travaillez la nuit. If you can't get your work done in the first 24 hours, work nights.
  2. Une tape dans le dos n'est jamais qu'a quelques centimètres d'un coup de pied au cul. A pat on the back is only a few centimeters off a kick in the butt.
  3. Ne soyez pas irremplaçable... Si on ne peut pas vous remplacer, vous n'aurez jamais de promotion. Don't be irreplaceable. If you can't be replaced, you can't be promoted.
  4. Peu importe ce que vous ayez réellement fait, seuls importent ce que vous dites avoir fait et ce que vous allez faire. It doesn't matter what you do; it only matters what you say you've done and what you're going to do.
  5. Après chaque augmentation de salaire, vous vous retrouverez avec moins d'argent en fin de mois que vous n'en aviez auparavant. After any salary raise, you will have less money at the end of the month than you did before.
  6. Si vous avez décidé de ne pas vous faire chier, on vous emmerdera. The more crap you put up with, the more crap you are going to get.
  7. Vous pouvez vous balader n'importe où et avoir l'air sérieux si vous trimbalez un porte-documents. You can go anywhere you want if you look serious and carry a clipboard.
  8. Mangez un crapaud vivant le matin au réveil et rien de pire ne pourra vous arriver le reste de la journée. Eat one live toad the first thing in the morning and nothing worse will happen to you the rest of the day.
  9. Quand les patrons parlent d'augmenter la productivité, ils ne parlent jamais pour eux-mêmes. When the bosses talk about improving productivity, they are never talking about themselves.
  10. Si vous ne parvenez pas à faire une chose du premier coup, essayez encore. Puis laissez tomber. ça ne sert à rien de se pourrir la vie avec ça. If at first you don't succeed, try again. Then quit. No use being a fool about it.
  11. Il y aura toujours une boite de bière vide qui roulera sur le plancher de votre bagnole lorsque votre patron vous demandera de le raccompagner chez lui. There will always be beer cans rolling on the floor of your car when the boss asks for a ride home from the office.
  12. Tout peut être classé sous l'appellation "divers". Everything can be filed under "miscellaneous."
  13. Ne retardez jamais la fin d'une réunion ou le début d'une réception. Never delay the ending of a meeting or the beginning of a dinner hour.
  14. L'erreur est humaine, le pardon ne figure pas dans notre règlement. To err is human; to forgive is not our policy.
  15. Tout le monde peut faire une quantité de travail phénoménale, du moment que ce n'est pas le travail qui lui incombait. Anyone can do any amount of work provided it isn't the work he/she is supposed to be doing.
  16. Un courrier important ne comportant aucune erreur, en développera spontanément et de façon proportionnelle au nombre de personnes qui en prendront connaissance. Important letters that contain no errors will develop errors in the mail.
  17. Si vous êtes bon, on vous donnera tout le travail. Si vous êtes très bon, vous le ferez faire par quelqu'un d'autre. If you are good, you will be assigned all the work. If you are really good, you will get out of it.
  18. Vous êtes toujours en train de faire quelque chose sans rapport avec le travail au moment où votre patron passe derrière vous. You are always doing something marginal when the boss drops by your desk.
  19. Les gens qui vont assister aux conférences sont ceux qui justement ne devraient pas y aller. People who go to conferences are the ones who shouldn't.
  20. Si il n'y avait pas de dernière minute, rien de valable ne pourrait être fait. If it wasn't for the last minute, nothing would get done.
  21. Au travail, l'autorité d'une personne est inversement proportionnelle au nombre de stylos qu'elle porte sur elle. At work, the authority of a person is inversely proportional to the number of pens that person is carrying.
  22. Quand vous n'avez rien à faire, marchez vite et prenez l'air soucieux. When you don't know what to do, walk fast and look worried.
  23. Suivre le règlement n'a jamais permis de faire le travail. Following the rules will not get the job done.
  24. Mais vouloir que le travail soit fait n'est pas une excuse pour ne pas suivre le règlement. Getting the job done is no excuse for not following the rules.
  25. Si vous êtes confrontés à un problème très difficile, vous pouvez le résoudre très facilement en vous posant la question: "Comment Lone Ranger ferait à ma place. When confronted by a difficult problem, you can solve it more easily by reducing it to the question, "How would the Lone Ranger handle this".
  26. Peu importe ce que vous avez fait, ce n'est jamais assez. No matter how much you do, you never do enough.
  27. La dernière personne à démissionner ou à se faire virer sera tenue pour responsable de tout ce qui ira mal par la suite. The last person that quit or was fired will be held responsible for everything that goes wrong.


Tags: Lois et principes

jeudi 4 juin 2009

Convertir Windows XP Home à Professional

Publié par Infinite Loop, à 19 h 48 0 commentaire

Avertissement : la procédure indiquée ici ne vous permettra pas de mettre à jour votre système d'exploitation Windows XP Home à XP Professional. Les composants supplémentaires ne seront pas installés et vous n'aurez pas accès à plus de fonctionnalités.

Cela dit, tout ce que ça permet, c'est de faire identifier à l'interne votre Windows XP édition Familiale comme étant une version Professionnelle. C'est pour cette raison que je classe cette entrée dans les catégories Curiosités et Easter Eggs, même si ç'en est pas vraiment un. Finalement, ça ne sert à pas grand chose, à moins que vous soyez gêné d'afficher publiquement que vous utilisez la version Home... Ce qui est bien, c'est de constater qu'il existe une switch dans le système pour faire ça. Qui sait si ça débloque réellement certaines fonctionnalités qui auraient été rétrogradées ?

Pour changer la version :

  1. Ouvrez l'éditeur de la base de registre (Start / Run / regedit)
  2. Repérez la clé HKEY_LOCAL_MACHINE / System / ControlSet00X. Choisissez celui où 00X est le plus élevé
  3. Dans mon cas, mon numéro est 003. Donc ControlSet003 / Control / ProductOptions
  4. Supprimez la clé ProductSuite (Name: ProductSuite, Type: REG_MULTI_SZ, Data:Personal)
  5. Créez un nouveau DWORD (bouton droit de la souris / New / DWORD value) et nommez le Brand
  6. Assignez la valeur 0 (zéro) à Brand
  7. Vous devrez rédémarrer Windows
  8. Lorsque l'écran du BIOS disparaîtra, appuyez sur F8 pour afficher l'écran de démarrage de Windows (en mode texte)
  9. Plusieurs choix seront affichés. Choisissez "Choose Last Known Good Configuration
Pour vérifier la nouvelle version :
  • si vous utilisez le "Classic start menu", il affichera Windows XP Professional
  • sinon l'onglet général dans les propriétés système (My Computer / Properties OU la combinaison de touches Windows+Pause) indiquera System: Microsoft Windows XP, Professional
  • enfin, si vous exécutez (Start / Run / winver.exe, l'écran "About Windows" s'affichera et l'image aura changé.


Tags: Curiosités, Easter Eggs

mercredi 3 juin 2009

Un site web all dressed avec bacon

Publié par Infinite Loop, à 19 h 14 0 commentaire

Internet est un lieu où tout est possible. On y trouve de tout, la preuve étant que vous pouvez ajouter une tranche de bacon à tout site web pour rendre votre visite plus alléchants (selon certaines sources plus ou moins fiables).

Rendez-vous sur bacolicio.us, ajoutez à la fin de l'URL le lien de la page à accéder et admirez le bacon dans votre écran.

Par exemple : http://bacolicio.us/http://code18.blogspot.com/

Un service pour réduire les liens à envoyer à vos amis (semblable à TinyUrl) offre même l'option d'y intégrer automatiquement le bacon : bacn.me.


Tags: Curiosités, Humour

mardi 2 juin 2009

3 façons de construire une query string en PHP

Publié par Infinite Loop, à 19 h 11 2 commentaires

Aujourd'hui, je vais partager avec vous un truc PHP qui résoud un problème de façon élégante. Je serai bref dans mon explication puisque l'exemple que je m'apprête à vous montrer parle de lui-même.

Êtes-vous du genre à créer des liens en concaténant la query string comme ceci?

$lng = 'fr';
$page = 5;
$recent = 'true';

echo 'page.php?lng=' . $lng . '&page=' . $page . '&recent=' . $recent;

// ou encore

echo "page.php?lng=$lng&page=$page&recent=$recent";
Si oui, changez vos habitudes pour adopter dès maintenant une méthode plus claire : la fonction PHP http_build_query().
$params = array(
'lng' => $lng,
'page' => $page,
'recent' => $recent
);

echo 'page.php?' . http_build_query($params, '', '&');
Dans tous les cas, la chaîne résultante sera :

page.php?lng=fr&page=5&recent=true

Intéressant non ? Ces dernières années, je ne me souviens pas avoir rencontré cette fonction dans les projets sur lesquels je travaille. Pourtant, elle offre beaucoup de flexibilité en plus de rendre le code lisible. Et moi-même, je ne la connaissais même pas il y a quelques semaines!

Défi à relever
Dans le même ordre d'idées, je vous lance un défi que j'essaie moi-même de relever : peu importe le langage de programmation que vous utilisez, explorez la documentation et essayez de découvrir une nouvelle fonctionnalité par jour. L'idée n'est pas de tout comprendre à fond mais juste de savoir que ça existe. C'est étonnant à quel point on peut assimiler des nouvelles connaissances en si peu de temps.


Tags: PHP

lundi 1 juin 2009

Retirer un site malicieux de l'index Google

Publié par Infinite Loop, à 20 h 35 0 commentaire

Si vous êtes dans une situation où votre site s'affiche dans les résultats de recherche de Google avec la mention "This site may harm your computer" et que votre fureteur affiche un message semblable au suivant lorsque vous le visitez, c'est certainement parce que votre site a été victime d'une attaque, qu'il a été infecté et qu'il tente à son tour de propager son virus ou son piège malicieux à vos visiteurs.



Pour ne pas apeurer et perdre votre clientèle, vous n'aurez pas le choix de procéder à un grand nettoyage du printemps. La chasse aux failles de sécurité est lancée. Plus votre projet est volumineux, plus le travail sera ardu. Repérez les vulnérabilités XSS (iframe ou JavaScript externes) ou les possibilités de SQL injection et assurez-vous de colmater le plus grand nombre de brèches. Scannez les fichiers en ligne, par exemple ceux proposés en téléchargement et nettoyez les virus qui pourraient s'y loger. Ça peut aussi être que vos pages comptent des liens externes qui pointent vers des sites jugés comme étant néfastes.

Une fois que vous aurez effectué le travail, vous pourrez demander une révision de site sur www.stopbadware.org, un projet collectif où collaborent Google, AOL, Mozilla, Verisign et plusieurs autres afin d'offrir un environnement web protégé.

  1. rendez-vous dans la section "Badware Website Clearinghouse"
  2. entrez l'URL du site
  3. cliquez sur le bouton Search clearinghouse
  4. dans la liste, cliquez sur le projet (le statut sera indiqué à côté)
  5. dans le haut de la page, cliquez sur le bouton Click to Request Review
  6. remplissez le formulaire de révision et soumettez votre demande
  7. patientez jusqu'à ce qu'il soit réévalué
Assurez-vous que les failles soient corrigées lorsque vous en ferez la demande. Selon mon expérience, les quelques fois où j'ai fait face à ce genre de problème, l'acceptation s'est faite à l'intérieur de 24h et les sites n'ont plus jamais été identifiés comme étant nuisibles.


Tags: Sécurité

Messages plus récents Messages plus anciens Accueil
S'abonner à : Messages (Atom)
    Suivre @code18 sur Twitter

    Catégories

    • Apache (21)
    • Citations (167)
    • Club Vidéo (24)
    • Coffre à outils (56)
    • CSS (8)
    • Curiosités (117)
    • Design Pattern (2)
    • Drupal (8)
    • Easter Eggs (22)
    • Extensions Firefox (20)
    • GIMP (7)
    • Histoire (21)
    • HTML (32)
    • Humour (57)
    • Intégration (34)
    • iPod (12)
    • JavaScript (110)
    • Jeu de combat (6)
    • Le coin du geek (128)
    • Liens (12)
    • Linux (56)
    • Livres (78)
    • Lois et principes (46)
    • Marché des saveurs (26)
    • Mathématique (18)
    • Mobile (5)
    • Montréal (32)
    • Musique (112)
    • Pancartes et écriteaux (16)
    • Perl (8)
    • Pérou (1)
    • PHP (130)
    • PostgreSQL (44)
    • Programmation (105)
    • Saviez-vous que (55)
    • Sécurité (22)
    • SEO (5)
    • SQL Server (22)
    • Vieilles publicités (6)
    • Virtualisation (8)
    • Voyages (1)
    • Zend Framework (26)

    Divers

    Archives

    • ►  2015 (6)
      • ►  août 2015 (1)
      • ►  juillet 2015 (1)
      • ►  février 2015 (3)
      • ►  janvier 2015 (1)
    • ►  2014 (8)
      • ►  décembre 2014 (1)
      • ►  novembre 2014 (1)
      • ►  octobre 2014 (1)
      • ►  août 2014 (2)
      • ►  juillet 2014 (2)
      • ►  janvier 2014 (1)
    • ►  2013 (53)
      • ►  décembre 2013 (2)
      • ►  novembre 2013 (1)
      • ►  octobre 2013 (3)
      • ►  septembre 2013 (2)
      • ►  août 2013 (5)
      • ►  juillet 2013 (3)
      • ►  juin 2013 (5)
      • ►  mai 2013 (3)
      • ►  avril 2013 (7)
      • ►  mars 2013 (7)
      • ►  février 2013 (11)
      • ►  janvier 2013 (4)
    • ►  2012 (105)
      • ►  décembre 2012 (8)
      • ►  novembre 2012 (5)
      • ►  octobre 2012 (4)
      • ►  septembre 2012 (1)
      • ►  août 2012 (8)
      • ►  juillet 2012 (7)
      • ►  juin 2012 (7)
      • ►  mai 2012 (10)
      • ►  avril 2012 (13)
      • ►  mars 2012 (15)
      • ►  février 2012 (15)
      • ►  janvier 2012 (12)
    • ►  2011 (146)
      • ►  décembre 2011 (14)
      • ►  novembre 2011 (11)
      • ►  octobre 2011 (12)
      • ►  septembre 2011 (13)
      • ►  août 2011 (15)
      • ►  juillet 2011 (17)
      • ►  juin 2011 (18)
      • ►  mai 2011 (15)
      • ►  avril 2011 (9)
      • ►  mars 2011 (7)
      • ►  février 2011 (3)
      • ►  janvier 2011 (12)
    • ►  2010 (398)
      • ►  décembre 2010 (29)
      • ►  novembre 2010 (28)
      • ►  octobre 2010 (32)
      • ►  septembre 2010 (34)
      • ►  août 2010 (22)
      • ►  juillet 2010 (35)
      • ►  juin 2010 (42)
      • ►  mai 2010 (36)
      • ►  avril 2010 (37)
      • ►  mars 2010 (34)
      • ►  février 2010 (32)
      • ►  janvier 2010 (37)
    • ▼  2009 (430)
      • ►  décembre 2009 (32)
      • ►  novembre 2009 (34)
      • ►  octobre 2009 (33)
      • ►  septembre 2009 (37)
      • ►  août 2009 (37)
      • ►  juillet 2009 (39)
      • ▼  juin 2009 (38)
        • Clone de lightbox pour jQuery
        • Nouveautés cette semaine
        • Thèmes pour Notepad++
        • Trouver de l'emploi en web au Québec ?
        • Citation no. 36 sur le silence
        • SSH2 : capturer le résultat d'une commande
        • Michael Jackson renaît grâce à son sosie !
        • Personnaliser les extensions de fichiers web
        • Remplacer APC par Zend_Cache
        • APC cache pour optimiser la performance
        • Norton Antivirus expire en direct chez Fox
        • Code source du Kindle d'Amazon
        • Netbeans et l'encodage UTF-8
        • Disque dur de 15 mega-octets de Radio Shack
        • Filtres de fichiers pour FileZilla FTP
        • Citation no. 35 sur l'histoire
        • Exclure les fichiers de projets avec TortoiseSVN
        • Mario Lemieux, un fin connaisseur de l'informatique ?
        • Commentaire sur la création de WSDL en PHP
        • Queue de fonctions en JavaScript
        • Équivalences Ajax avec jQuery et Prototype
        • Magazine Maximum PC en PDF
        • Film Home de Yann Arthus-Bertrand
        • Citation no. 34 sur la responsabilité
        • 6 destinations vacances aux noms insolites
        • À propos des chargés de projets
        • Astuce SQL pour remplacer les sous-requêtes
        • Message créatif et original de CD Baby
        • Composant HTML Purifier
        • Facebook mal programmé ?
        • Enregistrer des disques vinyls sur son ordinateur
        • Citation no. 33 sur les risques du travail
        • Full Text Search PostgreSQL
        • Lois du travail de Dilbert
        • Convertir Windows XP Home à Professional
        • Un site web all dressed avec bacon
        • 3 façons de construire une query string en PHP
        • Retirer un site malicieux de l'index Google
      • ►  mai 2009 (37)
      • ►  avril 2009 (35)
      • ►  mars 2009 (37)
      • ►  février 2009 (32)
      • ►  janvier 2009 (39)
    • ►  2008 (84)
      • ►  décembre 2008 (34)
      • ►  novembre 2008 (39)
      • ►  octobre 2008 (11)

    Abonnés

Copyright © All Rights Reserved. Code 18 | Converted into Blogger Templates by Theme Craft