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

View File

@@ -0,0 +1,110 @@
<?page
title=>Your Balance
body<=
<p>[&lt;&lt; <a href="./">Back</a>]</p>
<?_code
{
use strict;
my $dbh = LJ::get_db_writer();
my $remote = LJ::get_remote();
unless ($remote) { return $ML{'error.noremote'}; }
LJ::load_user_props($dbh, $remote, "legal_assignagree");
my ($ret, $sth);
LJ::Pay::bazaar_do_expirations($remote->{'userid'});
$sth = $dbh->prepare("SELECT date, amt, method, note FROM bzrpayout WHERE userid=?");
$sth->execute($remote->{'userid'});
my $hist;
while (my $po = $sth->fetchrow_hashref) {
unless ($hist) {
$hist .= "<?h1 Payment History h1?>";
$hist .= "<table cellpadding='3' border='1'><tr><th>Date</th><th>Amount</th><th>Method</th><th>Note</th></tr>\n";
}
$hist .= "<tr><td>$po->{'date'}</td><td>\$" . sprintf("%0.02f", $po->{'amt'}) . "</td><td>$po->{'method'}</td><td>$po->{'note'}</td></tr>\n";
}
if ($hist) {
$ret .= $hist;
$ret .= "</table>\n";
}
$sth = $dbh->prepare("SELECT bzid, date, amt, owed, expired ".
"FROM bzrbalance WHERE userid=? ORDER BY bzid");
$sth->execute($remote->{'userid'});
$ret .= "<?h1 Amount owed h1?>";
$ret .= "<table cellpadding='3' border='1'>";
$ret .= "<tr><th>Date</th><th>Amount</th><th>Balance</th><th>Note</th></tr>\n";
my $owed;
my $rows = 0;
my $now = time();
while (my $r = $sth->fetchrow_hashref) {
$rows++;
$ret .= "<tr><td>$r->{'date'}</td>";
$owed += $r->{'owed'};
$ret .= sprintf("<td align='right'>\$%0.02f</td>", $r->{'amt'});
$ret .= sprintf("<td align='right'>\$%0.02f</td>", $r->{'owed'});
my $extra;
if ($r->{'expired'} > 0) {
$extra .= sprintf(" (\$%0.02f expired after 3 months unclaimed)", $r->{'expired'});
}
my $time = LJ::mysqldate_to_time($r->{'date'});
my $exptime = $time + 86400*93;
if ($r->{'owed'} > 0 && $now < $exptime) {
$extra .= ", balance will expire in " . int(($exptime - $now) / 86400) . " days";
}
$ret .= "<td><a href='status.bml?bzid=$r->{'bzid'}'>Bazaar \#$r->{'bzid'}</a>$extra</td>";
$ret .= "</tr>\n";
}
unless ($rows) {
return "No balance or history.";
}
$ret .= "<tr><td colspan='2' align='right'><b>Amount owed:</b></td><td align='right'>" .
sprintf("\$%0.02f", $owed) . "</td><td></td></tr>";
$ret .= "</table>";
return $ret unless $owed;
unless ($remote->{'legal_assignagree'}) {
$ret .= "<?h1 Paperwork h1?>";
$ret .= "<?p The following paperwork needs to be completed and mailed to LiveJournal to get paid: p?><ul>";
$ret .= "<li><a href='$LJ::STATPREFIX/misc/assignment_agreement.doc'>Assignment Agreement</a> -- to assign copyright to Danga Interactive</li>\n";
$ret .= "<li>If in the United States:<ul><li><a href='http://www.irs.gov/pub/irs-pdf/fw9.pdf'>W-9</a> -- tax form</li></ul></li>";
$ret .= "<li>If outside the United States:<ul>";
$ret .= "<li><a href='http://www.irs.gov/pub/irs-fill/fw8ben.pdf'>W-8BEN</a> -- Certificate of Foreign Status of Beneficial Owner for United States Tax Withholding.</li>";
$ret .= "<li><a href='http://www.irs.gov/pub/irs-pdf/iw8ben.pdf'>Instructions for above form</a></li>\n";
$ret .= "<li><a href='http://www.irs.gov/businesses/small/international/article/0,,id=96696,00.html'>Obtaining an ITIN from Abroad</a></li>\n";
$ret .= "<li><a href='http://www.irs.gov/businesses/corporations/article/0,,id=96739,00.html'>Tax treaty list</a> -- the list of who the US has tax treaties with</li>";
$ret .= "</ul></li>";
$ret .= "</ul>";
$ret .= "Mailing address:<blockquote><pre>" . LJ::Pay::postal_address_text() . "</pre></blockquote>";
$ret .= "Include your LiveJournal username, as well as a mailing address to send your check if your balance is over \$50. If you'd prefer to not get paid (and instead generate coupons later at this URL), indicate as such in your letter.";
$ret .= "<?h1 Coupon Generation h1?>";
$ret .= "<?p Until we have your paperwork on file, you cannot generate coupons. p?>";
return $ret;
}
if ($owed >= 50) {
$ret .= "<?h1 Request payment h1?><?p To get paid, email sandy\@livejournal.com requesting a check. Include your LiveJournal username and mailing address. p?>";
} else {
$ret .= "<?h1 Balance under \$50 h1?><?p Your balance is under \$50. We can send out checks once your balance is \$50 or higher. For now, you can generate LiveJournal coupons instead. p?>";
}
$ret .= "<?h1 Generate coupon h1?><?p This form will let you generate a LiveJournal coupon which can be used by anybody, not just your account. <b>Important note:</b> coupons are either used or unused... they don't maintain a balance. As such, only generate a coupon for the amount you intend to use. For your protection, we only allow coupons to be generated for the amounts \$5.00 - \$25.00. You may use multiple coupons in an order, if your order will be more than \$25.00. p?>";
$ret .= "<form method='post' action='gencoupon.bml' style='margin-left: 40px'>\n";
$ret .= "Amount: \$<input type='text' size='6' name='amt' value='' /> <input type='submit' value='Generate' />";
$ret .= "</form>";
return $ret;
}
_code?>
<=body
page?>

View File

@@ -0,0 +1,97 @@
<?page
title=>Bazaar Details
body<=
<p>[&lt;&lt; <a href="./">Back</a>]</p>
<?h1 Seed Voters h1?>
<?p
To kick-start the system, the voters for the first month are the LiveJournal employees.
p?>
<?h1 Voting for yourself h1?>
<?p
You can't explictly vote for yourself. To prevent oscillations,
however, the system assigns a percentage of your votes back to
yourself, based on the weighted average of what the other voters for the
current month gave you.
p?>
<?h1 LiveJournal.com employees h1?><?p
Full-time LiveJournal.com employees receive votes and use their voting
power, but don't take any percentage of the pot. Part-time employees
likewise receive votes and use their voting power, but they can
receive some money from the pot past a certain per-employee threshold.
For instance, if the threshold for part-time employee "Bob" were
$1,000 and he earned $800, he'd get nothing. If he earned
$1,200 of the pot, he'd actually get $200, and the other $1,000 would
stay in the pot, to be divided amongst everybody else.
p?>
<?h1 Requirement to receive money h1?><?p Before you're eligible to
receive money from the pot, you must first complete the necessary tax
forms and a copyright assignment agreement. If you're outside of the
United States, things may be tedious or impossible, depending on your
country and its relation with the United States. We won't mail out
checks smaller than $50. However, see the next section.
p?>
<?h1 Cash-out alternative h1?><?p If it's too difficult for you to
receive money, or your balance is too low, we'll also let you apply
your pending balance towards LiveJournal <a href="/pay/">payment</a>
coupons. A minimum $5 coupon may be generated. p?>
<?h1 Participant Types h1?><?p
All participants in the bazaar fall into one of the following types:
<ul>
<li><b>Voter only</b> -- not eligible to receive money (full-time LiveJournal employees, and anybody who contacts us and tells us that they don't wish to receive money)</li>
<li><b>Part-time employees</b> -- details above. can vote, and can get some of the earned pot.</li>
<li><b>Money Queuing</b> -- (default state) You haven't done the paperwork to receive money yet, but your earnings are being held for up to three months. If after 5 months you do the paperwork, you'll receive the money you earned in the previous three months.</li>
<li><b>Money Recipient</b> -- you've done the paperwork and you'll get paid at the end of the month, after votes are tallied and reviewed. Money will be held indefinitely until you earn at least $25. (except if you live outside of the US and wire fees are high, in which case we won't pay until you've earned at least double what it'd cost to wire the money)
</ul>
p?>
<?h1 Privacy h1?>
<?p
Each user's state (above) is private. They may share it if others if they like, but we won't reveal it.
p?>
<?p
The voting weight you give to other people's contributions is private, except
to LiveJournal staff for the purpose of review.
p?>
<?p
LiveJournal will make public the current month's voters, and their voting power,
but not how much money they made in the previous month. Because the type of each
user is also hidden, it's not possible to accurately infer the money received.
p?>
<?h1 Minimum Percentages h1?>
<?p
Certain LiveJournal employees retain a guaranteed minimum voting percentage each month.
p?>
<?h1 Cheating h1?><?p
LiveJournal reserves the right to review voting, and disqualify people
if questionable voting is taking place. (people voting for each other
exclusively each month, etc)
p?>
<?h1 Pot increases h1?><?p
LiveJournal decides when projects are completed and when the pot amount increases. Completion of a project marked with $n increase doesn't necessarily mean you'll earn $n. You'll earn whatever the community decides it's worth.
p?>
<?h1 Acknowledgements vs. Voting h1?>
<?p
The default voting weight for a contribution acknowledgement is zero.
This lets you acknowledge that somebody did something (so they get
listed on the contributors page) but without giving them a percentage
of the pot. It's up to every voting user to decide what's important to
them and what deserves the pot (and voting rights).
p?>
<=body
page?>

View File

@@ -0,0 +1,46 @@
<?page
title=>Generate Coupon
body<=
<?_code
{
use strict;
use vars qw(%POST %GET);
my $dbh = LJ::get_db_writer();
my $remote = LJ::get_remote();
unless ($remote) { return $ML{'error.noremote'}; }
LJ::load_user_props($dbh, $remote, "legal_assignagree");
return BML::redirect("/bazaar/balance.bml") unless $remote->{'legal_assignagree'};
if ($GET{'cpid'}) {
my $cp = $dbh->selectrow_hashref("SELECT * FROM coupon WHERE cpid=? AND rcptid=?",
undef, $GET{'cpid'}, $remote->{'userid'});
return "<b>Error:</b> Coupon not found" unless $cp;
return "<?h1 Success h1?><?p The following coupon has been generated for <b>\$$cp->{'arg'}</b>:<center><span style='font-size: 20pt'>$cp->{'cpid'}-$cp->{'auth'}</span></center> p?><?p You'll be able to find this coupon back at any time from your <a href='balance.bml'>payment history</a>. p?>";
}
my $amt = $POST{'amt'};
unless ($amt =~ /^(\d+)(\.(\d\d))?$/) {
return "<b>Error:</b> Invalid format.";
}
if ($amt < 5 || $amt > 25) {
return "<b>Error:</b> Amount must be between \$5.00 and \$25.00.";
}
if (LJ::Pay::bazaar_remove_balance($remote, $amt)) {
my $auth = LJ::make_auth_code(10);
$dbh->do("INSERT INTO coupon (auth, type, arg, rcptid, locked, payid) VALUES (?, 'dollaroff', ?, ?, '0', 0)",
undef, $auth, $amt, $remote->{'userid'});
die $dbh->errstr if $dbh->err;
my $id = $dbh->{'mysql_insertid'};
my $coupon = "$id-$auth";
$dbh->do("INSERT INTO bzrpayout (userid, date, amt, method, note) VALUES (?, NOW(), ?, 'coupon', ?)",
undef, $remote->{'userid'}, $amt, "coupon: $coupon");
return BML::redirect("gencoupon.bml?cpid=$id");
} else {
return "You don't have \$$amt in your balance. If you did a double submit, you can get your coupon code on your <a href='balance.bml'>payment history</a>.";
}
}
_code?>
<=body
page?>

View File

@@ -0,0 +1,43 @@
<?page
title=>The Bazaar
body<=
The bazaar isn't really used anymore because it was too tedious to
maintain. We'd like to fix it and bring it back, but fixing it would
require analyzing what went wrong.
<?_c
<?h1 What is The Bazaar? h1?>
<?p
The Bazaar is a system to foster LiveJournal.com development goals and improve communication amongst the people who are doing work on the site.
p?>
<?p
There are a lot of <a href="details.bml">details</a>, but the basic gist is that each month there is a virtual pot, with so much money in it. At the end of the month the pot is divided up between the different <a href="/site/contributors.bml">contributors</a>, based on weightings determined by the pot recipients of the previous month. The LiveJournal staff increases the pot amount as the month goes on when key goals are met and projects completed.
p?>
<?p
This system has the following benefits:<ul>
<li style='margin-top: 10px'>It gets money out to people who deserve it, without LiveJournal.com needing to hire and manage tons of people, who might have fluctuating amounts of free time, with school or other life commitments.</li>
<li style='margin-top: 10px'>It lets us assign rough dollar amounts to projects we'd like to see done, without having to figure out exactly what everything's worth. We just commit to increasing the pot by, say, $200 for some project. The community's votes may end up making it worth $150 or $300.</li>
<li style='margin-top: 10px'>It encourages communication. People have to let other people know what they're doing, and when they've finished it, to get acknowledged.</li>
<li style='margin-top: 10px'>It encourages projects getting done. If somebody disappears for a few weeks, it's likely somebody else will finish their project first. Maybe the second person did it from scratch so the first person gets nothing, or maybe the second person worked off the former's ideas/code, and the community awards the first person some fraction. In any case, it relieves the need for anybody to hassle people to finish projects.</li>
<li style='margin-top: 10px'>It encourages people to <a href="/site/contributors.bml">list their contributions</a>. Even if they choose to not work for money, getting acknowledged at least gives them voting power for the next month.</il>
</ul>
p?>
<?h1 Areas h1?>
<?choices
items<=
<?choice Status|status.bml|Current status: who has voting power, and what the pot's at choice?>
<?choice Vote|vote.bml|Weight contributions for this month. choice?>
<=items
itemsb<=
<?choice Details|details.bml|Details & rules choice?>
<?choice Balance|balance.bml|Your Balance choice?>
<=itemsb
choices?>
_c?>
<=body
page?>

View File

@@ -0,0 +1,112 @@
<?page
title=>Bazaar Status
body<=
<p>[&lt;&lt; <a href="./">Back</a>]</p>
<?_code
{
use strict;
use vars qw(%GET %POST);
my $dbh = LJ::get_db_writer();
my ($ret, $sth);
my $remote = LJ::get_remote($dbh);
my $bzid = $GET{'bzid'}+0;
my $bz;
unless ($bzid) {
$bz = $dbh->selectrow_hashref("SELECT * FROM bzrs WHERE open='1' ".
"ORDER BY datestart LIMIT 1");
return "No bazaar session is currently active." unless $bz;
} else {
$bz = $dbh->selectrow_hashref("SELECT * FROM bzrs WHERE bzid=?",
undef, $bzid);
return "Invalid bazaar ID" unless $bz;
}
$bzid = $bz->{'bzid'};
my (@pot, $pot);
$sth = $dbh->prepare("SELECT dateadd, amt, reason FROM bzrpot ".
"WHERE bzid=? ORDER BY dateadd");
$sth->execute($bzid);
while ($_ = $sth->fetchrow_hashref) {
push @pot, $_;
$pot += $_->{'amt'};
}
my $is_voter;
$sth = $dbh->prepare("SELECT u.user, u.name, v.weight FROM bzrvoter v, user u ".
"WHERE u.userid=v.userid AND v.bzid=? ".
"ORDER BY v.weight DESC");
$sth->execute($bzid);
my @voters;
while ($_ = $sth->fetchrow_hashref) {
push @voters, $_;
$_->{'_votelink'} = 1 if $bz->{'open'} && $remote &&
$remote->{'user'} eq $_->{'user'};
}
$ret .= "<table>\n";
$ret .= "<tr><td align='right'><b>Bazaar Session:</b></td><td><a href=\"status.bml?bzid=$bzid\">\#$bzid</a>: $bz->{'name'}</td></tr>\n";
$ret .= "<tr><td align='right'><b>Start Time:</b></td><td>$bz->{'datestart'}</td></tr>\n";
my $state = $bz->{'open'} ? "In progress" : "Completed";
$ret .= "<tr><td align='right'><b>State:</b></td><td>$state</td></tr>\n";
$ret .= "<tr valign='top'><td align='right'><b>Pot:</b></td><td><span style='font-size: 15pt; font-weight: bold; font-family: arial,helvetica; color: #008000; background-color: #80ff80'>\$" . sprintf("%0.02f", $pot) . "</span>";
if (@pot > 1) {
$ret .= "<p><b>Details:</b><table>";
foreach (@pot) {
my $reason = $_->{'reason'};
if ($LJ::ZILLA_ROOT) {
$reason =~ s/bug (\d+)/<a href="$LJ::ZILLA_ROOT\/$1">$&<\/a>/gi;
}
$ret .= sprintf("<tr><td>%s</td><td align='right'><b>\$%0.02f</b></td><td>%s</td></tr>\n",
substr($_->{'dateadd'}, 0, 10),
$_->{'amt'}, $reason);
}
$ret .= "</table>";
}
$ret .= "</td></tr>\n";
$ret .= "</table>\n";
$ret .= "<?h1 Voters h1?><?p The following users have voting power for this Bazaar session, based on their contributions in the previous month. Some users below are employees who have only earned voting rights, and not money from last month's pot. View <a href='details.bml'>the details</a> to find out how the system works. p?>";
$ret .= "<div style='margin-left: 30px'><table>";
$ret .= "<tr><td align='left'><b>User</b></td><td align='right' width='100'><b>Weight</b></td><td></td></tr>\n";
foreach my $v (@voters) {
my $name = LJ::eall($v->{'name'});
$ret .= "<tr><td>" . LJ::ljuser($v->{'user'}) . " - $name</td><td align='right'>" .
sprintf("%0.02f%%", $v->{'weight'}*100) . "</td>";
$ret .= "<td>";
if ($v->{'_votelink'}) {
$ret .= "[<a href='vote.bml'>Vote</a>]";
}
$ret .= "</td></tr>\n";
}
$ret .= "</table></div>";
$ret .= "<?h1 Recognized Contributors & Contributions h1?><?p This month's voters have so far recognized the following contributions, sorted by contribution date. p?>";
$ret .= "<div style='margin-left: 30px'>";
$sth = $dbh->prepare("SELECT DISTINCT u.user, c.coid, c.cat, c.des, c.url, c.dateadd ".
"FROM contributed c, useridmap u, bzrvote v, bzrvoter vr ".
"WHERE u.userid=c.userid AND v.bzid=? AND vr.bzid=v.bzid ".
"AND vr.userid=v.userid AND v.coid=c.coid AND v.weight > 0 ".
"ORDER BY c.dateadd");
$sth->execute($bzid);
while (my $c = $sth->fetchrow_hashref) {
my $des = LJ::eall($c->{'des'});
$des = "<a href='$c->{'url'}'>$des</a>" if $c->{'url'};
$ret .= "<p>[<a href='/site/contributors.bml?mode=detail&coid=$c->{'coid'}'>$c->{'coid'}</a>] ";
$ret .= LJ::ljuser($c->{'user'}) . ": $des ($c->{'cat'}; $c->{'dateadd'})</p>\n";
}
$ret .= "</div>";
return $ret;
}
_code?>
<=body
page?>

View File

@@ -0,0 +1,154 @@
<?page
title=>Bazaar Voting
body<=
<p>[&lt;&lt; <a href="./">Back</a>]</p>
<?_code
{
use strict;
use vars qw(%GET %POST);
my $dbh = LJ::get_db_writer();
my ($ret, $sth);
my $remote = LJ::get_remote();
return "You must first <a href='/login.bml?ret=1'>login</a>." unless $remote;
my $bz = $dbh->selectrow_hashref("SELECT * FROM bzrs WHERE open='1' ".
"ORDER BY datestart LIMIT 1");
return "No bazaar session is currently active." unless $bz;
my $bzid = $bz->{'bzid'};
return "You aren't a voter for the <a href='status.bml?bzid=$bzid'>current bazaar</a> session."
unless $dbh->selectrow_array("SELECT weight FROM bzrvoter WHERE bzid=? AND userid=?",
undef, $bzid, $remote->{'userid'});
# load votes (if voter)
my %votes;
$sth = $dbh->prepare("SELECT u.user, v.coid, v.weight, c.cat, c.des, c.url, c.dateadd ".
"FROM bzrvote v, contributed c, useridmap u ".
"WHERE v.bzid=? AND v.userid=? AND v.coid=c.coid ".
"AND u.userid=c.userid");
$sth->execute($bzid, $remote->{'userid'});
while (my $v = $sth->fetchrow_hashref) {
$votes{$v->{'coid'}} = $v;
}
my @unvote;
$sth = $dbh->prepare("SELECT u.user, c.coid, c.cat, c.des, c.url, c.dateadd ".
"FROM contributed c, useridmap u ".
"WHERE u.userid=c.userid AND c.dateadd > ? ".
"AND c.userid <> ?");
$sth->execute($bz->{'datestart'}, $remote->{'userid'});
while (my $v = $sth->fetchrow_hashref) {
next if defined $votes{$v->{'coid'}};
push @unvote, $v;
}
if (LJ::did_post()) {
foreach my $id (keys %votes) {
next if $POST{"weight_$id"} eq "";
my $new = int($POST{"weight_$id"});
$new = 0 if $new < 0;
next if $POST{"weight_$id"} eq $votes{$id}->{'weight'};
$votes{$id}->{'weight'} = $new;
$dbh->do("REPLACE INTO bzrvote (bzid, userid, coid, weight) VALUES (?,?,?,?)",
undef, $bzid, $remote->{'userid'}, $id, $new);
}
foreach my $v (@unvote) {
my $id = $v->{'coid'};
next if $POST{"weight_$id"} eq "";
# delete contribution (so much stupid crap get submitted, like:
# "I gave my friend a code!")
if ($POST{"weight_$id"} eq "d") {
if (LJ::check_priv($dbh, $remote, "contrib_delete")) {
$dbh->do("DELETE FROM contributed WHERE coid=?", undef, $id);
$dbh->do("DELETE FROM contributedack WHERE coid=?", undef, $id);
}
$v->{'_deleted'} = 1;
next;
}
$votes{$id} = $v;
my $new = int($POST{"weight_$id"});
$new = 0 if $new < 0;
$votes{$id}->{'weight'} = $new;
$dbh->do("REPLACE INTO bzrvote (bzid, userid, coid, weight) VALUES (?,?,?,?)",
undef, $bzid, $remote->{'userid'}, $id, $new);
if ($new) {
$dbh->do("INSERT IGNORE INTO contributedack (coid, ackuserid) VALUES (?,?)",
undef, $v->{'coid'}, $remote->{'userid'});
}
}
# remove items that were just voted for
@unvote = grep { ! $votes{$_->{'coid'}} && ! $_->{'_deleted'} } @unvote;
if ($POST{'new_id'}) {
my $c = $dbh->selectrow_hashref("SELECT u.user, c.coid, c.cat, c.des, c.url, c.dateadd ".
"FROM contributed c, useridmap u WHERE c.coid=? ".
"AND c.dateadd > DATE_SUB(NOW(), INTERVAL 60 DAY) ".
"AND u.userid=c.userid",
undef, $POST{'new_id'});
return "Error: invalid contribution ID. Either does not exist, or is too old."
unless $c;
return "Error: can't vote for your own contributions"
if $c->{'user'} eq $remote->{'user'};
$c->{'weight'} = ($POST{'new_weight'}+0) || 1;
$dbh->do("REPLACE INTO bzrvote (bzid, userid, coid, weight) VALUES (?,?,?,?)",
undef, $bzid, $remote->{'userid'}, $c->{'coid'}, $c->{'weight'});
LJ::Contrib::ack($c->{'coid'}, $remote->{'userid'});
$votes{$c->{'coid'}} = $c;
}
}
$ret .= "<?h1 Your Votes h1?><?p As a voter in <a href='status.bml?bzid=$bzid'>this bazaar session</a>, you can add contributions you'd like to recognize here, and weight them all appropriately in regards to each other. p?>";
$ret .= "<form method='post' action='vote.bml' style='margin-left: 30px'>";
$ret .= "<table><tr><td width='250'><b>Contribution</b></td><td><b>Weight</b></td><td></td></tr>\n";
my $tw = 0;
foreach (values %votes) { $tw += $_->{'weight'}; }
my $row = sub {
my $v = shift;
my $des = LJ::eall($v->{'des'});
if ($v->{'url'}) {
$v->{'url'} = LJ::eall($v->{'url'});
$des = "<a href='$v->{'url'}'>$des</a>";
}
my $per = $v->{'weight'} ne "" ? sprintf("%0.02f%%", $v->{'weight'}*100/($tw||1)) : "";
$ret .= "<tr valign='top'><td>[<a href='/site/contributors.bml?mode=detail&coid=$v->{'coid'}'>$v->{'coid'}</a>] ";
$ret .= LJ::ljuser($v->{'user'}) . ": ";
$ret .= "$des<br />$v->{'cat'}, $v->{'dateadd'}</td><td><input name='weight_$v->{'coid'}' value='$v->{'weight'}' size='4'></td><td>$per</td></tr>";
};
# the ones that have been voted for, skipping zero weight
foreach my $v (sort { $b->{'weight'} <=> $a->{'weight'} } values %votes) {
next unless $v->{'weight'};
$row->($v);
}
$ret .= "<tr><td><i>New vote item:</i> <a href='/site/contributors.bml'>Contribution</a> ID: <input size='4' name='new_id'></td><td><input size='4' name='new_weight'></td><td></td></tr>\n";
$ret .= "<tr><td></td><td><input type='submit' value='Save'></td><td></td></tr>\n";
# unweighted contributions
if (@unvote) {
$ret .= "<tr><td colspan='2'><b>Contributions you haven't weighted:</b><br />(set to 0 to remove from this list)</td></tr>\n";
foreach my $v (@unvote) {
$row->($v);
}
$ret .= "<tr><td></td><td><input type='submit' value='Save'></td><td></td></tr>\n";
}
$ret .= "</table></form>";
return $ret;
}
_code?>
<=body
page?>