Add Popular Subscriptions feature, helps find new people to subscribe
to.
Patch by yvi.
diffs (382 lines):
diff -r f64ccc1de255 -r 5e837b3c4787 bin/upgrading/en.dat
--- a/bin/upgrading/en.dat Tue Jan 05 22:53:19 2010 +0000
+++ b/bin/upgrading/en.dat Tue Jan 05 23:58:20 2010 +0000
@@ -2097,6 +2097,8 @@ menunav.explore.interests=Interests
menunav.explore.directorysearch=Directory Search
+menunav.explore.popsubscriptions=Popular Subscriptions
+
menunav.explore.randomjournal=Random Journal
menunav.explore.randomcommunity=Random Community
diff -r f64ccc1de255 -r 5e837b3c4787 cgi-bin/DW/Logic/MenuNav.pm
--- a/cgi-bin/DW/Logic/MenuNav.pm Tue Jan 05 22:53:19 2010 +0000
+++ b/cgi-bin/DW/Logic/MenuNav.pm Tue Jan 05 23:58:20 2010 +0000
@@ -55,6 +55,7 @@ sub get_menu_navigation {
my $loggedin_canjoincomms = ( $loggedin && $u->is_person ) ? 1 : 0; #
note the semantic difference
my $loggedin_hasnetwork = ( $loggedin && $u->can_use_network_page ) ? 1 :
0;
my $loggedin_ispaid = ( $loggedin && $u->is_paid ) ? 1 : 0;
+ my $loggedin_popsubscriptions = ( $loggedin &&
$u->can_use_popsubscriptions );
my $loggedout = $loggedin ? 0 : 1;
my $always = 1;
my $never = 0;
@@ -215,6 +216,11 @@ sub get_menu_navigation {
display => $always,
},
{
+ url => "$LJ::SITEROOT/tools/popsubscriptions",
+ text => "menunav.explore.popsubscriptions",
+ display => $loggedin_popsubscriptions,
+ },
+ {
url => "$LJ::SITEROOT/support/faq",
text => "menunav.explore.faq",
display => $always,
diff -r f64ccc1de255 -r 5e837b3c4787 cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm Tue Jan 05 22:53:19 2010 +0000
+++ b/cgi-bin/LJ/User.pm Tue Jan 05 23:58:20 2010 +0000
@@ -1956,6 +1956,10 @@ sub can_use_mass_privacy {
return $_[0]->get_cap( 'mass_privacy' ) ? 1 : 0;
}
+sub can_use_popsubscriptions {
+ return $_[0]->get_cap( 'popsubscriptions' ) ? 1 : 0;
+}
+
sub can_use_network_page {
return 0 unless $_[0]->get_cap( 'friendsfriendsview' ) && $_[0]->is_person;
}
diff -r f64ccc1de255 -r 5e837b3c4787 etc/config.pl
--- a/etc/config.pl Tue Jan 05 22:53:19 2010 +0000
+++ b/etc/config.pl Tue Jan 05 23:58:20 2010 +0000
@@ -365,7 +365,6 @@
'findsim' => 0,
'friendsfriendsview' => 0,
'friendspage_per_day' => 0,
- 'friendspopwithfriends' => 0,
'friendsviewupdate' => 0,
'full_rss' => 1,
'getselfemail' => 0,
@@ -378,6 +377,7 @@
'mod_queue' => 50,
'mod_queue_per_poster' => 3,
'moodthemecreate' => 0,
+ popsubscriptions => 0,
's2layersmax' => 0,
's2props' => 0,
's2styles' => 0,
@@ -421,7 +421,6 @@
'findsim' => 1,
'friendsfriendsview' => 1,
'friendspage_per_day' => 1,
- 'friendspopwithfriends' => 1,
'friendsviewupdate' => 1,
'full_rss' => 1,
'getselfemail' => 1,
@@ -434,6 +433,7 @@
'mod_queue' => 100,
'mod_queue_per_poster' => 5,
'moodthemecreate' => 1,
+ popsubscriptions => 1,
's2layersmax' => 150,
's2props' => 1,
's2styles' => 1,
@@ -475,7 +475,6 @@
'findsim' => 1,
'friendsfriendsview' => 1,
'friendspage_per_day' => 1,
- 'friendspopwithfriends' => 1,
'friendsviewupdate' => 1,
'full_rss' => 1,
'getselfemail' => 1,
@@ -488,6 +487,7 @@
'mod_queue' => 100,
'mod_queue_per_poster' => 5,
'moodthemecreate' => 1,
+ popsubscriptions => 1,
's2layersmax' => 300,
's2props' => 1,
's2styles' => 1,
@@ -536,7 +536,6 @@
'findsim' => 1,
'friendsfriendsview' => 1,
'friendspage_per_day' => 1,
- 'friendspopwithfriends' => 1,
'friendsviewupdate' => 1,
'full_rss' => 1,
'getselfemail' => 1,
@@ -549,6 +548,7 @@
'mod_queue' => 100,
'mod_queue_per_poster' => 5,
'moodthemecreate' => 1,
+ popsubscriptions => 1,
's2layersmax' => 300,
's2props' => 1,
's2styles' => 1,
@@ -588,7 +588,6 @@
'findsim' => 1,
'friendsfriendsview' => 1,
'friendspage_per_day' => 1,
- 'friendspopwithfriends' => 1,
'friendsviewupdate' => 1,
'full_rss' => 1,
'getselfemail' => 1,
@@ -601,6 +600,7 @@
'mod_queue' => 100,
'mod_queue_per_poster' => 5,
'moodthemecreate' => 1,
+ popsubscriptions => 1,
's2layersmax' => 300,
's2props' => 1,
's2styles' => 1,
diff -r f64ccc1de255 -r 5e837b3c4787 htdocs/tools/popsubscriptions.bml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/tools/popsubscriptions.bml Tue Jan 05 23:58:20 2010 +0000
@@ -0,0 +1,203 @@
+<?_c
+#
+# tools/popsubscriptions.bml
+#
+# Page that shows a sorted list of popular accounts in the user's circle. User
can pick
+# which circle group to base these calculations on by selecting from a
drop-down menu.
+# Results are displayed in three sections: personal accounts, community
accounts, feed accounts.
+#
+# Authors:
+# Rebecca Freiburg <[email protected]>
+#
+# Copyright (c) 2009 by Dreamwidth Studios, LLC.
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself. For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+_c?>
+
+<?page
+title=><?_ml .title _ml?>
+body<=
+<?_code
+{
+ use strict;
+ use warnings;
+
+ my $ret = "<?p $ML{'.intro'} p?>";
+
+ my $remote = LJ::get_remote();
+
+ return "<?needlogin?>" unless $remote;
+
+ return $ML{'.invalidaccounttype'} unless $remote->can_use_popsubscriptions;
+
+ return $ML{'.disabled'} unless LJ::is_enabled( 'popsubscriptions' );
+
+ # filters options:
+ # 1: only accounts subscribed to
+ # 2: only mutually subscribed accounts
+ # 3: trusted accounts
+ # 4: mutually trusted accounts
+ # 5: whole circle => subscriptions + gives access to
+
+ my @calc_options;
+ @calc_options = ("1", $ML{'.filters.subscriptions'}, "2",
$ML{'.filters.mutualsubscriptions'}, "3", $ML{'.filters.access'},
+ "4", $ML{'.filters.mutualaccess'}, "5", $ML{'.filters.circle'} );
+
+ # drop-down menu and button for selecting which user accounts to base the
calulations on
+ $ret .= "<?p $ML{'.options.filter'} p?>";
+ $ret .= "<form method='get' action='/tools/popsubscriptions'>\n";
+ $ret .= LJ::html_select( { name => 'filter'}, @calc_options );
+ $ret .= LJ::html_submit( $ML{'.options.submit'} );
+ $ret .= "</form><br /></p>";
+
+ # circle_ids stores the user ids of accounts to base the calculation on.
which accounts these are is based on which filter the user picks.
+ # default: subscriptions (filter: 1)
+ my @circle_ids;
+
+ my $filter = $GET{filter};
+ if ( !$filter || $filter == 1 ) {
+ @circle_ids = $remote->watched_userids;
+ } elsif ( $filter == 2 ) {
+ @circle_ids = $remote->mutually_watched_userids;
+ } elsif ( $filter == 3 ) {
+ @circle_ids = $remote->trusted_userids;
+ } elsif ( $filter == 4 ) {
+ @circle_ids = $remote->mutually_trusted_userids;
+ } else {
+ @circle_ids = $remote->circle_userids;
+ }
+
+ # circle can currently have a maximum of 4,000 userid (2,000 watched,
2,000 trusted) calculate for a maximum of 750 of them
+ # on those scales, we won't lose much resolution doing this, as trusted
and watched are almost always overlapping
+ my $circle_limit = 750;
+ @circle_ids = splice( @circle_ids, 0, $circle_limit ) if @circle_ids >
$circle_limit;
+
+ # hash for searching whether the user is already subscribed to someone
later
+ my %circle_members;
+ foreach my $id ( @circle_ids ) {
+ $circle_members{$id} = 1;
+ }
+
+ # hash for counting how many accounts in @circle_ids are subscribed to a
particular account
+ my %count;
+
+ # limit the number of userids loaded for each @circle_ids user to 500
+ my $limit = 500;
+ my $remote_id = $remote->userid;
+
+ # load users...
+ my $circleusers = LJ::load_userids( @circle_ids );
+
+ # now load the accounts the users are watching...
+ foreach my $uid ( @circle_ids ) {
+ # don't want to include the user themself
+ next if $uid == $remote_id;
+
+ # since we have just loaded all user objects, we can now load
subscribed accounts of that user
+ my $circleuser = $circleusers->{$uid};
+
+ # but we only include undeleted, unsuspended, personal journals
(personal + identity)
+ next unless $circleuser->is_individual || ! $circleuser->is_inactive;
+
+ # get userids subscribers are watching
+ my @subsubs =$circleuser->watched_userids( limit => $limit ) ;
+
+ # if there are none, skip to next subscription
+ next unless @subsubs;
+
+ # now we count the occurance of the userids
+ foreach my $userid ( @subsubs ) {
+ $count{$userid}++;
+ }
+ }
+
+ # now that we have the count for all userids, we sort it and take the most
popular 500
+ my @pop = sort { $count{$b} <=> $count{$a} } keys %count;
+ @pop = splice( @pop, 0, 500 );
+
+ # now we sort according to personal, community or feed account and only
take the top 50 accounts
+ # for this we need to lead the user objects
+ my $popusers = LJ::load_userids( @pop );
+ my ( @poppersonal, @popcomms, @popfeeds );
+ my ( $numberpersonal, $numbercomms, $numberfeeds ) = ( 0, 0, 0 );
+ my $maximum = 50;
+ foreach my $uid ( @pop ) {
+ my $popuser = $popusers->{$uid};
+
+ # don't show already subscribed to accounts, inactive accounts, or
banned accounts
+ next if $circle_members{$uid} || $uid == $remote_id ||
$popuser->is_inactive || $remote->is_banned( $popuser, $remote);
+
+ # sort userids into arrays
+ if ( $numberpersonal < $maximum && $popuser->is_personal ) {
+ push @poppersonal, $uid;
+ $numberpersonal++;
+ } elsif ( $numbercomms < $maximum && $popuser->is_community ) {
+ push @popcomms, $uid;
+ $numbercomms++;
+ } elsif ( $numberfeeds < $maximum && $popuser->is_syndicated ) {
+ push @popfeeds, $uid;
+ $numberfeeds++;
+ }
+
+ # don't continue loop if all three arrays have reached the maximum
number
+ last if $numberpersonal + $numbercomms + $numberfeeds >= $maximum * 3;
+ }
+
+ # function to construct table rows which we print later
+ sub make_results_rows {
+ my ( $poparray, $count ) = @_;
+ my ( $results, $count_user, $popularu );
+
+ # need to load user objects to use ->ljuser_display. this is for a
maximum of 50 accounts here
+ my $popularusers = LJ::load_userids( @$poparray );
+
+ foreach my $popularid ( @$poparray ) {
+ $count_user = $count->{$popularid};
+ $popularu = $popularusers->{$popularid};
+ $results .= "<tr><td>" . $popularu->ljuser_display . "</td>";
+ $results .= "<td align='right'> $count_user</td></tr>";
+ }
+ return $results;
+ }
+
+ # store results in table format. these rows can be empty
+ my ( $results_personal, $results_communities, $results_feeds );
+ $results_personal = make_results_rows ( \...@poppersonal, \%count );
+ $results_communities = make_results_rows ( \...@popcomms, \%count );
+ $results_feeds = make_results_rows ( \...@popfeeds, \%count );
+
+ # no results to display: show error message
+ unless ( $results_personal || $results_communities || $results_feeds ) {
+ $ret .= $ML{'.error.noresults'};
+ return $ret;
+ }
+
+ # print the tables
+ # only show each result section if there are accounts in them, if not show
a message
+ if ( $results_personal ) {
+ $ret .= $ML{'.results.personal'};
+ $ret .= "<table cellpadding='3'>" . $results_personal . "</table><br
/></p>";
+ } else {
+ $ret .= "<?p $ML{'.error.noresults.personal'} p?>";
+ }
+ if ( $results_communities ) {
+ $ret .= $ML{'.results.communities'};
+ $ret .= "<table cellpadding='3'>" . $results_communities .
"</table><br /></p>";
+ } else {
+ $ret .= "<?p $ML{'.error.noresults.communities'} p?>";
+ }
+ if ( $results_feeds) {
+ $ret .= $ML{'.results.feeds'};
+ $ret .= "<table cellpadding='3'>" . $results_feeds . "</table><br
/></p>";
+ } else {
+ $ret .= "<?p $ML{'.error.noresults.feeds'} p?>";
+ }
+
+ return $ret;
+
+
+}
+_code?>
+<=body
+page?>
diff -r f64ccc1de255 -r 5e837b3c4787 htdocs/tools/popsubscriptions.bml.text
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/tools/popsubscriptions.bml.text Tue Jan 05 23:58:20 2010 +0000
@@ -0,0 +1,39 @@
+.communities.intro=These are the most popular community accounts in your
circle:
+
+.disabled=This feature is not available on this service.
+
+.error.noresults=Sorry, there were no accounts found for your search.
+
+.error.noresults.communities=Sorry, there were no community accounts found for
your search.
+
+.error.noresults.feeds=Sorry, there were no personal accounts found for your
search.
+
+.error.noresults.personal=Sorry, there were no feeds found for your search.
+
+.feeds.intro=These are the most popular feeds in your circle:
+
+.filters.access=access list
+
+.filters.circle=your circle
+
+.filters.mutualaccess=mutual access
+
+.filters.mutualsubscriptions=mutual subscriptions
+
+.filters.subscriptions=subscriptions
+
+.intro=This page displays popular subscriptions within your circle. Only
personal accounts are used for this analysis.
+
+.invalidaccounttype=Sorry, your account type does not permit using this page.
+
+.options.filter=Select a method to filter which users to include for this
analysis.
+
+.options.submit=Submit
+
+.results.communities=These are the most popular community accounts in your
circle:
+
+.results.feeds=These are the most popular feeds in your circle:
+
+.results.personal=These are the most popular personal accounts in your circle:
+
+.title=Popular With Circle
_______________________________________________
dw-changelog mailing list
[email protected]
http://lists.dwscoalition.org/mailman/listinfo/dw-changelog