madeon (madeon) wrote in changelog,
madeon
madeon
changelog

[livejournal] r20343: LJSUP-10119: Delayed entries and sticky ...

Committer: sbelyaev
LJSUP-10119: Delayed entries and sticky entry are disabled.
U   trunk/bin/upgrading/proplists.dat
U   trunk/cgi-bin/LJ/Entry.pm
U   trunk/cgi-bin/LJ/User.pm
U   trunk/cgi-bin/LJ/Widget/EntryForm.pm
U   trunk/cgi-bin/ljprotocol.pl
U   trunk/htdocs/editjournal.bml
Modified: trunk/bin/upgrading/proplists.dat
===================================================================
--- trunk/bin/upgrading/proplists.dat	2011-10-17 13:11:09 UTC (rev 20342)
+++ trunk/bin/upgrading/proplists.dat	2011-10-17 13:47:38 UTC (rev 20343)
@@ -1748,9 +1748,10 @@
   multihomed: 0
   cldversion: 8
 
-userproplist.sticky_entries:
+userproplist.sticky_entry:
   datatype: char
-  des: Sticky entries ids
+  des: Sticky entry
   indexed: 0
-  prettyname: Sticky enries
+  prettyname: Sticky entry
 
+

Modified: trunk/cgi-bin/LJ/Entry.pm
===================================================================
--- trunk/cgi-bin/LJ/Entry.pm	2011-10-17 13:11:09 UTC (rev 20342)
+++ trunk/cgi-bin/LJ/Entry.pm	2011-10-17 13:47:38 UTC (rev 20343)
@@ -444,7 +444,6 @@
 sub prop {
     my ($self, $prop) = @_;
     $self->_load_props unless $self->{_loaded_props};
-
     return $self->{props} unless $prop;
     return $self->{props}{$prop};
 }
@@ -452,7 +451,6 @@
 sub props {
     my ($self, $prop) = @_;
     $self->_load_props unless $self->{_loaded_props};
-
     return $self->{props} || {};
 }
 
@@ -465,13 +463,11 @@
 
 sub _load_props {
     my $self = shift;
-
     return 1 if $self->{_loaded_props};
 
     my $props = {};
     LJ::load_log_props2($self->{u}, [ $self->jitemid ], $props);
     $self->handle_prefetched_props($props->{$self->jitemid});
-
     return 1;
 }
 
@@ -1464,7 +1460,7 @@
     my ($self) = @_;
 
     my $u = $self->{u};
-    return $self->{jitemid} == $u->get_sticky_entry();
+    return $self->jitemid == $u->get_sticky_entry();
 }
 
 sub can_delete_journal_item {
@@ -1694,6 +1690,7 @@
 
             while (my ($jid, $jitemid, $propid, $value) = $sth->fetchrow_array) {
                 my $id = "$jid:$jitemid";
+#                my $propname = $LJ::CACHE_PROPID{'log'}->{$propid}->{name};
                 $ret->{'prop'}->{$id}->{$propid} = $value;
                 $gotid{$id} = 1;
             }
@@ -2256,21 +2253,16 @@
 
     while ( my ($k, $v) = each %$mem ) {
         next unless $k =~ /(\w+):(\d+):(\d+)/;
-        my ( $memkey, $uid, $pid ) = ( $1, $2, $3 );
 
-        if ( $memkey eq 'logprop2' ) {
+        if ( $1 eq 'logprop2' ) {
             next unless ref $v eq "HASH";
-
-            my @vkeys = keys %$v;
-            next if $vkeys[0] =~ /\D/;
-
-            delete $needprops{$pid};
-            $hashref->{$pid} = $v;
+            delete $needprops{$3};
+            $hashref->{$3} = $v;
         }
 
-        if ( $memkey eq 'rp' ) {
-            delete $needrc{$pid};
-            $rc{$pid} = int($v);  # change possible "0   " (true) to "0" (false)
+        if ( $1 eq 'rp' ) {
+            delete $needrc{$3};
+            $rc{$3} = int($v);  # change possible "0   " (true) to "0" (false)
         }
     }
 
@@ -2289,7 +2281,6 @@
     unless ( $db ) {
         my $u = LJ::load_userid($userid);
         $db = @LJ::MEMCACHE_SERVERS ? LJ::get_cluster_def_reader($u) :  LJ::get_cluster_reader($u);
-
         return unless $db;
     }
 
@@ -2336,7 +2327,6 @@
 sub convert_href_props {
     my $href = shift;
     my %new_href;
-    LJ::load_props('log');
 
     for my $key ( keys %$href ) {
         my $prop = $href->{$key};
@@ -2376,6 +2366,7 @@
 # des-jitemid: Journal itemid of item to delete.
 # des-quick: Optional boolean.  If set, only [dbtable[log2]] table
 #            is deleted from and the rest of the content is deleted
+#            later using [func[LJ::cmd_buffer_add]].
 # des-anum: The log item's anum, which'll be needed to delete lazily
 #           some data in tables which includes the anum, but the
 #           log row will already be gone so we'll need to store it for later.
@@ -2396,6 +2387,11 @@
     # delete tags
     LJ::Tags::delete_logtags($u, $jitemid);
 
+    #remove sticky
+    if ( $jitemid == $u->get_sticky_entry() ){
+        $u->remove_sticky_entry();
+    }
+
     LJ::run_hooks('report_entry_delete', $u->{'userid'}, $jitemid);
     my $dc = $u->log2_do(undef, "DELETE FROM log2 WHERE journalid=$jid AND jitemid=$jitemid $and");
     LJ::MemCache::delete([$jid, "log2:$jid:$jitemid"]);
@@ -2425,10 +2421,6 @@
     # delete all comments
     LJ::delete_all_comments($u, 'L', $jitemid);
 
-    if ( $jitemid == $u->get_sticky_entry() ){
-        $u->remove_sticky_entry();
-    }
-
     return 1;
 }
 

Modified: trunk/cgi-bin/LJ/User.pm
===================================================================
--- trunk/cgi-bin/LJ/User.pm	2011-10-17 13:11:09 UTC (rev 20342)
+++ trunk/cgi-bin/LJ/User.pm	2011-10-17 13:47:38 UTC (rev 20343)
@@ -28,7 +28,6 @@
 use LJ::TimeUtil;
 use LJ::User::PropStorage;
 use LJ::FileStore;
-use LJ::RelationService;
 
 use Class::Autouse qw(
                       URI
@@ -3831,7 +3830,7 @@
         return 1 if $u->can_manage ($comm) or $comm->is_friend($u);
     }
 
-    return 0;
+    return 1;
 }
 
 sub can_upload_photo {
@@ -4565,7 +4564,7 @@
     my $limit = int(delete $args{limit}) || 50000;
     Carp::croak("unknown option") if %args;
 
-    return LJ::RelationService->find_relation_sources($u, limit => $limit);
+    return $u->_friend_friendof_uids(limit => $limit, mode => "friendofs");
 }
 
 # returns array of friend uids.  by default, limited at 50,000 items.
@@ -4574,9 +4573,10 @@
     my $limit = int(delete $args{limit}) || 50000;
     Carp::croak("unknown option") if %args;
 
-    return LJ::RelationService->find_relation_destinations($u, limit => $limit);
+    return $u->_friend_friendof_uids(limit => $limit, mode => "friends");
 }
 
+
 # helper method since the logic for both friends and friendofs is so similar
 sub _friend_friendof_uids {
     my $u = shift;
@@ -4615,7 +4615,6 @@
 # actually get friend/friendof uids, should not be called directly
 sub _friend_friendof_uids_do {
     my ($u, %args) = @_;
-## method is also called from load-friends-gm worker.
 
     my $limit = int(delete $args{limit}) || 50000;
     my $mode  = delete $args{mode};
@@ -6240,27 +6239,33 @@
 # return sticky entries existing
 sub has_sticky_entry {
     my ($self) = @_;
-    my $has_sticky  = !!$self->prop("sticky_entries") || 0;
-    return int $has_sticky;
+    if ($self->prop("sticky_entry")) {
+        return 1;
+    }
+    return 0;
 }
 
 # returns sticky entry jitemid
 sub get_sticky_entry {
     my ($self) = @_;
-    return $self->prop("sticky_entries") || '';
+    return $self->prop("sticky_entry") || '';
 }
 
 # returns sticky entry jitemid
 sub remove_sticky {
     my ($self) = @_;
-    $self->clear_prop("sticky_entries");
+    my $ownerid = $self->userid;
+    $self->clear_prop("sticky_entry");
+    LJ::MemCache::delete([$ownerid, "log2lt:$ownerid"]);
 }
 
 # set sticky entry? 
 sub set_sticky {
     my ($self, $itemid) = @_;
+    my $ownerid = $self->userid;
     die "itemid is not set" unless ($itemid);
-    $self->set_prop( sticky_entries => $itemid );
+    $self->set_prop( sticky_entry => $itemid );
+    LJ::MemCache::delete([$ownerid, "log2lt:$ownerid"]);
 }
 
 package LJ;
@@ -8654,16 +8659,163 @@
     return undef unless $userid;
     return undef if $LJ::FORCE_EMPTY_FRIENDS{$userid};
 
-    my $u = LJ::load_userid($userid);
+    unless ($force) {
+        my $memc = _get_friends_memc($userid, $mask);
+        return $memc if $memc;
+    }
+    return {} if $memcache_only; # no friends
 
-    return LJ::RelationService->load_relation_destinations(
-            $u, uuid          => $uuid,
-                mask          => $mask,
-                memcache_only => $memcache_only,
-                force_db      => $force,
-                );
+    # nothing from memcache, select all rows from the
+    # database and insert those into memcache
+    # then return rows that matched the given groupmask
+
+    # no gearman/gearman not wanted
+    my $gc = LJ::gearman_client();
+    return _get_friends_db($userid, $mask)
+        unless $gc && LJ::conf_test($LJ::LOADFRIENDS_USING_GEARMAN, $userid);
+
+    # invoke the gearman
+    my $friends;
+    my $arg = Storable::nfreeze({ userid => $userid, mask => $mask });
+    my $task = Gearman::Task->new("load_friends", \$arg,
+                                  {
+                                      uniq => "$userid",
+                                      on_complete => sub {
+                                          my $res = shift;
+                                          return unless $res;
+                                          $friends = Storable::thaw($$res);
+                                      }
+                                  });
+
+    my $ts = $gc->new_task_set();
+    $ts->add_task($task);
+    $ts->wait(timeout => 30); # 30 sec timeout
+
+    return $friends;
 }
 
+sub _get_friends_memc {
+    my $userid = shift
+        or Carp::croak("no userid to _get_friends_db");
+    my $mask = shift;
+
+    # memcache data version
+    my $ver = 1;
+
+    my $packfmt = "NH6H6NC";
+    my $packlen = 15;  # bytes
+
+    my @cols = qw(friendid fgcolor bgcolor groupmask showbydefault);
+
+    # first, check memcache
+    my $memkey = [$userid, "friends:$userid"];
+
+    my $memfriends = LJ::MemCache::get($memkey);
+    return undef unless $memfriends;
+
+    my %friends; # rows to be returned
+
+    # first byte of object is data version
+    # only version 1 is meaningful right now
+    my $memver = substr($memfriends, 0, 1, '');
+    return undef unless $memver == $ver;
+
+    # get each $packlen-byte row
+    while (length($memfriends) >= $packlen) {
+        my @row = unpack($packfmt, substr($memfriends, 0, $packlen, ''));
+
+        # don't add into %friends hash if groupmask doesn't match
+        next if $mask && ! ($row[3]+0 & $mask+0);
+
+        # add "#" to beginning of colors
+        $row[$_] = "\#$row[$_]" foreach 1..2;
+
+        # turn unpacked row into hashref
+        my $fid = $row[0];
+        my $idx = 1;
+        foreach my $col (@cols[1..$#cols]) {
+            $friends{$fid}->{$col} = $row[$idx];
+            $idx++;
+        }
+    }
+
+    # got from memcache, return
+    return \%friends;
+}
+
+sub _get_friends_db {
+    my $userid = shift
+        or Carp::croak("no userid to _get_friends_db");
+    my $mask = shift;
+
+    my $dbh = LJ::get_db_writer();
+
+    my $lockname = "get_friends:$userid";
+    my $release_lock = sub {
+        LJ::release_lock($dbh, "global", $lockname);
+    };
+
+    # get a lock
+    my $lock = LJ::get_lock($dbh, "global", $lockname);
+    return {} unless $lock;
+
+    # in lock, try memcache
+    my $memc = _get_friends_memc($userid, $mask);
+    if ($memc) {
+        $release_lock->();
+        return $memc;
+    }
+
+    # inside lock, but still not populated, query db
+
+    # memcache data info
+    my $ver = 1;
+    my $memkey = [$userid, "friends:$userid"];
+    my $packfmt = "NH6H6NC";
+    my $packlen = 15;  # bytes
+
+    # columns we're selecting
+    my @cols = qw(friendid fgcolor bgcolor groupmask showbydefault);
+
+    my $mempack = $ver; # full packed string to insert into memcache, byte 1 is dversion
+    my %friends;        # friends object to be returned, all groupmasks match
+
+    my $sth = $dbh->prepare("SELECT friendid, fgcolor, bgcolor, groupmask, showbydefault " .
+                            "FROM friends WHERE userid=?");
+    $sth->execute($userid);
+    die $dbh->errstr if $dbh->err;
+    while (my @row = $sth->fetchrow_array) {
+
+        # convert color columns to hex
+        $row[$_] = sprintf("%06x", $row[$_]) foreach 1..2;
+
+        my $newpack = pack($packfmt, @row);
+        last if length($mempack) + length($newpack) > 950*1024;
+
+        $mempack .= $newpack;
+
+        # unless groupmask matches, skip adding to %friends
+        next if $mask && ! ($row[3]+0 & $mask+0);
+
+        # add "#" to beginning of colors
+        $row[$_] = "\#$row[$_]" foreach 1..2;
+
+        my $fid = $row[0];
+        my $idx = 1;
+        foreach my $col (@cols[1..$#cols]) {
+            $friends{$fid}->{$col} = $row[$idx];
+            $idx++;
+        }
+    }
+
+    LJ::MemCache::add($memkey, $mempack);
+
+    # finished with lock, release it
+    $release_lock->();
+
+    return \%friends;
+}
+
 # <LJFUNC>
 # name: LJ::get_friendofs
 # des: Returns userids of friendofs for a given user.
@@ -8677,11 +8829,27 @@
     my $userid = LJ::want_userid($uuid);
     return undef unless $userid;
 
-    my $u = LJ::load_userid($userid);
-    return LJ::RelationService->find_relation_sources($u, 
-            nolimit        => $opts->{force} || 0,
-            skip_memcached => $opts->{force},
-            );
+    # first, check memcache
+    my $memkey = [$userid, "friendofs:$userid"];
+
+    unless ($opts->{force}) {
+        my $memfriendofs = LJ::MemCache::get($memkey);
+        return @$memfriendofs if $memfriendofs;
+    }
+
+    # nothing from memcache, select all rows from the
+    # database and insert those into memcache
+
+    my $dbh = LJ::get_db_writer();
+    my $limit = $opts->{force} ? '' : " LIMIT " . ($LJ::MAX_FRIENDOF_LOAD+1);
+    my $friendofs = $dbh->selectcol_arrayref
+        ("SELECT userid FROM friends WHERE friendid=?$limit",
+         undef, $userid) || [];
+    die $dbh->errstr if $dbh->err;
+
+    LJ::MemCache::add($memkey, $friendofs);
+
+    return @$friendofs;
 }
 
 # <LJFUNC>

Modified: trunk/cgi-bin/LJ/Widget/EntryForm.pm
===================================================================
--- trunk/cgi-bin/LJ/Widget/EntryForm.pm	2011-10-17 13:11:09 UTC (rev 20342)
+++ trunk/cgi-bin/LJ/Widget/EntryForm.pm	2011-10-17 13:47:38 UTC (rev 20343)
@@ -824,8 +824,8 @@
                 }
 
                 if ($opts->{jitemid}) {
-                    my $sticky_entry = $journalu->get_sticky_entry();
-                    if ( $sticky_entry eq $opts->{jitemid} ) {
+                    my $sticky_entry_id = $journalu->get_sticky_entry();
+                    if ( $sticky_entry_id eq $opts->{jitemid} ) {
                         return 'checked' 
                     }
                 }   
@@ -1633,57 +1633,6 @@
 sub render_body {
     my ($self) = @_;
 
-    LJ::register_hook('add_to_site_js', sub {
-        my $site = shift;
-
-        my $remote = LJ::get_remote();
-        if (!$remote) {
-            return;
-        }
-        my $login_data = LJ::Protocol::do_request("login", {
-                            "ver" => $LJ::PROTOCOL_VER,
-                            "username" => $remote->username,
-                            "getpickws" => 1,
-                            "getpickwurls" => 1,
-                        }, undef, {
-                            "noauth" => 1,
-                            "u" => $remote,
-                        });
-
-        my $logins = $login_data->{'usejournals'};
-        push @$logins, $remote->username ;
-
-        my $site_data;
-        foreach my $login (@$logins) {
-            my $u = LJ::load_user($login);
-
-            my $can_manage = $remote->can_manage($u) || 0;
-            if (LJ::is_enabled("delayed_entries")) {
-                my $moderated = $u->prop('moderated');
-                my $need_moderated = ( $moderated =~ /^[1A]$/ ) ? 1 : 0;
-                my $can_post = ($u->{'journaltype'} eq 'C' && !$need_moderated) ||
-                            $can_manage;
-   
-                my $ownerid = $u->userid;
-                my $posterid = $remote->userid;
-
-                # don't moderate admins, moderators & pre-approved users
-                my $dbh = LJ::get_db_writer();
-                my $relcount = $dbh->selectrow_array("SELECT COUNT(*) FROM reluser ".
-                                                 "WHERE userid=$ownerid AND targetid=$posterid ".
-                                                 "AND type IN ('A','M','N')");
-        
-               $site_data->{$login}->{'can_post_delayed'} = (int $can_post) || !!$relcount;
-            } else {    
-                $site_data->{$login}->{'can_post_delayed'} = 1;
-            }
-
-            $site_data->{$login}->{'is_replace_sticky'} = $u->has_sticky_entry;
-            $site_data->{$login}->{'can_create_sticky'} = $can_manage;
-        }
-        $site->{remote_permissions} = $site_data;
-    });
-
     my $opts = $self->opts;
     my $head = $self->head;
     my $onload = $self->onload;

Modified: trunk/cgi-bin/ljprotocol.pl
===================================================================
--- trunk/cgi-bin/ljprotocol.pl	2011-10-17 13:11:09 UTC (rev 20342)
+++ trunk/cgi-bin/ljprotocol.pl	2011-10-17 13:47:38 UTC (rev 20343)
@@ -2448,7 +2448,6 @@
     # meta-data
     if (%{$req->{'props'}}) {
         my $propset = {};
-
         foreach my $pname (keys %{$req->{'props'}}) {
             next unless $req->{'props'}->{$pname};
             next if $pname eq "revnum" || $pname eq "revtime";
@@ -2457,21 +2456,9 @@
             next unless $req->{'props'}->{$pname};
             $propset->{$pname} = $req->{'props'}->{$pname};
         }
-
         my %logprops;
         LJ::set_logprop($uowner, $jitemid, $propset, \%logprops) if %$propset;
 
-        for my $key ( keys %logprops ) {
-            next if $key =~ /^\d+$/;
-
-            unless ( $LJ::CACHE_PROP{'log'}->{$key}->{'propid'} ) {
-                delete $logprops{$key};
-            }
-            else {
-                $logprops{ $LJ::CACHE_PROP{'log'}->{$key}->{'propid'} } = delete $logprops{$key};
-            }
-        }
-
         # if set_logprop modified props above, we can set the memcache key
         # to be the hashref of modified props, since this is a new post
         LJ::MemCache::set([$uowner->{'userid'}, "logprop2:$uowner->{'userid'}:$jitemid"],
@@ -2794,10 +2781,6 @@
             }
         };
 
-        if ( $itemid == $uowner->get_sticky_entry() ) {
-            $uowner->remove_sticky();
-        }
-
         return $res;
     }
 
@@ -2828,12 +2811,10 @@
     if ( $req->{sticky} ) {
         if( $uowner->get_sticky_entry() != $itemid ) {
             $uowner->set_sticky($itemid);
-            LJ::MemCache::delete([$ownerid, "log2lt:$ownerid"]);
         }
     }
     elsif ( $itemid == $uowner->get_sticky_entry() ) {
         $uowner->remove_sticky();
-        LJ::MemCache::delete([$ownerid, "log2lt:$ownerid"]);
     }
 
     ## give features
@@ -3014,7 +2995,6 @@
                          "journalid=$ownerid AND jitemid=$itemid");
         return fail($err,501,$dberr) if $dberr;
     }
-
     if ($req->{'props'}->{'opt_backdated'} eq "0" &&
         $oldevent->{'rlogtime'} == $LJ::EndOfTime) {
         my $dberr;
@@ -3080,7 +3060,9 @@
         $uowner = LJ::load_userid( $req->{journalid} );
     }
 
+
     my $sticky_id = $uowner->prop("sticky_entries") || undef;
+
     my $dbr = LJ::get_db_reader();
     my $sth;
 
@@ -3298,7 +3280,7 @@
         $orderby = "ORDER BY $rtime_what";
 
         unless ($skip) {
-            $where .= "OR ( journalid=$ownerid $secwhere $where AND jitemid=$sticky_id)" if defined $sticky_id;
+            $where .= "OR jitemid=$sticky_id" if defined $sticky_id;
         }
     }
     elsif ($req->{'selecttype'} eq "one" && $req->{'itemid'} eq "-1") {

Modified: trunk/htdocs/editjournal.bml
===================================================================
--- trunk/htdocs/editjournal.bml	2011-10-17 13:11:09 UTC (rev 20342)
+++ trunk/htdocs/editjournal.bml	2011-10-17 13:47:38 UTC (rev 20343)
@@ -55,9 +55,12 @@
                     js/photobucket_jw.js
                     ));
 
-    LJ::need_string(qw/
-                        entryform.sticky_replace.edit
-                        entryform.sticky.edit/);
+    if (LJ::is_enabled("delayed_entries")) {
+        LJ::need_string(qw/
+                            entryform.sticky_replace.edit
+                            entryform.sticky.edit
+                            entryform.choose_date/);
+    }
     
     return LJ::bad_input("You must be authenticated as a person.")
         unless $remote->is_personal || $remote->is_identity;

Tags: bml, dat, livejournal, madeon, pl, pm, sbelyaev
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