Code :
###############################################
# #
# B a s h F r F e t c h e r #
# v1.02 (13/03/2009) par MenzAgitat #
# #
# IRC: irc.epiknet.org #boulets #
# #
# Mes scripts sont téléchargeables sur #
# http://www.egghelp.org #
# ou http://www.eggdrop.fr #
# #
# merci à B0unTy pour sa routine #
# antiflood dont je me suis inspiré #
# ainsi qu'à wiki.tcl.tk pour les #
# nombreuses bonnes idées que j'y trouve #
# #
###############################################
#
# Description
# Affiche des citations de BashFr.org
# Syntaxe : !bashfr : affiche une citation aléatoire
# !bashfr last : affiche la dernière citation en date
# !bashfr n° : affiche la citation qui correspond au n° demandé
#
# Remarques :
# Ce script inclut une petite bidouille qui permet de contourner le filtrage
# de lignes en double dans la file d'attente des messages envoyés au serveur.
# Cette fonction (réglable au moyen des paramètres double-mode double-server
# et double-help dans le fichier eggdrop.conf) est problématique car elle
# supprime également les lignes en double dans les citations de BashFr
# (fi du comique de répétition donc ^^)
#
# Ce script est lourdement commenté et équippé d'un mode DEBUG, ceci dans le
# but que chacun puisse aisément le lire et le comprendre afin peut-être de
# le modifier, l'améliorer, l'adapter, ou de s'en inspirer pour ses propres
# scripts.
# Merci, le cas échéant de citer les auteurs respectifs lorsque vous reprenez
# le travail d'autrui.
# Changelog :
# 1.0 : Première version
# 1.01: Ajout d'un timeout si la connexion ne s'établit pas dans les temps
# 1.02: Correction du script qui ne fonctionnait plus suite à un changement
# sur le site www.bashfr.org
# LICENCE:
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A RTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
###########################
# REGLAGES #
###########################
##### Commande publique
set bashfr_cmd "!bash"
##### Chans sur lesquels BashFr Fetcher sera disponible
##### exemple : set bashfr_chans "#chan1 #chan2 chan3"
set bashfr_chans "#Accueil"
##### Contrôle de flood
##### -----------------
##### Nombre maximum de lignes affichées
set bashfr_maxlines 15
##### Anti-flood actif ? ( 1 pour oui, 0 pour non )
set bashfr_antiflood 1
##### Nombre maximum de requêtes
set bashfr_antiflood_max_request 1
##### toutes les ? secondes
set bashfr_antiflood_queue_time 60
##### Intervalle de temps minimum entre l'affichage de 2 messages
##### avertissant que l'anti-flood a été déclenché (ne réglez pas
##### cette valeur trop bas afin de ne pas flooder avec les messages
##### d'avertissement de l'anti-flood lui-même...
set bashfr_antiflood_msg_interval 20
##### Apparence
##### ---------
##### Les couleurs possible vont de 00 à 15
##### Couleur du texte du n° de la citation
set bashfr_numcolfg 09
##### Couleur de fond du n° de la citation
set bashfr_numcolbg 01
##### Couleur du texte de la citation
set bashfr_quotecolfg 04
##### Couleur de fond de la citation
set bashfr_quotecolbg 15
###################################################
# #
# NE MODIFIEZ RIEN EN DESSOUS DE CE CADRE A MOINS #
# DE SAVOIR EXACTEMENT CE QUE VOUS FAITES #
# #
###################################################
package require http
set bashfr_version "1.02.20090313"
set bashfr_DEBUGMODE 0
set bashfr_antiflood_msg 0
set bashfr_instance 0
set bashfr_duplicatesfix {}
set useragent "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"
set bashfr_url "http://danstonchat.com/"
bind pub -|- $bashfr_cmd pub:bashfr
##### Procédure principale
proc pub:bashfr {nick host hand chan arg} {
global bashfr_DEBUGMODE bashfr_antiflood bashfr_instance bashfr_antiflood_max_request bashfr_antiflood_queue_time bashfr_antiflood_msg_interval bashfr_antiflood_msg
##### Avons-nous la permission d'utiliser cette commande sur ce chan ?
set permission_result [bashfr_channel_check $chan]
if {$permission_result == 0} {return}
### contrôle de flood
if { $bashfr_antiflood == 1 } {
## flood détecté ?
if { $bashfr_instance >= $bashfr_antiflood_max_request } {
if {$bashfr_DEBUGMODE == 1} { putlog "\00304\[BASHFR DEBUG\]\003 anti-flood : flood détecté" }
if { $bashfr_antiflood_msg == 0 } {
set bashfr_antiflood_msg 1
putquick "privmsg $chan :Contrôle de flood : pas plus de $bashfr_antiflood_max_request requête(s) toutes les $bashfr_antiflood_queue_time secondes."
utimer $bashfr_antiflood_msg_interval bashfr_antiflood_msg_reset
}
return
}
incr bashfr_instance
if { $bashfr_DEBUGMODE == 1 } { putlog "\00304\[BASHFR DEBUG\]\003 anti-flood : nouvelle instance $bashfr_instance" }
utimer [set bashfr_antiflood_queue_time] bashfr_antiflood_close_instance
}
set arg [string trim $arg]
# Si l'argument n'est pas numérique ET n'est pas "last" et n'est pas ""
# on affiche de l'aide
if {([regexp {^[0-9]+$} $arg] != 1) && ($arg != "last") && ($arg != "")} {
bashfr_syntax $chan
# sinon, on traite la demande
} else {
global useragent bashfr_url bashfr_cmd bashfr_maxlines bashfr_numcolfg bashfr_numcolbg bashfr_quotecolfg bashfr_quotecolbg
# putcmdlog "$nick@$chan $bashfr_cmd $arg"
set res ""
set bashfr_duplicatesfix {}
## Construction de l'url
if {[regexp {^[0-9]+$} $arg] == 1} { set bashfr_url2 "?$arg" }
if {$arg == ""} { set bashfr_url2 "?sort=random" }
if {$arg == "last"} { set bashfr_url2 "?sort=latest" }
set url "$bashfr_url$bashfr_url2"
if $bashfr_DEBUGMODE {putlog "\00304\[BASHFR DEBUG\]\003 url = $url"}
##### on envoie la requête au socket
::http::config -useragent $useragent
set token [::http::geturl "$url" -timeout 6000]
##### si la connexion est établie, on traite les données reçues.
if {[::http::status $token] == "ok"} {
### l'argument est numérique donc on cherche une citation bien précise.
if {[regexp {^[0-9]+$} $arg] == 1} {
if $bashfr_DEBUGMODE {putlog "\00304\[BASHFR DEBUG\]\003 l'argument est numérique - n° de citation demandé : $arg"}
set numquote $arg
regexp "class=\"com\"></span></span><br />(.+?)</p>" [::http::data $token] res
if { $res != "" } {
bashfr_quote_processing $res $chan $url $numquote
} else {
puthelp "privmsg $chan :\00314$nick > La citation demandée n'existe pas.\003"
}
}
### l'argument est "last", on veut la dernière citation en date
if {($bashfr_DEBUGMODE) && ($arg == "last")} {putlog "\00304\[BASHFR DEBUG\]\003 requête de la dernière citation en date"}
### l'argument est inexistant, on veut une citation aléatoire
if {($bashfr_DEBUGMODE) && ($arg == "")} {putlog "\00304\[BASHFR DEBUG\]\003 requête d'une citation aléatoire"}
if {($arg == "last") || ($arg == "")} {
regexp "<span id=\"com-(.+?)\" class=\"com\">" [::http::data $token] numquote
regsub -all {[^0-9]+} $numquote "" numquote
regexp "class=\"com\"></span></span><br />(.+?)</p>" [::http::data $token] res
if { $res != "" } {
bashfr_quote_processing $res $chan $url $numquote
} else {
puthelp "privmsg $chan :\00314Aucune information identifiable n'a pu être récupérée. BashFr rencontre peut-être un problème ou bien le layout du site a changé.\003"
}
}
} else {
puthelp "privmsg $chan :\00314La connexion à \002BashFr\002 n'a pu être établie. Peut-être le site rencontre-t-il des difficultés techniques. Veuillez réessayer plus tard.\003"
}
::http::cleanup $token
}
}
##### Compte le nombre d'occurrence d'une sous-chaîne dans une chaîne de caractères donnée
proc scount {subs string} {regsub -all $subs $string $subs string}
##### Syntaxe
proc bashfr_syntax { chan } {
global bashfr_cmd
puthelp "privmsg $chan :\037Syntaxe :\037 \002$bashfr_cmd\002 \00314\[\003paramètre\00314\] \00307| \003Affiche une citation du site www.bashfr.org \00307| \003Cette commande a 3 fonctions : \002$bashfr_cmd\002 affiche une citation aléatoire. \00307— \003\002$bashfr_cmd\002 \00314\[\003n° de quote\00314\] \003affiche la citation du n° demandé. \00307— \003\002$bashfr_cmd\002 \00314\[\003last\00314\] \003affiche la dernière citation en date."
return "done"
}
##### Vérifie si le chan est dans la liste des chans autorisés
proc bashfr_channel_check { chan } {
global bashfr_chans
if {[lsearch -exact $bashfr_chans $chan] != -1} {
set permission 1
} else {
set permission 0
}
return $permission
}
##### Traitement des données
proc bashfr_quote_processing { res chan url numquote } {
global bashfr_DEBUGMODE
if $bashfr_DEBUGMODE {putlog "\00304\[BASHFR DEBUG\]\003 \037PRE-REGSUB\037 $res"}
regsub -all "class=\"com\">" $res "" res
## Conversion des caractères html spéciaux et filtrage des balises HTML
set res [bashfr_quote_filter $res]
## On teste si on a encore du contenu intéressant après le filtrage
if {$res != ""} {
# Si oui, on affiche le résultat
bashfr_display_quote $res $chan $url $numquote
}
return "done"
}
##### Conversion des caractères html spéciaux et filtrage des balises HTML
proc bashfr_quote_filter { res } {
global bashfr_DEBUGMODE
set res [string map -nocase {
"à" "à" "à" "à" "á" "á" "â" "â"
"ã" "ã" "ä" "ä" "å" "å" "æ" "æ"
"ç" "ç" "è" "è" "é" "é" "ê" "ê"
"ë" "ë" "ì" "ì" "í" "í" "î" "î"
"ï" "ï" "ð" "ð" "ñ" "ñ" "ò" "ò"
"ó" "ó" "ô" "ô" "õ" "õ" "ö" "ö"
"÷" "÷" "ø" "ø" "ù" "ù" "ú" "ú"
"û" "û" "ü" "ü" "ý" "ý" "þ" "þ"
"ÿ" "ÿ" """ "\"" "&" "&" "€" "€"
"œ" "Å“" "Ÿ" "Ÿ" " " " " "¡" "¡"
"¢" "¢" "£" "£" "¤" "¤" "¥" "Â¥"
"¦" "¦" "&brkbar;" "¦" "§" "§" "¨" "¨"
"¨" "¨" "©" "©" "ª" "ª" "«" "«"
"¬" "¬" "­" "Â-" "®" "®" "¯" "¯"
"&hibar;" "¯" "°" "°" "±" "±" "²" "²"
"³" "³" "´" "´" "µ" "µ" "¶" "¶"
"·" "·" "¸" "¸" "¹" "¹" "º" "º"
"»" "»" "¼" "¼" "½" "½" "¾" "¾"
"¿" "¿" "À" "À" "Á" "Ã" "Â" "Â"
"Ã" "Ã" "Ä" "Ä" "Å" "Å" "Æ" "Æ"
"Ç" "Ç" "È" "È" "É" "É" "Ê" "Ê"
"Ë" "Ë" "Ì" "í" "Í" "Ã" "Î" "Î"
"Ï" "Ã" "Ð" "Ã" "Đ" "Ã" "Ñ" "Ñ"
"Ò" "Ò" "Ó" "Ó" "Ô" "Ô" "Õ" "Õ"
"Ö" "Ö" "×" "×" "Ø" "Ø" "Ù" "Ù"
"Ú" "Ê" "Û" "Û" "Ü" "í" "Ý" "Ã"
"…" "..."
"Þ" "Î" "ß" "ß" "\r" "\n" "\t" ""
"'" "\'" "'" "\'"
""" "\'" "&" "&" "#91;" "\(" "\" "\/"
"]" ")" "{" "(" "}" ")" "£" "£"
"¨" "¨" "©" "©" "«" "«" "Â" "Â"
"®" "®" "´" "´" "·" "·" "¹" "¹"
"»" "»" "¼" "¼" "½" "½" "¾" "¾"
"À" "À" "Ã" "Ã" "Â" "Â" "Ã" "Ã"
"Ä" "Ä" "Å" "Å" "Æ" "Æ" "Ç" "Ç"
"È" "È" "É" "É" "Ê" "Ê" "Ë" "Ë"
"í" "í" "Ã" "Ã" "Î" "Î" "Ã" "Ã"
"Ã" "Ã" "Ñ" "Ñ" "Ò" "Ò" "Ó" "Ó"
"Ô" "Ô" "Õ" "Õ" "Ö" "Ö" "×" "×"
"Ø" "Ø" "Ù" "Ù" "Ê" "Ê" "Û" "Û"
"í" "í" "Ã" "Ã" "Î" "Î" "ß" "ß"
"à" "à" "á" "á" "â" "â" "ã" "ã"
"ä" "ä" "å" "å" "æ" "æ" "ç" "ç"
"è" "è" "é" "é" "ê" "ê" "ë" "ë"
"ì" "ì" "í" "í" "î" "î" "ï" "ï"
"ð" "ð" "ñ" "ñ" "ò" "ò" "ó" "ó"
"ô" "ô" "õ" "õ" "ö" "ö" "÷" "÷"
"ø" "ø" "ù" "ù" "ú" "ú" "û" "û"
"ü" "ü" "ý" "ý" "þ" "þ" "…" "..."
} $res]
regsub -all "<br />" $res "\n" res
regsub -all "<\[^<\]*>" $res "" res
set res [string map -nocase {
"<" "<" ">" ">"
} $res]
set res [encoding convertfrom "utf-8" $res ]
if $bashfr_DEBUGMODE {putlog "\00304\[BASHFR DEBUG\]\003 \037POST-REGSUB\037 $res"}
return "${res}"
}
##### Affichage de la citation
proc bashfr_display_quote { res chan url numquote } {
global bashfr_numcolfg bashfr_numcolbg bashfr_quotecolfg bashfr_quotecolbg bashfr_maxlines bashfr_DEBUGMODE bashfr_url bashfr_duplicatesfix
set numresults [scount "\n" $res]
set res [split $res "\n"]
set counter 1
foreach line $res {
if {[string trim $line] != "" && [string trim $line] != " "} {
if {$counter == 1} { set line "\002\003$bashfr_numcolfg,$bashfr_numcolbg\[$numquote\]\002\003$bashfr_quotecolfg,$bashfr_quotecolbg $line \003" }
if {($counter >= $bashfr_maxlines) && ($numresults >= $bashfr_maxlines)} { set line "$line \003\00304 (...)\003" }
# si, et tant qu'on trouve une autre ligne identique dans la citation
while {[expr [lsearch -exact $bashfr_duplicatesfix [bashfr_calculate_checksum $line]]] >= 0} {
# alors on ajoute un espace (caractère ascii 32 (40 en octal)) à la fin pour
# outrepasser le filtrage des lignes en double dans la file d'attente du bot.
set line "$line \003\040"
if $bashfr_DEBUGMODE {putlog "\00304\[BASHFR DEBUG\]\003 on a modifié la ligne \00314\"$line\"\003 car elle était identique à une autre dans la file d'attente"}
}
# maintenant qu'on est sûr qu'il n'y a pas d'autre ligne identique dans la queue,
# on ajoute cette ligne dans la liste pour comparaisons ultérieures.
lappend bashfr_duplicatesfix [bashfr_calculate_checksum $line]
# on affiche le résultat
puthelp "privmsg $chan :\003$bashfr_quotecolfg,$bashfr_quotecolbg$line \003"
if {($counter >= $bashfr_maxlines) && ($numresults >= $bashfr_maxlines)} {
puthelp "privmsg $chan :\00314La suite ici : \00312\037$bashfr_url?$numquote\037\003"
set bashfr_duplicatesfix {}
return "done"
}
incr counter
}
}
set bashfr_duplicatesfix {}
}
##### Clôture d'une instance de l'anti-flood après expiration du délai
proc bashfr_antiflood_close_instance { } {
global bashfr_DEBUGMODE bashfr_instance
if { $bashfr_instance > 0 } { incr bashfr_instance -1 }
if { $bashfr_DEBUGMODE == 1 } { putlog "\00304\[BASHFR DEBUG\]\003 anti-flood : le n° d'instance est descendu à $bashfr_instance" }
}
##### Remise en service du message d'avertissement de l'anti-flood
proc bashfr_antiflood_msg_reset { } {
global bashfr_antiflood_msg
set bashfr_antiflood_msg 0
}
##### Calcul du checksum (simplifié) d'une chaîne ASCII
proc bashfr_calculate_checksum { line } {
set line_chars [split $line {}]
set checksum 0
foreach char $line_chars {
scan $char "%c" value
incr checksum $value
}
return $checksum
}
putlog "\002*BashFr Fetcher v$bashfr_version*\002 par MenzAgitat (\037\00312http://www.boulets-roxx.com\003\037) a été chargé."