API workers using Gearman::Driver
[cloudstore.git] / gearman / transmission.pl
index bf6bce3..6e6e04a 100755 (executable)
@@ -5,11 +5,13 @@ use strict;
 use Transmission::Client;
 use JSON::XS;
 use Data::Dump qw(dump);
+use autodie;
+use File::Path qw(make_path remove_tree);
 
-sub home_dir {
+sub user_info {
        my $login = shift;
        my ( undef, undef, $uid, $gid, undef, undef, $email, $dir, $shell ) = getpwnam $login;
-       return $dir;
+       return ( $uid, $gid, $dir );
 }
 
 use Gearman::Worker;
@@ -22,9 +24,19 @@ my $j = JSON::XS->new;
 $j->allow_blessed(1);
 $j->convert_blessed(0);
 
+use lib 'lib';
+use CloudStore::MD5sum;
+
 my $name = $ENV{ZSLICE} || die "need ZSLICE";
+my $torrent_dir = "/$name/torrent";
 $name =~ s/\W+/_/g;
 
+=head1 host_s1_torrent_list
+
+Returns JSON encoded list of all torrents
+
+=cut
+
 $worker->register_function( $name . '_torrent_list' => sub {
        my ($job) = @_;
        my @cols = split(/\s+/,$job->arg);
@@ -40,6 +52,109 @@ $worker->register_function( $name . '_torrent_list' => sub {
        return $j->encode( \@list );
 } );
 
+=head1 host_s1_torrent_download ~login/path.torrent
+
+Start download of torrent
+
+=cut
+
+$worker->register_function( $name . '_torrent_download' => sub {
+       my $work = $_[0]->arg;
+       chomp $work;
+       warn "# torrent_download [$work]\n";
+       
+       my $user = $1 if $work =~ s{~(\w+)/}{};
+       my $path = $work;
+
+       my $dir = (getpwnam($user))[7] || die "no user $user";
+
+       my $torrent_file = "$dir/$path";
+
+       $path =~ s/\.torrent$//;
+       my $to_dir = "$torrent_dir/download/$user/$path";
+       my ($uid,$gid) = (stat($torrent_dir))[4,5];
+       make_path $to_dir, { uid => $uid, gid => $gid };
+
+       my $t = $tc->add( filename => $torrent_file, 'download-dir' => $to_dir );
+       warn "# added $to_dir = ",dump($t);
+
+       return $to_dir;
+} );
+
+$worker->register_function( $name . '_torrent_download_done' => sub {
+       my $work = $_[0]->arg;
+       chomp $work;
+       warn "# torrent_download_done [$work]\n";
+
+       my ( $id, $dir, $name, $hash ) = split(/\s+#\s+/,$work);
+
+       if ( $dir =~ m{/download/(\w+)/(.+)$} ) {
+               my $user = $1;
+               my $path = $2;
+
+               warn "# check $name md5sum";
+               my $md5sum = `md5sum "$dir/$name"`;
+               $md5sum =~ s/\s+.*$//s;
+               if ( $name ne $md5sum ) {
+                       warn "ERROR: invalid md5sum filename ",dump( $name, $md5sum );
+               }
+
+               warn "# move $name to $user $path\n";
+               my ( $uid, $gid, $home_dir ) = user_info $user;
+               link "$dir/$name", "$home_dir/$path";
+               chown $uid, $gid,  "$home_dir/$path";
+               warn "FIXME: add to md5 pool?";
+
+               my $t = $tc->remove( $id );
+               warn "# remove $id = ",dump($t);
+
+               warn "# $id removed $dir $name $hash\n";
+
+               remove_tree $dir;
+       } else {
+               warn "ERROR: can't find user in $dir for $name\n";
+       }
+
+
+} );
+
+=head1 host_s1_torrent_share ~login/file.txt
+
+Create torrent and start seeding it
+
+=cut
+
+$worker->register_function( $name . '_torrent_share' => sub {
+       my $work = $_[0]->arg;
+       chomp $work;
+       warn "# torrent_share [$work]\n";
+       
+       my $user = $1 if $work =~ s{~(\w+)/}{};
+       my $path = $work;
+
+       my $dir = (getpwnam($user))[7] || die "no user $user";
+       my $md5 = CloudStore::MD5sum->md5_get( "$dir/$path" );
+
+       warn "# $md5 $path";
+
+       if ( ! -e "$torrent_dir/download/$md5" ) {
+               symlink "/rsync1/s1/md5/$md5", "$torrent_dir/download/$md5"; # FIXME slice path
+               warn "# created $torrent_dir/download/$md5";
+       }
+
+       if ( ! -e "$torrent_dir/md5/$md5.torrent" ) {
+               my $tracker = "http://213.186.16.27:6502/announce"; # FIXME
+               system "mktorrent --announce $tracker --no-date --verbose --output $torrent_dir/md5/$md5.torrent $torrent_dir/download/$md5";
+
+       }
+
+       symlink "$torrent_dir/md5/$md5.torrent", "$dir/$path.torrent" unless -e "$dir/$path.torrent";
+
+       $tc->add( filename => "$torrent_dir/md5/$md5.torrent" );
+
+       return "$dir/$path";
+} );
+
 warn "$0 $name pid $$ waitng for jobs\n";
 $worker->work while 1;