NAME

POE::Component::WWW::YouTube::VideoURI - Non-blocking POE wrapper around WWW::YouTube::VideoURI with download abilities.

SYNOPSIS

use strict;
use warnings;

use POE qw(Component::WWW::YouTube::VideoURI);

POE::Component::WWW::YouTube::VideoURI->spawn( alias => 'tube' );

my $poco
    = POE::Component::WWW::YouTube::VideoURI->spawn;

POE::Session->create(
    package_states => [
        main => [ qw( _start  got_link  downloaded ) ]
    ],
);

POE::Session->create(
    inline_states => {
        _start => sub { $_[KERNEL]->alias_set->('secondary'); },
        tube_link => \&got_link,
    }
);

$poe_kernel->run;

sub _start {
    $poe_kernel->post( tube => get_uri => {
            uri => 'http://www.youtube.com/watch?v=dcmRImiffVM',
            event => 'got_link',
            _shtuf => 'foos',
        }
    );
    
    $poco->get_uri( {
            uri     => 'http://www.youtube.com/watch?v=dcmRImiffVM',
            event   => 'tube_link',
            session => 'secondary',
            _rand   => 'something',
        }
    );
}

sub got_link {
    my ( $kernel, $input ) = @_[ KERNEL, ARG0 ];
    
    unless ( defined $input->{out} ) {
        print "ZOMG!! Error: $input->{error}\n";
    }
    else {
        print "Got FLV URI: $input->{out}\n";
        print "Title is: $input->{title}\n";
        print "Starting download!\n";
        
        $kernel->post( tube => store => { 
                flv_uri => $input->{out},
                where   => '/home/zoffix/Desktop/Apex_Twin-Live.flv',
                store_event   => 'downloaded',
            }
        );
    }
    
    print "Oh, and BTW: $input->{_shtuf}\n";
}

sub downloaded {
    my ( $kernel, $input ) = @_[ KERNEL, ARG0 ];
    
    if ( $input->{store_error} ) {
        print "Flailed :( $input->{store_error}\n";
    }
    else {
        print "Success!! We saved $input->{flv_uri} to $input->{where}\n";
    }
    
    $poe_kernel->post( tube => 'shutdown' );
}

DESCRIPTION

The module is a simple non-blocking wrapper around WWW::YouTube::VideoURI with an additional feature of non-blocking downloads of .flv files.

CONSTRUCTOR

POE::Component::WWW::YouTube::VideoURI->spawn( alias => 'tube' );

POE::Component::WWW::YouTube::VideoURI->spawn(
    alias => 'tube',
    debug => 1,
);

my $poco
    = POE::Component::WWW::YouTube::VideoURI->spawn;

Returns a PoCo object. Takes three optional arguments:

alias

POE::Component::WWW::YouTube::VideoURI->spawn( alias => 'tube' );

Specifies a POE Kernel alias for the component.

options

POE::Component::WWW::YouTube::VideoURI->spawn(
    options => {
        trace => 1,
        default => 1,
    },
);

A hashref of POE Session options to pass to the component's session.

debug

POE::Component::WWW::YouTube::VideoURI->spawn( debug => 1 );

When set to a true value turns on output of debug messages.

METHODS

These are the object-oriented methods of the component.

get_uri

$poco->get_uri( {
        event         => 'got_link',
        uri           => 'http://www.youtube.com/watch?v=dcmRImiffVM',
        session       => 'foos',
        where         => '/tmp/foo.flv',
        store_session => 'bars',
        store_event   => 'stored',
        lwp_options   => {
            agent   => 'Tuber',
            timeout => 20,
        },
        _user_var     => 'something',
    }
);

Method posts a request to get a URI to .flv file. See get_uri event for detailed description.

store

$poco->store( {
        store_event => 'bars',
        where       => '/tmp/bars.flv',
        flv_uri     => 'http://www.youtube.com/get_video.php?video_id='
                      .'dcmRImiffVM&t=OEgsToPDskKZP4XrMtwMd3xwQol1LUWX',
        store_session => 'other_session',
        lwp_options => {
            agent   => 'Tuber',
            timeout => 20,
        },
        _user_var   => 'something',
    }
);

Method posts a request to download a certain movie. See store event for detailed description.

session_id

my $tube_id = $poco->session_id;

Takes no arguments. Returns POE Session ID of the component.

shutdown

$poco->shutdown;

Takes no arguments. Shuts the component down.

ACCEPTED EVENTS

get_uri

$poe_kernel->post( tube => get_uri => {
        event         => 'got_link',
        uri           => 'http://www.youtube.com/watch?v=dcmRImiffVM',
        session       => 'foos',
        where         => '/tmp/foo.flv',
        get_title     => 0,
        store_session => 'bars',
        store_event   => 'stored',
        lwp_options   => {
            agent   => 'Tuber',
            timeout => 20,
        },
        _user_var     => 'something',
    }
);

Tells the component to resolve YouTube.com link to a link to the actual .flv movie with an option to also download it. Takes one argument which is a hashref. The event and uri keys of that hashref are mandatory the rest of them are optional. The keys are as follows:

event

{ event => 'got_link' }

Mandatory. Specifies the event name to which the result should be sent to.

uri

{ uri => 'http://www.youtube.com/watch?v=dcmRImiffVM' }

Mandatory. Specifies a YouTube.com link from which to get the link to the .flv file. (this is the link you'd see in the location bar of your browser when you are watching a movie).

session

{ session => 'other_session_alias' }

{ session => $other_session_ID }

{ session => $other_session_ref }

Optional. Specifies an alternative POE Session to send the output to. Accepts either session alias, session ID or session reference. Defaults to the current session.

get_title

{ get_title => 0 }

Optional. Component is able to retrieve the title of the video. This functionality is enabled by default, however it requires an extra HTTP request to be issued which might slow things down. Thus is title of the video is not important to you, you may wish to set get_title option to a false value. Defaults to 1.

user defined arguments

{
    _user_var    => 'foos',
    _another_one => 'bars',
    _some_other  => 'beers',
}

Optional. Any keys beginning with the _ (underscore) will be present in the output intact. If where option (see below) is specified, any arguments will also be present in the result of "finished downloading" event.

where

{ where => '/tmp/movie.flv' }

Optional. If this key is present it will instruct the component to download the movie after getting a link for it. Specifies the filename where to download the movie. Note: the component mirrors the movie. If the file specified by the filename doesn't exist it will be created. If it exists and has an older modification date than the movie to be downloaded it will be overwritten. If it exists and is NOT older than the movie then the movie will NOT be downloaded and you will get 304 Not Modified error message in the return's store_error key.

store_session

{ store_session => 'other_session' }

Optional. Same as session option except it specifies an alternative session for the store event. In other words by specifying this parameter you may recieve the "resolved URI" event in one session and the "finished downloading" in another. Note: if you specified the session parameter by did not specify the store_session parameter the "finished downloading" event will be sent to the session specified with the session parameter. If you wish to recieve the "resolved URI" event in "some other session" but the "finished downloading" event in the current session you should explicitly specify that. If where option is not specified, specifying store_session has no effect, however it (store_session) key will be present in the result!

store_event

{ store_event => 'finished_downloading' }

Optional. Specifies an event that will recieve the results when the download is finished. If not specified it will default to whatever the event parameter is set to. If where option is not specified, specifying store_session has no effect, however, it (store_session) key will be present in the result!

lwp_options

{
    lwp_options   => {
        agent   => 'Tuber',
        timeout => 20,
    }
}

Optional. Takes a hashref of arguments to pass to LWP::UserAgent constructor for downloading of your movie. See LWP::UserAgent's new() method for the description of options. If not specified defaults to:

{
    agent => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)',
    timeout => 120,
}

Note: if where parameter is not specified, specifying lwp_options will have no effect, however, it (lwp_options) will be present in the result.

store

$poe_kernel->post( tube => store => {
        flv_uri       => 'http://www.youtube.com/' . 
                            'get_video.php?video_id=blah',
        where         => '/tmp/foo.flv',
        store_event   => 'stored',
        store_session => 'bars',
        lwp_options   => {
            agent   => 'Tuber',
            timeout => 20,
        },
        _user_var     => 'something',
    }
);

Instructs the component to download a certain movie. Takes one argument in the form of a hashref. Note that it does NOT do any check on the URI specified via flv_uri option, thus you can possibly download any file. The hashref keys specify different parameters (listed below) out of which the flv_uri, where, and store_event are mandatory. Note: you can automatically download the movies via get_uri event/method. The keys are as follows:

flv_uri

{ flv_uri => 'http://www.youtube.com/get_video.php?video_id=blah' }

Mandatory. Specifies the link to .flv movie. No checking on the form of the URI is done, so you can possibly download any file.

where

{ where => '/tmp/movie.flv' }

Mandatory. Specifies the filename to which download the movie. Note: the component mirrors the movie. If the file specified by the filename doesn't exist it will be created. If it exists and has an older modification date than the movie to be downloaded it will be overwritten. If it exists and is NOT older than the movie then the movie will NOT be downloaded and you will get 304 Not Modified error message in the return's store_error key.

store_event

{ store_event => 'download_is_done' }

Mandatory. Specifies an event to send the message about finished download.

store_session

{ store_session => 'some_other_session' }

Optional. Specifies an alternative POE Session to which the output will be sent.

lwp_options

{
    lwp_options   => {
        agent   => 'Tuber',
        timeout => 20,
    }
}

Optional. Takes a hashref of arguments to pass to LWP::UserAgent's constructor for downloading of your movie. See LWP::UserAgent's new() method for the description of options. If not specified defaults to:

{
    agent => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)',
    timeout => 120,
}

shutdown

$poe_kernel->post( tube => 'shutdown' );

Takes no arguments. Tells the component to shut itself down.

OUTPUT

The output from the component is recieved via events for both the OO and event based interface.

output from get_uri

$VAR1 = {
      'out' => 'http://www.youtube.com/get_video.php?video_id=blah',
      'uri' => 'http://www.youtube.com/watch?v=dcmRImiffVM',
      'get_title' => 1,
      'title' => 'Some title',
      '_shtuf' => 'foos'
    };

$VAR1 = {
      'out' => undef,
      'error' => '404 Not Found at lib/POE/Component/WWW/YouTube/VideoURI.pm line 345',
      'uri' => 'http://www.youtube.com/watch?v=blahblah',
      'get_title' => 0,
      '_shtuf' => 'foos'
};

The event specified in the event parameter of the get_uri method/event (and optionally the session specified in the session parameter) will receive the results in ARG0 in the form of a hashref.

Note: if the where parameter is specified to the get_uri method/event it will also be present in the return. You can use it to make decisions on whether or not to send store event for the flv uri in the result. However, if an error occured the store event will NOT be autosent.

The keys of the result are as follows:

out

{ 'out' => 'http://www.youtube.com/get_video.php?video_id=blah', }

This key will contain a direct link to the .flv movie (note that URI doesn't actually end in .flv). It will be undef in case of an error and error key (see below) will be present.

uri

{ 'uri' => 'http://www.youtube.com/watch?v=dcmRImiffVM' }

This will be identical to whatever you've set in the uri key in the get_uri method/event. Using this key you can find out what belongs where when you are sending multiple requests.

title

{ 'title' => 'Some title' }

This will contain the title of the video unless get_title option to the get_uri event/method was set to a false value.

user defined variables

{ '_shtuf' => 'foos' }

Any keys beginning with the _ (underscore) set in the get_uri method/event will be present intact in the result.

error

{ 'error' => '404 Not Found at ../../VideoURI.pm line 345' }

In case of an error the out key will be set to undef and error key will contain the reason... with garbage from croak() appended (don't blame me for that, see WWW::YouTube::VideoLink)

where

{ where => '/tmp/movie.flv' }

(Optional). If where parameter was specified to the get_uri method/event this key will be present intact.

output from store

$VAR1 = {
        'flv_uri' => 'http://www.youtube.com/get_video.php?video_id=blah',
        'is_store' => 1,
        'response' => bless( blah blah, 'HTTP::Response' ),
        'store_error' => '304 Not Modified',
        'where' => '/home/zoffix/Desktop/apex.flv',
        '_shtuf' => 'foos'
        };

The event specified in the store_event parameter of the store method/event (and optionally the session specified in the store_session parameter) will receive the results in ARG0 in the form of a hashref.

The keys of the result hashref are as follows:

flv_uri

{ 'flv_uri' => 'http://www.youtube.com/get_video.php?video_id=blah' }

This will contain the link to the .flv file that we mirrored.

response

{ 'response' => bless( blah blah, 'HTTP::Response' ) }

This will contain the HTTP::Response object from our mirroring in case you'd want to inspect it.

where

{ 'where' => '/home/zoffix/Desktop/apex.flv' }

This key will contain the location of the mirrored movie, it will be the where parameter you've specified to either store or get_uri methods/events.

store_error

{ 'store_error' => '304 Not Modified' }

In case of an error this key will be present and will contain the explanation of why we failed. (Note: read the store event's description if you don't understand why we'd get the 304 error).

is_store

{ is_store => 1 }

This key will be present if the event came from the store event/method (including the autostore from get_uri event/method). This is generally a key you'd check on if you decide to send both "resolved uri" and "completed download" events to the same event handler

user defined arguments

{ '_shtuf' => 'foos' }

Any keys beginning with _ (underscore) specified to the store (or get_uri if you also specified where to that method/event) will be present in the result intact.

A note on get_uri optional store call

If where argument to the get_uri method/event was specified you will recieve the output from the store as a second event followed by the "output from get_uri" event, also, read the description of the get_uri event to know where to expect the event to arrive.

The keys will also contain the user specified arguments (the ones beginning with _ (underscore) as well as uri key (the original movie URI).

The store results will also contain title if you are storing by a single get_uri method/event call.

PREREQUISITES

This module requires POE, POE:Wheel::Run, POE::Filter::Reference, POE::Filter::Line, WWW::YouTube::VideoURI, HTML::Entities and LWP::UserAgent

BUGS

None known.

SEE ALSO

POE, WWW::YouTube::VideoURI

AUTHOR

Zoffix Znet, <zoffix@cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2008 by Zoffix Znet

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.