fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2010-12-16 06:17 pm

[dw-free] convert interests.bml to TT

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

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

Convert from BML files to TT / controller. Modernize, make cleaner.

Patch by [personal profile] kareila.

Files modified:
  • bin/upgrading/en.dat
  • cgi-bin/DW/Controller/Search/Interests.pm
  • cgi-bin/ljfeed.pl
  • htdocs/interests.bml
  • htdocs/interests.bml.text
  • views/interests/add.tt
  • views/interests/add.tt.text
  • views/interests/enmasse.tt
  • views/interests/enmasse.tt.text
  • views/interests/enmasse_do.tt
  • views/interests/enmasse_do.tt.text
  • views/interests/findsim.tt
  • views/interests/findsim.tt.text
  • views/interests/index.tt
  • views/interests/index.tt.text
  • views/interests/int.tt
  • views/interests/int.tt.text
  • views/interests/popular.tt
  • views/interests/popular.tt.text
--------------------------------------------------------------------------------
diff -r 11ed0d63e6fd -r 75f310215036 bin/upgrading/en.dat
--- a/bin/upgrading/en.dat	Fri Dec 17 01:58:35 2010 +0800
+++ b/bin/upgrading/en.dat	Fri Dec 17 02:17:18 2010 +0800
@@ -2147,6 +2147,51 @@ inbox.nomessages=No Messages
 
 inbox.refresh=Refresh
 
+interests.add.toomany=You already have [[maxinterests]] interests defined.
+
+interests.enmasse.btn=Show List
+
+interests.enmasse.intro=Modify your interests based on those of:
+
+interests.error.ignored=Sorry, we're unable to help you find users matching the interests you've provided.
+
+interests.error.longinterest=As [[sitename]] does not support interests longer than [[maxlen]] characters, your search for <b>[[old_int]]</b> was converted into a search for <b>[[new_int]]</b> instead.
+
+interests.error.nointerests=The selected account hasn't specified any interests.
+
+interests.findsim_do.account.notallowed=Your account type doesn't let you use this tool.
+
+interests.findsim_do.nomatch=Nobody similar to [[user]].
+
+interests.findsim_do.notdefined=[[user]] has no interests defined.
+
+interests.interested.btn=Find
+
+interests.interested.in=Find people interested in:
+
+interests.popular.disabled=The popular interests feature is unavailable.
+
+interests.results.added=You've successfully added the selected interests to your interests list.
+
+interests.results.both=Success. You've successfully added the selected interests to your interests list and removed those you deselected.
+
+interests.results.deleted=You successfully removed the interests you deselected from your interests list.
+
+interests.results.del_and_toomany<<
+You successfully removed the interests you deselected, but you didn't add
+any new interests because you can only list a maximum of [[intcount]]
+interests. You may wish to go back and select fewer interests to add or
+delete some old interests.
+.
+
+interests.results.nothing=You didn't make any changes.
+
+interests.results.toomany<<
+You didn't add any of your selected interests because you can only list
+a maximum of [[intcount]] interests. You may wish to go back and select
+fewer interests to add or delete some old interests.
+.
+
 invitecodes.userclass.lucky=Lucky users
 
 label.screening.all=All comments
diff -r 11ed0d63e6fd -r 75f310215036 cgi-bin/DW/Controller/Search/Interests.pm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/DW/Controller/Search/Interests.pm	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,342 @@
+#!/usr/bin/perl
+#
+# DW::Controller::Search::Interests
+#
+# Interest search, based on code from LiveJournal.
+#
+# Authors:
+#      Jen Griffin <kareila@livejournal.com>
+#
+# Copyright (c) 2010 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'.
+#
+
+package DW::Controller::Search::Interests;
+
+use strict;
+use warnings;
+
+use DW::Routing;
+use DW::Template;
+use DW::Controller;
+use LJ::Constants;
+
+DW::Routing->register_string( '/interests', \&interest_handler, app => 1 );
+
+sub interest_handler {
+    my $r = DW::Request->get;
+    my $did_post = LJ::did_post();
+    my $args = $did_post ? $r->post_args : $r->get_args;
+    return error_ml( 'bml.badinput.body' ) unless LJ::text_in( $args );
+    return error_ml( 'error.invalidform' )
+        if $did_post && ! LJ::check_form_auth( $args->{lj_form_auth} );
+
+    # do mode logic first, to save typing later
+    my $mode = '';
+    $mode = 'int' if $args->{int} || $args->{intid};
+    $mode = 'popular' if $args->{view} && $args->{view} eq "popular";
+    if ( $args->{mode} ) {
+        $mode = 'add' if $args->{mode} eq "add" && $args->{intid};
+        $mode = 'addnew' if $args->{mode} eq "addnew" && $args->{keyword};
+        $mode = 'findsim_do' if !$did_post && $args->{mode} eq "findsim_do";
+        $mode = 'enmasse'    if !$did_post && $args->{mode} eq "enmasse";
+        $mode = 'enmasse_do' if  $did_post && $args->{mode} eq "enmasse_do";
+    }
+
+    # check whether authentication is needed or authas is allowed
+    # default is to allow anonymous users, except for certain modes
+    my ( $anon, $authas ) = ( $mode eq "add" ? 0 : 1, 0 );
+    ( $anon, $authas ) = ( 0, 1 )
+        if $mode eq ( $did_post ? "enmasse_do" : "enmasse" );
+
+    my ( $ok, $rv ) = controller( anonymous => $anon, authas => $authas );
+    return $rv unless $ok;
+
+    my $remote = $rv->{remote};
+    my $maxinterests = $remote ? $remote->count_max_interests : 0;
+    $rv->{can_use_popular} = LJ::is_enabled( 'interests-popular' );
+    $rv->{can_use_findsim} = LJ::is_enabled( 'interests-findsim' )
+        && $remote && $remote->can_find_similar;
+
+    # now do argument checking and database work for each mode
+
+    if ( $mode eq 'popular' ) {
+        return error_ml( 'interests.popular.disabled' )
+            unless $rv->{can_use_popular};
+        $rv->{no_text_mode} = 1
+            unless $args->{mode} && $args->{mode} eq 'text';
+
+        my $rows = LJ::Stats::get_popular_interests();
+        my %interests;
+        foreach my $int_array ( @$rows ) {
+            my ( $int, $count ) = @$int_array;
+            $interests{$int} = { eint  => LJ::ehtml( $int ),
+                                 url   => "/interests?int=" . LJ::eurl( $int ),
+                                 value => $count };
+        }
+        $rv->{pop_cloud} = LJ::tag_cloud( \%interests );
+        $rv->{pop_ints} = [ sort { $b->{value} <=> $a->{value} } values %interests ]
+            if %interests;
+        return DW::Template->render_template( 'interests/popular.tt', $rv );
+    }
+
+    if ( $mode eq 'add' || $mode eq 'addnew' ) {
+        my $rints = $remote->get_interests();
+        return error_ml( "interests.add.toomany",
+                         { maxinterests => $maxinterests } )
+            if scalar( @$rints ) >= $maxinterests;
+
+        my $intid;
+        if ( $mode eq "add" ) {
+            # adding an existing interest, so we have an intid to work with
+            $intid = $args->{intid} + 0;
+        } else {
+            # adding a new interest
+            my @validate = LJ::validate_interest_list( $args->{keyword} );
+            $intid = LJ::get_sitekeyword_id( $validate[0] ) if @validate;
+        }
+
+        return error_ml( 'error.invalidform' ) unless $intid;
+
+        # force them to either come from the interests page, or have posted the request.
+        # if both fail, ask them to confirm with a post form.
+
+        unless ( $did_post || LJ::check_referer( '/interests' ) ) {
+            my $int = LJ::get_interest( $intid );
+            LJ::text_out( \$int );
+            $rv->{need_post} = { int => $int, intid => $intid };
+        } else {  # let the user add the interest
+            $remote->interest_update( add => [$intid] );
+        }
+        return DW::Template->render_template( 'interests/add.tt', $rv );
+    }
+
+    if ( $mode eq 'findsim_do' ) {
+        return error_ml( 'error.tempdisabled' )
+            unless LJ::is_enabled( 'interests-findsim' );
+        return error_ml( 'interests.findsim_do.account.notallowed' )
+            unless $rv->{can_use_findsim};
+        my $u = LJ::load_user( $args->{user} )
+            or return error_ml( 'error.username_notfound' );
+
+        my $dbr = LJ::get_db_reader();
+        my $sth = $dbr->prepare( "SELECT i.intid, i.intcount " .
+                                 "FROM userinterests ui, interests i " .
+                                 "WHERE ui.userid=? AND ui.intid=i.intid" );
+        $sth->execute( $u->userid );
+
+        my ( @ints, %intcount, %pt_count, %pt_weight );
+        while ( my ( $intid, $count ) = $sth->fetchrow_array ) {
+            push @ints, $intid;
+            $intcount{$intid} = $count || 1;
+        }
+        return error_ml( 'interests.findsim_do.notdefined',
+                         { user => $u->ljuser_display } )
+            unless @ints;
+
+        # the magic's in this limit clause.  that's what makes this work.
+        # perfect results?  no.  but who cares if somebody that lists "music"
+        # or "reading" doesn't get an extra point towards matching you.
+        # we care about more unique interests.
+        $sth = $dbr->prepare( "SELECT userid FROM userinterests WHERE intid=? LIMIT 500" );
+        foreach my $int ( @ints ) {
+            $sth->execute( $int );
+            while ( my $uid = $sth->fetchrow_array ) {
+                next if $uid == $u->userid;
+                $pt_weight{$uid} += ( 1 / log( $intcount{$int} + 1 ) );
+                $pt_count{$uid}++;
+            }
+        }
+
+        my %magic;  # balanced points
+        $magic{$_} = $pt_weight{$_} * 10 + $pt_count{$_}
+            foreach keys %pt_count;
+        my @matches = sort { $magic{$b} <=> $magic{$a} } keys %magic;
+        @matches = @matches[ 0 .. ( $maxinterests - 1 ) ]
+            if scalar( @matches ) > $maxinterests;
+        return error_ml( 'interests.findsim_do.nomatch',
+                         { user => $u->ljuser_display } )
+            unless @matches;
+
+        # prepare userid => username hash
+        $sth = $dbr->prepare( "SELECT userid, user FROM useridmap WHERE userid IN (" .
+                              join( ",", @matches ) . ")" );
+        $sth->execute;
+        my %username;
+        while ( my ( $id, $name ) = $sth->fetchrow_array ) {
+            $username{$id} = $name;
+        }
+
+        my $count = 1;
+        my $data = [];
+        foreach my $uid ( @matches ) {
+            push @$data, { count => $count++,
+                           user  => LJ::ljuser( $username{$uid} ),
+                           magic => sprintf( "%.3f", $magic{$uid} ) };
+        }
+        $rv->{findsim_u} = $u;
+        $rv->{findsim_data} = $data;
+        return DW::Template->render_template( 'interests/findsim.tt', $rv );
+    }
+
+    if ( $mode eq 'enmasse' ) {
+        my $u = $rv->{u};
+        my $username = $u->user;
+        my $altauthas = $remote->user ne $username;
+        $rv->{getextra} = $altauthas ? "?authas=$username" : '';
+
+        my $fromu = LJ::load_user( $args->{fromuser} || $username )
+            or return error_ml( 'error.username_notfound' );
+        $rv->{fromu} = $fromu;
+
+        my %uint;
+        my %fromint = %{ $fromu->interests } or
+            return error_ml( 'interests.error.nointerests' );
+        $rv->{allintids} = join ( ",", values %fromint );
+
+        if ( $u->equals( $fromu ) ) {
+            %uint = %fromint;
+            $rv->{enmasse_body} = '.enmasse.body.you';
+        } else {
+            %uint = %{ $u->interests };
+            my $other = $altauthas ? 'other_authas' : 'other';
+            $rv->{enmasse_body} = ".enmasse.body.$other";
+        }
+
+        my @checkdata;
+        foreach my $fint ( sort keys %fromint ) {
+            push @checkdata, { checkid => "int_$fromint{$fint}",
+                               is_checked => $uint{ $fint } ? 1 : 0,
+                               int => $fint };
+        }
+        $rv->{enmasse_data} = \@checkdata;
+        return DW::Template->render_template( 'interests/enmasse.tt', $rv );
+    }
+
+    if ( $mode eq 'enmasse_do' ) {
+        my $u = $rv->{u};
+
+        # $args is actually an object so we want a plain hashref
+        my $argints = {};
+        foreach my $key ( keys %$args ) {
+            $argints->{$key} = $args->{$key} if $key =~ /^int_\d+$/;
+        }
+
+        my @fromints = map { $_ + 0 }
+                       split /\s*,\s*/, $args->{allintids};
+        my $sync = $u->sync_interests( $argints, @fromints );
+
+        my $result_ml = 'interests.results.';
+        if ( $sync->{deleted} ) {
+            $result_ml .= $sync->{added}   ? 'both' :
+                          $sync->{toomany} ? 'del_and_toomany' : 'deleted';
+        } else {
+            $result_ml .= $sync->{added}   ? 'added' :
+                          $sync->{toomany} ? 'toomany' : 'nothing';
+        }
+        $rv->{enmasse_do_result} = $result_ml;
+        $rv->{toomany} = $sync->{toomany} || 0;
+        $rv->{fromu} = LJ::load_user( $args->{fromuser} )
+            unless !$args->{fromuser} or $u->user eq $args->{fromuser};
+        return DW::Template->render_template( 'interests/enmasse_do.tt', $rv );
+    }
+
+    if ( $mode eq '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 $e_int = LJ::ehtml( $check_int );
+        # determine whether the interest is too long:
+        # 1. if the interest already exists, a long interest will result in $check_int and $interest not matching
+        # 2. if it didn't already exist, we fall back on just checking the length of $check_int
+        if ( ( $interest && $check_int ne $interest ) || length( $check_int ) > LJ::CMAX_SITEKEYWORD ) {
+            # if the searched-for interest is too long, we use the short version from here on
+            my $e_int_long = $e_int;
+            $e_int = LJ::ehtml( $interest ? $interest : substr( $check_int, 0, LJ::CMAX_SITEKEYWORD ) );
+            $rv->{warn_toolong} =
+                LJ::Lang::ml( 'interests.error.longinterest',
+                              { sitename => $LJ::SITENAMESHORT,
+                                old_int => $e_int_long, new_int => $e_int,
+                                maxlen => LJ::CMAX_SITEKEYWORD } );
+        }
+        $rv->{e_int} = $e_int;
+        $rv->{interest} = $interest;
+        $rv->{intid} = $intid;
+        $rv->{intcount} = $intcount;
+
+        my $dbr = LJ::get_db_reader();
+        my $int_query = sub {
+            my $i = shift;  # comminterests or userinterests
+            my $LIMIT = 500;
+            my $q = "SELECT $i.userid FROM $i, userusage
+                     WHERE $i.intid = ? AND $i.userid = userusage.userid
+                     ORDER BY userusage.timeupdate DESC LIMIT $LIMIT";
+            my $uref = $dbr->selectall_arrayref( $q, undef, $intid );
+            return LJ::load_userids( map { $_->[0] } @$uref );
+            # can't trust LJ::load_userids to maintain sort order
+        };
+
+        my $should_show = sub {
+            return $_[0]->should_show_in_search_results( for => $remote );
+        };
+
+        # community results
+        if ( LJ::is_enabled( 'interests-community' ) ) {
+            my $us = $int_query->( "comminterests" );
+            my $updated = LJ::get_timeupdate_multi( keys %$us );
+            my @cl = sort { $updated->{$b->id} <=> $updated->{$a->id} || $a->user cmp $b->user }
+                     grep { $_ && $_->is_visible && $should_show->( $_ ) } values %$us;
+            $rv->{int_comms} = { count => scalar @cl, data => [] };
+            foreach ( @cl ) {
+                my $updated = $updated->{$_->id}
+                            ? LJ::diff_ago_text( $updated->{$_->id} )
+                            : undef;
+                my $prop_theme = $_->prop("comm_theme");
+                my $theme = LJ::is_enabled('community_themes') && $prop_theme
+                          ? LJ::ehtml( $prop_theme )
+                          : undef;
+                push @{ $rv->{int_comms}->{data} },
+                      { u => $_, updated => $updated, theme => $theme };
+            }
+        }
+
+        # user results
+        my $us = $int_query->( "userinterests" );
+        my @ul = grep { $_
+                        && $_->is_visible                # visible users
+                        && ! $_->is_community            # not communities
+                        && ( ! $_->age || $_->age > 13 ) # are over 13
+                        && $should_show->( $_ )          # and should show to the remote user
+                      } values %$us;
+        my $navbar;
+        my $results =
+            LJ::user_search_display( users      => \@ul,
+                                     timesort   => 1,
+                                     perpage    => 50,
+                                     curpage    => exists $args->{page} ?
+                                                   $args->{page} : 1,
+                                     navbar     => \$navbar );
+
+        $rv->{int_users} = { count => scalar( @ul ), navbar => $navbar,
+                             results => $results };
+        return DW::Template->render_template( 'interests/int.tt', $rv );
+    }
+
+
+    # if we got to this point, we need to render the default template
+    return DW::Template->render_template( 'interests/index.tt', $rv );
+}
+
+
+1;
diff -r 11ed0d63e6fd -r 75f310215036 cgi-bin/ljfeed.pl
--- a/cgi-bin/ljfeed.pl	Fri Dec 17 01:58:35 2010 +0800
+++ b/cgi-bin/ljfeed.pl	Fri Dec 17 02:17:18 2010 +0800
@@ -757,7 +757,7 @@ sub create_view_foaf {
     foreach my $int (@$intu) {
         LJ::text_out(\$int->[1]); # 1==interest
         $ret .= "    <foaf:interest dc:title=\"". LJ::exml($int->[1]) . "\" " .
-                "rdf:resource=\"$LJ::SITEROOT/interests.bml?int=" . LJ::eurl($int->[1]) . "\" />\n";
+                "rdf:resource=\"$LJ::SITEROOT/interests?int=" . LJ::eurl($int->[1]) . "\" />\n";
     }
 
     # check if the user has a "FOAF-knows" group
diff -r 11ed0d63e6fd -r 75f310215036 htdocs/interests.bml
--- a/htdocs/interests.bml	Fri Dec 17 01:58:35 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,526 +0,0 @@
-<?_c
-# 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.
-_c?>
-<?page
-title=><?_ml .title _ml?>
-head<=
-<style>
-    div.tagcloud a { text-decoration: none; }
-    ul.contentlist li { padding-bottom: 3px; }
-</style>
-<=head
-
-body<=
-<?_code
-{
-    use strict;
-    use vars qw(%GET %POST);
-
-    LJ::need_res( qw( stc/interests.css ) );
-
-    LJ::set_active_crumb('searchinterests');
-
-    return "<?badinput?>"
-        unless LJ::text_in(\%GET) && LJ::text_in(\%POST);
-
-    my $did_post = LJ::did_post();
-
-    my $remote = LJ::get_remote();
-
-    my $maxinterests = $remote ? $remote->count_max_interests : 0;
-
-    my $table = sub { $_[0]->is_community ? 'comminterests' : 'userinterests' };
-
-    if (!$did_post && $GET{'view'} eq "popular") {
-        return $ML{'.popular.disabled'} unless LJ::is_enabled('interests-popular');
-        my $ret = '';
-        $ret .= "<?h1 $ML{'.popular.head'} h1?><?p $ML{'.popular.text'} ";
-
-        $ret .= BML::ml('.popular.textmode', { 'aopts' => "href='$LJ::SITEROOT/interests?view=popular&mode=text'" })
-            unless $GET{mode} eq 'text';
-
-        $ret .= " p?>";
-
-        my $rows = LJ::Stats::get_popular_interests();
-        return $ML{'.error.nodata'} unless @$rows;
-
-        my %interests;
-        foreach my $int_array (@$rows)
-        {
-            my ($int, $count) = @$int_array;
-            $interests{$int} = {
-                                int   => $int,
-                                eint  => LJ::ehtml($int),
-                                url   => "/interests?int=" . LJ::eurl($int),
-                                value => $count,
-                                };
-        }
-
-        unless ($GET{'mode'} eq 'text') {
-            $ret .= LJ::tag_cloud(\%interests);
-        } else {
-            $ret .= "<p><table><tr><th>$ML{'.interest'}</th><th>$ML{'.count'}</th></tr>";
-            foreach my $i (sort { $b->{value} <=> $a->{value} } values %interests) {
-                $ret .= "<tr><td><a href='$i->{url}'>$i->{eint}</a></td><td>$i->{value}</td></tr>";
-            }
-            $ret .= "</table>";
-        }
-
-        return $ret;
-    }
-
-    my $formargs = $did_post ? \%POST : \%GET;
-    if ( $formargs->{mode} &&
-         ( $formargs->{mode} eq "add" && $formargs->{intid} ||
-           $formargs->{mode} eq "addnew" && $formargs->{keyword} ) ) {
-
-        my $ret = '';
-        unless ( $remote ) {
-            $ret .= "<?h1 $ML{'Error'} h1?><?p $ML{'.error.add.mustlogin'} p?>";
-            return $ret;
-        }
-
-        # account for the case where we bypass the POST due to the referer
-        return $ML{'error.invalidform'} unless !$did_post || LJ::check_form_auth();
-
-        my $rints = $remote->get_interests();
-        my $count = scalar( @$rints );
-
-        if ($count >= $maxinterests) {
-            $ret .= "<?h1 $ML{'.add.toomany.head'} h1?><?p " .BML::ml( ".add.toomany.text", { maxinterests => $maxinterests } ) ." p?>";
-            return $ret;
-        }
-
-        my $intid;
-        if ( $formargs->{mode} eq "add" ) {
-            # adding an existing interest, so we have an intid to work with
-            $intid = $formargs->{intid} + 0;
-        } else {
-            # adding a new interest
-            my @validate = LJ::validate_interest_list( $formargs->{keyword} );
-            $intid = LJ::get_sitekeyword_id( $validate[0] ) if @validate;
-        }
-
-        return $ML{'error.invalidform'} unless $intid;
-
-        # force them to either come from the interests page, or have posted the request.
-        # if both fail, ask them to confirm with a post form.
-
-        unless ( $did_post || LJ::check_referer('/interests.bml') )
-        {
-            my $int = LJ::get_interest( $intid );
-            LJ::text_out(\$int);
-
-            $ret .= "<?h1 $ML{'.add.confirm.head'} h1?>";
-            $ret .= "<?p " . BML::ml(".add.confirm.text", {'interest' => $int});
-            $ret .= "<form method='post' action='interests'><div align='center'>";
-            $ret .= LJ::html_hidden('mode' => 'add', 'intid' => $intid);
-            $ret .= LJ::html_submit(undef, BML::ml(".add.btn.text", {'interest' => $int}));
-            $ret .= LJ::form_auth();
-            $ret .= "</div></form> p?>";
-            return $ret;
-        }
-
-        $remote->interest_update( add => [$intid] );
-
-        my $profile_url = $remote->profile_url;
-        $ret .= "<?h1 $ML{'.add.added.head'} h1?><?p $ML{'.add.added.text'} p?>" .
-            "<ul><li><a href='$LJ::SITEROOT/interests'>$ML{'.add.added.interestspage'}</a></li>" .
-            "<li><a href='$LJ::SITEROOT/manage/profile/#interests'>$ML{'.add.added.editinterests'}</a></li>" .
-            "<li><a href='$profile_url'>$ML{'.add.added.viewprofile'}</a></li>" .
-            "<li><a href='$LJ::SITEROOT/manage/profile'>$ML{'.add.added.editprofile'}</a></li></ul>";
-        return $ret;
-    }
-
-    if (!$did_post && $GET{'mode'} eq "findsim_do") {
-        return $ML{'error.tempdisabled'} unless LJ::is_enabled('interests-findsim');
-
-        return $ML{'.findsim_do.account.notallowed'} unless $remote && $remote->can_find_similar;
-
-        my $ret = "";
-        my $u = LJ::load_user($GET{'user'});
-        return "<?h1 $ML{'Error'} h1?><?p $ML{'error.username_notfound'} p?>" unless $u;
-
-        my @ints;
-        my %intcount;
-        my $dbr = LJ::get_db_reader();
-        my $sth = $dbr->prepare("SELECT i.intid, i.intcount FROM userinterests ui, interests i ".
-                                "WHERE ui.userid=? AND ui.intid=i.intid");
-        $sth->execute( $u->userid );
-        while (my ($intid, $count) = $sth->fetchrow_array) {
-            push @ints, $intid;
-            $intcount{$intid} = $count || 1;
-        }
-        unless (@ints) {
-            my $msg = BML::ml('.findsim_do.notdefined', { 'user' => LJ::ljuser($u) });
-            return "<?h1 $ML{'Error'} h1?><?p $msg p?>";
-        }
-
-        my %pt_count;
-        my %pt_weight;
-        foreach my $int (@ints) {
-            # the magic's in this limit clause.  that's what makes this work.  perfect 
-            # results?  no.  but who cares if somebody that lists "music" or "reading"
-            # doesn't get an extra point towards matching you.  we care about more unique interests.
-            my $sth = $dbr->prepare("SELECT userid FROM userinterests WHERE intid=? LIMIT 500");
-            $sth->execute($int);
-            while (my $uid = $sth->fetchrow_array) {
-                next if $uid == $u->userid;
-                $pt_weight{$uid} += (1 / log($intcount{$int}+1));
-                $pt_count{$uid}++;
-            }
-        }
-
-        my %magic;  # balanced points
-        foreach (keys %pt_count) {
-            $magic{$_} = $pt_weight{$_}*10 + $pt_count{$_};
-        }
-
-        my @matches = sort { $magic{$b} <=> $magic{$a} } keys %magic;
-        if (@matches > $maxinterests) { @matches = @matches[0..( $maxinterests - 1 )]; }
-        my $sth = $dbr->prepare("SELECT userid, user FROM useridmap WHERE userid IN (" . join(",",@matches) . ")");
-        $sth->execute;
-        my %username;
-        while (my ($id, $name) = $sth->fetchrow_array) {
-            $username{$id} = $name;
-        }
-
-        unless (@matches) {
-            return "<?h1 $ML{'.findsim_do.nomatch.head'} h1?><?p " .BML::ml(".findsim_do.nomatch.text", {'user' => LJ::ljuser($u)}) ." p?>";
-        }
-
-        $ret .= "<?h1 $ML{'.findsim_do.similar.head'} h1?><?p " .BML::ml(".findsim_do.similar.text", {'user' => LJ::ljuser($u)}) ." p?>";
-
-        $ret .= "<p><table cellpadding='3'><tr valign='bottom'><th>#</th><th width='250'>$ML{'.findsim_do.user'}</th><td><b>$ML{'.findsim_do.magic'}</b></td></tr>";
-        my $count;
-        foreach my $uid (@matches)
-        {
-            $count++;
-            $ret .= "<tr><td>$count</td><td>";
-            $ret .= LJ::ljuser($username{$uid});
-            $ret .= sprintf("</td><td>%.3f</td></tr>", $magic{$uid});
-        }
-        $ret .= "</table></p>";
-
-        $ret .= "<?h1 $ML{'.findsim_do.magic.head'} h1?><?p $ML{'.findsim_do.magic.text'} p?>";
-        return $ret;
-    }
-
-    if (!$did_post && $GET{'mode'} eq "enmasse")
-    {
-        return "<?needlogin?>" unless $remote;
-
-        my $authas = $GET{'authas'} || $remote->{'user'};
-        my $u = LJ::get_authas_user($authas);
-        return LJ::bad_input(BML::ml('.error.enmasse.noaccess', {'user' => LJ::ljuser($authas)})) unless $u;
-
-        my $altauthas = $remote->{'user'} ne $u->{'user'};
-        my $getextra = $altauthas ? "?authas=$u->{'user'}" : '';
-
-        my $userid = $u->userid;
-        my $username = $u->user;
-        my $fromu = LJ::load_user($GET{'fromuser'} || $username);
-
-        return "<?h1 $ML{'Error'} h1?><?p $ML{'.error.nointerests'} p?>" unless $fromu;
-
-        my %uint;
-
-        my %fromint;
-        my $fints = $fromu->get_interests();
-        foreach (@$fints) {
-            $fromint{$_->[1]} = $_->[0]+0;
-        }
-
-        return "<?h1 $ML{'Error'} h1?><?p $ML{'.error.nointerests'} p?>" unless %fromint;
-
-        my $ret = "<?p <form method='get' action='interests'>";
-        $ret .= LJ::html_hidden(mode => 'enmasse', fromuser => $fromu->{'user'});
-        $ret .= LJ::make_authas_select($remote, { 'authas' => $GET{'authas'} });
-        $ret .= "</form> p?><form method='post' action='interests$getextra'>";
-        $ret .= "<?h1 $ML{'.enmasse.header'} h1?><?p ";
-
-        if ( $u->equals( $fromu ) ) {
-            %uint = %fromint;
-            $ret .= $ML{'.enmasse.body.you'};
-        } else {
-            my $in = join (",", map { $fromint{$_} } keys %fromint);
-
-            my $uints = $u->get_interests();
-            foreach (@$uints) {
-                $uint{$_->[1]} = $_->[0];
-            }
-
-            if ($altauthas) {
-                $ret .= BML::ml('.enmasse.body.other_authas', { 'user' => LJ::ljuser($fromu),
-                                                                'target' => LJ::ljuser($u) });
-            } else {
-                $ret .= BML::ml('.enmasse.body.other', { 'user' => LJ::ljuser($fromu) });
-            }
-        }
-
-        $ret .= " p?><div style='margin-left: 40px; margin-top: 20px;'>";
-        $ret .= "<table summary='' cellpadding='0' cellspacing='0' border='0' width='100%'>";
-        my @fromintsorted = sort keys %fromint;
-        my $cols = 3;
-        my $rows = int((scalar(@fromintsorted) + $cols - 1) / $cols);
-        for (my $i = 0; $i < $rows; $i++) {
-            $ret .= "<tr valign='middle'>";
-            for (my $j = 0; $j < $cols; $j++) {
-                my $index = $rows * $j + $i;
-                if ($index < scalar(@fromintsorted)) {
-                    my $checked = $uint{$fromintsorted[$index]} ? 1 : undef;
-                    $ret .= "<td align='left' nowrap='nowrap'>";
-                    $ret .= LJ::html_check({name     => "int_$fromint{$fromintsorted[$index]}",
-                                            id       => "int_$fromint{$fromintsorted[$index]}",
-                                            selected => $checked,
-                                            value    => 1});
-                    my $bold1 = $checked ? "<strong>" : "";
-                    my $bold2 = $checked ? "</strong>" : "";
-                    $ret .= "&nbsp;<label for='int_$fromint{$fromintsorted[$index]}'>";
-                    $ret .= "$bold1$fromintsorted[$index]$bold2</label></td>";
-                } else {
-                    $ret .= "<td></td>";
-                }
-            }
-            $ret .= "</tr>";
-        }
-        $ret .= "</table></div>";
-
-        $ret .= LJ::html_hidden('mode',        'enmasse_do');
-        $ret .= LJ::html_hidden('fromuser',    $fromu->{'user'});
-        $ret .= LJ::html_hidden('allintids',   join (",", values %fromint));
-
-        $ret .= "<?h1 $ML{'.finished.header'} h1?><?p $ML{'.finished.about'} p?><?standout ";
-        $ret .= LJ::html_submit(undef, $ML{'.finished.save_button'}) . " standout?></form>";
-
-        return $ret;
-    }
-
-    if ($did_post && $POST{'mode'} eq "enmasse_do") {
-        return "<?needlogin?>" unless $remote;
-
-        my $authas = $GET{'authas'} || $remote->{'user'};
-        my $u = LJ::get_authas_user($authas);
-        return LJ::bad_input($ML{'.error.noauth'}) unless $u;
-
-        my @fromints = map { $_+0 } split (/\s*,\s*/, $POST{'allintids'});
-        my $sync = $u->sync_interests( \%POST, @fromints );
-
-        my $ret = "<?h1 $ML{'.results.header'} h1?><?p ";
-        if ($sync->{deleted}) {
-            $ret .= $sync->{added}   ? $ML{'.results.both'}
-                  : $sync->{toomany} ? BML::ml('.results.del_and_toomany', {'intcount' => $maxinterests})
-                  : $ML{'.results.deleted'};
-        } else {
-            $ret .= $sync->{added}   ? $ML{'.results.added'}
-                  : $sync->{toomany} ? BML::ml('.results.toomany', {'intcount' => $maxinterests})
-                  : $ML{'.results.nothing'};
-        }
-
-        my $profile_url = $u->profile_url;
-        my $u_other = LJ::load_user($POST{'fromuser'});
-        my $profile_url_other = $u_other ? $u_other->profile_url : "";
-        
-        $ret .= " p?><?p " . BML::ml('.results.message2', {'aopts' => "href='$profile_url'"});
-        $ret .= " " . BML::ml('.results.goback2', {'user' => LJ::ljuser($POST{'fromuser'}), 'aopts' => "href='$profile_url_other'"})
-            if ($POST{'fromuser'} ne "" && $POST{'fromuser'} ne $u->{'user'});
-        $ret .= " p?>";
-        return $ret;
-    }
-
-    if ( ! $did_post && ( $GET{intid} || $GET{int} ) ) {
-        my $intid = $GET{intid} ? $GET{intid} :
-            LJ::get_sitekeyword_id( $GET{int}, 0 );
-        my ( $interest, $intcount ) = LJ::get_interest( $intid );
-        
-        my $check_int = $GET{int} || $interest;
-        if (LJ::Hooks::run_hook("interest_search_ignore", query => $check_int, intid => $intid)) {
-            return "<?h1 $ML{'Error'} h1?><?p $ML{'.error.ignored'} p?>";
-        }
-
-        my $e_int = LJ::ehtml( $check_int );
-
-        my $ret = '';
-
-        # determine whether the interest is too long:
-        # 1. if the interest already exists, a long interest will result in $check_int and $interest not matching
-        # 2. if it didn't already exist, we fall back on just checking the length of $check_int
-        if ( ( $interest && $check_int ne $interest ) || length( $check_int ) > LJ::CMAX_SITEKEYWORD ) {
-
-            # if the searched-for interest is too long, we use the short version from here on
-            my $e_int_long = $e_int;
-            $e_int = LJ::ehtml( $interest ? $interest : substr( $check_int, 0, LJ::CMAX_SITEKEYWORD ) );
-            $ret .= "<?p " . BML::ml( '.error.longinterest', { sitename => $LJ::SITENAMESHORT, old_int => $e_int_long, new_int => $e_int, maxlen => LJ::CMAX_SITEKEYWORD } ) . " p?>";
-        }
-
-        $ret .= "<table summary=''>";
-        $ret .= "<tr valign='middle'><td class='findandmodify'>$ML{'.interested.in'}</td>";
-        $ret .= "<td class='findandmodify'><form method='get' action='interests'>";
-        $ret .= LJ::html_text({name => 'int', size => 20, value => $interest || $e_int}) . "&nbsp;";
-        $ret .= LJ::html_submit(undef, $ML{'.interested.btn.find'});
-        $ret .= "</form></td></tr>";
-        $ret .= "<tr valign='middle'><td class='findandmodify'>$ML{'.enmasse.intro'}</td>";
-        $ret .= "<td class='findandmodify'><form method='get' action='interests'>";
-        $ret .= LJ::html_text({name => 'fromuser', size => 20}) . "&nbsp;";
-        $ret .= LJ::html_submit(undef, $ML{'.enmasse.btn'});
-        $ret .= LJ::html_hidden('mode', 'enmasse');
-        $ret .= "</form></td></tr>";
-        $ret .= "</table>";
-
-        # no results
-        unless ( $interest ) {
-            $ret .= "<?h1 $ML{'.nocomms.header'} h1?><?p ";
-            $ret .= BML::ml( '.nocomms.text', { 'int' => $e_int, 'aopts' => qq(href="$LJ::SITEROOT/community/create") } );
-            $ret .= " p?><?h1 $ML{'.nousers.header'} h1?><?p ";
-            $ret .= BML::ml( '.nousers.text2', { int => $e_int, aopts_add => "href='$LJ::SITEROOT/interests?mode=addnew&amp;keyword=$e_int'", aopts_int => "href='$LJ::SITEROOT/interests'" } );
-            $ret .= " p?>";
-            return $ret;
-        } 
-
-        $intid += 0;
-
-        ### hook
-        LJ::Hooks::run_hooks("interests_bml", {
-            'intid'   => $intid,
-            'int'     => $interest,
-            'ret'     => \$ret,
-        });
-
-        ### communities
-        my $dbr = LJ::get_db_reader();
-        my $LIMIT = 500;
-
-        my $int_query = sub {
-            my $i = shift;  # comminterests or userinterests
-            my $q = "SELECT $i.userid FROM $i, userusage
-                     WHERE $i.intid = ? AND $i.userid = userusage.userid
-                     ORDER BY userusage.timeupdate DESC LIMIT $LIMIT";
-            my $uref = $dbr->selectall_arrayref( $q, undef, $intid );
-            return LJ::load_userids( map { $_->[0] } @$uref );
-            # can't trust LJ::load_userids to maintain sort order
-        };
- 
-        my $should_show = sub {
-            my $u = shift;
-            return $u->should_show_in_search_results( for => $remote );
-        };
-
-        if ( LJ::is_enabled( 'interests-community' ) ) {
-            my $us = $int_query->( "comminterests" );
-            my $updated = LJ::get_timeupdate_multi( keys %$us );
-            my @cl = sort { $updated->{$b->id} <=> $updated->{$a->id} || $a->user cmp $b->user }
-                     grep { $_ && $_->is_visible && $should_show->( $_ ) } values %$us;
-
-            my $count = @cl;
-            my $list;
-
-            my $show_comm_promos = LJ::is_enabled('community_themes');
-
-            foreach (@cl) {
-                my $name = $_->{name};
-                LJ::text_out(\$name);
-                $list .= "<li class='commname'>" . LJ::ljuser($_) . " - " . LJ::ehtml($name);
-
-                $list .= " <small class='lastupdated'>(";
-                if ($updated->{$_->id} > 0) {
-                    $list .= BML::ml( '.lastupdated.true', { 'time' => LJ::ago_text( time() - $updated->{$_->id} ) } );
-                } else {
-                    $list .= BML::ml( '.lastupdated.false' );
-                }
-                $list .= ")</small>";
-
-                $list .= "<br />&nbsp;&nbsp;&nbsp;<em>" . LJ::ehtml($_->prop("comm_theme")) . "</em>"
-                    if $show_comm_promos && $_->prop("comm_theme");
-
-                $list .= "</li>";
-            }
-
-            if (@cl) {
-                $ret .= "<h1>" . BML::ml( ".communities.header", { interest => $e_int } ) ."</h1>";
-                $ret .= "<p class='matches'><b>" . BML::ml('.matches2', {'num' => $count}) . "</b><ul class='contentlist'>$list</ul></p>";
-            }
-        }
-
-        ##### users
-
-        $ret .= "<h1>" . BML::ml( ".users.header", { interest => $e_int } ) . "</h1>\n<p class='interestinfo'>";
-        if ($remote) {
-            $ret .= " " . BML::ml('.addint2', {'aopts' => "href='$LJ::SITEROOT/interests?mode=add&amp;intid=$intid'"});
-        }
-        $ret .= " " . BML::ml('.morestuff2', {'aopts' => "href='$LJ::SITEROOT/interests'"}) . "</p>";
-
-        my $us = $int_query->( "userinterests" );
-        my @ul = grep { $_
-                            && $_->is_visible              # visible users
-                            && !$_->is_community           # that aren't communities
-                            && (!$_->age || $_->age > 13)  # are over 13
-                            && $should_show->($_)          # and should show to the remote user
-                        } values %$us;
-
-        $ret .= "<p class='matches'><b>" . BML::ml('.matches2', {'num' => scalar @ul}) . "</b></p>";
-
-        my $navbar;
-        my $results = LJ::user_search_display(
-                                              users      => \@ul,
-                                              timesort   => 1,
-                                              perpage    => 50,
-                                              curpage    => $GET{'page'} || 1,
-                                              navbar     => \$navbar,
-                                              );
-
-        $ret .= "<div style='text-align: center'>$navbar</div><br />";
-        $ret .= $results;
-        $ret .= "<div style='text-align: center; clear: both'>$navbar</div><br />";
-
-        return $ret;
-    }
-
-    my $ret = "";
-    $ret .= "<?p $ML{'.interests.text'} p?>";
-    $ret .= "<table summary='' cellspacing='5' style='margin-top: 10px; margin-left: 30px; margin-bottom: 10px;'>";
-
-    if ( LJ::is_enabled('interests-popular') ) {
-        $ret .= "<tr valign='top'><td colspan='2'>";
-        $ret .= "<a href=\"interests?view=popular\">$ML{'.interests.viewpop'}</a></td></tr>";
-    }
-
-    $ret .= "<tr valign='top'><td align='left'>$ML{'.interested.in'}</td>";
-    $ret .= "<td><form method='get' action='interests'>";
-    $ret .= LJ::html_text({name => 'int', size => 20}) . "&nbsp;";
-    $ret .= LJ::html_submit(undef, $ML{'.interested.btn.find'});
-    $ret .= "</form></td></tr>";
-
-    if ( LJ::is_enabled('interests-findsim') && $remote && $remote->can_find_similar ) {
-        $ret .= "<tr valign='top'><td>$ML{'.interests.findsim'}</td><td><form method='get' action='interests'>";
-        $ret .= LJ::html_hidden('mode', 'findsim_do');
-        $ret .= LJ::html_text({name => 'user', value => $remote->{'user'}, size => 20}) . "&nbsp;";
-        $ret .= LJ::html_submit(undef, $ML{'.interested.btn.find'});
-        $ret .= "</form></td></tr>";
-    }
-
-    $ret .= "<tr valign='top'><td>$ML{'.enmasse.intro'}</td>";
-    $ret .= "<td><form method='get' action='interests'>";
-    $ret .= LJ::html_text({name => 'fromuser', size => 20}) . "&nbsp;";
-    $ret .= LJ::html_submit(undef, $ML{'.enmasse.btn'});
-    $ret .= LJ::html_hidden('mode', 'enmasse');
-    $ret .= "</form></td></tr>";
-
-    $ret .= "</table>";
-    $ret .= BML::ml('.nointerests.text2', {'aopts' => "href='$LJ::SITEROOT/manage/profile/'"});
-
-    return $ret;
-}
-_code?>
-<=body
-page?>
diff -r 11ed0d63e6fd -r 75f310215036 htdocs/interests.bml.text
--- a/htdocs/interests.bml.text	Fri Dec 17 01:58:35 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-;; -*- coding: utf-8 -*-
-.add.added.head=Added.
-
-.add.added.editinterests=Edit your interests
-
-.add.added.editprofile=Edit your profile
-
-.add.added.interestspage=Return to the Interests page
-
-.add.added.viewprofile=View your profile
-
-.add.added.text=The interest has been added to your list.
-
-.add.btn.text=Add [[interest]]
-
-.add.confirm.head=Confirm
-
-.add.confirm.text=To add <strong>[[interest]]</strong> as an interest, click the button below.
-
-.add.toomany.head=Sorry...
-
-.add.toomany.text=You already have [[maxinterests]] interests defined.
-
-.addint2=If you're also interested in this, would you like to be <a [[aopts]]>added to this list</a>?
-
-.communities.header=Results for communities listing an interest in "[[interest]]"
-
-.count=Count
-
-.enmasse.body.other<<
-Here are [[user]]'s interests. Select the interests you want
-to add to your own and deselect the interests you want to remove.
-When you're done, save your changes.
-.
-
-.enmasse.body.other_authas<<
-Here are [[user]]'s interests. Select the interests you want
-to add to those of [[target]] and deselect the interests you want to remove.
-When you're done, save your changes.
-.
-
-.enmasse.body.you<<
-Deselect the interests you want to remove.
-When you're done, save your changes.
-.
-
-.enmasse.btn=Show List
-
-.enmasse.header=Add/Remove interests
-
-.enmasse.intro=Modify your interests based on those of:
-
-.error.ignored=Sorry, we're unable to help you find users matching the interests you've provided.
-
-.error.longinterest=As [[sitename]] does not support interests longer than [[maxlen]] characters, your search for <b>[[old_int]]</b> was converted into a search for <b>[[new_int]]</b> instead.
-
-.error.nodata=Sorry, interest data currently unavailable.
-
-.error.nointerests=The selected account hasn't specified any interests.
-
-.findsim_do.account.notallowed=Your account type doesn't let you use this tool.
-
-.findsim_do.magic=Magic<br />Index
-
-.findsim_do.magic.head=What's this Magic Index all about?
-
-.findsim_do.magic.text=We compute a magic index for each matching account. A magic index is a weighting of two factors: the raw number of shared interests and extra points for shared uncommon interests.
-
-.findsim_do.nomatch.head=No Matches
-
-.findsim_do.nomatch.text=Nobody similar to [[user]].
-
-.findsim_do.notdefined=[[user]] has no interests defined.
-
-.findsim_do.similar.head=Similar People
-
-.findsim_do.similar.text=The following people are the most related to [[user]]
-
-.findsim_do.user=People
-
-.finished.about=When you're done, save your changes.
-
-.finished.header=Done?
-
-.finished.save_button=Save Changes
-
-.interest=Interest
-
-.interested.btn.find=Find
-
-.interested.in=Find people interested in:
-
-.interests.findsim=Find people or communities with interests similar to those of:
-
-.interests.head=Interests
-
-.interests.text=Here are some fun things you can do with interests:
-
-.interests.viewpop=View popular interests
-
-.lastupdated.false=Never updated
-
-.lastupdated.true=Updated [[time]]
-
-.matches2=[[num]] [[?num|match|matches]]:
-
-.morestuff2=You can find more fun stuff on the <a [[aopts]]>interests page</a>.
-
-.nocomms.header=Relevant communities
-
-.nocomms.text=There are no communities interested in "<b>[[int]]</b>." You can <a [[aopts]]>create one</a>!
-
-.nointerests.text2=If you don't have any interests listed, you can add some by going to the <a [[aopts]]>Edit Personal Information</a> page.
-
-.nousers.header=Interested users
-
-.nousers.text2=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>.
-
-.popular.disabled=The popular interests feature is unavailable.
-
-.popular.head=Popular Interests
-
-.popular.text=Here are the most popular interests.
-
-.popular.textmode=<a [[aopts]]>View as a table</a>.
-
-.results.added=You've successfully added the selected interests to your interests list.
-
-.results.both=Success. You've successfully added the selected interests to your interests list and removed those you deselected.
-
-.results.deleted=You successfully removed the interests you deselected from your interests list.
-
-.results.del_and_toomany<<
-You successfully removed the interests you deselected, but you didn't add
-any new interests because you can only list a maximum of [[intcount]]
-interests. You may wish to go back and select fewer interests to add or
-delete some old interests.
-.
-
-.results.goback2=Return to [[user]]'s <a [[aopts]]>profile</a>.
-
-.results.header=Results
-
-.results.message2=Return to your revised <a [[aopts]]>profile page</a>.
-
-.results.nothing=You didn't make any changes.
-
-.results.toomany<<
-You didn't add any of your selected interests because you can only list
-a maximum of [[intcount]] interests. You may wish to go back and select
-fewer interests to add or delete some old interests.
-.
-
-.title=Interests
-
-.users.header=Results for people interested in "[[interest]]"
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/add.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/add.tt	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,47 @@
+[%# Interest search, based on code from LiveJournal.
+  #
+  # Authors:
+  #      Jen Griffin <kareila@livejournal.com>
+  #
+  # Copyright (c) 2010 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'.
+  #
+%]
+
+[%- sections.head = BLOCK %]
+<style type='text/css'>
+    div.tagcloud a { text-decoration: none; }
+    ul.contentlist li { padding-bottom: 3px; }
+</style>
+[% END -%]
+
+[%- dw.need_res( 'stc/interests.css' ) -%]
+
+[%- sections.title='.title' | ml -%]
+
+[%- IF need_post -%]
+    <h1>[% '.add.confirm.head' | ml %]</h1>
+    <p>[% '.add.confirm.text' | ml(interest = need_post.int) %]
+    <form method='post' action='interests'><div align='center'>
+    [%- dw.form_auth %]
+    <input type='hidden' name='mode' value='add' />
+    <input type='hidden' name='intid' value='[% need_post.intid %]' />
+    <input type='submit' value='[% ".add.btn.text" | ml(interest = need_post.int) %]' />
+    </div></form></p>
+[%- ELSE -%]
+    <h1>[% '.add.added.head' | ml %]</h1>
+    <p>[% '.add.added.text' | ml %]</p>
+    <ul>
+      <li><a href='[% roots.site %]/interests'>
+          [%- '.add.added.interestspage' | ml %]</a></li>
+      <li><a href='[% roots.site %]/manage/profile/#interests'>
+          [%- '.add.added.editinterests' | ml %]</a></li>
+      <li><a href='[% remote.profile_url %]'>
+          [%- '.add.added.viewprofile' | ml %]</a></li>
+      <li><a href='[% roots.site %]/manage/profile'>
+          [%- '.add.added.editprofile' | ml %]</a></li>
+    </ul>
+[%- END -%]
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/add.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/add.tt.text	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,20 @@
+;; -*- coding: utf-8 -*-
+.add.added.head=Added.
+
+.add.added.editinterests=Edit your interests
+
+.add.added.editprofile=Edit your profile
+
+.add.added.interestspage=Return to the Interests page
+
+.add.added.text=The interest has been added to your list.
+
+.add.added.viewprofile=View your profile
+
+.add.btn.text=Add [[interest]]
+
+.add.confirm.head=Confirm
+
+.add.confirm.text=To add <strong>[[interest]]</strong> as an interest, click the button below.
+
+.title=Interests
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/enmasse.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/enmasse.tt	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,62 @@
+[%# Interest search, based on code from LiveJournal.
+  #
+  # Authors:
+  #      Jen Griffin <kareila@livejournal.com>
+  #
+  # Copyright (c) 2010 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'.
+  #
+%]
+
+[%- sections.head = BLOCK %]
+<style type='text/css'>
+    div.tagcloud a { text-decoration: none; }
+    ul.contentlist li { padding-bottom: 3px; }
+</style>
+[% END -%]
+
+[%- dw.need_res( 'stc/interests.css' ) -%]
+
+[%- sections.title='.title' | ml -%]
+
+<form method='get' action='interests'>
+<input type='hidden' name='mode' value='enmasse' />
+<input type='hidden' name='fromuser' value='[% fromu.user %]' />
+[% authas_html %]</form>
+<form method='post' action='interests[% getextra %]'>
+[%- dw.form_auth %]
+<h1>[% '.enmasse.header' | ml %]</h1>
+<p>[% enmasse_body | ml(user = fromu.ljuser_display,
+                        target = u.ljuser_display) %]</p>
+<div style='margin-left: 40px; margin-top: 20px;'>
+<table summary='' cellpadding='0' cellspacing='0' border='0' width='100%'>
+[%- USE table(enmasse_data, cols=3) -%]
+[%- FOREACH rows = table.rows %]
+<tr valign='middle'>
+    [%- FOREACH cell = rows -%]
+        [%- IF cell.int -%]
+            <td align='left' nowrap='nowrap'>
+            <input type='checkbox' [% IF cell.is_checked %] checked='checked' [% END %]
+                name='[% cell.checkid %]' id='[% cell.checkid %]' value='1' />
+            <label for='[% cell.checkid %]'>
+            [%- IF cell.is_checked %] <strong> [% END -%]
+            [%- cell.int -%]
+            [%- IF cell.is_checked %] </strong> [% END -%]
+            </label></td>
+        [%- ELSE -%]
+            <td></td>
+        [%- END -%]
+    [%- END -%]
+</tr>
+[%- END -%]
+</table></div>
+<input type='hidden' name='mode' value='enmasse_do' />
+<input type='hidden' name='fromuser' value='[% fromu.user %]' />
+<input type='hidden' name='allintids' value='[% allintids %]' />
+<h1>[% '.finished.header' | ml %]</h1><p>[% '.finished.about' | ml %]</p>
+<div class='standout'><table summary='' class='standout-inner'><tr><td>
+<input type='submit' value='[% ".finished.save_button" | ml %]' />
+</td></tr></table></div></form>
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/enmasse.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/enmasse.tt.text	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,27 @@
+;; -*- coding: utf-8 -*-
+.enmasse.body.other<<
+Here are [[user]]'s interests. Select the interests you want
+to add to your own and deselect the interests you want to remove.
+When you're done, save your changes.
+.
+
+.enmasse.body.other_authas<<
+Here are [[user]]'s interests. Select the interests you want
+to add to those of [[target]] and deselect the interests you want to remove.
+When you're done, save your changes.
+.
+
+.enmasse.body.you<<
+Deselect the interests you want to remove.
+When you're done, save your changes.
+.
+
+.enmasse.header=Add/Remove interests
+
+.finished.about=When you're done, save your changes.
+
+.finished.header=Done?
+
+.finished.save_button=Save Changes
+
+.title=Interests
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/enmasse_do.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/enmasse_do.tt	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,32 @@
+[%# Interest search, based on code from LiveJournal.
+  #
+  # Authors:
+  #      Jen Griffin <kareila@livejournal.com>
+  #
+  # Copyright (c) 2010 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'.
+  #
+%]
+
+[%- sections.head = BLOCK %]
+<style type='text/css'>
+    div.tagcloud a { text-decoration: none; }
+    ul.contentlist li { padding-bottom: 3px; }
+</style>
+[% END -%]
+
+[%- dw.need_res( 'stc/interests.css' ) -%]
+
+[%- sections.title='.title' | ml -%]
+
+<h1>[% '.results.header' | ml %]</h1>
+<p>[% enmasse_do_result | ml(intcount = $toomany) %]</p>
+<p>[% '.results.message2' | ml(aopts = "href='$u.profile_url'") %]
+[%- IF fromu -%]
+    [% '.results.goback2' | ml(user = fromu.ljuser_display,
+                               aopts = "href='$fromu.profile_url'") %]
+[%- END -%]
+</p>
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/enmasse_do.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/enmasse_do.tt.text	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,8 @@
+;; -*- coding: utf-8 -*-
+.results.goback2=Return to [[user]]'s <a [[aopts]]>profile</a>.
+
+.results.header=Results
+
+.results.message2=Return to your revised <a [[aopts]]>profile page</a>.
+
+.title=Interests
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/findsim.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/findsim.tt	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,41 @@
+[%# Interest search, based on code from LiveJournal.
+  #
+  # Authors:
+  #      Jen Griffin <kareila@livejournal.com>
+  #
+  # Copyright (c) 2010 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'.
+  #
+%]
+
+[%- sections.head = BLOCK %]
+<style type='text/css'>
+    div.tagcloud a { text-decoration: none; }
+    ul.contentlist li { padding-bottom: 3px; }
+</style>
+[% END -%]
+
+[%- dw.need_res( 'stc/interests.css' ) -%]
+
+[%- sections.title='.title' | ml -%]
+
+<h1>[% '.findsim_do.similar.head' | ml %]</h1>
+<p>[% ".findsim_do.similar.text" | ml(user = findsim_u.ljuser_display) %]</p>
+<p><table cellpadding='3'><tr valign='bottom'>
+    <th>#</th>
+    <th width='250'>[% 'username' | ml %]</th>
+    <th>[% '.findsim_do.magic' | ml %]</th>
+</tr>
+[%- FOREACH findsim_data -%]
+    <tr>
+        <td>[% count %]</td>
+        <td>[% user %]</td>
+        <td>[% magic %]</td>
+    </tr>
+[%- END -%]
+</table></p>
+<h1>[% '.findsim_do.magic.head' | ml %]</h1>
+<p> [% '.findsim_do.magic.text' | ml %]</p>
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/findsim.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/findsim.tt.text	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,12 @@
+;; -*- coding: utf-8 -*-
+.findsim_do.magic=Magic<br />Index
+
+.findsim_do.magic.head=What's this Magic Index all about?
+
+.findsim_do.magic.text=We compute a magic index for each matching account. A magic index is a weighting of two factors: the raw number of shared interests and extra points for shared uncommon interests.
+
+.findsim_do.similar.head=Similar People
+
+.findsim_do.similar.text=The following people are the most related to [[user]]
+
+.title=Interests
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/index.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/index.tt	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,57 @@
+[%# Interest search, based on code from LiveJournal.
+  #
+  # Authors:
+  #      Jen Griffin <kareila@livejournal.com>
+  #
+  # Copyright (c) 2010 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'.
+  #
+%]
+
+[%- sections.head = BLOCK %]
+<style type='text/css'>
+    div.tagcloud a { text-decoration: none; }
+    ul.contentlist li { padding-bottom: 3px; }
+</style>
+[% END -%]
+
+[%- dw.need_res( 'stc/interests.css' ) -%]
+
+[%- sections.title='.title' | ml -%]
+
+<p>[% '.interests.text' | ml %]</p>
+<table summary='' cellspacing='5' style='margin-top: 10px; margin-left: 30px; margin-bottom: 10px;'>
+
+[%- IF can_use_popular -%]
+<tr valign='top'><td colspan='2'>
+<a href="interests?view=popular">[% '.interests.viewpop' | ml %]</a>
+</td></tr>
+[%- END -%]
+
+<tr valign='top'><td align='left'>[% 'interests.interested.in' | ml %]</td>
+<td><form method='get' action='interests'>
+<input type="text" name="int" size="20" />&nbsp;
+<input type='submit' value='[% "interests.interested.btn" | ml %]' />
+</form></td></tr>
+
+[%- IF can_use_findsim -%]
+<tr valign='top'><td>[% '.interests.findsim' | ml %]</td><td>
+<form method='get' action='interests'>
+<input type='hidden' name='mode' value='findsim_do' />
+<input type="text" name="user" size="20" value="[% remote.user %]" />&nbsp;
+<input type='submit' value='[% "interests.interested.btn" | ml %]' />
+</form></td></tr>
+[%- END -%]
+
+<tr valign='top'><td>[% 'interests.enmasse.intro' | ml %]</td><td>
+<form method='get' action='interests'>
+<input type='hidden' name='mode' value='enmasse' />
+<input type="text" name="fromuser" size="20" />&nbsp;
+<input type='submit' value='[% "interests.enmasse.btn" | ml %]' />
+</form></td></tr>
+
+</table>
+[% '.nointerests.text2' | ml(aopts = "href='$roots.site/manage/profile/'") %]
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/index.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/index.tt.text	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,10 @@
+;; -*- coding: utf-8 -*-
+.interests.findsim=Find people or communities with interests similar to those of:
+
+.interests.text=Here are some fun things you can do with interests:
+
+.interests.viewpop=View popular interests
+
+.nointerests.text2=If you don't have any interests listed, you can add some by going to the <a [[aopts]]>Edit Personal Information</a> page.
+
+.title=Interests
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/int.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/int.tt	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,80 @@
+[%# Interest search, based on code from LiveJournal.
+  #
+  # Authors:
+  #      Jen Griffin <kareila@livejournal.com>
+  #
+  # Copyright (c) 2010 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'.
+  #
+%]
+
+[%- sections.head = BLOCK %]
+<style type='text/css'>
+    div.tagcloud a { text-decoration: none; }
+    ul.contentlist li { padding-bottom: 3px; }
+</style>
+[% END -%]
+
+[%- dw.need_res( 'stc/interests.css' ) -%]
+
+[%- sections.title='.title' | ml -%]
+
+[%- IF warn_toolong %]<p>[% warn_toolong %]</p>[% END -%]
+<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='submit' value='[% "interests.interested.btn" | ml %]' />
+</form></td></tr>
+<tr valign='middle'><td class='findandmodify'>
+[% 'interests.enmasse.intro' | ml %]</td><td class='findandmodify'>
+<form method='get' action='interests'>
+<input type='hidden' name='mode' value='enmasse' />
+<input type="text" name="fromuser" size="20" />&nbsp;
+<input type='submit' value='[% "interests.enmasse.btn" | ml %]' />
+</form></td></tr></table>
+[%- IF intcount -%]
+    [%- IF int_comms.count -%]
+        <h1>[% ".communities.header" | ml(interest = e_int) %]</h1>
+        <p class='matches'><b>[% '.matches2' | ml(num = int_comms.count) %]</b>
+        <ul class='contentlist'>
+        [%- FOREACH int_comms.data -%]
+            <li class='commname'>[% u.ljuser_display %] - [% u.name_html %]
+            <small class='lastupdated'>(
+                [%- IF updated; '.lastupdated.true' | ml(time = updated) -%]
+                [%- ELSE; '.lastupdated.false' | ml; END -%]
+            )</small>
+            [%- IF theme -%]
+                <br />&nbsp;&nbsp;&nbsp;<em>[% theme %]</em>
+            [%- END -%]
+            </li>
+        [%- END -%]
+        </ul></p>
+    [%- ELSE -%]
+        <h1>[% '.nocomms.header' | ml %]</h1><p>
+        [%- '.nocomms.text' | ml(aopts = "href='$roots.site/community/create'",
+                                int = interest) %]</p>
+    [%- END -%]
+    <h1>[% ".users.header" | ml(interest = e_int) %]</h1>
+    <p class='interestinfo'>
+    [%- IF remote -%]
+        [%- '.addint2' | ml(aopts = "href='$roots.site/interests?mode=add&amp;intid=$intid'") -%]
+    [%- END -%]
+    [% '.morestuff2' | ml(aopts = "href='$roots.site/interests'") %]</p>
+    <p class='matches'><b>[% '.matches2' | ml(num = int_users.count) %]</b></p>
+    <div style='text-align: center'>[% int_users.navbar %]</div><br />
+    [% int_users.results %]
+    <div style='text-align: center; clear: both'>[% int_users.navbar %]</div><br />
+[%- ELSE -%]
+    <h1>[% '.nocomms.header' | ml %]</h1><p>
+    [%- '.nocomms.text' | ml(aopts = "href='$roots.site/community/create'",
+                            int = e_int) %]</p>
+    <h1>[% '.nousers.header' | ml %]</h1><p>
+    [%- '.nousers.text2' | ml(int = e_int,
+        aopts_add = "href='$roots.site/interests?mode=addnew&amp;keyword=$e_int'",
+        aopts_int = "href='$roots.site/interests'") %]</p>
+[%- END -%]
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/int.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/int.tt.text	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,24 @@
+;; -*- coding: utf-8 -*-
+.addint2=If you're also interested in this, would you like to be <a [[aopts]]>added to this list</a>?
+
+.communities.header=Results for communities listing an interest in "[[interest]]"
+
+.lastupdated.false=Never updated
+
+.lastupdated.true=Updated [[time]]
+
+.matches2=[[num]] [[?num|match|matches]]:
+
+.morestuff2=You can find more fun stuff on the <a [[aopts]]>interests page</a>.
+
+.nocomms.header=Relevant communities
+
+.nocomms.text=There are no communities interested in "<b>[[int]]</b>." You can <a [[aopts]]>create one</a>!
+
+.nousers.header=Interested users
+
+.nousers.text2=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>.
+
+.title=Interests
+
+.users.header=Results for people interested in "[[interest]]"
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/popular.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/popular.tt	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,46 @@
+[%# Interest search, based on code from LiveJournal.
+  #
+  # Authors:
+  #      Jen Griffin <kareila@livejournal.com>
+  #
+  # Copyright (c) 2010 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'.
+  #
+%]
+
+[%- sections.head = BLOCK %]
+<style type='text/css'>
+    div.tagcloud a { text-decoration: none; }
+    ul.contentlist li { padding-bottom: 3px; }
+</style>
+[% END -%]
+
+[%- dw.need_res( 'stc/interests.css' ) -%]
+
+[%- sections.title='.title' | ml -%]
+
+<h1>[% '.popular.head' | ml %]</h1><p>[% '.popular.text' | ml %]
+[%- IF no_text_mode -%]
+    [% '.popular.textmode'
+     | ml(aopts = "href='$roots.site/interests?view=popular&mode=text'") %]
+[%- END -%]
+</p>
+[%- IF pop_ints -%]
+    [%- IF no_text_mode; pop_cloud; ELSE -%]
+        <p><table><tr>
+            <th width='150' style="text-align: left">
+            [% '.interest' | ml %]</th>
+            <th>[% '.count' | ml %]</th>
+        </tr>
+        [%- FOREACH i = pop_ints -%]
+        <tr>
+            <td><a href='[% i.url | url %]'>[% i.eint %]</a></td>
+            <td>[% i.value %]</td>
+        </tr>
+        [%- END -%]
+        </table></p>
+    [%- END -%]
+[%- ELSE; '.error.nodata' | ml; END -%]
diff -r 11ed0d63e6fd -r 75f310215036 views/interests/popular.tt.text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/interests/popular.tt.text	Fri Dec 17 02:17:18 2010 +0800
@@ -0,0 +1,14 @@
+;; -*- coding: utf-8 -*-
+.count=Count
+
+.error.nodata=Sorry, interest data currently unavailable.
+
+.interest=Interest
+
+.popular.head=Popular Interests
+
+.popular.text=Here are the most popular interests.
+
+.popular.textmode=<a [[aopts]]>View as a table</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