Skip to content

Instantly share code, notes, and snippets.

@ynonp
Created March 5, 2015 21:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ynonp/d7542ac943a0a7e9214d to your computer and use it in GitHub Desktop.
Save ynonp/d7542ac943a0a7e9214d to your computer and use it in GitHub Desktop.
A url shortener written in Mojolicious
#!/usr/bin/env perl
use Mojolicious::Lite;
use Mojo::Util qw/b64_encode b64_decode/;
use DBI;
my $database = 'tinyurl.db';
my $data_source = "dbi:SQLite:dbname=$database";
my $dbh = DBI->connect(
$data_source,
undef,
undef,
{
RaiseError => 1,
PrintError => 0,
AutoCommit => 1,
}
);
my $add_sth = $dbh->prepare("INSERT INTO urls (short, long) VALUES(?,?)");
my $fetch_sth = $dbh->prepare("SELECT short,long FROM urls WHERE short = ?");
my ($idx) = $dbh->selectrow_array("SELECT count(*) FROM urls");
# Documentation browser under "/perldoc"
plugin 'PODRenderer';
get '/' => sub {
my $self = shift;
$self->render('index');
};
post '/' => sub {
my ($self) = @_;
# fetch parameter url from request
my $long = $self->param('url');
# base64 encode
chomp( my $short = b64_encode $idx );
# remove trailing =
$short =~ s/=*$//;
$idx++;
# add mapping to %urls hash
$add_sth->execute($short, $long);
# render HTML passing the short URL we created and original one
$self->render('index', result => $short, original => $long);
};
get '/:url' => sub {
my ($self) = @_;
# get URL from path
my $url = $self->param('url');
$fetch_sth->execute($url);
my $data_ref = $fetch_sth->fetchrow_hashref;
# throw an exception if no mapping is found for the URL
die "Missing url: $url" if ! $data_ref;
# send an HTTP Redirect to the long URL
$self->redirect_to($data_ref->{long});
};
app->start;
__DATA__
@@ index.html.ep
% layout 'default';
% title 'Welcome';
Welcome to the Mojolicious real-time web framework!
@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<style>
form {
width: 400px;
}
.control-group {
margin: 20px;
}
.control-group label {
display:inline-block;
min-width: 150px;
}
input {
width:140px;
}
input[type="submit"] {
float:right;
margin-right:80px;
}
</style>
</head>
<body>
<form method="POST" action="/">
<div class="control-group">
<label for="long-url">Full Address</label>
<input type="text" name="url" id="long-url" value="<%= defined(stash('original')) && stash('original') %>" />
</div>
<div class="control-group">
<label for="short-url">Short URL (result)</label>
<input type="text" id="short-url" readonly=yes value="<%= defined(stash('result')) && stash('result') %>" />
</div>
<input type="submit" value="Shorten" />
</form>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment