More refactoring. Make sure icons are sorted by upload order.
Patch by kareila.
diffs (948 lines):
diff -r 93050be9e5bf -r b0e5dbe30bbf cgi-bin/Apache/LiveJournal.pm
--- a/cgi-bin/Apache/LiveJournal.pm Wed Sep 08 15:10:03 2010 +0800
+++ b/cgi-bin/Apache/LiveJournal.pm Wed Sep 08 15:46:13 2010 +0800
@@ -40,6 +40,7 @@ use LJ::URI;
use LJ::URI;
use DW::Routing;
use DW::Template;
+use LJ::Talk;
BEGIN {
$LJ::OPTMOD_ZLIB = eval "use Compress::Zlib (); 1;";
@@ -1137,7 +1138,7 @@ sub userpic_content
return NOT_FOUND unless $u && ! ( $u->is_expunged || $u->is_suspended );
my %upics;
- LJ::load_userpics(\%upics, [ $u, $picid ]);
+ LJ::Talk::load_userpics(\%upics, [ $u, $picid ]);
my $pic = $upics{$picid} or return NOT_FOUND;
return NOT_FOUND if $pic->{'userid'} != $userid || $pic->{state} eq 'X';
diff -r 93050be9e5bf -r b0e5dbe30bbf cgi-bin/LJ/Talk.pm
--- a/cgi-bin/LJ/Talk.pm Wed Sep 08 15:10:03 2010 +0800
+++ b/cgi-bin/LJ/Talk.pm Wed Sep 08 15:46:13 2010 +0800
@@ -1168,10 +1168,103 @@ sub load_comments
$post->{'picid'} = $id;
push @load_pic, [ $pu, $id ];
}
- LJ::load_userpics($opts->{'userpicref'}, \...@load_pic);
+ load_userpics( $opts->{'userpicref'}, \...@load_pic );
}
}
return map { $posts->{$_} } @top_replies;
+}
+
+# <LJFUNC>
+# name: LJ::Talk::load_userpics
+# des: Loads a bunch of userpics at once.
+# args: dbarg?, upics, idlist
+# des-upics: hashref to load pictures into, keys being the picids.
+# des-idlist: [$u, $picid] or [[$u, $picid], [$u, $picid], +] objects
+# also supports deprecated old method, of an array ref of picids.
+# </LJFUNC>
+sub load_userpics {
+ my ($upics, $idlist) = @_;
+
+ return undef unless ref $idlist eq 'ARRAY' && $idlist->[0];
+
+ # $idlist needs to be an arrayref of arrayrefs,
+ # HOWEVER, there's a special case where it can be
+ # an arrayref of 2 items: $u (which is really an arrayref)
+ # as well due to 'fields' and picid which is an integer.
+ #
+ # [$u, $picid] needs to map to [[$u, $picid]] while allowing
+ # [[$u1, $picid1], [$u2, $picid2], [etc...]] to work.
+ if (scalar @$idlist == 2 && ! ref $idlist->[1]) {
+ $idlist = [ $idlist ];
+ }
+
+ my @load_list;
+ foreach my $row (@{$idlist})
+ {
+ my ($u, $id) = @$row;
+ next unless ref $u;
+
+ if ($LJ::CACHE_USERPIC{$id}) {
+ $upics->{$id} = $LJ::CACHE_USERPIC{$id};
+ } elsif ($id+0) {
+ push @load_list, [$u, $id+0];
+ }
+ }
+ return unless @load_list;
+
+ if (@LJ::MEMCACHE_SERVERS) {
+ my @mem_keys = map { [$_->[1],"userpic.$_->[1]"] } @load_list;
+ my $mem = LJ::MemCache::get_multi(@mem_keys) || {};
+ while (my ($k, $v) = each %$mem) {
+ next unless $v && $k =~ /(\d+)/;
+ my $id = $1;
+ $upics->{$id} = LJ::MemCache::array_to_hash("userpic", $v);
+ }
+ @load_list = grep { ! $upics->{$_->[1]} } @load_list;
+ return unless @load_list;
+ }
+
+ my %db_load;
+ foreach my $row (@load_list) {
+ # ignore users on clusterid 0
+ next unless $row->[0]->{clusterid};
+
+ push @{$db_load{$row->[0]->{clusterid}}}, $row;
+ }
+
+ foreach my $cid (keys %db_load) {
+ my $dbcr = LJ::get_cluster_def_reader($cid);
+ unless ($dbcr) {
+ print STDERR "Error: LJ::Talk::load_userpics unable to get handle;
cid = $cid\n";
+ next;
+ }
+
+ my (@bindings, @data);
+ foreach my $row (@{$db_load{$cid}}) {
+ push @bindings, "(userid=? AND picid=?)";
+ push @data, ($row->[0]->{userid}, $row->[1]);
+ }
+ next unless @data && @bindings;
+
+ my $sth = $dbcr->prepare("SELECT userid, picid, width, height, fmt,
state, ".
+ " UNIX_TIMESTAMP(picdate) AS 'picdate',
location, flags ".
+ "FROM userpic2 WHERE " . join(' OR ',
@bindings));
+ $sth->execute(@data);
+
+ while (my $ur = $sth->fetchrow_hashref) {
+ my $id = delete $ur->{'picid'};
+ $upics->{$id} = $ur;
+
+ # force into numeric context so they'll be smaller in memcache:
+ foreach my $k (qw(userid width height flags picdate)) {
+ $ur->{$k} += 0;
+ }
+ $ur->{location} = uc(substr($ur->{location}, 0, 1));
+
+ $LJ::CACHE_USERPIC{$id} = $ur;
+ LJ::MemCache::set([$id,"userpic.$id"],
LJ::MemCache::hash_to_array("userpic", $ur));
+ }
+ }
}
# XXX these strings should be in talk, but moving them means we have
diff -r 93050be9e5bf -r b0e5dbe30bbf cgi-bin/LJ/Userpic.pm
--- a/cgi-bin/LJ/Userpic.pm Wed Sep 08 15:10:03 2010 +0800
+++ b/cgi-bin/LJ/Userpic.pm Wed Sep 08 15:46:13 2010 +0800
@@ -125,17 +125,10 @@ sub new_from_md5 {
sub preload_default_userpics {
my ($class, @us) = @_;
- my %upics;
- LJ::load_userpics(\%upics, [
- map { [ $_, $_->{defaultpicid} ] }
- grep { $_->{defaultpicid} }
- @us
- ]);
+
foreach my $u (@us) {
- my $up = $u->userpic or next;
- my $row = $upics{$up->id} or next;
- $row->{picid} = $up->id;
- $up->absorb_row($row);
+ my $up = $u->userpic or next;
+ $up->load_row;
}
}
@@ -160,8 +153,7 @@ sub new_from_keyword
# instance methods
sub valid {
- my $self = shift;
- return defined $self->state;
+ return defined $_[0]->state;
}
sub absorb_row {
@@ -209,35 +201,35 @@ sub inactive {
}
sub state {
- my $self = shift;
+ my $self = $_[0];
return $self->{state} if defined $self->{state};
$self->load_row;
return $self->{state};
}
sub comment {
- my $self = shift;
+ my $self = $_[0];
return $self->{comment} if exists $self->{comment};
$self->load_row;
return $self->{comment};
}
sub description {
- my $self = shift;
+ my $self = $_[0];
return $self->{description} if exists $self->{description};
$self->load_row;
return $self->{description};
}
sub width {
- my $self = shift;
+ my $self = $_[0];
my @dims = $self->dimensions;
return undef unless @dims;
return $dims[0];
}
sub height {
- my $self = shift;
+ my $self = $_[0];
my @dims = $self->dimensions;
return undef unless @dims;
return $dims[1];
@@ -251,19 +243,18 @@ sub flags {
}
sub md5base64 {
- my $self = shift;
- return $self->{md5base64};
+ return $_[0]->{md5base64};
}
sub extension {
- my $self = shift;
+ my $self = $_[0];
return $self->{_ext} if $self->{_ext};
$self->load_row;
return $self->{_ext};
}
sub location {
- my $self = shift;
+ my $self = $_[0];
return $self->{location} if $self->{location};
$self->load_row;
return $self->{location};
@@ -271,7 +262,7 @@ sub location {
# returns (width, height)
sub dimensions {
- my $self = shift;
+ my $self = $_[0];
# width and height probably loaded from DB
return ($self->{width}, $self->{height}) if ($self->{width} &&
$self->{height});
@@ -289,7 +280,7 @@ sub max_allowed_bytes {
# Returns the direct link to the uploaded userpic
sub url {
- my $self = shift;
+ my $self = $_[0];
if (my $hook_path = LJ::Hooks::run_hook('construct_userpic_url', $self)) {
return $hook_path;
@@ -303,7 +294,7 @@ sub url {
# FIXME: Is this ever used? If not, should be deleted. If so,
# should be renamed to source_url
sub fullurl {
- my $self = shift;
+ my $self = $_[0];
return $self->{url} if $self->{url};
$self->load_row;
return $self->{url};
@@ -333,8 +324,7 @@ sub alttext {
# optional parameters (which must be explicitly passed) include
# width, keyword, and user (object)
sub imgtag {
- my $self = shift;
- my %opts = @_;
+ my ( $self, %opts ) = @_;
# if the width and keyword have been passed in as explicit
# parameters, set them. Otherwise, take what ever is set in
@@ -368,22 +358,22 @@ sub imgtag {
# FIXME: should have alt text, if it should be kept
sub imgtag_lite {
- my $self = shift;
+ my $self = $_[0];
return '<img src="' . $self->url . '" width="' . $self->width . '"
height="' . $self->height .
'" class="userpic-img" />';
}
# FIXME: should have alt text, if it should be kept
sub imgtag_nosize {
- my $self = shift;
+ my $self = $_[0];
return '<img src="' . $self->url . '" class="userpic-img" />';
}
# pass the decimal version of a percentage that you want to shrink/increase
the userpic by
# default is 50% of original size
sub imgtag_percentagesize {
- my $self = shift;
- my $percentage = shift || 0.5;
+ my ( $self, $percentage ) = @_;
+ $percentage ||= 0.5;
my $width = int($self->width * $percentage);
my $height = int($self->height * $percentage);
@@ -395,8 +385,7 @@ sub imgtag_percentagesize {
# must include either a height or width, if both are given the smaller of the
two is used
# returns the width and height attributes as a string to insert into an img tag
sub img_fixedsize {
- my $self = shift;
- my %opts = @_;
+ my ( $self, %opts ) = @_;
my $width = $opts{width} || 0;
my $height = $opts{height} || 0;
@@ -422,8 +411,7 @@ sub img_fixedsize {
# in list context returns list of keywords ( (pic#12345) if none defined )
# opts: 'raw' = return '' instead of 'pic#12345'
sub keywords {
- my $self = shift;
- my %opts = @_;
+ my ( $self, %opts ) = @_;
my $raw = delete $opts{raw} || undef;
@@ -450,47 +438,41 @@ sub keywords {
}
sub imagedata {
- my $self = shift;
+ my $self = $_[0];
- my %upics;
+ $self->load_row or return undef;
my $u = $self->owner;
- LJ::load_userpics(\%upics, [ $u, $self->{picid} ]);
- my $pic = $upics{$self->{picid}} or
- return undef;
- return undef if $pic->{'userid'} != $self->{userid} || $pic->{state} eq
'X';
+ return undef if $self->state eq 'X';
- if ($pic->{location} eq "M") {
- my $key = $u->mogfs_userpic_key( $self->{picid} );
+ # check mogile
+ if ( $self->location eq "M" ) {
+ my $key = $u->mogfs_userpic_key( $self->picid );
my $data = LJ::mogclient()->get_file_data( $key );
return $$data;
}
- my %MimeTypeMapd6 = (
- 'G' => 'gif',
- 'J' => 'jpg',
- 'P' => 'png',
- );
-
+ # check blobserver
my $data;
if ($LJ::USERPIC_BLOBSERVER) {
- my $fmt = $MimeTypeMapd6{ $pic->{fmt} };
- $data = LJ::Blob::get($u, "userpic", $fmt, $self->{picid});
+ my $fmt = $self->extension;
+ $data = LJ::Blob::get( $u, "userpic", $fmt, $self->picid );
return $data if $data;
}
+ # check userpicblob2 table
my $dbb = LJ::get_cluster_reader($u)
or return undef;
- $data = $dbb->selectrow_array("SELECT imagedata FROM userpicblob2 WHERE ".
- "userid=? AND picid=?", undef,
$self->{userid},
- $self->{picid});
+ $data = $dbb->selectrow_array( "SELECT imagedata FROM userpicblob2 WHERE ".
+ "userid=? AND picid=?", undef,
$self->userid,
+ $self->picid );
return $data ? $data : undef;
}
# get : class :: load_row : object
sub load_row {
- my $self = shift;
+ my $self = $_[0];
# use class method
return $self->get( $self->owner, $self->picid );
@@ -500,8 +482,7 @@ sub load_row {
# returns: undef if nothing in cache
# arrayref of LJ::Userpic instances if found in cache
sub get_cache {
- my $class = shift;
- my $u = shift;
+ my ( $class, $u ) = @_;
# check request cache first!
# -- this gets populated when a ->load_user_userpics call happens,
@@ -537,9 +518,7 @@ sub memkey {
}
sub set_cache {
- my $class = shift;
- my $u = shift;
- my $rows = shift;
+ my ( $class, $u, $rows ) = @_;
my $memkey = $class->memkey( $u );
my @vals = map { LJ::MemCache::hash_to_array( 'userpic2', $_ ) } @$rows;
@@ -567,7 +546,7 @@ sub load_user_userpics {
die "Error loading userpics: clusterid=$u->{clusterid}, errstr=" .
$u->errstr
if $u->err;
- my @ret = values %$data;
+ my @ret = sort { $a->{picid} <=> $b->{picid} } values %$data;
# set cache if reasonable
$class->set_cache($u, \...@ret);
@@ -587,7 +566,7 @@ sub create {
croak("Unknown options: " . join(", ", scalar keys %opts)) if %opts;
my $err = sub {
- my $msg = shift;
+ my $msg = $_[0];
};
eval "use Image::Size;";
@@ -794,23 +773,17 @@ sub _get_upf_scaled
# converts an ImageMagick object to the form returned to our callers
my $imageParams = sub {
- my $im = shift;
+ my $im = $_[0];
my $blob = $im->ImageToBlob;
return [\$blob, $im->Get('MIME'), $im->Get('width'),
$im->Get('height')];
};
# compute new width and height while keeping aspect ratio
my $getSizedCoords = sub {
- my $newsize = shift;
+ my ( $newsize, $img ) = @_;
- my $fromw = $ow;
- my $fromh = $oh;
-
- my $img = shift;
- if ($img) {
- $fromw = $img->Get('width');
- $fromh = $img->Get('height');
- }
+ my $fromw = $img ? $img->Get('width') : $ow;
+ my $fromh = $img ? $img->Get('height') : $oh;
return (int($newsize * $fromw/$fromh), $newsize) if $fromh > $fromw;
return ($newsize, int($newsize * $fromh/$fromw));
@@ -931,7 +904,7 @@ sub delete_cache {
# delete this userpic
# TODO: error checking/throw errors on failure
sub delete {
- my $self = shift;
+ my $self = $_[0];
local $LJ::THROW_ERRORS = 1;
my $fail = sub {
@@ -1103,9 +1076,7 @@ sub set_keywords {
# of existing pics is done asynchonously via TheSchwartz using the
# DW::Worker::UserpicRenameWorker.
sub set_and_rename_keywords {
- my $self = shift;
- my $new_keyword_string = $_[0];
- my $orig_keyword_string = $_[1];
+ my ( $self, $new_keyword_string, $orig_keyword_string ) = @_;
my $sclient = LJ::theschwartz();
@@ -1255,17 +1226,17 @@ sub fields { qw(userpic lost); }
sub fields { qw(userpic lost); }
sub number_lost {
- my $self = shift;
+ my $self = $_[0];
return scalar @{ $self->field("lost") };
}
sub lost_keywords_as_html {
- my $self = shift;
+ my $self = $_[0];
return join(", ", map { LJ::ehtml($_) } @{ $self->field("lost") });
}
sub as_html {
- my $self = shift;
+ my $self = $_[0];
my $num_words = $self->number_lost;
return BML::ml("/editicons.bml.error.toomanykeywords", {
numwords => $self->number_lost,
@@ -1278,7 +1249,7 @@ sub user_caused { 1 }
sub user_caused { 1 }
sub fields { qw(size max); }
sub as_html {
- my $self = shift;
+ my $self = $_[0];
return BML::ml('/editicons.bml.error.filetoolarge',
{ 'maxsize' => $self->{'max'} .
BML::ml('/editicons.bml.kilobytes')} );
@@ -1288,7 +1259,7 @@ sub user_caused { 1 }
sub user_caused { 1 }
sub fields { qw(w h); }
sub as_html {
- my $self = shift;
+ my $self = $_[0];
return BML::ml('/editicons.bml.error.imagetoolarge', {
imagesize => $self->{'w'} . 'x' . $self->{'h'}
});
@@ -1298,7 +1269,7 @@ sub user_caused { 1 }
sub user_caused { 1 }
sub fields { qw(type); }
sub as_html {
- my $self = shift;
+ my $self = $_[0];
return BML::ml("/editicons.bml.error.unsupportedtype",
{ 'filetype' => $self->{'type'} });
}
@@ -1307,7 +1278,7 @@ sub user_caused { 1 }
sub user_caused { 1 }
sub fields { qw(origkw newkw); }
sub as_html {
- my $self = shift;
+ my $self = $_[0];
return BML::ml("/editicons.bml.error.rename.mismatchedlength",
{ 'origkw' => $self->{'origkw'},
'newkw' => $self->{'newkw'} });
@@ -1317,7 +1288,7 @@ sub user_caused { 1 }
sub user_caused { 1 }
sub fields { qw(origkw newkw); }
sub as_html {
- my $self = shift;
+ my $self = $_[0];
return BML::ml("/editicons.bml.error.rename.blankkw",
{ 'origkw' => $self->{'origkw'},
'newkw' => $self->{'newkw'} });
@@ -1327,7 +1298,7 @@ sub user_caused { 1 }
sub user_caused { 1 }
sub fields { qw(keyword); }
sub as_html {
- my $self = shift;
+ my $self = $_[0];
return BML::ml("/editicons.bml.error.rename.keywordexists",
{ 'keyword' => $self->{'keyword'} });
}
@@ -1336,7 +1307,7 @@ sub user_caused { 0 }
sub user_caused { 0 }
sub fields { qw(origkw newkw); }
sub as_html {
- my $self = shift;
+ my $self = $_[0];
return BML::ml("/editicons.bml.error.rename.keywords",
{ 'origkw' => $self->{'origkw'},
'newkw' => $self->{'newkw'} });
diff -r 93050be9e5bf -r b0e5dbe30bbf cgi-bin/ljfeed.pl
--- a/cgi-bin/ljfeed.pl Wed Sep 08 15:10:03 2010 +0800
+++ b/cgi-bin/ljfeed.pl Wed Sep 08 15:46:13 2010 +0800
@@ -296,11 +296,10 @@ sub make_feed
return $viewfunc->{handler}->($journalinfo, $u, $opts, \...@cleanitems,
\...@entries);
}
-# the creator for the RSS XML syndication view
-sub create_view_rss
-{
- my ($journalinfo, $u, $opts, $cleanitems) = @_;
-
+# helper method for create_view_rss and create_view_comments
+sub _init_talkview {
+ my ( $journalinfo, $u, $opts, $talkview ) = @_;
+ my $hubbub = $talkview eq 'rss' && LJ::is_enabled( 'hubbub' );
my $ret;
# header
@@ -310,10 +309,14 @@ sub create_view_rss
"xmlns:atom10='http://www.w3.org/2005/Atom'>\n";
# channel attributes
+ my $desc = { rss => LJ::exml( "$journalinfo->{title} - $LJ::SITENAME" ),
+ comments => "Latest comments in "
+ . LJ::exml( $journalinfo->{title} ) };
+
$ret .= "<channel>\n";
$ret .= " <title>" . LJ::exml($journalinfo->{title}) . "</title>\n";
$ret .= " <link>$journalinfo->{link}</link>\n";
- $ret .= " <description>" . LJ::exml("$journalinfo->{title} -
$LJ::SITENAME") . "</description>\n";
+ $ret .= " <description>" . $desc->{$talkview} . "</description>\n";
$ret .= " <managingEditor>" . LJ::exml($journalinfo->{email}) .
"</managingEditor>\n" if $journalinfo->{email};
$ret .= " <lastBuildDate>$journalinfo->{builddate}</lastBuildDate>\n";
$ret .= " <generator>LiveJournal / $LJ::SITENAME</generator>\n";
@@ -321,7 +324,7 @@ sub create_view_rss
$ret .= " <lj:journaltype>" . $u->journaltype_readable .
"</lj:journaltype>\n";
# TODO: add 'language' field when user.lang has more useful information
- if ( LJ::is_enabled( 'hubbub' ) ) {
+ if ( $hubbub ) {
$ret .= " <atom10:link rel='self' href='" . $u->journal_base .
"/data/rss' />\n";
foreach my $hub (@LJ::HUBBUB_HUBS) {
$ret .= " <atom10:link rel='hub' href='" . LJ::exml($hub) . "'
/>\n";
@@ -329,19 +332,27 @@ sub create_view_rss
}
### image block, returns info for their current userpic
- if ($u->{'defaultpicid'}) {
- my $pic = {};
- LJ::load_userpics($pic, [ $u, $u->{'defaultpicid'} ]);
- $pic = $pic->{$u->{'defaultpicid'}}; # flatten
+ if ( $u->{'defaultpicid'} ) {
+ my $icon = $u->userpic;
+ my $url = $icon->url;
+ my ( $width, $height ) = $icon->dimensions;
$ret .= " <image>\n";
- $ret .= "
<url>$LJ::USERPIC_ROOT/$u->{'defaultpicid'}/$u->{'userid'}</url>\n";
- $ret .= " <title>" . LJ::exml($journalinfo->{title}) . "</title>\n";
+ $ret .= " <url>$url</url>\n";
+ $ret .= " <title>" . LJ::exml( $journalinfo->{title} ) .
"</title>\n";
$ret .= " <link>$journalinfo->{link}</link>\n";
- $ret .= " <width>$pic->{'width'}</width>\n";
- $ret .= " <height>$pic->{'height'}</height>\n";
+ $ret .= " <width>$width</width>\n";
+ $ret .= " <height>$height</height>\n";
$ret .= " </image>\n\n";
}
+
+ return $ret;
+}
+
+sub create_view_rss {
+ my ( $journalinfo, $u, $opts, $cleanitems ) = @_;
+
+ my $ret = _init_talkview( $journalinfo, $u, $opts, 'rss' );
my %posteru = (); # map posterids to u objects
LJ::load_userids_multiple([map { $_->{'posterid'},
\$posteru{$_->{'posterid'}} } @$cleanitems], [$u]);
@@ -921,21 +932,21 @@ sub create_view_userpics {
$descriptions{$pic} = LJ::strip_html($description);
}
- my @pics;
- push @pics, map { $info->{pic}->{$_} } sort { $a <=> $b }
- grep { $info->{pic}->{$_}->{state} eq 'N' } keys
%{$info->{pic}};
+ my @pics = map { $info->{pic}->{$_} } sort { $a <=> $b }
+ grep { $info->{pic}->{$_}->{state} eq 'N' }
+ keys %{ $info->{pic} };
- my $entry;
- my %picdata;
-
- # this is lame, but we have to do this iteration twice; we load the
userpic data first, so that
- # we can figure out what the most recently-uploaded userpic is. we need to
put that into the feed
- # before any of the <entry> values.
+ # FIXME: It sucks that there are two different methods for aggregating
+ # the information for a user's set of icons, one of which doesn't
+ # include keywords and the other of which doesn't include pictime.
+ # But hey, at least they both use caching.
+
+ my %pictimes = map { $_->picid => $_->pictime }
+ LJ::Userpic->load_user_userpics( $u );
my $latest = 0;
- foreach my $pic (@pics) {
- LJ::load_userpics(\%picdata, [$u, $pic->{picid}] );
- $latest = ($latest < $picdata{$pic->{picid}}->{picdate}) ?
$picdata{$pic->{picid}}->{picdate} : $latest;
+ foreach my $pictime ( values %pictimes ) {
+ $latest = ($latest < $pictime) ? $pictime : $latest;
}
$feed->updated( LJ::time_to_w3c($latest, 'Z') );
@@ -949,7 +960,7 @@ sub create_view_userpics {
my $title = ($pic->{picid} == $u->{defaultpicid}) ? "default userpic"
: "userpic";
$entry->title( $title );
- $entry->updated( LJ::time_to_w3c($picdata{$pic->{picid}}->{picdate},
'Z') );
+ $entry->updated( LJ::time_to_w3c( $pictimes{ $pic->{picid} }, 'Z') );
my $content;
$content = $entry_xml->createElement( "content" );
@@ -985,9 +996,8 @@ sub create_view_userpics {
}
-sub create_view_comments
-{
- my ($journalinfo, $u, $opts) = @_;
+sub create_view_comments {
+ my ( $journalinfo, $u, $opts ) = @_;
unless ( LJ::is_enabled('latest_comments_rss', $u) ) {
$opts->{handler_return} = 404;
@@ -999,37 +1009,7 @@ sub create_view_comments
return;
}
- my $ret;
- $ret .= "<?xml version='1.0' encoding='$opts->{'saycharset'}' ?>\n";
- $ret .= LJ::Hooks::run_hook("bot_director", "<!-- ", " -->") . "\n";
- $ret .= "<rss version='2.0'
xmlns:lj='http://www.livejournal.org/rss/lj/1.0/'>\n";
-
- # channel attributes
- $ret .= "<channel>\n";
- $ret .= " <title>" . LJ::exml($journalinfo->{title}) . "</title>\n";
- $ret .= " <link>$journalinfo->{link}</link>\n";
- $ret .= " <description>Latest comments in " .
LJ::exml($journalinfo->{title}) . "</description>\n";
- $ret .= " <managingEditor>" . LJ::exml($journalinfo->{email}) .
"</managingEditor>\n" if $journalinfo->{email};
- $ret .= " <lastBuildDate>$journalinfo->{builddate}</lastBuildDate>\n";
- $ret .= " <generator>LiveJournal / $LJ::SITENAME</generator>\n";
- $ret .= " <lj:journal>" . $u->user . "</lj:journal>\n";
- $ret .= " <lj:journaltype>" . $u->journaltype_readable .
"</lj:journaltype>\n";
- # TODO: add 'language' field when user.lang has more useful information
-
- ### image block, returns info for their current userpic
- if ($u->{'defaultpicid'}) {
- my $pic = {};
- LJ::load_userpics($pic, [ $u, $u->{'defaultpicid'} ]);
- $pic = $pic->{$u->{'defaultpicid'}}; # flatten
-
- $ret .= " <image>\n";
- $ret .= "
<url>$LJ::USERPIC_ROOT/$u->{'defaultpicid'}/$u->{'userid'}</url>\n";
- $ret .= " <title>" . LJ::exml($journalinfo->{title}) . "</title>\n";
- $ret .= " <link>$journalinfo->{link}</link>\n";
- $ret .= " <width>$pic->{'width'}</width>\n";
- $ret .= " <height>$pic->{'height'}</height>\n";
- $ret .= " </image>\n\n";
- }
+ my $ret = _init_talkview( $journalinfo, $u, $opts, 'comments' );
my @comments = $u->get_recent_talkitems(25);
foreach my $r (@comments)
diff -r 93050be9e5bf -r b0e5dbe30bbf cgi-bin/ljlib.pl
--- a/cgi-bin/ljlib.pl Wed Sep 08 15:10:03 2010 +0800
+++ b/cgi-bin/ljlib.pl Wed Sep 08 15:46:13 2010 +0800
@@ -138,7 +138,6 @@ require "ljcapabilities.pl";
require "ljcapabilities.pl";
use DW::Mood;
require "ljrelation.pl";
-require "ljuserpics.pl";
require "$LJ::HOME/cgi-bin/ljlib-local.pl"
if -e "$LJ::HOME/cgi-bin/ljlib-local.pl";
diff -r 93050be9e5bf -r b0e5dbe30bbf cgi-bin/ljuserpics.pl
--- a/cgi-bin/ljuserpics.pl Wed Sep 08 15:10:03 2010 +0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-# This code was forked from the LiveJournal project owned and operated
-# by Live Journal, Inc. The code has been modified and expanded by
-# Dreamwidth Studios, LLC. These files were originally licensed under
-# the terms of the license supplied by Live Journal, Inc, which can
-# currently be found at:
-#
-#
http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
-#
-# In accordance with the original license, this code and all its
-# modifications are provided under the GNU General Public License.
-# A copy of that license can be found in the LICENSE file included as
-# part of this distribution.
-
-package LJ;
-use strict;
-use Carp qw/ croak /;
-
-# <LJFUNC>
-# name: LJ::load_userpics
-# des: Loads a bunch of userpics at once.
-# args: dbarg?, upics, idlist
-# des-upics: hashref to load pictures into, keys being the picids.
-# des-idlist: [$u, $picid] or [[$u, $picid], [$u, $picid], +] objects
-# also supports deprecated old method, of an array ref of picids.
-# </LJFUNC>
-sub load_userpics {
- my ($upics, $idlist) = @_;
-
- return undef unless ref $idlist eq 'ARRAY' && $idlist->[0];
-
- # $idlist needs to be an arrayref of arrayrefs,
- # HOWEVER, there's a special case where it can be
- # an arrayref of 2 items: $u (which is really an arrayref)
- # as well due to 'fields' and picid which is an integer.
- #
- # [$u, $picid] needs to map to [[$u, $picid]] while allowing
- # [[$u1, $picid1], [$u2, $picid2], [etc...]] to work.
- if (scalar @$idlist == 2 && ! ref $idlist->[1]) {
- $idlist = [ $idlist ];
- }
-
- my @load_list;
- foreach my $row (@{$idlist})
- {
- my ($u, $id) = @$row;
- next unless ref $u;
-
- if ($LJ::CACHE_USERPIC{$id}) {
- $upics->{$id} = $LJ::CACHE_USERPIC{$id};
- } elsif ($id+0) {
- push @load_list, [$u, $id+0];
- }
- }
- return unless @load_list;
-
- if (@LJ::MEMCACHE_SERVERS) {
- my @mem_keys = map { [$_->[1],"userpic.$_->[1]"] } @load_list;
- my $mem = LJ::MemCache::get_multi(@mem_keys) || {};
- while (my ($k, $v) = each %$mem) {
- next unless $v && $k =~ /(\d+)/;
- my $id = $1;
- $upics->{$id} = LJ::MemCache::array_to_hash("userpic", $v);
- }
- @load_list = grep { ! $upics->{$_->[1]} } @load_list;
- return unless @load_list;
- }
-
- my %db_load;
- foreach my $row (@load_list) {
- # ignore users on clusterid 0
- next unless $row->[0]->{clusterid};
-
- push @{$db_load{$row->[0]->{clusterid}}}, $row;
- }
-
- foreach my $cid (keys %db_load) {
- my $dbcr = LJ::get_cluster_def_reader($cid);
- unless ($dbcr) {
- print STDERR "Error: LJ::load_userpics unable to get handle; cid =
$cid\n";
- next;
- }
-
- my (@bindings, @data);
- foreach my $row (@{$db_load{$cid}}) {
- push @bindings, "(userid=? AND picid=?)";
- push @data, ($row->[0]->{userid}, $row->[1]);
- }
- next unless @data && @bindings;
-
- my $sth = $dbcr->prepare("SELECT userid, picid, width, height, fmt,
state, ".
- " UNIX_TIMESTAMP(picdate) AS 'picdate',
location, flags ".
- "FROM userpic2 WHERE " . join(' OR ',
@bindings));
- $sth->execute(@data);
-
- while (my $ur = $sth->fetchrow_hashref) {
- my $id = delete $ur->{'picid'};
- $upics->{$id} = $ur;
-
- # force into numeric context so they'll be smaller in memcache:
- foreach my $k (qw(userid width height flags picdate)) {
- $ur->{$k} += 0;
- }
- $ur->{location} = uc(substr($ur->{location}, 0, 1));
-
- $LJ::CACHE_USERPIC{$id} = $ur;
- LJ::MemCache::set([$id,"userpic.$id"],
LJ::MemCache::hash_to_array("userpic", $ur));
- }
- }
-}
-
-1;
-
diff -r 93050be9e5bf -r b0e5dbe30bbf htdocs/community/moderate.bml
--- a/htdocs/community/moderate.bml Wed Sep 08 15:10:03 2010 +0800
+++ b/htdocs/community/moderate.bml Wed Sep 08 15:46:13 2010 +0800
@@ -411,17 +411,15 @@ body<=
$ret .= "<p>";
$ret .= "<table><tr valign='middle'>";
- my $picid = $up ? $up->get_picid_from_keyword(
$props->{picture_keyword} ) : undef;
+ my $kw = $props->{picture_keyword};
+ my $icon = LJ::Userpic->new_from_keyword( $up, $kw );
- my %userpics;
- if ( $picid ) {
- LJ::load_userpics(\%userpics, [ $up, $picid ]);
- my $alt = $up->{name};
- $alt .= ": $props->{picture_keyword}"
- if $props->{picture_keyword};
- $alt = LJ::ehtml( $alt );
- $ret .= "<td><img src='$LJ::USERPIC_ROOT/$picid/$up->{'userid'}'
width='$userpics{$picid}->{'width'}' ".
- "height='$userpics{$picid}->{'height'}' align='absmiddle' ".
+ if ( $up && $icon ) {
+ my $alt = $up->name_html . LJ::ehtml( ": $kw" );
+ my $src = $icon->url;
+ my ( $width, $height ) = $icon->dimensions;
+ $ret .= "<td><img src='$src' width='$width' ".
+ "height='$height' align='absmiddle' ".
"hspace='3' title='$alt' alt=''></td>";
}
diff -r 93050be9e5bf -r b0e5dbe30bbf htdocs/manage/profile/index.bml
--- a/htdocs/manage/profile/index.bml Wed Sep 08 15:10:03 2010 +0800
+++ b/htdocs/manage/profile/index.bml Wed Sep 08 15:46:13 2010 +0800
@@ -132,15 +132,9 @@ body<=
### Picture Settings
$ret .= "<tr class='field_block'><td
class='field_name'>$ML{'.fn.userpic2'}</td>\n";
$ret .= "<td><div style='width: 100px; height: 100px; float: left;
text-align: center; border: 1px solid #ddd'>";
- if ($u->{'defaultpicid'}) {
- my $picid = $u->{'defaultpicid'};
- my %userpics = ();
- # FIXME: this repetitive load will be fixed in bug
- # 513. For now, memcache keeps this from hitting the
- # db twice.
- LJ::load_userpics(\%userpics, [ $u, $picid ]);
- my $userpic_obj = LJ::Userpic->new( $u, $picid );
- $ret .= $userpic_obj->imgtag;
+ if ( $u->{'defaultpicid'} ) {
+ my $icon = $u->userpic;
+ $ret .= $icon->imgtag;
} else {
$ret .= "<br /><i>($ML{'.userpic.none'})</i>";
}
diff -r 93050be9e5bf -r b0e5dbe30bbf htdocs/support/see_request.bml
--- a/htdocs/support/see_request.bml Wed Sep 08 15:10:03 2010 +0800
+++ b/htdocs/support/see_request.bml Wed Sep 08 15:46:13 2010 +0800
@@ -311,14 +311,8 @@ body<=
$ret .= "<table class='support-requesttable'>\n";
$ret .= "<tr><td valign='bottom'
align='right'><b>$ML{'.from'}</b></td><td>";
- if ($u->{'defaultpicid'} && !$u->is_suspended) {
- my %pic;
- my $picid = $u->{'defaultpicid'};
- # FIXME: this repetitive load will be fixed in bug
- # 513. For now, memcache keeps this from hitting the
- # db twice.
- LJ::load_userpics(\%pic, [ $u, $picid ]);
- my $userpic_obj = LJ::Userpic->new( $u, $picid );
+ if ( $u->{'defaultpicid'} && !$u->is_suspended ) {
+ my $userpic_obj = $u->userpic;
$ret .= "<a href='" . $u->allpics_base . "'>";
$ret .= $userpic_obj->imgtag;
$ret .= "</a>";
@@ -539,8 +533,6 @@ body<=
$ML{'.private.request'}."</div>";
}
- my %userpics; # id -> {..}
-
my @screened;
my $most_recent_tier = 0;
my $curlang = BML::get_language();
@@ -592,15 +584,16 @@ body<=
my $header = "";
if ($up && LJ::Support::can_see_helper($sp, $remote)) {
my $picid = $up->get_picid_from_keyword( '_support' ) ||
$up->{defaultpicid};
- $userpics{$picid} or LJ::load_userpics(\%userpics, [[ $up, $picid
]]);
+ my $icon = $picid ? LJ::Userpic->new( $up, $picid ) : undef;
$header = "<table style='margin-top: 15px;'><tr valign='bottom'>";
- if ($picid && !$up->is_suspended) {
- $header .= "<td><img
src='$LJ::USERPIC_ROOT/$picid/$up->{'userid'}'
width='$userpics{$picid}->{'width'}' height='$userpics{$picid}->{'height'}'
hspace='3' alt='$up->{'user'}'/></td>";
+ if ( $icon && !$up->is_suspended ) {
+ my $alt = $up->display_name;
+ my $src = $icon->url;
+ my ( $width, $height ) = $icon->dimensions;
+ $header .= "<td><img src='$src' width='$width'
height='$height' hspace='3' alt='$alt'/></td>";
}
- $header .= "<td>" . LJ::ljuser($up->{'user'}, { 'full' => 1 });
- if (!$up->is_suspended) {
- $header .= " - " . LJ::ehtml($up->{'name'});
- }
+ $header .= "<td>" . LJ::ljuser( $u, { full => 1 } );
+ $header .= " - " . $up->name_html unless $up->is_suspended;
$header .= "</td></tr></table>\n"
}
_______________________________________________
dw-changelog mailing list
[email protected]
http://lists.dwscoalition.org/mailman/listinfo/dw-changelog