mirror of https://github.com/BOINC/boinc.git
server/web: preliminary support for badges
- DB: add tables for badges and badge/user and badge/team associations - add script that defines 3 RAC-based badges and assigns them - add images for these badges - add admin page for creating/editing badges - show badges on user page not done: - figure out how to send badges to client - display badges somewhere in the GUIs - export badges in db_dump - enable badges by default for new projects
This commit is contained in:
parent
8ee575438d
commit
65b5ab5184
|
@ -132,3 +132,9 @@ alter table assignment
|
|||
|
||||
alter table job_file
|
||||
add unique jf_md5(md5);
|
||||
|
||||
alter table badge_user
|
||||
add unique (user_id, badge_id);
|
||||
|
||||
alter table badge_team
|
||||
add unique(team_id, badge_id);
|
||||
|
|
|
@ -690,3 +690,37 @@ create table notify (
|
|||
opaque integer not null
|
||||
-- some other ID, e.g. that of the thread, user or PM record
|
||||
);
|
||||
|
||||
create table badge (
|
||||
id serial primary key,
|
||||
create_time double not null,
|
||||
type tinyint not null,
|
||||
-- 0=user, 1=team
|
||||
name varchar(255) not null,
|
||||
-- internal use (not visible to users)
|
||||
title varchar(255) not null,
|
||||
-- user-visible, short
|
||||
description varchar(255) not null,
|
||||
-- user-visible, possibly longer
|
||||
image_url varchar(255) not null,
|
||||
-- location of image
|
||||
level varchar(255) not null,
|
||||
-- project-defined
|
||||
tags varchar(255) not null,
|
||||
-- project-defined
|
||||
sql_rule varchar(255) not null
|
||||
);
|
||||
|
||||
create table badge_user (
|
||||
badge_id integer not null,
|
||||
user_id integer not null,
|
||||
create_time double not null,
|
||||
reassign_time double not null
|
||||
);
|
||||
|
||||
create table badge_team (
|
||||
badge_id integer not null,
|
||||
team_id integer not null,
|
||||
create_time double not null,
|
||||
reassign_time double not null
|
||||
);
|
||||
|
|
|
@ -501,4 +501,72 @@ function latest_avs_app($appid) {
|
|||
return $r;
|
||||
}
|
||||
|
||||
class BoincBadge {
|
||||
static function enum($where_clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->enum('badge', 'BoincBadge', $where_clause);
|
||||
}
|
||||
static function insert($clause) {
|
||||
$db = BoincDb::get();
|
||||
$ret = $db->insert('badge', $clause);
|
||||
if (!$ret) return 0;
|
||||
return $db->insert_id();
|
||||
}
|
||||
function update($clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->update($this, 'badge', $clause);
|
||||
}
|
||||
static function lookup_id($id) {
|
||||
$db = BoincDb::get();
|
||||
return $db->lookup_id($id, 'badge', 'BoincBadge');
|
||||
}
|
||||
static function lookup($clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->lookup('badge', 'BoincBadge', $clause);
|
||||
}
|
||||
}
|
||||
|
||||
class BoincBadgeUser {
|
||||
static function enum($where_clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->enum('badge_user', 'BoincBadgeUser', $where_clause);
|
||||
}
|
||||
static function insert($clause) {
|
||||
$db = BoincDb::get();
|
||||
$ret = $db->insert('badge_user', $clause);
|
||||
if (!$ret) return false;
|
||||
return true;
|
||||
}
|
||||
static function lookup($clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->lookup('badge_user', 'BoincBadgeUser', $clause);
|
||||
}
|
||||
static function update($clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->update_aux('badge_user', $clause);
|
||||
}
|
||||
function delete($clause) {
|
||||
$db = BoincDb::get();
|
||||
$db->delete_aux('badge_user', $clause);
|
||||
}
|
||||
}
|
||||
|
||||
class BoincBadgeTeam {
|
||||
static function lookup($clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->lookup('badge_team', 'BoincBadgeTeam', $clause);
|
||||
}
|
||||
static function insert($clause) {
|
||||
$db = BoincDb::get();
|
||||
$ret = $db->insert('badge_team', $clause);
|
||||
if (!$ret) return false;
|
||||
return true;
|
||||
}
|
||||
function delete($clause) {
|
||||
$db = BoincDb::get();
|
||||
$db->delete_aux('badge_team', $clause);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
|
|
@ -396,6 +396,17 @@ function community_links($clo, $logged_in_user){
|
|||
}
|
||||
}
|
||||
|
||||
function show_badges($user) {
|
||||
$bus = BoincBadgeUser::enum("user_id=$user->id");
|
||||
if (!$bus) return;
|
||||
$x = "";
|
||||
foreach ($bus as $bu) {
|
||||
$badge = BoincBadge::lookup_id($bu->badge_id);
|
||||
$x .= "<img title=\"$badge->title\" height=40 src=$badge->image_url> ";
|
||||
}
|
||||
row2("Badges", $x);
|
||||
}
|
||||
|
||||
function show_profile_link($user) {
|
||||
if ($user->has_profile) {
|
||||
row2(tra("Profile"), "<a href=\"view_profile.php?userid=$user->id\">".tra("View")."</a>");
|
||||
|
|
|
@ -327,7 +327,7 @@ function table_header() {
|
|||
$col = func_get_arg($i);
|
||||
echo "<th ".$col[1].">".$col[0]."</th>\n";
|
||||
} else {
|
||||
echo "<th>".func_get_arg($i)."</th>\n";
|
||||
echo "<th valign=top>".func_get_arg($i)."</th>\n";
|
||||
}
|
||||
}
|
||||
echo "</tr>\n";
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2013 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
// as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// BOINC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// web interface for administering badges
|
||||
|
||||
require_once('../inc/util_ops.inc');
|
||||
|
||||
function show_form() {
|
||||
start_table();
|
||||
table_header(
|
||||
"ID",
|
||||
"name",
|
||||
"type<br>0=user<br>1=team",
|
||||
"title",
|
||||
"description",
|
||||
"image URL",
|
||||
"level",
|
||||
"tags"
|
||||
);
|
||||
|
||||
$badges = BoincBadge::enum("");
|
||||
foreach ($badges as $badge) {
|
||||
echo "<tr valign=top><form action=badge_admin.php method=POST>";
|
||||
echo "<input type=hidden name=id value=$badge->id>";
|
||||
echo "<td>$badge->id</td>\n";
|
||||
echo "<td><input name=\"name\" value=\"$badge->name\"></td>\n";
|
||||
echo "<td><input name=\"type\" size=4 value=\"$badge->type\"></td>\n";
|
||||
echo "<td><input name=\"title\" value=\"$badge->title\"></td>\n";
|
||||
echo "<td><input name=\"description\" value=\"$badge->description\"></td>\n";
|
||||
$x = "";
|
||||
if ($badge->image_url) {
|
||||
$x = " <img align=right height=64 src=\"$badge->image_url\">";
|
||||
}
|
||||
echo "<td><input name=\"image_url\" value=\"$badge->image_url\">$x</td>\n";
|
||||
echo "<td><input name=\"level\" value=\"$badge->level\"></td>\n";
|
||||
echo "<td><input name=\"tags\" value=\"$badge->tags\"></td>\n";
|
||||
echo "<td><input type=submit name=\"update\" value=Update>\n";
|
||||
echo "</form></tr>\n";
|
||||
}
|
||||
|
||||
echo "<tr><form action=badge_admin.php method=POST>";
|
||||
echo "<td><br></td>\n";
|
||||
echo "<td><input name=\"name\"></td>\n";
|
||||
echo "<td><input name=\"type\" size=4></td>\n";
|
||||
echo "<td><input name=\"title\"></td>\n";
|
||||
echo "<td><input name=\"description\"></td>\n";
|
||||
echo "<td><input name=\"image_url\"></td>\n";
|
||||
echo "<td><input name=\"level\"></td>\n";
|
||||
echo "<td><input name=\"tags\"></td>\n";
|
||||
echo "<td><input type=submit name=\"add_badge\" value=\"Create badge\"></td>\n";
|
||||
echo "</form></tr>\n";
|
||||
|
||||
end_table();
|
||||
}
|
||||
|
||||
function add_badge() {
|
||||
$name = BoincDb::escape_string(post_str("name"));
|
||||
$type = post_int("type");
|
||||
$title = BoincDb::escape_string(post_str("title"));
|
||||
$description = BoincDb::escape_string(post_str("description"));
|
||||
$image_url = BoincDb::escape_string(post_str("image_url"));
|
||||
$level = BoincDb::escape_string(post_str("level"));
|
||||
$tags = BoincDb::escape_string(post_str("tags"));
|
||||
$now = time();
|
||||
$id = BoincBadge::insert("(create_time, name, type, title, description, image_url, level, tags) values ($now, '$name', $type, '$title', '$description', '$image_url', '$level', '$tags')");
|
||||
if (!$id) {
|
||||
admin_error_page("Insert failed");
|
||||
}
|
||||
}
|
||||
|
||||
function update_badge() {
|
||||
$id = post_int("id");
|
||||
$badge = BoincBadge::lookup_id($id);
|
||||
if (!$badge) {
|
||||
admin_error_page("no such badge");
|
||||
}
|
||||
$name = BoincDb::escape_string(post_str("name"));
|
||||
$type = post_int("type");
|
||||
$title = BoincDb::escape_string(post_str("title"));
|
||||
$description = BoincDb::escape_string(post_str("description"));
|
||||
$image_url = BoincDb::escape_string(post_str("image_url"));
|
||||
$level = BoincDb::escape_string(post_str("level"));
|
||||
$tags = BoincDb::escape_string(post_str("tags"));
|
||||
$retval = $badge->update("name='$name', type=$type, title='$title', description='$description', image_url='$image_url', level='$level', tags='$tags'");
|
||||
if (!$retval) {
|
||||
admin_error_page("update failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (post_str('add_badge', true)) {
|
||||
add_badge();
|
||||
} else if (post_str('update', true)) {
|
||||
update_badge();
|
||||
}
|
||||
admin_page_head("Manage badges");
|
||||
show_form();
|
||||
admin_page_tail();
|
||||
?>
|
|
@ -0,0 +1,105 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2013 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
// as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// BOINC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Assign badges based on RAC.
|
||||
// Customize this to grant other types of badges
|
||||
|
||||
require_once("../inc/boinc_db.inc");
|
||||
|
||||
define("GOLD_RAC", 100000);
|
||||
define("SILVER_RAC", 10000);
|
||||
define("BRONZE_RAC", 1000);
|
||||
|
||||
function get_badge($name, $t, $rac, $image_url) {
|
||||
$b = BoincBadge::lookup("name='$name'");
|
||||
if ($b) return $b;
|
||||
$now = time();
|
||||
$title = "$t badge: average credit > $rac";
|
||||
$id = BoincBadge::insert("(create_time, name, title, image_url) values ($now, '$name', '$title', 'img/$image_url')");
|
||||
$b = BoincBadge::lookup_id($id);
|
||||
if ($b) return $b;
|
||||
die("can't create badge $name\n");
|
||||
}
|
||||
|
||||
$rac_gold = get_badge("rac_gold", "Gold", GOLD_RAC, "gold.png");
|
||||
$rac_silver = get_badge("rac_silver", "Silver", SILVER_RAC, "silver.png");
|
||||
$rac_bronze = get_badge("rac_bronze", "Bronze", BRONZE_RAC, "bronze.png");
|
||||
|
||||
function assign_badge($user, $badge) {
|
||||
$now = time();
|
||||
$bbu = BoincBadgeUser::lookup("user_id=$user->id and badge_id=$badge->id");
|
||||
if ($bbu) {
|
||||
echo "reassigning $badge->name to $user->id\n";
|
||||
$bbu->update("reassign_time=$now where user_id=$user->id and badge_id=$badge->id");
|
||||
} else {
|
||||
echo "assigning $badge->name to $user->id\n";
|
||||
BoincBadgeUser::insert("(create_time, user_id, badge_id, reassign_time) values ($now, $user->id, $badge->id, $now)");
|
||||
}
|
||||
}
|
||||
|
||||
function unassign_badges($user, $badges) {
|
||||
$list = null;
|
||||
foreach($badges as $badge) {
|
||||
echo "unassigning $badge->name to $user->id\n";
|
||||
if ($list) {
|
||||
$list .= ",$badge->id";
|
||||
} else {
|
||||
$list = "$badge->id";
|
||||
}
|
||||
}
|
||||
BoincBadgeUser::delete("user_id=$user->id and badge_id in ($list)");
|
||||
}
|
||||
|
||||
function assign_rac_badge($user) {
|
||||
global $rac_gold, $rac_silver, $rac_bronze;
|
||||
if ($user->expavg_credit > GOLD_RAC) {
|
||||
assign_badge($user, $rac_gold);
|
||||
unassign_badges($user, array($rac_silver, $rac_bronze));
|
||||
} else if ($user->expavg_credit > SILVER_RAC) {
|
||||
assign_badge($user, $rac_silver);
|
||||
unassign_badges($user, array($rac_bronze, $rac_gold));
|
||||
} else if ($user->expavg_credit > BRONZE_RAC) {
|
||||
assign_badge($user, $rac_bronze);
|
||||
unassign_badges($user, array($rac_gold, $rac_silver));
|
||||
} else {
|
||||
unassign_badges($user, array($rac_gold, $rac_silver, $rac_bronze));
|
||||
}
|
||||
}
|
||||
|
||||
function assign_badges_user($user) {
|
||||
assign_rac_badge($user);
|
||||
// ... assign other types of badges
|
||||
}
|
||||
|
||||
function assign_badges() {
|
||||
$n = 0;
|
||||
$maxid = BoincUser::max("id");
|
||||
while ($n <= $maxid) {
|
||||
$m = $n + 1000;
|
||||
$users = BoincUser::enum_fields("id, expavg_credit", "id>=$n and id<$m and total_credit>0");
|
||||
foreach ($users as $user) {
|
||||
assign_badges_user($user);
|
||||
}
|
||||
$n = $m;
|
||||
}
|
||||
}
|
||||
|
||||
assign_badges();
|
||||
|
||||
?>
|
|
@ -114,6 +114,7 @@ echo "
|
|||
<td><b>User management</b>
|
||||
<ul>
|
||||
<li><a href=\"profile_screen_form.php\">Screen user profiles </a></li>
|
||||
<li><a href=\"badge_admin.php\">Badges</a></li>
|
||||
<li><a href=\"manage_special_users.php\">User privileges</a></li>
|
||||
<li><a href=".URL_BASE."/manage_project.php>User job submission privileges</a></li>
|
||||
<li><a href=\"mass_email.php\">Send mass email to a selected set of users</a></li>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
|
@ -71,6 +71,9 @@ if ($format=="xml"){
|
|||
} else {
|
||||
// No data was found, generate new data for the cache and store it
|
||||
$user = lookup_user_id($id);
|
||||
if (!$user) {
|
||||
error_page("No such user $id");
|
||||
}
|
||||
BoincForumPrefs::lookup($user);
|
||||
$user = @get_other_projects($user);
|
||||
$community_links = get_community_links_object($user);
|
||||
|
@ -97,6 +100,7 @@ if ($format=="xml"){
|
|||
echo "</td><td valign=top>";
|
||||
start_table();
|
||||
show_profile_link($user);
|
||||
show_badges($user);
|
||||
community_links($community_links, $logged_in_user);
|
||||
end_table();
|
||||
echo "</td></tr></table>";
|
||||
|
|
Loading…
Reference in New Issue