fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2010-08-19 10:09 am

[dw-free] replace ljmood.pl with DW::Mood.pm

[commit: http://hg.dwscoalition.org/dw-free/rev/e4bbbdb03788]

http://bugs.dwscoalition.org/show_bug.cgi?id=2690

Refactor set_picture and set_pictures_multi out of the bml page and into a
module.

Patch by [personal profile] kareila.

Files modified:
  • cgi-bin/DW/Mood.pm
  • cgi-bin/LJ/Console/Command/MoodthemeSetpic.pm
  • htdocs/manage/moodthemes.bml
  • htdocs/manage/moodthemes.bml.text
--------------------------------------------------------------------------------
diff -r 0acbf04e2b68 -r e4bbbdb03788 cgi-bin/DW/Mood.pm
--- a/cgi-bin/DW/Mood.pm	Thu Aug 19 17:53:28 2010 +0800
+++ b/cgi-bin/DW/Mood.pm	Thu Aug 19 18:08:53 2010 +0800
@@ -211,6 +211,71 @@ sub get_picture {
         return 1;
     }
     return 0;  # couldn't find a picture anywhere in the parent chain
+}
+
+# object method to update or delete a mood icon
+# arguments: moodid; hashref containing new mood icon data; error ref
+# returns: 1 on success, undef otherwise.
+sub set_picture {
+    my ( $self, $moodid, $pic, $err, $dbh ) = @_;
+    my $errsub = sub { $$err = $_[0] if ref $err; return undef };
+    return $errsub->( LJ::Lang::ml( "/manage/moodthemes.bml.error.cantupdatetheme" ) )
+        unless $self->id and $moodid and ref $pic and $moodid =~ /^\d+$/;
+
+    my ( $picurl, $w, $h ) = @{ $pic }{ qw/ picurl width height / };
+    return $errsub->( LJ::Lang::ml( "/manage/moodthemes.bml.error.notanumber",
+                      { moodname => $self->mood_name( $moodid ) } ) )
+        if ( $w and $w !~ /^\d+$/ ) or ( $h and $h !~ /^\d+$/ );
+    return $errsub->( LJ::Lang::ml( "/manage/moodthemes.bml.error.picurltoolong" ) )
+        if $picurl and length $picurl > 200;
+
+    $dbh ||= LJ::get_db_writer() or
+        return $errsub->( LJ::Lang::ml( "error.nodb" ) );
+
+    if ( $picurl && $w && $h ) {  # do update
+        $dbh->do( "REPLACE INTO moodthemedata (moodthemeid, moodid," .
+                  " picurl, width, height) VALUES (?, ?, ?, ?, ?)",
+                 undef, $self->id, $moodid, $picurl, $w, $h );
+    } else {  # do delete
+        $dbh->do( "DELETE FROM moodthemedata WHERE moodthemeid = ?" .
+                  " AND moodid= ?", undef, $self->id, $moodid );
+    }
+    return $errsub->( LJ::Lang::ml( "error.dberror" ) . $dbh->errstr )
+        if $dbh->err;
+    $self->clear_cache;
+
+    return 1;
+}
+
+# object method to update or delete multiple mood icons in one transaction
+# arguments: arrayref of data arrayrefs [ $moodid => \%pic ]; error ref
+# returns: 1 on success, undef otherwise.
+sub set_picture_multi {
+    my ( $self, $data, $err ) = @_;
+    die "Need array reference for set_picture_multi"
+        unless ref $data eq "ARRAY";
+
+    my $errsub = sub { $$err = $_[0] if ref $err; return undef };
+    my $dbh = LJ::get_db_writer() or
+        return $errsub->( LJ::Lang::ml( "error.nodb" ) );
+    $dbh->begin_work;
+    return $errsub->( LJ::Lang::ml( "error.dberror" ) . $dbh->errstr )
+        if $dbh->err;
+
+    foreach ( @$data ) {
+        # we pass the database handle for transaction continuity
+        my $rv = $self->set_picture( $_->[0], $_->[1], $err, $dbh );
+        unless ( $rv ) {  # abort transaction
+            $dbh->rollback;
+            return undef;  # error message already in $err
+        }
+    }
+
+    $dbh->commit;
+    return $errsub->( LJ::Lang::ml( "error.dberror" ) . $dbh->errstr )
+        if $dbh->err;
+
+    return 1;
 }
 
 # get theme description (adapted from LJ::mood_theme_des)
diff -r 0acbf04e2b68 -r e4bbbdb03788 cgi-bin/LJ/Console/Command/MoodthemeSetpic.pm
--- a/cgi-bin/LJ/Console/Command/MoodthemeSetpic.pm	Thu Aug 19 17:53:28 2010 +0800
+++ b/cgi-bin/LJ/Console/Command/MoodthemeSetpic.pm	Thu Aug 19 18:08:53 2010 +0800
@@ -43,32 +43,18 @@ sub execute {
     return $self->error("Sorry, your account type doesn't let you create new mood themes")
         unless $remote->can_create_moodthemes;
 
-    my $owner = DW::Mood->ownerid( $themeid );
-    return $self->error("You do not own this mood theme.")
-        unless $owner == $remote->id;
+    my $theme = DW::Mood->new( $themeid );
+    return $self->error( "You do not own this mood theme." )
+        unless $theme && $theme->ownerid == $remote->id;
 
-    my $dbh = LJ::get_db_writer() or
-        return $self->error( "Database unavailable" );
+    my $err;
+    return $self->error( $err ) unless
+        $theme->set_picture( $moodid, { picurl => $picurl,
+                                        width  => $width,
+                                        height => $height }, \$err );
 
-    $width += 0;
-    $height += 0;
-    $moodid += 0;
-
-    if (!$picurl || $width == 0 || $height == 0) {
-        $dbh->do("DELETE FROM moodthemedata WHERE moodthemeid = ? AND moodid= ?", undef, $themeid, $moodid);
-        $self->print("Data deleted for theme #$themeid, mood #$moodid.");
-    } elsif ( length($picurl) > 200 ) {
-        $self->error("Moodpic URLs cannot exceed 200 characters.");
-    } else {
-        $dbh->do("REPLACE INTO moodthemedata (moodthemeid, moodid, picurl, width, height) VALUES (?, ?, ?, ?, ?)",
-                 undef, $themeid, $moodid, $picurl, $width, $height);
-        $self->print("Data inserted for theme #$themeid, mood #$moodid.");
-    }
-
-    $self->error("Database error: " . $dbh->errstr)
-        if $dbh->err;
-
-    DW::Mood->clear_cache( $themeid );
+    my $verb = ( $picurl && $width && $height ) ? 'inserted' : 'deleted';
+    $self->print( "Data $verb for theme #$themeid, mood #$moodid." );
 
     return 1;
 }
diff -r 0acbf04e2b68 -r e4bbbdb03788 htdocs/manage/moodthemes.bml
--- a/htdocs/manage/moodthemes.bml	Thu Aug 19 17:53:28 2010 +0800
+++ b/htdocs/manage/moodthemes.bml	Thu Aug 19 18:08:53 2010 +0800
@@ -329,7 +329,8 @@ body<=
             $ret .= "</form> p?>\n";
 
         } elsif ( $themeid )  { # Save their changes
-            my $theme = DW::Mood->new( $themeid );
+            my $theme = DW::Mood->new( $themeid ) or return
+                    "<?h1 $ML{'Error'} h1?><?p $ML{'.error.cantupdatetheme'} p?>";
 
             # Update the name or description if needed
             if ( $info->{name} ne $POST{name} ) {
@@ -338,13 +339,12 @@ body<=
             }
 
             # The fun part of figuring out what needs to be changed in the db
-            my $dbh = LJ::get_db_writer();
-            my (@repl_values, @repl_bind, @del_values, @del_bind);
-            foreach my $key (keys %POST) {
+            my @picdata;
+            foreach my $key ( keys %POST ) {
                 # A key that is fully numeric signifies an actual mood theme.
                 # We then build off this id number to get other information needed
                 # about what the user specified.
-                if ($key =~ /(^\d+$)/) {
+                if ( $key =~ /(^\d+$)/ ) {
                     my $mid = $1;
                     my $width = $POST{$mid.'w'};
                     my $height = $POST{$mid.'h'};
@@ -352,49 +352,31 @@ body<=
                     my $mname = DW::Mood->mood_name( $mid );
 
                     # inherited, don't represent in db
-                    if ($POST{$mid.'check'} eq 'checked') {
-                        push @del_values, $mid;
-                        push @del_bind, ("?");
-                        $ret .= BML::ml('.mood.deleted', {'mood' => "$mname($mid)"}) . "<br />\n";
+                    if ( $POST{$mid.'check'} eq 'checked' ) {
+                        push @picdata, [ $mid, {} ];
+                        $ret .= BML::ml( '.mood.deleted', { mood => "$mname($mid)"} ) . "<br />\n";
                         next;
                     }
 
                     # one of these is blank, so delete the mood
-                    if (!$picurl || $width == 0 || $height == 0) {
-                        push @del_values, $mid;
-                        push @del_bind, ("?");
+                    unless ( $picurl && $width && $height ) {
+                        push @picdata, [ $mid, {} ];
                         next;
                     }
 
                     # we have a picurl, width, and height. add it.
-                    if ($picurl =~ m!^https?://[^\'\"\0\s]+$!) {
-                        push @repl_values, ($themeid, $mid, $picurl, $width, $height);
-                        push @repl_bind, ("(?, ?, ?, ?, ?)");
-                        $ret .= BML::ml('.mood.setpic', {'mood' => "$mname($mid)", 'url' => $picurl}) . "<br />\n";
+                    if ( $picurl =~ m!^https?://[^\'\"\0\s]+$! ) {
+                        push @picdata, [ $mid, { picurl => $picurl, width => $width, height => $height } ];
+                        $ret .= BML::ml( '.mood.setpic', { mood => "$mname($mid)", url => $picurl } ) . "<br />\n";
                     }
                 }
             }
 
-            if (@del_values) {
-                my $bind = join(",", @del_bind);
-                my $p = $dbh->do("DELETE FROM moodthemedata WHERE moodthemeid=? AND moodid IN($bind)",
-                                 undef, $themeid, @del_values);
-                return "<?h1 $ML{'Error'} h1?><?p $ML{'.error.cantupdatetheme'} p?>" unless $p;
-            }
-
-            if (@repl_values) {
-                my $bind = join(",", @repl_bind);
-                my $i = $dbh->do("REPLACE INTO moodthemedata (moodthemeid, moodid, " .
-                                 "picurl, width, height) VALUES $bind", undef, @repl_values);
-                return "<?h1 $ML{'Error'} h1?><?p $ML{'.error.cantupdatetheme'} p?>" unless $i;
-            }
-
-            # Kill any memcache data about this moodtheme
-            DW::Mood->clear_cache( $themeid );
-            $u->delete_moodtheme_cache;
+            my $err;
+            $theme->set_picture_multi( \@picdata, \$err ) or
+                return "<?h1 $ML{'Error'} h1?><?p $err p?>";
 
             $ret .= "<br />$ML{'.saved'}<br /><br />\n";
-            return BML::redirect( $self_uri );
         }
 
         $ret .= BML::ml('Backlink', {
diff -r 0acbf04e2b68 -r e4bbbdb03788 htdocs/manage/moodthemes.bml.text
--- a/htdocs/manage/moodthemes.bml.text	Thu Aug 19 17:53:28 2010 +0800
+++ b/htdocs/manage/moodthemes.bml.text	Thu Aug 19 18:08:53 2010 +0800
@@ -29,7 +29,11 @@
 
 .error.nonamegiven=You must specify a name for this theme.
 
+.error.notanumber=Width and height for "[[moodname]]" must be numeric.
+
 .error.notyourtheme=You do not have permission to edit this theme.
+
+.error.picurltoolong=Moodpic URLs cannot exceed 200 characters.
 
 .mood.deleted=[[mood]] was deleted and will now be represented by its parent.
 
--------------------------------------------------------------------------------