#!/usr/bin/perl -w #boot pogody , author Patryk Kowalczyk #LICENCE GPLv2 #... #0.1.3 poprawaione wyj±tki #w planach subskrypcja, zmiana opisow dla userkow, avatar use constant RELEASE => '0.1.3'; #laczenie z jabberekiem use Net::Jabber qw(Client); #pobieranie stron i ich parsowanie use LWP::UserAgent; use HTTP::Request; use HTTP::Response; use XML::Simple; use Text::Iconv; my $converterISO = Text::Iconv->new("utf-8","iso-8859-2"); my $converterUTF = Text::Iconv->new("iso-8859-2","utf-8"); use HTML::Entities::Numbered; use Time::localtime; use Date::Manip; use strict; #configuration use constant SERVER => 'linux.si4.org'; use constant PORT => '5222'; use constant USERNAME => 'weather'; #zastepcze konto use constant PASSWORD => 'passa'; use constant RESOURCE => 'pogoda'; use constant PRIORITY => '777'; # default for bot : 777 use constant ADMIN => 'xxx@linux.si4.org'; # admin boota :D use constant ADMIN2 => 'yyy@linux.si4.org';; use vars qw( $code_onet); use vars qw( $code_pogodainfo); $code_pogodainfo = XMLin ('code_pogodainfo.xml' , contentkey => '-code', grouptags => {codes => 'code'} ); $code_onet = XMLin ('code_onet.xml' , contentkey => '-code', grouptags => {codes => 'code'} ); #watki $SIG{HUP} = \&Stop; $SIG{KILL} = \&Stop; $SIG{TERM} = \&Stop; $SIG{INT} = \&Stop; #generowanie nowego polaczenia my $POGODA = new Net::Jabber::Client(); $POGODA->SetCallBacks(message=>\&GetInfo, presence=>\&InPresence, iq=>\&InIQ); # #beta testy - Xpatch, moze sie kiedys przyda # $POGODA->SetXPathCallBacks('/message'=>\&GetInfo, # '/presence'=>\&InPresence, # '/iq'=>\&InIQ); my $status = $POGODA->Connect(hostname => SERVER, port => PORT); $POGODA->Info(name => "Pogodynka", version => RELEASE); if(!(defined($status))){ print "BLAD: brak polaczenia z serwerem jabbera \n"; exit(0); } my @result = $POGODA->AuthSend(username => USERNAME, password => PASSWORD, resource => RESOURCE); if ($result[0] ne "ok"){ print "BLAD: brak autoryzacji! \n"; print "kod bledu: \n"; print "$result[0] - $result[1]" . "\n"; exit(0); } #zostal zalogowany - teraz ustalamy info w rosterku :D #pobieranie listy z rosterka :D my %roster = $POGODA->RosterGet(); #send presence- ustalanie opisow etc $POGODA->PresenceSend(show=>"available", status=>"Pogodynka ". RELEASE ." - bot", priority=>PRIORITY); while(defined($POGODA->Process())) {} print "BLAD: polaczenie zostalo zabite \n"; exit(0); sub Stop { print "Wuychodzenie z programu ...\n"; $POGODA->Disconnect(); exit(0); } sub GetInfo { #zmienne lokalne my $sid=shift; my $message=shift; #typ wiadomosci oraz do kogo my $type = $message->GetType(); my $fromJID = $message->GetFrom("jid"); #wiadomosc od kogo -nick my $from = $fromJID->GetUserID(); # caly jid my $fromJIDs = $message->GetFrom('jid')->GetJID('base'); my $resource = $fromJID->GetResource(); my $subject = $message->GetSubject(); my $body = $message->GetBody(); my $text = ""; my $text2 =""; #my $icon =-1; my $code = $converterISO->convert($body); my @codes = split(/ /, $code); #wysylanie wiadomosci - definicje $codes[0]=lc($codes[0]); #nie lapie polskich znaczkow:/ $message = new Net::Jabber::Message; $message->SetMessage(to => $fromJID, type => "chat"); #help if ($codes[0] eq "help" || $codes[0] eq "pomoc"){ $text = "Prosze podac nazwe miasta z ktorego chcesz pogode polecenia: - pomoc (help) - wyswietla pomoc ogolna - lista (list) - wyswietla liste dostepnych miejscowosci - lista (list) pomoc (help) - wyswietla pomoc do polecenia lista - uzytkownicy (users) - lista zapisanych osob ( administrator ) - uptime - czas zycia bota ;) - opis - zmiana opisu bota ( administrator ) - jako drugi parametr przy nazwie miasta mozemy podac \"info\" lub \"onet\" wybierajac w ten sposob zrodlo pogody Autor: Patryk Kowalczyk, versja : " . RELEASE ; } elsif($codes[0] eq "opis"){ if ($fromJIDs eq ADMIN || $fromJIDs eq ADMIN2 ){ my ($opis, $temp); foreach (@codes){ $opis.=$_." ";} ($temp, $opis)=split(/opis / ,$opis); $POGODA->PresenceSend(show=>"available", status=>$opis, priority=>PRIORITY); }else{ $text="Nie masz praw do administracji botem";} } elsif ($codes[0] eq "uptime" ){ $text = "Uptime: ".Delta_Format(DateCalc("epoch $^T","now"),0,"%dhd %hvh %mvm %svs"); } elsif ($codes[0] eq "users" || $codes[0] eq "uzytkownicy"){ $text.= "\n" .ctime(); if ($fromJIDs eq ADMIN || $fromJIDs eq ADMIN2 ){ foreach ( keys (%roster) ){ $text.= "\n". $_; } }else{ $text="Nie masz praw do administracji botem";} } elsif ($codes[0] eq "lista"|| $codes[0] eq "list" ){ $text.= "\n". ctime()."\n"; my %miasta=(); if ($#codes == 0 ){ $miasta{$_}++ for (keys %{$code_pogodainfo->{code}}); $miasta{$_}++ for (keys %{$code_onet->{code}}); $text.= "$_, " for (sort keys(%miasta)); }else{ $codes[1]=lc($codes[1]); if($codes[1] eq "onet"){ $miasta{$_}++ for (keys %{$code_onet->{code}}); $text.= "$_, " for (sort keys(%miasta)); }elsif($codes[1] eq "info"){ $miasta{$_}++ for (keys %{$code_onet->{code}}); $text.= "$_, " for (sort keys(%miasta)); }elsif($codes[1] eq "zrodla" ||$codes[1] eq "source" ){ $text= "dostepne zrodla: onet, info"; }elsif($codes[1] eq "help" || $codes[1] eq "pomoc"){ $text="skladnia polecenia lista : lista zrodlo , dostepne zrodla: onet, info, wszystkie(all)";} } } else{ $codes[0] =~ s/³|£/l/g; #nie wiem czemu ale lc() nie lapie plskich znaczkow :/ $codes[0] =~ s/ó|Ó/o/g; $codes[0] =~ s/ê|Ê/e/g; $codes[0] =~ s/¶|¦/s/g; $codes[0] =~ s/±|¡/a/g; $codes[0] =~ s/æ|Æ/c/g; $codes[0] =~ s/¿|¯/z/g; $codes[0] =~ s/¼|¬/z/g; $codes[0] =~ s/ñ|Ñ/n/g; my $code2 = $code_pogodainfo->{code}->{$codes[0]}; $code2 = $code2.""; if ($#codes > 0){ $codes[1]=lc($codes[1]);} if ($#codes == 0 || ($codes[1] eq "info") ){ unless ($code2 eq ""){ my $request = HTTP::Request->new('GET', 'http://www.pogoda.info/index.php?id='.$code2); #pobieranie stronki my $ua = LWP::UserAgent->new; $ua->agent("Opera 9.1 (X11; I; FreeBSD 6.2)"); $ua->timeout(10); my $response = $ua->request($request); my $content = $response->content; if ($response->is_error) { printf STDERR $response->status_line, "\n"; } elsif($response->is_success){ unless ( $text ){ my ($temp, $windk, $wind, $hum, $UV, $press, $conds, $curr, $min, $max); $content =~ s/( )|(º)|(\n)/ /g; $content =~ s/(<[^>]*>)//g; $content =~ s/(::)|(.:)|(:.)|(\'\); \/\/-->)|(\.)//g; ($temp) = ($content =~ /odczuwan \s*([-\d]+)/i); if(defined $temp){$temp.=' C';$content = $';} else{$temp='-'} ($windk) = ($content =~ /wiat \s*(\w+( \d+)?)/i); ($wind) = ($content =~ /\s*([-\d]+)/i); # if($wind =~ /\d/) { if($format eq 'F') { $wind.= ' mph'; } else {$wind.=' km/h'}; } if(defined $wind) {$wind.=' km/h';$content = $';} else{$wind='-'} ($hum) = ($content =~ /Wilgotno¶ \s*([-\d]+)/i); if(defined $hum){$hum.=' %';$content = $';} else{$hum='-'} ($UV) = ($content =~ /\*U \s*([-\d]+)/i); if(defined $UV){$UV.='';$content = $';} else{$UV='-'} ($press) = ($content =~ /nieni \s*([-\d]+)/i); if(defined $press){$press.=' hPa';$content = $';} else{$press='-'} ($conds) = ($content =~ /warunki \s*(\w\w\w\w\w\w)/i); if(defined $conds){$conds.='';$content = $';} else{$conds='-'} if ($conds eq "przewa" ){ $conds = "Przewa¿nie Pochmurno"; } # bugowate !!! if ($conds eq "niewie" ){ $conds = "Niewielkie zachmurzenie"; } # to samo if ($conds eq "przejr" ){ $conds = "Przejrzyste Niebo"; } ($curr) = ($content =~ / \s*([-\d]+)/i); if(defined $curr){$curr.=' C';$content = $';} else{$curr='-'} ($max) = ($content =~ /max\s*([-\d]+)/i); if(defined $max){$max.=' C';$content = $';} else{$max='-'} ($min) = ($content =~ /min\s*([-\d]+)/i); if(defined $min){$min.=' C';$content = $';} else{$min='-'} $text = "\n Temperatura: $curr Temp_odczuwalna: $temp Wiatr: $wind Kierunek Wiatru $windk Wilgontosc: $hum Cisnienie: $press Promieniowanie UV: $UV Warunki atmosferyczne: $conds T_max: $max T_min: $min"; } } #elsif } #unless else {$text = "\n Sprawdz czy twoje miasto jest na liscie dostepnych w info \n"} } ###########################################ONET if ($#codes == 0 || $codes[1] eq "onet"){ my $code3 = $code_onet->{code}->{$codes[0]}; $code3 = $code3.""; unless ($code3 eq ""){ my $request2 = HTTP::Request->new('GET', 'http://pogoda.onet.pl/1,'.$code3.',38,miasto.html'); #pobieranie stronki my $ua2 = LWP::UserAgent->new; $ua2->agent("Opera 9.1 (X11; I; FreeBSD 6.2)"); $ua2->timeout(10); my $response2 = $ua2->request($request2); my $content = $response2->content; if ($response2->is_error) { printf STDERR $response2->status_line, "\n"; } elsif($response2->is_success){ unless ( $text2 ){ my ($spierwszy, $wkrotce, $wiatr, $temp, $snieg, $deszcz, $press, $wiatr2, $temp2, $snieg2, $deszcz2, $press2); $content =~ s/(<[^>]*>)//g; if( $content =~ /PolskaPrognoza pogody/ ) { $content = $'; } else { $text = "Internal error"; } if( $content =~ /MC-Wetter/ ) { $content = $`; } else { $text = "Internal error"; } #teraz ($temp) = ($content =~ /Temp.:\s*([-\d]+)/i); if(defined $temp){$temp.=' C';$content = $';} else{$temp='-'} ($press) = ($content =~ /Ci¶n.:\s*([-\d]+)/i); if(defined $press){$press.=' hPa';$content = $';} else{$press='-'} ($wiatr) = ($content =~ /Wiatr:\s*([-\d]+)/i); if(defined $wiatr){$wiatr.=' km/h';$content = $';} else{$wiatr='-'} ($snieg) = ($content =~ /nieg:\s*([-\d]+)/i); if(defined $snieg){$snieg.=' mm';$content = $';} else{$snieg='-'} ($deszcz) = ($content =~ /Deszcz:\s*([-\d]+)/i); if(defined $deszcz){$deszcz.=' mm';$content = $';} else{$deszcz='-'} ($wkrotce) = ($content =~ /Wkrótce \s*([-\d]+)/i); if(defined $wkrotce){$wkrotce.='';$content = $';} else{$wkrotce='-'} #Wkrotece ($temp2) = ($content =~ /Temp.:\s*([-\d]+)/i); if(defined $temp2){$temp2.=' C';$content = $';} else{$temp2='-'} ($press2) = ($content =~ /Ci¶n.:\s*([-\d]+)/i); if(defined $press2){$press2.=' hPa';$content = $';} else{$press2='-'} ($wiatr2) = ($content =~ /Wiatr:\s*([-\d]+)/i); if(defined $wiatr2){$wiatr2.=' km/h';$content = $';} else{$wiatr2='-'} ($snieg2) = ($content =~ /nieg:\s*([-\d]+)/i); if(defined $snieg2){$snieg2.=' mm';$content = $';} else{$snieg2='-'} ($deszcz2) = ($content =~ /Deszcz:\s*([-\d]+)/i); if(defined $deszcz2){$deszcz2.=' mm';$content = $';} else{$deszcz2='-'} #szczegolowa $content =~ s/( )|(º)|(\n)//g; $text2= "\nPogoda Onet:\n Teraz: \n Temperatura: $temp \n Cisnienie: $press \n Wiatr: $wiatr \n Snieg: $snieg \n Deszcz: $deszcz \nWkrotce: Godziny ( $wkrotce ) \n Temperatura: $temp2 \n Cisnienie: $press2 \n Wiatr: $wiatr2 \n Snieg: $snieg2 \n Deszcz: $deszcz2"; } } #elsif } #unless- else {$text2 = "\n Sprawdz czy twoje miasto jest dostepne w bazie onetu"} } unless ($#codes == 0 || $codes[1] eq "onet" ||$codes[1] eq "info" ){ $text = "\n pierwszy czlon polecenia to nazwa miasta, jako paramet podaj zrodlo informacji pogodowych(opcjonalnie), polecenie: \"lista(list) zrodla(source)\""}; ####################################ONET KONIEC ############################### }#else $text = $converterUTF->convert($text); $text2 = $converterUTF->convert($text2); $message->InsertRawXML(''.name2hex_xml($text).name2hex_xml($text2).''); $POGODA->Send($message); }#cala funkcja GetInfo sub InPresence { my $sid = shift; my $presence = shift; my $to = USERNAME."\@".SERVER; my $from = $presence->GetFrom(); my $type = $presence->GetType(); if ( $type eq 'subscribe' ) { sendPresence($presence, $from, $to, 'subscribe', ); sendPresence($presence, $from, $to, 'subscribed', ); } } sub sendPresence { my ($pres, $to, $from, $type, $show, $status) = @_; $pres->SetType($type); $pres->SetShow($show); $pres->SetStatus($status); $pres->SetTo($to); $pres->SetFrom($from); $pres->SetShow("Pogodynka"); $POGODA->Send($pres); } sub InIQ{ my $sid = shift; my $iq = shift; my $from = $iq->GetFrom(); $from=$from.""; my $type = $iq->GetType(); my $query = $iq->GetQuery(); my $xmlns = $query->GetXMLNS(); print "===\n"; print "IQ\n"; print " From $from\n"; print " Type: $type\n"; print " XMLNS: $xmlns"; print "===\n"; print $iq->GetXML(),"\n"; print "===\n"; } sub onAuth { print "Polaczony...\n"; } # # sub log1 { # # WARN # my $msg = shift; # # return unless VERBOSE >= 1; # print STDERR ctime()." WARN: $msg\n"; # } # # sub log2 { # # INFO # my $msg = shift; # # return unless VERBOSE >= 2; # print ctime()." INFO: $msg\n"; # } # # sub log3 { # # DBUG # my $msg = shift; # # return unless VERBOSE >= 3; # print ctime(). " DBUG: $msg\n"; # }