123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- #!/bin/env perl
- # Copyright (c) 2014, 2015 Daniel Jakots <vigdis@chown.me>
- # Permission to use, copy, modify, and distribute this software for any
- # purpose with or without fee is hereby granted, provided that the above
- # copyright notice and this permission notice appear in all copies.
- #
- # Permission to use, copy, modify, and distribute this software for any
- # purpose with or without fee is hereby granted, provided that the above
- # copyright notice and this permission notice appear in all copies.
- #
- # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- use warnings;
- use strict;
- ######################################################################
- # this package was created only for checking modified files. If a #
- # file was modified, append timestamp will be updated, you need to #
- # have write access to checked file! #
- ######################################################################
- { package check;
- use strict;
- use warnings;
- use File::stat;
- use Time::localtime;
- use POSIX qw(strftime);
- sub fichier {
- my $file = shift();
- my $time;
- $time = shift() or $time = 10;
- # if checked file doesn't exist, return 0
- unless (-f $file) {
- return(0);
- }
-
- # init all local variables
- my $ltime = strftime("%s", @{ localtime() });
- my $atime = strftime("%s", @{ localtime(stat($file)->atime) });
- my $mtime = strftime("%s", @{ localtime(stat($file)->mtime) });
- my $ntime = $mtime-($time+2);
-
- # we check if localtime minus modified time is less than configured
- # time. If it's true, we set a new append/modified time via utime().
- if (($ltime-$mtime) <= $time) {
- utime($ntime, $ntime, $file);
- return(1);
- }
- else {
- return(0);
- }
- }
- }
- package MyBot;
- use base qw( Bot::BasicBot );
- binmode STDOUT, ":utf8";
- use utf8;
- # le repectoire des données du bot aka autoconf
- my $bot_dir = `pwd`; chomp $bot_dir ; $bot_dir .= "/";
- my $wrk_dir = "wrk-dir/";
- my $dir = $bot_dir.$wrk_dir;
- # symbol auquel le bot répond
- my $symbol = "+";
- # dictionnaire contenant les regex permettants de trouver les FAI
- my %regex = (
- "apinnet" => "(ap[in]|Poitou|Charente|Rochelle|(Deux[- ])?S[èe]vres?|Vienne|Angoul[eêè]me|Niort|Poitiers)",
- "aquilenet" => "(aq(ui|n)|Bord(o|e?au)|Landes|Gironde)",
- "arn" => "(a(lsace|rn)|Stras|Colma)",
- "auvernet" => "(Auver|Puy[- ](de[- ])D[oô]me|avn)",
- "cafai" => "(cafai|champagne|ardenn?e)",
- "faimaison" => "(fma|fail?m|Nantes|Loire[- ]Atlantique)",
- "fdn" => "f(rench|dn)",
- "franciliens" => "b(f(ranc|cn)|idf|Paris)",
- "grifon" => "(grif|rennes|[îi]l?le[- ](et[- ])?vilaine)",
- "ilico" => "(ilc|ill?[iy][ck])|(Corr?[éêèe][sz])",
- "illyse" => "(ill?y|ill?i[sz]|lyon|rh[ôo]ne|loire|((st|saint)[- ]etienn?e))",
- "iloth" => "(ilo|mont?pel|h[ée]rault)",
- "ldn" => "(l(or|dn)|Nancy|Metz|Moselle|Meuse|Meurthe|Vosges)",
- "ndn" => "(n(ice|dn)|Antibes|Cannes|Valbonne|Alpes[- ]Maritimes)",
- "netopi" => "(netopi|Seine[- ](et[- ])?Marne)",
- "pclight" => "(yonne|beon|cheny|pc[- ]?l)",
- "rezine" => "(r[eé]z|Isère|Grenoble)",
- "rhizome" => "(rh?[iy][sz]om|Oise|Compi[eéêè]gne)",
- "sames" => "sam|(Pyrénées[- ]Atlantiques)",
- "sdn" => "(s(all|dn)|Savoie|Haute[- ]Savoie)",
- "teleragno" => "(mars|telerag|telegrano)",
- "tetaneutral" => "(t(eta|tn|nn)|Toulouse|Comminges|(Haute[- ]Garon?ne))",
- "ail-network" => "a(il|utan)",
- "chaul-hertz" => "(c(haul|hz)|hertz|tarn)",
- "igwan" => "(ig[wn]|sbg|saint[- ]barth)",
- "neutrinet" => "(neutri|n[tre]n|belgique)",
- "ffdn" => "f(ede|fdn|rance|édé)",
- "tdn" => "(t(dn|ouraine)|centre|rouvr)",
- );
- # Lis le fichier contenant les infos d'un FAI
- sub info {
- my $fai = shift @_;
- my $filename = $dir.$fai.".info";
- if (-e $filename)
- {
- my $fh;
- open ($fh, '<', $filename) or die "Impossible d'ouvrir le fichier $filename en lecture";
- while (my $line = <$fh>)
- {
- return $line;
- }
- close $fh;
- }
- else
- {
- return "pas d'information pour ". $fai ."\n";
- }
- }
- # Lis le fichier contenant les nombres adh/abo d'un FAI
- sub adh {
- my $fai = shift @_;
- my $filename = $dir.$fai.".adh";
- if (-e $filename)
- {
- my $fh;
- open ($fh, '<', $filename) or die "Impossible d'ouvrir le fichier $filename en lecture";
- while (my $line = <$fh>)
- {
- return $line;
- }
- close $fh;
- }
- else
- {
- return "pas d'information pour ". $fai ."\n";
- }
- }
- # lis le fichier et retourne le contenu
- sub lecture_fichier {
- my $fichier = shift @_;
- my $filename = $dir.$fichier;
- if (-e $filename)
- {
- my $fh;
- open ($fh, '<', $filename) or die "Impossible d'ouvrir le fichier $filename en lecture";
- while (my $line = <$fh>)
- {
- return $line;
- }
- close $fh;
- }
- else
- {
- return "Nope\n";
- }
- }
- # on compte le nombre d'adh et d'abo pour la fédé
- sub adh_abo_ffdn {
- my $filename = $dir."ffdn.adh";
- if (-e $filename)
- {
- my $fh;
- open ($fh, '<', $filename) or die "Impossible d'ouvrir le fichier $filename en lecture";
- while (my $line = <$fh>)
- {
- return $line;
- }
- close $fh;
- }
- else
- {
- return "pas d'information\n";
- }
- }
- # on note les RP
- sub rp {
- my $link = shift @_;
- my $filename = "/usr/share/nginx/www/rp.txt";
- my $filehandle;
- open ($filehandle, '>>', $filename) or die "Impossible d'ouvrir le fichier $filename en écriture";
- print $filehandle "$link\n";
- close $filehandle;
- return "Une nouvelle RP à traiter est disponible à http://unefede.fdn.fr/rp.txt (hl quota_atypique taziden)";
- }
- sub get_fai {
- my ($commande, $message) = @_;
- my @fai_trouves = grep { $message =~ /$regex{$_}/ } keys %regex;
- if (@fai_trouves < 1 ) {
- return "commande : ".$symbol."$commande <fai> (".$symbol."liste pour avoir la liste) ou ".$symbol."$commande <lieu geographique>";
- }
- elsif (@fai_trouves > 1 ) {
- return "Trop de fai trouvés : " . join ', ', @fai_trouves;
- }
- else {
- if ($commande eq 'info') {
- info $fai_trouves[0];
- }
- elsif ($commande eq 'adh') {
- adh $fai_trouves[0];
- }
- }
- }
- ## Le bot lit le chan et réagit
- sub said {
- my ($self, $message) = @_;
- # check if file was modified. if true we print this file when one user do
- # something on the chan.
- if (check::fichier("wrk-dir/suivi", 60)) {
- return("Il y a du nouveau pour la réunion de suivi. "
- . lecture_fichier("suivi"));
- }
- # si on veut des info
- if ($message->{body} =~ /^\Q$symbol\Einfo/) {
- shift @_;
- if($message->{body} =~ /$regex{"ffdn"}/i) {
- return "La fédération FDN regroupe des Fournisseurs d'Accès à Internet associatifs se reconnaissant dans des valeurs communes : bénévolat, solidarité, fonctionnement démocratique et à but non lucratif; défense et promotion de la neutralité du Net.";
- }
- get_fai 'info', $message->{body};
- }
- # si on veut le nombre d'adhérent
- elsif ($message->{body} =~ /^\Q$symbol\Eadh/) {
- shift @_;
- get_fai 'adh', $message->{body};
- }
- # si on veut de l'aide
- elsif ($message->{body} =~ /^\Q$symbol\Ehelp/) {
- return "commandes gérées : ".$symbol."liste, ".$symbol."info, ".$symbol."adh, ".$symbol."suivi, ".$symbol."vote, ".$symbol."source, ".$symbol."ag, ".$symbol."json, ".$symbol."rp";
- }
- # les sources du bot
- elsif ($message->{body} =~ /^\Q$symbol\Esource/) {
- lecture_fichier("source");
- }
- # les infos par rapport aux réunions de suivies
- elsif ($message->{body} =~ /^\Q$symbol\Esuivi/) {
- lecture_fichier("suivi");
- }
- # les infos par rapport aux réunions de suivies
- elsif ($message->{body} =~ /^\Q$symbol\Evote/) {
- lecture_fichier("vote");
- }
- # les infos par rapport à l'ag de la fédé
- elsif ($message->{body} =~ /^\Q$symbol\Eag/) {
- lecture_fichier("ag");
- }
- # les infos par rapport au source du bot
- elsif ($message->{body} =~ /^\Q$symbol\Ejson/) {
- lecture_fichier("json");
- }
- elsif ($message->{body} =~ /^\Q$symbol\Eliste/) {
- return "Les associations surveillées (par mes petits yeux de bot) sont : Ail-network, Apinnet, Aquilenet, ARN, Auvernet, CAFAI, Chaul-Hertz, FAImaison, FDN, Franciliens.net, GRIFON, Igwan, Ilico, Illyse, Iloth, LDN, NDN, Neutrinet, PC Light, Rezine, Rhizome, Sames Wireless, Teleragno, TDN et Tetaneutral";
- }
- # on assiste ceux qui ont alzheimer :p
- elsif ($message->{"body"} =~ /^symbol/) {
- return "Les symboles sont : pour UnRouteur : > ; pour moi-même : $symbol";
- }
- # easter egg
- elsif ($message->{body} =~ /datafoin/) {
- my @datafoin = (
- 'il ne faut pas me donner à manger après minuit /o\\',
- 'omnomnom',
- 'mais je vais grossir /o\\',
- 'vouiii',
- 'datafoin <3',
- );
- return $datafoin[int rand($#datafoin+1)];
- }
- elsif ($message->{body} =~ /^\Q$symbol\Erp/) {
- my $url = $message->{body};
- $url =~ s/^\Q$symbol\Erp //;
- rp($url);
- }
- }
- # tout ce qu'on écrit dans le ficher log apparait dans $channel
- sub connected {
- my $fichier = $dir."log";
- my $self = shift;
- $self->forkit({ channel => "#ffdn",
- run => [ qw( /usr/bin/tail -f -n0 /home/bot/bot-irc/wrk-dir/log ) ],
- });
- }
- # aucune idée de comment on déclenche cette ligne
- sub help { "Je suis le bot de la fédé." }
- #Info de connexion du bot
- MyBot->new(
- server => 'irc.geeknode.org',
- channels => [ '#fdn', '#ffdn', '#franciliens.net', '#faimaison', '#illyse'],
- nick => 'UneFede',
- username => 'bot',
- name => 'Droide de la Federation FDN, run by fédé'
- )->run();
|