Permalink
Browse files

implemented basic version that gets data from youtube directly

  • Loading branch information...
1 parent f0707bb commit 5004a46be05a4ca1505958a59f211a7c6ead28e0 @wchristian committed Aug 7, 2012
Showing with 190 additions and 19 deletions.
  1. +25 −10 META.json
  2. +3 −1 README.pod
  3. +4 −0 bin/scenefinity
  4. +58 −6 lib/Web/Scenefinity.pm
  5. +0 −1 share/infinity
  6. +61 −0 share/infinity.html
  7. +38 −0 share/youtube.js
  8. +1 −1 t/basic.t
View
35 META.json
@@ -1,10 +1,10 @@
{
- "abstract" : "#",
+ "abstract" : "web app to endlessly stream random demos",
"author" : [
"Christian Walde <walde.christian@googlemail.com>"
],
"dynamic_config" : 0,
- "generated_by" : "Dist::Zilla version 4.300006, CPAN::Meta::Converter version 2.113640",
+ "generated_by" : "Dist::Zilla version 4.300020, CPAN::Meta::Converter version 2.120921",
"license" : [
"unrestricted"
],
@@ -27,30 +27,45 @@
"prereqs" : {
"configure" : {
"requires" : {
- "ExtUtils::MakeMaker" : "6.30"
+ "ExtUtils::MakeMaker" : "6.30",
+ "File::ShareDir::Install" : "0.03"
}
},
"runtime" : {
"requires" : {
+ "Data::Dumper" : "0",
+ "File::ShareDir" : "0",
+ "HTTP::Tiny" : "0",
+ "JSON" : "0",
+ "List::Util" : "0",
+ "Scalar::Util" : "0",
+ "Sub::Exporter::Simple" : "0",
+ "Text::Xslate" : "0",
+ "Try::Tiny" : "0",
+ "Web::Simple" : "0",
"perl" : "5.006",
- "strictures" : 0
+ "strictures" : "0"
}
},
"test" : {
"requires" : {
- "File::Find" : 0,
- "File::Temp" : 0,
- "Test::InDistDir" : 0,
- "Test::More" : 0,
- "strict" : 0,
- "warnings" : 0
+ "File::Find" : "0",
+ "File::Temp" : "0",
+ "Test::InDistDir" : "0",
+ "Test::More" : "0",
+ "strict" : "0",
+ "warnings" : "0"
}
}
},
"provides" : {
"Web::Scenefinity" : {
"file" : "lib/Web/Scenefinity.pm",
"version" : "0.000001"
+ },
+ "Web::SimpleX::Helper::ActionWithRender" : {
+ "file" : "lib/Web/SimpleX/Helper/ActionWithRender.pm",
+ "version" : "0.000001"
}
},
"release_status" : "stable",
View
4 README.pod
@@ -1,6 +1,6 @@
=head1 NAME
-Web::Scenefinity
+Web::Scenefinity - web app to endlessly stream random demos
=head1 VERSION
@@ -31,10 +31,12 @@ Christian Walde <walde.christian@googlemail.com>
=head1 COPYRIGHT AND LICENSE
+
Christian Walde has dedicated the work to the Commons by waiving all of his
or her rights to the work worldwide under copyright law and all related or
neighboring legal rights he or she had in the work, to the extent allowable by
law.
Works under CC0 do not require attribution. When citing the work, you should
not imply endorsement by the author.
+
View
4 bin/scenefinity
@@ -1,3 +1,7 @@
+#!/usr/bin/perl
use strictures;
+
+package scenefinity;
+
use Web::Scenefinity;
Web::Scenefinity->run_if_script;
View
64 lib/Web/Scenefinity.pm
@@ -11,28 +11,66 @@ package Web::Scenefinity;
use Web::Simple;
use Web::SimpleX::Helper::ActionWithRender qw' mm action ';
-use File::ShareDir 'module_file';
+use File::ShareDir 'dist_dir';
use Text::Xslate;
+use JSON qw' from_json to_json ';
+use HTTP::Tiny;
+use Data::Dumper;
+use List::Util qw( shuffle );
sub share_dir {
- eval { module_dir( __PACKAGE__ ) } || "../share/";
+ eval { dist_dir( "Web-Scenefinity" ) } || "../share/";
}
sub dispatch_request {
- ( "/" => mm( action "infinity" ) );
+ (
+ "/" => mm( action "infinity" ),
+ "/youtube.js" => mm( action "youtube_js" ),
+ "/more_demos" => mm( action "more_demos", "json" ),
+ );
}
sub default_view { "Xslate" }
-sub infinity {
- ['infinity'];
+sub jget {
+ my ( $url ) = @_;
+ my $res = HTTP::Tiny->new->get( $url );
+ die Dumper( $res ) unless $res->{success};
+ return from_json( $res->{content} );
}
+sub author_all_videos {
+ my ( $author ) = @_;
+ my $base =
+ "http://gdata.youtube.com/feeds/api/videos?author=%s&v=2&format=5&start-index=%d&max-results=%d&alt=json";
+ my @videos;
+ my $i = 1;
+ while ( 1 ) {
+ my $all = jget sprintf $base, $author, $i, 50;
+ last if !$all->{feed}{entry};
+ push @videos, @{ $all->{feed}{entry} };
+ $i += 50;
+ }
+ return @videos;
+}
+
+sub more_demos {
+ my @videos = author_all_videos( "Annikras" );
+ @videos = shuffle @videos;
+ @videos = grep $_, @videos[ 0 .. 9 ];
+ my @ids = map $_->{id}{'$t'}, @videos;
+ $_ =~ s/.*video:(.*)/$1/ for @ids;
+
+ return \@ids;
+}
+
+sub infinity { ['infinity.html'] }
+sub youtube_js { ["youtube.js"] }
+
sub render_Xslate {
my ( $self, $result ) = @_;
my $content = Text::Xslate->new( path => $self->share_dir )->render( @{$result} );
[ 200, [ "Content-Type" => "text/html; charset=utf-8" ], [$content], ];
-
}
sub view_error_Xslate {
@@ -41,4 +79,18 @@ sub view_error_Xslate {
[ 500, [ "Content-Type" => "text/html; charset=utf-8" ], [$msg], ];
}
+sub render_json {
+ my ( $self, $result ) = @_;
+ my $content = to_json $result;
+ [ 200, [ "Content-Type" => "text/html; charset=utf-8" ], [$content], ];
+}
+
+sub action_error_json { die $_[1] }
+
+sub view_error_json {
+ my ( $self, $error ) = @_;
+ my $msg = "An error happened during rendering of the page.<br><pre>$error</pre>";
+ [ 500, [ "Content-Type" => "text/html; charset=utf-8" ], [$msg], ];
+}
+
1;
View
1 share/infinity
@@ -1 +0,0 @@
-hello world
View
61 share/infinity.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Scenefinity - an endless, randomized stream of demos</title>
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject.js"></script>
+ <script type="text/javascript" src="/youtube.js" ></script>
+ <link rel="shortcut icon" type="image/x-icon" href="http://perl-tutorial.org/favicon.ico">
+
+ <style type="text/css">
+ body {
+ font-family: Tahoma, sans-serif;
+ color: #eee;
+ background: #1A1A1A;
+ text-align: center;
+ margin: auto;
+ width: 40em;
+ }
+ a {
+ color: #fff;
+ }
+ .subtitle {
+ font-size: 0.5em;
+ color: #999;
+ }
+ h1 {
+ line-height: 1em;
+ }
+ </style>
+</head>
+<body>
+ <h1>
+ Scenefinity<br />
+ <span class="subtitle">an endless, randomized stream of demos</span>
+ </h1>
+
+ <div style="width: 40em;height:30em;">
+ <span id="ytapiplayer">You need Flash player 8+ and Javascript enabled to view videos.</div>
+ <script type="text/javascript">
+ var flashvars = {};
+ var params = {};
+ params.wmode = "transparent";
+ params.AllowScriptAccess = "always";
+ params.allowfullscreen = "true";
+ var attributes = { id: "playerid" };
+ swfobject.embedSWF(
+ "http://www.youtube.com/v/svGk_pF67gc?fs=1&playerapiid=playerid&enablejsapi=1&rel=0",
+ "ytapiplayer",
+ "100%",
+ "100%",
+ "8",
+ "false",
+ flashvars,
+ params,
+ attributes
+ );
+ </script>
+ </div>
+ <a href="javascript:play_next_video();" style="font-size:2em">next demo</a>
+</body>
+</html>
View
38 share/youtube.js
@@ -0,0 +1,38 @@
+var player;
+var default_id = "svGk_pF67gc";
+var playlist = [];
+var current_id;
+var playlist_is_updating;
+
+function onYouTubePlayerReady(player_id) {
+ player = document.getElementById(player_id);
+ player.addEventListener("onStateChange", "on_yt_state_change");
+ update_playlist();
+}
+
+function on_yt_state_change(new_state) {
+ if (new_state != 0) return;
+ play_next_video();
+}
+
+function play_next_video() {
+ var next_id = playlist.shift();
+ if (!next_id) next_id = default_id;
+ player.loadVideoById(next_id);
+ update_playlist();
+}
+
+function update_playlist() {
+ if (playlist.length > 5) return;
+ if (playlist_is_updating) return;
+
+ playlist_is_updating = 1;
+
+ $.get('/more_demos', function(data) {
+ playlist = playlist.concat(data);
+ playlist_is_updating = 0;
+ }, "json").error(function(jqXHR, textStatus, errorThrown) {
+ alert(textStatus + " : " + errorThrown + " :\n" + jqXHR.responseText);
+ playlist_is_updating = 0;
+ });
+}
View
2 t/basic.t
@@ -12,6 +12,6 @@ done_testing;
exit;
sub run {
-
+ ok( 1, "loads" );
return;
}

0 comments on commit 5004a46

Please sign in to comment.