BaroqueW

BaroqueW

and his sidekick nikkitaa

BaroqueW RSS Feed
 
 
 
 

Posts tagged codage

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)

Autoregistration to Nickserv for your eggdrop bot

I guess when people set a bot for themselves, to use on IRC, they want it to identify its name, especially when it ends up managing a channel. Here is how to configure this (somewhat summarily, but at least you don’t have to install a script) for your eggdrop.

Edit eggdrop.conf to look like below, set nick “Mybot” and other lines are already present but at least you see where to add the lines:

# Set the nick the bot uses on IRC, and on the botnet unless you specify a
# separate botnet-nick, here.
set nick "Mybot"
set identpass "mypass"   # set the variables used to register (identpass, nickserv, identcmd)
set nickserv "NickServ@services.dal.net"   # It is safer to use the full nickserv identifier, not jut "nickserv"
set identcmd "IDENTIFY"

# Set the alternative nick which the bot uses on IRC if the nick specified
# by ’set nick’ is unavailable. All ‘?’ characters will be replaced by random
# numbers.
set altnick "MybotX?"

# Set what should be displayed in the real-name field for the bot on IRC.
# This can not be blank, it has to contain something.
set realname "It’s my bot"

# This is a Tcl script to be run immediately after connecting to a server.
bind evnt – init-server evnt:init_server

proc evnt:init_server {type} {
  global botnick nickserv identcmd identpass # don’t forget to tell the script to use the global variables we defined above
  putquick "MODE $botnick +i-ws"
  putquick "PRIVMSG $nickserv :$identcmd $identpass"  # we will identify on connect
}

# All this is new
# Upon receiving "*This nickname is owned by someone else.*", we will try to identify
bind notc – "*This nickname is owned by someone else.*" identify:notc
proc identify:notc { nick uhost handle text dest } {
 global botnick nickserv identcmd identpass
  if { $nick == $nickserv } {
    puthelp "PRIVMSG $nickserv :$identcmd $identpass"
      putlog "Identifying : $nickserv (as $botnick)"
       }
       }

  • Share/Save/Bookmark
Category: Articles in English, Tech >> Computer | Comments (2)

iPhoto et tags EXIF

Adapté d’un script par Andrew Turner, ce script Applescript permet d’ajouter des tags Exif (commentaires, titre, date, etc.) à vos photos à partir des méta-données que vous aurez saisies dans iPhoto. Pour ce faire, sélectionnez vos photos dans iPhoto (pas des albums mais bien des photos) et exécutez ce script. Voir plus bas pour quelques commentaires et le script à télécharger.

– This applescript will set the exif keywords, name, and comments of all selected iPhoto
–   images using the information current in iPhoto.

– Author: Andrew Turner (http://highearthorbit.com)
– Editor: BaroqueW (http://www.baroquew.net)

property copyright : ""
property URL : ""
property exifToolOriginal : "_original"

– True retains copyright, False means Public Domain
property Copyrighted : "False"

tell application "iPhoto"
        activate
        try
                copy (my selected_images()) to these_images
                if these_images is false or (the count of these_images) is 0 then ¬
                        error "Please select a single image."

                set counter to 0

                repeat with i from 1 to the count of these_images
                        set the keywordslist to ""
                        set this_photo to item i of these_images
                        tell this_photo
                                set the image_file to the image path
                                set the image_title to the title
                                set the image_filename to the image filename
                                set the image_comment to the comment
                                set the assigned_keywords to the name of keywords
                                set the image_date to the date
                                set date_step1 to do shell script "echo " &amp; image_date &amp; " | sed ’s/,//g’ | sed ’s/\\([A-Z][a-z][a-z]\\)\\([a-z]\\)*/\\1/g’ | sed ’s/[0-9][0-9]\\([0-9][0-9]\\)/\\1/’"
                                set date_step2 to do shell script "date -j -f ‘%a %b %d %y %I:%M:%S %p’ " &amp; quoted form of date_step1 &amp; " ‘+%y:%m:%d %H:%M:%S’  | sed ’s/^0/200/’ | sed ’s/^9/199/’"
                        end tell
                        repeat with j from 1 to the count of assigned_keywords
                                set the keywordslist to keywordslist &amp; " -keywords+=" &amp; item j of assigned_keywords
                        end repeat
                        set the command to "exiftool -m -PL -title=\"" &amp; image_title &amp; ¬
                                "\" " &amp; keywordslist &amp; ¬
                                " " &amp; " -comment=’" &amp; image_comment &amp; ¬
                                "’ " &amp; " -CreateDate=’" &amp; date_step2 &amp; ¬
                                "’ " &amp; " -DateTimeOriginal=’" &amp; date_step2 &amp; ¬
                                "’ " &amp; " -Copyright=’" &amp; copyright &amp; ¬
                                "’ " &amp; " -CopyrightNotice=’" &amp; copyright &amp; ¬
                                "’ " &amp; " -Rights=’" &amp; copyright &amp; ¬
                                "’ " &amp; " -Marked=’" &amp; Copyrighted &amp; ¬
                                "’ " &amp; "\"" &amp; image_file &amp; "\""
                        set output to do shell script command
                        do shell script "rm \"" &amp; image_file &amp; "\"" &amp; exifToolOriginal
                        set counter to counter + 1
                end repeat
                display dialog "Exif writing complete for " &amp; (counter as string) &amp; " files."
        on error error_message number error_number
                if the error_number is not -128 then
                        display dialog error_message &amp; " Exif writing complete for " &amp; (counter as string) &amp; " files." buttons {"Cancel"} default button 1
                end if
        end try
end tell

on selected_images()
        tell application "iPhoto"
                try
                        – get selection
                        set these_items to the selection
                        – check for single album selected
                        if the class of item 1 of these_items is album then error
                        – return the list of selected photos
                        return these_items
                on error
                        return false
                end try
        end tell
end selected_images

J’ai amélioré le script pour le rendre compatible avec les inévitables accents et apostrophes de la langue française. J’ai aussi ajouté le support pour les dates (cf. les expressions régulières et ’sed’ plus haut, lignes 33 et 34) – à noter que mes locales sont en anglais sur MacOSX donc il y aura peut-être des adaptations à faire pour retomber sur vos pieds (notamment l’usage de AM/PM serait surprenant avec des locales françaises, voir ligne 34). Petite cerise sur le gâteau, le programme retourne le nombre de fichiers modifiés (ligne 53) et éventuellement le fichier qui a causé une erreur en cas de plantage (ligne 56).

Attention : par choix personnel, j’ai décidé d’ignorer les erreurs mineures (modificateur ‘-m’ dans la commande ‘exiftool’ à la ligne 39). Il est recommandé d’essayer le script sans ce modificateur et de le rajouter si vous rencontrez des problèmes et que vous voulez tenter votre chance.

Vous pouvez télécharger le script ici : Set Exif Data

  • Share/Save/Bookmark
Category: Articles en français, Tech >> Computer | 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