| version 1.1, 2005/03/24 00:22:09 | version 1.28, 2010/01/07 18:50:02 | 
|  |  | 
| #!/usr/bin/perl -T | #!/usr/bin/perl -T | 
| #$Id$ | #$RedRiver: ServerTorrents.pl,v 1.27 2008/12/29 22:04:00 andrew Exp $ | 
| use strict; | use strict; | 
| use warnings; | use warnings; | 
| use diagnostics; | use diagnostics; | 
|  |  | 
| use BT::MetaInfo; |  | 
| use LWP::UserAgent; | use LWP::UserAgent; | 
| use Time::Local; | use Time::Local; | 
|  | use File::Basename; | 
|  |  | 
|  | #use YAML; | 
|  |  | 
| use lib 'lib'; | use lib 'lib'; | 
| use OpenBSDTorrents; | use OpenBSDTorrents; | 
|  | use BT::MetaInfo::Cached; | 
|  |  | 
| %ENV = (); | %ENV = (); | 
|  |  | 
| use YAML; | justme(); | 
|  |  | 
| my $url_torrents = 'http://openbsd.somedomain.net/dumptorrents.php'; | my @Sizes = ( '', 'Ki', 'Mi', 'Gi', 'Ti' ); | 
| my $url_upload   = 'http://openbsd.somedomain.net/newtorrents.php'; |  | 
| my $url_delete   = 'http://openbsd.somedomain.net/deltorrents.php'; |  | 
|  |  | 
| my $user = 'torrentup'; |  | 
| my $pass = 'ssapword'; |  | 
|  |  | 
| my $ua = LWP::UserAgent->new; | my $ua = LWP::UserAgent->new; | 
|  |  | 
| my $response = $ua->get($url_torrents); | my $response = $ua->get( $OBT->{URL_TORRENTS} ); | 
|  |  | 
| my %server_torrents; | my %server_torrents; | 
| if ($response->is_success) { | if ( $response->is_success ) { | 
| my $content = $response->content;  # or whatever | my $content = $response->content;    # or whatever | 
| $content =~ s/^.*<!-- BEGIN LIST -->//s || die "Beginning of list not found!"; | $content =~ s/^.*<!-- BEGIN LIST -->//s | 
| $content =~ s/<!-- END LIST -->.*$//s   || die "End of list not found!"; | || die "Beginning of list not found!"; | 
| unless ($content =~ /No data/) { | $content =~ s/<!-- END LIST -->.*$//s || die "End of list not found!"; | 
| foreach (split /\n/, $content) { | unless ( $content =~ /No data/ ) { | 
|  | foreach ( split /\n/, $content ) { | 
| s/^\s+//; | s/^\s+//; | 
| s/\s+$//; | s/\s+$//; | 
| next unless $_; | next unless $_; | 
| my ($name, $hash) = split /\t/; | my ( $name, $hash, $disabled ) = split /\t/; | 
| next if $name eq 'File'; | next if $name eq 'File'; | 
|  |  | 
| $name =~ s#^/torrents/##; | $name =~ s#.*/##; | 
| $server_torrents{$name} = $hash; | $server_torrents{$hash} = { | 
|  | name     => $name, | 
|  | disabled => $disabled, | 
|  | }; | 
| } | } | 
| } | } | 
| } else { | } | 
|  | else { | 
| die $response->status_line; | die $response->status_line; | 
| } | } | 
|  |  | 
|  | my %torrents; | 
|  | opendir DIR, $OBT->{DIR_TORRENT} | 
|  | or die "Couldn't opendir $OBT->{DIR_TORRENT}: $!"; | 
|  | foreach my $torrent ( readdir DIR ) { | 
|  | chomp $torrent; | 
|  | next unless $torrent =~ /\.torrent$/; | 
|  |  | 
| my %files; | if ($torrent =~ /^([^\/]+)$/) { | 
| opendir DIR, $TorrentDir or die "Couldn't opendir $TorrentDir: $!"; | $torrent = $1; | 
| foreach (readdir DIR) { | } | 
| if (/^([^\/]+)$/) { | else { | 
| $_ = $1; | die "Invalid character in $torrent: $!"; | 
| } else { | } | 
| die "Invalid character in $_: $!"; |  | 
| } |  | 
| next unless /\.torrent$/; |  | 
| chomp; |  | 
| my ($name, $year, $mon, $mday, $hour, $min) = |  | 
| /^(.*)-(\d{4})-(\d{2})-(\d{2})-(\d{2})(\d{2})/; |  | 
|  |  | 
| my $epoch = timegm(0,$min,$hour,$mday,$mon,$year); | my $name = basename( $torrent, '.torrent' ); | 
|  |  | 
| $files{$name}{$epoch} = { | if ( my ( $base, $year, $mon, $mday, $hour, $min ) | 
| file      => $_, | = $torrent =~ /^(.*)-(\d{4})-(\d{2})-(\d{2})-(\d{2})(\d{2})/ ) | 
| year      => $year, | { | 
| mon       => $mon, | $name = $base; | 
| mday      => $mday, | } | 
| hour      => $hour, |  | 
| min       => $min, |  | 
| epoch     => $epoch, |  | 
| }; |  | 
|  |  | 
|  | my $t; | 
|  | eval { | 
|  | $t = BT::MetaInfo::Cached->new( | 
|  | $OBT->{DIR_TORRENT} . '/' . $torrent, | 
|  | {   cache_root => '/tmp/OBTFileCache' | 
|  |  | 
|  | #$OBT->{DIR_HOME} . '/FileCache' | 
|  | } | 
|  | ); | 
|  | }; | 
|  | if ($@) { | 
|  | warn "Error reading torrent $torrent\n"; | 
|  | next; | 
|  | } | 
|  |  | 
|  | #my $epoch = $t->creation_date; | 
|  |  | 
|  | my $hash = unpack( "H*", $t->info_hash ); | 
|  | $torrents{$hash} = { | 
|  | file    => $torrent, | 
|  | details => $t, | 
|  | name    => $name, | 
|  | #epoch   => $epoch, | 
|  | }; | 
|  |  | 
|  | if ( !exists $server_torrents{$hash} ) { | 
|  | Upload_Torrent( $torrents{$hash} ); | 
|  | } | 
| } | } | 
| closedir DIR; | closedir DIR; | 
|  |  | 
| #print Dump \%server_torrents, \%files; | #print Dump \%server_torrents; | 
|  | #exit; | 
|  |  | 
| foreach my $name (keys %files) { | foreach my $hash ( keys %server_torrents ) { | 
| #print "$name\n"; |  | 
| foreach my $epoch ( sort { $b <=> $a } keys %{ $files{$name} } ) { |  | 
| #print "\t$epoch\n"; |  | 
| my $torrent = $files{$name}{$epoch}{file}; |  | 
| unless (exists $server_torrents{$torrent} ) { |  | 
| my $time = |  | 
| $files{$name}{$epoch}{year} . '-' . |  | 
| $files{$name}{$epoch}{mon}  . '-' . |  | 
| $files{$name}{$epoch}{mday} . ' ' . |  | 
| $files{$name}{$epoch}{hour} . ':' . |  | 
| $files{$name}{$epoch}{min}  . ':00'; |  | 
|  |  | 
| Upload_Torrent($torrent, $time); |  | 
| } |  | 
| next; |  | 
| } |  | 
| } |  | 
|  |  | 
| foreach my $file (keys %server_torrents) { | #printf "SERVER: [%s] [%s]\n", $hash, $torrent; | 
| unless (exists $files{$file}) { | if (   ( !exists $torrents{$hash} ) | 
| Delete_Torrent($file); | && ( !$server_torrents{$hash}{disabled} ) ) | 
| } | { | 
|  | Delete_Torrent( $server_torrents{$hash}{name}, $hash ); | 
|  | } | 
| } | } | 
|  |  | 
|  | $ua->get( $OBT->{URL_SANITY} ); | 
|  |  | 
| sub Upload_Torrent | sub Upload_Torrent { | 
| { | my $torrent = shift; | 
| my $file = shift; | my $t       = $torrent->{'details'}; | 
| my $time = shift; |  | 
|  |  | 
| print "Uploading $file\n"; | my $file = $torrent->{'file'}; | 
|  | print "Uploading $file\n"; | 
|  |  | 
| my $t; | my $size = $t->total_size; | 
| eval { $t = BT::MetaInfo->new("$TorrentDir/$file"); }; | my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday ) | 
| if ($@) { | = gmtime( $t->creation_date ); | 
| warn "Error reading torrent $file\n"; | $year += 1900; | 
| return undef; | $mon++; | 
| } | my $time = sprintf "%04d.%02d.%02d %02d:%02d", | 
|  | $year, $mon, $mday, $hour, $min; | 
|  |  | 
| my $comment = $t->{comment}; | ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday ) | 
| $comment =~ s/\n.*$//s; | = localtime( $t->creation_date ); | 
|  | $year += 1900; | 
|  | $mon++; | 
|  | my $sql_time = sprintf "%04d-%02d-%02d %02d:%02d", | 
|  | $year, $mon, $mday, $hour, $min; | 
|  |  | 
| my ($filename) = $comment =~ /Files from ([^<]+)/; | my $i = 0; | 
| $filename =~ s#/# #g; | while ( $size > 1024 ) { | 
|  | $size /= 1024; | 
| $filename .= ' (' . $time . ')'; | $i++; | 
|  | } | 
|  | $size = sprintf( '%.2f', $size ); | 
|  | $size .= $Sizes[$i] . 'B'; | 
|  |  | 
| my $response = $ua->post($url_upload, { | my $comment = $t->{comment}; | 
| username => $user, | $comment =~ s/\n.*$//s; | 
| password => $pass, |  | 
| torrent  => [ "$TorrentDir/$file" ], |  | 
| url      => "/torrents/$file", |  | 
| filename => $filename, |  | 
| filedate => $time, |  | 
| info     => $comment, |  | 
| hash     => '', |  | 
| autoset  => 'enabled', # -> checked="checked" |  | 
| }, Content_Type => 'form-data'); |  | 
|  |  | 
| if ($response->is_success) { | my $filename | 
| print "Uploaded  $file\n"; | = $comment =~ /($OBT->{BASENAME}.+)/ | 
| #print $response->content; | ? $1 | 
| } else { | : $file; | 
| die $response->status_line; | $filename =~ s#/# #g; | 
| } | $filename =~ s/\.torrent\z//; | 
|  |  | 
|  | $comment  .= " [$size]"; | 
|  | $filename .= " [$time]"; | 
|  |  | 
|  | my $response = $ua->post( | 
|  | $OBT->{URL_UPLOAD}, | 
|  | {   username => $OBT->{UPLOAD_USER}, | 
|  | password => $OBT->{UPLOAD_PASS}, | 
|  | torrent  => [ $OBT->{DIR_TORRENT} . "/$file" ], | 
|  | url      => "/torrents/$file", | 
|  | filename => $filename, | 
|  | filedate => $sql_time, | 
|  | info     => $comment, | 
|  | hash     => '', | 
|  | autoset => 'enabled',    # -> checked="checked" | 
|  | }, | 
|  | Content_Type => 'form-data' | 
|  | ); | 
|  |  | 
|  | if ( $response->is_success ) { | 
|  | print STDERR "Uploaded  $file\n"; | 
|  |  | 
|  | #print $response->content; | 
|  | } | 
|  | else { | 
|  | die $response->status_line; | 
|  | } | 
| } | } | 
|  |  | 
| sub Delete_Torrent | sub Delete_Torrent { | 
| { | my $filename = shift; | 
| my $file = shift; | my $hash     = shift; | 
| print "Will delete $file soon enough\n"; | die "No hash passed!" unless $hash; | 
|  |  | 
|  | print "Removing $filename [$hash]\n"; | 
|  |  | 
|  | my $response = $ua->post( | 
|  | $OBT->{'URL_DELETE'}, | 
|  | {   username => $OBT->{UPLOAD_USER}, | 
|  | password => $OBT->{UPLOAD_PASS}, | 
|  | filename => $filename, | 
|  | hash     => $hash, | 
|  | }, | 
|  | Content_Type => 'form-data' | 
|  | ); | 
|  |  | 
|  | if ( $response->is_success ) { | 
|  | my ($result) = $response->content =~ /class="error"\>([^<]+)\</; | 
|  |  | 
|  | if ( $result eq 'Torrent was removed successfully.' ) { | 
|  | print STDERR "Removed $filename [$hash]\n"; | 
|  | } | 
|  | elsif ($result) { | 
|  | print STDERR "Error: $result (removing $filename [$hash])\n"; | 
|  | } | 
|  | else { | 
|  | print STDERR | 
|  | "An unknown error occurred removing $filename [$hash]\n"; | 
|  | } | 
|  | } | 
|  | else { | 
|  | die $response->status_line . " removing $filename [$hash]\n"; | 
|  | } | 
| } | } |