#!/usr/bin/env perl use strict; use warnings; use LWP::Simple; use URI::Escape; use utf8; use Math::Trig; $| = 1; binmode(STDOUT, ':utf8'); use Data::Dumper; use AnyEvent::XMPP::IM::Connection; use AnyEvent::XMPP::Ext::Disco; use AnyEvent::XMPP::Ext::MUC; my $nick = "O_O"; my $room = 'sg@conference.jabber.ru'; my $own_jid = "azq2\@jabber.ru"; my $cond = AnyEvent->condvar; my $conn = AnyEvent::XMPP::IM::Connection->new( jid => $own_jid, password => '', resource => "xuj" ); my $disco = AnyEvent::XMPP::Ext::Disco->new; my $muc = AnyEvent::XMPP::Ext::MUC->new(disco => $disco); $conn->add_extension($disco); $conn->add_extension($muc); $conn->reg_cb(contact_request_subscribe => sub { my (undef, undef, $contact) = @_; $contact->send_subscribed; }); $conn->reg_cb(message => sub { my (undef, $msg) = @_; print "message = ".$msg->body."\n"; my $out_msg = parse_cmd($msg->body); if (defined $out_msg) { my $reply = $msg->make_reply; $reply->add_body($out_msg); $reply->send; } }); $conn->reg_cb(session_ready => sub { $muc->join_room($conn, $room, $nick); }); $muc->reg_cb(message => sub { my (undef, undef, $msg) = @_; print "body = ".$msg->body."\n"; return if $msg->is_delayed; my $body = $msg->body; if ($msg->type && $msg->type eq 'groupchat') { return if ($msg->from eq $own_jid); if ($body =~ /^$nick([:,])\s*(.*)/) { my $from = $msg->from_nick; $body = $2; } else { #return; } } my $out_msg = parse_cmd($body); if (defined $out_msg) { my $reply = $msg->make_reply; $reply->add_body($out_msg); $reply->send; return; } if ($body =~ /Your messages to/) { AnyEvent::XMPP::IM::Message->new ( body => $msg->from.": ".$msg->body, to => "azq2\@ya.ru" )->send($conn); } }); my @money_types = ('ATS','AUD','BEF','BYR','CAD','CHF','CNY','DEM','DKK','EEK', 'EGP','ESP','EUR','FIM','FRF','GBP','GRD','IEP','ISK','ITL', 'JPY','KGS','KWD','KZT','LTL','NLG','NOK','PTE','SDR','SEK', 'SGD','TRL','TRY','UAH','USD','XDR','YUN','RUB'); my @months = ("Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"); sub parse_cmd { my ($cmd) = @_; my @args = split(/\s+/, $cmd); if ($args[0] eq "cy") { my $from = undef; my $to = undef; my $sum = 0; for (my $i = 1; $i <= 3; ++$i) { last if (!defined($args[$i])); if ($args[$i] =~ /^\d+(\.\d+)?$/) { $sum = $args[$i]; } elsif (!defined($from)) { $from = uc($args[$i]); } elsif (!defined($to)) { $to = uc($args[$i]); } } if (!defined($to) || !defined($from) || !($from ~~ @money_types) || !($to ~~ @money_types)) { return $args[0]." \nВалюты: ".join(", ", @money_types); } my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); my $data = get "http://quote.rbc.ru/cgi-bin/conv/external/converter.shtml?source=cb.0&tid_from=$from&commission=1.0&tid_to=$to&summa=$sum&day=$mday&mon=".uri_escape_utf8($months[$mon - 1])."&year=".(1900 + $year); if ($data =~ /([\d\.]+)<\/td>\s+<\/tr>\s+\s+[^<>]+<\/td>\s+([\.\d]+)<\/td>\s+<\/tr>\s+\s+[a-z]+<\/td>\s+([\.\d]+)<\/td>/sui) { return "$1 $from = $3 $to (Курс: 1 $from = $2 $to)"; } } elsif ($args[0] eq "dec2bin") { return dec2bin($args[1]); } elsif ($args[0] eq "bin2dec") { return bin2dec($args[1]); } elsif ($args[0] eq "hex2dec") { return hex($args[1]); } elsif ($args[0] eq "dex2hex") { return sprintf("%d", $args[1]); } elsif ($args[0] eq "icalc") { my $code = " ".substr($cmd, length $args[0]); $code =~ s/([^\d\+\-\*\/\^\%\|\&\sa-z\,><\(\)])//sig; $code =~ s/([^a-z0-9])([a-z][a-z0-9]*)/check_calc_function($1, $2)/sieg; my $out; $out = eval("\$out = ".$code.";"); $out = "" if (!defined $out); $out .= $@ if ($@); print "code = '$code'\n'$out'\n"; return $out; } return undef; } our %calc_functions = ( "pow" => sub { return $_[0] ** $_[1] }, "sin" => sub { return sin($_[0]); }, "cos" => sub { return cos($_[0]); }, "atan2" => sub { return atan2($_[0], $_[1]); }, "exp" => sub { return exp($_[0]); }, "hex" => sub { return hex($_[0]); }, "int" => sub { return int($_[0]); }, "log" => sub { return log($_[0]); }, "oct" => sub { return oct($_[0]); }, "rand" => sub { return rand($_[0]); }, "time" => sub { return time(); }, "sqrt" => sub { return sqrt($_[0]); }, "abs" => sub { return $_[0] < 0 ? -$_[0] : $_[0]; }, "max" => sub { return $_[0] > $_[1] ? $_[0] : $_[1]; }, "min" => sub { return $_[0] < $_[1] ? $_[0] : $_[1]; }, "tan" => sub { return tan($_[0]); }, "csc" => sub { return csc($_[0]); }, "cosec" => sub { return cosec($_[0]); }, "sec" => sub { return sec($_[0]); }, "cot" => sub { return cot($_[0]); }, "cotan" => sub { return cotan($_[0]); }, "asin" => sub { return asin($_[0]); }, "acos" => sub { return acos($_[0]); }, "atan" => sub { return atan($_[0]); }, "atan2" => sub { return atan2($_[0], $_[0]); }, "acsc" => sub { return acsc($_[0]); }, "acosec" => sub { return acosec($_[0]); }, "asec" => sub { return asec($_[0]); }, "acot" => sub { return acot($_[0]); }, "acotan" => sub { return acotan($_[0]); }, "sinh" => sub { return sinh($_[0]); }, "cosh" => sub { return cosh($_[0]); }, "tanh" => sub { return tanh($_[0]); }, "csch" => sub { return csch($_[0]); }, "cosech" => sub { return cosech($_[0]); }, "sech" => sub { return sech($_[0]); }, "coth" => sub { return coth($_[0]); }, "cotanh" => sub { return cotanh($_[0]); }, "asinh" => sub { return asinh($_[0]); }, "acosh" => sub { return acosh($_[0]); }, "atanh" => sub { return atanh($_[0]); }, "acsch" => sub { return acsch($_[0]); }, "acosech" => sub { return acosech($_[0]); }, "asech" => sub { return asech($_[0]); }, "acoth" => sub { return acoth($_[0]); }, "acotanh" => sub { return acotanh($_[0]); }, "pi" => sub { return pi(); }, "pi2" => sub { return pi2(); }, "pi4" => sub { return pi4(); }, "pip2" => sub { return pip2(); }, "pip4" => sub { return pip4(); }, "deg2rad" => sub { return deg2rad($_[0]); }, "grad2rad" => sub { return grad2rad($_[0]); }, "rad2deg" => sub { return rad2deg($_[0]); }, "grad2deg" => sub { return grad2deg($_[0]); }, "deg2grad" => sub { return deg2grad($_[0]); }, "rad2grad" => sub { return rad2grad($_[0]); }, "dec2bin" => sub { return dec2bin($_[0]); }, "system" => sub { return "bash: ".$_[0].": команда не найдена"; }, ); sub calc { die "function ".$_[0]." not found!" if (!exists $calc_functions{$_[0]}); return $calc_functions{$_[0]}; } sub check_calc_function { return $_[0]."&{calc('".$_[1]."')}"; } sub dec2bin { my $str = unpack("B32", pack("N", shift)); $str =~ s/^0+(?=\d)//; return $str; } sub bin2dec { return unpack("N", pack("B32", substr("0" x 32 . shift, -32))); } $conn->connect; $cond->recv;