Amethyst

 view release on metacpan or  search on metacpan

Amethyst/Brain/Infobot/Module/Exchange.pm  view on Meta::CPAN

package Amethyst::Brain::Infobot::Module::Exchange;

use strict;
use vars qw(@ISA
		%CODE2CODE %TLD2CODE %CURR2CODE %COUNTRY2CODE
		%CODE2CURR
				$REFERER $CONVERTER);
use Data::Dumper;
use POE;
use POE::Component::Client::UserAgent;
use HTTP::Request::Common;
use HTTP::Response;
use LWP::UserAgent;	# For init
use Amethyst::Message;
use Amethyst::Brain::Infobot;
use Amethyst::Brain::Infobot::Module;

@ISA = qw(Amethyst::Brain::Infobot::Module);

sub new {
	my $class = shift;
	my $self = $class->SUPER::new(
					Name		=> 'Exchange',
					Regex		=> qr/^(?:ex)?change\s+(\d+)\s+(\w+)\s+(?:into|to|for)\s+(\w+)/x,
					Usage		=> '(ex)?change 100 USD for DEM',
					Description	=> "Convert currencies",
					@_
						);

	return bless $self, $class;
}

sub init {
	my $self = shift;

	eval { spawn POE::Component::Client::UserAgent; };
	if ($@) {
		die $@ unless $@ =~ /^alias is in use by another session/;
	}

	$REFERER = 'http://www.xe.net/ucc/full.shtml';
	$CONVERTER ='http://www.xe.net/ucc/convert.cgi';

	my $ua = new LWP::UserAgent;
	my $uri = new URI($REFERER);
	my $request = new HTTP::Request(GET => $uri);

	print STDERR "Requesting $uri\n";

	my $response = $ua->request($request);

	unless ($response->is_success) {
		print STDERR $response->error_as_HTML;
		die "Failed to contact currency converter";
	}

	my $html = $response->content;
	$html =~ s|.*<SELECT[^>]*>(.*?)</SELECT.*|$1|s;

	my @data =
			map {
				[ $_ =~ /=\"([^\"]+)\">(.*?)(?:,\s*(.*?))? \(...\)</g ]
			}
			grep /\S/,
			split /\n/, $html;

	%CURR2CODE = map { defined $_->[2]
					? (lc $_->[2] => uc $_->[0])
					: () } @data;
	%COUNTRY2CODE = map { lc $_->[1] => uc $_->[0] } @data;
	%CODE2CODE = map { lc $_->[0] => uc $_->[0] } @data;

	%CODE2CURR = reverse %CURR2CODE;

TLD:
	while (<DATA>) {
		chomp;

		my ($tld, $country) = split /\s+/, $_, 2;
		if (exists $COUNTRY2CODE{lc $country}) {
			$TLD2CODE{lc $tld} = $COUNTRY2CODE{lc $country};
			next TLD;
		}

		($tld, $country) = split /\s+/, $_, 3;
		if (exists $COUNTRY2CODE{lc $country}) {
			$TLD2CODE{lc $tld} = $COUNTRY2CODE{lc $country};
			next TLD;
		}

		# print STDERR "Unable to identify $_\n";
	}
}

sub action {
    my ($self, $message, $number, $from, $to) = @_;

	$from = lc $from;
	$to = lc $to;

	my @all = (keys %CODE2CODE, keys %CURR2CODE, keys %COUNTRY2CODE,
	keys %TLD2CODE);

	print STDERR join(", ", sort @all);

	my $fcode = $CODE2CODE{$from}

Amethyst/Brain/Infobot/Module/Exchange.pm  view on Meta::CPAN

	my %states = map { $_ => "handler_$_" } qw(
					_start response
						);

	print STDERR "Creating child session for exchange\n";

	POE::Session->create(
		package_states	=> [ ref($self) => \%states ],
		args			=> [ $self, $message, $number, $fcode, $tcode ],
			);

	return 1;
}

sub handler_response {
	my ($kernel, $heap, $session, $pbargs) =
					@_[KERNEL, HEAP, SESSION, ARG1];
	my ($request, $response, $entry) = @$pbargs;

	unless ($response->is_success) {
		my $reply = $heap->{Module}->reply_to($heap->{Message},
						"HTTP Request failed");
		$reply->send;
		print STDERR $response->error_as_HTML;
		return;
	}

	my $html = $response->content;

	unless ($html =~ /Live Rates.*\+1><B>([^\n]*)\n(?:.*)\+1><B>([^\n]*)/si)
	{
		my $reply = $heap->{Module}->reply_to($heap->{Message},
						"Failed to parse response");
		$reply->send;
		print STDERR $response->content;
		return;
	}

	my $out = "$1 = $2";
	$out =~ s/<.*?>/ /g;
	$out =~ s/\s+/ /g;

	my $reply = $heap->{Module}->reply_to($heap->{Message}, $out);
	$reply->send;
}

sub handler__start {
	my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];
	my ($module, $message, $number, $fcode, $tcode) = @_[ARG0..$#_];

	$heap->{Module} = $module;
	$heap->{Message} = $message;

	my $uri = new URI($CONVERTER);
	$uri->query_form(
			From		=> $fcode,
			To			=> $tcode,
			Amount		=> $number,
				);
	$uri = $uri->canonical;
	my $request = new HTTP::Request(GET => $uri);
	$request->referer($REFERER);

	my $postback = $session->postback('response');

	$kernel->post('useragent', 'request',
					request		=> $request,
					response	=> $postback,
						);
}

1;

__DATA__
AF	AFGHANISTAN
AL	ALBANIA
DZ	ALGERIA
AS	AMERICAN SAMOA
AD	ANDORRA
AO	ANGOLA
AI	ANGUILLA
AQ	ANTARCTICA
AG	ANTIGUA AND BARBUDA
AR	ARGENTINA
AM	ARMENIA
AW	ARUBA
AU	AUSTRALIA
AT	AUSTRIA
AZ	AZERBAIJAN
BS	BAHAMAS
BH	BAHRAIN
BD	BANGLADESH
BB	BARBADOS
BY	BELARUS
BE	BELGIUM
BZ	BELIZE
BJ	BENIN
BM	BERMUDA
BT	BHUTAN
BO	BOLIVIA
BA	BOSNIA AND HERZEGOWINA
BW	BOTSWANA
BV	BOUVET ISLAND
BR	BRAZIL
IO	BRITISH INDIAN OCEAN TERRITORY
BN	BRUNEI DARUSSALAM
BG	BULGARIA
BF	BURKINA FASO
BI	BURUNDI
KH	CAMBODIA
CM	CAMEROON
CA	CANADA
CV	CAPE VERDE
KY	CAYMAN ISLANDS
CF	CENTRAL AFRICAN REPUBLIC
TD	CHAD
CL	CHILE
CN	CHINA
CX	CHRISTMAS ISLAND
CC	COCOS (KEELING) ISLANDS
CO	COLOMBIA



( run in 0.454 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )