sunnyman's (sunnyman) wrote in changelog,
sunnyman's
sunnyman
changelog

[fotobilder] r1456: LJSUP-10497: Security mapping supported,...

Committer: vtroitsky
LJSUP-10497: Security mapping supported, video formats eliminated, UploadTempFile/UploadPrepare/UploadPic/GetGalsTree/Login supported
U   trunk/lib/FB/Protocol/Fotki/CreateGals.pm
U   trunk/lib/FB/Protocol/Fotki/GetGals.pm
U   trunk/lib/FB/Protocol/Fotki/GetGalsTree.pm
U   trunk/lib/FB/Protocol/Fotki/GetPics.pm
U   trunk/lib/FB/Protocol/Fotki/Login.pm
U   trunk/lib/FB/Protocol/Fotki/UploadPic.pm
A   trunk/lib/FB/Protocol/Fotki/UploadPrepare.pm
A   trunk/lib/FB/Protocol/Fotki/UploadTempFile.pm
A   trunk/lib/FB/Protocol/Fotki.pm
U   trunk/lib/FB/Protocol/Response.pm
Modified: trunk/lib/FB/Protocol/Fotki/CreateGals.pm
===================================================================
--- trunk/lib/FB/Protocol/Fotki/CreateGals.pm	2011-11-28 15:35:57 UTC (rev 1455)
+++ trunk/lib/FB/Protocol/Fotki/CreateGals.pm	2011-11-30 18:37:38 UTC (rev 1456)
@@ -2,6 +2,8 @@
 
 package FB::Protocol::Fotki::CreateGals;
 
+use FB::Protocol::Fotki;
+
 use strict;
 
 use LJ::Fotki::Album;
@@ -47,11 +49,18 @@
         return $err->(211 => "Malformed gallery name: $galname")
             unless FB::valid_gallery_name($galname);
 
-#        warn "Creating gallery...";
+        # check that GalSec was valid, if it was specified
+        my $galsec = exists $gvar->{GalSec} ? $gvar->{GalSec} : 255;
+        return $err->(211 => "Invalid GalSec value")
+            unless defined $galsec && FB::valid_security_value($u, \$galsec);
 
-        my $album = LJ::Fotki::Album->create(userid => $lj_userid, album_title => $galname, album_desc => '');
+        my ($security, $allowmask) = FB::Protocol::Fotki->fb2lj_security($galsec);
 
-#        warn "AID:".$album->album_id;
+        my $album;
+        eval {
+            $album = LJ::Fotki::Album->create(userid => $lj_userid, album_title => $galname, album_desc => '', security => $security, allowmask => $allowmask);
+        };
+        return $err->(512 => 'Error creation LJ Fotki album' ) if $@;
 
         return $err->(512 => 'Error creation LJ Fotki album' ) unless($album);
 
@@ -67,199 +76,4 @@
     return 1;
 }
 
-
-# FIXME: perhaps add support for adding multiple 
-#        parents/children by ParentID and/or Path?
-
-sub old_handler {
-    my $resp = shift or return undef;
-    my $req  = $resp->{req};
-    my $vars = $req->{vars}->{CreateGals};
-    my $u = $resp->{u};
-
-    my $ret = { Gallery => [] };
-
-    my $err = sub {
-        $resp->add_method_error(CreateGals => @_);
-        return undef;
-    };
-
-    return $err->(212 => 'Gallery')
-        unless defined $vars->{Gallery};
-
-    return $err->(211 => 'CreateGals')
-        unless ref $vars->{Gallery} eq 'ARRAY' && @{$vars->{Gallery}};
-
-    # to which galleries should this picture be added?
-    my @gals;
-  GALLERY:
-    foreach my $gvar (@{$vars->{Gallery}}) {
-
-        # FIXME: make sure that gallery doesn't already exist,
-        #        case is different from uploadpic
-
-        # existence of GalName is required
-        return $err->(212 => 'GalName')
-            unless exists $gvar->{GalName};
-
-        # exists but not defined?
-        my $galname = $gvar->{GalName};
-        return $err->(211 => 'GalName')
-            unless defined $galname;
-
-        # defined but not valid?
-        return $err->(211 => "Malformed gallery name: $galname")
-            unless FB::valid_gallery_name($galname);
-
-        # check for invalid argument interactions
-        return $err->(211 => "Can't specify both ParentID and Path when adding to gallery")
-            if exists $gvar->{ParentID} && exists $gvar->{Path};
-
-        # check that GalSec was valid, if it was specified
-        my $galsec = exists $gvar->{GalSec} ? $gvar->{GalSec} : 255;
-        return $err->(211 => "Invalid GalSec value")
-            unless defined $galsec && FB::valid_security_value($u, \$galsec);
-
-        # check against existence of undefined values:
-        foreach (qw(ParentID GalDate)) {
-            return $err->(211 => $_) 
-                if exists $gvar->{$_} && ! defined $gvar->{$_};
-        }
-
-        # check that ParentID was valid, if it was specified
-        my $parentid = exists $gvar->{ParentID} ? $gvar->{ParentID} : 0;
-        return $err->(211 => "ParentID must be a non-negative integer")
-             if ! defined $parentid || $parentid =~ /\D/ || $parentid < 0;
-
-        # check gallery names in Path
-        my @path = @{$gvar->{Path}||[]};
-        foreach (@path) {
-            next if defined $_ && FB::valid_gallery_name($_);
-            return $err->(211 => [ "Malformed gallery name in Path" => $_ ]);
-        }
-
-        # if no path was specified, and the parentid is 0 only because
-        # it defaulted to that, then the gallery we create will be 
-        # top-level
-        my $top_level = ! @path && $parentid == 0 ? 1 : 0;
-
-        # check that GalDate was valid, if it was specified
-        my $galdate = FB::date_from_user($gvar->{GalDate});
-        return $err->(211 => "Malformed date: $galdate")
-            if exists $gvar->{GalDate} && ! defined $galdate;
-        
-        # goal from here on is to find what gals this 'Gallery' struct refers to, 
-        # we'll create those galleries as needed
-        
-        my $udbh = FB::get_user_db_writer($u)
-            or return $err->(501 => "Cluster $u->{clusterid}");
-
-        # if a GalName was specified in conjunction with a path, it is a 
-        # special case and means that we should attempt to create galleries
-        # down the path, starting at the root, then create a new gallery 
-        # (if it doesn't exist) of the given GalName at the end of the path
-        if (@path) {
-
-            # add GalName to the end of the path since it will be the final
-            # destination gallery and follows the same rules for creation as
-            # the rest of the path.
-            push @path, $galname;
-
-            # for error reporting if necessary later
-            my $pathstr = join(" / ", @path);
-
-            my $pid = 0;
-          PATH:
-            while (@path) {
-                my $currname = shift @path;
-
-                # FIXME: pretty sure this could be further optimized
-
-                # see if the parent of the path thus far exists
-                my $gal = $udbh->selectrow_hashref
-                    ("SELECT g.* FROM gallery g, galleryrel gr ".
-                     "WHERE g.userid=? AND g.name=? AND gr.userid=g.userid ".
-                     "AND gr.gallid2=g.gallid AND gr.gallid=? AND gr.type='C' ".
-                     "ORDER BY gr.sortorder LIMIT 1",
-                     undef, $u->{userid}, $currname, $pid);
-                return $err->(502) if $udbh->err;
-
-                # if we've reached the end of the path and the gallery being
-                # referenced already exists, then error.
-                return $err->(211 => "Gallery already exists: $pathstr")
-                    if @path == 0 && $gal;
-
-                # gal didn't exist, create and set that as parent
-                unless ($gal) {
-                    $gal = FB::create_gallery
-                        ($u, $currname, $galsec, $pid, 
-                         @path == 0 ? { dategal => $galdate } : {})
-                        or return $err->(512 => FB::last_error());
-
-                    if (@path == 0) {
-                        push @{$ret->{Gallery}}, { GalID   => [ $gal->{gallid} ],
-                                                   GalName => [ $galname ],
-                                                   GalURL  => [ FB::url_gallery($u, $gal) ] };
-                    }
-                }
-
-                # parent is either the gallery we just looked up or the
-                # one we just created
-                $pid = $gal->{gallid};
-
-                next PATH;
-            }
-
-            # move on to the next gallery record
-            next GALLERY;
-        }
-
-        # if a name was specified with a ParentID, then create a gallery
-        # named GalName that is also a child of $parentid.  it is possible
-        # that the parentid was set to 0 because no parentid was specified, 
-        # meaning that the gallery should be created top-level
-        if (defined $parentid && $parentid > 0 || $top_level) {
-
-            # does the specified parent gallery even exist?
-            my $pgal = undef;
-            unless ($top_level) {
-                $pgal = FB::load_gallery_id($u, $parentid)
-                    or return $err->(211 => "Parent gallery does not exist: $parentid");
-            }
-
-            my $rows = $udbh->selectrow_array
-                ("SELECT COUNT(*) FROM gallery g, galleryrel gr ".
-                 "WHERE g.userid=? AND g.name=? AND gr.userid=g.userid ".
-                 "AND gr.gallid2=g.gallid AND gr.gallid=? AND gr.type='C'",
-                 undef, $u->{userid}, $galname, $parentid);
-            return $err->(502) if $udbh->err;
-
-            # gallery already existed?
-            if ($rows) {
-                my @galpath = ($galname);
-                unshift @galpath, $pgal->{name} if $pgal;
-                return $err->(512 => "Gallery aready exists: " . join('/', @galpath));
-            }
-                
-            # create a new gallery
-            my $gal = FB::create_gallery
-                ($u, $galname, $galsec, $parentid, { dategal => $galdate })
-                or return $err->(512 => FB::last_error());
-
-            push @{$ret->{Gallery}}, { GalID   => [ $gal->{gallid} ],
-                                       GalName => [ $galname ],
-                                       GalURL  => [ FB::url_gallery($u, $gal) ] };
-
-
-            next GALLERY;
-        }
-
-        next GALLERY;
-    }
-
-    # register return value with parent Request
-    $resp->add_method_vars(CreateGals => $ret);
-
-    return 1;
-}
 1;

Modified: trunk/lib/FB/Protocol/Fotki/GetGals.pm
===================================================================
--- trunk/lib/FB/Protocol/Fotki/GetGals.pm	2011-11-28 15:35:57 UTC (rev 1455)
+++ trunk/lib/FB/Protocol/Fotki/GetGals.pm	2011-11-30 18:37:38 UTC (rev 1456)
@@ -2,6 +2,8 @@
 
 package FB::Protocol::Fotki::GetGals;
 
+use FB::Protocol::Fotki;
+
 use strict;
 use LJ::Fotki::Album;
 
@@ -18,7 +20,6 @@
     my $lj_userid = FB::get_domain_userid($u);
     my $lj_user = LJ::load_userid($lj_userid);
 
-#    warn "userid: ".$u->userid." -> ljuserid: $lj_userid # $lj_user" ;
     # TODO: eval to catch all errors
     my $albums = LJ::Fotki::Album->get_albums($lj_userid, $lj_user);
 
@@ -29,14 +30,14 @@
             next unless($album);
             my $album_ret = {
                                 id      => $album->album_id,
-                                Name    => [ $album->title ],
-                                Sec     => [ 255 ],                             # default security: public
-                            #    Date    => [ $album->createtime ],             # gallery creation date in 2004-01-01 01:01:01 format
-                            #    TimeUpdate  => [ $album->updatetime ],         # update timestamp
+                                Name    => [ FB::transform_gal_name($album->title) ],
+                                Sec     => [ FB::Protocol::Fotki->lj2fb_security($album->get_security, $album->get_mask) ],
+                                Date    => [ FB::date_unix_to_mysql($album->timecreate) ],         
+                                ($album->timeupdate ?  (TimeUpdate => [ $album->timeupdate ]) : ()),
                                 URL     => [ $album->url ],
                             };
             # is this the incoming gallery?
-#            $gal_ret->{incoming} = 1 if $album->is_unsorted;
+            $album_ret->{incoming} = 1 if $album->is_default;
 
             # GalMembers
             my $photos = $album->get_all_photos($lj_user);
@@ -58,66 +59,4 @@
     return 1;
 }
 
-sub handler_old {
-    my $resp = shift or return undef;
-    my $req  = $resp->{req};
-    my $vars = $req->{vars};
-    my $u = $resp->{u};
-
-    my $err = sub {
-        $resp->add_method_error(GetGals => @_);
-        return undef;
-    };
-
-    my $gals = FB::gals_of_user($u);
-    return $err->(500) unless ref $gals;
-
-    my $ret = { Gal => [] };
-
-    if (%$gals) {
-
-        # load gallery rels and pic rels for use later
-        my @gal_rel = FB::user_galleryrel($u);
-        my @pic_rel = FB::user_gallerypics($u);
-
-        while (my ($gallid, $gal) = each %$gals) {
-            my $gal_ret = { id         => $gallid,
-                            Name       => [ FB::transform_gal_name($gal->{name}) ],
-                            Sec        => [ $gal->{secid} ],
-                            Date       => [ $gal->{dategal} ],
-                            TimeUpdate => [ $gal->{timeupdate} ],
-                            URL        => [ FB::url_gallery($u, $gal) ],
-                        };
-
-            # is this the incoming gallery?
-            $gal_ret->{incoming} = 1 if FB::gal_is_unsorted($gal);
-
-            # GalMembers
-            $gal_ret->{GalMembers}->{GalMember} = 
-                [ map { { id => $_->{upicid} } }
-                  grep { $_->{gallid} == $gallid }
-                  @pic_rel ];
-
-            # ParentGals
-            $gal_ret->{ParentGals}->{ParentGal} = 
-                [ map { { id => $_->{gallid}, sortorder => $_->{sortorder} } }
-                  grep { $_->{gallid2} == $gallid && $_->{type} eq 'C' }
-                  @gal_rel ];
-
-            # ChildGals
-            $gal_ret->{ChildGals}->{ChildGal} = 
-                [ map { { id => $_->{gallid2}, sortorder => $_->{sortorder} } }
-                  grep { $_->{gallid} == $gallid && $_->{type} eq 'C' }
-                  @gal_rel ];
-
-            push @{$ret->{Gal}}, $gal_ret;
-        }
-    }
-
-    # register return value with parent Request
-    $resp->add_method_vars(GetGals => $ret);
-
-    return 1;
-}
-
 1;

Modified: trunk/lib/FB/Protocol/Fotki/GetGalsTree.pm
===================================================================
--- trunk/lib/FB/Protocol/Fotki/GetGalsTree.pm	2011-11-28 15:35:57 UTC (rev 1455)
+++ trunk/lib/FB/Protocol/Fotki/GetGalsTree.pm	2011-11-30 18:37:38 UTC (rev 1456)
@@ -2,6 +2,7 @@
 
 package FB::Protocol::Fotki::GetGalsTree;
 
+use FB::Protocol::Fotki;
 use strict;
 use LJ::Fotki::Album;
 
@@ -34,13 +35,13 @@
             my $album_ret = {
                                 id      => $album->album_id,
                                 Name    => [ $album->title ],
-                                Sec     => [ 255 ],                             # default security: public
-                            #    Date    => [ $album->createtime ],             # gallery creation date in 2004-01-01 01:01:01 format
-                            #    TimeUpdate  => [ $album->updatetime ],         # update timestamp
+                                Sec     => [ FB::Protocol::Fotki->lj2fb_security($album->get_security, $album->get_mask) ],
+                                Date    => [ FB::date_unix_to_mysql($album->timecreate) ],             # gallery creation date in 2004-01-01 01:01:01 format
+                                ($album->timeupdate ? (TimeUpdate => [ $album->timeupdate ]) : ()),         # update timestamp
                                 URL     => [ $album->url ],
                             };
             # is this the incoming gallery?
-#            $gal_ret->{incoming} = 1 if $album->is_unsorted;
+            $album_ret->{incoming} = 1 if $album->is_default;
 
             # GalMembers
             my $photos = $album->get_all_photos($lj_user);
@@ -58,108 +59,6 @@
     $resp->add_method_vars(GetGalsTree => $ret);
 
     return 1;
-
-
 }
 
-sub handler_old {
-    my $resp = shift or return undef;
-    my $req  = $resp->{req};
-    my $vars = $req->{vars};
-    my $u = $resp->{u};
-
-    my $err = sub {
-        $resp->add_method_error(GetGalsTree => @_);
-        return undef;
-    };
-
-    my $gals = FB::gals_of_user($u);
-    return $err->(500) unless ref $gals;
-
-    my $ret = {
-        RootGals        => [ { Gal => [ ] } ],
-        UnreachableGals => [ { Gal => [ ] } ],
-    };
-
-    if (%$gals) {
-
-        # load gallery rels and pic rels for use later
-        my @gal_rel = FB::user_galleryrel($u);
-        my @pic_rel = FB::user_gallerypics($u);
-
-        # build a data structure of parent gallids => array of their children
-        my %parents  = ();
-        my %children = ();
-        foreach (grep { $_->{type} eq 'C' } @gal_rel) {
-            my ($pid, $cid) = ($_->{gallid}, $_->{gallid2});
-            push @{$children{$pid}}, $gals->{$cid};
-            push @{$parents{$cid}}, $gals->{$pid};
-            $gals->{$cid}->{sortorder} = $_->{sortorder};
-        }
-
-        # resets every visit to top-level (0)
-        my %seen = ();
-        my %unreachable = map { $_ => 1 } keys %$gals;
-
-        my $recurse;
-        $recurse = sub {
-            my $gal = shift;
-            my $gallid = $gal->{gallid};
-
-            # since we've visited this gallery, it's not unreachable
-            delete $unreachable{$gallid};
-
-            my $node = { id         => $gallid,
-                         sortorder  => $gal->{sortorder}+0,
-                         Name       => [ FB::transform_gal_name($gal->{name}) ],
-                         Sec        => [ $gal->{secid} ],
-                         Date       => [ $gal->{dategal} ],
-                         TimeUpdate => [ $gal->{timeupdate} ],
-                         URL        => [ FB::url_gallery($u, $gal) ],
-                     };
-
-            # is this the incoming gallery?
-            $node->{incoming} = 1 if FB::gal_is_unsorted($gal);
-
-            # GalMembers
-            $node->{GalMembers}->{GalMember} = 
-                [ map { { id => $_->{upicid} } }
-                  grep { $_->{gallid} == $gallid }
-                  @pic_rel ];
-
-            # now the hard part: ChildGals
-            $node->{ChildGals}->{Gal} = 
-                [ map  { $recurse->($_) } 
-                  sort { $a->{sortorder} <=> $b->{sortorder} || $a->{gallid} <=> $b->{gallid} }
-                  grep { ! $seen{$_->{gallid}}++ } 
-                  @{$children{$gallid}} ];
-
-            return $node;
-        };
-
-        # start at parent (top-level) node and built tree
-        # of all its children
-        foreach my $child (@{$children{0}}) {
-            %seen = ( $child->{gallid} => 1 );
-            push @{$ret->{RootGals}->[0]->{Gal}}, $recurse->($child);
-        }
-
-        # represent any galleries that were unreachable, recursing down
-        # from each gallery that has no parents
-        foreach my $gal (map  { $gals->{$_} }
-                         sort { $gals->{$a}->{sortorder} <=> $gals->{$b}->{sortorder} ||
-                                $gals->{$a}->{gallid} <=> $gals->{$b}->{gallid} }
-                         keys %unreachable) {
-
-            %seen = ( $gal->{gallid} => 1 );
-            push @{$ret->{UnreachableGals}->[0]->{Gal}}, $recurse->($gal);
-        }
-    }
-
-    # register return value with parent Request
-    $resp->add_method_vars(GetGalsTree => $ret);
-
-    return 1;
-}
-
 1;

Modified: trunk/lib/FB/Protocol/Fotki/GetPics.pm
===================================================================
--- trunk/lib/FB/Protocol/Fotki/GetPics.pm	2011-11-28 15:35:57 UTC (rev 1455)
+++ trunk/lib/FB/Protocol/Fotki/GetPics.pm	2011-11-30 18:37:38 UTC (rev 1456)
@@ -2,6 +2,8 @@
 
 package FB::Protocol::Fotki::GetPics;
 
+use FB::Protocol::Fotki;
+
 use strict;
 use LJ::Fotki::Photo;
 
@@ -30,10 +32,10 @@
 
             push @{$ret->{Pic}}, {
                 id         => $photo->photo_id,
-                Sec        => [ $photo->get_security ],   # TODO: convert mask!!!
-#                Width      => [ $pic->{width} ],       # TODO: necessary to support original photo sizes
-#                Height     => [ $pic->{height} ],
-#                Bytes      => [ $pic->{bytes} ],       # TODO: original photo size
+                Sec        => [ FB::Protocol::Fotki->lj2fb_security($photo->get_security, $photo->get_mask) ],   # TODO: convert mask to FB format
+                Width      => [ $photo->orig_width ],
+                Height     => [ $pic->orig_height ],
+                Bytes      => [ $pic->orig_size ],
 #                Format     => [ FB::fmtid_to_mime($pic->{fmtid}) ],    # TODO: Format of the original photo
 #                MD5        => [ FB::bin_to_hex($gpic_md5->{$pic->{gpicid}}) ],
                 URL        => [ $photo->orig_url  ],
@@ -55,57 +57,4 @@
     return 1;
 }
 
-
-sub handler_old {
-    my $resp = shift or return undef;
-    my $req  = $resp->{req};
-    my $vars = $req->{vars};
-    my $u = $resp->{u};
-
-    my $err = sub {
-        $resp->add_method_error(GetPics => @_);
-        return undef;
-    };
-
-    my $ret = { Pic => [] };
-    my $upics = FB::upics_of_user($u, { props => [ qw(filename pictitle) ] });
-    return $err->(500 => FB::last_error) unless ref $upics eq 'HASH';
-
-    if (%$upics) {
-
-        # get md5s of all the gpics
-        my $gpic_md5      = FB::get_gpic_md5_multi([ map { $_->{gpicid} } values %$upics ]);
-        return $err->(500 => FB::last_error()) unless ref $gpic_md5 eq 'HASH';
-
-        my @pics_with_des = FB::get_des_multi($u, 'P', [ values %$upics ]);
-        return $err->(500 => FB::last_error()) unless ref $pics_with_des[0] eq 'HASH';
-
-        foreach my $pic (sort { $a->{upicid} <=> $b->{upicid} } @pics_with_des) {
-
-            push @{$ret->{Pic}}, {
-                id         => $pic->{upicid},
-                Sec        => [ $pic->{secid} ],
-                Width      => [ $pic->{width} ],
-                Height     => [ $pic->{height} ],
-                Bytes      => [ $pic->{bytes} ],
-                Format     => [ FB::fmtid_to_mime($pic->{fmtid}) ],
-                MD5        => [ FB::bin_to_hex($gpic_md5->{$pic->{gpicid}}) ],
-                URL        => [ FB::url_picture($u, $pic) ],
-                Meta       => [ map { 
-                                     { name    => $_->[0], 
-                                       content => $pic->{$_->[1]} }
-                                    } (['filename'    => 'filename' ],
-                                       ['title'       => 'pictitle' ],
-                                       ['description' => 'des'      ])
-                              ],
-            };
-        }
-    }
-
-    # register return value with parent Request
-    $resp->add_method_vars(GetPics => $ret);
-
-    return 1;
-}
-
 1;

Modified: trunk/lib/FB/Protocol/Fotki/Login.pm
===================================================================
--- trunk/lib/FB/Protocol/Fotki/Login.pm	2011-11-28 15:35:57 UTC (rev 1455)
+++ trunk/lib/FB/Protocol/Fotki/Login.pm	2011-11-30 18:37:38 UTC (rev 1456)
@@ -3,6 +3,7 @@
 package FB::Protocol::Fotki::Login;
 
 use strict;
+
 use LJ::Fotki::UserSpace;
 
 sub handler {
@@ -49,45 +50,4 @@
     return 1;
 }
 
-sub handler_old {
-    my $resp = shift or return undef;
-    my $req  = $resp->{req};
-    my $vars = $req->{vars}->{Login};
-    my $u    = $resp->{u};
-
-    my $err = sub {
-        $resp->add_method_error(Login => @_);
-        return undef;
-    };
-
-    my $ret = { ServerTime => [ FB::date_unix_to_mysql() ]};
-
-    # store client version in $r->notes so we can log it optionally
-    # to keep stats
-    if (defined $vars->{ClientVersion}) {
-        LJ::Request->notes(ProtocolClientVersion => $vars->{ClientVersion});
-    }
-
-    # look up quota and usage information to return with this request
-    if (FB::are_hooks('disk_usage_info')) {
-
-        my $qinf = FB::run_hook('disk_usage_info', $u);
-        if (ref $qinf eq 'HASH') {
-            $ret->{Quota} = {
-                Total     => [ $qinf->{quota} * (1 << 10) ], # kb -> bytes
-                Used      => [ $qinf->{used}  * (1 << 10) ],
-                Remaining => [ $qinf->{free}  * (1 << 10) ],
-            };
-        }
-    }
-
-    # are there any current system messages applying to this user?
-    $ret->{Message} = [ FB::get_system_message($u) . '' ];
-
-    # register return value with parent Request
-    $resp->add_method_vars( Login => $ret );
-
-    return 1;
-}
-
 1;

Modified: trunk/lib/FB/Protocol/Fotki/UploadPic.pm
===================================================================
--- trunk/lib/FB/Protocol/Fotki/UploadPic.pm	2011-11-28 15:35:57 UTC (rev 1455)
+++ trunk/lib/FB/Protocol/Fotki/UploadPic.pm	2011-11-30 18:37:38 UTC (rev 1456)
@@ -2,6 +2,8 @@
 
 package FB::Protocol::Fotki::UploadPic;
 
+use FB::Protocol::Fotki;
+
 use strict;
 use LJ::Fotki;
 use LJ::Fotki::Album;
@@ -36,135 +38,9 @@
     return $err->(201 => "Cannot specify both ImageLength and Receipt")
         if exists $vars->{ImageLength} && exists $vars->{Receipt};
 
-    my $gpic;
+#    my $photo;
     my ($fmtid, $length, $md5_hex);
 
-    # did they specify an ImageData variable?
-    return $err->(212 => "ImageData")
-         unless $img && ref $img eq 'HASH';
-
-    return $err->(212 => "ImageLength")
-         unless exists $vars->{ImageLength};
-
-    $length = $vars->{ImageLength};
-
-    return $err->(211 => "ImageLength")
-         unless defined $length;
-
-    # did we count bytes?
-    return $err->(213 => "No data sent")
-         unless $img->{bytes};
-
-    # did they match the declared length?
-    return $err->(211 => "ImageLength does not match data length")
-         unless $img->{bytes} == $length;
-
-    # check that it's a valid fmtid
-    $fmtid = $img->{fmtid};
-    return $err->(213 => "Unknown format")
-         unless $fmtid;
-
-    # valid filehandle -- not applicable to $img from receipt
-    return $err->(500 => "No spool filehandle")
-         unless  $img->{spool_fh};
-
-    # valid md5 sum?
-    return $err->(500 => "Could not calculate MD5 sum")
-         unless $img->{md5sum};
-
-    # if an md5 is supplied, check that it matches the image's actual
-    # calculated md5
-    $md5_hex = FB::bin_to_hex($img->{md5sum});
-    if ($vars->{MD5} && $vars->{MD5} ne $md5_hex) {
-         return $err->(211 => "Supplied MD5 does not match data MD5");
-    }
-
-    # check PicSec if specified
-
-    # TODO: Support
-    my $picsec = exists $vars->{PicSec} ? $vars->{PicSec} : 255;
-    return $err->(211 => "PicSec")
-        unless defined $picsec && FB::valid_security_value($u, $picsec);
-
-    # Meta information
-    if (exists $vars->{Meta}) {
-        my $meta = $vars->{Meta};
-        return $err->(211 => "Meta")
-            unless ref $meta eq 'HASH';
-
-        foreach (qw(Filename Title Description)) {
-            next unless exists $meta->{$_};
-            return $err->(211 => "Meta-$_")
-                unless defined $meta->{$_};
-
-            # Description is a BLOB (2^16-1 bytes)
-            my $maxlen = $_ eq 'Description' ? 65535 : 255;
-            return $err->(211 => [ "Meta-$_" => "Too long, maximum length is $maxlen" ])
-                if length($meta->{$_}) > $maxlen;
-        }
-    }
-
-    # call hook to check if user has disk space for picture before uploading
-    my $spaces = LJ::Fotki::UserSpace->get_spaces($lj_user);
-    return $err->(401) if $spaces->[3] <= 0;
-    return $err->(402) if $spaces->[3] < $length;
-
-
-    # TODO: process Galleries: add uploaded photo into specified galleries (albums)
-
-
-
-
-    # use default upload album
-    my $album = LJ::Fotki::Album->get_default_album($lj_user);
-
-    # upload photo to fotki and create
-
-    my $content = '';
-    seek $img->{spool_fh}, 0,0;
-    read $img->{spool_fh}, $content, $length;
-
-    my $photo = LJ::Fotki::Photo->create(userid => $lj_userid, album_id => $album->album_id, photo_data => $content);
-
-    # register return value with parent Request
-    $resp->add_method_vars(
-                            UploadPic => {
-                                PicID  => [ $photo->photo_id ],
-                                URL    => [ $photo->orig_url ],
-                                Width  => [ $up->width ],
-                                Height => [ $up->height ],
-                                Bytes  => [ $length ],
-                            });
-
-    return 1;
-}
-
-sub handler_old {
-    my $resp = shift or return undef;
-    my $req  = $resp->{req};
-    my $vars = $req->{vars}->{UploadPic};
-
-    my $u = $resp->{u};
-
-    my $err = sub {
-        $resp->add_method_error(UploadPic => @_);
-        return undef;
-    };
-
-    # is the user allowed to upload?
-    return $err->(303)
-        unless FB::get_cap($u, 'can_upload') && $u->{statusvis} eq 'V';
-
-    # specifying two data sources makes no sense, error
-    my $img = $vars->{ImageData};
-    return $err->(201 => "Cannot specify both ImageData and Receipt")
-        if $img && exists $vars->{Receipt};
-    return $err->(201 => "Cannot specify both ImageLength and Receipt")
-        if exists $vars->{ImageLength} && exists $vars->{Receipt};
-
-    my $gpic;
-    my ($fmtid, $length, $md5_hex);
-
     # are they supplying a receipt for their upload data?
     if (exists $vars->{Receipt}) {
         return $err->(211 => 'Receipt')
@@ -183,19 +59,19 @@
         return $err->(211 => [ 'Receipt' => "Expired" ])
             unless $rcpt->{timecreate} > time() - $rcpt_exp->{$rcpt->{type}};
 
-        # UploadPrepare receipt
-        if ($rcpt->{type} eq 'P') {
+        # UploadPrepare receipt: there no such type at all at the moment
+#        if ($rcpt->{type} eq 'P') { 
+#
+#            eval { $gpic = FB::Gpic->load($rcpt->{val}) };
+#            return $err->(500 => $@) if $@;
+#
+#            # still have no gpic from receipt?
+#            return $err->(211 => 'Receipt')
+#                unless $gpic;
+        # UploadTempFile receipt 
+#       }        
+        if ($rcpt->{type} eq 'T') {
 
-            eval { $gpic = FB::Gpic->load($rcpt->{val}) };
-            return $err->(500 => $@) if $@;
-
-            # still have no gpic from receipt?
-            return $err->(211 => 'Receipt')
-                unless $gpic;
-
-        # UploadTempFile receipt
-        } elsif ($rcpt->{type} eq 'T') {
-
             my $inf = $rcpt->{val_hash};
             return $err->(211 => 'Receipt')
                 unless ref $inf eq 'HASH';
@@ -231,13 +107,11 @@
             }
         }
     }
-
     # so now we know that no receipt was specified, else we'd have a $gpic or error by now
     # error check data submission so we can attempt to create a new gpic later after the
     # rest of the request is error checked
+ #   unless ($photo) {
 
-    unless ($gpic) {
-
         # did they specify an ImageData variable?
         return $err->(212 => "ImageData")
             unless $img && ref $img eq 'HASH';
@@ -259,10 +133,6 @@
         return $err->(211 => "ImageLength")
             unless defined $length;
 
-        # valid pclustertype / pclusterid
-        return $err->(500 => "Could not determine pclustertype/id")
-            unless $img->{pclustertype} && $img->{pclusterid};
-
         # did we count bytes?
         return $err->(213 => "No data sent")
             unless $img->{bytes};
@@ -276,9 +146,12 @@
         return $err->(213 => "Unknown format")
             unless $fmtid;
 
+        return $err->(213 => "Format doesn't supported")
+            unless FB::Protocol::Fotki->accepted_fmtid($fmtid);
+
         # valid filehandle -- not applicable to $img from receipt
         return $err->(500 => "No spool filehandle")
-            unless $img->{_from_rcpt} || $img->{spool_fh};
+            unless  $img->{spool_fh};
 
         # valid md5 sum?
         return $err->(500 => "Could not calculate MD5 sum")
@@ -290,20 +163,22 @@
         if ($vars->{MD5} && $vars->{MD5} ne $md5_hex) {
             return $err->(211 => "Supplied MD5 does not match data MD5");
         }
-    }
-
+ #   }
     # check PicSec if specified
+    # TODO: Support security groups
     my $picsec = exists $vars->{PicSec} ? $vars->{PicSec} : 255;
     return $err->(211 => "PicSec")
-        unless defined $picsec && FB::valid_security_value($u, $picsec);
+        unless defined $picsec && FB::valid_security_value($u, $picsec);   # TODO check it!
 
+    my ($security, $allowmask) = FB::Protocol::Fotki->fb2lj_security($picsec);
+
     # Meta information
     if (exists $vars->{Meta}) {
         my $meta = $vars->{Meta};
         return $err->(211 => "Meta")
             unless ref $meta eq 'HASH';
 
-        foreach (qw(Filename Title Description)) {
+        foreach (qw(Title Description)) {
             next unless exists $meta->{$_};
             return $err->(211 => "Meta-$_")
                 unless defined $meta->{$_};
@@ -316,386 +191,124 @@
     }
 
     # call hook to check if user has disk space for picture before uploading
-    my $Kibfree = FB::run_hook("disk_remaining", $u);
-    if (defined $Kibfree) {
-        return $err->(401) if $Kibfree <= 0;
-        return $err->(402) if $Kibfree < $length>>10;
-    }
+    my $spaces = LJ::Fotki::UserSpace->get_spaces($lj_user);
+    return $err->(401) if $spaces->[3] <= 0;
+    return $err->(402) if $spaces->[3] < $length;
 
+    # TODO: process Galleries: add uploaded photo into specified galleries (albums)
+    
+
     # to which galleries should this picture be added?
-    my @gals;
+    my @albums;
   GALLERY:
     foreach my $gvar (@{$vars->{Gallery}}) {
 
-        # check for invalid argument interactions
-        return $err->(211 => "Can't specify both GalName and GalID when adding to gallery")
-            if exists $gvar->{GalName} && exists $gvar->{GalID};
+        # TODO here
 
-        return $err->(212 => "Must specify either GalName or GalID when adding to gallery")
-            unless exists $gvar->{GalName} || exists $gvar->{GalID};
 
-        return $err->(211 => "Can't specify both ParentID and Path when adding to gallery")
-            if exists $gvar->{ParentID} && exists $gvar->{Path};
-
-        # check that GalSec was valid, if it was specified
-        my $galsec = exists $gvar->{GalSec} ? $gvar->{GalSec} : 255;
-        return $err->(211 => "Invalid GalSec value")
-            unless defined $galsec && FB::valid_security_value($u, \$galsec);
-
-        # check against existence of undefined values:
-        foreach (qw(ParentID GalDate GalName)) {
-            return $err->(211 => $_)
-                if exists $gvar->{$_} && ! defined $gvar->{$_};
-        }
-
-        # check that ParentID was valid, if it was specified
-        my $parentid = exists $gvar->{ParentID} ? $gvar->{ParentID} : 0;
-        return $err->(211 => "ParentID must be a non-negative integer")
-             if ! defined $parentid || $parentid =~ /\D/ || $parentid < 0;
-
-        # check that GalDate was valid, if it was specified
-        my $galdate = FB::date_from_user($gvar->{GalDate});
-        return $err->(211 => "Malformed date: $galdate")
-            if exists $gvar->{GalDate} && ! defined $galdate;
-
-        # check GalName, as well as any names in @path
-        my $galname = $gvar->{GalName};
-        return $err->(211 => "Malformed gallery name: $galname")
-            if defined $galname && ! FB::valid_gallery_name($galname);
-
-        # check gallery names in Path
-        my @path = @{$gvar->{Path}||[]};
-        foreach (@path) {
-            next if defined $_ && FB::valid_gallery_name($_);
-            return $err->(211 => [ "Malformed gallery name in Path" => $galname ]);
-        }
-
-        # goal from here on is to find what gals this 'Gallery' struct refers to,
-        # we'll push those to the @gals array and add the picture to each of them
-
-        # simple if they've specified a gallid
-        if (exists $gvar->{GalID}) {
-            my $gallid = $gvar->{GalID};
-            return $err->(211 => "GalID must be a positive integer")
-                unless defined $gallid && $gallid =~ /^\d+$/ && $gallid > 0;
-
-            my $gal = $u->load_gallery_id($gallid)
-                or return $err->(211 => "Gallery '$gallid' does not exist");
-
-            push @gals, $gal;
-            next GALLERY;
-        }
-
-        # more complicated if specified by name, need to check / create
-        # gallery based on GalName, Path and ParentID
-        if ($galname) {
-
-            my $udbh = FB::get_user_db_writer($u)
-                or return $err->(501 => "Cluster $u->{clusterid}");
-
-            # if a GalName was specified in conjunction with a path, it is a
-            # special case and means that we should attempt to create galleries
-            # down the path, starting at the root, then create a new gallery
-            # (if it doesn't exist) of the given GalName at the end of the path
-            if (@path) {
-
-                # add GalName to the end of the path since it will be the final
-                # destination gallery and follows the same rules for creation as
-                # the rest of the path.
-                push @path, $galname;
-
-                my $pid = 0;
-              PATH:
-                while (@path) {
-                    my $currname = shift @path;
-
-                    # FIXME: pretty sure this could be further optimized
-
-                    # see if the parent of the path thus far exists
-                    my $galrow = $u->selectrow_hashref
-                        ("SELECT g.* FROM gallery g, galleryrel gr ".
-                         "WHERE g.userid=? AND g.name=? AND gr.userid=g.userid ".
-                         "AND gr.gallid2=g.gallid AND gr.gallid=? AND gr.type='C' ".
-                         "ORDER BY gr.sortorder LIMIT 1",
-                         $u->{userid}, $currname, $pid);
-                    return $err->(502) if $u->err;
-
-                    my $gal;
-                    # gal didn't exist, create and set that as parent
-                    if ($galrow) {
-                        $gal = FB::Gallery->from_gallery_row($u, $galrow)
-                            or return $err->(512 => FB::last_error());
-                    } else {
-                        $gal = FB::Gallery->create($u, name => $currname, secid => $galsec)
-                            or return $err->(512 => FB::last_error());
-                        $gal->link_from($pid);
-                        $gal->set_date($galdate) if @path == 0 && $galdate;
-                    }
-
-                    # if we've worn the path list completely away, we've found
-                    # the target to add the picture to... it's the result of the
-                    # traversal of @path from the root, then finding/creating
-                    # GalName at the end of that traversal.
-                    if (@path == 0) {
-                        push @gals, $gal;
-                        last PATH;
-                    }
-
-                    # parent is either the gallery we just looked up or the
-                    # one we just created
-                    $pid = $gal->id;
-                    next PATH;
-                }
-
-                # move on to the next gallery record
-                next GALLERY;
-            }
-
-            # if a name was specified with a ParentID, then add to galleries
-            # named GalName that are also children of $parentid.  find those now.
-            if ($parentid) {
-
-                my $sth = $u->prepare
-                    ("SELECT g.* FROM gallery g, galleryrel gr ".
-                     "WHERE g.userid=? AND g.name=? AND gr.userid=g.userid ".
-                     "AND gr.gallid2=g.gallid AND gr.gallid=? AND gr.type='C'",
-                     $u->{userid}, $galname, $parentid);
-                $sth->execute;
-                return $err->(502) if $u->err;
-                while (my $grow = $sth->fetchrow_hashref) {
-                    my $gal = FB::Gallery->from_gallery_row($u, $grow) or die;
-                    push @gals, $gal;
-                }
-
-                # gal didn't exist, create and set that as parent
-                unless (@gals) {
-                    my $gal = FB::Gallery->create($u, name => $galname, secid => $galsec)
-                        or return $err->(512 => FB::last_error());
-                    $gal->link_from($parentid);
-                    push @gals, $gal;
-                }
-
-                next GALLERY;
-            }
-
-            # otherwise we have a GalName but no constraining parentid, so we just
-            # add to any galleries having that name
-            my $sth = $u->prepare("SELECT * FROM gallery WHERE userid=? AND name=?",
-                                  $u->{userid}, $galname);
-            $sth->execute;
-            return $err->(502) if $udbh->err;
-            while (my $grow = $sth->fetchrow_hashref) {
-                my $gal = FB::Gallery->from_gallery_row($u, $grow) or die;
-                push @gals, $gal;
-            }
-
-            # but if there were no galleries by this name, create a new one
-            # under the root
-            unless (grep { $_->{name} eq $galname } @gals) {
-                my $newgal = FB::Gallery->create($u, name => $galname, secid => $galsec)
-                    or return $err->(512 => FB::last_error());
-                $newgal->link_from(0);
-                $newgal->set_date($galdate) if $galdate;
-                push @gals, $newgal;
-            }
-
-            next GALLERY;
-        }
-
-        # end processing of Gallery array
     }
 
-    # internally, a minimum of one gallery.  use ":FB_in" which means
-    # "unsorted" or "incoming" or something equivalent in user's native language.
-    unless (@gals) {
-        my $g = $u->incoming_gallery
-            or return $err->(502 => "Cannot load incoming gallery");
-        push @gals, $g;
+    # use default upload album if no albums specified
+    unless (@albums) {
+        my $a = LJ::Fotki::Album->get_default_album($lj_user)
+            or return $err->(502 => "Cannot load default album");
+        push @albums, $a;
     }
 
     # now we're finished with all input error checking, and we know that all the
     # destination galleries exist... time to start processing the data, either from
     # ImageData or from an upload receipt (tempfile or prepare)
 
-    # already have a gpic if an existing one was specified via UploadPrepare receipt
-    unless ($gpic) {
+    my $content = '';
+    
+    # see if we have image data from a UploadTempFile receipt, if so we need to
+    # handle things a bit differently
+    if ($img->{_from_rcpt}) {
+        if ($img->{pclustertype} eq 'mogilefs') {
 
-        # need to get an existing gpic, or start making one.
+            # Get content from Mogile FS
+            my $fh = $FB::MogileFS->read_file($img->{_rcpt_pathkey})
+                or return $err->(510 => "Unable to read MogileFS temp file");
+            eval { 
+                seek $fh, 0,0;
+                read $fh, $content, $length;
+            };
+            return $err->(510 => $@) if $@;
+        } elsif ($img->{pclustertype} eq 'disk') {
+            eval { 
+                seek $img->{spool_fh}, 0,0;
+                read $img->{spool_fh}, $content, $length;
+            };
+            return $err->(510 => $@) if $@;
 
-        if ( my $gpicid = FB::find_equal_gpicid($md5_hex, $length, $fmtid, 'verify_paths') ) {
-
-            # found an existing gpic for this fingerprint
-            $gpic = FB::Gpic->load($gpicid)
-                or return $err->(500);
-
-            # note that we could have TempFiles to clean up at this point,
-            # in the case that the fingerprint above was that of a receipt
-            # tempfile.  in any case, it will be cleaned up later.
-
+        } else {
+            return $err->(510 => [ "Unknown pclustertype" => $img->{pclustertype} ]);
         }
 
-        # still no gpic?  time to create anew
-        unless ($gpic) {
-
-            # create a new gpic from $img hashref (defined and validated above)
-            $gpic = FB::Gpic->new
-                ( map { $_ => $img->{$_} } qw(pclustertype pclusterid md5sum fmtid bytes) )
-                or return $err->(510 => $@);
-
-            # errors from now until $gpic->save require the gpic to be discarded
-            my $err_discard = sub {
-                my $errcode = shift;
-                my @errmsg = @_;
-
-                # $gpic->discard will croak on err, catch it
-                eval { $gpic->discard };
-                push @errmsg, $@ if $@;
-
-                return @errmsg ? $err->($errcode => \@errmsg) : $err->($errcode);
-            };
-
-
-            # swap in the spoolfile
-
-            # see if we have image data from a UploadTempFile receipt, if so we need to
-            # handle things a bit differently
-            if ($img->{_from_rcpt}) {
-
-                if ($img->{pclustertype} eq 'mogilefs') {
-
-                    # rename the old TempFile MogileFS key for this to
-                    # be a permanent one of the mogfs_key form
-                    $FB::MogileFS->rename($img->{_rcpt_pathkey}, FB::Gpic::mogfs_key($gpic->{gpicid}))
-                        or return $err_discard->(510 => "Unable to rename MogileFS temp file");
-
-                } elsif ($img->{pclustertype} eq 'disk') {
-
-                    # swap in (hard link) pathkey to the final gpic disk path via API
-                    eval { $gpic->file_from_spool($img->{spool_fh}, $img->{_rcpt_pathkey}) };
-                    return $err_discard->(510 => $@) if $@;
-
-                } else {
-                    return $err_discard->(510 => [ "Unknown pclustertype" => $img->{pclustertype} ]);
-                }
-
             # otherwise we're working on a spool filehandle for data uploaded in
             # this request and collected in Request.pm
-            } else {
+    } else {
+        eval { 
+            seek $img->{spool_fh}, 0,0;
+            read $img->{spool_fh}, $content, $length;
+        };
+        return $err->(510 => $@) if $@;
+    }
 
-                # swap in (hard link) pathkey to the final gpic disk path via API
-                eval { $gpic->file_from_spool($img->{spool_fh}, $img->{spool_path}) };
-                return $err_discard->(510 => $@) if $@;
-            }
-
-            # save gpic in database
-            # 1) in case of all disk uploads, this only saves gpic row
-            # 2) in case of mogilefs uploads not via receipt, this gives
-            #    them a key and makes them permanent
-            # 3) in case of mogilefs uploads via receipt, this only saves
-            #    gpic row since mogilefs file already has a key (was renamed above)
-            eval { $gpic->save('remote' => $u) };
-            return $err_discard->(510 => $@) if $@;
-        }
-
-        # now need to clean up any receipt tempfiles that have now been made into
-        # permanent gpics
-        # -- but don't need to do this if it was a mogilefs TempFile, since
-        #    we did a rename and there's nothing to delete. 'twould be redundant
-        if ($img->{pclustertype} ne 'mogilefs' &&
-            $img->{_from_rcpt} && $img->{_rcpt_pathkey}) {
-
-            FB::clean_receipt_tempfile($img->{pclustertype}, $img->{_rcpt_pathkey})
-                or return $err->(500 => FB::last_error());
-        }
-
+    # now need to clean up any receipt tempfiles that have now been made into
+    # permanent gpics
+    # -- but don't need to do this if it was a mogilefs TempFile, since
+    #    we did a rename and there's nothing to delete. 'twould be redundant
+    if ($img->{pclustertype} ne 'mogilefs' &&
+        $img->{_from_rcpt} && $img->{_rcpt_pathkey}) {
+        FB::clean_receipt_tempfile($img->{pclustertype}, $img->{_rcpt_pathkey})
+            or return $err->(500 => FB::last_error());
     }
 
     # definitely have a $gpic now, either from above or from an existing receipt
-    return $err->(510) unless $gpic; # should never happen, but be safe
+    return $err->(510) unless $content; # should never happen, but be safe
 
-    # allocate new upic
-    my $pre_existing = 0;
-    my $up = FB::Upic->create($u, $gpic->{gpicid},
-                              secid => $picsec,
-                              exist_flag => \$pre_existing)
-        or return $err->(511 => $@);
+    # upload photo to fotki and create
+    my $upload_res;
+    eval {
+        $upload_res = LJ::Fotki->upload_photo($lj_user, $content, debug => 1);
+    };     
+    return $err->(510 => $@) if $@;
 
-    # only need to re-check disk quota if the upic returned wasn't an
-    # already existing and accounted for upic
-    unless ($pre_existing) {
-        # call hook again to check if user has disk space for picture
-        # AFTER uploading (rather than try to hold some sort of lock over
-        # some indefinite period of time)
-        my $Kibfree = FB::run_hook("disk_remaining", $u);
-        if (defined $Kibfree && $Kibfree < 0) {
-            # need to delete this picture now because apparently two pics
-            # were uploading at once.
-            $up->delete;
-            return $err->(401);
-        }
-    }
+    my $photo_data = $upload_res->{'photo_data'};
+    my $version = $upload_res->{'api_version'};
 
-    # parse EXIF data from image and store it if necessary
-    if ($FB::EXTRACT_EXIF_ON_UPLOAD && $up->fmtid == FB::fmtid_from_ext('jpg')) {
-        $up->exif_header($gpic->data)
-            or return $err->(511 => "Couldn't extract EXIF Header" => FB::last_error());
-    }
+    # add photo to all necessary albums
+    my $photo;
+    foreach my $album (@albums) {
+        $photo = LJ::Fotki::Photo->create(userid => $lj_userid, album_id => $album->album_id, photo_data => $photo_data, version => $version, security => $security, allowmask => $allowmask);
+        return $err->(513 => 'Error adding photo to album '.$album->album_id) unless $photo;
+        # Meta information
+        # -- existence vs definition checked at top
+        if (defined $vars->{Meta}) {
+            my $meta = $vars->{Meta};
 
-    # auto-rotate picture
-    {
-        my $handle_dup = sub {
-            my $exist_upicid = shift;
-            # delete the one we'd been working with,
-            # and keep working with the original one
-            $up->delete;
-            $up = FB::Upic->new($u, $exist_upicid);
-        };
-        $up->add_event_listener("set_gpic_failed_dup", $handle_dup);
-        $up->autorotate;
-        $up->remove_event_listener("set_gpic_failed_dup", $handle_dup);
-    }
+            # set photo title
+            if (defined $meta->{Title}) {
+                $photo->set_title($meta->{Title}) or return $err->(511 => "Couldn't set title prop");
+            }
 
-
-    if (! $FB::NO_UPLOAD_PRESCALING && ($gpic->{width} > 640 || $gpic->{height} > 640)) {
-        # load the scaled version, creating unless necessary... just to make sure it's there
-        eval { $gpic->load_scaled(640, 640, { create => 1 }) };
-        return $err->(510 => [ "Unable to scale Gpic" => $@ ]) if $@;
-    }
-
-    # add to galleries
-    foreach my $gal (@gals) {
-        $gal->add_picture($up)
-            or return $err->(513 => FB::last_error());
-    }
-
-    # Meta information
-    # -- existence vs definition checked at top
-    if (defined $vars->{Meta}) {
-        my $meta = $vars->{Meta};
-
-        # set upc props if they're present
-        foreach ([Filename => 'filename'], [Title => 'pictitle']) {
-            my $val = $meta->{$_->[0]};
-            next unless defined $val;
-            $up->set_text_prop($_->[1] => $val)
-                or return $err->(511 => "Couldn't set $_->[0] prop");
+            # set photo description
+            if (defined $meta->{Description}) {
+                $photo->set_desc($meta->{Description}) or return $err->(511 => "Couldn't set Description");
+            }
         }
-
-        # set picture description if it's present
-        if (defined $meta->{Description}) {
-            $up->set_des($meta->{Description})
-                or return $err->(511 => [ "Couldn't set Description" => FB::last_error() ]);
-        }
     }
 
+    # return the last returned photo_id
     # register return value with parent Request
     $resp->add_method_vars(
                             UploadPic => {
-                                PicID  => [ $up->id ],
-                                URL    => [ $up->url_full ],
-                                Width  => [ $up->width ],
-                                Height => [ $up->height ],
-                                Bytes  => [ $up->bytes ],
+                                PicID  => [ $photo->photo_id ],
+                                URL    => [ $photo->orig_url ],
+                                Width  => [ $photo->orig_width ],
+                                Height => [ $photo->orig_height ],
+                                Bytes  => [ $length ],
                             });
 
     return 1;

Added: trunk/lib/FB/Protocol/Fotki/UploadPrepare.pm
===================================================================
--- trunk/lib/FB/Protocol/Fotki/UploadPrepare.pm	                        (rev 0)
+++ trunk/lib/FB/Protocol/Fotki/UploadPrepare.pm	2011-11-30 18:37:38 UTC (rev 1456)
@@ -0,0 +1,108 @@
+#!/usr/bin/perl
+
+package FB::Protocol::Fotki::UploadPrepare;
+
+use FB::Protocol::Fotki;
+
+use strict;
+
+use LJ::Fotki::UserSpace;
+
+sub handler {
+    my $resp = shift or return undef;
+    my $req  = $resp->{req};
+    my $vars = $req->{vars}->{UploadPrepare};
+    my $u = $resp->{u};
+
+    my $err = sub {
+        $resp->add_method_error(UploadPrepare => @_);
+        return undef;
+    };
+
+    my $lj_userid = FB::get_domain_userid($u);
+    my $lj_user = LJ::load_userid($lj_userid);
+
+    return $err->(212 => "Pic") unless exists $vars->{Pic};
+
+    my $picarr = $vars->{Pic};
+    return $err->(211 => "Pic") unless ref $picarr eq 'ARRAY';
+
+    my $ret = {};
+
+# Get available space for the user
+    my $spaces = LJ::Fotki::UserSpace->get_spaces($lj_user);
+
+    if (ref $spaces eq 'ARRAY') {
+        my $free_space = $spaces->[3] - $spaces->[0]; 
+        $free_space = 0 if $free_space < 0;
+        $ret->{Quota} = {
+            Total     => [ $spaces->[3] ], # kb -> bytes
+            Used      => [ $spaces->[0] ],
+            Remaining => [ $free_space ],
+        };
+    }
+
+  PIC:
+    foreach my $pic (@$picarr) {
+
+        # default values to return, override later
+        my $picret = {
+            MD5   => [ $pic->{MD5} ],
+            known => 0,
+        };
+
+        # err subref, notes error in $picret and goes to next PIC in array
+        my $picerr = sub {
+
+            $picret->{Error} = {
+                code    => $_[0],
+                content => $resp->error_msg(@_),
+            };
+
+            # add to final return structure
+            push @{$ret->{Pic}}, $picret;
+
+            next PIC;
+        };
+
+        # check existence of required vars
+        foreach (qw(Size MD5 Magic)) {
+            $picerr->(212 => $_) unless exists $pic->{$_};
+        }
+
+        # validate Size argument
+        my $size = $pic->{Size};
+        $picerr->(211 => "Size")
+            unless $size =~ /^\d+$/ && $size > 0;
+
+        # valid MD5 argument
+        my $md5 = $pic->{MD5};
+        $picerr->(211 => "MD5")
+            unless $md5 =~ /^[a-f0-9]{32}$/;
+
+        # validate Magic argument
+        my $magic = $pic->{Magic};
+        $picerr->(211 => "Magic")
+            unless $magic =~ /^[a-f0-9]{20}$/;
+
+        my $fmtid = FB::fmtid_from_magic(FB::hex_to_bin($magic))
+            or $picerr->(211 => [ "Magic" => "Invalid Image Format" ]);
+
+        return $err->(213 => "Format doesn't supported")
+            unless FB::Protocol::Fotki->accepted_fmtid($fmtid);
+
+        ### everything's validated now, make a response
+
+        ### nothing to do due to we don't store md5 sums of photos
+
+        # add to final return structure
+        push @{$ret->{Pic}}, $picret;
+    }
+
+    # register return value with parent Request
+    $resp->add_method_vars(UploadPrepare => $ret);
+
+    return 1;
+}
+
+1;

Added: trunk/lib/FB/Protocol/Fotki/UploadTempFile.pm
===================================================================
--- trunk/lib/FB/Protocol/Fotki/UploadTempFile.pm	                        (rev 0)
+++ trunk/lib/FB/Protocol/Fotki/UploadTempFile.pm	2011-11-30 18:37:38 UTC (rev 1456)
@@ -0,0 +1,136 @@
+#!/usr/bin/perl
+
+package FB::Protocol::Fotki::UploadTempFile;
+
+use FB::Protocol::Fotki;
+
+use strict;
+use LJ::Fotki::UserSpace;
+
+sub handler {
+    my $resp = shift or return undef;
+    my $req  = $resp->{req};
+    my $vars = $req->{vars}->{UploadTempFile};
+
+    my $u = $resp->{u};
+
+    my $err = sub {
+        $resp->add_method_error(UploadTempFile => @_);
+        return undef;
+    };
+
+    my $lj_userid = FB::get_domain_userid($u);
+    my $lj_user = LJ::load_userid($lj_userid);
+
+    # is the user allowed to upload?
+    return $err->(303)
+        unless FB::get_cap($u, 'can_upload') && $u->{statusvis} eq 'V';
+
+    # did they specify an ImageData variable?
+    my $img = $vars->{ImageData};
+    return $err->(212 => "ImageData")
+        unless $img;
+
+    # valid pclustertype / pclusterid
+    return $err->(500 => "Could not determine pclustertype/id")
+        unless $img->{pclustertype} && $img->{pclusterid};
+
+    # did we count bytes?
+    return $err->(213 => "No data sent")
+        unless $img->{bytes};
+
+    # check the declared imagelength
+    return $err->(212 => "ImageLength")
+        unless exists $vars->{ImageLength};
+
+    my $length = $vars->{ImageLength};
+    return $err->(211 => "ImageLength")
+        unless defined $length;
+    return $err->(211 => "ImageLength does not match data length")
+        unless $length == $img->{bytes};
+
+    # check that it's a valid fmtid
+    my $fmtid = $img->{fmtid};
+    return $err->(213 => "Unknown format")
+        unless $fmtid;
+
+
+    return $err->(213 => "Format doesn't supported")
+        unless FB::Protocol::Fotki->accepted_fmtid($fmtid);
+
+
+    # valid filehandle -- can't count on path
+    return $err->(500 => "No spool filehandle")
+        unless $img->{spool_fh};
+
+    # valid md5 sum?
+    return $err->(500 => "Could not calculate MD5 sum")
+        unless $img->{md5sum};
+
+    # if an md5 is supplied, check that it matches the image's actual 
+    # calculated md5
+    my $md5_hex = FB::bin_to_hex($img->{md5sum});
+    if ($vars->{MD5} && $vars->{MD5} ne ...
 (truncated)
Tags: fotobilder, pm, sunnyman, vtroitsky
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments