#include <db.h>
#include <config.h>
inherit "/w/taffyd/html_library";
#include <http.h>
#define MAKE_SQL_REQUEST( cmd, fp ) DB_HANDLER->make_sql_request( \
"errors", CONFIG_DB_ERRORS_USER, "", (cmd), (fp) )
#define TYPO "Type = 'TYPO'" /*is a typo*/
#define BUG "Type = 'BUG'" /*is a bug*/
#define IDEA "Type = 'IDEA'" /*is an idea*/
#define FIXED "Status = 'FIXED'" /*is fixed*/
#define OPEN "Status = 'OPEN'" /*open bug*/
#define DENIED "Status = 'DENIED'" /*denied report*/
#define FIXER "Fixer is not NULL" /*has a fixer*/
#define FORWARDER_QUERY "Forwarder is not NULL"
#define RESULT_KEY "A"
int _doing_queries;
string _error_cache;
function *_finished_funcs;
mixed *_queries = ({
({
({ "Bug Fixers", "Fixer", "errors", ({ FIXER, BUG, FIXED }) }),
({ "Bugs Fixed", "Reporter", "errors", ({ FIXER, BUG, FIXED }) }),
({ "Open Bugs", "Reporter", "errors", ({ OPEN, BUG }) }),
({ "Bugs Reported", "Reporter", "errors", ({ BUG }) }),
}),
({
({ "Typo Fixers", "Fixer", "errors", ({ FIXER, TYPO, FIXED }) }),
({ "Typo Fixed", "Reporter", "errors", ({ FIXER, TYPO, FIXED }) }),
({ "Open Typos", "Reporter", "errors", ({ OPEN, TYPO }) }),
({ "Typos Reported", "Reporter", "errors", ({ TYPO }) }),
}),
({
({ "Idea \"Fixers\"", "Fixer", "errors", ({ FIXER, IDEA, FIXED }) }),
({ "Ideas \"Fixed\"", "Reporter", "errors", ({ FIXER, IDEA, FIXED }) }),
({ "Open Ideas ", "Reporter", "errors", ({ OPEN, IDEA }) }),
({ "Ideas Reported", "Reporter", "errors", ({ IDEA }) }),
}),
({
({ "Total Fixers", "Fixer", "errors", ({ FIXER, FIXED }) }),
({ "Total Fixed", "Reporter", "errors", ({ FIXER, FIXED }) }),
({ "Open Reports", "Reporter", "errors", ({ OPEN }) }),
({ "Reported", "Reporter", "errors", ({ }) }),
}),
({
({ "Denied Reports By Player", "Reporter", "errors", ({ DENIED }) }),
({ "Denied Reports By Creator", "Fixer", "errors", ({ DENIED }) }),
({ "Report Forwarders", "Forwarder", "forwards", ({ FORWARDER_QUERY }) }),
({ "Commenter", "Commenter", "comments", ({ }) }),
}),
});
mixed *_finished_queries;
void build_tables(int row, int column);
void build_error_stats();
void create() {
html_library::create();
set_title( "Bug Fixing Statistics" );
build_error_stats();
} /* create() */
void build_error_stats() {
int i, j;
int size;
_error_cache = 0;
_finished_queries = allocate( sizeof( _queries ) );
_doing_queries = 0;
_finished_funcs = ({ });
for ( i = 0; i < sizeof( _queries ); i++ ) {
size = sizeof( _queries[ i ] );
_doing_queries += size;
_finished_queries[ i ] = allocate( size );
for ( j = 0; j < size; j++ ) {
call_out( (: build_tables :), i, i, j);
}
}
} /* build_error_stats() */
string make_table( string header, mixed *data ) {
return "<table cellpadding=\"5\" cellspacing=\"0\" width=\"100%\">\n"
"<tr><th>" + header + "</th><th>Number</th></tr>\n" +
implode( map( data, (: "<tr><td>" + $1[0] + "</td><td>" +
$1[1] + "</td></tr>" :) ), "\n" ) +
"</table>\n";
} /* make_table() */
string build_full_sql_query(string who, string table, string select){
return sprintf("SELECT %s, COUNT(*) AS " + RESULT_KEY + " FROM %s %s "
"GROUP BY %s ORDER BY " + RESULT_KEY + " DESC LIMIT 10", who, table,
select, who);
} /* make_query() */
mixed build_sql_query(string who, string table, string *select) {
string query;
if ( sizeof(select) ) {
query = sprintf("WHERE %s", implode(select, " AND "));
}
else {
query = "";
}
return build_full_sql_query(who, table, query);
} /* build_sql_query() */
string build_final_tables() {
string txt;
int i, j;
txt = "";
for ( i = 0; i < sizeof( _finished_queries ); i++ ) {
txt += "<table cellpadding=\"5\" cellspacing=\"0\" width=\"100%\">\n"
"<tr>";
for ( j = 0; j < sizeof( _finished_queries[ i ] ); j++ ) {
txt += "<td>" + _finished_queries[i][j] + "</td>";
}
txt += "</tr>"
"</table>\n<hr>";
}
txt += "\n<div style=\"text-align: center;font-size: 10pt;\">\n"
"<em>Statistics are generated once a reboot.</em>\n"
"</div>\n";
return construct_html_document(txt);
} /* build_final_tables() */
void check_finished() {
if ( !_doing_queries ) {
_error_cache = build_final_tables();
foreach( function func in _finished_funcs ) {
if ( functionp(func) ) {
evaluate( func, _error_cache );
}
}
_finished_funcs = ({ });
}
} /* check_finished() */
void finished_sql_query(int status, mixed *data, string key, string title, int row, int column) {
mixed *results;
if ( status != DB_SUCCESS ) {
_doing_queries--;
check_finished();
return;
}
/* 0: ({
([
"A" : 1905,
"Reporter" : "hagi",
]),
([
"A" : 837,
"Reporter" : "lanfear",
]),
*/
results = ({ });
foreach( mapping result in data ) {
results += ({ ({ result[ key ], result[ RESULT_KEY ] }) });
}
_finished_queries[ row ][ column ] = make_table( title, results );
_doing_queries--;
// tell_creator( "taffyd", "%s, %d\n", _finished_queries[ row ][ column ], _doing_queries );
check_finished();
} /* finished_sql_query() */
void build_tables(int row, int column) {
mixed *bits;
string query;
bits = _queries[ row ][ column ];
query = build_sql_query( bits[1], bits[2], bits[3] );
MAKE_SQL_REQUEST(query, (: finished_sql_query($1, $2, $(bits)[1], $(bits)[0], $(row), $(column)) :));
tell_creator( "taffyd", "%s\n", query );
} /* build_tables() */
mixed www_delayed( function func, string str, mapping args, class http_request req ) {
if ( _doing_queries ) {
_finished_funcs += ({ func });
return 1;
}
return 0;
} /* www_delayed() */
string www_request(string, mapping args, class http_request req) {
if ( _error_cache ) {
return _error_cache;
}
return construct_html_document( "No error statistics are available "
"at the moment.\n");
} /* www_request() */
#ifdef OLD_CODE_JESUS_CHRIST_MY_EYES
sixth = cont {
rows = do_query("select Reporter, EntryDate, Directory, Filename, Status "
"from errors where Status != 'FIXED' and Status != "
"'DENIED' and Type = 'BUG' order by EntryDate",
fix(({"select Reporter", "EntryDate", "Directory", "Filename",
"Status"}), {
ret += make_table(rows, "Oldest bugs", "reporter", "date", "directory",
"filename", "status");
ret += "<br clear=left>";
/*
rows = db_exec(db, "select Reporter, EntryDate, Directory, Filename, Status "
"from errors where Status != 'FIXED' and Status != "
"'DENIED' and Type = 'IDEA' order by EntryDate");
ret += make_table(rows, "Oldest ideas", "reporter", "date", "directory",
"filename", "status");
ret += "<br clear=left>";
rows = db_exec(db, "select Reporter, EntryDate, Directory, Filename, Status "
"from errors where Status != 'FIXED' and Status != "
"'DENIED' and Type = 'TYPO' order by EntryDate");
ret += make_table(rows, "Oldest typos", "reporter", "date", "directory",
"filename", "status");
ret += "<br clear=left>";
rows = db_exec(db, "select Filename, count(*) as bing from errors where "
OPEN " and " BUG " group by filename order by bing desc");
ret += make_table(rows, "Files with most bug reports", "file", "reports");
rows = db_exec(db, "select Filename, count(*) as bing from errors where "
OPEN " and " IDEA " group by filename order by bing desc");
ret += make_table(rows, "Files with most idea reports", "file", "reports");
*/
#endif