| 14 | | #Days |
|---|
| 15 | | my $diff = shift @ARGV || 0; |
|---|
| 16 | | my $gctr = shift @ARGV || 5; |
|---|
| 17 | | my $time = time; |
|---|
| 18 | | my $days = int($time/86400) - $diff; |
|---|
| | 44 | sub usage { |
|---|
| | 45 | print "\n"; |
|---|
| | 46 | print "fuzzy-stats [ options ] [ num days ago ] [ num entries to show ]\n"; |
|---|
| | 47 | print " default 0 default 5\n"; |
|---|
| | 48 | print "Options: --all Show all entries (ignore num days limit)\n"; |
|---|
| | 49 | print " --colons Print hashes in colon delimited format\n"; |
|---|
| | 50 | print " --dbtype=2|3 Force MLDBM (2) or MySQL (3) data source\n"; |
|---|
| | 51 | print " --debug Print ugly raw data\n"; |
|---|
| | 52 | print " --help This screen\n"; |
|---|
| | 53 | print " --verbose Print informational details\n"; |
|---|
| | 54 | print "\n"; |
|---|
| | 55 | exit; |
|---|
| | 56 | } |
|---|
| 20 | | foreach my $f (keys %Files) { |
|---|
| 21 | | my %DB; my $err = 0; |
|---|
| 22 | | tie %DB, 'MLDBM', $Files{$f} or ++$err; |
|---|
| 23 | | next if $err; my @Top = (); |
|---|
| 24 | | foreach my $k (keys %DB) { |
|---|
| 25 | | my $db = $DB{$k}; |
|---|
| 26 | | $Stats{$f}{'images'}++; |
|---|
| 27 | | $Stats{$f}{'score'} += $db->{score}; |
|---|
| 28 | | if (int($db->{check}/86400) == $days) { |
|---|
| 29 | | $Stats{$f}{'today'}++; |
|---|
| 30 | | $Stats{$f}{'score2'} += $db->{score}; |
|---|
| 31 | | my @basic = split(':',$db->{basic}); |
|---|
| 32 | | my $line; |
|---|
| 33 | | if ($db->{score}) { |
|---|
| 34 | | $line = sprintf "%5d Time(s) -> %8.3f %9d %dx%dx%d" |
|---|
| 35 | | ,$db->{match}+1,$db->{score},@basic; |
|---|
| 36 | | } else { |
|---|
| 37 | | $line = sprintf "%5d Time(s) -> %9d %dx%dx%d" |
|---|
| 38 | | ,$db->{match}+1,@basic; |
|---|
| 39 | | } |
|---|
| 40 | | foreach my $t (qw/fname ctype/) { |
|---|
| 41 | | $line .= sprintf ' %s',$db->{$t} if defined $db->{$t}; |
|---|
| 42 | | } |
|---|
| 43 | | push @Top,$line; |
|---|
| 44 | | } |
|---|
| 45 | | $Stats{$f}{'oldest'} = $db->{input} |
|---|
| 46 | | unless $Stats{$f}{'oldest'}; |
|---|
| 47 | | $Stats{$f}{'oldest'} = $db->{input} |
|---|
| 48 | | if ($Stats{$f}{'oldest'} > $db->{input}); |
|---|
| | 58 | open CONFIG, "< $cfgfile" or warn "Can't read configuration file, using defaults...\n"; |
|---|
| | 59 | |
|---|
| | 60 | while (<CONFIG>) { |
|---|
| | 61 | chomp; |
|---|
| | 62 | if ($_ =~ m/^focr_enable_image_hashing (\d)/) { |
|---|
| | 63 | $App{hashing_type} = $1; |
|---|
| | 64 | printf "Found DB Hashing\n" if ($verbose and $1 == 2); |
|---|
| | 65 | printf "Found MySQL Hashing\n" if ($verbose and $1 == 3); |
|---|
| | 66 | } |
|---|
| | 67 | if ($_ =~ m/^focr_mysql_(\w+) (.+)/) { |
|---|
| | 68 | $MySQL{$1} = $2; |
|---|
| | 69 | printf "Found MySQL option $1 => '$2'\n" if $verbose; |
|---|
| | 71 | } |
|---|
| | 72 | |
|---|
| | 73 | close CONFIG; |
|---|
| | 74 | |
|---|
| | 75 | # Allow user to override location of data (2 -> MLDBM, 3 -> MySQL) |
|---|
| | 76 | $App{'hashing_type'} = $opts{'dbtype'} || $App{'hashing_type'}; |
|---|
| | 77 | |
|---|
| | 78 | sub get_ddb { |
|---|
| | 79 | my %dopts = ( AutoCommit => 1 ); |
|---|
| | 80 | my $dsn = "dbi:mysql:database=".$MySQL{db}; |
|---|
| | 81 | if (defined $MySQL{socket}) { |
|---|
| | 82 | $dsn .= ";mysql_socket=$MySQL{socket}"; |
|---|
| | 83 | } else { |
|---|
| | 84 | $dsn .= ";host=$MySQL{host}"; |
|---|
| | 85 | $dsn .= ";port=$MySQL{port}" unless $MySQL{port} == 3306; |
|---|
| | 86 | } |
|---|
| | 87 | printf "Connecting to: $dsn\n" if $verbose; |
|---|
| | 88 | return DBI->connect($dsn,$MySQL{user},$MySQL{pass},\%dopts); |
|---|
| | 89 | } |
|---|
| | 90 | |
|---|
| | 91 | sub print_summary { |
|---|
| | 92 | my ($f,$time,$gctr,@Top) = @_; |
|---|
| | 93 | # %Stats is a global variable |
|---|
| | 120 | |
|---|
| | 121 | sub process_items { |
|---|
| | 122 | my ($Stats,$f,$db,$days,%opts) = @_; |
|---|
| | 123 | my @Text = (); |
|---|
| | 124 | |
|---|
| | 125 | $Stats->{$f}{'images'}++; |
|---|
| | 126 | $Stats->{$f}{'score'} += $db->{score}; |
|---|
| | 127 | if (int($db->{check}/86400) == $days || $opts{'all'}) { |
|---|
| | 128 | $Stats->{$f}{'today'}++; |
|---|
| | 129 | $Stats->{$f}{'score2'} += $db->{score}; |
|---|
| | 130 | my @basic = split(':',$db->{basic}); |
|---|
| | 131 | my $line; |
|---|
| | 132 | # Output is human readable by default, but if user wants to |
|---|
| | 133 | # easily delete items, print in ::: format for easy cut/paste |
|---|
| | 134 | my $format = $opts{'colon'} ? "%9d:%d:%d:%d" : "%9d %dx%dx%d"; |
|---|
| | 135 | if ($db->{score}) { |
|---|
| | 136 | $line = sprintf "%5d Time(s) -> %8.3f $format" |
|---|
| | 137 | ,$db->{match}+1,$db->{score},@basic; |
|---|
| | 138 | } else { |
|---|
| | 139 | $line = sprintf "%5d Time(s) -> $format" |
|---|
| | 140 | ,$db->{match}+1,@basic; |
|---|
| | 141 | } |
|---|
| | 142 | foreach my $t (qw/fname ctype/) { |
|---|
| | 143 | $line .= sprintf ' %s',$db->{$t} if defined $db->{$t}; |
|---|
| | 144 | } |
|---|
| | 145 | push @Text, $line; |
|---|
| | 146 | } |
|---|
| | 147 | $Stats->{$f}{'oldest'} = $db->{input} |
|---|
| | 148 | unless $Stats->{$f}{'oldest'}; |
|---|
| | 149 | $Stats->{$f}{'oldest'} = $db->{input} |
|---|
| | 150 | if ($Stats->{$f}{'oldest'} > $db->{input}); |
|---|
| | 151 | #print Dumper @Text if $opts{debug}; |
|---|
| | 152 | return @Text; |
|---|
| | 153 | } |
|---|
| | 154 | |
|---|
| | 155 | #Days |
|---|
| | 156 | my $diff = shift @ARGV || 0; |
|---|
| | 157 | my $gctr = shift @ARGV || 5; |
|---|
| | 158 | my $time = time; |
|---|
| | 159 | my $days = int($time/86400) - $diff; |
|---|
| | 160 | |
|---|
| | 161 | if ($App{hashing_type} == 2) { |
|---|
| | 162 | foreach my $f (keys %Files) { |
|---|
| | 163 | my %DB; my $err = 0; |
|---|
| | 164 | tie %DB, 'MLDBM', $Files{$f} or ++$err; |
|---|
| | 165 | next if $err; my @Top = (); |
|---|
| | 166 | foreach my $k (keys %DB) { |
|---|
| | 167 | my $db = $DB{$k}; |
|---|
| | 168 | # Pass global %Stats reference and modify values in func |
|---|
| | 169 | push @Top, &process_items(\%Stats,$f,$db,$days,%opts); |
|---|
| | 170 | } |
|---|
| | 171 | print_summary($f,$time,$gctr,@Top); |
|---|
| | 172 | } |
|---|
| | 173 | } elsif ($App{hashing_type} == 3) { |
|---|
| | 174 | my $key = '%'; |
|---|
| | 175 | my $dbb = get_ddb(); |
|---|
| | 176 | if ($dbb) { |
|---|
| | 177 | my $now = time; |
|---|
| | 178 | foreach my $f (keys %Files) { |
|---|
| | 179 | my @Top = (); |
|---|
| | 180 | my $db; |
|---|
| | 181 | $f =~ s/db_//; |
|---|
| | 182 | my $sql = "SELECT * FROM $MySQL{$f}"; |
|---|
| | 183 | my $data = $dbb->selectall_arrayref($sql,undef); |
|---|
| | 184 | foreach my $dbref (@{$data}) { |
|---|
| | 185 | # Shove into the generic hashref to pass to process func |
|---|
| | 186 | $db = { 'basic' => $dbref->[1], |
|---|
| | 187 | 'fname' => $dbref->[2], |
|---|
| | 188 | 'ctype' => $dbref->[3], |
|---|
| | 189 | 'match' => $dbref->[5], |
|---|
| | 190 | 'input' => $dbref->[6], |
|---|
| | 191 | 'check' => $dbref->[7], |
|---|
| | 192 | 'score' => $dbref->[8], |
|---|
| | 193 | }; |
|---|
| | 194 | # Pass global %Stats reference and modify values in func |
|---|
| | 195 | push @Top, &process_items(\%Stats,$f,$db,$days,%opts); |
|---|
| | 196 | } |
|---|
| | 197 | print Dumper @Top if $opts{debug}; |
|---|
| | 198 | print_summary($f,$time,$gctr,@Top); |
|---|
| | 199 | } |
|---|
| | 200 | } |
|---|
| | 201 | } |