1. #!/usr/bin/perl
  2. # Filename: photoreflect
  3. # Author:   David Ljung Madison <DaveSource.com>
  4. # See License:  http://MarginalHacks.com/License/
  5. # Description:  Downloads a set of photoreflect images without watermarks
  6. use strict;
  7.  
  8. ## Thumbnail pages
  9. #http://www.photoreflect.com/pr3/OrderPage.aspx?pi=0R1G000Z000000&po=0&c=3UJ95V
  10.  
  11.  
  12. ## A photoreflect image page URL looks like this:
  13. # http://www.photoreflect.com/pr3/OrderPage.aspx?pi=0R1G0011000000&po=10&c=3UJ95V
  14. ## The watermarked image can be found by looking for 'startingImgSrc':
  15. # WAS: http://www.photoreflect.com/prbin/prpv.dll?photo?s=0&i=0R1G000Z000010&p=3UJ95V
  16. # NOW: http://www.photoreflect.com/prbin/prpv.dll?photo?s=0&i=0R1G0011000000&p=&e=
  17. ## And s=-1 gives us the non-watermarked image
  18. # http://www.photoreflect.com/prbin/prpv.dll?photo?s=-1&i=0R1G0011000000&p=&e=
  19.  
  20. # We could get the number of images from the image page:
  21. # "var imageCount = 138;"
  22.  
  23. my $IMAGE = 'http://www.photoreflect.com/prbin/prpv.dll?photo?s=-1&i=%{pi}&p=%c';
  24. #my $SAVE = '%{pi}_%c.jpg';
  25. ## We don't need the %c for the save!
  26. my $SAVE = '%{pi}.jpg';
  27.  
  28. # Downloader
  29. my $GET = "GET -H 'user-agent: Mozilla/5.0'";
  30. my $LYNX = "lynx -source";
  31.  
  32. # Pick one
  33. my $FETCH = $LYNX;
  34.  
  35. ##################################################
  36. # Setup the variables
  37. ##################################################
  38. my $PROGNAME = $0; $PROGNAME =~ s|.*/||;
  39. my ($BASENAME,$PROGNAME) = ($0 =~ m|(.*)/(.+)|) ? ($1?$1:'/',$2) : ('.',$0);
  40.  
  41.  
  42. ##################################################
  43. # Usage
  44. ##################################################
  45. sub fatal {
  46.     foreach my $msg (@_) { print STDERR "[$PROGNAME] ERROR:  $msg\n"; }
  47.     exit(-1);
  48. }
  49.  
  50. sub usage {
  51.     foreach my $msg (@_) { print STDERR "ERROR:  $msg\n"; }
  52.     print STDERR <<USAGE;
  53.  
  54. Usage:\t$PROGNAME [-d] <first-image-url> <num_images>
  55. \tDownload a set of photoreflect images without watermarks
  56. \t-d\tSet debug mode
  57.  
  58. Go to the first image page of a photoreflect photo set.
  59. You *must* go to this image by clicking on the thumbnail page, do
  60. not navigate to it from another image using the next/prev buttons.
  61.  
  62. The second arg is the number of images in the set, or the number you want.
  63.  
  64. You will likely need to put the url in quotes (depending on your shell)
  65.  
  66. USAGE
  67.     exit -1;
  68. }
  69.  
  70. sub parse_args {
  71.     my $opt = {};
  72.     while (my $arg=shift(@ARGV)) {
  73.         if ($arg =~ /^-h$/) { usage(); }
  74.         if ($arg =~ /^-d$/) { $MAIN::DEBUG=1; next; }
  75.         if ($arg =~ /^-/) { usage("Unknown option: $arg"); }
  76.         if (!$opt->{url}) { $opt->{url} = $arg; next; }
  77.         if ($arg =~ /^\d+$/) { $opt->{cnt} = $arg; next; }
  78.         usage();
  79.     }
  80.     usage("No url defined") unless $opt->{url};
  81.    
  82.     $opt;
  83. }
  84.  
  85. sub debug {
  86.     return unless $MAIN::DEBUG;
  87.     foreach my $msg (@_) { print STDERR "[$PROGNAME] $msg\n"; }
  88. }
  89.  
  90. ##################################################
  91. # URL wrangling
  92. ##################################################
  93. sub parseQuery {
  94.     my ($url) = @_;
  95.     my %ret;
  96.     return \%ret unless $url =~ s/.*\?//;
  97.     foreach my $kv ( split('&',$url) ) {
  98.         my ($k,$v) = split('=',$kv,2);
  99.         $ret{$k}=$v;
  100.         $ret{"orig_$k"}=$v;
  101.     }
  102.     return \%ret;
  103. }
  104.  
  105. sub replaceQuery {
  106.     my ($url,$q) = @_;
  107.     while ($url =~ s/%{([^}]+)}/$q->{$1}/g || $url =~ s/%([^{])/$q->{$1}/g) {};
  108.     $url;
  109. }
  110.  
  111. sub interrupt { die("[$PROGNAME] Interrupted\n"); }
  112. $SIG{INT} = \&interrupt; $SIG{TERM} = \&interrupt;
  113. $SIG{HUP} = \&interrupt; $SIG{QUIT} = \&interrupt;
  114. $SIG{EXIT} = \&interrupt; $SIG{__DIE__} = \&interrupt;
  115.  
  116. sub getURL {
  117.     my ($url,$to) = @_;
  118.     system("$FETCH \Q$url\E > \Q$to\E");
  119.     my ($exit,$signal,$dump) = ($? >> 8, $? & 127, $? & 128);
  120.     fatal("Error from $GET:\n  code: $!") if $exit;
  121.     fatal("Core dump for:\n  code: $!") if $dump;
  122.     interrupt() if $signal;
  123. }
  124.  
  125. sub inc {
  126.     my ($q) = @_;
  127.     # Increment the values.  Add one to pi, and increment each piece of c
  128.     $q->{pi} =~ s/(\d{1,4})$//;
  129.     my ($num,$len) = ($1,length($1));
  130.     $num++;
  131.     $q->{pi} .= sprintf("%0.${len}d",$num);
  132.  
  133.     my @c = split(//,$q->{c});
  134.     @c = map { $_++; substr($_,-1,1); } @c;
  135.  
  136.     # Every 10 we start over??
  137.     @c = split(//,$q->{orig_c}) if !($num%10);
  138.  
  139.     # For every 100 we add one to the third letter??
  140.     my $hun = $num%10 ? 0 : int($num/100);
  141.     while ($hun--) { $c[2]++; }
  142.     $c[2] = substr($c[2],-1,1);
  143.  
  144.     # Every 1000, what happens???
  145.  
  146.     $q->{c} = join('', @c);
  147. }
  148.  
  149. ##################################################
  150. # Main code
  151. ##################################################
  152. sub main {
  153.     my $opt = parse_args();
  154.    
  155.     debug("$opt->{url}\n");
  156.     my $query = parseQuery($opt->{url});
  157.     usage("URL missing 'pi=...' query") unless $query->{pi};
  158.     usage("'pi=...' query must end in a number") unless $query->{pi} =~ /\d$/;
  159. $query->{c} |= 0;   # Photoreflect doesn't use 'c=' always.
  160.     usage("URL missing 'c=...' query") unless defined $query->{c};
  161.     debug("  pi = $query->{pi}");
  162.     debug("  c  = $query->{c}");
  163.     my $cnt=0;
  164.     while ($cnt++< $opt->{cnt}) {
  165.         my $img = replaceQuery($IMAGE,$query);
  166.         debug("Img: $img");
  167.         my $save = replaceQuery($SAVE,$query);
  168.         print "$save\n";
  169.         getURL($img,$save); #unless $cnt<109;
  170.  
  171.         inc($query);
  172.     }
  173. }
  174. main();