First draft
This commit is contained in:
commit
b5552ced50
8 changed files with 214 additions and 0 deletions
3
.hgignore
Normal file
3
.hgignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
syntax: glob
|
||||
|
||||
perl5
|
4
bin/app.pl
Executable file
4
bin/app.pl
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env perl
|
||||
use Dancer;
|
||||
use SeriesMailer::App;
|
||||
dance;
|
17
config.yml.dist
Normal file
17
config.yml.dist
Normal file
|
@ -0,0 +1,17 @@
|
|||
# This is the main configuration file of your Dancer app
|
||||
# env-related settings should go to environments/$env.yml
|
||||
# all the settings in this file will be loaded at Dancer's startup.
|
||||
|
||||
# Your application's name
|
||||
appname: "SeriesMailer::App"
|
||||
|
||||
# when the charset is set to UTF-8 Dancer will handle for you
|
||||
# all the magic of encoding and decoding. You should not care
|
||||
# about unicode within your app when this setting is set (recommended).
|
||||
charset: "UTF-8"
|
||||
|
||||
api_key: "FILLIN"
|
||||
user: "USERNAME"
|
||||
password: "PASSWORD"
|
||||
|
||||
# cpanm Dancer JSON WWW::Mechanize YAML Digest::SHA1
|
27
environments/development.yml
Normal file
27
environments/development.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
# configuration file for development environment
|
||||
|
||||
# the logger engine to use
|
||||
# console: log messages to STDOUT (your console where you started the
|
||||
# application server)
|
||||
# file: log message to a file in log/
|
||||
logger: "console"
|
||||
|
||||
# the log level for this environment
|
||||
# core is the lowest, it shows Dancer's core log messages as well as yours
|
||||
# (debug, info, warning and error)
|
||||
log: "debug"
|
||||
|
||||
# should Dancer consider warnings as critical errors?
|
||||
warnings: 1
|
||||
|
||||
# should Dancer show a stacktrace when an error is caught?
|
||||
show_errors: 1
|
||||
|
||||
# auto_reload is a development and experimental feature
|
||||
# you should enable it by yourself if you want it
|
||||
# Module::Refresh is needed
|
||||
#
|
||||
# Be aware it's unstable and may cause a memory leak.
|
||||
# DO NOT EVER USE THAT FEATURE IN PRODUCTION
|
||||
# OR TINY KITTENS SHALL DIE WITH LOTS OF SUFFERING
|
||||
auto_reload: 0
|
17
environments/production.yml
Normal file
17
environments/production.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
# configuration file for production environment
|
||||
|
||||
# only log warning and error messsages
|
||||
log: "warning"
|
||||
|
||||
# log message to a file in logs/
|
||||
logger: "file"
|
||||
|
||||
# don't consider warnings critical
|
||||
warnings: 0
|
||||
|
||||
# hide errors
|
||||
show_errors: 0
|
||||
|
||||
# cache route resolution for maximum performance
|
||||
route_cache: 1
|
||||
|
110
lib/SeriesMailer/App.pm
Normal file
110
lib/SeriesMailer/App.pm
Normal file
|
@ -0,0 +1,110 @@
|
|||
package SeriesMailer::App;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use WWW::Mechanize;
|
||||
use MIME::Base64;
|
||||
use Digest::SHA1 qw(sha1 sha1_hex sha1_base64);
|
||||
|
||||
our $VERSION = '0.1';
|
||||
|
||||
get '/list' => sub {
|
||||
my $today = "TODAY";
|
||||
forward '/list/' . $today;
|
||||
};
|
||||
|
||||
get '/list/:date' => sub {
|
||||
forward '/list/' . params->{date} . '/7';
|
||||
};
|
||||
|
||||
get '/list/:date/:days' => sub {
|
||||
my $browser = WWW::Mechanize->new();
|
||||
|
||||
$browser->default_header(
|
||||
Authorization => 'Basic ' . encode_base64( setting("user") . ':' . setting("password") ) );
|
||||
|
||||
my $list_url = "http://api.trakt.tv/user/calendar/shows.json/" .setting("api_key"). "/" .setting("user"). "/";
|
||||
if (params->{date} =~ m/^\d+$/) {
|
||||
$list_url = $list_url . params->{date} . '/' . params->{days};
|
||||
}
|
||||
|
||||
eval {
|
||||
$browser->get($list_url);
|
||||
} or do {
|
||||
return "Error while getting server answer";
|
||||
};
|
||||
|
||||
my $json_content = from_json($browser->content());
|
||||
|
||||
my $user_text;
|
||||
|
||||
foreach my $date (@{$json_content}) {
|
||||
foreach my $episode (@{$date->{episodes}}) {
|
||||
$user_text .= $date->{date} . ": " . $episode->{show}->{title} . "\n";
|
||||
|
||||
my $ep_title = sprintf "%02d",$episode->{episode}->{season};
|
||||
$ep_title .= "x" . sprintf "%02d",$episode->{episode}->{number};
|
||||
$ep_title .= " - " . $episode->{episode}->{title};
|
||||
|
||||
$user_text .= " " . $ep_title . "\n";
|
||||
$user_text .= " " . $episode->{episode}->{overview} . "\n";
|
||||
|
||||
my $validation_url = uri_for('/seen') . "/";
|
||||
$validation_url .= $episode->{show}->{tvdb_id} . "/";
|
||||
$validation_url .= $episode->{episode}->{season} . "/";
|
||||
$validation_url .= $episode->{episode}->{number} . "/";
|
||||
|
||||
my $validation_token = setting("user");
|
||||
$validation_token .= $episode->{show}->{tvdb_id};
|
||||
$validation_token .= $episode->{episode}->{season};
|
||||
$validation_token .= $episode->{episode}->{number};
|
||||
|
||||
$validation_url .= sha1_hex($validation_token);
|
||||
|
||||
$user_text .= " " . $validation_url . "\n";
|
||||
$user_text .= "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $user_text;
|
||||
};
|
||||
|
||||
get '/seen/:serie_id/:season/:episode/:secret' => sub {
|
||||
|
||||
my $validation_token = setting("user");
|
||||
$validation_token .= params->{serie_id};
|
||||
$validation_token .= params->{season};
|
||||
$validation_token .= params->{episode};
|
||||
|
||||
if ( sha1_hex($validation_token) ne params->{secret} ) {
|
||||
debug "Validation should be " . sha1_hex($validation_token) . " but is " . params->{secret};
|
||||
send_error("Not allowed", 403);
|
||||
}
|
||||
my $browser = WWW::Mechanize->new();
|
||||
|
||||
my %test_ei = ("season" => params->{season}, "episode" => params->{episode});
|
||||
my @test_ep = (\%test_ei);
|
||||
my %test_a = (
|
||||
"username" => setting("user"),
|
||||
"password" => sha1_hex(setting("password")),
|
||||
"tvdb_id" => params->{serie_id},
|
||||
"episodes" => (\@test_ep) );
|
||||
|
||||
my $json_encode = to_json(\%test_a);
|
||||
debug "Seen JSON sent is: " . $json_encode;
|
||||
|
||||
my $seen_url = "http://api.trakt.tv/show/episode/seen/" . setting("api_key");
|
||||
|
||||
my $req = HTTP::Request->new(POST => $seen_url);
|
||||
$req->content_type('application/json');
|
||||
$req->content($json_encode);
|
||||
|
||||
$browser->request($req);
|
||||
|
||||
my $req_answer = from_json($browser->content());
|
||||
|
||||
debug to_json($req_answer);
|
||||
|
||||
return $req_answer->{message};
|
||||
};
|
||||
|
||||
true;
|
18
public/404.html
Normal file
18
public/404.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Error 404</title>
|
||||
<link rel="stylesheet" href="/css/error.css" />
|
||||
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Error 404</h1>
|
||||
<div id="content">
|
||||
<h2>Page Not Found</h2><p>Sorry, this is the void.</p>
|
||||
</div>
|
||||
<div id="footer">
|
||||
Powered by <a href="http://perldancer.org/">Dancer</a>.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
18
public/500.html
Normal file
18
public/500.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Error 500</title>
|
||||
<link rel="stylesheet" href="/css/error.css" />
|
||||
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Error 500</h1>
|
||||
<div id="content">
|
||||
<h2>Internal Server Error</h2><p>Wooops, something went wrong</p>
|
||||
</div>
|
||||
<div id="footer">
|
||||
Powered by <a href="http://perldancer.org/">Dancer</a>.
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Reference in a new issue