BaroqueW

BaroqueW

and his sidekick nikkitaa

BaroqueW RSS Feed
 
 
 
 

Archive for Articles en français

News from the site | Des nouvelles du site

Vous l’avez peut-être remarqué, il y a eu quelques changements sur le site, des additions surtout :

  • sur votre gauche, vers le haut : mes derniers status tirés de ping.fm / Twitter
  • sur votre droite, en bas : la liste de nos prêts sur Kiva, le site de micro-crédit pour les pays en voie de développement
  • sur certains articles désormais : géolocalisation ! En cadeau bonus, sur la liste des articles en Français, la carte de localisation de tous les articles ! (enfin, de tous ceux qui valent la peine d’être localisés…)

In English after the break…

More »

  • Share/Save/Bookmark
Category: Articles en français, Articles in English, Blog | Leave a comment

Latex – Autres astuces

Voici quelques snipets de LaTeX basé sur mon rapport de stage / Master.

Pour faire cadres et avoir un fond en couleur

Pour avoir un cadre autour de votre texte, un peu de la même manière que pour afficher le code sur ce site :

\begin{figure}[htb!]
\centering
\fcolorbox{black0}{graylight}{\parbox{1\textwidth}{
\paragraph{}
A concrete example in our case would be to retrieve all the URIs watched by the client with the URI "sip:cz@iptel.org". This can be done with the following XPath query: \texttt{//service[@uri="sip:cz@iptel.org"]//entry/@uri}. This would also work in the case there are multiple \texttt{list} elements associated to the URI "sip:cz@iptel.org".
}}
\caption{The XPath query language}\label{fig:XCAPquery}
\end{figure}

Tableaux

\begin{table}[htb!]
\caption{Improvements and their level of implementation}\label{table:3lvl}
\begin{center}
\begin{tabular}{|c|c|c|c|}
\hline
Improvement  \ Level & JBoss Server & Configuration & Asterisk \\
\hline
\hline
Call control & X & & X \\
\hline
External SIP proxy support & & X & X \\
\hline
H.323 support & X & X & X \\
\hline
Statistics & X & & X \\
\hline
Non-human user detection & & & X \\
\hline
\end{tabular}
\end{center}
\end{table}

Pour ajouter des éléments dans la table des matières

Par exemple, pour ajouter la bibliographie à la table des matières :

\usepackage[nottoc]{tocbibind}

Pour faire des chapitres non-numérotés mais présents dans la table des matières :

\chapter*{Acknowledgments}\label{section:ack}\addcontentsline{toc}{chapter}{Acknowledgments}

Utiliser verbatimtab

Pour afficher du texte, tel quel :

\begin{figure}[p]
\begin{verbatimtab}
<?xml version="1.0" encoding="UTF-8"?>
<rls-services>
        <service uri="sip:smith-list@iptel.org">
                <resource-list>http://localhost/xcap-root/resource-lists/users/smith/
resource-list.xml/~~/resource-lists/list[@name=\%22default\%22]
                </resource-list>
                <packages>
                        <package>presence</package>
                </packages>
        </service>
        <service uri="sip:cz@iptel.org">
                <list name="czech iptel">
                        <entry uri="sip:abc@iptel.org">
                                <display-name>A B</display-name>
                        </entry>
                        <entry uri="sip:cde@iptel.org">
                                <display-name>C D</display-name>
                        </entry>
                        <entry uri="sip:efg@iptel.org">
                                <display-name>Ef Ge</display-name>
                        </entry>
                </list>
                <packages>
                        <package>presence</package>
                        <package>email</package>
                </packages>
        </service>
</rls-services>
\end{verbatimtab}
\centering%
\caption{Example of RLS services document~\cite{presencehandbook}}
\label{fig:rlsdoc}
\end{figure}

Résumé en plusieurs langues

Parfois, vous voulez faire un résumé (abstract) en plusieurs langues, pour ce faire vous pouvez utiliser le code ci-dessous :

\usepackage[swedish,french,english]{babel}

\selectlanguage{english}
\begin{abstract}
\paragraph{}
The increased use of computer networks has lead to the adoption of Internet-based solutions for reducing telephony costs. This has proved a boon to callers who can reach the other party directly via the Internet. Unfortunately numerous business person still need to call to and from mobile phones which are currently a domain where the customers are generally tightly bound to their operators. To provide a simple solution to this problem, Opticall AB has designed an integrated system called the Dial over Data (DoD) solution, coupling a mobile interface with an Asterisk PBX and a GSM gateway, which allows calls to be originated remotely at the best price, exploiting the company’s existing network. This scheme allows the company to easily control telecommunications costs and to monitor of their employees’ efficiency.

\end{abstract}

\selectlanguage{swedish}
\begin{abstract}
Den nuvarande ökningen av datanätverk har lett till adoptionen av Internetbaserade lösningar för att
förminskar kostnader inom telefoni. Tyvärr behöver åtskilliga affärsmän fortfarande ringa till och ifrån
mobiler som återstår som ett område där kunderna är fastkedjade till deras operatörer. För att tillföra en
enkel lösning till detta problem har Opticall AB planlagt ett integrerat system som kallas den DoD
servern som kopplar ihop ett mobilt gränssnitt, med en Asterisk PABX\glossary{[PABX] Private Automatic Branch eXchange, synonym with PBX} och en GSM förmedlingsnod, som tillåter telefonsamtal påbörjas avlägset på det billigaste priset tack vare företagets nätverk. Det ger möjligheten till företaget att  vara centralt för sina personals kommunikationer. Det medger ett enkelt sätt att kontrollera kostnader samt övervaka personalens effektivitet.

\end{abstract}

\selectlanguage{french}
\begin{abstract}
L’omniprésence des réseaux informatiques aujourd’hui a pour effet de pousser de plus en plus à l’adoption de solutions en ligne pour réduire les coûts liés à la téléphonie. Malheureusement de nombreux hommes d’affaires doivent toujours appeler vers et depuis des téléphones portables, qui, pourtant, demeurent un domaine où les clients sont étroitement dépendants des opérateurs. Afin de fournir une solution à ce problème, Opticall AB a conçu un système intégré appelé le Dial over Data Server, comprenant une interface mobile à un  PABX Asterisk et une passerelle GSM, qui permet à des appels d’être lancés à distance au meilleur prix en utilisant le réseau de l’entreprise. Un tel dispositif place l’entreprise aux centres des communications de ses employés en permanence. Ceci permet un meilleur contrôle des coûts et une surveillance centralisée de l’activité des employés.

\end{abstract}

Accolades géantes

Pour mettre une belle portion de votre texte entre accolades, et pas seulement sur une ligne : notez que ce snippet comporte aussi le “cadre couleur” évoqué plus haut

\begin{figure}[htb!]
\centering
\fcolorbox{black0}{gray1}{
The administrator $\left\{\begin{tabular}{m{4.2in}}
has access to full settings through a dedicated Web interface. Timeout periods, dialplan contexts, and the number of conferences simultaneously allowed can be adjusted to suit the needs of the company. Users and operators can also be managed via this interface.\\
\\
The manager $\left\{\begin{tabular}{m{3.2in}}
has access to detailed statistics for each user as both raw values and graphs, to allow monitoring of user activity. The manager can also access aggregated values per day, week, or month for each user.\\
\\
The user $\left\{\begin{tabular}{m{2.4in}}
can place calls and manage their contacts. He or she can also access a small subset of the statistics concerning her.
                        \end{tabular}\right.$
                \end{tabular}\right.$
           \end{tabular}\right.$
}
\caption{Access level model for the DoD interface}\label{fig:modelauth}
\end{figure}

Le secret réside dans le

$\left\{\begin{tabular}{m{4.2in}} \\ xxx \\.

Mes headers

Pour la bonne bouche, voilà tous mes includes et définitions en tête de document :

\documentclass[10pt,a4paper,onecolumn, openright]{report}
\usepackage[applemac]{inputenc}
\usepackage[swedish,french,english]{babel}
\author{Max Weltz}
\title{Dial over Data solution}

\usepackage[left=1.5in, right=1in, top=1in, bottom=1in, includefoot, headheight=13.6pt]{geometry}

\usepackage{multirow}
\usepackage{listings}
\usepackage{graphics}
\usepackage{footmisc}
\usepackage{verbatim}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage[left]{eurosym}
\usepackage{array}
\usepackage{xy}
\usepackage{url}
\usepackage{afterpage}
\usepackage{float}
\restylefloat{figure}
\usepackage{moreverb}
\usepackage{algorithm}
\usepackage{algorithmic}
\usepackage{subfigure}
\usepackage{color}
\definecolor{gray1}{gray}{0.5}
\definecolor{graylight}{gray}{0.7}
\definecolor{black0}{gray}{0}
\setlength{\fboxrule}{1pt}%
\setlength{\fboxsep}{10pt}%

\makeglossary

\usepackage[nottoc]{tocbibind}%ajouter une entrée bibliographique à la table des matières %

\usepackage{graphicx}

\newcommand{\footnoteremember}[2]{\footnote{#2}\newcounter{#1}\setcounter{#1}{\value{footnote}}}\newcommand{\footnoterecall}[1]{\footnotemark[\value{#1}]}

\newcommand{\montitre}{\Huge Dial over Data solution}

\hyphenpenalty=5000
\tolerance=1000

\usepackage{hyperref}
\pdfcompresslevel=9
\hypersetup{
colorlinks=true, %colorise les liens
breaklinks=true, %permet le retour à la ligne dans les liens trop longs
urlcolor= blue,  %couleur des hyperliens
linkcolor= blue, %couleur des liens internes
anchorcolor = blue,
citecolor = blue,
filecolor = blue,
pagecolor = blue,
pdftitle={Dial over Data solution}, %informations apparaissant dans
pdfauthor={Max Weltz}    %dans les informations du document sous Acrobat.
}

  • Share/Save/Bookmark
Category: Articles en français, Tech >> Computer | Leave a comment

MeteoqueW – Script TCL pour eggdrop

En complément à mon article précédent, voici le script TCL MeteoqueW pour eggdrop qui permet d’afficher la mété des villes françaises dans votre salon (ou en privé) :

Merci de ne pas faire de copier/coller avec le code ci-dessous. J’ai dû modifier le code pour qu’il s’affiche proprement.

# MeteoqueW[IRC] 1.2
# Cree le 09/04/2006
# Modifie la derniere fois le 05/01/2009
# !meteo affiche la meteo sur [endroit par défaut]
# !meteo XXXX affiche la meteo pour la ville/code postal
# !aide affiche l’aide
#
# by BaroqueW
#
# 0.1 : affichage températures, prévisions, fonction de recherche "un seul mot"
# 0.2 : ajout de l’aide, gestion des villes inconnues, gestion des noms de ville avec apastrophe et espaces
# 0.3 : fonction de recherche multi mots avec gestion des "-[]()’ et autres espaces, ajout du dtcmode, ajout du mode debug
# 1.0 : mise-à-jour du script ‘future-proof’. Toutes les requêtes sont désormais faites par le site www.baroquew.info
#       pour éviter d’avoir à modifier un large nombre d’installations à chaque fois que Meteo France change son format de données
# 1.1 : possibilité de personnaliser le message d’aide en fonction de l’endroit par défaut
# 1.2 : possibilité pour les utilisateurs de définir leur propre niveau de détail (configurable par l’admin)

package require http

bind pub – !meteo pub:meteo
bind pub – !aide pub:aide

#0 n’affiche pas l’aide sur !aide et !help, 1 affiche l’aide
set affiche_aide 1

#0 pas de message spécifique sur !meteo XXX (XXX appartenant à dtcmatches), 1 mode cdtc (ie on répond dtcmessage à !meteo XXX)
set dtcmode 1
set dtcmessage "Il fait chaud et humide dtc !"
set dtcmatches {"dtc" "dans ton cul"}

#choisir où sera affichée la meteo
#1 -> sera affiché sur cette fenetre, 0 -> ne sera pas affiché sur cette fenetre
set chanpublic 1
set notice 0
set query 0

#choisir le niveau de verbosité
#2 -> affiche tout, 1 -> n’affiche pas les vents, 0 -> n’affiche pas les vents, ni la météo détaillée
set verbosity 1

#pour laisser choisir les utilisateurs leur niveau de verbosité
set freeverbosity 1

#code par défaut du lieu renvoyé par !meteo
#et nom du lieu pour le message d’aide
#75013/Paris XIIIème par défaut
set IDDefault "75013"
set nomvilledefaut "Paris XIIIème"

#1 -> affiche les print de debug, 0 -> ne les affiche pas
set debug 0

#NE RIEN MODIFIER EN DESSOUS DE CETTE LIGNE!

set agent "Mozilla"

if { ($freeverbosity == 1) } {
        bind pub – !meteo0 pub:meteo0
        bind pub – !meteo1 pub:meteo1
        bind pub – !meteo2 pub:meteo2
}

proc print { nick channel message} {
        global chanpublic
        global notice
        global query   

        if { ($chanpublic == 1) &amp;&amp; ($query == 0) &amp;&amp; ($notice == 0) } {
        putserv "PRIVMSG $channel :$message"
        } elseif { ($chanpublic == 0) &amp;&amp; ($query == 1) &amp;&amp; ($notice == 0) } {
        putserv "PRIVMSG $nick :$message"
        } elseif { ($chanpublic == 0) &amp;&amp; ($query == 0) &amp;&amp; ($notice == 1) } {
        putserv "NOTICE $nick :$message"
        }

}

proc printdebug { nick channel message} {
        global chanpublic
        global notice
        global query
        global debug

if {($debug == 1)} {
        if { ($chanpublic == 1) &amp;&amp; ($query == 0) &amp;&amp; ($notice == 0) } {
        putserv "PRIVMSG $channel :$message"
        } elseif { ($chanpublic == 0) &amp;&amp; ($query == 1) &amp;&amp; ($notice == 0) } {
        putserv "PRIVMSG $nick :$message"
        } elseif { ($chanpublic == 0) &amp;&amp; ($query == 0) &amp;&amp; ($notice == 1) } {
        putserv "NOTICE $nick :$message"
        }
 }
}

proc pub:aide { nick uhost handle channel arg } {
        global affiche_aide
        global nomvilledefaut
        global freeverbosity
        global verbosity

        if { ($affiche_aide == 1) } {
        print $nick $channel "!meteo pour avoir la météo sur $nomvilledefaut"
        print $nick $channel "!meteo code_postal ou !meteo ville pour rechercher la météo d’un autre endroit"
        print $nick $channel "Données fournies par Meteo France (http://www.meteofrance.com)"
        if { ($freeverbosity == 1) } {
                print $nick $channel "Utilisez !meteo0 pour avoir la météo abrégée"
                print $nick $channel "Utilisez !meteo1 pour avoir la météo détaillée"
                print $nick $channel "Utilisez !meteo2 pour avoir la météo détaillée avec les vents"
                print $nick $channel "Par défaut, !meteo affiche la météo comme !meteo$verbosity"
        }
        }
}

proc aplatir { vect } {

#si on a un code postal, pas de traitement
set first [lindex $vect 0]
set iscodepostal [regexp {[0-9][0-9][0-9][0-9][0-9]} $first codepostal]
 if {([llength vect] == 1) &amp;&amp; ($iscodepostal == 1)} {
        set aplat $first
   } else {

   #traitement standard

        set space "%20"

        #on merge tous les arguments avec des %20 entre chaque (ie un espace)
        set aplat [join $vect $space]

        #on vire tous les chiffres puisque ce n’est pas un code postal
        regsub -all {[0-9]} $aplat "" aplat

        #on vire tous les "- et les espaces et on met un %20 à leur place
        regsub -all {[ -]+} $aplat $space aplat

        #on remplace les apostrophes par leur code HTML (%27)
        regsub -all {\} $aplat "%27" aplat

        #au cas où, on vire les parenthèses, crochets et accolades et on les remplace par des espaces (%20)
        set setbrackets {\[|\]|\(|\)|\{|\}}
        regsub -all $setbrackets+ $aplat $space aplat

        #on supprime les "%20" à répétition
        set aplat [split $aplat $space]
        set buffer {}
        foreach word $aplat {
                if { ( $word != $space ) &amp;&amp; ( $word != "" ) } {
                        lappend buffer $word
                }
        }
        set aplat [join $buffer $space]
        #petite feinte
        regsub {%207} $aplat "%27" aplat
        }

        #dans tous les cas, on retourne aplat sans accents
        return [string map -nocase {
                "à" "a" "â" "a" "ä" "a"
                "é" "e" "è" "e" "ê" "e" "ë" "e"
                "î" "i" "ï" "i"
                "ô" "o" "ö" "o"
                "ù" "u" "û" "u" "ü" "u"
                "ç" "c" "ñ" "n" "ã" "a" "õ" "o"
        } $aplat]
}

proc pub:meteo { nick uhost handle channel arg } {
        global dtcmode
        global agent
        global IDDefault
        global dtcmessage
        global dtcmatches
        global verbosity

        set ID $IDDefault

        if {[llength $arg] == 0} {

        #par defaut : Paris Montsouris
                set query "http://www.baroquew.net/cgi-bin/meteo.cgi?ville=$ID&amp;v=$verbosity&amp;html=0"

                set token [::http::config -useragent $agent]
                set token [::http::geturl $query -timeout 3000]
                puts stderr ""
                set htmlFile [::http::data $token]
                set token [::http::cleanup $token]

                set result [split $htmlFile _]

                foreach i $result {
                        print $nick $channel $i
                }

        #si il y a des arguments
        } else {

                        #chercher la premiere ville correspondante
                        set ville [aplatir $arg]
                        printdebug $nick $channel $ville

                        #vérifier le dtc mode
                        regsub -all {%20} $ville " " villedtc
                        printdebug $nick $channel $villedtc

                        set dtctest [lsearch -exact $dtcmatches $villedtc]
                        if { ($dtctest >= 0) &amp;&amp; ($dtcmode == 1) } {
                        print $nick $channel $dtcmessage
                        } else {

                        set pagesearch [::http::config -useragent $agent]
                        set urlsearch "http://www.baroquew.net/cgi-bin/meteo.cgi?ville=$ville&amp;v=$verbosity&amp;html=0"
                        set token [::http::config -useragent $agent]
                        set token [::http::geturl $urlsearch]
                        puts stderr ""
                        set htmlFile [::http::data $token]
                        set token [::http::cleanup $token]

                        set result [split $htmlFile _]

                        foreach i $result {
                                print $nick $channel $i
                        }
  }
 }
}

proc pub:meteo0 { nick uhost handle channel arg } {
        global dtcmode
        global agent
        global IDDefault
        global dtcmessage
        global dtcmatches
        global verbosity

        set ID $IDDefault

        if {[llength $arg] == 0} {

        #par defaut : Paris Montsouris
                set query "http://www.baroquew.net/cgi-bin/meteo.cgi?ville=$ID&amp;v=0&amp;html=0"

                set token [::http::config -useragent $agent]
                set token [::http::geturl $query -timeout 3000]
                puts stderr ""
                set htmlFile [::http::data $token]
                set token [::http::cleanup $token]

                set result [split $htmlFile _]

                foreach i $result {
                        print $nick $channel $i
                }

        #si il y a des arguments
        } else {

                        #chercher la premiere ville correspondante
                        set ville [aplatir $arg]
                        printdebug $nick $channel $ville

                        #vérifier le dtc mode
                        regsub -all {%20} $ville " " villedtc
                        printdebug $nick $channel $villedtc

                        set dtctest [lsearch -exact $dtcmatches $villedtc]
                        if { ($dtctest >= 0) &amp;&amp; ($dtcmode == 1) } {
                        print $nick $channel $dtcmessage
                        } else {

                        set pagesearch [::http::config -useragent $agent]
                        set urlsearch "http://www.baroquew.net/cgi-bin/meteo.cgi?ville=$ville&amp;v=$verbosity&amp;html=0"
                        set token [::http::config -useragent $agent]
                        set token [::http::geturl $urlsearch]
                        puts stderr ""
                        set htmlFile [::http::data $token]
                        set token [::http::cleanup $token]

                        set result [split $htmlFile _]

                        foreach i $result {
                                print $nick $channel $i
                        }
  }
 }
}

proc pub:meteo1 { nick uhost handle channel arg } {
        global dtcmode
        global agent
        global IDDefault
        global dtcmessage
        global dtcmatches
        global verbosity

        set ID $IDDefault

        if {[llength $arg] == 0} {

        #par defaut : Paris Montsouris
                set query "http://www.baroquew.net/cgi-bin/meteo.cgi?ville=$ID&amp;v=1&amp;html=0"

                set token [::http::config -useragent $agent]
                set token [::http::geturl $query -timeout 3000]
                puts stderr ""
                set htmlFile [::http::data $token]
                set token [::http::cleanup $token]

                set result [split $htmlFile _]

                foreach i $result {
                        print $nick $channel $i
                }

        #si il y a des arguments
        } else {

                        #chercher la premiere ville correspondante
                        set ville [aplatir $arg]
                        printdebug $nick $channel $ville

                        #vérifier le dtc mode
                        regsub -all {%20} $ville " " villedtc
                        printdebug $nick $channel $villedtc

                        set dtctest [lsearch -exact $dtcmatches $villedtc]
                        if { ($dtctest >= 0) &amp;&amp; ($dtcmode == 1) } {
                        print $nick $channel $dtcmessage
                        } else {

                        set pagesearch [::http::config -useragent $agent]
                        set urlsearch "http://www.baroquew.net/cgi-bin/meteo.cgi?ville=$ville&amp;v=$verbosity&amp;html=0"
                        set token [::http::config -useragent $agent]
                        set token [::http::geturl $urlsearch]
                        puts stderr ""
                        set htmlFile [::http::data $token]
                        set token [::http::cleanup $token]

                        set result [split $htmlFile _]

                        foreach i $result {
                                print $nick $channel $i
                        }
  }
 }
}

proc pub:meteo2 { nick uhost handle channel arg } {
        global dtcmode
        global agent
        global IDDefault
        global dtcmessage
        global dtcmatches
        global verbosity

        set ID $IDDefault

        if {[llength $arg] == 0} {

        #par defaut : Paris Montsouris
                set query "http://www.baroquew.net/cgi-bin/meteo.cgi?ville=$ID&amp;v=2&amp;html=0"

                set token [::http::config -useragent $agent]
                set token [::http::geturl $query -timeout 3000]
                puts stderr ""
                set htmlFile [::http::data $token]
                set token [::http::cleanup $token]

                set result [split $htmlFile _]

                foreach i $result {
                        print $nick $channel $i
                }

        #si il y a des arguments
        } else {

                        #chercher la premiere ville correspondante
                        set ville [aplatir $arg]
                        printdebug $nick $channel $ville

                        #vérifier le dtc mode
                        regsub -all {%20} $ville " " villedtc
                        printdebug $nick $channel $villedtc

                        set dtctest [lsearch -exact $dtcmatches $villedtc]
                        if { ($dtctest >= 0) &amp;&amp; ($dtcmode == 1) } {
                        print $nick $channel $dtcmessage
                        } else {

                        set pagesearch [::http::config -useragent $agent]
                        set urlsearch "http://www.baroquew.net/cgi-bin/meteo.cgi?ville=$ville&amp;v=$verbosity&amp;html=0"
                        set token [::http::config -useragent $agent]
                        set token [::http::geturl $urlsearch]
                        puts stderr ""
                        set htmlFile [::http::data $token]
                        set token [::http::cleanup $token]

                        set result [split $htmlFile _]

                        foreach i $result {
                                print $nick $channel $i
                        }
  }
 }
}

putlog "MeteoqueW\[IRC\] 1.2 – LOADED!"

Notez les paramètres :

  • affiche_aide : 0 pour désactiver l’aide, 1 pour l’activer (trigger sur !aide)
  • dtcmode : 0 pour désactiver, 1 pour activer. Si le mode est activé, le bot répondra dtcmessage lorsqu’il sera interrogé sur la météo à un endroit listé dans dtcmatches
  • chanpublic, notice, query : 0/1 pour choisir où afficher les résultats
  • verbosity : 0/1/2 affichent respectivement les tendances du jour, les tendances ET la météo détaillée des jours à venir, les tendances ET la météo détaillée des jours à venir ET les vents (pour les villes qui bénéficient de ce genre d’informations
  • freeverbosity : 0/1 pour laisser les utilisateurs libres de choisir leur niveau de verbosité via les nouvelles commandes !meteo0, !meteo1, !meteo2
  • IDDefault : ville par défaut si !meteo est appelé sans argument
  • nomvilledefaut : nom de la ville par défaut affichée dans l’aide
  • debug : 0/1 pour activer les messages de debugging

Si vous utilisez ce script MeteoqueW, merci de me laisser un mot ! De même si vous décidez de le modifier, merci de toujours référer à mon site et de faire profiter tout le monde de vos modifications !

Creative Commons License
MeteoqueW by http://www.baroquew.info/wordpress/archives/meteoquew-script-tcl-pour-eggdrop is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.0 France License.
Based on a work at www.baroquew.info.

J’avoue avoir emprunté la table de mapping des lettres avec/sans accents au script “Motus” que vous pouvez trouver sur http://forum.egghelp.org/viewtopic.php?t=13665

  • Share/Save/Bookmark
Category: Articles en français, Tech >> Computer | Leave a comment

Météo en Ruby

Il y a quelque temps j’avais fait un script pour fournir des données météorologiques sur IRC (pour la France seulement). Malheureusement, le script a été rendu caduque par un changement du site Météo France sur lequel il se basait. En voici la nouvelle version.

Ce script remplace feu MeteoqueW (PHP et TCL) par une version Ruby, histoire de s’amuser, mais surtout histoire de fournir un serveur qui se chargera de traduire les pages Météo France en quelque chose de plus simple pour le nouveau script TCL (qui du coup n’aura plus besoin de télécharger et analyser les pages Web lui-même – thin client, nous voilà !). Le script TCL sera détaillé dans un autre article comme il sert seulement d’interface avec un eggdrop pour IRC.

Ci-dessous le code du script Ruby :

Notez que j’ai dû enlever les apostrophes des expressions régulières pour que le texte s’affiche proprement ci-dessous.

#!/usr/bin/ruby
# = Meteo CGI application
#
# Meteo CGI application, formerly MeteoqueW (PHP, TCL) provides a text version of Meteo France’s weather forecast for one specific location
#
# This location is passed in argument with the parameter ‘ville’ (HTTP GET)
# Other parameter is ‘html’ to display in HTML with line breaks or in plain text, lines being separated by _
# Last parameter is ‘verbosity’ (v) to display more or less information: 0 hides winds and detailed weather forecast, 1 show detailed weather
# forecast, 2 and above shows everything.

require ‘net/http’
require "cgi"
require ‘extend_string’
require ‘uri’

# UNICODE
$KCODE=‘u’

# Web server informations
$host = ‘france.meteofrance.com’
iphost = ‘160.92.186.20′
pathprefix = ‘/france/accueil/resultat?RECHERCHE_RESULTAT_PORTLET.path=rechercheresultat&amp;query=’
pathsuffix = ‘&amp;type=PREV_FRANCE&amp;satellite=france’

# Used if we do not find the city
$failure = false

# Class to store a resulting weather forecas
class Meteo
   attr_accessor :maindays, :times, :temperatures, :refreshsrc, :weathers, :winds, :windspeeds, :windpeaks, :location, :html

 # Found new time entry, let’s add it
 def add_time(object)
     object.gsub!("soiree", "soirée")
     object.gsub!("apres-midi", "après-midi")
     object.gsub!("aujourdhui", "Aujourd’hui")
     object.gsub!(‘  ’, ‘, ‘)
     @times.push(object)
 end

 # Found new mainday entry, let’s add it
 def add_mainday(object)
     @maindays.push(object)
 end

 # Found new temperatures entry, let’s add it
 def add_temperature(object)
     @temperatures.push(object)
 end

 # Found new weather entry, let’s add it
 def add_weather(object)
     object.gsub!("eparses", "éparses")
     object.gsub!("eclaircies", "éclaircies")
     object.gsub!("leger", "léger")
     @weathers.push(object)
 end

 # Found new wind entry, let’s add it
 def add_wind(object)
     @winds.push(object)
 end

 # Found new windpeak entry, let’s add it
 def add_windpeak(object)
     @windpeaks.push(object)
 end

 # Found new windspeed entry, let’s add it
 def add_windspeed(object)
     @windspeeds.push(object)
 end

 # Make sure to create the arrays
 # If html = 0 then no html output
 def initialize(html)
   @html = html
   @times = Array.new
   @weathers = Array.new
   @winds = Array.new
   @maindays = Array.new
   @windspeeds = Array.new
   @windpeaks = Array.new
   @temperatures = Array.new
 end

 # Format nicely the results
 def display (verbosity = 0)
   k = maindays.length

   # HTML display
   if html != ‘0′
     line = "<b><u>Météo à #{location}</u></b>"
     if verbosity.to_i > 0
       line += " (Actualisé à #{refreshsrc})"
     end
   puts "#{line}<br/><br/>"
   puts "<b>Tendances :</b><br/>"
    for x in (0..k-1)
      line = "#{maindays[x]} : #{weathers[x]} (#{temperatures[x]})"
      if verbosity.to_i > 1
        line += ", #{winds[x]}"
        if !windspeeds[x].include? "-"
          line += " à #{windspeeds[x]}"
        end
        if !windpeaks[x].include? "-"
            line += " avec des rafales à #{windpeaks[x]}"
          end
      end
    puts "#{line}<br/>"

    end
    if verbosity.to_i > 0
      puts "<br/><b>Météo détaillée :</b><br/>"
      for x in (k..k + times.length1)
        line = "#{times[x-k]} : #{weathers[x]} (#{temperatures[x]})"
        if verbosity.to_i > 1
          line += ", #{winds[x]}"
        end
      puts "#{line}<br/>"
      end
    end
   # Plain text display
   else
       line = "Météo à #{location}"
       if verbosity.to_i > 0
         line += " (Actualisé à #{refreshsrc})"
       end
     line += "_"
     line += "Tendances :_"
     for x in (0..k-1)
       line += "#{maindays[x]} : #{weathers[x]} (#{temperatures[x]})"
       if verbosity.to_i > 1
         line += ", #{winds[x]}"
         if !windspeeds[x].include? "-"
           line += " à #{windspeeds[x]}"
         end
         if !windpeaks[x].include? "-"
             line += " avec des rafales à #{windpeaks[x]}"
           end
       end
     line += "_"
     end
     if verbosity.to_i > 0
     line += "Météo détaillée :_"
       for x in (k..k + times.length1)
         line += "#{times[x-k]} : #{weathers[x]} (#{temperatures[x]})"
         if verbosity.to_i > 1
           line += ", #{winds[x]}"
         end
       line += "_"
       end
     end
     puts "#{line}"
   end
 end

end

# Gets the correct page with the weather forecast
#
# One redirection 302 is OK, not 2
#
# If we get a 200 OK reply, fetch the first link, as we got a multiple-answer result
def fetch(uri_str, exec = 0)

response = Net::HTTP.get_response(URI.parse(uri_str))

# Check answer
case response
  # If we get a proper reply from server
    when Net::HTTPSuccess     then

            if exec == 0

            body = response.body

            firstfound = /.france.meteo\?PREVISIONS_PORTLET.path=previsionsville.\d{6}/.match(body)

            fetch(‘http://’ + $host + firstfound.to_s, exec + 1)

          elsif exec == 1

            response.body

          end

    when Net::HTTPRedirection then

            if exec == 0
              fetch(response[‘location’], exec + 1)
            elsif exec == 1
              response.body
            end

    else
            error()
end
end

# analyze the resulting body from the requested page
def analyze(text)

  #find name of city
  ville = /<p class="city"><strong>([a-zA-Z0-9 ;&amp;-]+)<.strong>/.match(text)

  # If there is indeed a city found
  if !$1.nil?

    ville_locale = $1
    arrondissement = /([0-9])+eme/.match(ville_locale)
    num_arrondissement = $1
    if !$1.nil?
      $meteoresult.location = ville_locale.gsub(num_arrondissement + "eme", num_arrondissement + "ème")
    else
      $meteoresult.location = ville_locale
    end

    refresh = /<p class="refreshed"><em>Actualise a ([0-9][0-9]?h[0-9][0-9]?)<.em>/.match(text)
    $meteoresult.refreshsrc = $1

    #find main days and general forecast
    name_of_maindays = text.scan(/<a class="lienAtmographe" style="cursor:pointer;">([&amp;;a-zA-Z -]+)<.a><.td><td class="temperatures"><img alt="([a-zA-Z -]+)" src="meteo.pictos.web.CARTE.[0-9]+.[a-zA-Z0-9 -_]+" title="[a-zA-Z -]+".> (-?[0-9]+°C . -?[0-9]+°C)<.td><td class="winds"><img alt="[a-zA-Z0-9 -]+" src="meteo.pictos.web.SITE.[0-9]+.[a-zA-Z0-9 -_]+" title="([a-zA-Z -]+)".> ([0-9]+ km.h|-)<.td><td class="winds2"> ([0-9]+ km.h|-)<.td><td class="borderRight"><.td><.tr>/)
    flat_maindays = name_of_maindays.flatten

    i = 0
    while i < flat_maindays.length
      $meteoresult.add_mainday(flat_maindays[i].to_s)
      i += 1
      $meteoresult.add_weather(flat_maindays[i].to_s)
      i += 1
      $meteoresult.add_temperature(flat_maindays[i].to_s)
      i += 1
      $meteoresult.add_wind(flat_maindays[i].to_s)
      i += 1
      $meteoresult.add_windspeed(flat_maindays[i].to_s)
      i += 1
      $meteoresult.add_windpeak(flat_maindays[i].to_s)
      i += 1
    end

    #find days and forecast
    name_of_days = text.scan(/<tr class="([a-zA-Z 0-9]+)"><td class="borderLeft"><.td><td class="firstCol">([&amp;;a-zA-Z -]+)<.td><td class="temperatures"><img alt="[a-zA-Z -]+" src="meteo.pictos.web.SITE.[0-9]+.[a-zA-Z0-9 -_]+" title="([a-zA-Z -]+)".> (-?[0-9]+°C)<.td><td class="winds"><img alt="[a-zA-Z0-9 -]+" src="meteo.pictos.web.SITE.[0-9]+.[a-zA-Z0-9 -_]+" title="([a-zA-Z -]+)".>/)
    flat_days = name_of_days.flatten
    trimmed_names = flat_days.collect {|x| x.gsub(/currentLine\d/, )}

    i = 0
    while i < trimmed_names.length do
      $meteoresult.add_time(trimmed_names[i] + ‘ ‘ + trimmed_names[i+1].downcase!)
      i += 2
      $meteoresult.add_weather(trimmed_names[i].to_s)
      i += 1
      $meteoresult.add_temperature(trimmed_names[i].to_s)
      i += 1
      $meteoresult.add_wind(trimmed_names[i].to_s)
      i += 1
      #$meteoresult.add_windspeed(trimmed_names[i].to_s)
      #i += 1
      #$meteoresult.add_windpeak(trimmed_names[i].to_s)
      #i += 1
    end
  else
    $failure = true
  end
end

cgi = CGI.new

# HTML headers
# Present, even in case of error, if html!=0

if cgi["html"] != ‘0′
  puts "Content-Type: text/html"
  puts
  puts "<html>"
  puts "<head>"
  puts "<title>Météo</title>"
  puts "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"
  puts "<link REL=\"icon\" HREF=\"/temp/meteo/MeteoqueW/favicon.ico\">"
  puts "</head>"
  puts "<body><p>"
else
  puts "Content-Type: text/plain; charset=UTF-8"
  puts
end

# If we receive the argument (ville) properly
if cgi.has_key?(‘ville’)

    if !cgi["ville"].empty?
      # Fetch the argument and sanitize it
      ville = cgi["ville"]

      # Create a connection and request file
      path = pathprefix + CGI::escape(ville) + pathsuffix

      reply_body = fetch(‘http://’ + $host + path)

      $meteoresult = Meteo.new(cgi["html"])

      analyze(reply_body.removeaccents())

      v=0

      if cgi.has_key?(‘v’)
        if !cgi["v"].empty?
          v = cgi["v"]
        end
      end

      if !$failure
           $meteoresult.display(v)
      else
        puts "Ville introuvable"
      end
    # If we don’t receive the argument (ville) properly
    else
        puts "Vous n’avez pas précisé la ville"
    end
    else
        puts "Vous n’avez pas précisé la ville"
end

    # Closing HTML tags
if cgi["html"] != ‘0′
    puts "</p></body>"
    puts "</html>"
end

Le code est accompagné d’un peu de Rdoc. Je ne suis pas bien sûr de son utilité dans le cas présent mais c’est toujours intéressant de maintenir un semblant de documentation sur tous ses projets.

Le code fourni est à placer dans le dossier ‘cgi-bin’ de votre serveur Web. Les paramètres d’entrée sont respectivement ‘ville’, ‘v’ et ‘html’ pour le nom de la ville (ou code postal) pour lequel trouver la météo, le degré de verbosité de la réponse (0, 1, 2) et le format de retour (plain text avec chaque ligne séparée par un _ à cause de l’utilisation conjointe avec le script TCL pour IRC).

À noter, la classe interne “Meteo” qui stocke les données et en gère l’affichage après analyse par la fonction du même nom.

Vous pouvez télécharger la librairie ‘extend_string.rb’ sur http://www.techniconseils.ca/en/scripts-remove-accents-ruby.php.

Si vous utilisez ce script, merci de me laisser un mot ! Merci également de toujours référer à mon site si vous modifiez ce script.

Creative Commons License
MeteoqueW by http://www.baroquew.info/wordpress/archives/meteo-en-ruby is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.0 France License.

Dans un futur article, je ferai une petite introduction à Ruby basée sur ce script.

  • Share/Save/Bookmark
Category: Articles en français, Tech >> Computer | Comments (5)

Nouveau thème

Je viens de changer le thème du blog pour Athaulpa (au lieu de Talian qui a disparu du site de son créateur…). Au passage la bannière – précédemment un coucher de soleil sur un fjord norvégien – a été remplacée par une série de panoramas de mon cru :

  • Place Rouge de Moscou en Russie
  • Split en Croatie vue depuis la colline Marijan
  • Bratislava en Slovaquie vue depuis le palais
  • Le quartier des souks vu depuis la crique de Dubai aux Émirats Arabes Unis

Les panoramas ont été faits avec DoubleTake pour les premiers et PhotoStitch de Canon pour le dernier. PhotoStitch a une interface un peu plus austère et pas très “Mac” mais détecte et recolle bien mieux les images. En revanche, les options pour faire des réglages manuels sont bien moindres dans le logiciel de Canon (PhotoStitch est offert gratuitement avec certains modèles d’appareils photo de Canon).

  • Share/Save/Bookmark
Category: Articles en français, Blog | Leave a comment

Status

  • BaroqueW ecoute desproges dans les fjords
    1 day ago
  • BaroqueW : it is in fact NOT funny to point people in the wrong direction when they're lost
    1 day ago
  • BaroqueW : iphone 3gs, July 31st in Sweden - according to Telia
    3 days ago
  • BaroqueW had a quick look at the book keeping of the holidays... gloups
    3 days ago

Popular posts

My Social Networks

DandyID 43 Things Clipmarks coComment Dailymotion Delicious deviantART Digg Diigo Facebook Flickr Get Satisfaction Guitar Hero HelloTxt Hulu ICQ Imdb Imeem Kiva last.fm Linkedin Netvibes orkut PeoplePond Picasa Plaxo PostCrossing RockBand Scribd Stumbleupon Tagged TripAdvisor Twitpic Twitter Xbox LIVE YouTube

Expand the experience

Blogroll

Internet Map

Meta