Sébastien

Sébastien

Un docx, c'est quoi ?

Aujourd'hui, j'ai tenté de ressortir des méta données, avec PHP, des fichiers Office, tous aux formal XML. Pour ceux qui l'ignorent, tous les fichiers de la suite Office se terminant par un X sont un "nouveau" format (plutôt le dernier format, car il n'a pas loin de 10 ans !) de la suite Office. En formation, j'avais entendu dire que ce fichier n'était ni plus ni moins qu'un fichier XML à la "sauce" Microsoft. Oui,... enfin presque !

Cet article relate la manière de faire pour aboutir à mes fins. Nous verrons pourquoi je n'ai pas pu le faire. L'idée, tout comme l'article de la semaine dernière, etait bien d'extraire des méta-données de ces fichiers, pour les afficher sur la page du fichier de ma GED, GED propulsée par Joomla.

Dans un premier temps, je me suis posé la question "un docx, c'est quoi ?" et je n'ai pas mis lontemps à comprendre : un docx, c'est ni plus ni moins qu'un ensemble de fichiers, compressé au format... zip.

-"A ouais, alors je peux l'ouvrir avec un dézippeur ?"
-"Bah wai !"

dezippeur

On a déja fait un grand pas. Mais maintenant, y'a quoi dans cette archive et surtout y'a-t-il des méta données ?

Et les méta-données ?

Je ne vais pas vous cacher que comme ce n'est que cette partie là qui m'interessait, je ne suis pas allé voir le reste du zip, du docx. Et c'est plutôt pas trop mal fait (je ne vais pas encenser non plus un format propriétaire !)

Vous voyez le dossier docsProp ?

  • Non achetez des lunettes.
  • Oui, ouvrez le !

Vous avez à l'intérieur deux fichiers dans un format "standard", si l'on en croit l'extension de fichier : XML ! Ouvrons le dans un (vrai) navigateur (qui lui sait afficher correctement un XML)

arbreXML

 

Interessant tout ca, surtout qu'un XML, ca se parse facilement ! Et les méta données, du coup je peux les récupérer....

Oui... mais non !

Jusque là, content de ma découverte, je me suis dis, y'a pu qu'a parser. Et quand on tient un blog sur lees API du web, parser un fichier XML, ca reste dans mes cordes. Sauf que...

Sauf que, on l'a vu en début d'article, un .docx est un fichier ZIP. Et pour dézipper un .zip en PHP, il faut des bibliothèques compatibles php 7.2. Or je ne travaille pas (en local, je précise !) sur cette version de PHP, je n'ai jamais fait la mise à jour et reste sur un version 2. Aller je blague mais je suis sur un PHP 5.2, du coup, je n'ai pas accès à la bibliothèque ZipArchive, une biliothèque PHP de travaux sur des ZIP) pour aller, par programmation, dézipper mon fichier docx (ca fait drôle d'écrire cà !) . Ce qui explique que ca ne fonctionne pas. Il faudrait que j'essaie de faire une mise à jour du paquet PHP de ma distrib pour aller + loin dans mon travail.

Mais pas plus. Mais si je trouve une bibliothèque php5 pour faire ca...

ffmpeg -streamloop -1 -i input.gif -i audio.mp3 -vf crop=" + width + " + height + 0:40,scale=1280:720,setsar=1,format=yuv420p -shortest -fflags +shortest -maxinterleave_delta 100M -movflags +faststart output.mp4

  • -shortest : boucle la durée du temps des deux éléments en choissisant celui le plus court
  • crop : redécoupe la video
  • scale : mise à l'échelle
  • format : spécifie le format de sortie
  • -maxinterleave_delta : Définit la durée maximale de mise en mémoire tampon pour l'entrelacement. La durée est exprimée en microsecondes et est définie par défaut sur 1000000 (1 seconde).
  • -movflags +faststart : Ecrit une "particule" initiale directement au début du fichier, sans décrire les échantillons qu'il contient. 

Aujourd'hui je vais vous présenter un besoin que j'ai eu dans un cadre professionnel. Je dois récupérer des métadonnées de fichiers, tous au format PDF, afin de les afficher sur la page web sur laquelle ce propre fichier PDF est téléchargeable. Voyons comment je me suis pris pour réaliser cette prouesse.

Dans un premier temps, j'ai créé un fichier PDF avec un outil de type générateur de PDF. La suite LibreOffice permet notamment de le faire, mais d'autres outils  professionnels comme Adobe PDF Reader (!) permettent aussi de le faire.
Partons du principe que vous possédez un fichier PDF dont l'intégralité des métadonnées sont remplies.
La première question que je me suis posée et très simple : peut-on rajouter ses propres champs personnalisés dans les métadonnées d'un PDF ?
Pour l'instant, la sa réponse que j'ai trouvé est malheureusement négative. Cependant, j'avoue n'avoir pas trop chercher car mon objectif peut-être largement atteint avec l'ensemble des chamsp étant déjà à ma disposition dans le format PDF par défaut.

PDF propriete

 
Pour récupérer l'intégralité des métadonnées d'un fichier PDF, j'ai dans un premier temps, ouvert un fichier PDF dont je savais il contenait des métadonnées. J'ai ouvert ce fichier avec un lecteur PDF classique pour vérifier que ces metadatas était bien présents, puis j'ai réouvert ce même fichier dans un simple éditeur de texte.
PDF sous kate
 
Ainsi, voilà comment je m'y suis pris : j'ai chargé l'intégralité du fichier PDF, grâce à la fonction file en PHP, qui permet de stocker dans une variable globale, au format texte bien entendu, l'intégralité du PDF.
Dans un deuxième temps, je parcours l'ensemble du fichier stocké dans mon tableau, (car la fonction file stocke le résultat de la lecture du fichier dans un tableau ! ) afin de détecter une chaîne de caractères "xmpmeta". Vous n'aurez donc désormais compris, le format PDF intègre des données au format XMP. Sans vouloir faire un cours exhaustif sur ce type de format, vous retrouverez une documentation sur Wikipédia, ce format intègre ou format XML, des métadonnées propre au fichier PDF. Le format été créé par Adobe en 2001 et intégré à partir de la version 5 d'Acrobat. Or, comme ce format est basé sur XML, forcément en ouvrant un fichier PDF, les données apparaissent "en clair" afin, notamment, de pouvoir être exportées.
Ainsi, en revenant à mon code, je parcour l'ensemble du tableau chargé à partir du texte brut formant mon fichier PDF, à la recherche de la chaîne de caractère XMP méta, ligne à ligne. Si une ligne comporte à la fois la chaîne de caractère XMP méta, ainsi que la chaîne je recherche, commençant toujours par <XMP et se terminant de la même manière, il suffit au moyen d'une petite fonction d'extraction, fonction que je vous mets dans le code ci-dessous, extraire le contenu chargé entre les deux balises.
Il ne nous vous reste plus qu'à afficher d'une manière relativement propre, et de la manière que vous souhaitez, les informations que vous venez d'extraire. Dans mon cas elles sont dans des DIV, afin de pouvoir leur appliquer un style CSS, décrit en début de fichier.

<?PHP
$lines = file('Sans titre_1.pdf');

function everythingintags($string, $tagname)
{
$pattern = "#<\s?$tagname\b[^>]>(.?)</$tagname\b[^>]>#s";
preg_match($pattern, $string, $matches);
return $matches[1];
}

foreach ($lines as $line_num => $line) {

if (strpos($line, "xmpmeta") !== false )
{
$a=$line;
}

}

function extractString($string, $start, $end) {
$string = " ".$string;
$ini = strpos($string, $start);
if ($ini == 0) return "";
$ini += strlen($start);
$len = strpos($string, $end, $ini) - $ini;
return substr($string, $ini, $len);
}

$string = filegetcontents('Sans titre_1.pdf');
echo '<div style="width:900px;height:180px;border:2px solid black;box-shadow: 20px 20px 20px lightgreen;font-size:70%;">';
echo '<div style="background-color:yellow;font-weight:bold;width:100%;text-align:center;">Propriétés du fichier</div>';
echo '<div style="width:25%;background-color:#ffe8e9;float:left;">Date de modification : </div><div style="background-color:#ffe8e9;width:100%;">'.date("d M Y, H:m:s",strtotime(extractString($string, '<xmp:ModifyDate>', '</xmp:ModifyDate>')))."</div>";
echo '<div style="width:25%;background-color: #e7f9dd;float:left;">Date de création : </div><div style="background-color: #e7f9dd;width:100%;">'.date("d M Y, H:m:s",strtotime(extractString($string, '<xmp:CreateDate>', '</xmp:CreateDate>')))."</div>";
echo '<div style="width:25%;background-color:#ffe8e9;float:left;">Générateur du PDF : </div><div style="background-color:#ffe8e9;width:100%;">'.extractString($string, '<xmp:CreatorTool>', '</xmp:CreatorTool>')."</div>";
echo '<div style="width:25%;background-color: #e7f9dd;float:left;">Identifiant du PDF : </div><div style="background-color: #e7f9dd;width:100%;">'.extractString($string, '<xmpMM:DocumentID>', '</xmpMM:DocumentID>')."</div>";
echo '<div style="width:25%;background-color:#ffe8e9;float:left;">ID de l\'instance du PDF : </div><div style="background-color:#ffe8e9;width:100%;">'.extractString($string, '<xmpMM:InstanceID>', '</xmpMM:InstanceID>')."</div>";
echo '<div style="width:25%;background-color: #e7f9dd;float:left;">ID de l\'auteur du PDF : </div><div style="background-color: #e7f9dd;width:100%;">'.extractString($string, '<rdf:li>', '</rdf:li>')."</div>";
echo '<div style="width:25%;background-color:#ffe8e9;float:left;">Titre du PDF :</div><div style="background-color:#ffe8e9;width:100%;">'.extractString($string, '<rdf:li xml:lang="x-default">', '</rdf:li>')."</div>";
echo '<div style="width:25%;background-color: #e7f9dd;float:left;">Sujet du PDF : </div><div style="background-color: #e7f9dd;width:100%;">'.extractString($string, '<rdf:Alt><rdf:li xml:lang="x-default">', '</rdf:li></rdf:Alt>')."</div>";
echo '<div style="width:25%;background-color:#ffe8e9;float:left;">Mots cles du PDF : </div><div style="width:100%;background-color:#ffe8e9;">'.extractString($string, '<rdf:Bag><rdf:li>', '</rdf:li></rdf:Bag>')."</div>";

echo '<div style="width:25%;background-color: #e7f9dd;float:left;">Producteur du PDF : </div><div style="background-color: #e7f9dd;width:100%;">'.extractString($string, '<pdf:Producer>', '</pdf:Producer>')."</div>";

echo '<div style="width:25%;background-color:#ffe8e9;float:left;">Date d\'écriture des métadata du PDF : </div><div style="width:100%;background-color:#ffe8e9;">'.date("d M Y, H:m:s",strtotime(extractString($string, '<xmp:MetadataDate>', '</xmp:MetadataDate>')))."</div>";
echo "</div>";
?>

 
samedi, 17 octobre 2020 17:16

Augmenter le gamma d'une video

ffmpeg -i leo.mp4 -vf "split [main][tmp]; [tmp] lutyuv=y=gammaval(0.6) [tmp2]; [main][tmp2] overlay" leo88.avi

Avec l'avènement des réseaux sociaux, sur Internet, nous avons tous des dizaines d'amis ou d'amis virtuels que nous ne connaissons pas forcément, dans tous nos réseaux sociaux que ce soit Facebook, Instagram ou d'autres sites internet.
Tout le monde n'a pas les mêmes finalités des utilisations de ces sites "sociaux", d'aucuns les utilise essentiellement pour rencontrer du monde, se créer des groupes d'amis virtuel, échanger des idées via les groupes comme sur Facebook là où d'autres utilisent les réseaux sociaux pour garder des contacts. Aujourd'hui nous allons nous pencher sur le site Internet http://searchusers.com dont la finalité est... de trouver des utilisateurs des réseaux sociaux, mais aussi de "calculer" leur "notoriété sociale" si l'on peut dire.
En effet, les recherches sont effectuées sur Facebook, Instagram et peut-être d'autres plateformes j'aurais zappé. Tout commence par effectuer une recherche sur un utilisateur (son pseudonyme) potentiellement présent sur un réseau social. Vous pouvez effectuer cette recherche en saisissant son nom ou son pseudonyme.
À l'issue de cette recherche, le site vous retourne un ensemble de résultats, avec éventuellement des photographies associées à l'utilisateur ainsi qu'un cadenas ou pas, selon que le profil est public ou pas. Dans la mesure où la recherche est aussi effectuée sur Instagram, vous avez parfois à l'ensemble des photos reliées à l'utilisateur Instagram.
 
searchusers
Mais qui vois-je ?
 
Notons au passage que cette recherche ne se fait pas sur la chaîne de caractères exacte que vous avez saisi dans le champ prévu à cet effet, mais il utilise la chaîne que vous avez saisi comme une sous-chaîne. Si vous tapez Nanc, vous risquez de vous retrouver avec toutes les femmes prénommées Nancy. Les photographies de profil sont affichées dans les résultats de la recherche et vous pouvez désormais sélectionner l'utilisateur de votre choix si vous (re)connaissez son visage.
Pour le profil que vous avez choisi, le site internet vous retourne le nombre de posts, le nombre de like ainsi que le nombre de commentaires effectués sur chacun de ses derniers posts.
APol1
 
Pour ce même utilisateur que vous avez sélectionné, le site vous retourne aussi l'ensemble des dernières photographies postées sur l'ensemble des réseaux sociaux reliés à son compte, compte trouvé à partir de la chaîne de caractères que vous avez saisie en guise de pseudonyme.
Dans le même esprit, afin de mesurer le "poids social" de cet utilisateur, le site internet retourne les tops user mentions, mais vous retourne aussi la photographie préférée de ses followers, les photographies les plus visualisées ainsi que les dernières photographies regardées par ce dit utilisateur.
Enfin, le site internet vous propose aussi un ensemble d'utilisateurs similaires à celui que vous avez sélectionné. Ce que l'histoire ne dit pas, c'est comment cette sélection est effectuée...
 
 
 
 
 
 
 
 
 
 
lundi, 05 octobre 2020 12:48

Pister l'historique Firefox

A l'époque où je fûs animateur multimédia, géranr un pôle multimédia, la plus grande crainte de notre structuré, une bibliothèque, était les dérives qu'un espace publique multimédia pouuvait avoir, notamment la visualisation d'images qui ne doivent pas se montrer en publique, et encore moinsd avec des publics mineurs. A l'époque, où le net était en trait de se développer, il n'existait pas de "logiciel de contrôl parental.

Sans ce type de logiciel, j'ai voulu voir comment faire parler un historique de navigation. j'ai choisis le navigateur Firefox. Ce dernier utilise une base de données SQLite pour enregistrer toutes les données que ce dernier peut avoir besoin ; historique, bookmarks, préférences.... Ici nous allons faire parler l'historique.

Dans vorte home (Linux/mac) ou dans votre répertoire utilisateur dans Windows, nous avez un dossier caché .mozilla (oui oui il commence par un point puisqque c'sst un dossier caché, norme linux) qui comporte par mal de données. Dans ce dossier, vous aller retrouver tous les profils déclérés dans votre navigateur. En général, rare sont ceux qui déclarent plusieurs profills mais on peut le faire. Allez dans le répertoire du profil vous interessant, si vous n'en avez pas déclarer, allez dans le dossier qui comporte la chaine "default".

La,  vous allez retrouver le fichiers places.sqlite. Vous pouvez en faire une copie, et l'ouvrri avec https://sqlitebrowser.org/ ou encore avec https://sqliteonline.com/ (attention, on ne sais pas si les datas sont gardées ou pas). Importez sur ce site le fichiers de vos données et vérifiez que vous avez bien l'historique.

Une fois cetre confirmation effectuée, maintenant que vous être sûr que ce fichier est rempli, nous allons voir comment scrippter les choses pour exploiter ces données facilement. Je me base cette fois-ci sir Linux, mais je pense que c'est tres facilement adaptable sur d'autres OS. Pour ce faire, commencez par installer sqlite 3.

La commande suivante est asez facile à comprendre mais je vais toutefois la commenter :

sqlite3 -header -csv /home/sebastien/.mozilla/firefox/default/places.sqlite "select p.url,h.visitdate from mozhistoryvisits as h, mozplaces as p where substr(h.visitdate, 0, 11) >= strftime('%s', date('now')) and p.id == h.placeid order by h.visitdate;">liste.txt

Cette commande permet d'exporter en CSV le fichiers d'historique (places.sqlite), en selectionnant l'URL, la date de visite de la table mozhistoryvisits. L'ensemble des résultats sera exporté dans le fichiers liste.txt trié par date. La restriction permet de sortir les dates de visites supérieures ou égales à la date du jour, la deuxieme restriction n'étant qu'une simple jointure entre dex tables. Le résultat sera stocké dans liste..txt.

 

 

Une petite brève un tout petit article aujourd'hui sur un site internet que j'ai découvert un peu par hasard je dois le dire.
Ayant un besoin assez particulier, suivre un flux RSS (jusqu'à y a rien de très spécial) mais je souhaitais trouver un outil qui puisse me filtrer certains éléments du flux RSS, selon des critères qui me sont propres.
Parmi les principaux critères que je souhaitais trouver, c'est notamment la possibilité de trier sur le contenu ou le titre d'un élément du flux RSS, à savoir si ce dernier contient ou non une information, et en fonction de ce contenu, générer un deuxième flux RSS qui va contenir les informations essentielles à ce que je souhaite suivre. En d'autres termes, mon deuxième RSS généré, va afficher certaines informations ou non, selon des règles de tri que je lui donne. 
Après une brève recherche sur le moteur de recherche Google, je suis tombé sur le site internet siftrss.com, qui correspond exactement à ma recherche. Pour les plus pointilleux d'entre vous, cet outil prend même en compte l'utilisation de regex, mais vous pouvez donner les critères de recherche relativement simples et qui finalement remplissent, dans mon cas, contrat.
siftrss
 
Après avoir saisi ou copier-coller de votre flux RSS dans le premier champ, vous allez pouvoir spécifier si, dans votre recherche, vous recherchez des items avec ou sans les critères évoqués ci-après. C'est le concept include/exclude proposé comme premier critère de votre filtre de tri.
Le deuxième critère que vous allez remplir sur ce site, c'est l'endroit sur lequel vous souhaitez que le tri soit effectué. Vous pouvez faire une recherche sur le titre des éléments du fil RSS, mais encore sur la description ou le lien fourni dans le flux.
Le troisième critère que vous devez remplir, vous permet de spécifier si vous souhaitez que votre chaîne recherchée, que vous allez remplir dans le dernier champ que nous n'avons encore pas vu, doit contenir ou non cette chaîne, doit correspondre à un regex particulier ou non, doit exister ou enfin de doit pas exister.
Et pour finir bien entendu, vous devez spécifier la chaîne de caractère devant remplir les conditions énoncées ci-dessus.
Il ne vous reste plus qu'à valider votre filtre en cliquant sur le bouton "Feed me!", de manière à ce que l'outil siftrss vous retourne une nouvelle URL de votre  fil RSS prenant en compte les critères que vous venez de spécifier.
Ce que j'aime particulièrement dans cet outil, pour celle de ceux qui comprennent et qui savent utiliser les regex, c'est justement la possibilité de leur utilisation, vous permettant de faire ainsi des recherches très spécifiques dont les fils RSS que vous pouvez suivre.
 
 
 

Dans cet article, je veux montrer à des fins non seulement de démonstration, mais aussi pour aider une tierce personne qui ne me l'a pas demandé mais qui je suis sûr se reconnaitra, comment utiliser le site internet OpenStreetMap afin de pouvoir récupérer sous la forme d'un ensemble cohérent de données, dans un format standard que vous pourrez choisir, un ensemble d'éléments répondant à une requête (ou plutôt une géorequête ?) particulière.
Je prends comme exemple son besoin, à savoir comment récupérer une liste des commerces, ou plutôt des petits commerces, que l'on peut trouver dans la ville de Nancy. La réponse est simple : il suffit donc d'interroger les données intégrées à OpenStreetMap de la manière suivante.

En allant sur le site http://overpass-turbo.eu, vous avez la possibilité de récupérer ces informations. Une fois votre navigateur positionné sur le site dont je vous ai donné l'URL, positionnez la carte de vous avez sur votre droite, grosso-modo sur la région que vous souhaitez interroger, on zoomant et en dezoomant la carte sous vos yeux.
Une fois la définition de votre zone géographique marquée par ce rectangle dans lequel vous avez toute votre carte affichée, dans la partie gauche collez le code que je vous donne ci- dessous :

[out:json][timeout:25]; // gather results ( // query part for: “Magasin” node["shop"]({{bbox}}); way["shop"]({{bbox}}); relation["shop"]({{bbox}}); ); // print results out body; >; out skel qt;

Remarquez dans ce code que vous avez il y a possibilité de changer le mot "shop" (il se trouve entre les crochets), par d'autres termes que vous retrouverez en suivant l'adresse que je vous donne :

https://nominatim.org/release-docs/latest/api/Search/

Une fois ce code collé, cliquez sur le bouton "exécuter". Ici un ensemble de magasins s'affiche sur votre carte.
Mais vous allez me dire, "que puis-je faire d'une carte comme ceci ? ".
Et bien l'exporter pardi !

Mais pas exporter la carte qui ne serait pas intégralement exploitable, mais bien exporter l'ensemble des données qu'elle contient !
Pour cela sur la barre horizontale située en haut de votre écran, cliquez sur le terme exporter (vous devez être dans l'onglet données). Toutefois vous pouvez remarquer que la requette que vous allez générer sur open Street Map, vous pouvez l'enregistrer pour la rejouer ultérieurement. Parenthèse fermée, lancez votre requête dans le but de pouvoir exporter les résultats renvoyés.
L'ensemble des résultats s'affiche sur votre carte de droite, sous la forme de petits points colorés, il ne vous reste plus qu'à en exporter ses données.

OSM

Pour le faire, cliquez sur le bouton exporter en haut dans la barre des actions. Une fenêtre modale s'ouvre, afin de vous proposer le format dans lequel l'export doit être effectué. Ce format vous est proposé dans l'onglet données. Choisissez votre format en cliquant sur le lien télécharger. Notez que, si vous êtes amené à relancer ultérieurement cette même requête, sélectionnez le dernier onglet tout en bas requête, vous pourrez ainsi récupérer la requête générée dans le but de la sauvegarder pour la rejouer ultérieurement. Je vous conseille de la stocker dans un petit fichier texte sur votre machine ou dans le cloud
Vous avez donc plusieurs formats qui vous sont proposés, malheureusement le format texte brut ne l'est pas. Mais vous pouvez exporter vous donnez au format JSON, format suffisamment standard pour pouvoir être ultérieurement réexploité par n'importe quel outil de développement. Vous pouvez aussi récupérer ces données au format KML voire GeoJson.

Si vous êtes amené à ré-importer ces mêmes données dans une autre carte de celle proposée par OpenStreetMap, vous pourrez le faire. Je vous laisse bien entendu le choix de regarder les autres options comme export de votre carte au format PNG, c'est-à-dire sous la forme d'une image, ou d'intégrer votre carte dans un format dynamique que vous pourrez par la suite réintégrer à votre propre site web.

vendredi, 25 septembre 2020 13:44

Radiograbber avec Zenity

INPUT=$(yad --title="Grabber la radio" --form --field="URL:TXT" --field="Fichiersortie:TXT") && CHAMPS1=$(echo "$INPUT" |cut -d'|' -f1) && CHAMPS2=$(echo "$INPUT" |cut -d'|' -f2) && LIGNE=$(ffmpeg -i "$CHAMPS1" -af silenceremove=stopperiods=-1:stopduration=1:stopthreshold=-30dB "$CHAMPS2")

Radiograbber

Page 1 sur 36