head<=
<=head
body<=
'bml.interests', ljadwrapper => 1 });
return $ad_box . $str;
};
LJ::set_active_crumb('searchinterests');
return $print_with_ad->("") unless LJ::text_in(\%GET) && LJ::text_in(\%POST);
my $did_post = LJ::did_post();
my $remote = LJ::get_remote();
my $table = sub { $_[0]->{'journaltype'} eq 'C' ? 'comminterests' : 'userinterests' };
if (!$did_post && $GET{'view'} eq "popular") {
return $print_with_ad->($ML{'.popular.disabled'}) if $LJ::DISABLED{'interests-popular'};
my $ret = '';
$ret .= " "href='$LJ::SITEROOT/interests.bml?view=popular&mode=text'" })
unless $GET{mode} eq 'text';
$ret .= " p?>";
my $rows = LJ::Stats::get_popular_interests();
return $print_with_ad->("Sorry, interest data currently unavailable.") unless @$rows;
my %interests;
foreach my $int_array (@$rows)
{
my ($int, $count) = @$int_array;
$interests{$int} = {
int => $int,
eint => LJ::ehtml($int),
url => "/interests.bml?int=" . LJ::eurl($int),
value => $count,
};
}
unless ($GET{'mode'} eq 'text') {
$ret .= LJ::tag_cloud(\%interests);
} else {
$ret .= "
| $ML{'.interest'} | $ML{'.count'} |
";
foreach my $i (sort { $b->{value} <=> $a->{value} } values %interests) {
$ret .= "| $i->{eint} | $i->{value} |
";
}
$ret .= "
";
}
return $print_with_ad->($ret);
}
if ((!$did_post && $GET{'mode'} eq "add" && $GET{'intid'}) ||
($did_post && $POST{'mode'} eq "add" && $POST{'intid'})) {
my $intid = $did_post ? $POST{'intid'}+0 : $GET{'intid'}+0;
my $ret = '';
unless ($remote) {
$ret .= "";
return $print_with_ad->($ret);
}
# force them to either come from the interests.bml page, or have posted the request.
# if both fail, ask them to confirm with a post form.
my $dbr = LJ::get_db_reader();
unless ($did_post || BML::get_client_header('Referer') =~ /^\Q$LJ::SITEROOT\E\/interests\.bml\?/)
{
my ($int) = $dbr->selectrow_array("SELECT interest FROM interests WHERE intid=?", undef, $intid);
LJ::text_out(\$int);
$ret .= "";
$ret .= " $int});
$ret .= " p?>";
return $print_with_ad->($ret);
}
my $rints = LJ::get_interests($remote);
my $count = scalar(@$rints);
# account for the case where we bypass the POST due to the referer
return $print_with_ad->($ML{'error.invalidform'}) unless !$did_post || LJ::check_form_auth();
if ($count >= 150) {
$ret .= " "150"}) ." p?>";
return $print_with_ad->($ret);
}
my $dbh = LJ::get_db_writer();
my $uitable = $table->($remote);
$dbh->do("INSERT INTO $uitable (userid, intid) VALUES (?, ?)",
undef, $remote->{'userid'}, $intid);
LJ::memcache_kill($remote, "intids");
unless ($dbh->err) {
$dbh->do("UPDATE interests SET intcount=intcount+1 WHERE intid=?", undef, $intid);
}
# if a community, remove any old rows from userinterests
if ($remote->{'journaltype'} eq 'C') {
$dbh->do("DELETE FROM userinterests WHERE userid=?", undef, $remote->{'userid'});
}
$ret .= "";
return $print_with_ad->($ret);
}
if (!$did_post && $GET{'mode'} eq "findsim_do") {
return $print_with_ad->($ML{'error.tempdisabled'}) if $LJ::DISABLED{'interests-findsim'};
return $print_with_ad->($ML{'.findsim_do.account.notallowed'}) unless LJ::get_cap($remote, "findsim");
my $ret = "";
my $u = LJ::load_user($GET{'user'});
return $print_with_ad->("") 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 $print_with_ad->("");
}
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 "women"
# 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 > 150) { @matches = @matches[0..149]; }
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 $print_with_ad->(" LJ::ljuser($u)}) ." p?>");
}
$ret .= " LJ::ljuser($u)}) ." p?>";
$ret .= "| # | $ML{'User'} | $ML{'.findsim_do.magic'} |
";
my $count;
foreach my $uid (@matches)
{
$count++;
$ret .= "| $count | ";
$ret .= LJ::ljuser($username{$uid});
$ret .= sprintf(" | %.3f |
", $magic{$uid});
}
$ret .= "
";
$ret .= "";
return $print_with_ad->($ret);
}
if (!$did_post && $GET{'mode'} eq "enmasse")
{
return $print_with_ad->("") unless $remote;
my $authas = $GET{'authas'} || $remote->{'user'};
my $u = LJ::get_authas_user($authas);
return $print_with_ad->(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);
my %uint;
my %fromint;
my $fints = LJ::get_interests($fromu);
foreach (@$fints) {
$fromint{$_->[1]} = $_->[0]+0;
}
return $print_with_ad->("") unless %fromint;
my $ret = "";
$ret .= LJ::html_hidden(mode => 'enmasse', fromuser => $fromu->{'user'});
$ret .= LJ::make_authas_select($remote, { 'authas' => $GET{'authas'} });
$ret .= " p?>";
return $ret;
}
if ($did_post && $POST{'mode'} eq "enmasse_do") {
return $print_with_ad->("") unless $remote;
my $authas = $GET{'authas'} || $remote->{'user'};
my $u = LJ::get_authas_user($authas);
return $print_with_ad->(LJ::bad_input($ML{'.error.noauth'})) unless $u;
my $uitable = $table->($u);
my %uint;
my $intcount = 0;
my $uints = LJ::get_interests($u);
foreach (@$uints) {
$uint{$_->[0]} = $_->[1]; # uint{intid} = interest
$intcount++;
}
my @fromints = map { $_+0 } split (/\s*,\s*/, $POST{'allintids'});
my @todel;
my @toadd;
foreach my $fromint (@fromints) {
next unless $fromint > 0; # prevent adding zero or negative intid
push (@todel, $fromint) if $uint{$fromint} && !$POST{'int_'.$fromint};
push (@toadd, $fromint) if !$uint{$fromint} && $POST{'int_'.$fromint};
}
my ($deleted, $added, $toomany) = (0, 0, 0);
if (@todel) {
my $intid_in = join(",", @todel);
my $dbh = LJ::get_db_writer();
$dbh->do("DELETE FROM $uitable WHERE userid=? AND intid IN ($intid_in)",
undef, $u->{'userid'});
$dbh->do("UPDATE interests SET intcount=intcount-1 WHERE intid IN ($intid_in)");
$deleted = 1;
}
if (@toadd) {
if ($intcount + scalar @toadd > 150) {
$toomany = 1;
} else {
my $dbh = LJ::get_db_writer();
my $sqlp = "(?,?)" . (",(?,?)" x (scalar(@toadd) - 1));
my @bindvars = map { ($u->{'userid'}, $_) } @toadd;
$dbh->do("REPLACE INTO $uitable (userid, intid) VALUES $sqlp", undef, @bindvars);
my $intid_in = join(",", @toadd);
$dbh->do("UPDATE interests SET intcount=intcount+1 WHERE intid IN ($intid_in)");
$added = 1;
}
}
# if a community, remove any old rows from userinterests
if ($u->{'journaltype'} eq 'C') {
my $dbh = LJ::get_db_writer();
$dbh->do("DELETE FROM userinterests WHERE userid=?", undef, $u->{'userid'});
}
my $ret = " 150})
: $ML{'.results.deleted'};
} else {
$ret .= $added ? $ML{'.results.added'}
: $toomany ? BML::ml('.results.toomany', {'intcount' => 150})
: $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?> "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?>";
LJ::memcache_kill($u, "intids");
return $print_with_ad->($ret);
}
if (!$did_post && ($GET{'intid'} || $GET{'int'})) {
my $sth;
my $dbr = LJ::get_db_reader();
my ($interest, $intid, $intcount);
if ($GET{'intid'}) {
($interest, $intid, $intcount) = $dbr->selectrow_array("SELECT interest, intid, intcount
FROM interests WHERE intid=?", undef, $GET{'intid'});
} else {
($interest, $intid, $intcount) = $dbr->selectrow_array("SELECT interest, intid, intcount
FROM interests WHERE interest=?", undef, $GET{'int'});
}
my $check_int = $GET{int} || $interest;
if (LJ::run_hook("interest_search_ignore", query => $check_int, intid => $intid)) {
return $print_with_ad->("");
}
my $search_ad = LJ::search_ads(query => $GET{int}, count => 2) if $GET{int};
my $e_int = LJ::ehtml($GET{int});
my $ret = '';
$ret .= "";
$ret .= "| $ML{'.interested.in'} | ";
$ret .= " |
";
$ret .= "| $ML{'.enmasse.intro'} | ";
$ret .= " |
";
$ret .= "
";
# no results
return $print_with_ad->(qq {
$ret
$search_ad
"$e_int." You can
create one! p?>
$e_int. If you are interested in this
and would like to be added to this list, click here.
More fun stuff can be found on the interests page. p?>
}) unless $interest;
$intid += 0;
### hook
my $hide_ad = 0;
LJ::run_hooks("interests_bml", {
'intid' => $intid,
'int' => $interest,
'ret' => \$ret,
'hide_ad' => \$hide_ad,
});
$ret .= $search_ad unless $hide_ad;
### communities
my $LIMIT = 500;
my $should_show = sub {
my $u = shift;
return $u->should_show_in_search_results( for => $remote );
};
unless ($LJ::DISABLED{'interests-community'}) {
my @uids;
$sth = $dbr->prepare("SELECT userid FROM comminterests WHERE intid=? LIMIT $LIMIT");
$sth->execute($intid);
push @uids, $_ while $_ = $sth->fetchrow_array;
my @other_uids = LJ::run_hook("get_other_interested_comms", $interest, $remote);
foreach my $uid (@other_uids) {
push @uids, $uid;
}
my $updated = LJ::get_timeupdate_multi(@uids);
my $us = LJ::load_userids(@uids);
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::conf_test($LJ::DISABLED{"community_themes"});
foreach (@cl) {
my $name = $_->{name};
LJ::text_out(\$name);
$list .= "" . LJ::ljuser($_) . " - " . LJ::ehtml($name);
$list .= " (";
if ($updated->{$_->id} > 0) {
$list .= "Updated ";
$list .= LJ::ago_text(time() - $updated->{$_->id});
} else {
$list .= "Never updated";
}
$list .= ")";
$list .= "
" . LJ::ehtml($_->prop("comm_theme")) . ""
if $show_comm_promos && $_->prop("comm_theme");
$list .= "";
}
if (@cl) {
$ret .= "" . BML::ml(".communities.header", {'interest' => $interest}) ."
";
$ret .= "" . BML::ml('.matches2', {'num' => $count}) . "
";
}
}
##### users
$ret .= "" . BML::ml(".users.header", {'interest' => $interest}) . "
\n";
if ($remote) {
$ret .= " " . BML::ml('.addint2', {'aopts' => "href='$LJ::SITEROOT/interests.bml?mode=add&intid=$intid'"});
}
$ret .= " " . BML::ml('.morestuff2', {'aopts' => "href='$LJ::SITEROOT/interests.bml'"}) . "
";
my @uids;
$sth = $dbr->prepare("SELECT userid FROM userinterests WHERE intid=? LIMIT $LIMIT");
$sth->execute($intid);
push @uids, $_ while $_ = $sth->fetchrow_array;
my $us = LJ::load_userids(@uids);
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 .= "" . BML::ml('.matches2', {'num' => scalar @ul}) . "
";
my $navbar;
my $results = LJ::user_search_display(
users => \@ul,
timesort => 1,
perpage => 50,
curpage => $GET{'page'} || 1,
navbar => \$navbar,
);
$ret .= "$navbar
";
$ret .= $results;
return $hide_ad ? $ret : $print_with_ad->($ret);
}
my $ret = "";
$ret .= "";
$ret .= "";
unless ($LJ::DISABLED{'interests-popular'}) {
$ret .= "| ";
$ret .= "$ML{'.interests.viewpop'} |
";
}
$ret .= "| $ML{'.interested.in'} | ";
$ret .= " |
";
if (!$LJ::DISABLED{'interests-findsim'} && $remote && LJ::get_cap($remote, "findsim")) {
$ret .= "| $ML{'.interests.findsim'} | |
";
}
$ret .= "| $ML{'.enmasse.intro'} | ";
$ret .= " |
";
$ret .= "
";
$ret .= BML::ml('.nointerests.text2', {'aopts' => "href='$LJ::SITEROOT/manage/profile/'"});
return $print_with_ad->($ret);
}
_code?>
";
$ret .= LJ::search_ads(query => $GET{int}, count => 2) if $GET{int};
return $ret;
}
_code?>
<=body
page?>
link: htdocs/interests.bml, htdocs/manage/profile/index.bml
post: htdocs/interests.bml
form: htdocs/interests.bml
_c?>