This commit is contained in:
2019-02-06 00:49:12 +03:00
commit 8dbb1bb605
4796 changed files with 506072 additions and 0 deletions

243
local/htdocs/manage/siteopts.bml Executable file
View File

@@ -0,0 +1,243 @@
<?_code
{
use strict;
use vars qw(%GET %POST $title $body);
LJ::set_active_crumb('siteopts');
# set $title later because we may be changing languages
$title = "";
$body = "";
# error handling closures
my $redir = sub { BML::redirect("siteopts.bml"); };
# thumb schemes have thumbnails
# text schemes are in a drop-down
my @thumb_schemes;
my @text_schemes;
foreach (@LJ::SCHEMES) {
if (ref $_->{'thumb'} eq 'ARRAY') {
push @thumb_schemes, $_;
} else {
push @text_schemes, $_;
}
}
# saving changes
if (LJ::did_post()) {
my $remote = LJ::get_remote();
# was a scheme change posted?
my $scheme;
if (exists $POST{'action:setscheme'}) {
foreach (@text_schemes) {
$scheme = $_->{'scheme'} if $POST{'scheme'} eq $_->{'scheme'};
}
} else {
foreach (@thumb_schemes) {
$scheme = $_->{'scheme'} if exists $POST{"action:setscheme:$_->{'scheme'}.x"};
}
}
# set scheme
if ($scheme) {
my $cval = $scheme;
# don't set cookie for default scheme
if ($scheme eq $LJ::SCHEMES[0]->{'scheme'}) {
$cval = '';
delete $COOKIE{'BMLschemepref'};
}
# logged in?
if ($remote) {
# set a userprop to remember their schemepref
LJ::set_userprop($remote, 'schemepref', $cval);
# cookie expires when session expires
if ($remote->{'_session'}->{'exptype'} eq 'long') {
$cval = [ $scheme, $remote->{'_session'}->{'timeexpire'} ];
}
}
# set cookie
$COOKIE{'BMLschemepref'} = $cval if $cval;
# redirect to refresh cookie settings
return $redir->();
}
# set language
if (exists $POST{'action:setlang'} && $POST{'lang'}) {
my $l = LJ::Lang::get_lang($POST{'lang'});
return $redir->() unless $l;
# default cookie value to set
my $cval = $l->{'lncode'} . "/" . time();
# if logged in, change userprop and make cookie expiration
# the same as their login expiration
my $remote = LJ::get_remote();
if ($remote) {
LJ::set_userprop($remote, "browselang", $l->{'lncode'});
if ($remote->{'_session'}->{'exptype'} eq 'long') {
$cval = [ $cval, $remote->{'_session'}->{'timeexpire'} ];
}
}
# set cookie
$COOKIE{'langpref'} = $cval;
# set language through BML so it will apply immediately
BML::set_language($l->{'lncode'});
}
}
# set title now that we have the correct language
$title = $ML{'.title'};
# preferences page output
# wrapper box to to keep tables from scrolling horizontally
$body .= "<table><tr><td>";
# scheme selector
if (@LJ::SCHEMES) {
$body .= "<?h1 $ML{'.head.scheme'} h1?>";
$body .= "<form method='post' action='siteopts.bml'>";
my $scheme = $BML::COOKIE{'BMLschemepref'};
$scheme = $LJ::SCHEMES[0]->{'scheme'} unless $scheme;
if (@thumb_schemes) {
my $ct = 0;
my $cols = 3;
my $width = int(100 / $cols +.5) . "%";
my $switch = @thumb_schemes / $cols;
$body .= "<table border='0' width='100%' cellpadding='2'>";
$body .= "<tr valign='top' align='left'>";
foreach my $sh (@thumb_schemes) {
if ($ct == 0) {
$body .= "<td width='$width' align='left' valign='top'>";
}
my $th = $sh->{'thumb'};
$body .= "<div style='float: left'><?h2 $sh->{'title'} h2?> <input type='image' ";
$body .= "name='action:setscheme:$sh->{'scheme'}' ";
$body .= "src='$LJ::IMGPREFIX/$th->[0]'";
$body .= " width='$th->[1]'" if $th->[1];
$body .= " height='$th->[2]'" if $th->[2];
if ($sh->{'scheme'} eq $scheme) {
$body .= "style='border: solid 2px blue;' ";
} else {
$body .= "style='border: solid 1px black;' ";
}
my $alt = BML::ml('.scheme.preview', {'title' => $sh->{'title'},});
$body .= " alt='$alt' title='$sh->{'title'}'/></div>";
if (++$ct >= $switch) {
$body .= "</td>";
$ct = 0;
}
}
$body .= "</tr></table>";
}
if (@text_schemes) {
my $ct = 0;
my $cols = 3;
my $width = int(100 / $cols +.5) . "%";
my $switch = @text_schemes / $cols;
$body .= "<table border='0' width='100%' cellpadding='2'>";
$body .= "<tr valign='top' align='left'>";
foreach my $sh (@text_schemes) {
if ($ct == 0) {
$body .= "<td width='$width' align='left'>";
}
$body .= "<p>" .
LJ::html_check({ 'type' => 'radio', 'name' => 'scheme',
'value' => $sh->{'scheme'},
'id' => "scheme-$sh->{'scheme'}",
'selected' => $scheme eq $sh->{'scheme'} });
$body .= "<label for='scheme-$sh->{'scheme'}'>$sh->{'title'}</label></p>";
if (++$ct >= $switch) {
$body .= "</td>";
$ct = 0;
}
}
$body .= "</tr><tr><td colspan='$cols' align='left'>";
$body .= LJ::html_submit('action:setscheme', $ML{'.btn.scheme'});
$body .= "</td></tr></table>";
}
$body .= "</form>";
}
# language selector
$body .= "<?h1 $ML{'.head.lang'} h1?>";
$body .= "<form method='post' action='siteopts.bml'>";
my $ct = 0;
my $cols = 3;
my $width = int(100 / $cols +.5) . "%";
my $switch = @LJ::LANGS / $cols;
my $curr = BML::get_language();
$body .= "<table border='0' width='100%' cellpadding='2'>";
$body .= "<tr valign='top' align='left'>";
my @inc;
push @inc, $GET{'addlang'} if $GET{'addlang'};
foreach my $code (@LJ::LANGS, @inc) {
my $l = LJ::Lang::get_lang($code);
next unless $l;
my $item = "langname.$code";
my $namethislang = BML::ml($item);
my $namenative = LJ::Lang::get_text($l->{'lncode'}, $item);
if ($ct == 0) {
$body .= "<td width='$width' align='left'>";
}
$body .= "<p>" . LJ::html_check({ 'type' => 'radio', 'name' => 'lang',
'value' => $code, 'id' => "sel_$code",
'selected' => $code eq $curr });
$body .= " <label for='sel_$code'>$namenative";
$body .= " ($namethislang)" if $namethislang ne $namenative;
$body .= "</label></p>\n";
if (++$ct >= $switch) {
$body .= "</td>";
$ct = 0;
}
}
$body .= "<tr><td colspan='$cols' align='left'>";
$body .= LJ::html_submit('action:setlang', $ML{'.btn.lang'});
$body .= "</td></tr>";
$body .= "</table></form>";
$body .= "</td></tr></table>";
return;
}
_code?><?page
title=><?_code return $title; _code?>
body=><?_code return $body; _code?>
page?>

269
local/htdocs/manage/tags.bml Executable file
View File

@@ -0,0 +1,269 @@
<?page
title=><?_code return $ML{'.title'}; _code?>
body<=
<?_code
{
use strict;
use vars qw(%POST %GET);
LJ::set_active_crumb('tags');
return "<?h1 $ML{'Error'} h1?><?p $ML{'/edittags.bml.disabled'} p?>"
if $LJ::DISABLED{tags};
my $remote = LJ::get_remote();
return "<?needlogin?>" unless $remote;
my $authas = $GET{'authas'} || $remote->{'user'};
my $u = LJ::get_authas_user($authas);
return LJ::bad_input($ML{'error.invalidauth'})
unless $u;
# do user requested changes
my $add_text = $ML{'.addnew'};
if (LJ::did_post()) {
# Adding new tags
$POST{add} = 1 if $POST{'add.x'} or $POST{'add.y'}; # image submit
if ($POST{add} or ($POST{'add_field'} && $POST{'add_field'} ne $add_text)) {
LJ::Tags::create_usertag($u, $POST{'add_field'}, { display => 1 });
}
# Deleting tags
if ($POST{delete}) {
foreach my $id (split /\0/, $POST{tags}) {
$id =~ s/_.*//;
LJ::Tags::delete_usertag( $u, 'id', $id );
}
}
if ($POST{rename}) {
my @tagnames = map { s/\d+_//; $_; } split /\0/, $POST{tags};
my $new_tag = LJ::trim($POST{rename_field});
$new_tag =~ s/,.*//;
# FIXME: merge support later
my $rr = LJ::Tags::rename_usertag( $u, 'name', $tagnames[0], $new_tag );
return "<?h1 $ML{'Error'} h1?><?p Error renaming tags p?>" unless $rr;
}
if ($POST{'show posts'}) {
# this should do some cute ajax display later.
my $tags = LJ::Tags::get_usertags( $u ); # we redirect, so we don't double load anyway
my $taglist = LJ::eurl(join ',', map { $tags->{$_}->{name} } map { /^(\d+)_/; $1; } split /\0/, $POST{tags});
BML::redirect( LJ::journal_base($u) . "/tag/$taglist" );
}
}
# get tags list!
my $tags = LJ::Tags::get_usertags( $u );
my $tagcount = scalar keys %$tags;
# create histogram usage levels from 'uses' counts
# for 'cell bars' icon display
if ($tagcount) {
my (
@data,
$groups,
$max, $min,
$width,
%range,
);
$groups = 5;
# order by use
@data = map { [ $_, $tags->{$_}->{uses} ] }
sort { $tags->{$a}->{uses} <=> $tags->{$b}->{uses} } keys %$tags;
# get min use, max use, and group 'width'
$max = $data[-1]->[1];
$min = $data[0]->[1];
$width = ($max - $min) / $groups || 1;
# pre calculate ranges for groups
for (1..$groups) {
$range{$_} = [];
@{$range{$_}}[0] = $min + ($_ - 1) * $width; # low
@{$range{$_}}[1] = $min + ($_ * $width); # high
}
# iterate through sorted data, adding
# histogram group to the tags data structure.
foreach (@data) {
my ($id, $use) = (@$_);
GROUP:
for (1..$groups) {
if ($use >= @{$range{$_}}[0] && $use <= @{$range{$_}}[1]) {
$tags->{$id}->{histogram_group} = $_;
last GROUP;
}
}
}
}
# button titles (mouseovers)
my $mo = {
create => $ML{'.hint.create'},
rename => $ML{'.hint.rename'},
delete => $ML{'.hint.delete'},
entries => $ML{'.hint.entries'},
};
my $sp = '&nbsp;&nbsp;';
my $ret;
# user switcher
$ret .= "<form method='GET'>\n";
$ret .= LJ::make_authas_select($remote, { authas => $u->{user} });
$ret .= "</form>\n";
$ret .= "<?p $ML{'.intro'} p?>";
# convert tags data structure to javascript array for quick prop display.
# this is temporary, we'll eventually do a smarter
# xml-rpc call instead of requiring this.
$ret .= "\n<script type='text/javascript'>\n";
$ret .= "var tags = new Array();\n";
foreach (sort keys %$tags) {
my $tag = $tags->{$_};
my $sec = $tag->{security};
my ($pub, $pri, $fr, $tot) =
($sec->{public}, $sec->{private},
$sec->{friends}, $tag->{uses});
my $grp = $tot - ($pub+$pri+$fr);
$ret .= "tags[$_] = [ '" . LJ::ejs($tag->{name}) . "', '$tag->{security_level}', $pub, $pri, $fr, $grp, $tot ];\n";
}
$ret .= "</script>\n";
# the extra 'padding' div is a workaround for how
# IE incorrectly renders fieldsets.
$ret .= qq{
<form method="POST" name="tagform" id="tagform">
<table cellpadding="0" cellspacing="0">
<tr><td valign="top">
<fieldset>
<legend>$ML{'.label.yours'}</legend>
<div style="padding-top: 6px;">
};
my $tagsort = sub {
$GET{sort} eq 'use' ?
$tags->{$b}->{uses} <=> $tags->{$a}->{uses} :
$tags->{$a}->{name} cmp $tags->{$b}->{name};
};
if ($tagcount) {
$ret .= "<select name='tags' id='tags' multiple='multiple' class='tagbox' " .
"onChange='tagselect(this)'>";
foreach (sort { $tagsort->() } keys %$tags) {
my $tag = $tags->{$_};
my $etag = LJ::ehtml( $tag->{name} );
# keep id and value for both JS and perl
# double escape for javascript div display (so &amp; stays '&amp;')
my $value = $_ . '_' . LJ::ehtml( $etag );
$ret .= "<option class='level$tag->{histogram_group}' ";
$ret .= "value='$value'>$etag</option>";
}
$ret .= "</select>";
$ret .= "<div class='tagsort'>";
$ret .= $GET{sort} eq 'use' ? BML::ml('.sort.a', { aopts => "href='$LJ::SITEROOT/manage/tags.bml?authas=$u->{user}&sort=alpha'" }) :
BML::ml('.sort.b', { aopts => "href='$LJ::SITEROOT/manage/tags.bml?authas=$u->{user}&sort=use'" });
$ret .= '</div>';
} else {
$ret .= "<div class='taginfo'>$ML{'.none'}</div>"
}
$ret .= '<div style="margin-top: 10px">';
$ret .= LJ::html_text(
{
name => 'add_field',
size => 20,
style => 'width: 260px',
class => 'tagfield',
value => LJ::did_post() ? "" : $add_text,
onClick => "reset_field(this, '$add_text')",
}
);
$ret .= '&nbsp;';
$ret .= "<input type='image' name='add' src='/img/rte/post_button_text_larger.gif'
border='0' align='middle' title='$mo->{create}'
onClick='return validate_input(this, \"add_field\", \"$add_text\")'>";
$ret .= '
</div>
</div>
</fieldset>
</td>
<td valign="top">';
unless ($tagcount) {
$ret .= '&nbsp;</td></tr></table></form>';
return $ret;
}
$ret .= "<fieldset><legend>$ML{'.label.tags'}</legend>";
$ret .= '<div style="padding-top: 6px;">';
$ret .= "<div id='selected_tags'>&nbsp;</div>";
$ret .= "<div style='white-space: nowrap'>";
$ret .= LJ::html_text(
{
name => 'rename_field',
size => 30,
class => 'tagfield',
onClick => 'reset_field(this)',
}
);
$ret .= $sp;
$ret .= LJ::html_submit(
'rename', $ML{'.button.rename'},
{
class => 'btn',
title => $mo->{rename},
onClick => 'return validate_input(this, "rename_field")',
}
);
$ret .= '<br /><br />';
my $del_conf = $ML{'.confirm.delete'};
$ret .= LJ::html_submit(
'delete', $ML{'.button.delete'},
{
class => 'btn',
title => $mo->{delete},
onClick => "return confirm('$del_conf')",
}
) . $sp;
$ret .= LJ::html_submit(
'show posts', $ML{'.button.show'},
{
class => 'btn',
title => $mo->{entries},
}
);
$ret .= '</div><br /><div id="tag_props">&nbsp;</div>';
$ret .= '
</div>
</fieldset>
</td></tr></table>
</form>
';
return $ret;
} _code?>
<=body
head<=
<link rel='stylesheet' type='text/css' href='/styles/tags.css' />
<script type="text/javascript" src="/js/tags.js"></script>
<=head
bodyopts=>onLoad="initTagPage()"
page?>