Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

working

  • Loading branch information...
commit 9e2c759ff60af40558cb31be0dad4e9a466c6d4a 0 parents
Jonathan Rockway authored
Showing with 99 additions and 0 deletions.
  1. +54 −0 lib/Unshorten.pm
  2. +45 −0 lib/Unshorten/Model.pm
54 lib/Unshorten.pm
@@ -0,0 +1,54 @@
+use MooseX::Declare;
+use Unshorten::Model;
+use POE;
+use HTTP::Engine::Role; # for type constraints
+use feature 'say';
+
+class Unshorten with MooseX::Getopt with MooseX::Runnable with HTTP::Engine::Role {
+ has '_engine_type' => ( is => 'ro', default => 'POE' );
+
+ has 'dsn' => (
+ is => 'ro',
+ isa => 'Str',
+ required => 1,
+ default => 'hash',
+ documentation => 'DSN of the KiokuDB',
+ );
+
+ has 'model' => (
+ traits => ['NoGetopt'],
+ is => 'ro',
+ isa => 'Unshorten::Model',
+ lazy_build => 1,
+ );
+
+ method _build_model() {
+ return Unshorten::Model->new( dsn => $self->dsn );
+ }
+
+ method handle_request(HTTP::Engine::Request $req){
+
+ my $short = URI->new(substr $req->uri->path, 1);
+
+ my $long = eval { $self->model->unshorten($short) };
+ if(!$long || $@){
+ return HTTP::Engine::Response->new(
+ code => 500,
+ content_type => 'text/plain',
+ body => "An error occurred while shortening '$short': $@",
+ );
+ }
+
+ return HTTP::Engine::Response->new(
+ content_type => 'text/plain',
+ body => $long,
+ );
+ }
+
+ method run() {
+ $self->engine->run;
+ say "Starting server on port ". $self->port;
+ POE::Kernel->run;
+ }
+
+};
45 lib/Unshorten/Model.pm
@@ -0,0 +1,45 @@
+use MooseX::Declare;
+
+class Unshorten::Model extends KiokuX::Model {
+ use Moose::Util::TypeConstraints;
+ use MooseX::Types::URI qw(Uri);
+
+ use AnyEvent::HTTP qw(http_head);
+
+ method unshorten(Uri $url) {
+ return $self->_lookup_or_cache($url, sub {
+ $self->_lookup(@_),
+ });
+ }
+
+ method _lookup(Uri $url) {
+ my $done = AnyEvent->condvar;
+
+ http_head $url, sub {
+ my ($data, $headers) = @_;
+ my $long_url = eval { URI->new($headers->{URL}) };
+ confess 'Failed to get a URL' unless $url;
+ $done->send($long_url);
+ };
+
+ return $done->recv;
+ }
+
+ method _lookup_or_cache(Uri $url, CodeRef $shortener) {
+ my $scope = $self->new_scope;
+ my $shortened = $self->lookup("$url");
+ return $shortened if $shortened;
+
+ $shortened = $shortener->($url);
+
+ # "Unknown reason" because the shortener should die if it knows
+ # the reason
+ confess "Unable to shorten '$url': Unknown reason"
+ unless $shortened;
+
+ $self->store("$url" => $shortened);
+
+ return $shortened;
+ }
+
+};
Please sign in to comment.
Something went wrong with that request. Please try again.