init
This commit is contained in:
156
livejournal/htdocs/translate/diff.bml
Executable file
156
livejournal/htdocs/translate/diff.bml
Executable file
@@ -0,0 +1,156 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<style type="text/css">
|
||||
del {
|
||||
text-decoration: none;
|
||||
color: #ff0000;
|
||||
background-color: #ffd0d0;
|
||||
}
|
||||
ins {
|
||||
text-decoration: none;
|
||||
color: #002000;
|
||||
background-color: #20ff20;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?_code
|
||||
{
|
||||
use strict;
|
||||
use vars qw(%GET);
|
||||
use File::Temp qw/tempfile/;
|
||||
|
||||
BML::set_content_type("text/html; charset=utf-8");
|
||||
|
||||
my $lang = $GET{'lang'};
|
||||
my $l = LJ::Lang::get_lang($lang);
|
||||
return "<b>Invalid language</b>" unless $l;
|
||||
|
||||
return "<b>Invalid item</b>" unless $GET{'it'} =~ /^(\d+):(\d+)$/;
|
||||
my ($dmid, $itid) = ($1, $2);
|
||||
|
||||
my @lnids = $l->{'lnid'};
|
||||
{
|
||||
my $il = $l;
|
||||
while ($il && $il->{'parentlnid'}) {
|
||||
push @lnids, $il->{'parentlnid'};
|
||||
$il = LJ::Lang::get_lang_id($il->{'parentlnid'});
|
||||
}
|
||||
}
|
||||
my $lnids = join(",", @lnids);
|
||||
|
||||
my $dbr = LJ::get_db_reader();
|
||||
my ($sth, $ret);
|
||||
|
||||
my $sth = $dbr->prepare("select * from ml_text where dmid=$dmid and itid=$itid and lnid in ($lnids) ORDER BY txtid");
|
||||
$sth->execute;
|
||||
my @tlist;
|
||||
while (my $t = $sth->fetchrow_hashref) {
|
||||
next if @tlist && $t->{'text'} eq $tlist[-1]->{'text'};
|
||||
push @tlist, $t;
|
||||
}
|
||||
|
||||
my $changes = scalar @tlist - 1;
|
||||
return "<b>No changes</b>" unless $changes;
|
||||
|
||||
my $view_change = $GET{'change'} || $changes;
|
||||
return "bogus change" if $view_change < 1 || $view_change > $changes;
|
||||
for (1..$changes) {
|
||||
if ($_ eq $view_change) {
|
||||
$ret .= "<b>[Change $_]</b>\n";
|
||||
} else {
|
||||
$ret .= "<a href='diff.bml?lang=$lang&it=$GET{'it'}&change=$_'>[Change $_]</a>\n";
|
||||
}
|
||||
}
|
||||
$ret .= "<hr>";
|
||||
my $was = $tlist[$view_change-1]->{'text'};
|
||||
my $then = $tlist[$view_change]->{'text'};
|
||||
|
||||
my ($was_alt, $then_alt) = ($was, $then);
|
||||
foreach (\$was_alt, \$then_alt) {
|
||||
$$_ =~ s/\n/*NEWLINE*/g;
|
||||
$$_ =~ s/\s+/\1\n/g;
|
||||
$$_ .= "\n";
|
||||
}
|
||||
|
||||
my ($was_file, $then_file, $fh);
|
||||
my $tries = 0;
|
||||
|
||||
($fh, $was_file) = tempfile();
|
||||
print $fh $was_alt; close $fh;
|
||||
($fh, $then_file) = tempfile();
|
||||
print $fh $then_alt; close $fh;
|
||||
|
||||
my @words = split(/\n/, $was_alt);
|
||||
my $diff = `diff -u $was_file $then_file`;
|
||||
|
||||
my $pos = 0;
|
||||
my $mode;
|
||||
my $setmode = sub {
|
||||
my $newmode = shift;
|
||||
return " " if $newmode eq $mode;
|
||||
my $ret;
|
||||
$ret .= "</$mode>" if $mode;
|
||||
$ret .= " ";
|
||||
$ret .= "<$newmode>" if $newmode;
|
||||
$mode = $newmode;
|
||||
return $ret;
|
||||
};
|
||||
|
||||
foreach my $dl (split(/\n/, $diff)) {
|
||||
next if $dl =~ /^(\+\+\+|\-\-\-)/;
|
||||
if ($dl =~ /^\@\@ \-(\d+),(\d+)/) {
|
||||
my $newpos = $1;
|
||||
$ret .= $setmode->("");
|
||||
for (my $i=$pos+1; $i<$newpos; $i++) {
|
||||
my $word = LJ::ehtml($words[$i-1]);
|
||||
$word =~ s/\*NEWLINE\*/<br>\n/g;
|
||||
$ret .= "$word ";
|
||||
$pos++;
|
||||
}
|
||||
next;
|
||||
}
|
||||
if ($dl =~ /^ /) {
|
||||
$pos++;
|
||||
my $word = LJ::ehtml($words[$pos-1]);
|
||||
$word =~ s/\*NEWLINE\*/<br>\n/g;
|
||||
$ret .= $setmode->("") . $word;
|
||||
}
|
||||
if ($dl =~ /^\-/) {
|
||||
$pos++;
|
||||
my $word = LJ::ehtml($words[$pos-1]);
|
||||
$word =~ s/\*NEWLINE\*/<br>\n/g;
|
||||
$ret .= $setmode->("del") . $word;
|
||||
}
|
||||
if ($dl =~ /^\+(.*)/) {
|
||||
my $word = LJ::ehtml($1);
|
||||
$word =~ s/\*NEWLINE\*/<br>\n/g;
|
||||
$ret .= $setmode->("ins") . $word;
|
||||
}
|
||||
}
|
||||
|
||||
$ret .= $setmode->("");
|
||||
while ($pos < @words) {
|
||||
my $word = LJ::ehtml($words[$pos]);
|
||||
$word =~ s/\*NEWLINE\*/<br>\n/g;
|
||||
$ret .= "$word ";
|
||||
$pos++;
|
||||
}
|
||||
|
||||
$was = LJ::eall($was);
|
||||
$was =~ s/\n( *)/"<br \/>" . " "x length($1)/eg;
|
||||
$then = LJ::eall($then);
|
||||
$then =~ s/\n( *)/"<br \/>" . " "x length($1)/eg;
|
||||
|
||||
$ret .= "<p><table width='100%' border='1'><tr valign='top'><td width='50%'><b>Before:</b><br>$was</td>";
|
||||
$ret .= "<td width='50%'><b>After:</b><br>$then</td></tr></table>";
|
||||
|
||||
unlink($was_file, $then_file);
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
_code?>
|
||||
</body>
|
||||
</html>
|
||||
16
livejournal/htdocs/translate/edit.bml
Executable file
16
livejournal/htdocs/translate/edit.bml
Executable file
@@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Language Editor</title>
|
||||
</head>
|
||||
|
||||
<frameset cols="200,*">
|
||||
<frameset rows="200,*">
|
||||
<frame name="search" src="searchform.bml?lang=<?_code return $FORM{'lang'}; _code?>">
|
||||
<frame name="res" src="search.bml?lang=<?_code return $FORM{'lang'}; _code?>&stale=1%2B&search=sev">
|
||||
</frameset>
|
||||
<frame name="main" src="welcome.bml">
|
||||
</frameset>
|
||||
|
||||
</html><!-- <LJDEP>
|
||||
link: htdocs/translate/searchform.bml, htdocs/translate/welcome.bml, htdocs/translate/search.bml
|
||||
</LJDEP> -->
|
||||
318
livejournal/htdocs/translate/editpage.bml
Executable file
318
livejournal/htdocs/translate/editpage.bml
Executable file
@@ -0,0 +1,318 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<?_code
|
||||
use strict;
|
||||
use vars qw(%FORM);
|
||||
|
||||
BML::set_content_type("text/html; charset=utf-8");
|
||||
|
||||
my $lang = $FORM{'lang'};
|
||||
my $l = LJ::Lang::get_lang($lang);
|
||||
return "<b>Invalid language</b>" unless $l;
|
||||
my $lp = $l->{'parentlnid'} ? LJ::Lang::get_lang_id($l->{'parentlnid'}) : undef;
|
||||
|
||||
my $dbr = LJ::get_db_reader();
|
||||
my $dbh;
|
||||
my ($sth, $ret);
|
||||
|
||||
my $remote = LJ::get_remote();
|
||||
my $can_edit = (LJ::check_priv($remote, "translate", "*") ||
|
||||
LJ::check_priv($remote, "translate", $l->{'lncode'}));
|
||||
my $can_delete = LJ::check_priv($remote, "translate", "[itemdelete]");
|
||||
my $can_rename = LJ::check_priv($remote, "translate", "[itemrename]");
|
||||
|
||||
my $mode = {
|
||||
'' => 'view',
|
||||
'save' => 'save',
|
||||
}->{$FORM{'mode'}};
|
||||
return "bogus mode" unless $mode;
|
||||
|
||||
my $MAX_EDIT = 100;
|
||||
|
||||
if ($mode eq "view")
|
||||
{
|
||||
my @load;
|
||||
foreach (split /,/, $FORM{'items'})
|
||||
{
|
||||
next unless /^(\d+):(\d+)$/;
|
||||
last if @load >= $MAX_EDIT;
|
||||
push @load, { 'dmid' => $1, 'itid'=> $2 };
|
||||
}
|
||||
|
||||
return "Nothing to show." unless @load;
|
||||
|
||||
$ret .= "<form method='post' action='editpage.bml'>";
|
||||
$ret .= LJ::html_hidden('lang', $lang,
|
||||
'mode', 'save');
|
||||
|
||||
# load item info
|
||||
my %ml_items;
|
||||
my $itwhere = join(" OR ", map { "(dmid=$_->{'dmid'} AND itid=$_->{'itid'})" } @load);
|
||||
$sth = $dbr->prepare("SELECT dmid, itid, itcode, notes FROM ml_items WHERE $itwhere");
|
||||
$sth->execute;
|
||||
while (my ($dmid, $itid, $itcode, $notes) = $sth->fetchrow_array) {
|
||||
$ml_items{"$dmid-$itid"} = { 'itcode' => $itcode, 'notes' => $notes };
|
||||
}
|
||||
|
||||
# getting latest mappings for this lang and parent
|
||||
my %ml_text;
|
||||
my %ml_latest;
|
||||
$sth = $dbr->prepare("SELECT lnid, dmid, itid, txtid, chgtime, staleness FROM ml_latest ".
|
||||
"WHERE ($itwhere) AND lnid IN ($l->{'lnid'}, $l->{'parentlnid'})");
|
||||
$sth->execute;
|
||||
return $dbr->errstr if $dbr->err;
|
||||
while ($_ = $sth->fetchrow_hashref) {
|
||||
$ml_latest{"$_->{'dmid'}-$_->{'itid'}"}->{$_->{'lnid'}} = $_;
|
||||
$ml_text{"$_->{'dmid'}-$_->{'txtid'}"} = undef; # mark to load later
|
||||
}
|
||||
|
||||
# load text
|
||||
$sth = $dbr->prepare("SELECT dmid, txtid, lnid, itid, text FROM ml_text ".
|
||||
"WHERE " . join(" OR ",
|
||||
map { "(dmid=$_->[0] AND txtid=$_->[1])" }
|
||||
map { [ split(/-/, $_) ] } keys %ml_text));
|
||||
$sth->execute;
|
||||
while ($_ = $sth->fetchrow_hashref) {
|
||||
$ml_text{"$_->{'dmid'}-$_->{'txtid'}"} = $_;
|
||||
}
|
||||
|
||||
if ($can_delete) {
|
||||
$ret .= "<p style='font-size:9pt'><b>To delete an item:</b> edit text to be \"XXDELXX\"</p>";
|
||||
}
|
||||
|
||||
# show all editing items
|
||||
my $ict = 0;
|
||||
foreach my $i (@load)
|
||||
{
|
||||
my ($dmid, $itid) = ($i->{'dmid'}, $i->{'itid'});
|
||||
my $ituq = "$dmid-$itid";
|
||||
my $it = $ml_items{$ituq};
|
||||
my $lat = $ml_latest{$ituq}->{$l->{'lnid'}};
|
||||
next unless $it and $lat;
|
||||
$ict++;
|
||||
|
||||
my $plat;
|
||||
if ($lp && defined $ml_latest{$ituq}->{$lp->{'lnid'}}) {
|
||||
$plat = $ml_latest{$ituq}->{$lp->{'lnid'}};
|
||||
}
|
||||
|
||||
$ret .= LJ::html_hidden("dom_$ict", $dmid,
|
||||
"itid_$ict", $itid,
|
||||
"oldtxtid_$ict", $lat->{'txtid'},
|
||||
"oldptxtid_$ict", $plat ? $plat->{'txtid'} : 0,
|
||||
);
|
||||
|
||||
# top bar
|
||||
$ret .= "<table bgcolor='#c0c0c0' width='100%'><tr><td><b>Code:</b> ";
|
||||
if ($dmid != 1) {
|
||||
my $d = LJ::Lang::get_dom_id($dmid);
|
||||
$ret .= "[$d->{'uniq'}] ";
|
||||
}
|
||||
|
||||
my $difflink;
|
||||
if ($lat->{'staleness'}) {
|
||||
$difflink = "($plat->{'chgtime'}, <a target='_new' href='diff.bml?it=$i->{'dmid'}:$i->{'itid'}&lang=$lp->{'lncode'}'>diff</a>)";
|
||||
}
|
||||
|
||||
$ret .= "$it->{'itcode'} $difflink</td>";
|
||||
$ret .= "<td align='right'><b><a target='_new' href='help-severity.bml'>Sev</a>:</b> $lat->{'staleness'}</td>";
|
||||
$ret .= "</tr></table>";
|
||||
|
||||
$ret .= "<dl>";
|
||||
if ($it->{'notes'}) {
|
||||
my $notes = $it->{'notes'};
|
||||
$notes =~ s!\n!<br />!g;
|
||||
$ret .= "<dt><b>Notes:</b></dt><dd>$notes</dd>";
|
||||
}
|
||||
|
||||
my $show_edit = 0;
|
||||
my $use_textarea = 0;
|
||||
|
||||
if ($plat) {
|
||||
$ret .= "<dt><b>$lp->{'lnname'}:</b></dt>";
|
||||
my $t = $ml_text{"$plat->{'dmid'}-$plat->{'txtid'}"}->{'text'};
|
||||
if ($t =~ /\n/) { $use_textarea = 1; }
|
||||
if (length($t) > 255) { $use_textarea = 1; }
|
||||
$t = LJ::eall($t);
|
||||
$t =~ s/\n( *)/"<br \/>" . " "x length($1)/eg;
|
||||
$ret .= "<dd>$t</dd>";
|
||||
}
|
||||
|
||||
my $curtext = LJ::eall($ml_text{"$lat->{'dmid'}-$lat->{'txtid'}"}->{'text'});
|
||||
if ($curtext =~ /\n/) { $use_textarea = 1; }
|
||||
if (length($curtext) > 255) { $use_textarea = 1; }
|
||||
if ($lat->{'staleness'} >= 3) {
|
||||
# if wrong language, why populate it with stuff they'll just have to delete?
|
||||
$curtext = "";
|
||||
}
|
||||
|
||||
$ret .= "<dt><b>$l->{'lnname'}</b>:</b></dt><dd>";
|
||||
my $disabled = "disabled='disabled'";
|
||||
if ($lat->{'staleness'} >= 3) {
|
||||
$disabled = "";
|
||||
# when something's this stale, assume both it's being
|
||||
# edited and that the severity is major (going from wrong
|
||||
# language to right language is a major change, afterall)
|
||||
$ret .= LJ::html_hidden("ed_$ict", "1",
|
||||
"sev_$ict", "2",
|
||||
);
|
||||
} else {
|
||||
$ret .= "<input name='ed_$ict' type='checkbox' value='1' id='ed_$ict' onClick='a=document.getElementById(\"newtext_$ict\"); a.disabled=!this.checked; if (this.checked) a.focus();' /><label for='ed_$ict'>Edit Text</label>";
|
||||
if ($l->{'children'} && @{$l->{'children'}}) {
|
||||
$ret .= " Severity: ";
|
||||
$ret .= LJ::html_select({ 'name' => "sev_$ict", "selected" => 1 },
|
||||
0 => "Typo/etc (no notify)",
|
||||
1 => "Minor (notify translators)",
|
||||
2 => "Major (require translation updates)");
|
||||
}
|
||||
$ret .= "<br />";
|
||||
}
|
||||
if ($use_textarea) {
|
||||
$ret .= "<textarea name='newtext_$ict' id='newtext_$ict' $disabled wrap='soft' rows='10' cols='60'>$curtext</textarea>";
|
||||
} else {
|
||||
$ret .= "<input name='newtext_$ict' id='newtext_$ict' $disabled size='60' value=\"$curtext\"/>";
|
||||
}
|
||||
$ret .= "</dd>\n";
|
||||
$ret .= "</dl>";
|
||||
}
|
||||
|
||||
if ($ict) {
|
||||
$ret .= LJ::html_hidden("ict", $ict);
|
||||
my $disabled = $can_edit ? "" : "disabled='disabled'";
|
||||
$ret .= "<table width='100%' bgcolor='#e0e0e0'><tr><td align='center'><input type='submit' $disabled value='Save' /></td></tr></table>";
|
||||
} else {
|
||||
$ret .= "No items to show. (since been deleted, perhaps?)";
|
||||
}
|
||||
$ret .= "</form>";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($mode eq "save")
|
||||
{
|
||||
my $num = $FORM{'ict'}+0;
|
||||
$num = $MAX_EDIT if $num > $MAX_EDIT;
|
||||
|
||||
my (@errors, @info);
|
||||
unless ($can_edit) {
|
||||
push @errors, "You don't have access to edit text for this language.";
|
||||
$num = 0;
|
||||
}
|
||||
|
||||
unless (LJ::text_in(\%FORM)) {
|
||||
push @errors, "You seem to have changed your browser's encoding to something other than UTF-8. It needs to be in UTF-8.";
|
||||
push @errors, "Nothing saved.";
|
||||
$num = 0;
|
||||
}
|
||||
|
||||
my $saved = 0; # do any saves?
|
||||
|
||||
for (my $i=1; $i<=$num; $i++)
|
||||
{
|
||||
next unless $FORM{"ed_$i"};
|
||||
my ($dom, $itid, $oldtxtid, $oldptxtid, $sev) =
|
||||
map { int($FORM{"${_}_$i"}+0) } qw(dom itid oldtxtid oldptxtid sev);
|
||||
|
||||
my $itcode = $dbr->selectrow_array("SELECT itcode FROM ml_items WHERE dmid=$dom AND itid=$itid");
|
||||
unless (defined $itcode) {
|
||||
push @errors, "Bogus dmid/itid: $dom/$itid";
|
||||
next;
|
||||
}
|
||||
|
||||
$dbh ||= LJ::get_db_writer();
|
||||
my $lat = $dbh->selectrow_hashref("SELECT * FROM ml_latest WHERE lnid=$l->{'lnid'} AND dmid=$dom AND itid=$itid");
|
||||
unless ($lat) {
|
||||
push @errors, "No existing mapping for $itcode";
|
||||
next;
|
||||
}
|
||||
unless ($lat->{'txtid'} == $oldtxtid) {
|
||||
push @errors, "Another translator updated '$itcode' before you saved, so your edit has been ignored.";
|
||||
next;
|
||||
}
|
||||
|
||||
my $plat;
|
||||
if ($lp) {
|
||||
$plat = $dbh->selectrow_hashref("SELECT * FROM ml_latest WHERE lnid=$lp->{'lnid'} ".
|
||||
"AND dmid=$dom AND itid=$itid");
|
||||
my $ptid = $plat ? $plat->{'txtid'} : 0;
|
||||
unless ($ptid == $oldptxtid) {
|
||||
push @errors, "The source text of item '$itcode' changed while you were editing, so your edit has been ignored.";
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
# did they type anything?
|
||||
my $text = $FORM{"newtext_$i"};
|
||||
next unless $text =~ /\S/;
|
||||
|
||||
# delete
|
||||
if ($text eq "XXDELXX") {
|
||||
if ($can_delete) {
|
||||
$dbh->do("DELETE FROM ml_latest WHERE dmid=$dom AND itid=$itid");
|
||||
push @info, "Deleted: '$itcode'";
|
||||
} else {
|
||||
push @errors, "You don't have access to delete items.";
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
# did anything even change, though?
|
||||
my $oldtext = $dbr->selectrow_array("SELECT text FROM ml_text WHERE dmid=$dom AND txtid=$lat->{'txtid'}");
|
||||
if ($oldtext eq $text && $lat->{'staleness'} == 2) {
|
||||
push @errors, "Severity of source language change requires change in text for item '$itcode'";
|
||||
next;
|
||||
}
|
||||
|
||||
# keep old txtid if text didn't change.
|
||||
my $opts = {};
|
||||
if ($oldtext eq $text) {
|
||||
$opts->{'txtid'} = $lat->{'txtid'};
|
||||
$text = undef;
|
||||
$sev = 0;
|
||||
}
|
||||
|
||||
# if setting text for first time, push down to children langs
|
||||
if ($lat->{'staleness'} == 4) {
|
||||
$opts->{'childrenlatest'} = 1;
|
||||
}
|
||||
|
||||
# severity of change:
|
||||
$opts->{'changeseverity'} = $sev;
|
||||
|
||||
# set userid of writer
|
||||
$opts->{'userid'} = $remote->{'userid'};
|
||||
|
||||
my $res = LJ::Lang::set_text($dom, $l->{'lncode'}, $itcode, $text, $opts);
|
||||
unless ($res) {
|
||||
push @errors, LJ::Lang::last_error();
|
||||
} else {
|
||||
push @info, "Saved: $itcode";
|
||||
$saved = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$dbh ||= LJ::get_db_writer();
|
||||
$dbh->do("UPDATE ml_langs SET lastupdate=NOW() WHERE lnid=$l->{'lnid'}") if $saved;
|
||||
|
||||
if (@errors) {
|
||||
$ret .= "<b>ERRORS:</b><ul>";
|
||||
foreach (@errors) { $ret .= "<li>$_</li>"; }
|
||||
$ret .= "</ul>";
|
||||
}
|
||||
if (@info) {
|
||||
$ret .= "<b>Results:</b><ul>";
|
||||
foreach (@info) { $ret .= "<li>$_</li>"; }
|
||||
$ret .= "</ul>";
|
||||
}
|
||||
if (! @errors && ! @info) {
|
||||
$ret .= "<i>No errors & nothing saved.</i>";
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
_code?>
|
||||
</body>
|
||||
</html>
|
||||
12
livejournal/htdocs/translate/help-severity.bml
Executable file
12
livejournal/htdocs/translate/help-severity.bml
Executable file
@@ -0,0 +1,12 @@
|
||||
<h1>Description of severity levels:</h1>
|
||||
|
||||
<table cellpadding='3'>
|
||||
<tr valign='top'><td><b>0</b></td><td>Translate is up-to-date</td></tr>
|
||||
<tr valign='top'><td><b>1</b></td><td>Parent language has changed a little. Your translation might need updating.</td></tr>
|
||||
<tr valign='top'><td><b>2</b></td><td>Parent language has changed. Your translation probably needs updating.</td></tr>
|
||||
<tr valign='top'><td><b>3</b></td><td>New text was added in parent language which you haven't yet translated.</td></tr>
|
||||
<tr valign='top'><td><b>4</b></td><td>Item code in use but no text exists yet for any language.</td></tr>
|
||||
</table>
|
||||
|
||||
<h2>Searching</h2>
|
||||
When searching, you can search for a certain severity level (0, 1, 2, 3, 4) or search for everything at or above a certain severity level (0+, 1+, 2+, 3+).
|
||||
70
livejournal/htdocs/translate/index.bml
Executable file
70
livejournal/htdocs/translate/index.bml
Executable file
@@ -0,0 +1,70 @@
|
||||
<?page
|
||||
title=>Translation Area
|
||||
body<=
|
||||
|
||||
<?_code
|
||||
|
||||
my $dbr = LJ::get_db_reader();
|
||||
my $sth;
|
||||
|
||||
$sth = $dbr->prepare("SELECT lnid, lncode, lnname, lastupdate FROM ml_langs");
|
||||
$sth->execute;
|
||||
my %lang;
|
||||
$lang{$_->{'lnid'}} = $_ while $_ = $sth->fetchrow_hashref;
|
||||
|
||||
$sth = $dbr->prepare("SELECT lnid, staleness > 1, COUNT(*) FROM ml_latest GROUP by 1, 2");
|
||||
$sth->execute;
|
||||
while (my ($lnid, $stale, $ct) = $sth->fetchrow_array) {
|
||||
next unless exists $lang{$lnid};
|
||||
$lang{$lnid}->{'_total'} += $ct;
|
||||
$lang{$lnid}->{'_good'} += (1-$stale) * $ct;
|
||||
$lang{$lnid}->{'percent'} = 100 * $lang{$lnid}->{'_good'} / ($lang{$lnid}->{'_total'}||1);
|
||||
}
|
||||
|
||||
my $sortcol = exists $lang{'1'}->{$FORM{'s'}} ? $FORM{'s'} : "lnname";
|
||||
my @cols = (['lncode','Code'],
|
||||
['lnname','Language Name', sub {
|
||||
my $r = shift;
|
||||
"<td><a href='edit.bml?lang=$r->{'lncode'}'>$r->{'lnname'}</a></td>";
|
||||
}],
|
||||
['percent','% Done', sub {
|
||||
my $r = shift;
|
||||
"<td align='right'><b>" .
|
||||
sprintf("%.02f%%", $r->{'percent'}) . "</b><br />" .
|
||||
"<font size='-1'>$r->{'_good'}/$r->{'_total'}</font>" .
|
||||
"</td>";
|
||||
}, sub { $b->{'percent'} <=> $a->{'percent'} ||
|
||||
$b->{'_total'} <=> $a->{'_total'} }],
|
||||
['lastupdate','Last Update',undef,
|
||||
sub { $b->{'lastupdate'} cmp $a->{'lastupdate'} }]);
|
||||
my $ret;
|
||||
my $sorter = sub { $a->{$sortcol} cmp $b->{$sortcol} };
|
||||
|
||||
$ret .= "The following table lists the progress by each of the different <a href='teams.bml'>translation teams</a>.";
|
||||
|
||||
$ret .= "<p><table border='1' cellspacing='1' cellpadding='3'><tr>";
|
||||
foreach (@cols) {
|
||||
if ($sortcol eq $_->[0]) {
|
||||
$ret .= "<td><b>$_->[1]</b></td>";
|
||||
} else {
|
||||
$ret .= "<td><b><a href=\"./?s=$_->[0]\">$_->[1]</a></b></td>";
|
||||
}
|
||||
if ($_->[0] eq $sortcol && $_->[3]) { $sorter = $_->[3]; }
|
||||
}
|
||||
$ret .= "</tr>\n";
|
||||
|
||||
foreach my $r (sort $sorter values %lang) {
|
||||
$ret .= "<tr>";
|
||||
foreach (@cols) {
|
||||
$ret .= $_->[2] ? $_->[2]->($r) : "<td>$r->{$_->[0]}</td>";
|
||||
}
|
||||
$ret .= "</tr>\n";
|
||||
}
|
||||
|
||||
$ret .= "</table>\n";
|
||||
return $ret;
|
||||
|
||||
_code?>
|
||||
|
||||
<=body
|
||||
page?>
|
||||
77
livejournal/htdocs/translate/search.bml
Executable file
77
livejournal/htdocs/translate/search.bml
Executable file
@@ -0,0 +1,77 @@
|
||||
<?_code
|
||||
{
|
||||
my $lang = $FORM{'lang'};
|
||||
my $l = LJ::Lang::get_lang($lang);
|
||||
return "<b>Invalid language</b>" unless $l;
|
||||
|
||||
my $dbr = LJ::get_db_reader();
|
||||
my $sth;
|
||||
|
||||
my $sql;
|
||||
|
||||
if ($FORM{'search'} eq 'sev')
|
||||
{
|
||||
my $what = ">= 1";
|
||||
if ($FORM{'stale'} =~ /^(\d+)(\+?)$/) {
|
||||
$what = ($2 ? ">=" : "=") . $1;
|
||||
}
|
||||
$sql = "SELECT i.dmid, i.itid, i.itcode FROM ml_items i, ml_latest l WHERE l.lnid=$l->{'lnid'} AND l.staleness $what AND l.dmid=i.dmid AND l.itid=i.itid ORDER BY i.dmid, i.itcode";
|
||||
}
|
||||
|
||||
if ($FORM{'search'} eq 'txt')
|
||||
{
|
||||
my $remote = LJ::get_remote();
|
||||
return "This search type is restricted to $l->{'lnname'} translators." unless
|
||||
(LJ::check_priv($remote, "translate", "*") ||
|
||||
LJ::check_priv($remote, "translate", $l->{'lncode'}) ||
|
||||
LJ::check_priv($remote, "faqedit", "*")); # FAQ admins can search too
|
||||
|
||||
my $qtext = $dbr->quote($FORM{'searchtext'});
|
||||
my $dmid = $FORM{'searchdomain'}+0;
|
||||
my $dmidwhere = $dmid ? "AND i.dmid=$dmid" : "";
|
||||
if ($FORM{'searchwhat'} eq "code") {
|
||||
$sql = qq{
|
||||
SELECT i.dmid, i.itid, i.itcode FROM ml_items i, ml_latest l
|
||||
WHERE l.lnid=$l->{'lnid'} AND l.dmid=i.dmid AND i.itid=l.itid
|
||||
$dmidwhere AND LOCATE($qtext, i.itcode)
|
||||
};
|
||||
} else {
|
||||
my $lnid = $l->{'lnid'};
|
||||
if ($FORM{'searchwhat'} eq "parent") { $lnid = $l->{'parentlnid'}; }
|
||||
$sql = qq{
|
||||
SELECT i.dmid, i.itid, i.itcode FROM ml_items i, ml_latest l, ml_text t
|
||||
WHERE l.lnid=$lnid AND l.dmid=i.dmid AND i.itid=l.itid
|
||||
$dmidwhere AND t.dmid=l.dmid AND t.txtid=l.txtid AND LOCATE($qtext, t.text)
|
||||
ORDER BY i.itcode
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return "Bogus or unimplemented query type." unless $sql;
|
||||
|
||||
my $ret;
|
||||
$sth = $dbr->prepare($sql);
|
||||
$sth->execute;
|
||||
my $page = 0;
|
||||
my @page = ();
|
||||
my $addlink = sub {
|
||||
return unless @page;
|
||||
$page++;
|
||||
my $link = "editpage.bml?lang=$lang&items=" . LJ::eurl(join(",",map{"$_->[0]:$_->[1]"}@page));
|
||||
$ret .= "<b><a target='main' href='$link'>Page $page</a></b><br /><span style='font-size:8pt'>\n";
|
||||
$ret .= "$page[0]->[2]<br />\n";
|
||||
$ret .= "$page[-1]->[2]<br /></span>\n";
|
||||
@page = ();
|
||||
};
|
||||
while (my ($dmid, $itid, $itcode) = $sth->fetchrow_array) {
|
||||
push @page, [ $dmid, $itid, $itcode ];
|
||||
$addlink->() if @page >= 10;
|
||||
}
|
||||
$addlink->();
|
||||
|
||||
if ($page == 0) { $ret .= "<i>(No matches)</i>"; }
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
_code?>
|
||||
61
livejournal/htdocs/translate/searchform.bml
Executable file
61
livejournal/htdocs/translate/searchform.bml
Executable file
@@ -0,0 +1,61 @@
|
||||
<html>
|
||||
<head><title>Search Form</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body marginwidth='0' marginheight='0'>
|
||||
<form target='res' action='search.bml' method='get'>
|
||||
<input type='hidden' name='lang' value='<?_code $FORM{'lang'} _code?>'>
|
||||
<input type='hidden' name='search' value='sev'>
|
||||
|
||||
[<a href="./" target='_top'><-- Back</a>]
|
||||
<?_code
|
||||
my $lang = $FORM{'lang'};
|
||||
my $l = LJ::Lang::get_lang($lang);
|
||||
BML::finish() unless $l;
|
||||
return "<b>" . ($l ? $l->{'lnname'} : "Invalid language") . "</b>";
|
||||
_code?>
|
||||
|
||||
<p>By Severity: (<a href='help-severity.bml' target='main'>help</a>)<br /><select name='stale'>
|
||||
<option value="0">0</option>
|
||||
<option value="0+">0+</option>
|
||||
<option value="1">1</option>
|
||||
<option value="1+" selected='selected'>1+</option>
|
||||
<option value="2">2</option>
|
||||
<option value="2+">2+</option>
|
||||
<option value="3">3</option>
|
||||
<option value="3+">3+</option>
|
||||
<option value="4">4</option>
|
||||
</select><input type='submit' value='Search'/>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<form target='res' action='search.bml' method='get'>
|
||||
<input type='hidden' name='lang' value='<?_code $FORM{'lang'} _code?>'>
|
||||
<input type='hidden' name='search' value='txt'>
|
||||
|
||||
<p>Search
|
||||
<?_code
|
||||
my $ret;
|
||||
my $l = LJ::Lang::get_lang($FORM{'lang'});
|
||||
my $pl = LJ::Lang::get_lang_id($l->{'parentlnid'});
|
||||
my @opt = ("src" => $l->{'lnname'});
|
||||
if ($pl) { push @opt, "parent", $pl->{'lnname'} };
|
||||
push @opt, "code", "Item Code";
|
||||
$ret .= LJ::html_select({ 'name' => 'searchwhat' },
|
||||
@opt);
|
||||
$ret .= "<br />Area: ";
|
||||
$ret .= LJ::html_select({ 'name' => 'searchdomain' },
|
||||
0, "(all)",
|
||||
map { $_->{'dmid'}, $_->{'uniq'} }
|
||||
sort { $a->{'dmid'} <=> $b->{'dmid'} } LJ::Lang::get_domains());
|
||||
return $ret;
|
||||
_code?>
|
||||
<br />Text: <input name='searchtext' size='15'><input type='submit' value='Search'>
|
||||
</p>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
65
livejournal/htdocs/translate/teams.bml
Executable file
65
livejournal/htdocs/translate/teams.bml
Executable file
@@ -0,0 +1,65 @@
|
||||
<?page
|
||||
title=>Translation Teams
|
||||
body<=
|
||||
|
||||
<a href="./"><<</a> Back to progress page.
|
||||
|
||||
<?h1 Teams h1?>
|
||||
<?p
|
||||
Translation is being done by the following teams:
|
||||
p?>
|
||||
|
||||
<?_code
|
||||
|
||||
my $dbr = LJ::get_db_reader();
|
||||
my ($ret, $sth);
|
||||
|
||||
# get langs
|
||||
$sth = $dbr->prepare("SELECT lnid, lncode, lnname, lastupdate FROM ml_langs");
|
||||
$sth->execute;
|
||||
my %lang;
|
||||
$lang{$_->{'lnid'}} = $_ while $_ = $sth->fetchrow_hashref;
|
||||
|
||||
# get each lang's community
|
||||
$sth = $dbr->prepare("SELECT l.lnid, t.text ".
|
||||
"FROM ml_latest l, ml_items i, ml_text t ".
|
||||
"WHERE l.dmid=1 AND t.dmid=1 AND i.dmid=1 AND i.itcode='thislang.community' ".
|
||||
"AND l.itid=i.itid AND t.txtid=l.txtid AND t.lnid=l.lnid");
|
||||
$sth->execute;
|
||||
while ($_ = $sth->fetchrow_hashref) {
|
||||
next unless exists $lang{$_->{'lnid'}};
|
||||
$lang{$_->{'lnid'}}->{'community'} = $_->{'text'};
|
||||
}
|
||||
|
||||
# get people with privs
|
||||
$sth = $dbr->prepare("SELECT pm.arg, u.user FROM useridmap u, priv_list pl, priv_map pm ".
|
||||
"WHERE pm.userid=u.userid AND pm.prlid=pl.prlid AND pl.privcode='translate'");
|
||||
$sth->execute;
|
||||
my %team;
|
||||
while (my ($arg, $user) = $sth->fetchrow_array) {
|
||||
push @{$team{$arg}}, $user;
|
||||
}
|
||||
|
||||
$ret .= "<p><table cellpadding='5' border='1'>";
|
||||
$ret .= "<tr><th>Language</th><th>Community</th><th>Users with privs</th></tr>";
|
||||
|
||||
foreach my $l (sort { $a->{'lncode'} cmp $b->{'lncode'} } values %lang)
|
||||
{
|
||||
$ret .= "<tr valign='top' align='left'><td><b>$l->{'lnname'}</b></td>";
|
||||
$ret .= "<td>";
|
||||
$ret .= "<?ljcomm $l->{'community'} ljcomm?>" if $l->{'community'};
|
||||
$ret .= "</td><td>";
|
||||
if ($team{$l->{'lncode'}}) {
|
||||
$ret .= join(", ", map { LJ::ljuser($_) }
|
||||
sort @{$team{$l->{'lncode'}}});
|
||||
}
|
||||
$ret .= "</td></tr>\n";
|
||||
}
|
||||
|
||||
$ret .= "</table>";
|
||||
return $ret;
|
||||
|
||||
_code?>
|
||||
|
||||
<=body
|
||||
page?>
|
||||
7
livejournal/htdocs/translate/welcome.bml
Executable file
7
livejournal/htdocs/translate/welcome.bml
Executable file
@@ -0,0 +1,7 @@
|
||||
Welcome to the translation area.
|
||||
|
||||
<p>In the top-left frame you search for phrases to translate.
|
||||
|
||||
<p>The lower-left frame shows your search result links, paginated.
|
||||
|
||||
<p>This large frame is the work area, in which text is edited.
|
||||
Reference in New Issue
Block a user