Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Tk-front-end-to YouTube.com videos

by zentara (Archbishop)
on Sep 02, 2006 at 16:22 UTC ( [id://570873]=CUFP: print w/replies, xml ) Need Help??

In an attempt to merge YouTube Video Downloader and my Tk front end to Mplayer at Perl/Tk front-end to mplayer, here is a YouTube.com sampler. It is not perfect. The categories are hard coded in, and it only gets the first page of each category( maybe 10 videos each)

Also I hacked a quick Listbox widget to display the retreived files. But since I used a thread to download, I needed to update the listbox every 10 seconds manually, which can be annoying if you try to select a file right at update time.

Anyways, it will work on linux (X11) only, and you need an mplayer that can play .flv files.

I creatively named the downloaded files, by concating the titles and flv filename, so you can tell what they are more easily.

Start the app, if any flv files are present in the working dir, they will be listed. Otherwise, press the Select Catagories button, and select 1 or more categories to sample. Then the downloader will get the videos in the background.

#!/usr/bin/perl -w use strict; use Tk; require Tk::Pane; use Proc::Killfam; + use Tk::ROText; use LWP::UserAgent; use LWP::Simple; use HTML::LinkExtor; use URI::URL; use threads; use threads::shared; # it will work on linux (X11) only, and you need an mplayer # that can play .flv files. #I creatively named the downloaded files, by concating the # titles and flv filename, so you can tell what they are more # easily. # Start the app, if any flv files are present in the working dir, # they will be listed. Otherwise, press the Select Catagories # button, and select 1 or more categories to sample. Then the # downlo +ader will get the videos in the background. # must setup thread code before any Tk code is used # to avoid Tk thread-safety problems my $thread_die : shared; my $thread_go : shared; my @selected : shared; my @ready : shared; $thread_die = 0; $thread_go = 0; @selected = (); @ready = (); my $thread = threads->new( \&work ); ################################################### + $|++; my @links; #a global for Link extractor, funky callback hack my $ua = LWP::UserAgent->new(); my @selected_cats =(); my @ready_lb; #local non-thread copy of @ready to prevent #Tk from segfaulting $SIG{INT} = sub { &close_it_up }; $SIG{PIPE} = 'IGNORE'; my $mpg_in = shift || ''; #mpg to play from command line # needs an init.mpg which will be created if you # don't supply one if( ! -e 'init.mpg'){ &make_init} #setup local files to play @ready = <*.flv>; #newly downloaded files will be pushed onto @ready #if there are no .flv files in the dir, the first completed #download will play upon arrival @ready_lb = @ready; my $cur_play; my $title; my $playing = 0; #flag used in auto-playing first completed download my $timer; my $timer1; my $mw = MainWindow->new(-background =>'black'); $mw->geometry('530x650+20+30'); $mw->Tk::bind("<q>", sub{&close_it_up}); $mw->Tk::bind("<Escape>", sub{&close_it_up}); my $cframe1 = $mw->Frame(-background =>'black') ->pack( -fill =>'x'); my $cframe2 = $mw->Frame(-background =>'black') ->pack( -fill =>'x'); my $canv = $mw->Scrolled('Canvas', -bg => 'black', -borderwidth => 0, -highlightthickness => 0, -relief => 'sunken', -width => 500, -height => 400, -scrollregion=>[0,0,500,400], + -scrollbars=>'osoe', )->pack(); my $contWidth = 500; my $contHeight = 400; ## this Frame is needed for including the window in Tk::Canvas my $Container = $canv->Frame(-container => 1); my $xtid = $Container->id(); # converting the id from HEX to decimal as xterm requires a decimal Id my ($xtId) = sprintf hex $xtid; my $dcontitem = $canv->createWindow(10,10, -anchor=>'nw', -window => $Container, -width => $contWidth, -height => $contHeight, -state => 'hidden', -tags => ['viewport'], ); my $pid; my @options = ( '-slave','-loop 0', '-zoom', "-x $contWidth", "-y $contHeight", '-really-quiet', "-wid $xtId", ); my $loadu_but = $cframe1->Button(-text => 'Select Category', -padx => 0, -command => sub{ my $url = &get_url; })->pack(-side =>'left',-padx=>10 ); $cframe1->Button(-text => "Exit", -padx => 0, -command => [sub{&close_it_up}] ) ->pack(-side=>'right', -padx =>10 ); $cframe1->Button(-text => "Stop Download", -padx => 0, -command => sub{ $thread_go = 0; $timer1->cancel; #stop updating list } ) ->pack(-side=>'right', -padx =>10 ); my $sound = 1; + $cframe1->Checkbutton( + -text => 'Sound', + -background => 'lightblue', -variable => \$sound, + -command => \&set_sound, + )->pack(-fill =>'y' ); + $cframe2->Label(-text => 'SpaceBar->Pause q or esc -> exit left + and right arrow keys navigate', -background => 'black', -foreground => 'lightgreen', )->pack(-expand=>1 ); $cframe2->Label( -textvariable => \$title , -background => 'black', -foreground => 'lightblue', )->pack(-expand=>1 ); &start_player; if($mpg_in ne ''){ &play($mpg_in)} $mw->Label( -text => 'Left Click Select...Right Click Play', -background => 'black', -foreground => 'green', )->pack(-fill => 'x',-expand => 1 ); my $lb = $mw->Scrolled('Listbox', -scrollbars=>'osow', -listvariable => \@ready_lb, -background => 'white', )->pack(-fill => 'x',-expand=>1); $lb->bind( '<ButtonPress-3>', sub{ my $file = $lb->get($lb->curselection); $playing = 1; #set flag that we are playing a local file &play($file); }); MainLoop(); ######################################################### sub get_url{ my %cats = ( 1 => 'Arts &Animation', 2 => 'Autos & Vehicles', 23 => 'Comedy', 24 => 'Entertainment', 10 => 'Music', 25 => 'News & Blogs', 22 => 'People', 15 => 'Pets & Animals', 26 => 'Science & Technology', 17 => 'Sports', 19 => 'Travel & Places', 20 => 'Video Games' ); my $url_top = "http://youtube.com/categories_portal"; # for instanc +e @links = &get_links( $url_top ); # http://youtube.com/categories_portal?c=1&e=1 my $lead = 'http://youtube.com/categories_portal?c='; my $rx = qr/\Q$lead\E(.*)/; @links = grep{/$rx/} @links; #remove dups @links = keys %{{map{$_,1} @links}}; my %result_list =(); #sort the links according to category my $rx1 = qr/\Q$lead\E(\d+).*/; foreach my $link (@links){ $link =~ /$rx1/; my $cat = $1; push @{ $result_list{ $cat } }, $link; } my @hyperlinks =(); foreach my $key (keys %result_list){ # print $cats{$key},"\n"; # print join( "\n", @{ $result_list{ $key } } ), "\n\n\n"; push @hyperlinks, "$cats{$key}\n"; foreach( @{ $result_list{ $key } } ){ push @hyperlinks, "$_\n"; } } #popup my $tl = MainWindow->new(); $tl->title("Select YouTube Categories"); $tl->fontCreate('big', -family=>'arial', -weight=>'bold', -size=>int(-18*18/14)); my $t = $tl->Scrolled('ROText', -width => 80, -height => 30, -background => 'white', )->pack(); my $ebutton = $tl->Button(-text =>'Done Selecting', -command => sub{ $tl->destroy; #print "@selected_cats\n"; #now start to process links and download #videos in the work thread &start_downloads; })->pack(); #add colors $t->tagConfigure( 'tag1', -foreground => 'red', -font => 'big' ); my $tag = "tag000"; foreach (@hyperlinks) { chomp; my @res = split (/(http:\S+)/); foreach (@res) { if (/(http:\S+)/) { $t->insert( 'end', $_, $tag ); $t->tagConfigure( $tag, -foreground => 'blue' ); $t->tagBind( $tag, '<Any-Enter>' => [ \&manipulate_link, $tag, 'raised', +'hand2' ] ); $t->tagBind( $tag, '<Any-Leave>' => [ \&manipulate_link, $tag, 'flat', 'x +term' ] ); $t->tagBind( $tag, '<Button-1>' => [ \&manipulate_link, $tag, 'sunken' ] +); $t->tagBind( $tag, '<ButtonRelease-1>' => [ \&manipulate_link, $tag, 'raised', undef, \&printm +e ] ); $tag++; } else { $t->insert( 'end', $_ , 'tag1' ); } } $t->insert( 'end', "\n" ); } } ############################################## sub get_links{ my $url_in = shift; # Set up a callback that collect image links @links = (); # a global # Make the parser. Unfortunately, we don't know the base yet # (it might be diffent from $url) my $p = HTML::LinkExtor->new(\&callback,\@links); # Request document and parse it as it arrives my $res = $ua->request( HTTP::Request->new( GET => $url_in ), sub { $p->parse( $_[0] ); } ); # Expand all URLs to absolute ones my $base = $res->base; @links = map { $_ = url( $_, $base )->abs; } @links; return @links; } ################################################# sub callback { my ( $tag, %attr) = @_; return if $tag ne 'a'; # we only look closer at <a href ...> push( @links, values %attr ); } #################################################### sub printme { # print "@_\n"; $_[0]->tagConfigure( $_[2], -foreground => 'yellow', -background = +> 'black' ); push @selected_cats, $_[1]; #now we have an array of urls to fetch and process for all #video links #this is done in the 'Done Selecting' callback } ####################################################### sub manipulate_link { # manipulate the link as you press the mouse key my ($a) = shift; my ($tag) = shift; my ($relief) = shift; my ($cursor) = shift; my ($after) = shift; # by configuring the relief (to simulate a button press) $a->tagConfigure( $tag, -relief => $relief, -borderwidth => 1 ); # by changing the cursor between hand and xterm $a->configure( -cursor => $cursor ) if ($cursor); # and by scheduling the specified action to run "soon" if ($after) { my ($s) = $a->get( $a->tagRanges($tag) ); $mw->after( 100, [ $after, $a, $s, $tag, @_ ] ) if ($after); } } ######################################################## sub get_file{ my @types =( ["mpeg,mp3,avi", [qw/.mpg .mpeg .mp3 .avi .flv/]],); my $file = $mw->getOpenFile( -filetypes => \@types ); return $file; } ########################################################### sub set_sound{ &stop; if($sound == 1 ){ @options = grep{ $_ ne '-nosound'} @options;} else{ unshift @options, '-nosound';} &start_player; &play($cur_play); } ############################################################## sub start_player{ $pid = open(MP, "| mplayer @options init.mpg >/dev/null 2>&1 "); $canv->itemconfigure($dcontitem,-state => 'normal'); } ############################################################## sub play { my $mpg = shift || 'init.mpg'; syswrite(MP, "loadfile $mpg\n"); $cur_play = $mpg; my $filename = substr ($mpg, rindex ($mpg, "/") + 1); $mw->configure(-title=>$filename); $title = $filename; } ################################################################### sub stop{ syswrite(MP, "quit\n"); $canv->itemconfigure($dcontitem,-state => 'hidden'); killfam 9, $pid; close MP; } ################################################################# sub close_it_up{ &stop; $thread_die = 1; $thread->join; exit; } ###################################################################### +######## sub start_downloads{ foreach my $page( @selected_cats ){ my @links1 = &get_links( $page ); # "http://youtube.com/watch?v=EkTpUxh8Vxc"; my $lead = 'http://youtube.com/watch?v='; my $rx = qr/\Q$lead\E(.*)/; @links1 = grep{/$rx/} @links1; #remove dups @links1 = keys %{{map{$_,1} @links1}}; #print "@links1\n"; foreach(@links1){ push @selected , $_ } } #print join "\n", @selected,"\n"; #start downloading thread if needed if( scalar @selected > 0 ){ $thread_go = 1; # timer to autoplay first download $timer = $mw->repeat(500, sub{ if( scalar @ready > 0 ){ if( ! $playing ){ &play( $ready[0] ) }; $timer->cancel; } }); #update download list (hack for tk thread safety) #use 10 seconds to allow time to make selections #definitely a hack :-) $timer1 = $mw->repeat(10000, sub{ @ready_lb = @ready; $lb->update; }); } } ############################################################# sub work{ no warnings "all"; #stops a harmless shared var warning my $received_size; my $request_time; my $last_update; my $ua = LWP::UserAgent->new(); $|++; while(1){ if($thread_die == 1){ goto END }; if ( $thread_go == 1 ){ print "starting next page retrieval\n"; my $urlin = shift @selected; my $content = get( $urlin ) or die "$!\n"; print "done page retrieval\n"; #get human friendly title for video $content =~ /<title>(.*)<\/title>/; my $title = $1; #put underscores for spaces in title $title =~ tr/ /_/; # regex for 2 key text strings which identify the video file # the second one $2 is unique for each download attempt $content =~ /player2\.swf\?video_id=([^&]+)&.*t=([^&]+)&/ ; print $1, "\n" , $2, "\n"; #make add title to filename for ease of identification my $infile = $title.'--'.$1.'.flv'; #add a .flv extension #http://www.youtube.com/get_video?video_id=p_YMigZmUuk&t=OEgsToPD +skLRl9-iKyfQVcNT8xes2OIT my $get_url = 'http://www.youtube.com/get_video?video_id='.$1.'&t +='.$2; print "gettin video file $get_url\n"; # don't buffer the prints to make the status update $| = 1; open(IN,"> $infile") or die "$_\n"; $received_size = 0; my $url = $get_url; print "Fetching $url\n"; $request_time = time; $last_update = 0; my $response = $ua->get($url, ':content_cb' => \&callback_t, ':read_size_hint' => 8192, ); print "\n"; close IN; print "$infile done\n"; push @ready, $infile; }else { select(undef,undef,undef,.1); } #sleep .1 second } #end while loop sub callback_t { my ($data, $response, $protocol) = @_; my $total_size = $response->header('Content-Length') || 0; $received_size += length $data; # write the $data to a filehandle or whatever should happen # with it here. print IN $data; my $time_now = time; if($thread_go == 0){last} if($thread_die == 1){ goto END }; # this to make the status only update once per second. return unless $time_now > $last_update or $received_size == $total_ +size; $last_update = $time_now; print "\rReceived $received_size bytes"; printf " (%i%%)", (100/$total_size)*$received_size if $total_size; printf " %6.1f/bps", $received_size/(($time_now-$request_time)||1) if $received_size; } END: } ################################################################### sub make_init{ use MIME::Base64; + my $init_mpg =' UklGRvYUAABBVkkgTElTVOgRAABoZHJsYXZpaDgAAABAQg8AfJIAAAAAAAAQCQAAAwAAAA +AAAAAB AAAAAAAQAMAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAExJU1SQEAAAc3RybHN0cmg4AAAAdm +lkc0RJ VlgAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAAAAAQAP////8ARAEAAAAAAMAAkABzdH +JmKAAA ACgAAADAAAAAkAAAAAEAGABESVZYAEQBAAAAAAAAAAAAAAAAAAAAAABKVU5LFBAAAAQAAA +AAAAAA MDBkYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAEpVTksEAQAAb2RtbGRtbGj4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMSVNUwgIAAG +1vdmkw MGRjbAEAAAAAAbABAAABtYkTAAABAAAAASAAxI2IAA0GBBIUYwAAAbJGRm1wZWcwLjQuOG +I0Njgw AH8AAAGzABAHAAABthYPGC/bfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfx +tt/G23 8bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbf +xtt/G2 38bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bb +fxtt/G 238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238b +bfxtt/ G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238bbfxtt/G238 +bbfxtt /G238bbfxtt/G238bbfxtt/G238bbfxtt/G2378wMGRjIwEAAAAAAbZrgRC+5wX3OC+5wX +3OC+5w X3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5w +X3OC+5 wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5 +wX3OC+ 5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+ +5wX3OC +5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC ++5wX3O C+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OC+5wX3OfwAwMGRjFQAAAA +AAAbZr AR//////////////////fwBpZHgxMAAAADAwZGMQAAAABAAAAGwBAAAwMGRjAAAAAHgBAA +AjAQAA MDBkYwAAAACkAgAAFQAAAA=='; open(FH,"> init.mpg") or die "$!\n"; print FH decode_base64($init_mpg); close FH; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://570873]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (2)
As of 2024-04-19 19:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found