.:Bordel-de-Nerd:.

Bref, j’ai fait un script en Bash

closeCet article a été publié il y a 1 an 4 mois 22 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.

Comme beaucoup de monde, j’apprécie la mini série Bref diffusée par Canal.

Sur le site officiel il n’y a pas de flux rss afin de savoir quand un nouvel épisode est diffusé, j’ai donc décidé d’en construire un à l’aide de Bash.

Vous trouverez ci-dessous le code du script qui permet de générer le flux rss et pouvez télécharger la dernière version en cliquant sur ce lien.:

#!/bin/bash
# -*- coding: UTF8 -*-
 
# Définir l'URL du flux
url="http://www.exemple.fr/feed"
 
# On télécharge le xml qui contient les adresses rtmp 
wget -O xmlresult http://service.canal-plus.com/video/rest/search/cplus/Bref%20episodes > /dev/null 2>&1
 
# On efface les balises CDATA
sed -i -e 's/!\[CDATA\[//g' -e 's/\]\]//g' xmlresult 
 
# On déclare une fonction pour lire le DOM
lire_dom () {
	local IFS=\>
	read -d \< ENTITY CONTENT
}
 
# On commence à créer le flux RSS format XML
(
cat <<'EOF'
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Flux RSS Bref.</title>
        <description>flux RSS 2.0 de la série Canal Bref.</description>
EOF
) > bref.xml
 
# On renseigne la date de création, l'url du flux etc...
echo -e "\t\t<link>$url</link>\n" >> bref.xml
# -R -> date au format RFC 2822
echo -e "\t\t<lastBuildDate>$(date -R)</lastBuildDate>\n" >> bref.xml
echo -e "\t\t<generator>$(bash --version | grep version | head -n1)</generator>\n" >> bref.xml
 
# On continue d'alimenter notre fichier XML avec les items
while lire_dom; do
	if [[ $ENTITY = "HEURE" ]]; then
		HEURE=$CONTENT
	elif [[ $ENTITY = "DATE" ]]; then
		tDATE=$CONTENT
		tDATE=`echo $tDATE | sed -E 's|(..)/(..)/(....)|\2/\1/\3|'`
		tDATE="$tDATE $HEURE"
		DATE=`date -d "$tDATE" -R`
		echo -e "\t\t<item>\n\t\t\t<pubDate>$DATE</pubDate>"
	elif [[ $ENTITY = "ID" ]]; then
		ID=$CONTENT
	elif [[ $ENTITY == Bref.* ]]; then
      TITRE=${ENTITY//.}
	elif [[ $ENTITY == Episode*du* ]]; then
		STITRE=$ENTITY
	   echo -e "\t\t\t<link>http://www.canalplus.fr/c-divertissement/pid3848-c-bref.html?vid=$ID</link>"
      echo -e "\t\t\t<title>$STITRE : $TITRE</title>"
	elif [[ $ENTITY = "BAS_DEBIT" ]]; then
		echo -e "\t\t\t<description>\n\t\t\t\t<![CDATA[\n<i>Pour lire la vidéo vous pouvez, au choix, cliquer sur le titre de l'épisode pour vous rendre sur le site officiel ou utiliser votre lecteur vidéo préféré ( VLC, mplayer...) avec l'adresse rtmp.</i><br><br>\n\t\t\t\t<b>Bas débit:</b> $CONTENT <br>\n"
	elif [[ $ENTITY = "HAUT_DEBIT" ]]; then
		echo -e "\t\t\t\t<b>Haut débit:</b> $CONTENT <br>\n"
	elif [[ $ENTITY = "HD" ]]; then
		echo -e "\t\t\t\t<b>Haute définition:</b> $CONTENT \n\t\t\t\t]]>\n\t\t\t</description>\n\t\t</item>\n"
		echo -e "Télécharger : [[ ! -f \"${TITRE}.mp4\" ]] && rtmpdump -r $CONTENT -o \"${TITRE}.mp4\""
	else
		continue
	fi 
done < xmlresult >> bref.xml
 
(
cat <<'EOF'
    </channel>
</rss>
EOF
) >> bref.xml
 
# On efface le fichier temporaire
rm -f xmlresult
 
# On conserve uniquement les ligne qui contiennent "Télécharger" pour commencer un script de téléchargement
cat bref.xml | grep Télécharger | sed 's/Télécharger : //' > telecharger.sh
cat bref.xml | grep -v Télécharger > bref.txt
mv -f bref.txt bref.xml
 
# On termine notre script de téléchargement avec la conversion du conteneur flash en conteneur mp4 avec mencodeur
echo 'for i in *.mp4; do [[ `file -bi "$i" | cut -d";" -f1` = "video/x-flv" ]] && mencoder "$i" -o "${i/.mp4/.ok.mp4}" -oac mp3lame -ovc copy -of lavf -lavcopts vcodec=mp4; done' >> telecharger.sh
echo 'for i in *.ok.mp4; do mv "$i" "${i/.ok.mp4/.mp4}";done' >> telecharger.sh
 
# on le rend exécutable
chmod +x telecharger.sh
 
# On affiche un message pour indiquer que c'est terminé
echo "fichiers bref.xml et telecharger.sh créés"

Le code est commenté et comme vous pouvez le constater, on commence par créer un flux rss 2.0 qui contient les adresses rtmp des vidéos (lisibles en streaming avec vlc, mplayer etc…) et ensuite on construit également un script telecharger.sh qu’il suffira d’exécuter afin de télécharger les épisodes en hd (il faut installer rtmpdump disponible à cette adresse pour qu’il fonctionne et mencoder pour changer le conteneur flv des vid# -R -> date au format RFC 2822éos en mp4).

Il y a juste un léger problème avec le service de canal qui ne renvoie pas les vidéos par date de diffusion ( il renvoie en premier un épisode diffusé le 14/10/2011).

J’ai donc cherché une solution pour trier le flux rss par date.

La solution que j’ai retenu est d’appliquer une transformation xslt sur le flux xml pour le trier à l’aide de l’exemple disponible ici

Pour appliquer cette transformation xslt en Bash, j’utilise l’outil xsltproc fourni par la libxslt disponible ici.

Voici donc une version du script qui permet d’obtenir un flux rss trié par date de diffusion.

#!/bin/bash
# -*- coding: UTF8 -*-
 
# Définir l'URL du flux
url="http://www.exemple.fr/feed"
 
# On télécharge le xml qui contient les adresses rtmp 
wget -O xmlresult http://service.canal-plus.com/video/rest/search/cplus/Bref%20episodes > /dev/null 2>&1
 
# On efface les balises CDATA
sed -i -e 's/!\[CDATA\[//g' -e 's/\]\]//g' xmlresult 
 
# On déclare une fonction pour lire le DOM
lire_dom () {
	local IFS=\>
	read -d \< ENTITY CONTENT
}
 
# On commence à créer le flux RSS format XML
(
cat <<'EOF'
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Flux RSS Bref.</title>
        <description>flux RSS 2.0 de la série Canal Bref.</description>
EOF
) > bref.xml
 
# On renseigne la date de création, l'url du flux etc...
echo -e "\t\t<link>$url</link>\n" >> bref.xml
# -R -> date au format RFC 2822
echo -e "\t\t<lastBuildDate>$(date -R)</lastBuildDate>\n" >> bref.xml
echo -e "\t\t<generator>$(bash --version | grep version | head -n1)</generator>\n" >> bref.xml
 
# On continue d'alimenter notre fichier XML avec les items
while lire_dom; do
	if [[ $ENTITY = "HEURE" ]]; then
		HEURE=$CONTENT
	elif [[ $ENTITY = "DATE" ]]; then
		tDATE=$CONTENT
		tDATE=`echo $tDATE | sed -E 's|(..)/(..)/(....)|\2/\1/\3|'`
		tDATE="$tDATE $HEURE"
		DATE=`date -d "$tDATE" -R`
		echo -e "\t\t<item>\n\t\t\t<pubDate>$DATE</pubDate>"
	elif [[ $ENTITY = "ID" ]]; then
		ID=$CONTENT
	elif [[ $ENTITY == Bref.* ]]; then
      TITRE=${ENTITY//.}
	elif [[ $ENTITY == Episode*du* ]]; then
		STITRE=$ENTITY
	   echo -e "\t\t\t<link>http://www.canalplus.fr/c-divertissement/pid3848-c-bref.html?vid=$ID</link>"
      echo -e "\t\t\t<title>$STITRE : $TITRE</title>"
	elif [[ $ENTITY = "BAS_DEBIT" ]]; then
		echo -e "\t\t\t<description>\n\t\t\t\t<![CDATA[\n<i>Pour lire la vidéo vous pouvez, au choix, cliquer sur le titre de l'épisode pour vous rendre sur le site officiel ou utiliser votre lecteur vidéo préféré ( VLC, mplayer...) avec l'adresse rtmp.</i><br><br>\n\t\t\t\t<b>Bas débit:</b> $CONTENT <br>\n"
	elif [[ $ENTITY = "HAUT_DEBIT" ]]; then
		echo -e "\t\t\t\t<b>Haut débit:</b> $CONTENT <br>\n"
	elif [[ $ENTITY = "HD" ]]; then
		echo -e "\t\t\t\t<b>Haute définition:</b> $CONTENT \n\t\t\t\t]]>\n\t\t\t</description>\n\t\t</item>\n"
		echo -e "Télécharger : [[ ! -f \"${TITRE}.mp4\" ]] && rtmpdump -r $CONTENT -o \"${TITRE}.mp4\""
	else
		continue
	fi 
done < xmlresult >> bref.xml
 
(
cat <<'EOF'
    </channel>
</rss>
EOF
) >> bref.xml
 
# On efface le fichier temporaire
rm -f xmlresult
 
# On conserve uniquement les ligne qui contiennent "Télécharger" pour commencer un script de téléchargement
cat bref.xml | grep Télécharger | sed 's/Télécharger : //' > telecharger.sh
cat bref.xml | grep -v Télécharger > bref.txt
mv -f bref.txt bref.xml
 
# On termine notre script de téléchargement avec la conversion du conteneur flash en conteneur mp4 avec mencodeur
echo 'for i in *.mp4; do [[ `file -bi "$i" | cut -d";" -f1` = "video/x-flv" ]] && mencoder "$i" -o "${i/.mp4/.ok.mp4}" -oac mp3lame -ovc copy -of lavf -lavcopts vcodec=mp4; done' >> telecharger.sh
echo 'for i in *.ok.mp4; do mv "$i" "${i/.ok.mp4/.mp4}";done' >> telecharger.sh
 
# on le rend exécutable
chmod +x telecharger.sh
 
# trier par date en appliquant une transformation xslt
 
(
cat <<'EOF'
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 
  <xsl:variable name="vrtfMonths">
    <m name="Jan" num="01"/>
    <m name="Feb" num="02"/>
    <m name="Mar" num="03"/>
    <m name="Apr" num="04"/>
    <m name="May" num="05"/>
    <m name="Jun" num="06"/>
    <m name="Jul" num="07"/>
    <m name="Aug" num="08"/>
    <m name="Sep" num="09"/>
    <m name="Oct" num="10"/>
    <m name="Nov" num="11"/>
    <m name="Dec" num="12"/>
  </xsl:variable>
 
  <xsl:variable name="vMonths" select=
   "document('')/*/xsl:variable
                   [@name='vrtfMonths']/*"
   />
 
    <xsl:template match="channel">
      <xsl:for-each select="item">
        <xsl:sort data-type="number" order="descending" select=
        "concat(substring(pubDate,13,4),
                $vMonths[@name 
                        = 
                         substring(current()/pubDate,9,3)]/@num,
 
                substring(pubDate,6,2),
                translate(substring(pubDate,18,8),
                          ':',
                          ''
                          )
                )
         "/>
 
         <xsl:if test="not(position() > 40)">
           <xsl:copy-of select="."/>
 
         </xsl:if>
      </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
 
EOF
)> bref.xsl
 
# appliquer la transformation avec xsltproc
ITEM=`xsltproc bref.xsl bref.xml`
 
# On efface le fichier xsl
rm -f bref.xsl
 
# on commence à créer le flux RSS format XML
(
cat <<'EOF'
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Flux RSS Bref.</title>
        <description>flux RSS 2.0 de la série Canal Bref.</description>
EOF
) > bref.xml
 
# On renseigne la date de création, l'url du flux etc...
echo -e "\t\t<link>$url</link>\n" >> bref.xml
echo -e "\t\t<lastBuildDate>$(date -R)</lastBuildDate>\n" >> bref.xml
echo -e "\t\t<generator>$(bash --version | grep version | head -n1)</generator>\n" >> bref.xml
 
 
echo $ITEM >> bref.xml
 
 
(
cat <<'EOF'
    </channel>
</rss>
EOF
) >> bref.xml
 
# On affiche un message pour indiquer que c'est terminé
echo "fichiers bref.xml et telecharger.sh créés"

Pour finir il nous reste à créer une tâche planifiée dans cron pour mettre à jour le flux rss chaque heure par exemple :

Sauvegardez le script sous le nom bref.sh puis rendez le exécutable :

chmod +x bref.sh

Ouvrez la crontab

crontab -e

Ajoutez la ligne suivante

0 * * * * bash /chemin/vers/bref.sh

Vous pouvez vous rendre à cette adresse pour voir le résultat ou cliquer sur ce lien pour télécharger directement le script.

4 Responses to Bref, j’ai fait un script en Bash

  1. @David @Nicolas merci pour vos commentaires.

    J’en ai fait une version pour « Pépites sur le Net » et il faut en effet modifier que très peu de choses.

    Ça serait même assez simple de faire une version de ce script qui prendrait comme argument le nom de la mini série et … bref ça fonctionnerait !

  2. Pour les deux derniers épisodes j’ai l’impression que l’url utilisée dans le script pour rechercher les épisodes ne fonctionne plus : http://service.canal-plus.com/video/rest/search/cplus/Bref

    Du coup dès que j’ai deux minutes je vais modifier le code pour parser directement la page web principal.

    Voici le début du code :

    curl -vs http://www.canalplus.fr/c-divertissement/pid3848-c-bref.html 2>&1 | \
    iconv --from-code=ISO-8859-1 --to-code=UTF-8 | \
    sed -n '/contenuOnglet/,/Page Suivante/p' | \
    sed -n -e '/alt=/p' -e '/Episode/p' -e '/<a href=".*vid=/p' | \
    sed -e 's|.*<a href="\(.*\)" onclick.*|\1|'  -e 's|.*alt="\(.*\)" widt.*|\1|' -e 's|.*\(Episode.*/..\).*|\1|' | \
    sed '/<img/d' | \
    awk ' !x[$0]++' > SORTIE.txt

    Si quelqu’un a une autre idée, merci de laisser un commentaire.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Get Adobe Flash player