| version 1.11, 2005/04/07 00:04:40 | version 1.27, 2010/01/05 19:43:44 | 
|  |  | 
| #!/usr/bin/perl -T | #!/usr/bin/perl -T | 
| #$Id$ | #$RedRiver: CurrentTorrents.pl,v 1.26 2009/10/20 19:04:28 andrew Exp $ | 
| use strict; | use strict; | 
| use warnings; | use warnings; | 
| use diagnostics; | use diagnostics; | 
|  |  | 
| use BT::MetaInfo; |  | 
| use Time::Local; | use Time::Local; | 
|  | use Fcntl ':flock'; | 
|  | use File::Basename; | 
|  |  | 
|  | #use YAML; | 
|  |  | 
| use lib 'lib'; | use lib 'lib'; | 
| use OpenBSDTorrents; | use OpenBSDTorrents; | 
|  | use BT::MetaInfo::Cached; | 
|  |  | 
| %ENV = (); | %ENV = (); | 
|  |  | 
| #use YAML; | #justme(); | 
|  |  | 
| justme(); | my $Name_Filter = shift || ''; | 
|  | if ( $Name_Filter =~ /^(\w*)$/ ) { | 
|  | $Name_Filter = $1; | 
|  | } | 
|  | else { | 
|  | die "Invalid filter: $Name_Filter"; | 
|  | } | 
|  |  | 
|  | my %Possible_Torrents; | 
|  | Process_Dir( $OBT->{DIR_FTP} ); | 
|  |  | 
| my %files; | my %files; | 
| opendir DIR, $OBT->{DIR_TORRENT} | my %keep; | 
| or die "Couldn't opendir $OBT->{DIR_TORRENT}: $!"; | my @delete; | 
| foreach (readdir DIR) { | foreach my $DIR ( $OBT->{DIR_NEW_TORRENT}, $OBT->{DIR_TORRENT} ) { | 
| if (/^([^\/]+)$/) { | opendir DIR, $DIR | 
| $_ = $1; | or die "Couldn't opendir $DIR: $!"; | 
| } else { | foreach ( readdir DIR ) { | 
| die "Invalid character in $_: $!"; | next unless my ($ext) = /\.(torrent|$OBT->{META_EXT})$/; | 
| } |  | 
| next unless /\.torrent$/; |  | 
| my ($name, $year, $mon, $mday, $hour, $min) = |  | 
| /^(.*)-(\d{4})-(\d{2})-(\d{2})-(\d{2})(\d{2})/; |  | 
|  |  | 
| $mon--; | if (/^([^\/]+)$/) { | 
| my $epoch = timegm(0,$min,$hour,$mday,$mon,$year); | $_ = $1; | 
|  | } | 
|  | else { | 
|  | die "Invalid character in $_: $!"; | 
|  | } | 
|  | my $epoch = 0; | 
|  | my $name = basename( $_, '.torrent' ); | 
|  |  | 
| #print "Adding $_\n"; | if ( my ( $base, $year, $mon, $mday, $hour, $min ) | 
|  | = /^(.*)-(\d{4})-(\d{2})-(\d{2})-(\d{2})(\d{2})/ ) | 
|  | { | 
|  |  | 
| $files{$name}{$epoch} = { | $mon--; | 
| file      => $_, | $epoch = timegm( 0, $min, $hour, $mday, $mon, $year ); | 
| year      => $year, | $name = $base; | 
| mon       => $mon, | } | 
| mday      => $mday, |  | 
| hour      => $hour, |  | 
| min       => $min, |  | 
| epoch     => $epoch, |  | 
| }; |  | 
|  |  | 
|  | #print "Adding $_\n"; | 
|  |  | 
|  | $files{$ext}{$name}{$epoch} = { | 
|  | file => $_, | 
|  | dir  => $DIR, | 
|  | path => "$DIR/$_", | 
|  | ext  => $ext, | 
|  |  | 
|  | #year      => $year, | 
|  | #mon       => $mon, | 
|  | #mday      => $mday, | 
|  | #hour      => $hour, | 
|  | #min       => $min, | 
|  | name  => $name, | 
|  | epoch => $epoch, | 
|  | }; | 
|  |  | 
|  | if ( $name =~ m/\A $OBT->{BASENAME} /xms | 
|  | && !exists $Possible_Torrents{$name} ) | 
|  | { | 
|  | print "Would remove $_\n"; | 
|  | push @delete, $files{$ext}{$name}{$epoch}; | 
|  | } | 
|  | } | 
|  | closedir DIR; | 
| } | } | 
| closedir DIR; |  | 
|  |  | 
| my %keep; | #print Dump \%files; | 
| my @delete; | foreach my $name ( sort keys %{ $files{torrent} } ) { | 
| foreach my $name (keys %files) { | next unless $name =~ /^$Name_Filter/; | 
| #print "$name\n"; |  | 
|  |  | 
| foreach my $epoch ( sort { $b <=> $a } keys %{ $files{$name} } ) { | #print "Checking $name\n"; | 
| #print "\t$epoch\n"; |  | 
| my $torrent = $files{$name}{$epoch}{file}; |  | 
|  |  | 
| my $t; | foreach my $epoch ( sort { $b <=> $a } keys %{ $files{torrent}{$name} } ) | 
| eval { $t = BT::MetaInfo->new($OBT->{DIR_TORRENT} . "/$torrent"); }; | { | 
| if ($@) { |  | 
| warn "Error reading torrent $torrent\n"; |  | 
| next; |  | 
| } |  | 
|  |  | 
| $files{$name}{$epoch}{comment}   = $t->{comment}; | #print "\t$epoch\n"; | 
| my ($path) = $t->{comment} =~ /Files from ([^\n]+)\n/s; | my $torrent = $files{torrent}{$name}{$epoch}{path}; | 
|  |  | 
| unless (-d $OBT->{DIR_FTP} . "/$path") { | if ( keys %{ $files{torrent}{$name} } == 1 | 
| #print "Deleting $files{$name}{$epoch}{file} the path doesn't exist.\n"; | && $files{torrent}{$name}{$epoch}{dir} eq $OBT->{DIR_TORRENT} ) | 
| push @delete, $files{$name}{$epoch}{file}; | { | 
| } |  | 
|  |  | 
| if (keys %{ $files{$name} } == 1) { | #print "Skipping torrent for $name there is only one.\n"; | 
| #print "Skipping torrent for $name there is only one.\n"; | next; | 
| next; | } | 
| } |  | 
|  |  | 
| my $hash = $t->info_hash; | my $t; | 
| $hash = unpack("H*", $hash); | eval { | 
|  | $t = BT::MetaInfo::Cached->new( | 
|  | $torrent, | 
|  | {   cache_root => '/tmp/OBTFileCache' | 
|  |  | 
| $files{$name}{$epoch}{info_hash} = $hash; | #$OBT->{DIR_HOME} . '/FileCache' | 
|  | } | 
|  | ); | 
|  | }; | 
|  |  | 
| undef $t; | if ($@) { | 
|  | warn "Error reading torrent $torrent\n"; | 
|  | push @delete, $files{torrent}{$name}{$epoch}; | 
|  | delete $files{torrent}{$name}{$epoch}; | 
|  | next; | 
|  | } | 
|  |  | 
| if (exists $keep{$name}) { | $files{torrent}{$name}{$epoch}{comment} = $t->{comment}; | 
| if (exists $keep{$name}{$hash}) { | my ($path) = $t->{comment} =~ /($OBT->{BASENAME}\/[^\n]+)\n/s; | 
| push @delete, $keep{$name}{$hash}; |  | 
| $keep{$name}{$hash} = |  | 
| $files{$name}{$epoch}{file}; |  | 
| } else { |  | 
| push @delete, $files{$name}{$epoch}{file}; |  | 
| } |  | 
| } else { |  | 
| $keep{$name}{$hash} = |  | 
| $files{$name}{$epoch}{file}; |  | 
|  |  | 
| } | unless ( -e $OBT->{DIR_FTP} . "/$path" ) { | 
| } | print | 
|  | "Deleting $files{torrent}{$name}{$epoch}{file} the path ($path) doesn't exist.\n"; | 
|  | push @delete, $files{torrent}{$name}{$epoch}; | 
|  | delete $files{torrent}{$name}{$epoch}; | 
|  | next; | 
|  | } | 
|  |  | 
|  | my $hash = $t->info_hash; | 
|  | $hash = unpack( "H*", $hash ); | 
|  |  | 
|  | undef $t; | 
|  |  | 
|  | $files{torrent}{$name}{$epoch}{info_hash} = $hash; | 
|  |  | 
|  | if ( exists $keep{$name} ) { | 
|  | if ( exists $keep{$name}{$hash} ) { | 
|  | if ( $keep{$name}{$hash}{epoch} == $epoch ) { | 
|  | next; | 
|  | } | 
|  | print "Removing [$name] [$hash]\n\t", | 
|  | $keep{$name}{$hash}{path}, | 
|  | "\n"; | 
|  | push @delete, $keep{$name}{$hash}; | 
|  | delete $files{torrent}{ $keep{$name}{$hash}{name} } | 
|  | { $keep{$name}{$hash}{epoch} }; | 
|  | $keep{$name}{$hash} = $files{torrent}{$name}{$epoch}; | 
|  | print "Keeping additional instance of  [$name] [$hash]\n\t", | 
|  | $keep{$name}{$hash}{path}, | 
|  | "\n"; | 
|  | } | 
|  | else { | 
|  | print "Removing old [$name] [$hash]\n"; | 
|  | if ( $keep{$name}{$hash}{path} ) { | 
|  | print "\t", $keep{$name}{$hash}{path}, "\n"; | 
|  | } | 
|  | push @delete, $files{torrent}{$name}{$epoch}; | 
|  | delete $files{torrent}{$name}{$epoch}; | 
|  | } | 
|  | } | 
|  | else { | 
|  | print "Keeping first instance of $name [$hash]\n\t", | 
|  | $files{torrent}{$name}{$epoch}{path}, | 
|  | "\n"; | 
|  | $keep{$name}{$hash} = $files{torrent}{$name}{$epoch}; | 
|  |  | 
|  | } | 
|  | } | 
| } | } | 
|  |  | 
| #print Dump \%files, \%keep, \@delete; | #print Dump \%files, \%keep, \@delete; | 
|  | #exit; | 
|  |  | 
| foreach (@delete) { | foreach (@delete) { | 
| print "Deleting '$_'\n"; | print "Deleting '$_->{path}'\n"; | 
| unlink $OBT->{DIR_TORRENT} . "/$_" or die "Couldn't unlink $_"; | unlink $_->{path} or die "Couldn't unlink $_->{path}"; | 
| } | } | 
|  |  | 
|  | foreach my $name ( keys %{ $files{ $OBT->{META_EXT} } } ) { | 
|  | foreach my $epoch ( keys %{ $files{ $OBT->{META_EXT} }{$name} } ) { | 
|  | unless ( exists $files{torrent}{$name}{$epoch} ) { | 
|  | my $path = $files{ $OBT->{META_EXT} }{$name}{$epoch}{path}; | 
|  | print "Unlinking '$path'\n"; | 
|  | unlink $path or die "couldn't unlink '$path': $!"; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | #print Dump \%keep; | 
|  | foreach my $name ( keys %keep ) { | 
|  | foreach my $hash ( keys %{ $keep{$name} } ) { | 
|  | my $file = $keep{$name}{$hash}{file} || q{}; | 
|  | my $dir  = $keep{$name}{$hash}{dir}  || q{}; | 
|  | if ( $dir eq $OBT->{DIR_NEW_TORRENT} ) { | 
|  | print "Moving $file to current torrents\n"; | 
|  | rename( "$dir/$file", $OBT->{DIR_TORRENT} . "/" . $file ) | 
|  | or die "Couldn't rename '$file': $!"; | 
|  |  | 
|  | my $name  = $keep{$name}{$hash}{name}; | 
|  | my $epoch = $keep{$name}{$hash}{epoch}; | 
|  |  | 
|  | if ( exists $files{txt}{$name}{$epoch} ) { | 
|  | my $m_file = $files{txt}{$name}{$epoch}{file}; | 
|  | my $m_dir  = $files{txt}{$name}{$epoch}{dir}; | 
|  | rename( "$m_dir/$m_file", | 
|  | $OBT->{DIR_TORRENT} . "/" . $m_file ) | 
|  | or die "Couldn't rename '$m_file': $!"; | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | sub Process_Dir { | 
|  | my $basedir = shift; | 
|  |  | 
|  | my ( $dirs, $files ) = Get_Files_and_Dirs($basedir); | 
|  | if (@$files) { | 
|  | my $dir = $basedir; | 
|  | $dir =~ s/^$OBT->{DIR_FTP}\///; | 
|  | my $torrent = Name_Torrent($dir); | 
|  | $torrent =~ s/-.*$//; | 
|  | $Possible_Torrents{$torrent} = 1; | 
|  | foreach my $file (@$files) { | 
|  | if ( $file =~ /$INSTALL_ISO_REGEX/ ) { | 
|  | $torrent = Name_Torrent("$dir/$file"); | 
|  | $torrent =~ s/-.*$//; | 
|  | $Possible_Torrents{$torrent} = 1; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | foreach my $subdir (@$dirs) { | 
|  | next if $subdir eq '.'; | 
|  | next if $subdir eq '..'; | 
|  | Process_Dir("$basedir/$subdir"); | 
|  | } | 
|  | } | 
|  |  |