fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-10-18 03:48 pm

[dw-free] Search for several interests at once

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

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

Search for up to 3 interests at a time over on /interests. This is an AND
search -- that is, search for all users and communities that have interest A
and interest B (not: search for all users that either have interest A or
have interest B)

Patch by [personal profile] kareila.

Files modified:
  • bin/upgrading/en.dat
  • cgi-bin/DW/Controller/Search/Interests.pm
  • views/interests/int.tt
  • views/interests/int.tt.text
--------------------------------------------------------------------------------
diff -r bcf5b08d50e7 -r a6aa1d25ea3c bin/upgrading/en.dat
--- a/bin/upgrading/en.dat	Tue Oct 18 10:21:14 2011 -0500
+++ b/bin/upgrading/en.dat	Tue Oct 18 23:47:19 2011 +0800
@@ -1859,6 +1859,8 @@
 
 interests.error.nointerests=The selected account hasn't specified any interests.
 
+interests.error.toomany=You can't search for more than [[num]] interests at a time.
+
 interests.findsim_do.account.notallowed=Your account type doesn't let you use this tool.
 
 interests.findsim_do.nomatch=Nobody similar to [[user]].
diff -r bcf5b08d50e7 -r a6aa1d25ea3c cgi-bin/DW/Controller/Search/Interests.pm
--- a/cgi-bin/DW/Controller/Search/Interests.pm	Tue Oct 18 10:21:14 2011 -0500
+++ b/cgi-bin/DW/Controller/Search/Interests.pm	Tue Oct 18 23:47:19 2011 +0800
@@ -282,7 +282,8 @@
                 $e_int = LJ::ehtml( $interest ? $interest :
                                     substr( $check_int, 0, LJ::CMAX_SITEKEYWORD ) );
 
-                $rv->{warn_toolong} =
+                $rv->{warn_toolong} = ( $rv->{warn_toolong} ?
+                                        $rv->{warn_toolong} . "<br />" : '' ) .
                     LJ::Lang::ml( 'interests.error.longinterest',
                                   { sitename => $LJ::SITENAMESHORT,
                                     old_int => $e_int_long, new_int => $e_int,
@@ -292,21 +293,53 @@
             return $e_int;
         };
 
-        my $intarg = LJ::utf8_lc ( $args->{int} );
-        my $intid = $args->{intid} ? $args->{intid} + 0 :
-            LJ::get_sitekeyword_id( $intarg, 0 ) || 0;
-        my ( $interest, $intcount ) = LJ::get_interest( $intid );
-
-        my $check_int = $intarg || $interest;
-        if ( LJ::Hooks::run_hook( "interest_search_ignore",
-                                  query => $check_int, intid => $intid ) ) {
-            return error_ml( 'interests.error.ignored' );
+        my ( @intids, @intargs );
+        if ( $args->{intid} ) {
+            @intids = ( $args->{intid} + 0 );
+        } else {
+            @intargs = LJ::interest_string_to_list( $args->{int} );
+            @intids = map { LJ::get_sitekeyword_id( $_, 0 ) || 0 } @intargs;
         }
 
-        $rv->{e_int} = $trunc_check->( $check_int, $interest );
-        $rv->{interest} = $interest;
-        $rv->{intid} = $intid;
-        $rv->{intcount} = $intcount;
+        my $max_search = 3;
+        if ( scalar @intids > $max_search ) {
+            return error_ml( 'interests.error.toomany', { num => $max_search } );
+        }
+
+        my ( @intdata, @no_users, @not_interested );
+        my $index = 0;  # for referencing @intargs
+        my $remote_interests = $remote ? $remote->interests : {};
+
+        foreach my $intid ( @intids ) {
+            my $intarg = @intargs ? $intargs[$index++] : '';
+            my ( $interest, $intcount ) = LJ::get_interest( $intid );
+            my $check_int = $intarg || $interest;
+
+            if ( LJ::Hooks::run_hook( "interest_search_ignore",
+                                      query => $check_int,
+                                      intid => $intid ) ) {
+                return error_ml( 'interests.error.ignored' );
+            }
+
+            my $e_int = $trunc_check->( $check_int, $interest );
+            push @intdata, $e_int;
+            push @no_users, $e_int unless $intcount;
+
+            $rv->{allcount} = $intcount if scalar @intids == 1;
+
+            # check to see if the remote user already has the interest
+            push @not_interested, { int => $e_int, intid => $intid }
+                if defined $interest && ! $remote_interests->{$interest};
+        }
+
+        $rv->{interest} = join ', ', @intdata;
+        $rv->{query_count} = scalar @intdata;
+        $rv->{no_users} = join ', ', @no_users;
+        $rv->{no_users_count} = scalar @no_users;
+        $rv->{not_interested} = \@not_interested;
+
+        # if any one interest is unused, the search can't succeed
+        undef @intids if @no_users;
 
         # filtering by account type
         my @type_args = ( 'none', 'P', 'C', 'I' );
@@ -330,7 +363,16 @@
                         I => 'nocomms', F => 'circle' );
         $type_opts = { $opt_map{$type} => 1 } if defined $opt_map{$type};
 
-        my @uids = LJ::users_with_all_ints( [$intid], $type_opts );
+        my @uids = LJ::users_with_all_ints( \@intids, $type_opts );
+
+        # determine the count of the full set for comparison
+        # (already set to intcount, unless we have multiple ints)
+        if ( $opt_map{$type} ) {
+            $rv->{allcount} ||= scalar LJ::users_with_all_ints( \@intids );
+        } else {
+            # we just did the full search; count the existing list
+            $rv->{allcount} ||= scalar @uids;
+        }
 
         # limit results to 500 most recently updated journals
         if ( scalar @uids > 500 ) {
@@ -365,7 +407,7 @@
         my @ul = sort { $def_upd->($b) <=> $def_upd->($a) || $a->user cmp $b->user }
                  grep { $_ && $typefilter->( $_ ) && $should_show->( $_ ) }
                  values %$us;
-        $rv->{type_count} = scalar @ul if $intcount != scalar @ul;
+        $rv->{type_count} = scalar @ul if $rv->{allcount} != scalar @ul;
         $rv->{comm_count} = 1 if $type_opts->{nocomms};  # doesn't count
 
         if ( @ul ) {
@@ -400,10 +442,6 @@
             $rv->{data} = \@data;
         }
 
-        # check to see if the remote user already has the interest
-        $rv->{not_interested} = ! $remote->interests->{$interest}
-            if $remote && defined $interest;
-
         return DW::Template->render_template( 'interests/int.tt', $rv );
     }
 
diff -r bcf5b08d50e7 -r a6aa1d25ea3c views/interests/int.tt
--- a/views/interests/int.tt	Tue Oct 18 10:21:14 2011 -0500
+++ b/views/interests/int.tt	Tue Oct 18 23:47:19 2011 +0800
@@ -32,8 +32,7 @@
 <table summary=''><tr valign='middle'><td class='findandmodify'>
 [% 'interests.interested.in' | ml %]</td><td class='findandmodify'>
 <form method='get' action='interests'>
-<input type="text" name="int" size="20" value="
-[%- interest ? interest : e_int %]" />&nbsp;
+<input type="text" name="int" size="20" value="[% interest # escaped in the controller %]" />&nbsp;
 <input type='submit' value='[% "interests.interested.btn" | ml %]' />
 </form></td></tr>
 <tr valign='middle'><td class='findandmodify'>
@@ -43,32 +42,32 @@
 <input type="text" name="fromuser" size="20" />&nbsp;
 <input type='submit' value='[% "interests.enmasse.btn" | ml %]' />
 </form></td></tr></table>
-<h1>[% ".header" | ml(interest = e_int) %]</h1>
-<div class='typefilter'>[% '.filterlink.label' | ml %]&nbsp;
-[%- FOREACH type = type_list -%]
-    [%- link = type_link(type) -%]
-    [%- IF type != 'none' ; '&nbsp;|&nbsp;' ; END -%]
-    [%- IF link %]<a href="[% link | html %]">[% END -%]
-    [%- ".filterlink.$type" | ml -%]
-    [%- IF link ; '</a>' ; END -%]
-[%- END -%]
-</div>
-[%- IF intcount -%]
-    <p class='interestinfo'>
-    [%- IF not_interested -%]
-        [%- '.addint2' | ml(aopts = "href='$site.root/interests?mode=add&amp;intid=$intid'") -%]
+<h1>[% ".header" | ml(interest = interest) %]</h1>
+[%- IF allcount -%]
+  <div class='typefilter'>[% '.filterlink.label' | ml %]&nbsp;
+    [%- FOREACH type = type_list;
+        link = type_link(type);
+        IF type != 'none' ; '&nbsp;|&nbsp;' ; END;
+        IF link %]<a href="[% link | html %]">[% END;
+        ".filterlink.$type" | ml;
+        IF link ; '</a>' ; END;
+        END -%]
+  </div>
+    [%- FOREACH not_interested -%]
+        <p class='interestinfo'>
+        [%- '.addint3' | ml(int = int, aopts = "href='$site.root/interests?mode=add&amp;intid=$intid'") -%]</p>
     [%- END -%]
-    [% '.morestuff2' | ml(aopts = "href='$site.root/interests'") %]</p>
     [%- UNLESS comm_count -%]
         <p class='interestinfo'>
-        [%- '.nocomms' | ml(aopts = "href='$site.root/community/create'",
-                            int = e_int) %]</p>
+        [%- '.nocomms2' | ml(aopts = "href='$site.root/community/create'", num = query_count) %]</p>
     [%- END -%]
+    <p class='interestinfo'>
+    [% '.morestuff2' | ml(aopts = "href='$site.root/interests'") %]</p>
     <p class='matches'><b>
     [%- IF type_count -%]
-        [% '.filtered' | ml(num = intcount, count = type_count) %]</p>
+        [% '.filtered' | ml(num = allcount, count = type_count) %]</p>
     [%- ELSE -%]
-        [% '.matches2' | ml(num = intcount) %]
+        [% '.matches2' | ml(num = allcount) %]
     [%- END -%]
     </b></p>
     [%- IF data -%]
@@ -95,10 +94,17 @@
     [%- END -%]
 [%- ELSE -%]
     <p class='interestinfo'>
-    [%- '.nocomms' | ml(aopts = "href='$site.root/community/create'",
-                        int = e_int) %]</p>
+    [%- '.nocomms2' | ml(aopts = "href='$site.root/community/create'", num = query_count) %]</p>
     <p class='interestinfo'>
-    [%- '.nousers' | ml(int = e_int,
-        aopts_add = "href='$site.root/interests?mode=addnew&amp;keyword=$e_int'",
-        aopts_int = "href='$site.root/interests'") %]</p>
+    [%- IF no_users -%]
+        [%- '.nousers2' | ml(aopts = "href='$site.root/interests?mode=addnew&amp;keyword=$no_users'", num = no_users_count) %]</p>
+    [%- ELSE -%]
+        [%- '.notall' | ml %]</p>
+        [%- FOREACH not_interested -%]
+            <p class='interestinfo'>
+            [%- '.addint3' | ml(int = int, aopts = "href='$site.root/interests?mode=add&amp;intid=$intid'") -%]</p>
+        [%- END -%]
+    [%- END -%]
+    <p class='interestinfo'>
+    [% '.morestuff2' | ml(aopts = "href='$site.root/interests'") %]</p>
 [%- END -%]
diff -r bcf5b08d50e7 -r a6aa1d25ea3c views/interests/int.tt.text
--- a/views/interests/int.tt.text	Tue Oct 18 10:21:14 2011 -0500
+++ b/views/interests/int.tt.text	Tue Oct 18 23:47:19 2011 +0800
@@ -1,5 +1,5 @@
 ;; -*- coding: utf-8 -*-
-.addint2=If you're also interested in this, would you like to be <a [[aopts]]>added to this list</a>?
+.addint3=If you're also interested in "<b>[[int]]</b>", would you like to <a [[aopts]]>add it to your profile</a>?
 
 .filtered=[[num]] [[?num|match|matches]], showing [[count]] [[?count|result|results]]:
 
@@ -25,10 +25,12 @@
 
 .morestuff2=You can find more fun stuff on the <a [[aopts]]>interests page</a>.
 
-.nocomms=There are no communities interested in "<b>[[int]]</b>." You can <a [[aopts]]>create one</a>!
+.nocomms2=There are no communities matching the [[?num|interest|interests]] you specified, but you can <a [[aopts]]>create one</a>!
 
 .nomatch=No matching users for the specified account type. <a href="[[link]]">View all accounts with this interest.</a>
 
-.nousers=There are no users interested in "<b>[[int]]</b>". If you are interested in this, <a [[aopts_add]]>click here to add the interest to your profile</a>. More fun stuff can be found on the <a [[aopts_int]]>interests page</a>.
+.notall=There are no users matching all of the interests you specified.  You may want to modify your search.
+
+.nousers2=No one currently has [[num]] of the interests you're searching for. If you're interested, <a [[aopts]]>click here to add [[?num|the new interest|all of the new interests]] to your profile</a>.
 
 .title=Interests
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org