[dw-free] move /translate to /admin/translate
[commit: http://hg.dwscoalition.org/dw-free/rev/8428f0b6ae2d]
http://bugs.dwscoalition.org/show_bug.cgi?id=2323
Move all pages under /translate to /admin/translate.
Patch by
denise.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=2323
Move all pages under /translate to /admin/translate.
Patch by
![[staff profile]](https://www.dreamwidth.org/img/silk/identity/user_staff.png)
Files modified:
- cgi-bin/redirect.dat
- htdocs/admin/index.bml
- htdocs/admin/index.bml.text
- htdocs/admin/translate/diff.bml
- htdocs/admin/translate/edit.bml
- htdocs/admin/translate/editpage.bml
- htdocs/admin/translate/help-severity.bml
- htdocs/admin/translate/index.bml
- htdocs/admin/translate/index.bml.text
- htdocs/admin/translate/search.bml
- htdocs/admin/translate/searchform.bml
- htdocs/admin/translate/teams.bml
- htdocs/admin/translate/teams.bml.text
- htdocs/admin/translate/welcome.bml
- htdocs/translate/diff.bml
- htdocs/translate/edit.bml
- htdocs/translate/editpage.bml
- htdocs/translate/help-severity.bml
- htdocs/translate/index.bml
- htdocs/translate/index.bml.text
- htdocs/translate/search.bml
- htdocs/translate/searchform.bml
- htdocs/translate/teams.bml
- htdocs/translate/teams.bml.text
- htdocs/translate/welcome.bml
-------------------------------------------------------------------------------- diff -r 9323f181bcb6 -r 8428f0b6ae2d cgi-bin/redirect.dat --- a/cgi-bin/redirect.dat Tue Feb 16 15:09:47 2010 +0000 +++ b/cgi-bin/redirect.dat Tue Feb 16 15:26:10 2010 +0000 @@ -45,3 +45,13 @@ /mobile/friends.bml /mobile/read /misc/import /tools/importer /misc/import.bml /tools/importer +/translate /admin/translate +/translate/ /admin/translate +/translate/diff.bml /admin/translate/diff +/translate/edit.bml /admin/translate/edit +/translate/editpage.bml /admin/translate/editpage +/translate/help-severity.bml /admin/translate/help-severity +/translate/search.bml /admin/translate/search +/translate/searchform.bml /admin/translate/searchform +/translate/teams.bml /admin/translate/teams +/translate/welcome.bml /admin/translate/welcome diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/index.bml --- a/htdocs/admin/index.bml Tue Feb 16 15:09:47 2010 +0000 +++ b/htdocs/admin/index.bml Tue Feb 16 15:26:10 2010 +0000 @@ -100,6 +100,8 @@ body<= '<?_ml .admin.sysban.link _ml?>', '<?_ml .admin.sysban.text _ml?>', [ 'sysban' ] ], [ 'theschwartz', '<?_ml .admin.theschwartz.link _ml?>', '<?_ml .admin.theschwartz.text _ml?>', [ 'siteadmin:theschwartz' ] ], + [ 'translate/', + '<?_ml .admin.translate.link _ml?>', '<?_ml .admin.translate.text _ml?>' ], [ 'userlog', '<?_ml .admin.userlog.link _ml?>', '<?_ml .admin.userlog.text _ml?>', [ 'canview:userlog', 'canview:*' ] ], ); diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/index.bml.text --- a/htdocs/admin/index.bml.text Tue Feb 16 15:09:47 2010 +0000 +++ b/htdocs/admin/index.bml.text Tue Feb 16 15:26:10 2010 +0000 @@ -80,6 +80,9 @@ .admin.theschwartz.link=TheSchwartz Queue/Error Viewer .admin.theschwartz.text=View the status of jobs in the TheSchwartz queue. +.admin.translate.link=Translation & Site Copy +.admin.translate.text=View and edit the site copy and translations. + .admin.userlog.link=Userlog Viewer .admin.userlog.text=Shows you a user's logged actions. diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/diff.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/diff.bml Tue Feb 16 15:26:10 2010 +0000 @@ -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?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> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/edit.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/edit.bml Tue Feb 16 15:26:10 2010 +0000 @@ -0,0 +1,14 @@ +<html> +<head> + <title>Language Editor</title> +</head> + +<frameset cols="200,*"> + <frameset rows="230,*"> + <frame name="search" src="searchform?lang=<?_code return $FORM{'lang'}; _code?>"> + <frame name="res" src="search?lang=<?_code return $FORM{'lang'}; _code?>&stale=1%2B&search=sev"> + </frameset> + <frame name="main" src="welcome"> +</frameset> + +</html> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/editpage.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/editpage.bml Tue Feb 16 15:26:10 2010 +0000 @@ -0,0 +1,363 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<?_code +{ + LJ::Hooks::run_hook('trans_editpage_bml_postsave_begin'); + return LJ::res_includes(); +} + _code?> +</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 = $remote && $remote->has_priv( "translate", $l->{'lncode'} ); + my $can_delete = $remote && $remote->has_priv( "translate", "[itemdelete]" ); + my $can_rename = $remote && $remote->has_priv( "translate", "[itemrename]" ); + + # Extra checkboxes for default language and root language (DW: en_DW and en) + my $extra_checkboxes = $l->{'lncode'} eq $LJ::DEFAULT_LANG || !defined $lp; + + 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'>"; + $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, proofed, updated, notes FROM ml_items WHERE $itwhere"); + $sth->execute; + while (my ($dmid, $itid, $itcode, $proofed, $updated, $notes) = $sth->fetchrow_array) { + $ml_items{"$dmid-$itid"} = { 'itcode' => $itcode, 'proofed' => $proofed, 'updated' => $updated, '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?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'>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 { + my $js = "a=document.getElementById(\"newtext_$ict\"); a.disabled=!this.checked; if (this.checked) a.focus();"; + $js .= "a=document.getElementById(\"pr_$ict\"); a.disabled=!this.checked; a=document.getElementById(\"up_$ict\"); a.disabled=!this.checked;" + if $extra_checkboxes; + $ret .= "<input name='ed_$ict' type='checkbox' value='1' id='ed_$ict' onClick='$js' /><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 />" unless $extra_checkboxes; + } + + if ( $extra_checkboxes ) { + $ret .= " "; + $ret .= LJ::html_check( { type => 'checkbox', label => 'Proofed', + selected => $it->{proofed}, value => 1, + name => "pr_$ict", id => "pr_$ict", + disabled => $disabled eq '' ? 0 : 1 } ); + $ret .= " "; + $ret .= LJ::html_check( { type => 'checkbox', label => 'Updated', + selected => $it->{updated}, value => 1, + name => "up_$ict", id => "up_$ict", + disabled => $disabled eq '' ? 0 : 1 } ); + $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, $proofed, $updated) = + map { int($FORM{"${_}_$i"}+0) } + qw(dom itid oldtxtid oldptxtid sev pr up); + + 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, $msg) = LJ::Lang::web_set_text($dom, $l->{'lncode'}, $itcode, $text, $opts); + if ($res) { + push @info, "OK: $itcode"; + $saved = 1; + + if ( $extra_checkboxes ) { + # Not gonna bother to refactor to LJ::Lang as the whole + # translation system will get thrown away and redone later. + # FIXME: make sure my words don't come back to haunt me. + $dbh->do( "UPDATE ml_items SET proofed = ?, updated = ? " . + "WHERE dmid = ? AND itid = ?", undef, $proofed ? 1 : 0, + $updated ? 1 : 0, $dom, $itid ); + + if ( $dbh->err ) { + push @errors, $dbh->errstr; + } else { + push @info, "OK: $itcode (flags)"; + } + } + } else { + push @errors, $msg; + } + + push @info, LJ::Hooks::run_hook('trans_editpage_bml_postsave', $opts) + if LJ::Hooks::are_hooks('trans_editpage_bml_postsave'); + } + + $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> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/help-severity.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/help-severity.bml Tue Feb 16 15:26:10 2010 +0000 @@ -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+). diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/index.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/index.bml Tue Feb 16 15:26:10 2010 +0000 @@ -0,0 +1,78 @@ +<?page +title=><?_ml .title _ml?> +body<= + +<?_code +{ + use strict; + + my $dbr = LJ::get_db_reader(); + my $sth; + + LJ::set_active_crumb('translate'); + + $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', $ML{'.table.code'}], + ['lnname', $ML{'.table.langname'}, sub { + my $r = shift; + "<td><a href='edit?lang=$r->{'lncode'}'>$r->{'lnname'}</a></td>"; + }], + ['percent', $ML{'.table.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', $ML{'.table.lastupdate'}, undef, sub { + $b->{'lastupdate'} cmp $a->{'lastupdate'} + }]); + my $ret; + my $sorter = sub { $a->{$sortcol} cmp $b->{$sortcol} }; + + $ret .= BML::ml('.text', {'aopts' => "href='$LJ::SITEROOT/admin/translate/teams'"}); + + $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?> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/index.bml.text --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/index.bml.text Tue Feb 16 15:26:10 2010 +0000 @@ -0,0 +1,13 @@ +;; -*- coding: utf-8 -*- +.table.code=Code + +.table.done=% Done + +.table.langname=Language Name + +.table.lastupdate=Last Update + +.text=The following table lists the progress by each of the different <a [[aopts]]>translation teams</a>. + +.title=Translation Area + diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/search.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/search.bml Tue Feb 16 15:26:10 2010 +0000 @@ -0,0 +1,100 @@ +<?_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; + + # all queries use the visible flag + my $vis_flag = ''; + $vis_flag = 'AND i.visible = 1' unless $LJ::IS_DEV_SERVER; + + if ($FORM{'search'} eq 'sev') + { + my $what = ">= 1"; + if ($FORM{'stale'} =~ /^(\d+)(\+?)$/) { + $what = ($2 ? ">=" : "=") . $1; + } + $sql = qq( + 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 $vis_flag + 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 + $remote && ( $remote->has_priv( "translate", $l->{'lncode'} ) || + $remote->has_priv( "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 $vis_flag + $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) $vis_flag + ORDER BY i.itcode + }; + } + } + + if ($FORM{'search'} eq 'flg') { + return "This type of search isn't available for this language." + unless $l->{'lncode'} eq $LJ::DEFAULT_LANG || !$l->{'parentlnid'}; + + my $whereflags = join ' AND ', + map { $FORM{"searchflag$_"} eq 'yes' ? "$_ = 1" : "$_ = 0" } + grep { $FORM{"searchflag$_"} ne 'whatev' } qw(proofed updated); + $whereflags = "AND $whereflags" + if $whereflags ne ''; + $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 l.itid=i.itid $whereflags $vis_flag + ORDER BY i.dmid, 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?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?> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/searchform.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/searchform.bml Tue Feb 16 15:26:10 2010 +0000 @@ -0,0 +1,80 @@ +<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' 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' 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' 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> + +<?_code + my $l = LJ::Lang::get_lang($FORM{'lang'}); + return '' unless $l->{'lncode'} eq $LJ::DEFAULT_LANG || !$l->{'parentlnid'}; + + my $ret = <<HTML; +<form target='res' action='search' method='get'> +<input type='hidden' name='lang' value='$l->{lncode}'> +<input type='hidden' name='search' value='flg'> +<p><table><tr><td>Prf:</td> +<td><input type='radio' name='searchflagproofed' value='whatev'>Both</td> +<td><input type='radio' name='searchflagproofed' value='yes'>Yes</td> +<td><input type='radio' name='searchflagproofed' value='no'>No</td></tr> +<tr><td>Upd:</td> +<td><input type='radio' name='searchflagupdated' value='whatev'>Both</td> +<td><input type='radio' name='searchflagupdated' value='yes'>Yes</td> +<td><input type='radio' name='searchflagupdated' value='no'>No</td></tr></table> +<input type='submit' value='Search'></p></form> +HTML + return $ret; +_code?> + +</body> +</html> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/teams.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/teams.bml Tue Feb 16 15:26:10 2010 +0000 @@ -0,0 +1,63 @@ +<?page +title=><?_ml .title _ml?> +body<= +<?_code +{ + use strict; + + my $dbr = LJ::get_db_reader(); + my ($ret, $sth); + + LJ::set_active_crumb('translateteams'); + + $ret .= "<?h1 $ML{'.teams.header'} h1?>"; + $ret .= "<?p $ML{'.teams.text'} p?>"; + + # 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>$ML{'.table.language'}</th><th>$ML{'.table.community'}</th><th>$ML{'.table.users'}</th></tr>"; + + foreach my $l (sort { $a->{'lnname'} cmp $b->{'lnname'} } 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?> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/teams.bml.text --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/teams.bml.text Tue Feb 16 15:26:10 2010 +0000 @@ -0,0 +1,13 @@ +;; -*- coding: utf-8 -*- +.table.community=Community + +.table.language=Language + +.table.users=Users With Privs + +.teams.header=Teams + +.teams.text=Translation is being done by the following teams: + +.title=Translation Teams + diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/admin/translate/welcome.bml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/htdocs/admin/translate/welcome.bml Tue Feb 16 15:26:10 2010 +0000 @@ -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. diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/diff.bml --- a/htdocs/translate/diff.bml Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -<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?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> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/edit.bml --- a/htdocs/translate/edit.bml Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -<html> -<head> - <title>Language Editor</title> -</head> - -<frameset cols="200,*"> - <frameset rows="230,*"> - <frame name="search" src="searchform?lang=<?_code return $FORM{'lang'}; _code?>"> - <frame name="res" src="search?lang=<?_code return $FORM{'lang'}; _code?>&stale=1%2B&search=sev"> - </frameset> - <frame name="main" src="welcome"> -</frameset> - -</html> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/editpage.bml --- a/htdocs/translate/editpage.bml Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,363 +0,0 @@ -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -<?_code -{ - LJ::Hooks::run_hook('trans_editpage_bml_postsave_begin'); - return LJ::res_includes(); -} - _code?> -</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 = $remote && $remote->has_priv( "translate", $l->{'lncode'} ); - my $can_delete = $remote && $remote->has_priv( "translate", "[itemdelete]" ); - my $can_rename = $remote && $remote->has_priv( "translate", "[itemrename]" ); - - # Extra checkboxes for default language and root language (DW: en_DW and en) - my $extra_checkboxes = $l->{'lncode'} eq $LJ::DEFAULT_LANG || !defined $lp; - - 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'>"; - $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, proofed, updated, notes FROM ml_items WHERE $itwhere"); - $sth->execute; - while (my ($dmid, $itid, $itcode, $proofed, $updated, $notes) = $sth->fetchrow_array) { - $ml_items{"$dmid-$itid"} = { 'itcode' => $itcode, 'proofed' => $proofed, 'updated' => $updated, '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?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'>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 { - my $js = "a=document.getElementById(\"newtext_$ict\"); a.disabled=!this.checked; if (this.checked) a.focus();"; - $js .= "a=document.getElementById(\"pr_$ict\"); a.disabled=!this.checked; a=document.getElementById(\"up_$ict\"); a.disabled=!this.checked;" - if $extra_checkboxes; - $ret .= "<input name='ed_$ict' type='checkbox' value='1' id='ed_$ict' onClick='$js' /><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 />" unless $extra_checkboxes; - } - - if ( $extra_checkboxes ) { - $ret .= " "; - $ret .= LJ::html_check( { type => 'checkbox', label => 'Proofed', - selected => $it->{proofed}, value => 1, - name => "pr_$ict", id => "pr_$ict", - disabled => $disabled eq '' ? 0 : 1 } ); - $ret .= " "; - $ret .= LJ::html_check( { type => 'checkbox', label => 'Updated', - selected => $it->{updated}, value => 1, - name => "up_$ict", id => "up_$ict", - disabled => $disabled eq '' ? 0 : 1 } ); - $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, $proofed, $updated) = - map { int($FORM{"${_}_$i"}+0) } - qw(dom itid oldtxtid oldptxtid sev pr up); - - 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, $msg) = LJ::Lang::web_set_text($dom, $l->{'lncode'}, $itcode, $text, $opts); - if ($res) { - push @info, "OK: $itcode"; - $saved = 1; - - if ( $extra_checkboxes ) { - # Not gonna bother to refactor to LJ::Lang as the whole - # translation system will get thrown away and redone later. - # FIXME: make sure my words don't come back to haunt me. - $dbh->do( "UPDATE ml_items SET proofed = ?, updated = ? " . - "WHERE dmid = ? AND itid = ?", undef, $proofed ? 1 : 0, - $updated ? 1 : 0, $dom, $itid ); - - if ( $dbh->err ) { - push @errors, $dbh->errstr; - } else { - push @info, "OK: $itcode (flags)"; - } - } - } else { - push @errors, $msg; - } - - push @info, LJ::Hooks::run_hook('trans_editpage_bml_postsave', $opts) - if LJ::Hooks::are_hooks('trans_editpage_bml_postsave'); - } - - $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> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/help-severity.bml --- a/htdocs/translate/help-severity.bml Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -<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+). diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/index.bml --- a/htdocs/translate/index.bml Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -<?page -title=><?_ml .title _ml?> -body<= - -<?_code -{ - use strict; - - my $dbr = LJ::get_db_reader(); - my $sth; - - LJ::set_active_crumb('translate'); - - $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', $ML{'.table.code'}], - ['lnname', $ML{'.table.langname'}, sub { - my $r = shift; - "<td><a href='edit?lang=$r->{'lncode'}'>$r->{'lnname'}</a></td>"; - }], - ['percent', $ML{'.table.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', $ML{'.table.lastupdate'}, undef, sub { - $b->{'lastupdate'} cmp $a->{'lastupdate'} - }]); - my $ret; - my $sorter = sub { $a->{$sortcol} cmp $b->{$sortcol} }; - - $ret .= BML::ml('.text', {'aopts' => "href='$LJ::SITEROOT/translate/teams'"}); - - $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?> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/index.bml.text --- a/htdocs/translate/index.bml.text Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -;; -*- coding: utf-8 -*- -.table.code=Code - -.table.done=% Done - -.table.langname=Language Name - -.table.lastupdate=Last Update - -.text=The following table lists the progress by each of the different <a [[aopts]]>translation teams</a>. - -.title=Translation Area - diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/search.bml --- a/htdocs/translate/search.bml Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -<?_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; - - # all queries use the visible flag - my $vis_flag = ''; - $vis_flag = 'AND i.visible = 1' unless $LJ::IS_DEV_SERVER; - - if ($FORM{'search'} eq 'sev') - { - my $what = ">= 1"; - if ($FORM{'stale'} =~ /^(\d+)(\+?)$/) { - $what = ($2 ? ">=" : "=") . $1; - } - $sql = qq( - 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 $vis_flag - 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 - $remote && ( $remote->has_priv( "translate", $l->{'lncode'} ) || - $remote->has_priv( "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 $vis_flag - $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) $vis_flag - ORDER BY i.itcode - }; - } - } - - if ($FORM{'search'} eq 'flg') { - return "This type of search isn't available for this language." - unless $l->{'lncode'} eq $LJ::DEFAULT_LANG || !$l->{'parentlnid'}; - - my $whereflags = join ' AND ', - map { $FORM{"searchflag$_"} eq 'yes' ? "$_ = 1" : "$_ = 0" } - grep { $FORM{"searchflag$_"} ne 'whatev' } qw(proofed updated); - $whereflags = "AND $whereflags" - if $whereflags ne ''; - $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 l.itid=i.itid $whereflags $vis_flag - ORDER BY i.dmid, 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?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?> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/searchform.bml --- a/htdocs/translate/searchform.bml Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -<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' 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' 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' 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> - -<?_code - my $l = LJ::Lang::get_lang($FORM{'lang'}); - return '' unless $l->{'lncode'} eq $LJ::DEFAULT_LANG || !$l->{'parentlnid'}; - - my $ret = <<HTML; -<form target='res' action='search' method='get'> -<input type='hidden' name='lang' value='$l->{lncode}'> -<input type='hidden' name='search' value='flg'> -<p><table><tr><td>Prf:</td> -<td><input type='radio' name='searchflagproofed' value='whatev'>Both</td> -<td><input type='radio' name='searchflagproofed' value='yes'>Yes</td> -<td><input type='radio' name='searchflagproofed' value='no'>No</td></tr> -<tr><td>Upd:</td> -<td><input type='radio' name='searchflagupdated' value='whatev'>Both</td> -<td><input type='radio' name='searchflagupdated' value='yes'>Yes</td> -<td><input type='radio' name='searchflagupdated' value='no'>No</td></tr></table> -<input type='submit' value='Search'></p></form> -HTML - return $ret; -_code?> - -</body> -</html> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/teams.bml --- a/htdocs/translate/teams.bml Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -<?page -title=><?_ml .title _ml?> -body<= -<?_code -{ - use strict; - - my $dbr = LJ::get_db_reader(); - my ($ret, $sth); - - LJ::set_active_crumb('translateteams'); - - $ret .= "<?h1 $ML{'.teams.header'} h1?>"; - $ret .= "<?p $ML{'.teams.text'} p?>"; - - # 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>$ML{'.table.language'}</th><th>$ML{'.table.community'}</th><th>$ML{'.table.users'}</th></tr>"; - - foreach my $l (sort { $a->{'lnname'} cmp $b->{'lnname'} } 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?> diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/teams.bml.text --- a/htdocs/translate/teams.bml.text Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -;; -*- coding: utf-8 -*- -.table.community=Community - -.table.language=Language - -.table.users=Users With Privs - -.teams.header=Teams - -.teams.text=Translation is being done by the following teams: - -.title=Translation Teams - diff -r 9323f181bcb6 -r 8428f0b6ae2d htdocs/translate/welcome.bml --- a/htdocs/translate/welcome.bml Tue Feb 16 15:09:47 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -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. --------------------------------------------------------------------------------