PDF et ligne de commande - Génération d'image pour iDevices


26 août 2013

Notes en vrac

#GHOSTSCRIPT (à intégrer à mon futur post)
#Sources utilisées pour convertir comme il faut un PDF en image
#http://stackoverflow.com/questions/7446552/resizing-a-pdf-using-ghostscript
#http://svn.ghostscript.com/ghostscript/tags/ghostscript-9.01/doc/Devices.htm#PNG
#http://www.ghostscript.com/doc/9.06/Use.htm
#Un iPad : 2048*1536 pixels, 264 pixels par inch, 9.7 inch de diagonale = 7.757*5.818 inches = 558.504 * 418.896 points
#Pour générer une image de 2048 (Z=1) :
#gs -sDEVICE=png16m -dNOPAUSE -dBATCH -dSAFER -sOutputFile=test1024.png -r264 -dDEVICEWIDTHPOINTS=558.504 -dDEVICEHEIGHTPOINTS=418.896 -dPDFFitPage source/67-batifile-CEBI-17-N0-PL-MIS-CVC-01-K.pdf
#Pour générer une image de 4096 (Z=2) :
#gs -sDEVICE=png16m -dNOPAUSE -dBATCH -dSAFER -sOutputFile=test2048.png -r528 -dDEVICEWIDTHPOINTS=558.504 -dDEVICEHEIGHTPOINTS=418.896 -dPDFFitPage source/67-batifile-CEBI-17-N0-PL-MIS-CVC-01-K.pdf
#for i in tiff12nc tiff24nc tiff32nc tiff48nc tiff64nc tiffcrle tiffg3 tiffg32d tiffg4 tiffgray tifflzw tiffpack tiffscaled tiffsep; do echo $i; gs -sDEVICE=$i -dNOPAUSE -dBATCH -dSAFER -sOutputFile=p300-$i.tif -r300x300 67-batifile-CEBI-17-N0-PL-MIS-CVC-01-K.pdf; done

SQL : conversion de vidéos du format WMV au format MP4


13 juin 2013
./configure --prefix=<ffmpegInstall> --enable-libx264 --enable-gpl --enable-libmp3lame
make
make install
ffmpeg -i input.wmv -c:v libx264 -crf 23 -c:a libmp3lame -q:a 100 output.mp4
http://superuser.com/questions/73529/how-to-convert-wmv-to-mp4 http://ffmpeg.org/ffmpeg.html

Utiliser Bash (et PHP) pour se faciliter la vie


23 mars 2013

Pour lire le manga Shamo depuis le site KissManga en utilisant son terminal à bon escient voici un petit script PHP :

#!/usr/bin/php -q
<?
if (array_key_exists(2, $_SERVER["argv"]))      {
    $TitleURL = $_SERVER["argv"][2];
    preg_match("@(http://[^/]+)@", $TitleURL, $Matches);
    $RootURL = $Matches[1];
}   else    $RootURL = false;

$Contents = file_get_contents("php://stdin");

//Analyse de la page principale du manga : on en déduit le nom du volume et la page spécifique du volume contenant toutes ses images
if ($_SERVER["argv"][1] == "--main")        preg_match_all('@<a\s+href="([^"]*)" title="Read[^"]+online">([^<]*)</a>@is', $Contents, $Matches);
//Analyse de la page d'un volume donné : on en déduit toutes les URLs des images du volume
if ($_SERVER["argv"][1] == "--volume")      preg_match_all('@lstImages\.push\("([^"]+)"\)@', $Contents, $Matches);

foreach($Matches[1] as $i=>$U)      echo $RootURL === false ? "$U\n" : "$RootURL$U|".trim($Matches[2][$i])."\n";

?>

Pour l'utiliser, du Bash sympathique :

MangaURL='http://kissmanga.com/Manga/Shamo'; MangaDir="shamo"; which wget && dlout='wget -qO -' && dlhead='wget --spider -qS 2>&1' && dlfile='wget -qO'; which curl && dlout='curl -s' && dlhead='curl -sI' && dlfile='curl -s -o'; $dlout "$MangaURL" | ./kissmanga --main "$MangaURL" | while read f; do URL=$(echo $f | awk -F '|' '{print $1}'); Folder=$(echo $f | awk -F '|' '{print $2}'); echo $Folder; mkdir -p "$MangaDir/$Folder"; i=-1; $dlout "$URL" | ./kissmanga --volume | while read img; do ((i++)); echo -n $i" : "$img; ImgType=$($dlhead "$img" | grep 'Content-Type:' | awk -F ':' '{print $2}'); Ext=${ImgType#*/}; PicName=$MangaDir/$Folder/$(printf %03d $i).$Ext; [[ -f $PicName ]] && echo " : existe" && continue; $dlfile "$PicName" "$img"; echo " : ok"; done; done

Et au final on obtient en moins de 20 minutes 5722 images correctement nommées et classées en 20 dossiers.

Ce script est compatible Linux et OSX.

Le script commenté est accessible et donc téléchargeable.

Minification de fichiers JavaScript


19 février 2013

Le problème

Considérant un dossier de fichiers JS dont un sous-ensemble est quotidiennement modifié, le problème de leur minification se pose : je veux que ces fichiers minimisés puissent être générés automatiquement en utilisant yui-compressor (pour l'instant). En Bash, ça donne :

find . -maxdepth 1 -name "*js" | while read f; do
    [[ `stat -c %Y minified/${f%.js}-min.js` -gt `stat -c %Y $f` ]] && continue;
    echo $f
    yui-compressor --type js --charset utf-8 -v -o minified/${f%.js}-min.js $f;
done 2> minified.log

Le meilleur compresseur

Même si le script précédent fonctionne, YUI-Compressor n'est pas terrible (ou je ne sais pas l'utiliser). Je vais donc m'orienter vers le Google Closure Compiler qui est plus lent à l'exécution (10x) mais BEAUCOUP plus intéressant. A noter que l'on peut utiliser deux modes pour ce minificateur : le mode par défaut (sans option particulière) et le mode ADVANCED_OPTIMIZATIONS, qui donne des résultats très intéressants. Par contre, le code à minimiser/obfusquer doit être adapté. Ainsi, pour utiliser le mode ADVANCED_OPTIMIZATIONS et obtenir ainsi des scripts extrêmement petits et obfusqués, il faut :

  • ajouter, selon le format jsDoc, le fait qu'une fonction est un constructeur : ainsi, elle pourra utiliser "this" sans warning de la part de Google Closure. D'autres types d'annotations sont disponibles.
  • ajouter window["MonConstructeur"] = MonConstructeur;
  • si le code utilise un hash externe il faut utiliser la notation des tableaux a.["nom-du-membre"] plutôt que la notation objet : a.nomDuMembre
  • on n'écrit PLUS JAMAIS :
    MonObjet.prototype = { ... }; MonObjet.prototype.constructor = MonObjet;
    mais on va déclarer une par une toutes les propriétés d'un objet, aussi bien les méthodes que les variables comme indiqué par les 4 points suivants
  • pour les fonctions publiques :
    MonObjet.prototype["NomDeLaFonctionPublique"] = function(...) { ... Corps de la fonction publique ... };
  • pour les fonctions privées :
    MonObjet.prototype.NomDeLaFonctionPrivée = function(...) { ... Corps de la fonction privée ... };
  • pour les variables publiques :
    MonObjet.prototype["NomDeLaVariablePublique"] = ...;
  • pour les variables privées :
    MonObjet.prototype.NomDeLaVariablePrivée = ...;

L'appel au compilateur/minificateur, installé dans mon répertoire utilisateur, se fait avec la ligne ci-dessous, avec $f contenant le chemin du fichier JS à compresser :
java -jar ~/closure/compiler.jar --charset UTF-8 --compilation_level ADVANCED_OPTIMIZATIONS --js "$f" --js_output_file ${f%.js}-min.js

Résultats

...

Droits harmonieux des fichiers d'un serveur


4 novembre 2012

Pour disposer d'un dépôt de fichier possèdant des droit pas trop laxistes et pas trop restrictifs, j'utilise INotify sur mes serveurs web. �a permet de ne pas tout mettre en root (si, si, j'en connais beaucoup qui font ça) et de ne pas tout mettre en 0777 (�a c'est pour Magento et ses problèmes de droits imbéciles). Pour mettre ça en place, il suffit d'utiliser INotify et d'exécuter le script qui suit et tout est magique :)

#!/bin/bash

(inotifywait -mqr --format "%w%f" --excludei ".*\.log" -e create /home/www |
        while read item; do
                echo "$item";
                DirName=`dirname "$item"`;
                #Tous les éléments fils de /home/www doivent avoir www-data comme propriétaire (Apache) et www-coder comme groupe ou le groupe du dossier parent
                ParentGroup=`stat -c '%G' "$DirName"`
                chown www-data:$ParentGroup "$item";
                #
                chmod 0460 "$item";
                #
                [[ -d "$item" ]] && chmod ug+x "$item";
                #Si le dossier parent possède un droit en écriture pour le propriétaire, alors on règle le même droit pour le nouveau fichier (dossiers d'uploads, logs etc)
                IsParentFolderWritable=`stat -c '%A' "$DirName" | cut -c 3`;
                [[ $IsParentFolderWritable == "w" ]] && chmod u+w "$item";
        done
) &

Le résultat ? Dès qu'un fichier est créé dans un (sous-)dossier quelconque de mon espace regroupant tous mes sites web, il possède automatiquement les droits 460. Pour un dossier ça sera 570. Le propriétaire est toujours www-data (L'utilisateur exécutant Apache) et le groupe est toujours www-coder. Ainsi si l'utilisateur crée un fichier avec un touch ou à l'aide d'un IDE comme Kate ou Coda et que cet utilisateur fait partie du groupe www-coder, toutes les opérations sont transparentes et il n'aura pas besoin de faire le moindre chmod/chown. Liberté...

�a n'est pas tout : par défaut Apache ne peut pas modifier un nouveau fichier et ne peut pas non plus créer quoi que ce soit dans un nouveau dossier (le propriétaire, Apache, peut juste lire l'élément). C'est important car ça évite beaucoup de problèmes). Que faire si on a un dossier "upload" dans lequel Apache doit pouvoir écrire des choses ? Il suffit de faire un chmod u+w sur ce dossier et tous les fichiers/dossiers qui seront créés disposeront également de ce droit. Magique je vous dit :)

L'étape d'après est que chaque site sous /home/www puisse avoir un groupe différent et que chaque dossier/fichier créé à l'intérieur au lieu d'être affecté à www-data:www-coder puisse être affecté au groupe de son parent. Ainsi, chaque fichier continuera d'avoir pour propriétaire www-data mais aura codersite1 ou codersite2 comme groupe. La granularité est (?) optimale.

Faire la suite avec ma nouvelle version :
#!/bin/bash

killCommand()       {
    kill $INotifyPID
    rm -f $PipePath
    exit
}

handleItem()        {
    item=$1
    echo "$item";
    DirName=`dirname "$item"`;
    #Tous les éléments fils de /home/www doivent avoir www-data comme propriétaire (Apache) et www-coder comme gro ou le groupe du dossier parent
    ParentGroup=`stat -c '%G' "$DirName"`
    chown www-data:$ParentGroup "$item";
    #
    chmod 0460 "$item";
    #
    [[ -d "$item" ]] && chmod ug+x "$item";
    #Si le dossier parent possède un droit en écriture pour le propriétaire, alors on règle le même droit pour le nouveau fichier
    IsParentFolderWritable=`stat -c '%A' "$DirName" | cut -c 3`;
    [[ $IsParentFolderWritable == "w" ]] && chmod u+w "$item";
}

PipePath="/tmp/adjustWWW.pipe"
mkfifo $PipePath

inotifywait -mqr --format "%w%f" --excludei ".*\.log" -e create,close_write /home/www > $PipePath &
INotifyPID=$!
trap "killCommand" 2 3 15

while read item; do
    handleItem $item &
done < $PipePath

killCommand
Source : http://kerlinux.org/2010/08/utilisation-de-inotifywait-dans-des-scripts-shell/
Accueil1 2 3 4 5 6 7 8