*** cgi-bin/ljprotocol.pl.orig	Sun Apr 15 04:39:09 2001
--- cgi-bin/ljprotocol.pl	Sun Apr 15 10:43:32 2001
***************
*** 1301,1312 ****
--- 1301,1431 ----
          return 1;
      }
         
+     ####
+     #### MODE: uploadpic
+     ####
+     if ($req->{'mode'} eq "uploadpic")
+     {
+         use LWP::Simple;
+         use Image::Size;
+         use Digest::MD5 qw(md5_base64);
  
+         # should these be in ljlib.pl?
+         my $MAX_SIZE_KBYTES = 40;
+         my $MAX_NUMPICS = 3;
+         my $MAX_NUMPICS_PAID = { early => 6, paid => 10, on => 15 };
+             
+         # helper functions for setting result stuff, to avoid repeating code.
+         # perhaps these should be declared outside this block for use elsewhere.
+         my $fail = sub {
+             my $msg = shift; 
+             $res->{success} = "FAIL";
+             $res->{errmsg}  = $msg;
+         };
+         my $dbfail = sub {
+             $fail->("Database error: " . $dbh->errstr);
+         };
+         my $success = sub {
+             my %args = @_;
+             $res->{success} = "OK";
+             while (my ($key, $value) = each %args) {
+                 $res->{$key} = $value;
+             }
+         };
+             
+         # are they already at max pictures uploaded?
+         # if so, fail, and maybe suggest a paid account.
+         $sth = $dbh->prepare("SELECT COUNT(*) FROM userpic WHERE userid=$userid");
+         $sth->execute;
+         my $numpics = $sth->fetchrow_array;
+         my $max_numpics = ($MAX_NUMPICS_PAID->{$paidfeatures} or $MAX_NUMPICS);
+         if ($numpics >= $max_numpics) {
+             my $maybe_suggest_paid = "";
+             if ($max_numpics < $MAX_NUMPICS->{paid}) {
+                 $maybe_suggest_paid = " (or <A HREF=\"/paidaccounts/\">purchase a paid account</A>)";
+             }
+             $fail->("You are already at your limit of $max_numpics pictures.  You cannot upload this picture until you <A HREF=\"/editpics.bml\">delete an existing one</A>${maybe_suggest_paid}.");
+         }
+ 
+         # get the data, check for file size
+         my $img;
+         if (exists $req->{data} and exists $req->{url}) {
+             return $fail->("Cannot specify both image data and URL.");
+         } elsif (exists $req->{data}) {
+             $img = $req->{data};
+         } elsif (exists $req->{url}) {
+             $img = get($req->{url});
+             $img
+               or return $fail->("Unable to retrieve image at " . $req->{url});
+         } else {
+             return $fail->("No image data or URL specified.");
+         }
+         # XXX - it'd be nice to check size BEFORE slurping all the bytes
+         length($img) < $MAX_SIZE_KBYTES * 1024
+           or return $fail->("File size exceeds limit of ${MAX_SIZE_KBYTES}K.");
+         
+         # check file type, dimensions of image
+         my ($width, $height, $filetype) = imgsize(\$img);
+         $filetype eq "JPG" or $filetype eq "PNG" or $filetype eq "GIF"
+           or return $fail->("Data is not in a supported image file format.  Only JPG, PNG, and GIF files are supported.  Use an image/photo program to convert this picture to one of these three formats.");
+         $width <= 100 and $height <= 100
+           or return $fail->("Picture dimensions (${width}x${height}) exceed limit of 100x100 pixels.  Use an image/photo program to reduce the size of this picture.");
+         
+         # is this image a duplicate?  if so, get existing picid.
+         my $qbase64 = $dbh->quote(md5_base64($img));
+         $sth = $dbh->prepare("SELECT picid FROM userpic WHERE userid=$userid AND md5base64=$qbase64");
+         $sth->execute;
+         my ($picid) = $sth->fetchrow_array;  # undef if no result rows
+         my $is_duplicate = defined $picid;
+ 
+         # if it's not a duplicate, insert it
+         unless ($is_duplicate) {
+             my $qimagedata   = $dbh->quote($img);
+             my $qcontenttype = $dbh->quote("image/" . lc $filetype);
+ 
+             # first insert the metadata into userpic
+             $sth = $dbh->prepare("INSERT INTO userpic (userid, contenttype, width, height, picdate, md5base64) VALUES ($userid, $qcontenttype, $width, $height, NOW(), $qbase64)");
+             $sth->execute;
+             not $dbh->err
+               or return &$dbfail;
+             $picid = $sth->{mysql_insertid};
+             
+             # then insert the image data into userpicblob
+             $dbh->do("INSERT INTO userpicblob (picid, imagedata) VALUES ($picid, $qimagedata)")
+               or return &$dbfail;
+         }
+ 
+         # set keywords, overwriting existing kw-pic mappings if necessary.
+         if (exists $req->{keywords}) {
+             my @keywords = split /,/, $req->{keywords};
+             foreach my $kw (@keywords) {
+                 trim($kw);
+                 my $kwid = LJ::get_keyword_id($dbh, $kw))
+                   or return &$dbfail;
+                 $dbh->do("DELETE FROM userpicmap WHERE picid=$picid AND kwid=$kwid")
+                   or return &$dbfail;
+                 $dbh->do("INSERT INTO userpicmap (userid, kwid, picid) VALUES ($userid, $kwid, $picid)")
+                   or return &$dbfail;
+             }
+         }
+ 
+         # set this picture as default if requested.
+         if (exists $req->{default} and $req->{default}) {
+             $dbh->do("UPDATE user SET defaultpicid=$picid WHERE user=$quser")
+               or return &$dbfail;
+         }
+ 
+         return $success->(picid  => $picid,
+                           width  => $width,
+                           height => $height);
+     }
+             
  
      ### unknown mode!
      $res->{'success'} = "FAIL";
      $res->{'errmsg'} = "Client error: Unknown mode ($req->{'mode'})";
      return;
  }
+ 
  
  1;
