Bonjour à tous,
English readers : if you want translation you can contact me.
Toujours dans la série NSLU2, je vous avait parlé récemment de l'installation de TorrentFlux. Je vous avait également parlé de l'optimisation du réglage de la SWAP sous Linux embarqué.
Et bien surprise : les 2 ne font pas forcément très bon ménage !
En effet, les téléchargements (surtout de gros fichiers) avaient tendance à couper régulièrement, me donnant la fameuse erreur "Torrent Died" (bien connue des utilisateurs de TorrentFlux si on en croit leur forum). En regardant les logs de ma machine, je me suis rendu compte que les scripts python de téléchargement (BitTornado) étaient tués par le système à cause d'une quantité de mémoire insuffisante.
Bizarre, car j'ai plus de 700 Mo de SWAP de libre et la mémoire utilisée à ce moment atteignait les 40 Mo. Je suppose (étant donné l'évolution chaotique et imprévisible de la répartition mémoire RAM / virtuelle pendant le téléchargement) que le script devait demander trop de mémoire d'un coup, et que le système n'avait pas le temps d'allouer de la SWAP pour combler la demande. Ça n'est que supposition, j'aimerai bien comprendre...
En tout cas c'est cohérent avec le fait qu'en rajustant la swappiness à 40% au lieu de 15%, tout marche maintenant. Je pense qu'avec 40% il hésite beaucoup moins à réserver de la mémoire SWAP et donc le système peut répondre aux demandes de mémoire soudaines plus facilement (il anticipe plus).
À noter que le système "s'enlise" plus facilement au bout de quelques heures sur de gros fichiers (une bonne partie des autres processus sont en SWAP et ne repassent pas en mémoire vive quand une partie se libère), mais c'est ça ou pas de torrent.
Bref, ça marche, c'est cool.
Bonjour à tous,
Voici un lien que je viens de découvrir et que je trouve fort bon : http://developer.yahoo.com/performance/rules.html
Il s'agit d'une liste de best practices élaborées par Yahoo pour aider à améliorer le développement web. Elles sont axées sur la rapidité de chargement et d'exécution des sites web. En voici un résumé :
- Minimiser le nombre de requêtes HTTP
- Répartir le contenu sur des serveurs répartis dans le monde (euh, ça c'est pour les gros sites web)
- Utiliser des Header "Expires" et "Cache-Control"
- Compresser les fichiers avec Gzip
- Mettre les CSS dans la balise HEAD (rien de bien surprenant)
- Mettre les scripts le plus bas possible dans la page (un peu plus surprenant, mais évite de bloquer le chargement de la page à cause d'une script externe par exemple)
- Éviter les expressions CSS (car réévaluées à chaque évènement, donc par exemple à chaque survol de la page)
- Placer les CSS et les scripts dans des fichiers externes (car les navigateurs vont les mettre en cache)
- Réduire les résolutions DNS (donc mettre des liens relatifs pour les fichiers de votre site)
- Optimiser la taille des scripts et CSS (en supprimant les retours à la ligne, espaces inutiles, etc.)
- Éviter tant que possible les redirections
- Éviter d'inclure 2 fois le même script (erreur d'inattention courante sur de gros projets)
- Utiliser les ETag (Entity Tags) sur votre serveur (permet d'éviter au navigateur de recharger un fichier qu'il a déjà)
- Mettre en place un système de cache pour Ajax
- Faire un flush() du buffer après les balises "head" (pour permettre au navigateur de charger les CSS et Javascript)
- Utiliser de préférence GET pour Ajax (POST fait 2 connexions TCP en Ajax d'après eux)
- Charger des composants non essentiels après le chargement complet de la page
- Précharger des composants de la page (qui seront affichés par Javascript)
- Réduire le nombre d'éléments DOM (qui ralentiront l'exécution du Javascript)
- Répartir les composants de la page sur différents serveurs (pas plus de 4 à cause de la question des DNS)
- Minimiser le nombre d'iframe (beurk)
- Éviter le plus possible les erreurs 404 (c'est une requête comme une autre qui charge le serveur)
- Réduire la taille et le nombre des cookies
- Utiliser des domaines différents pour les fichiers statiques (images, scripts) sans cookies
- Minimiser les accès à des éléments DOM
- Développer des évènements intelligemment (en évitant des surcharges inutiles)
- Utiliser <link> plutôt que @import (sous IE avec @import le chargement de la feuille de style est délayé)
- Éviter les filtres CSS destinés à IE 6 et inférieur (utilisez des PNG transparents)
- Optimiser les images (encoder les Gif avec la meilleur palette possible, comparer les formats, etc.)
- Optimiser les images utilisée dans les CSS
- Ne pas redimensionner une image en HTML
- Faire un favicon, lui activer le cache et lui préférer un faible poids
- Garder les composants en dessous de 25Ko (en plus les iPhones ne le mettront pas en cache sinon)
- Grouper les composants dans un document Multipart (comme les mails, mais à vérifier que le user-agent est compatible)
Alors, vous aussi vous faites le check de ce qui est bon ou pas :) ? Quel est votre score héhé ?
Bon on est d'accord, y'en avait des bateaux, mais y'a des choses que je ne connaissais pas personnellement.
Bonjour à tous,
J'utilise depuis peu un service génial : l'envoi de SMS depuis Internet, à partir d'un script PHP s'exécutant sur votre serveur. Voici un exemple d'utilisation pour vous faire comprendre à quel point c'est simple.
Tout d'abord, dans ce tutorial j'utiliserai la plateforme TM4B.com, car elle est :
- pas chère (7 centimes d'euro le SMS en France)
- facile à utiliser
- fiable (d'après les échos que j'en ai eu)
- pas de frais fixes pour l'inscription (on ne paye que les SMS, et pas de limite minimum d'achat)
- on peut simuler un envoi pour débugger les développements
1. Création d'un compte
Inscrivez vous (gratuitement) sur leur site et achetez quelques crédits pour tester le système (100 crédits par exemple, vous donnent une dizaine de SMS, et coutent 1 euro). Attention, si vous payez avec paypal, votre compte doit être vérifié (ce que m'a fait attendre paypal plusieurs jours pour le faire personnellement).
2. Envoi d'un SMS
L'envoi d'un sms se fait par méthode POST HTTP. Voici un exemple de code source permettant d'en envoyer un (à compléter avec vos identifiants de connexion).
<?php
$request = "";
// Nom d'utilisateur du comte TM4B
$param["username"] = "Bob";
// Mot de passe du comte TM4B
$param["password"] = "12345";
// Le contenu du SMS
$param["msg"] = "Hello World !";
// Les destinataires (séparés par un "pipe" | s'il y'en a plusieurs)
$param["to"] = "33123456789";
// Celui qui envoie le message
$param["from"] = "BarackObama";
// Route à utiliser
$param["route"] = "frst";
// Determine si l'envoi est simulé (si oui, c'est gratuit)
// Valeurs : "yes" / "no"
$param["sim"] = "yes";
// Pour être compatible avec l'API 2.0
$param["type"] = "broadcast";
//Construit la requete
foreach($param as $key=>$val){
$request .= $key . '=' . urlencode($val);
$request .= '&';
}
// Supprime le dernier "&"
$request = substr($request, 0, strlen($request) - 1);
// URL de la passerelle
$url = "http://www.tm4b.com/client/api/http.php";
//Envoie la requete avec curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // retourne le resultat en variable
curl_setopt($ch, CURLOPT_POST, 1); // méthode POST nécessaire pour les envois multiples
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
$response = curl_exec($ch);
curl_close($ch);
// Affiche le résultat
print $response;
?>À noter que ce script nécessite l'extension PHP Curl (php_curl) activée.
La réponse du serveur, si il n'y a pas d'erreur, doit être de la forme : MT0015195005-1. Il s'agit de l'identifiant du SMS envoyé.
Voilà, bon courage pour la suite (l'API TM4B propose beaucoup de possibilité pour suivre le message). Par contre, pour recevoir des SMS, ça vous coutera plus cher.
Pour ma part, je compte surement installer ce système sur mon NSLU2 pour pouvoir recevoir des alertes à distance.
Bonjour à tous,
Toujours dans la série NSLU2 (machine embarquée tournant sous Linux, et pouvant faire office de serveur pour 50 euros), voici un petit How-To pour installer un client pour torrents. Il s'agit d'un condensé de différentes sources, au fil des difficultés que j'ai rencontré.
TorrentFlux est un client torrent dont l'interface est une page web utilisant PHP. Les avantages de cette installation sont multiples : le serveur tourne 24/24, donc pas besoin d'avoir son ordinateur allumé pour télécharger, l'interface est accessible depuis internet (pour peu que vous ayez configuré votre routeur) et les fichiers téléchargés sont disponibles à travers le réseau (car téléchargés sur le serveur).
Le principe : l'interface PHP et SQL (sqlite) permet de lancer et voir l'état des torrents (très détaillé et ergonomique), et le script qui réalise le téléchargement proprement dit est en python.
Voici les étapes de l'installation de torrentflux sur un NSLU2 tournant sous Debian.
Installer les packages nécessaires
$ apt-get install lighttpd php5-cgi sqlite php5-sqlite
Récupérer TorrentFlux
$ cd /tmp
$ wget http://www.torrentflux.com/torrentflux_2.3.tar.gz
$ tar -xvzf torrentflux_2.3.tar.gz
Créer la base de données
$ cd /tmp/torrentflux_2.3/sql
$ wget http://homepage.ntlworld.com/cyborgsystems/CS_Main/NSLU2/torrentflux/sqlite_torrentflux.sql
$ mkdir /www-database
$ chown www-data /www-database
$ sqlite /www-database/torrentflux.db < sqlite_torrentflux.sql
$ chown www-data /www-database/torrentflux.db
$ chmod 777 /www-database/torrentflux.db
La base de données doit être accessible en écriture pour sqlite (qui s'exécutera sous l'utilisateur www-data). Elle doit également se trouver dans un répertoire possédé par www-data, c'est pourquoi ici nous créons /www-database/ (sinon on obtiens des erreurs à l'exécution du script PHP).
Configurer Lighttpd
$ nano /etc/lighttpd.conf
modifier la ligne :
fastcgi.server = ( ".php" => ((
"bin-path" => "/usr/bin/php5-cgi",
"socket" => "/tmp/php.socket" )))
Configurer TorrentFlux
$ mkdir /var/www/torrentflux
$ cp -R /tmp/torrentflux_2.3/html/. /var/www/torrentflux/.
$ nano /var/www/torrentflux/config.php
Modifier db_type : $cfg["db_type"] = "sqlite";
Modifier db_host : $cfg["db_host"] = "/www-database/torrentflux.db";
Correction d'erreurs
D'après un post du forum de TorrentFlux, voici quelques corrections à apporter au code :
Fichier functions.php : fonction startQManager : ligne 2212
remplacer :
$btphp = "'" . $cmd1. "; HOME=".$cfg["path"]."; export HOME; nohup " . $pyCmd . " " .$cfg["btphpbin"] . " '";
par :
$btphp = "\"'" . $cmd1. "; HOME=".$cfg["path"]."; export HOME; nohup " . $pyCmd . " " .$cfg["btphpbin"] . " '\"";
Fichier index.php : ligne 254
remplacer :
$command .= " ".escapeshellarg($cfg["cmd_options"])." > /dev/null &";
par :
$x = explode(" ",$cfg["cmd_options"]);
foreach ($x as $y)
$command .= " ".escapeshellarg($y);
$command .= " > /dev/null &";
Première utilisation
Ouvrez la page http://adresse-ip/torrentflux/. À la première connexion, l'utilisateur sera créé. Pensez bien à modifier la configuration (lien "edit settings") et à controler que tous les icones soient verts (les scripts python se trouvent dans le dossier /var/www/torrentflux/).
Pensez également à supprimer les fichiers temporaires (dans /tmp).
Après une première utilisation, cela a l'air de bien fonctionner. L'interface est vraiment sympa, et si vous configurez votre routeur, vous pourrez y accéder depuis internet (à condition de connaitre l'adresse IP internet de votre NSLU2).
Dans certains contextes, la mémoire peut être un critère déterminant dans la gestion d'une machine. J'en fais l'expérience sur mon NSLU2 (machine embarquée tournant sous Linux, et pouvant faire office de serveur pour 50 euros).
Avec seulement 32Mo de RAM, la SWAP est très vite sollicitée, ce qui peut être embêtant si elle est sur une partition d'une clé USB par exemple (le nombre de lectures/écritures est limité). Il est donc possible de configurer le système pour qu'il n'utilise la SWAP que lorsqu'il en a vraiment besoin, et non pas comme sur un PC de bureau (c'est à dire à tout bout de champ).
La swappiness
La swappiness décrit la quantité de RAM libre en dessous de laquelle le système va utiliser la SWAP. Par défaut, c'est à 60% de RAM. Vous pouvez le constater vous même :
cat /proc/sys/vm/swappiness
60
Il serait plus judicieux de la passer à 15% par exemple. Pour cela, il faut executer la commande :
sysctl vm.swappiness=15
Pour que cette modification soit persistante pour tous les prochains démarrage, il faut éditer le fichier /etc/sysctl.conf et y ajouter la ligne suivante:
vm.swappiness = 15
Les priorités entre plusieurs SWAP
Si vous avez plusieurs partitions SWAP, il est possible de leur attribuer chacune une priorité pour, par exemple, favoriser une SWAP sur disque dur plutôt que sur clé USB.
Pour voir les priorités actuelles :
swapon -s
Filename Type Size Used Priority
/dev/sda2 partition 265032 173388 -1
/dev/sdb5 partition 257000 0 -2
Pour changer les priorités, il faut modifier le fichier /etc/fstab et pour chaque partition swap utiliser l'option pri=#. Plus le chiffre est élevé, plus la priorité est élevée.
nano /etc/fstab
# file system mount point type options dump pass
proc /proc proc defaults 0 0
/dev/sda1 / ext3 defaults,errors=remount-ro,noatime 0 1
/dev/sda2 none swap sw,pri=1 0 0
/dev/sda1 /media/usb0 auto rw,user,noauto,noatime 0 0
/dev/sda2 /media/usb1 auto rw,user,noauto,noatime 0 0
/dev/sdb1 /hddsys ext3 defaults,noatime 0 0
/dev/sdb5 /hdd ext3 defaults,noatime 0 0
/hddsys/swap none swap sw,pri=2 0 0
Notez également l'attribut noatime pour les autres partitions, pour éviter que la date d'accès aux fichiers soit mise à jour. En effet, ces écritures inutiles sur la mémoire Flash diminuent sa durée de vie.
Conséquences !
Paragraphe ajouté le 23/06/09
Après environ 1 mois d'utilisation, j'ai rencontré un problème lors de l'utilisation de TorrentFlux (installation détaillée dans un autre article) sur ma machine. Les problèmes en question sont expliqués dans un autre article. Au final, je me suis rendu compte que la swappiness était trop faible et par moment ça faisait paniquer le système qui tuait l'application mangeuse de mémoire.
Morale de l'histoire : Ne pas télécharger de torrent ? Euh, non mais ça aurait pu :)
J'ai ré-ajusté la swapiness à 40, car maintenant j'ai un disque dur externe pour la SWAP.
Donc, si vous constatez des instabilités au niveau de la mémoire, soyez peut être moins restrictif.
Bonjour à tous,
Aujourd'hui, un petit article sur la reconnaissance et la synthèse vocale.
Définitions
Reconnaissance vocale : 2 utilisations : l'utilisateur dicte un texte qui est retranscrit par l'ordinateur, ou l'utilisateur énonce des commandes auxquelles l'ordinateur est programmé pour répondre. Nous ne parlerons pas de l'identification à l'aide de l'empreinte vocale.
Synthèse vocale (ou Text-To-Speech, TTL) : l'ordinateur lit un texte pour le synthétiser vocalement avec une "parole" artificielle.
Utilisation
Actuellement, je n'ai réussi qu'a trouvé qu'une seule façon de faire de la reconnaissance vocale : en utilisant les API Microsoft SAPI 5.1, contenues dans le Microsoft Speech SDK 5.1. Relativement efficace (mais moins efficace que Dragon Naturally Speaking par exemple), ces API ne sont bien entendu disponibles que sur plateforme Windows, on ne peut donc pas les utiliser sur Linux ou autre... De plus, à l'heure actuelle, seule la langue anglaise (et japonaise avec un patch) est supportée. Donc préparez votre accent pour une bonne reconnaissance.
Notion à comprendre : La reconnaissance vocale peut se faire de 2 façons.
- Il peut s'agir d'une dictée libre de texte, c'est à dire que vous dictez du texte et l'ordinateur essaye de retranscrire ce que vous dites.
- Ou alors il peut s'agir du mode "Control & Command" (ou C&C) qui est basé sur une liste de commandes prédéfinies. Dans ce mode, SAPI a une reconnaissance beaucoup plus efficace, car il y'a beaucoup moins de possibilités de reconnaissance.
Pour la synthèse vocale, dans ce SDK sont présentes plusieurs voix anglaises. Mais vous pouvez également télécharger des voix françaises ou autres, soit gratuites faites par Microsoft (je n'ai pas de lien pour l'instant), soit faites par des entreprises extérieures (mais pas toujours gratuites).
Téléchargement et installation du SDK
Petite précision : le SDK est la partie de Microsoft Speech API qui est utilisable par les développeurs pour l'intégrer à leur application. C'est donc uniquement un outil pour développeur et non pas une application en soi.
Pour télécharger le SDK, c'est ici : télécharger SAPI SDK 5.1
Je vous conseille de télécharger "SpeechSDK51.exe", c'est la partie qui nous sera utile.
Une fois installé, rendez-vous dans le panneau de configuration et ouvrez "Voix". Creez-vous un nouveau profil, faites de l'apprentissage pour améliorer la reconnaissance et configurez les options pour le Text-To-Speech en choisissant votre voix.
Une fois le tout configuré, testez les démos proposées pour vous donner une idée de ce qu'il est possible de faire. Vous remarquerez qu'il est bien entendu possible d'utiliser SAPI dans n'importe quel langage, C++, C#, VB, VB.Net, même Javascript d'après la démo. À noter que les sources des démos sont fournies, donc vous pouvez vous y mettre facilement.
Le fichier de documentation est le fichier sapi.chm, qui se trouve dans C:\Program Files\Microsoft Speech SDK 5.1\Docs\Help. Il peut paraitre rebutant au début, mais c'est une mine d'or.
A propos de l'apprentissage :
- Lorsque vous allez faire l'apprentissage pour la première fois, il se peut que l'ordinateur ne reconnaisse RIEN, et qu'il ne se passe rien. Ne paniquez pas, n'abandonnez pas. Passez des mots, voir des pages entières, et essayez d'arriver à faire reconnaitre quelques mots. Une fois les premiers mots reconnus, le reste devrait suivre.
- J'ai remarqué qu'une fois que l'apprentissage est efficace, si on essaye encore de l'améliorer, la reconnaissance se dégrade. J'imagine que c'est l'effet classique du sur-apprentissage. Moralité, une fois que la reconnaissance est à peu près bonne, ne poussez pas trop le bouchon sinon vous risquez d'avoir à supprimer votre profil et en recréer un nouveau (et donc de refaire l'apprentissage).
- Pour vous donner un ordre d'idée, pour ma part la reconnaissance est bonne en 2 à 3 séances d'apprentissage. Quand je dis qu'elle est bonne, c'est que la reconnaissance de commandes dans les applis de démo du SDK est fiable. Par contre en ce qui concerne la dictée libre de texte, c'est la cata quoi que je fasse. Mais je ne maitrise encore pas trop le terrain de la "dictée" libre.
Exemple d'utilisation
Voici un court paragraphe sur l'utilisation que je fais de SAPI. Il s'agit d'une application permettant de contrôler le PC avec la voix.
L'application tourne donc en tache de fond et est inactive. Elle est simplement à l'écoute du mot clé qui la rend active (par exemple "Computer").
Lorsque je prononce le mot clé, l'application me répond "Yes ?" et devient active pour écouter ma commande. Lorsque je donne une commande, la reconnaissance se fait dans une liste prédéfinie de commandes (donc en mode Control&Command). Ainsi mon application sait reconnaitre et exécuter les commandes "Open google", "Play music", "Go to next song" etc... Mais si je dis une commande qu'elle ne connait pas, elle ne fera rien.
Pour aller plus loin, je travaille actuellement à mélanger le mode "liste de commandes définies" (Control&Command) et "dictée libre". Ainsi, il sera possible de faire des commandes comme :
- "Open XXX" (ou XXX est une application, un fichier, une adresse web...)
- "Send mail to YYY" (ou YYY est un contact ou une adresse mail)
Les possibilités sont énormes, et il est possible de faire des commandes très évoluées avec une grammaire s'inspirant des expressions régulières, par exemple en mettant des mots optionnels (par ex. "please" avant chaque commande), en mettant des variables (comme précédemment : "open XXX"), de définir quel "pattern" une commande doit suivre, etc... Si cela vous intéresse, lisez donc la partie "Grammaire".
Grammaire
Les grammaires sont un élément essentiel de la reconnaissance vocale. Ce n'est pas compliqué, prenez le temps de lire cette partie avant d'attaquer le code. Au début, vous pourrez commencer avec une grammaire très simple, puis avec le temps vous pourrez l'étoffer et la rendre très puissante.
Le tutorial concernant la grammaire fera l'objet d'un article à part entière prochainement. Les liens seront mis à jour lorsque l'article sera fait.
Code
L'utilisation de SAPI dans le code fera l'objet d'un article à part entière prochainement. Les liens seront mis à jour lorsque l'article sera fait.
Redistribution
Pour la redistribution de SAPI 5.1 dans l'installeur de votre application, je vous conseille l'article suivant :
http://support.microsoft.com/?scid=kb%3Ben-us%3B320207&x=15&y=16
Aller plus loin
Ma carte son (Realtek High Audio) possède une option permettant de supprimer l'écho acoustique. En d'autre termes, si mon PC joue de la musique, mon micro capte ma voix plus la musique, mais pré-traite le signal pour en soustraire le son qui sort dans les enceintes (donc la musique). Au final, même si mon PC joue de la musique, SAPI n'entend que ma voix et donc cela ne gène pas la reconnaissance vocale.
C'est d'ailleurs assez impressionnant, on ne s'entend même pas dire la commande mais le PC la comprend sans problème. Par contre cette option est désactivée par défaut, donc si votre carte son propose cette option, essayez de l'activer. Ça évitera également que lorsque la synthèse vocale vous parle, la reconnaissance vocale croit que vous lui donnez des commandes (c'est bête, mais chez moi ça faisait des commandes en boucle, l'ordinateur se parlait à lui-même :-).
J'espère que cette introduction à SAPI vous a plut, si vous connaissez d'autres moteurs de reconnaissance vocale, en particulier qui pourrait être en Français ou tourner sous Linux, merce de le partager dans les commentaires. Également, si vous avez des bonnes idées pour utiliser ça, n'hésitez pas à partager.
J'essayerai de faire une vidéo de présentation de mon application un de ces jours.
Merci à ghuysmans99 pour les corrections de fautes d'orthographe.
Après avoir installé Debian sur votre NSLU2, il est conseillé de faire un backup complet du système : une image du système de fichier. En effet, la durée de vie d'une clé USB est limitée dans le temps, ça vous évitera de tout réinstaller.
Pour cela, il suffit d'executer la commande suivante :
cat /dev/mtdblock* > image.bin
Quand vous en aurez besoin, vous pourrez alors restaurer l'image depuis linux ou windows en
flashant le NSLU2.
Ubiquity
est une extension pour Firefox qui sera intégrée à la prochaine version (Firefox 3.1 renommée récemment Firefox 3.5).
Le principe de cette extension est de permettre l'interprétation de commandes en langage naturel. En appuyant sur le raccourci clavier "Ctrl+Espace", vous ouvrez une boite de dialogue où vous pouvez taper des commandes. Il y a une bonne liste de commandes installées par défaut : search, map, weather, twitter, email (ne fonctionne qu'avec gmail), youtube etc... mais il est possible facilement d'en créer ou d'en trouver des personnalisées.
Par exemple, pour envoyer un mail à Jean, vous n'aurez qu'à taper « email contenu de mon message to Jean », en ça comprendra automatiquement ce que je veux faire et qui est Jean à partir de ma liste de contact. Autre exemple : vous sélectionnez un texte et vous exécutez la commande « translate to french ». Le texte sélectionné est alors directement remplacé par sa traduction en français.
Voici une vidéo de présentation du service :
Ubiquity for Firefox from Aza Raskin on Vimeo.
Actuellement, cette extension sert surtout de raccourcis vers des services, mais on peut imaginer des fonctionnalités plus puissantes dans le futur, par exemple en integrant la recherche d'url des favoris ou liens visités (comme la barre d'adresse), ou la compatibilité avec d'autres services de messagerie.
Bonjour à tous,
Aujourd'hui, point de développement ou astuce informatique, je voudrais réagir aux dernières modifications des conditions d'utilisation de Facebook.
Voici un extrait :
"Vous accordez à Facebook le droit irrévocable, perpétuel,
non-exclusif, transférable et mondial (avec l’autorisation d’accorder
une sous-licence) d’utiliser, copier, publier, diffuser, stocker,
exécuter, transmettre, scanner, modifier, éditer, traduire, adapter,
redistribuer n’importe quel contenu déposé sur le site."
"You hereby grant
Facebook an irrevocable, perpetual, non-exclusive, transferable, fully
paid, worldwide license (with the right to sublicense) to (a) use,
copy, publish, stream, store, retain, publicly perform or display,
transmit, scan, reformat, modify, edit, frame, translate, excerpt,
adapt, create derivative works and distribute (through multiple
tiers), any User Content you (i) Post on or in connection with the
Facebook Service or the promotion thereof subject only to your
privacy settings or (ii) enable a user to Post, including by
offering a Share Link on your website and (b) to use your name,
likeness and image for any purpose, including commercial or
advertising, each of (a) and (b) on or in connection with the Facebook
Service or the promotion thereof."
En d'autres termes,
tout contenu (texte, photo, vidéo, information personnelle, musique) que vous postez dessus appartient à Facebook.
Et ce passage :
"votre contenu d’utilisateur peut être effacé du site à n’importe quel
moment. Si vous l’effacez, le droit accordé à Facebook évoqué
précédemment expirera automatiquement, mais notez que l’entreprise peut
en conserver des copies archivées".
a été
retiré le 4 février.
Donc, impossible de récupérer les droits de votre contenu, même en fermant votre compte.Selon l'Union des photographes créateurs (UPC), ces conditions d'utilisation sont
illégales en France : "le droit moral sur une œuvre est inaliénable, de même que céder ses droits sans restriction n'est pas possible en droit français".
Mais il reste à le prouver et surtout, à les faire modifier.
En tout cas, je vais de ce pas retirer toutes mes photos (informations personnelles, c'était globalement déjà fait), et je songe chaque jour de plus en plus à
fermer mon compte.
Des réactions ?
EDIT (18 février)
Voici ce qu'on peut lire sur le
blog facebook le 18 Février 2009 :
"Over the past few days, we have received a lot of feedback about the
new terms we posted two weeks ago. Because of this response, we have
decided to return to our previous Terms of Use while we resolve the
issues that people have raised. For more information, visit the
Facebook Blog."
Espérons qu'ils ne commettront pas la même erreur 2 fois.
Bonjour à tous,
Si vous vous retrouvez dans le cas où vous avez 2 applications (ou processus), et que vous souhaitez échanger des informations entre elles (Inter-process Communication : IPC), il existe plusieurs solutions. Celle que je vais présenter n'est pas de passer par un fichier tampon ! 
Windows propose la gestion d'évenements (ou messages/signaux) comme sous linux. Seulement, contrairement à Linux, il est possible d'y joindre de l'information. Par contre, ce que j'ai vu sur certaines sources, c'est qu'il était possible d'utiliser des évènements "classiques" et de les détourner de leur usage normal pour les utiliser de façon personnalisée. Ce n'est pas la meilleure solution puisqu'il existe un message dédié à cet usage : WM_COPYDATA.
Ainsi, dans l'application A, voici les opérations à suivre :
- Récupérer le handle de la fenêtre à laquelle envoyer le message WM_COPYDATA (avec FindWindow par exemple)
- Lui envoyer le message : SendMessage(hwnd, WM_COPYDATA, wParam, lParam). lParam contient la structure de données à échanger.
Du côté de l'application B :
- Sous-classer si besoin la fenêtre (dans Visual Basic par exemple), sinon tant mieux
- Lorsque le message WM_COPYDATA arrive, on récupère les données de lParam)
Très pratique pour échanger peu de données sans trop s'embeter, et de manière propre. Sous Visual Basic ça rajoute la contrainte du sous-classement, mais on peu facilement le faire avec la
DLL de vbAccelerator (et la version avec ASM ne plante pas l'IDE !)
J'ai trouvé pas mal d'
infos sur la MSDN, et j'ai posté un
exemple VB (tiré de la MSDN).
Matthieu
Bonjour à tous,
Voici depuis quelques temps la petite bête qui m'occupe :

Il s'agit d'un NSLU2.
Quésaco ?
Un NSLU2 est un boitier vendu par Linksys et qui permet, en y branchant un disque dur externe USB et en branchant le NSLU2 à un routeur, de partager un disque dur sur un réseau facilement.
La où ça devient intéressant, c'est que le firmware développé par Linksys est dérivé d'un
Linux. Ils ont donc été "obligé" par la licence de linux de diffuser le code source de leur système.
Une communauté a donc repris en main le code et l'a utilisé pour porter d'autres systèmes sur la machine. Il est donc possible d'installer une linux
Debian et toutes les applications standards.
La machine dispose d'un processeur à
266Mhz,
32M de RAM,
2 ports USB et
1 port Ethernet. C'est tout ^^, pas d'écran, clavier, souris. Linux peut s'installer sur une clé USB, et on peut accéder au système par SSH (connexion ligne de commande sécurisée depuis un autre oirdi du réseau).
Au final, on a un serveur :
- qui coute environ 50 euros à l'achat
- qui consomme 10 watt, soit environ 70 centimes / mois (d'après mes calculs)
- sans bruit (pas de disque dur)
Bilan
Je ne peux que vous conseiller de vous lancer si ça vous intéresse. Si comme moi au départ vous ne connaissiez pas trop linux, vous apprendrez énormément car tout se passe en ligne de commande (la seule façon d'accéder au système est de s'y connecter par le réseau en SSH). C'est donc du pur linux, un peu compliqué au début mais tellement puissant.
Chez moi, j'ai donc mis mon NSLU2 sur mon réseau local à une adresse IP fixe. J'ai mis des règles de redirection de ports sur mon routeur (NAT) pour pouvoir accéder à mon serveur depuis l'extérieur.
J'ai installé les services suivants :
- Mise à jour auto des DNS d'un nom de domaine pour pouvoir accéder à mon serveur (IP dynamique) depuis un nom de domaine (avec
DynDNS)
- Serveur
HTTP (web)
- Serveur
SSH (normal, c'est la base), je peux donc entièrement controler mon serveur depuis n'importe où
- Serveur de
fichiers local : je branche mon disque dur externe et je peux y accéder depuis n'importe quel PC de mon réseau local, même windows en lecteur réseau (serveur samba sous linux)
- Serveur
rsync : synchronise automatiquement les fichiers de mon PC portable (sous Windows !) pour garder une copie parfaite en temps réel sur le disque dur externe qui est sur le NSLU2
- Serveur
FTP et
SFTP : je peux accéder à tous mes fichiers, y compris ceux de mes autres ordis (cf plus haut), de n'importe où dans le monde
-
Serveur de téléchargement bittorrent avec interface web- Stream
webcam (pas encore fait, je vais essayer pour rigoler)
Je configure tout ça en SSH depuis linux ou même windows (avec
cygwin), aucun problème.
Les possibilités sont très grandes.
Et encore, il est possible (vu la faible consommation et la petite taille) de rendre le NSLU2
autonome électriquement avec des piles ou batteries. Rajoutez lui une clé Wifi, une clé USB GPS, un petit ecran LCD, une webcam, des moteurs....... Et vous pouvez faire de
l'embarqué, des
robots, des
caméras numériques, des
GPS simplifiés, des
terminaux wifi portables, un traceur GPS...... Plein de possibilités.
Si ça vous intéresse : la liste des articles que j'ai écrit concernant le NSLU2.
Je suis tombé sur ce site génial qui pourrait en intéresser certains : dot-o-mator.
Il s'agit d'un générateur de nom de site ou marque ou produit, bref un générateur de nom, orienté web 2.0. Parfait pour stimuler notre imagination lorsqu'il s'agit de trouver des noms originaux.
Vous avez le générateur automatique spécial web 2.0, qui est pas mal : lien, mais limité, et vous avez le générateur avancé qui permet de faire des combinaisons entre des propositions classées par catégories, ou même vos idées.
Bref, pour ceux en manque d'idées, ça pourra s'utiliser en parallèle avec un générateur de jeux de couleur.
Voici un petit tuto des actions à suivre pour arriver à compiler un code source utilisant OpenCV dans l'IDE DevC++, pour ceux qui comme moi on du mal à trouver de la documentation (en français du moins).
OpenCv
OpenCV est une librairie open source développée par Intel fournissant plein d'outils pour le traitement d'images, notamment celles d'une webcam (détection de forme ou de visages par exemple…)
Compiler un programme utilisant OpenCV sous DevCpp
Je pars du principe que vous voulez compiler l'exemple "facedetect.c" et que vous avez installé OpenCV dans C:\Program Files\opencv
- Copier le fichier "facedetect.c" dans un dossier et créez un nouveau projet DevC++ dans lequel vous ajoutez ce fichier.
- Ouvrez les propriétés du projet (Projet > Options du projet)
- Dans l'onglet "Paramètres", dans le champ "Éditeur de liens" ajoutez les arguments suivants : -lhighgui -lcv -lcxcore -lcvaux -lcvcam
- Dans l'onglet "Répertoires" ajoutez le dossier suivant dans la liste des répertoires de bibliothèques : C:\Program Files\opencv\lib
- Dans le même onglets mais dans les répertoires d'inclusion, ajoutez les dossiers suivants : C:\Program Files\opencv\cv\include, C:\Program Files\opencv\otherlibs\highgui, C:\Program Files\opencv\cxcore\include, C:\Program Files\opencv\cvaux\include
Maintenant ça devrait compiler (j'espère pour vous, sinon peut-être que vous n'avez pas la même version de OpenCV que moi, ou pas les même dossiers).
Voilà j'espère que ça vous servira.
Vous voulez avoir accès à vos machines linux de n'importe où et sans avoir obligatoirement de client ssh ?
Voici un client ssh mais web : sous forme d'applet Java. Si vous l'hébergez sur un de vos serveur (il ne nécessite aucun script particulier, contrairement à de nombreux web-based ssh qui tournent sous python), vous pourrez vous connecter en ssh à vos machines de n'importe où avec un simple navigateur web supportant le java.
Il a l'air très puissant : il intègre aussi des clients telnet, sftp etc... Et gratuit pour un usage personnel.
Bref, si vous voulez le télécharger, rendez-vous ici :
http://www.appgate.com/index/products/mindterm/mindterm_download.html
Voici une découverte très récente que je viens de faire : l'azerty (et le qwerty) sont des claviers qui ont été inventés POUR RALENTIR la frappe des utilisateurs. Ça date de l'époque des machines à écrire, où si le/la secrétaire tapait trop vite, les touches se bloquaient.
Seulement aujourd'hui on a plus ce problème, et je dirais même qu'on voudrait le plus de rapidité possible, pourtant on est resté aux mêmes clavier azerty.
C'est bien dommage, d'autant plus que ces claviers sont fait pour nous ralentir, donc parcourir de grands mouvements avec les mains, ce qui peut entrainer dommages aux muscles, tendons et nerfs (y'a t'il des victimes dans la salle ^^ ?).
Bref, c'est la où je vous parle du Dvorak : une configuration des touches alternative conçue pour minimiser les mouvements et accélerer un maximum la frappe : de l'ergonomie quoi.
Le Dvorak est à l'origine anglais mais il existe des équivalents français.
Apparemment il y'en aurai 3 types différents, personnellement j'ai retenu le dernier : le fr-dvorak-bépo, car il est à jour, issu de communautés open source (donc suffisamment travaillé) et ça a l'air d'être le meilleur des 3 (purement subjectif).
Un peu de visuel, c'est plus parlant :

(la configuration fr-dvorak-bépo)
Pour y installer, sous windows, linux ou mac, aucun souci (il suffit de télécharger les pilote ici :
http://www.clavier-dvorak.org/wiki/Windows_:_installation)
Le problème : c'est que ça ne change pas physiquement vos touches :-D, donc perso j'ai choisi la bonne vieille méthode avec des étiquettes par dessus les touches, ça marche bien. Maintenant il ne reste plus qu'à apprendre à réécrire à l'ordinateur (le basculement entre azerty/dvorak est très facile au cas ou).
Les gains possibles :
- jusqu'à 40% de vitesse de frappe
- moins de fatigue musculaire et repos des tendons et nerfs (idéal pour les problèmes de canal carpien)
- les mains bougent moins, la frappe est beaucoup plus agréable (selon les dires de ceux qui le pratiquent)
Pour ma part je commence juste à m'y mettre, j'ai à peine mis 1/2 heure pour taper cet article ;-)
Lien vers le site :
http://www.clavier-dvorak.org/wiki/Accueil
Pour les intéressés, je ne crois pas que ce genre de claviers soient vendus tels quels (physiquement modifiés), j'ai cherché des revendeurs mais je n'en ai pas trouvé.
Si vous développez des captcha, graphiques en tous genres etc... en PHP (ou autre langage serveur), vous avez peut-être été confronté à ce problème : l'image précédemment générée reste en cache dans le navigateur et si le script génère une image différente, celle-ci n'est pas réactualisée.
Voici une solution, tordue mais simple, quand vous ne voulez pas (ou pouvez pas) toucher aux Headers de l'image : rendre le nom de l'image aléatoire.
Comment ? En insérant simplement un nombre aléatoire dans l'url en paramètre GET, comme ça ça n'influe sur rien d'autre que l'appel à l'image. Voici un exemple tout simple :
<img src="histogramme.php?random=<?php echo rand(); ?>" alt="Chargement de l'histogramme..." />
Ahaha, voilà une erreur PHP assez sympa :
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting ',' or ')' in xxx on line 20
Apparemment, ça serait une histoire de "::"... J'en sais pas plus j'ai fait une erreur de frappe et je crois qu'il n'a pas aimé mon code PHP.
Aujourd'hui, je viens d'apprendre quelque chose que j'ai trouvé vraiment intéressant, et surtout piégeur !
Je développe actuellement un site web tout simple avec stockage de la connexion des utilisateurs en
variable de session. Seulement, j'ai remarqué des phénomènes limites paranormaux : de temps en temps, après une redirection avec la fonction PHP
header(), on se retrouvait déconnecté sans raison. Et impossible de reproduire le bug à coup sur, et surtout : ça n'arrivait jamais en local.
La raison est assez simple, mais tordue (merci aux commentaires dans les fonctions PHP du site php.net !) :
Si le script A ouvre une session (pour voir si l'internaute est connecté), puis redirige avec header() vers le script B, et que le script B ouvre lui aussi rouvre la session pour voir si l'utilisateur est connecté, il peut y avoir un problème.En effet, normalement la session PHP est refermée à la fin du script. Donc quand A redirige vers B, on fait
die() (ou
exit) dans A et A termine son exécution.
Mais le serveur peut être tellement rapide que le script B est déjà appelé par le navigateur client avant même que A ait fini son exécution, et donc le serveur exécute le script B qui demande d'ouvrir la session. Il y'a donc un
conflit et B (en tout cas c'est ce que j'ai constaté avec mes tests approximatifs) voit bien le tableau de session, mais celui-ci est vide. Et donc boum -> l'internaute est déconnecté.
La parade ?
Utiliser
session_write_close().
Soit après en avoir finit avec la session, c'est plus sur, soit juste avant l'appel à la fonction header(). Comme ça on est certain d'avoir fini de travailler sur la session et le script B peut l'ouvrir sans problème.
PS : je
pense que ça n'arrivait jamais en local car mon PC n'a pas du tout la même puissance que le serveur, bien que les temps de réponses soient bien plus infimes, mais ça n'est que mon interprétation.
J'ai récemment rencontré un bug facheux sur le script BigDump.
Ce script PHP sert à importer des gros fichiers de bases de données sans se soucier des limitations de tailles imposées par phpMyAdmin ou de la nécessité d'avoir un shell linux pour executer des commandes mysql (que généralement on a pas sur notre hébergeur).
Il est très sympa, simple (1 seul fichier), rapide et configurable, joli (avec interface AJAX), mais a un gros défaut :
il ne fonctionne pas avec les fichiers Windows.
L'erreur en question commence par :
Error at the line 3001: INSERT INTO table (xxx)
xxx représente un peu n'importe quoi, le script de découpage du fichier ayant un bug, c'est une chaine de caractère un peu aléatoire qui en sort.
La ligne 3001, c'est parce que le script traite les lignes par paquets, et donc au 2è paquet de ligne à traiter, la il y a erreur. C'est du aux retours à la ligne différents sous Windows (\r\n) et sous UNIX (\n).
C'est ce que j'ai eu le malheur de découvrir en l'utilisant, et j'ai remarqué que je n'étais pas le seul à avoir cette erreur. J'ai fouillé dans le script et je me suis rendu compte qu'en fait l'auteur a rajouté quelques lignes pour rendre son script compatible avec Windows mais qu'il ne l'a jamais testé (et ça ne marche pas bien sur :( ). Donc la solution la plus simple, c'est d'ouvrir le fichier csv à importer dans votre base de données avec Notepad ++, de le convertir en fichier UNIX, et de relancer le chargement.
Je n'ai trouvé cette solution nulle part ailleurs, alors j'espère que ça pourra en aider quelques uns.
Un super casse-tête qui m'a empeché de dormir pendant un certain temps 
Le principe est simple, vous avez 2 triangles composés exactement des mêmes "morceaux". Seulement sur le triangle du bas, un "trou" apparaît... Où est l'erreur ?

Les 10 derniers blogs postés
-
[Refactoring] ReSharper pour Visual Studio 2010 (Preview) par
Thomas Jaskula le il y a 13 heures et 31 minutes
-
[Refactoring] Analyser vos exceptions avec ReSharper Exceptional par
Thomas Jaskula le il y a 14 heures et 45 minutes
-
SharePoint 2007 : patterns & practices SharePoint Guidance par
Philippe Sentenac [MVP SharePoint] le 07-03-2009, 09:56
-
[Visual Studio 2010] Les tests cases c’est bien, mais je vais devoir tout réécrire ? par
Etienne Margraff le 07-03-2009, 09:00
-
MVP[Gribouillon].AddYear par
The Grib's Lair [Sébastien PICAMELOT - MVP SharePoint] le 07-03-2009, 08:45
-
Clinique INSIA - Projet de fin d’Etudes (Silverlight 3 MVVM et OutOfBrowser, WCF, TFS) - Part 1 par
David REI le 07-02-2009, 23:38
-
C’est la crise ? Bah pourquoi cramer du budget pub alors ? par
Nix's Blog le 07-02-2009, 15:31
-
Soyons MVP ! par
TheSaib .NET blog le 07-02-2009, 12:15
-
SharePoint : Gestion des Erreurs 6398, 7076 et 6482 par
Blog Technique de Romelard Fabrice le 07-02-2009, 11:53
-
EF avec WPF par
Matthieu MEZIL le 07-02-2009, 10:18