[BACK]Return to CurrentTorrents.pl CVS log [TXT][DIR] Up to [local] / openbsd / OpenBSDTorrents

Annotation of openbsd/OpenBSDTorrents/CurrentTorrents.pl, Revision 1.38

1.1       andrew      1: #!/usr/bin/perl -T
1.38    ! andrew      2: #$RedRiver: CurrentTorrents.pl,v 1.37 2010/03/16 22:40:18 andrew Exp $
1.1       andrew      3: use strict;
                      4: use warnings;
                      5: use diagnostics;
                      6:
1.2       andrew      7: use Time::Local;
1.16      andrew      8: use Fcntl ':flock';
1.23      andrew      9: use File::Basename;
1.27      andrew     10:
1.29      andrew     11: use Transmission::Client;
                     12: use Transmission::Utils;
                     13:
1.23      andrew     14: #use YAML;
1.1       andrew     15:
1.9       andrew     16: use lib 'lib';
1.1       andrew     17: use OpenBSDTorrents;
1.17      andrew     18: use BT::MetaInfo::Cached;
1.1       andrew     19:
                     20: %ENV = ();
                     21:
1.15      andrew     22: #justme();
1.1       andrew     23:
1.12      andrew     24: my $Name_Filter = shift || '';
1.27      andrew     25: if ( $Name_Filter =~ /^(\w*)$/ ) {
                     26:     $Name_Filter = $1;
                     27: }
                     28: else {
                     29:     die "Invalid filter: $Name_Filter";
1.12      andrew     30: }
                     31:
1.15      andrew     32: my %Possible_Torrents;
1.27      andrew     33: Process_Dir( $OBT->{DIR_FTP} );
1.15      andrew     34:
1.2       andrew     35: my %files;
1.15      andrew     36: my @delete;
1.27      andrew     37: foreach my $DIR ( $OBT->{DIR_NEW_TORRENT}, $OBT->{DIR_TORRENT} ) {
                     38:     opendir DIR, $DIR
                     39:         or die "Couldn't opendir $DIR: $!";
                     40:     foreach ( readdir DIR ) {
                     41:         next unless my ($ext) = /\.(torrent|$OBT->{META_EXT})$/;
                     42:
                     43:         if (/^([^\/]+)$/) {
                     44:             $_ = $1;
                     45:         }
                     46:         else {
                     47:             die "Invalid character in $_: $!";
                     48:         }
                     49:         my $epoch = 0;
                     50:         my $name = basename( $_, '.torrent' );
                     51:
                     52:         if ( my ( $base, $year, $mon, $mday, $hour, $min )
                     53:             = /^(.*)-(\d{4})-(\d{2})-(\d{2})-(\d{2})(\d{2})/ )
                     54:         {
                     55:
                     56:             $mon--;
                     57:             $epoch = timegm( 0, $min, $hour, $mday, $mon, $year );
                     58:             $name = $base;
                     59:         }
                     60:
1.36      andrew     61:         #print "Adding $DIR/$_\n";
                     62:
1.38    ! andrew     63:         my $ct = {
1.27      andrew     64:             file => $_,
                     65:             dir  => $DIR,
1.35      andrew     66:             #path => "$DIR/$_",
1.27      andrew     67:             ext  => $ext,
                     68:
                     69:             #year      => $year,
                     70:             #mon       => $mon,
                     71:             #mday      => $mday,
                     72:             #hour      => $hour,
                     73:             #min       => $min,
                     74:             name  => $name,
                     75:             epoch => $epoch,
                     76:         };
                     77:
                     78:         if ( $name =~ m/\A $OBT->{BASENAME} /xms
                     79:             && !exists $Possible_Torrents{$name} )
                     80:         {
1.38    ! andrew     81:             print "Would remove impossible $_\n";
        !            82:             push @delete, $ct;
        !            83:         }
        !            84:         else {
        !            85:                if ($files{$ext}{$name}{$epoch}) {
        !            86:                    warn "Multiple torrents with $name and epoch $epoch\n";
        !            87:                    push @delete, $files{$ext}{$name}{$epoch};
        !            88:                }
        !            89:
        !            90:                $files{$ext}{$name}{$epoch} = $ct;
1.27      andrew     91:         }
1.38    ! andrew     92:
1.27      andrew     93:     }
                     94:     closedir DIR;
1.2       andrew     95: }
                     96:
1.25      andrew     97: #print Dump \%files;
1.28      andrew     98:
                     99: my %keep;
1.29      andrew    100: my %seen;
1.27      andrew    101: foreach my $name ( sort keys %{ $files{torrent} } ) {
                    102:     next unless $name =~ /^$Name_Filter/;
                    103:
1.31      andrew    104:     #next if $name !~ /songs/xms;
1.29      andrew    105:     #next if $name =~ /_packages_/xms;
1.27      andrew    106:     #print "Checking $name\n";
                    107:
1.29      andrew    108:     my $cn = $files{torrent}{$name};
1.27      andrew    109:
1.31      andrew    110: EPOCH: foreach my $epoch ( sort { $b <=> $a } keys %{$cn} ) {
1.29      andrew    111:         my $ct = $cn->{$epoch};
1.35      andrew    112:         my $cf = $ct->{dir} . '/' . $ct->{file};
1.27      andrew    113:
1.29      andrew    114:         #print "\t$epoch - $cf\n";
1.27      andrew    115:
                    116:         my $t;
                    117:         eval {
1.29      andrew    118:             $t
                    119:                 = BT::MetaInfo::Cached->new( $cf,
                    120:                 { cache_root => '/tmp/OBTFileCache' } );
1.27      andrew    121:         };
                    122:
                    123:         if ($@) {
1.29      andrew    124:             warn "Error reading torrent $cf\n";
                    125:             push @delete, $ct;
                    126:             next EPOCH;
1.27      andrew    127:         }
                    128:
1.29      andrew    129:         $ct->{comment} = $t->{comment};
1.27      andrew    130:         my ($path) = $t->{comment} =~ /($OBT->{BASENAME}\/[^\n]+)\n/s;
                    131:
1.29      andrew    132:         if ( !-e $OBT->{DIR_FTP} . "/$path" ) {
1.27      andrew    133:             print
1.29      andrew    134:                 'Deleting ',
                    135:                 $cn->{$epoch}{file}, ' the path (', $path,
                    136:                 ") doesn't exist.\n";
                    137:             push @delete, $ct;
                    138:             next EPOCH;
1.27      andrew    139:         }
                    140:
1.29      andrew    141:         my $hash = unpack( "H*", $t->info_hash );
                    142:         $ct->{info_hash} = $hash;
1.27      andrew    143:
                    144:         undef $t;
                    145:
1.29      andrew    146:         if ( $seen{$name} && $seen{$name} ne $hash ) {
1.31      andrew    147:             print "Removing older [$name] [$hash]\n\t",
1.35      andrew    148:                 $cf,
1.31      andrew    149:                 "\n";
                    150:             $ct->{reason} = 'older';
1.29      andrew    151:             push @delete, $ct;
                    152:             next EPOCH;
                    153:         }
1.31      andrew    154:         elsif ( keys %{$cn} == 1 && $ct->{dir} eq $OBT->{DIR_TORRENT} ) {
                    155:             $ct->{reason} = 'only';
1.29      andrew    156:         }
                    157:         elsif ( $keep{$hash} ) {
1.28      andrew    158:             if ( $keep{$hash}{epoch} == $epoch ) {
1.29      andrew    159:                 next EPOCH;
1.27      andrew    160:             }
1.29      andrew    161:
                    162:             print "Removing duplicate [$name] [$hash]\n\t",
1.35      andrew    163:                 $keep{$hash}{file}, "\n";
1.31      andrew    164:
                    165:             $keep{$hash}{reason} = 'duplicate';
                    166:             $ct->{reason} = 'duplicate';
                    167:
1.28      andrew    168:             push @delete, $keep{$hash};
                    169:         }
                    170:         else {
1.31      andrew    171:             $ct->{reason} = 'first';
                    172:         }
1.2       andrew    173:
1.31      andrew    174:         $keep{$hash} = $ct;
                    175:         $seen{$name} = $hash;
1.27      andrew    176:     }
1.2       andrew    177: }
                    178:
                    179: #print Dump \%files, \%keep, \@delete;
1.31      andrew    180: #print Dump \%keep, \@delete;
1.23      andrew    181: #exit;
1.2       andrew    182:
1.29      andrew    183: my $client = Transmission::Client->new;
                    184: my %seeding;
                    185: foreach my $torrent ( @{ $client->torrents } ) {
                    186:
                    187:     #my $status = Transmission::Utils::from_numeric_status($torrent->status);
                    188:     my $hash = $torrent->hash_string;
                    189:     if ( exists $keep{$hash} ) {
                    190:         $seeding{$hash} = $torrent;
                    191:     }
                    192:     else {
                    193:         print "No longer seeding [$hash]\n";
                    194:         $torrent->stop or warn $torrent->error_string;
                    195:         $client->remove( $torrent->id ) or warn $client->error;
1.27      andrew    196:     }
1.13      andrew    197: }
                    198:
1.27      andrew    199: #print Dump \%keep;
1.28      andrew    200: foreach my $hash ( keys %keep ) {
                    201:     my $file = $keep{$hash}{file} || q{};
                    202:     my $dir  = $keep{$hash}{dir}  || q{};
1.31      andrew    203:
                    204:     my $name  = $keep{$hash}{name};
                    205:     my $epoch = $keep{$hash}{epoch};
1.33      andrew    206:     my $reason = $keep{$hash}{reason} ? $keep{$hash}{reason} . q{ } : q{};
1.31      andrew    207:
1.32      andrew    208:     #if ($reason && $reason ne 'only') {
                    209:     #    print "Keeping $reason instance of [$file] [$hash]\n",
                    210:     #        "\t", $file, "\n";
                    211:     #}
1.31      andrew    212:
1.28      andrew    213:     if ( $dir eq $OBT->{DIR_NEW_TORRENT} ) {
                    214:         print "Moving $file to current torrents\n";
                    215:         rename( "$dir/$file", $OBT->{DIR_TORRENT} . "/" . $file )
                    216:             or die "Couldn't rename '$file': $!";
                    217:
1.29      andrew    218:         $dir = $OBT->{DIR_TORRENT};
1.37      andrew    219:         $keep{$hash}{dir} = $dir;
1.28      andrew    220:
                    221:         if ( exists $files{txt}{$name}{$epoch} ) {
                    222:             my $m_file = $files{txt}{$name}{$epoch}{file};
                    223:             my $m_dir  = $files{txt}{$name}{$epoch}{dir};
                    224:             rename( "$m_dir/$m_file", $OBT->{DIR_TORRENT} . "/" . $m_file )
                    225:                 or die "Couldn't rename '$m_file': $!";
1.35      andrew    226:             $files{txt}{$name}{$epoch}{dir} = $OBT->{DIR_TORRENT};
1.27      andrew    227:         }
                    228:     }
1.29      andrew    229:
                    230:     if ( !$seeding{$hash} ) {
1.34      andrew    231:         print 'Starting seed of ' . $reason . "[$file] [$hash]\n";
1.29      andrew    232:         if (!$client->add(
                    233:                 filename     => "$dir/$file",
                    234:                 download_dir => $OBT->{DIR_FTP},
                    235:             )
                    236:             )
                    237:         {
                    238:
                    239:             #warn $client->error, ": $dir/$file\n";
1.35      andrew    240:             print "Removing invalid torrent\n\t", $keep{$hash}{file}, "\n";
1.29      andrew    241:             push @delete, $keep{$hash};
                    242:         }
                    243:     }
                    244: }
                    245:
                    246: foreach (@delete) {
1.35      andrew    247:     my $path = $_->{dir} . '/' . $_->{file};
                    248:     if ( -e $path ) {
                    249:         print "Deleting '$path'\n";
                    250:         unlink $path or die "Couldn't delete $path";
1.31      andrew    251:         delete $files{torrent}{ $_->{name} }{ $_->{epoch} };
1.29      andrew    252:     }
                    253:     else {
                    254:         use Data::Dumper;
                    255:         print Dumper $_;
                    256:     }
                    257: }
                    258:
                    259: foreach my $name ( keys %{ $files{ $OBT->{META_EXT} } } ) {
                    260:     foreach my $epoch ( keys %{ $files{ $OBT->{META_EXT} }{$name} } ) {
                    261:         unless ( exists $files{torrent}{$name}{$epoch} ) {
1.35      andrew    262:             my $path = $files{ $OBT->{META_EXT} }{$name}{$epoch}{dir}
                    263:                      . '/'
                    264:                      . $files{ $OBT->{META_EXT} }{$name}{$epoch}{file};
                    265:
1.29      andrew    266:             print "Unlinking '$path'\n";
                    267:             unlink $path or die "couldn't unlink '$path': $!";
                    268:         }
                    269:     }
1.13      andrew    270: }
1.29      andrew    271:
                    272: $client->start;
1.13      andrew    273:
1.27      andrew    274: sub Process_Dir {
                    275:     my $basedir = shift;
1.13      andrew    276:
1.27      andrew    277:     my ( $dirs, $files ) = Get_Files_and_Dirs($basedir);
                    278:     if (@$files) {
                    279:         my $dir = $basedir;
                    280:         $dir =~ s/^$OBT->{DIR_FTP}\///;
1.31      andrew    281:         Make_Possible($dir);
1.27      andrew    282:         foreach my $file (@$files) {
                    283:             if ( $file =~ /$INSTALL_ISO_REGEX/ ) {
1.31      andrew    284:                 Make_Possible("$dir/$file");
1.38    ! andrew    285:             }
        !           286:             elsif ( $file =~ /$SONG_REGEX/xms ) {
        !           287:                 Make_Possible("$dir/$1");
1.27      andrew    288:             }
1.15      andrew    289:         }
1.27      andrew    290:     }
                    291:
                    292:     foreach my $subdir (@$dirs) {
                    293:         next if $subdir eq '.';
                    294:         next if $subdir eq '..';
                    295:         Process_Dir("$basedir/$subdir");
                    296:     }
1.15      andrew    297: }
                    298:
1.31      andrew    299: sub Make_Possible {
                    300:     my ($path) = @_;
                    301:
                    302:     my $torrent = Name_Torrent($path);
                    303:     $torrent =~ s/-.*$//;
                    304:     $Possible_Torrents{$torrent} = 1;
                    305:
                    306:     return $torrent;
                    307: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>