[dw-free] cleaning up userpics code
[commit: http://hg.dwscoalition.org/dw-free/rev/e84aad104e41]
http://bugs.dwscoalition.org/show_bug.cgi?id=513
More functions under LJ::Userpic and on the user, rather than in package LJ
Patch by
kareila.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=513
More functions under LJ::Userpic and on the user, rather than in package LJ
Patch by
Files modified:
- cgi-bin/LJ/User.pm
- cgi-bin/ljfeed.pl
- cgi-bin/ljprotocol.pl
- cgi-bin/ljuserpics.pl
- htdocs/preview/entry.bml
--------------------------------------------------------------------------------
diff -r b29d6cfc5a83 -r e84aad104e41 cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm Wed Sep 08 14:41:32 2010 +0800
+++ b/cgi-bin/LJ/User.pm Wed Sep 08 14:47:35 2010 +0800
@@ -6234,15 +6234,228 @@ sub get_userpic_count {
return $count;
}
+# des: Given a user, gets their userpic information.
+# des-opts: Optional; hash of options, 'load_comments', 'load_urls', 'load_descriptions'.
+# returns: hash of userpicture information;
+# for efficiency, we store the userpic structures
+# in memcache in a packed format.
+# info: memory format:
+# [
+# version number of format,
+# userid,
+# "packed string", which expands to an array of {width=>..., ...}
+# "packed string", which expands to { 'kw1' => id, 'kw2' => id, ...}
+# ]
+
+sub get_userpic_info {
+ my ( $u, $opts ) = @_;
+ return undef unless LJ::isu( $u ) && $u->clusterid;
+
+ # in the cache, cool, well unless it doesn't have comments or urls or descriptions
+ # and we need them
+ if (my $cachedata = $LJ::CACHE_USERPIC_INFO{ $u->userid }) {
+ my $good = 1;
+ $good = 0 if $opts->{load_comments} && ! $cachedata->{_has_comments};
+ $good = 0 if $opts->{load_urls} && ! $cachedata->{_has_urls};
+ $good = 0 if $opts->{load_descriptions} && ! $cachedata->{_has_descriptions};
+
+ return $cachedata if $good;
+ }
+
+ my $VERSION_PICINFO = 3;
+
+ my $memkey = [$u->userid,"upicinf:$u->{'userid'}"];
+ my ($info, $minfo);
+
+ if ($minfo = LJ::MemCache::get($memkey)) {
+ # the pre-versioned memcache data was a two-element hash.
+ # since then, we use an array and include a version number.
+
+ if (ref $minfo eq 'HASH' ||
+ $minfo->[0] != $VERSION_PICINFO) {
+ # old data in the cache. delete.
+ LJ::MemCache::delete($memkey);
+ } else {
+ my (undef, $picstr, $kwstr) = @$minfo;
+ $info = {
+ 'pic' => {},
+ 'kw' => {},
+ };
+ while (length $picstr >= 7) {
+ my $pic = { userid => $u->{'userid'} };
+ ($pic->{picid},
+ $pic->{width}, $pic->{height},
+ $pic->{state}) = unpack "NCCA", substr($picstr, 0, 7, '');
+ $info->{pic}->{$pic->{picid}} = $pic;
+ }
+
+ my ($pos, $nulpos);
+ $pos = $nulpos = 0;
+ while (($nulpos = index($kwstr, "\0", $pos)) > 0) {
+ my $kw = substr($kwstr, $pos, $nulpos-$pos);
+ my $id = unpack("N", substr($kwstr, $nulpos+1, 4));
+ $pos = $nulpos + 5; # skip NUL + 4 bytes.
+ $info->{kw}->{$kw} = $info->{pic}->{$id} if $info;
+ }
+ }
+
+ # Load picture comments
+ if ( $opts->{load_comments} ) {
+ my $commemkey = [$u->userid, "upiccom:" . $u->userid];
+ my $comminfo = LJ::MemCache::get( $commemkey );
+
+ if ( defined( $comminfo ) ) {
+ my ( $pos, $nulpos );
+ $pos = $nulpos = 0;
+ while ( ($nulpos = index( $comminfo, "\0", $pos )) > 0 ) {
+ my $comment = substr( $comminfo, $pos, $nulpos-$pos );
+ my $id = unpack( "N", substr( $comminfo, $nulpos+1, 4 ) );
+ $pos = $nulpos + 5; # skip NUL + 4 bytes.
+ $info->{pic}->{$id}->{comment} = $comment;
+ $info->{comment}->{$id} = $comment;
+ }
+ $info->{_has_comments} = 1;
+ } else { # Requested to load comments, but they aren't in memcache
+ # so force a db load
+ undef $info;
+ }
+ }
+
+ # Load picture urls
+ if ( $opts->{load_urls} && $info ) {
+ my $urlmemkey = [$u->userid, "upicurl:" . $u->userid];
+ my $urlinfo = LJ::MemCache::get( $urlmemkey );
+
+ if ( defined( $urlinfo ) ) {
+ my ( $pos, $nulpos );
+ $pos = $nulpos = 0;
+ while ( ($nulpos = index( $urlinfo, "\0", $pos )) > 0 ) {
+ my $url = substr( $urlinfo, $pos, $nulpos-$pos );
+ my $id = unpack( "N", substr( $urlinfo, $nulpos+1, 4 ) );
+ $pos = $nulpos + 5; # skip NUL + 4 bytes.
+ $info->{pic}->{$id}->{url} = $url;
+ }
+ $info->{_has_urls} = 1;
+ } else { # Requested to load urls, but they aren't in memcache
+ # so force a db load
+ undef $info;
+ }
+ }
+
+ # Load picture descriptions
+ if ( $opts->{load_descriptions} && $info ) {
+ my $descmemkey = [$u->userid, "upicdes:" . $u->userid];
+ my $descinfo = LJ::MemCache::get( $descmemkey );
+
+ if ( defined ( $descinfo ) ) {
+ my ( $pos, $nulpos );
+ $pos = $nulpos = 0;
+ while ( ($nulpos = index( $descinfo, "\0", $pos )) > 0 ) {
+ my $description = substr( $descinfo, $pos, $nulpos-$pos );
+ my $id = unpack( "N", substr( $descinfo, $nulpos+1, 4 ) );
+ $pos = $nulpos + 5; # skip NUL + 4 bytes.
+ $info->{pic}->{$id}->{description} = $description;
+ $info->{description}->{$id} = $description;
+ }
+ $info->{_has_descriptions} = 1;
+ } else { # Requested to load descriptions, but they aren't in memcache
+ # so force a db load
+ undef $info;
+ }
+ }
+ }
+
+ my %minfocom; # need this in this scope
+ my %minfourl;
+ my %minfodesc;
+ unless ($info) {
+ $info = {
+ 'pic' => {},
+ 'kw' => {},
+ };
+ my ($picstr, $kwstr);
+ my $sth;
+ my $dbcr = LJ::get_cluster_def_reader($u);
+ my $db = @LJ::MEMCACHE_SERVERS ? LJ::get_db_writer() : LJ::get_db_reader();
+ return undef unless $dbcr && $db;
+
+ $sth = $dbcr->prepare( "SELECT picid, width, height, state, userid, comment, url, description ".
+ "FROM userpic2 WHERE userid=?" );
+ $sth->execute( $u->userid );
+ my @pics;
+ while (my $pic = $sth->fetchrow_hashref) {
+ next if $pic->{state} eq 'X'; # no expunged pics in list
+ push @pics, $pic;
+ $info->{'pic'}->{$pic->{'picid'}} = $pic;
+ $minfocom{int($pic->{picid})} = $pic->{comment}
+ if $opts->{load_comments} && $pic->{comment};
+ $minfourl{int($pic->{picid})} = $pic->{url}
+ if $opts->{load_urls} && $pic->{url};
+ $minfodesc{int($pic->{picid})} = $pic->{description}
+ if $opts->{load_descriptions} && $pic->{description};
+ }
+
+
+ $picstr = join('', map { pack("NCCA", $_->{picid},
+ $_->{width}, $_->{height}, $_->{state}) } @pics);
+
+ $sth = $dbcr->prepare( "SELECT k.keyword, m.picid FROM userpicmap2 m, userkeywords k ".
+ "WHERE k.userid=? AND m.kwid=k.kwid AND m.userid=k.userid" );
+ $sth->execute($u->{'userid'});
+ my %minfokw;
+ while (my ($kw, $id) = $sth->fetchrow_array) {
+ next unless $info->{'pic'}->{$id};
+ next if $kw =~ /[\n\r\0]/; # used to be a bug that allowed these to get in.
+ $info->{'kw'}->{$kw} = $info->{'pic'}->{$id};
+ $minfokw{$kw} = int($id);
+ }
+ $kwstr = join('', map { pack("Z*N", $_, $minfokw{$_}) } keys %minfokw);
+
+ $memkey = [$u->{'userid'},"upicinf:$u->{'userid'}"];
+ $minfo = [ $VERSION_PICINFO, $picstr, $kwstr ];
+ LJ::MemCache::set($memkey, $minfo);
+
+ if ( $opts->{load_comments} ) {
+ $info->{comment} = \%minfocom;
+ my $commentstr = join( '', map { pack( "Z*N", $minfocom{$_}, $_ ) } keys %minfocom );
+
+ my $memkey = [$u->userid, "upiccom:" . $u->userid];
+ LJ::MemCache::set( $memkey, $commentstr );
+
+ $info->{_has_comments} = 1;
+ }
+
+ if ($opts->{load_urls}) {
+ my $urlstr = join( '', map { pack( "Z*N", $minfourl{$_}, $_ ) } keys %minfourl );
+
+ my $memkey = [$u->userid, "upicurl:" . $u->userid];
+ LJ::MemCache::set( $memkey, $urlstr );
+
+ $info->{_has_urls} = 1;
+ }
+
+ if ($opts->{load_descriptions}) {
+ $info->{description} = \%minfodesc;
+ my $descstring = join( '', map { pack( "Z*N", $minfodesc{$_}, $_ ) } keys %minfodesc );
+
+ my $memkey = [$u->userid, "upicdes:" . $u->userid];
+ LJ::MemCache::set( $memkey, $descstring );
+
+ $info->{_has_descriptions} = 1;
+ }
+ }
+
+ $LJ::CACHE_USERPIC_INFO{$u->userid} = $info;
+ return $info;
+}
+
# gets a mapping from userpic ids to keywords for this User.
sub get_userpic_kw_map {
- my $self = shift;
-
- if ( $self->{picid_kw_map} ) {
- return $self->{picid_kw_map};
- }
-
- my $picinfo = LJ::get_userpic_info( $self->userid, {load_comments => 0} );
+ my ( $u ) = @_;
+
+ return $u->{picid_kw_map} if $u->{picid_kw_map}; # cache
+
+ my $picinfo = $u->get_userpic_info( { load_comments => 0 } );
my $keywords = {};
foreach my $keyword ( keys %{$picinfo->{kw}} ) {
my $picid = $picinfo->{kw}->{$keyword}->{picid};
@@ -6250,8 +6463,7 @@ sub get_userpic_kw_map {
push @{$keywords->{$picid}}, $keyword if ( $keyword && $picid );
}
- $self->{picid_kw_map} = $keywords;
- return $keywords;
+ return $u->{picid_kw_map} = $keywords;
}
# <LJFUNC>
diff -r b29d6cfc5a83 -r e84aad104e41 cgi-bin/ljfeed.pl
--- a/cgi-bin/ljfeed.pl Wed Sep 08 14:41:32 2010 +0800
+++ b/cgi-bin/ljfeed.pl Wed Sep 08 14:47:35 2010 +0800
@@ -901,7 +901,7 @@ sub create_view_userpics {
# now start building all the userpic data
# start up by loading all of our userpic information and creating that part of the feed
- my $info = LJ::get_userpic_info( $u, { load_comments => 1, load_urls => 1, load_descriptions => 1 } );
+ my $info = $u->get_userpic_info( { load_comments => 1, load_urls => 1, load_descriptions => 1 } );
my %keywords = ();
while (my ($kw, $pic) = each %{$info->{kw}}) {
diff -r b29d6cfc5a83 -r e84aad104e41 cgi-bin/ljprotocol.pl
--- a/cgi-bin/ljprotocol.pl Wed Sep 08 14:41:32 2010 +0800
+++ b/cgi-bin/ljprotocol.pl Wed Sep 08 14:47:35 2010 +0800
@@ -3058,9 +3058,10 @@ sub hash_menus
sub list_pickws
{
- my $u = shift;
-
- my $pi = LJ::get_userpic_info($u);
+ my ( $u ) = @_;
+ return [] unless LJ::isu( $u );
+
+ my $pi = $u->get_userpic_info;
my @res;
my %seen; # mashifiedptr -> 1
diff -r b29d6cfc5a83 -r e84aad104e41 cgi-bin/ljuserpics.pl
--- a/cgi-bin/ljuserpics.pl Wed Sep 08 14:41:32 2010 +0800
+++ b/cgi-bin/ljuserpics.pl Wed Sep 08 14:47:35 2010 +0800
@@ -108,242 +108,18 @@ sub load_userpics {
}
}
-# <LJFUNC>
-# name: LJ::get_userpic_info
-# des: Given a user, gets their userpic information.
-# args: uuid, opts?
-# des-uuid: userid, or user object.
-# des-opts: Optional; hash of options, 'load_comments', 'load_urls', 'load_descriptions'.
-# returns: hash of userpicture information;
-# for efficiency, we store the userpic structures
-# in memcache in a packed format.
-# info: memory format:
-# [
-# version number of format,
-# userid,
-# "packed string", which expands to an array of {width=>..., ...}
-# "packed string", which expands to { 'kw1' => id, 'kw2' => id, ...}
-# ]
-# </LJFUNC>
-
-sub get_userpic_info
-{
- my ($uuid, $opts) = @_;
- return undef unless $uuid;
- my $userid = LJ::want_userid($uuid);
- my $u = LJ::want_user($uuid); # This should almost always be in memory already
- return undef unless $u && $u->{clusterid};
-
- # in the cache, cool, well unless it doesn't have comments or urls or descriptions
- # and we need them
- if (my $cachedata = $LJ::CACHE_USERPIC_INFO{$userid}) {
- my $good = 1;
- $good = 0 if $opts->{load_comments} && ! $cachedata->{_has_comments};
- $good = 0 if $opts->{load_urls} && ! $cachedata->{_has_urls};
- $good = 0 if $opts->{load_descriptions} && ! $cachedata->{_has_descriptions};
-
- return $cachedata if $good;
- }
-
- my $VERSION_PICINFO = 3;
-
- my $memkey = [$u->{'userid'},"upicinf:$u->{'userid'}"];
- my ($info, $minfo);
-
- if ($minfo = LJ::MemCache::get($memkey)) {
- # the pre-versioned memcache data was a two-element hash.
- # since then, we use an array and include a version number.
-
- if (ref $minfo eq 'HASH' ||
- $minfo->[0] != $VERSION_PICINFO) {
- # old data in the cache. delete.
- LJ::MemCache::delete($memkey);
- } else {
- my (undef, $picstr, $kwstr) = @$minfo;
- $info = {
- 'pic' => {},
- 'kw' => {},
- };
- while (length $picstr >= 7) {
- my $pic = { userid => $u->{'userid'} };
- ($pic->{picid},
- $pic->{width}, $pic->{height},
- $pic->{state}) = unpack "NCCA", substr($picstr, 0, 7, '');
- $info->{pic}->{$pic->{picid}} = $pic;
- }
-
- my ($pos, $nulpos);
- $pos = $nulpos = 0;
- while (($nulpos = index($kwstr, "\0", $pos)) > 0) {
- my $kw = substr($kwstr, $pos, $nulpos-$pos);
- my $id = unpack("N", substr($kwstr, $nulpos+1, 4));
- $pos = $nulpos + 5; # skip NUL + 4 bytes.
- $info->{kw}->{$kw} = $info->{pic}->{$id} if $info;
- }
- }
-
- # Load picture comments
- if ( $opts->{load_comments} ) {
- my $commemkey = [$u->userid, "upiccom:" . $u->userid];
- my $comminfo = LJ::MemCache::get( $commemkey );
-
- if ( defined( $comminfo ) ) {
- my ( $pos, $nulpos );
- $pos = $nulpos = 0;
- while ( ($nulpos = index( $comminfo, "\0", $pos )) > 0 ) {
- my $comment = substr( $comminfo, $pos, $nulpos-$pos );
- my $id = unpack( "N", substr( $comminfo, $nulpos+1, 4 ) );
- $pos = $nulpos + 5; # skip NUL + 4 bytes.
- $info->{pic}->{$id}->{comment} = $comment;
- $info->{comment}->{$id} = $comment;
- }
- $info->{_has_comments} = 1;
- } else { # Requested to load comments, but they aren't in memcache
- # so force a db load
- undef $info;
- }
- }
-
- # Load picture urls
- if ( $opts->{load_urls} && $info ) {
- my $urlmemkey = [$u->userid, "upicurl:" . $u->userid];
- my $urlinfo = LJ::MemCache::get( $urlmemkey );
-
- if ( defined( $urlinfo ) ) {
- my ( $pos, $nulpos );
- $pos = $nulpos = 0;
- while ( ($nulpos = index( $urlinfo, "\0", $pos )) > 0 ) {
- my $url = substr( $urlinfo, $pos, $nulpos-$pos );
- my $id = unpack( "N", substr( $urlinfo, $nulpos+1, 4 ) );
- $pos = $nulpos + 5; # skip NUL + 4 bytes.
- $info->{pic}->{$id}->{url} = $url;
- }
- $info->{_has_urls} = 1;
- } else { # Requested to load urls, but they aren't in memcache
- # so force a db load
- undef $info;
- }
- }
-
- # Load picture descriptions
- if ( $opts->{load_descriptions} && $info ) {
- my $descmemkey = [$u->userid, "upicdes:" . $u->userid];
- my $descinfo = LJ::MemCache::get( $descmemkey );
-
- if ( defined ( $descinfo ) ) {
- my ( $pos, $nulpos );
- $pos = $nulpos = 0;
- while ( ($nulpos = index( $descinfo, "\0", $pos )) > 0 ) {
- my $description = substr( $descinfo, $pos, $nulpos-$pos );
- my $id = unpack( "N", substr( $descinfo, $nulpos+1, 4 ) );
- $pos = $nulpos + 5; # skip NUL + 4 bytes.
- $info->{pic}->{$id}->{description} = $description;
- $info->{description}->{$id} = $description;
- }
- $info->{_has_descriptions} = 1;
- } else { # Requested to load descriptions, but they aren't in memcache
- # so force a db load
- undef $info;
- }
- }
- }
-
- my %minfocom; # need this in this scope
- my %minfourl;
- my %minfodesc;
- unless ($info) {
- $info = {
- 'pic' => {},
- 'kw' => {},
- };
- my ($picstr, $kwstr);
- my $sth;
- my $dbcr = LJ::get_cluster_def_reader($u);
- my $db = @LJ::MEMCACHE_SERVERS ? LJ::get_db_writer() : LJ::get_db_reader();
- return undef unless $dbcr && $db;
-
- $sth = $dbcr->prepare( "SELECT picid, width, height, state, userid, comment, url, description ".
- "FROM userpic2 WHERE userid=?" );
- $sth->execute( $u->userid );
- my @pics;
- while (my $pic = $sth->fetchrow_hashref) {
- next if $pic->{state} eq 'X'; # no expunged pics in list
- push @pics, $pic;
- $info->{'pic'}->{$pic->{'picid'}} = $pic;
- $minfocom{int($pic->{picid})} = $pic->{comment}
- if $opts->{load_comments} && $pic->{comment};
- $minfourl{int($pic->{picid})} = $pic->{url}
- if $opts->{load_urls} && $pic->{url};
- $minfodesc{int($pic->{picid})} = $pic->{description}
- if $opts->{load_descriptions} && $pic->{description};
- }
-
-
- $picstr = join('', map { pack("NCCA", $_->{picid},
- $_->{width}, $_->{height}, $_->{state}) } @pics);
-
- $sth = $dbcr->prepare( "SELECT k.keyword, m.picid FROM userpicmap2 m, userkeywords k ".
- "WHERE k.userid=? AND m.kwid=k.kwid AND m.userid=k.userid" );
- $sth->execute($u->{'userid'});
- my %minfokw;
- while (my ($kw, $id) = $sth->fetchrow_array) {
- next unless $info->{'pic'}->{$id};
- next if $kw =~ /[\n\r\0]/; # used to be a bug that allowed these to get in.
- $info->{'kw'}->{$kw} = $info->{'pic'}->{$id};
- $minfokw{$kw} = int($id);
- }
- $kwstr = join('', map { pack("Z*N", $_, $minfokw{$_}) } keys %minfokw);
-
- $memkey = [$u->{'userid'},"upicinf:$u->{'userid'}"];
- $minfo = [ $VERSION_PICINFO, $picstr, $kwstr ];
- LJ::MemCache::set($memkey, $minfo);
-
- if ( $opts->{load_comments} ) {
- $info->{comment} = \%minfocom;
- my $commentstr = join( '', map { pack( "Z*N", $minfocom{$_}, $_ ) } keys %minfocom );
-
- my $memkey = [$u->userid, "upiccom:" . $u->userid];
- LJ::MemCache::set( $memkey, $commentstr );
-
- $info->{_has_comments} = 1;
- }
-
- if ($opts->{load_urls}) {
- my $urlstr = join( '', map { pack( "Z*N", $minfourl{$_}, $_ ) } keys %minfourl );
-
- my $memkey = [$u->userid, "upicurl:" . $u->userid];
- LJ::MemCache::set( $memkey, $urlstr );
-
- $info->{_has_urls} = 1;
- }
-
- if ($opts->{load_descriptions}) {
- $info->{description} = \%minfodesc;
- my $descstring = join( '', map { pack( "Z*N", $minfodesc{$_}, $_ ) } keys %minfodesc );
-
- my $memkey = [$u->userid, "upicdes:" . $u->userid];
- LJ::MemCache::set( $memkey, $descstring );
-
- $info->{_has_descriptions} = 1;
- }
- }
-
- $LJ::CACHE_USERPIC_INFO{$u->userid} = $info;
- return $info;
-}
-
sub get_picid_from_keyword
{
my ($u, $kw, $default) = @_;
$default ||= (ref $u ? $u->{'defaultpicid'} : 0);
return $default unless $kw;
- my $info = LJ::get_userpic_info($u);
+ my $info = LJ::isu( $u ) ? $u->get_userpic_info : undef;
return $default unless $info;
my $pr = $info->{'kw'}{$kw};
# normal keyword
- return $pr->{picid} if $pr->{'picid'};
+ return $pr->{picid} if $pr->{picid};
# the lame "pic#2343" thing when they didn't assign a keyword
if ($kw =~ /^pic\#(\d+)$/) {
diff -r b29d6cfc5a83 -r e84aad104e41 htdocs/preview/entry.bml
--- a/htdocs/preview/entry.bml Wed Sep 08 14:41:32 2010 +0800
+++ b/htdocs/preview/entry.bml Wed Sep 08 14:47:35 2010 +0800
@@ -121,14 +121,10 @@ _c?>
if ($u) {
$ret .= "<table><tr valign='middle'>";
- my $picid = LJ::get_picid_from_keyword($up, $req{'prop_picture_keyword'});
- my $upics = LJ::get_userpic_info($up);
- my $pic = $upics->{'pic'}->{$picid};
- if ($pic) {
- my $userpic = LJ::Userpic->new( $up, $picid );
- $ret .= "<td>" . $userpic->imgtag . "</td>";
- }
+ my $pic = LJ::Userpic->new_from_keyword( $up, $req{prop_picture_keyword} );
+ my $imgtag = $pic ? $pic->imgtag : undef;
+ $ret .= "<td>$imgtag</td>" if $imgtag;
$ret .= "<td>";
if ( $u->is_community ) {
--------------------------------------------------------------------------------
