→ Par
Simon ,
Le
30/03/2013 à 01:45
Lorsqu'on développe un site internet et qu'on n'a pas l'âme d'un administrateur système, c'est pénible de configurer un serveur web. Quand on travail sur un projet versionné, c'est irritant de configurer un vhost à chaque nouvelle branche. Bref, pour développer, c'est chiant de se cogner la configuration d'un serveur...quelqu'il soit.
Depuis PHP 5.4.0, il est possible de lancer un serveur (voué au développement) très facilement. En effet, il suffit de se placer dans le répertoire de travail et de lancer une commande pour avoir un son serveur opérationnel.
$ cd /chemin/vers/le/projet
$ php -S localhost:8000
Dans cette commande, je décide que le serveur écoute sur le port 8000. Si je me rend sur mon navigateur à l'adresse http://localhost:8000/, alors mon projet est exécuté comme si c'était via un serveur web classique.

La particularité de ce serveur se place dans le routage. Par défaut, si aucun fichier n'est explicitement indiqué dans la requête HTTP, alors le fichier index.php (ou index.html) servira de routeur : toutes les requêtes passeront donc par lui. On peut redéfinir le routeur par défaut et spécifier le répertoire de travail directement la commande de lancement du serveur.
$ php -S localhost:8000 -t /chemin/vers/le/projet
$ php -S localhost:8000 -t /chemin/vers/le/projet /chemin/vers/le/routeur.php
Si le routeur est redéfini, alors vous devrez gérer l'accès aux assets (@see la doc, exemple 3).
Bref, un outil très pratique pour déployer rapidement un environnement de développement PHP. Il est bon de noter que les requêtes sont servies de manière séquentielle donc vous aurez des pertes de performances.
→ Par
Simon ,
Le
17/02/2013 à 17:51
Info Cet article a été posté il y a plus de 3 mois. Il est suceptible de contenir des informations outdated.
Si vous avez une masse importante de bookmarks et que vous aimeriez les retrouver dans Uzbl alors je vous propose ce script d'importation. Il se repose sur les bookmarks de la "Barre personnelle" uniquement, et configure les bookmarks avec des tags (cf le précédent article).
Pour que le script fonctionne, vous devez posséder php et vous aurez besoin de faire un export (au format json) à la racine de votre répertoire personnelle.
Il suffira de lancer le script et tout se fera automatiquement :)
#!/usr/bin/php5
<?php
$bookmarks_file = array_pop(glob(getenv('HOME').'/bookmarks-*.json'));
if (empty($bookmarks_file)) {
echo sprintf("No bookmarks found in \"%s\"/\n", getenv('HOME'));
exit(0);
}
$datas = json_decode(file_get_contents($bookmarks_file));
function get_firefox_bookmarks_for_uzbl($node, $prefix)
{
$config = '';
if (isset($node->children)) {
foreach ($node->children as $child) {
$config.= get_firefox_bookmarks_for_uzbl($child, $prefix.'/'.$node->title);
}
} else {
if (isset($node->uri)) {
$config.= str_replace(
array(
'/Barre personnelle/',
'/Barre personnelle'
),
array(
'/Barre personnelle',
'/'
),
"$node->uri $prefix $node->title\n"
);
}
}
return $config;
}
file_put_contents(
getenv('HOME').'/.local/share/uzbl/bookmarks',
get_firefox_bookmarks_for_uzbl($datas->children[2], '')
);
→ Par
Simon ,
Le
17/02/2013 à 17:26
Info Cet article a été posté il y a plus de 3 mois. Il est suceptible de contenir des informations outdated.
J'utilise à présent Uzbl-tabbed comme navigateur (hormis quand je fais du développement web). Il fonctionne à merveille, sans compter l'incroyable facilité de personnalisation.
Voici quelques éléments de ma configuration :
Clique molette : ouverture dans un onglet
@bind <Button2> = sh 'if [ "$1" ]; then echo "event NEW_TAB $1" > "$UZBL_FIFO"; else echo "uri $(xclip -o | sed s/\\\@/%40/g)" > "$UZBL_FIFO"; fi' '\@SELECTED_URI'
Divers binds
@cbind <Ctrl>n = event REQ_NEW_WINDOW # nouvelle fenêtre
@cbind <Ctrl>r = reload # rechargement
@cbind <Ctrl>R = reload_ign_cache # rechargement sans cache
@cbind <Mod1>b = back # précédent
@cbind <Mod1>n = forward suivant
@cbind <Ctrl>w = exit # fermerture d'onglet/fenêtre
@on_event NEW_WINDOW sh 'uzbl-tabbed "$1"' %r
@cbind clone = event REQ_NEW_WINDOW \@uri # copie de fenêtre/fenêtre
Gestion de bookmarks avec des tags
Ce script est un hack de celui présent sur le site d'Uzbl.
- Emplacement :
@scripts_dir/bookmark_with_tags_for_folders.sh
- Bind :
@cbind <Ctrl>d = spawn @scripts_dir/bookmark_with_tags_for_folders.sh
#!/bin/bash
# @scripts_dir/bookmark_with_tags_for_folders.sh
#NOTE: it's the job of the script that inserts bookmarks to make sure there are no dupes.
file=${XDG_DATA_HOME:-$HOME/.local/share}/uzbl/bookmarks
[ -r "$file" ] || exit
DMENU_SCHEME="bookmarks"
DMENU_OPTIONS="xmms vertical resize"
. "$UZBL_UTIL_DIR/dmenu.sh"
. "$UZBL_UTIL_DIR/uzbl-dir.sh"
TAG=`cat $file | cut -d" " -f2 | sort -u | $DMENU -nb \#303030 -nf khaki -sb \#CCFFAA -sf \#303030`
goto=`grep $TAG $file | cut -d" " -f1,3- | while read url name; do [ -z "\$name" ] || name="\$name "; echo "\$name: $url"; done | $DMENU $COLORS | cut -d":" -f2-`
[ -n "$goto" ] && echo "uri $goto" > "$UZBL_FIFO"
Le contrôle+L de Firefox
- Emplacement :
@scripts_dir/prompt_url.sh
- Bind :
@cbind <Ctrl>l = spawn @scripts_dir/prompt_url.sh
#!/bin/sh
goto=$(zenity --entry --text "$UZBL_TITLE" --entry-text "$UZBL_URI" --title "$UZBL_TITLE")
if [ $? -eq 0 ]; then
echo "uri $goto" > "$UZBL_FIFO"
fi
Le contrôle+K de Firefox
- Emplacement :
@scripts_dir/prompt_search.sh
- Bind :
@cbind <Ctrl>k = spawn @scripts_dir/prompt_search.sh
#!/bin/sh
search=$(zenity --entry --text "Effectuer une recherche" --entry-text "" --title "UZBL : Effectuer une recherche")
if [ $? -eq 0 ]; then
echo "uri http://www.google.fr/search?q=$(echo "$search" | sed 's/ /%20/g')" > "$UZBL_FIFO"
fi
Gestion du zoom à la Firefox (contenu + conteneur)
Binds :
@cbind <Ctrl>i = js (function() { var event = document.createEvent('HTMLEvents'); event.initEvent('uzbl_zoom_in', true, true); document.dispatchEvent(event); } )();
@cbind <Ctrl><Shift>I = js (function() { var event = document.createEvent('HTMLEvents'); event.initEvent('uzbl_zoom_out', true, true); document.dispatchEvent(event); } )();
@cbind <Ctrl>à = js (function() { var event = document.createEvent('HTMLEvents'); event.initEvent('uzbl_zoom_init', true, true); document.dispatchEvent(event); } )();
@on_event LOAD_COMMIT script @scripts_dir/zoom.js
Dans @scripts_dir/zoom.js :
function get_cookie(name) {
var dc = document.cookie;
var prefix = name + '=';
var begin = dc.indexOf('; ' + prefix);
if (begin == -1) {
begin = dc.indexOf(prefix);
if (begin!= 0) {
return null;
}
}
else {
begin += 2;
}
var end = document.cookie.indexOf(';', begin);
if (end == -1) {
end = dc.length;
}
return unescape(dc.substring(begin + prefix.length, end));
}
var step = function()
{
return 0.1;
}
var get_body = function()
{
var body = document.getElementsByTagName('body');
return body ? body[0] : null;
}
var get_body_zoom = function()
{
return get_body().getAttribute('data-zoom') ? parseFloat(get_body().getAttribute('data-zoom')) : 1;
}
var set_body_zoom = function(zoom)
{
get_body().setAttribute('data-zoom', zoom);
get_body().style.zoom = zoom;
document.cookie='uzbl_zoom='+zoom+';path=/;expires=Tue, 2 Jun 2020 00:00:00 UTC;'
}
var zoom_in = function()
{
set_body_zoom(get_body_zoom() + step());
}
var zoom_out = function()
{
set_body_zoom(get_body_zoom() - step());
}
var zoom_init = function()
{
set_body_zoom(1);
}
var zoom_retrieve = function()
{
var zoom = get_cookie('uzbl_zoom');
if (zoom) {
set_body_zoom(zoom);
}
}
document.addEventListener('uzbl_zoom_in', zoom_in, true);
document.addEventListener('uzbl_zoom_out', zoom_out, true);
document.addEventListener('uzbl_zoom_init', zoom_init, true);
document.addEventListener('DOMContentLoaded', zoom_retrieve, true);
J'espère que ça vous sera utile :)
→ Par
Simon ,
Le
29/12/2012 à 14:29
Info Cet article a été posté il y a plus de 3 mois. Il est suceptible de contenir des informations outdated.
DebFlux est mon outil principal pour lire les différents flux RSS auxquels je souscris. Il fonctionne pas trop mal et me permet, quelque soit la machine sur laquelle je me trouve, de suivre l'actualité des sites internet qui m'intéressent. Il s'appuie sur BilboPlanet, un logiciel libre que je hack pour le sortir (un peu) de son objectif initial : gérer un planet.
Il me sert énormément mais je dois dire que cette nouvelle version me surprend, surtout d'un point de vue technique. En effet, les développeurs ont choisi de faire un peu d'objet, un peu de procédural et de coller par dessus un moteur de template un peu dépassé. Peut-être voulaient-ils se passer de la gestion du cache et la déléguer à ce moteur ? Ou bien est-ce un choix pour rendre plus simple la modification du rendu et de gérer plusieurs thèmes ? Je ne sais pas, mais je reste sur ma faim.
Mon objectif au travers de ce billet n'est pas descendre le boulot abattu puisque j'apprécie le service qu'il me rend. Cependant, il me paraît nécessaire d'élever une critique qui pourrait aider à son développement, surtout d'un point de vue communautaire.
Dans un premier temps, je regrette qu'il ne repose pas sur un framework. Il aurait été vraiment intéressant que derrière ce CMS, un outil tels que Symfony, CakePHP, Zend Framework ou CodeIgniter ait été utilisé. La raison est simple : les méthodes de développement auraient été standardisées et ce travail aurait permis une intégration plus simple dans d'autres plateformes. Demain je souhaite intégrer le moteur de gestion des flux sur une application et je devrai me coltiner la réécriture du BilboPlanet.
Le choix du moteur de template me dérange. J'ai déjà utilisé un tel outil et ma conclusion est simple : quand on doit polluer son code PHP de méthodes ou fonctions propres au moteur de template, alors il faut changer d'outil. La couche de rendu doit être dissociée de la gestion des données et coller des $core->tpl-> partout dans son code, ça craint : je ne connais pas Hyla et ça me gonfle de devoir lire sa documentation alors que je dois simplement modifier la récupération des données. Il aurait été judicieux de travailler avec des méthodes proches de celles de Symfony : on a des données générées et stockées dans des tableaux simples (array) et le moteur de rendu pourra s'appuyer sur ce qu'il veut : PHP, Twig ou n'importe quoi d'autres. Qui plus est, ça facilite grandement l'intégration du code à l'intérieur d'autres projets.
D'un point de vue sécurité, j'aurais également apprécié d'avoir un grain de sel qui se paramètre à l'installation ou dans un fichier de conf. Avec la gestion de base, on peut brute forcer sans problème puisque qu'on connaît la clé définie en dure dans l'appel de la méthode de hash.
Enfin, pourquoi éparpiller les fonctions un peu partout dans le code ? C'est quand même intéressant de retrouver ses billes quand on connaît les répertoires où elles sont déclarées. Dans le code actuel, il y a un répertoire lib/ mais des fonctions sont écrites un peu partout ailleurs, typiquement l'index de l'administration. Heureusement que ctags est performant !
C'est le genre de projet qui mérite de recevoir des contributions et en ce qui me concerne, c'est le seul qui me convient pour gérer mes flux. Mais de mon point de vue, c'est une réécriture complète à faire.
Que faire ? Est-ce que je vais passer pour un élitiste après m'avoir lu, ou un gros con qui fait chier son monde car on ne fait pas comme il aime ? Faut-il forker ou bien contribuer en faisant un gros pull request avec moultes modifications ? No idea.
→ Par
Simon ,
Le
26/11/2012 à 14:54
Info Cet article a été posté il y a plus de 3 mois. Il est suceptible de contenir des informations outdated.
Je suis devenu un vrai fan du gestionnaire de fenêtres i3wm et pour cause, il est ultra simple à scripter :)
Jusqu'à aujourd'hui une fonctionnalité majeure me manquait : pouvoir naviguer vers le workspace qui précède ou qui suit celui courant. On peut switcher entre les deux derniers workspaces qui ont été focused ou se déplacer directement vers un workspace (pour autant qu'un mapping soit prévu).
Pour arriver à combler ce manque, j'ai utilisé i3-msg qui permet de récupérer des informations sur i3wm et de lui donner des instructions. Je script en php car il faut lire du json...et en shell c'est compliqué !
L'algo est simple :
- je récupère les workspaces avec :
i3-msg -t get_workspaces
- je les ordonne par ordre alphabétique (c'est comme ça que i3 les affiche)
- je récupère le workspace courant
- suivant ce qu'on demande, je retourne le workspace qui précède ou suit le workspace courant
- je demande à i3 de switcher vers le workspace via :
i3-msg 'workspace "le nom du workspace cible"'
Le script est disponible ici. Placez-le où vous voulez et renseignez un mapping tel que celui-ci (dans ~/.i3/config) :
bindsym $mod+p exec ~/bin/i3_switch_workspace.php previous
bindsym $mod+n exec ~/bin/i3_switch_workspace.php next
Note : dans ce mapping, mes raccourcis sont window+P pour aller au workspace précédant et window+N pour aller au suivant. Mon script se trouve dans ~/bin/ et le fichier est nommé i3_switch_workspace.php.
N'oubliez pas de rendre le script exécutable (chmod +x).