Copying ede-bug-report from branches in trunk

This commit is contained in:
Sanel Zukan
2009-07-03 14:23:51 +00:00
parent bfed428c37
commit 66e586f37f
138 changed files with 35380 additions and 0 deletions

View File

@@ -0,0 +1,208 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include <stdlib.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/client.h>
#include <edelib/Debug.h>
#include <edelib/String.h>
#include "Bugzilla.h"
EDELIB_NS_USING(String)
#define CLIENT_NAME "ede-bug-report"
#define CLIENT_VERSION "0.1"
/* must be static; don't ask me why */
static struct xmlrpc_clientparms gparms;
struct BugzillaData {
xmlrpc_env xenv;
xmlrpc_client *xcli;
String url;
IdResponseCallback id_response_cb;
VersionResponseCallback version_response_cb;
void *cb_data;
};
static void _logout_response_handler(const char *url, const char *method,
xmlrpc_value *val, void *user_data, xmlrpc_env *faultp, xmlrpc_value *result)
{
/* do nothing */
}
static void _version_response_handler(const char *url, const char *method,
xmlrpc_value *val, void *user_data, xmlrpc_env *faultp, xmlrpc_value *result)
{
BugzillaData *data = (BugzillaData *)user_data;
if(faultp->fault_occurred) {
if(data->version_response_cb) {
/* do callback with error */
(*data->version_response_cb)(NULL, data->cb_data, faultp->fault_occurred, faultp->fault_string);
}
return;
}
char *tmp;
xmlrpc_decompose_value(&data->xenv, result, "{s:s,*}", "version", &tmp);
if(data->version_response_cb) {
/* do callback with values */
(*data->version_response_cb)(tmp, data->cb_data, faultp->fault_occurred, faultp->fault_string);
}
/* xmlrpc_decompose_value() allocates returned string value */
free(tmp);
}
static void _id_response_handler(const char *url, const char *method,
xmlrpc_value *val, void *user_data, xmlrpc_env *faultp, xmlrpc_value *result)
{
BugzillaData *data = (BugzillaData *)user_data;
if(faultp->fault_occurred) {
if(data->id_response_cb) {
/* do callback with error */
(*data->id_response_cb)(-1, data->cb_data, faultp->fault_occurred, faultp->fault_string);
}
return;
}
int id;
xmlrpc_decompose_value(&data->xenv, result, "{s:i,*}", "id", &id);
if(data->id_response_cb) {
/* do callback with values */
(*data->id_response_cb)(id, data->cb_data, faultp->fault_occurred, faultp->fault_string);
}
}
BugzillaData *bugzilla_new(const char *u) {
BugzillaData *data = new BugzillaData;
xmlrpc_env_init(&data->xenv);
xmlrpc_client_setup_global_const(&data->xenv);
data->url = u;
/* only cURL transport is supported */
gparms.transport = "curl";
xmlrpc_client_create(&data->xenv, XMLRPC_CLIENT_NO_FLAGS, CLIENT_NAME, CLIENT_VERSION,
&gparms, sizeof(gparms), &data->xcli);
if(data->xenv.fault_occurred) {
E_WARNING(E_STRLOC ": Unable to init xmlrpc client data (%s)\n", data->xenv.fault_string);
delete data;
data = NULL;
}
/* nullify callback stuff */
data->id_response_cb = NULL;
data->version_response_cb = NULL;
data->cb_data = NULL;
return data;
}
void bugzilla_free(BugzillaData *data) {
if(data == NULL)
return;
xmlrpc_client_destroy(data->xcli);
xmlrpc_env_clean(&data->xenv);
delete data;
}
void bugzilla_set_id_response_callback(BugzillaData *data, IdResponseCallback cb) {
E_ASSERT(data != NULL);
data->id_response_cb = cb;
}
void bugzilla_set_version_response_callback(BugzillaData *data, VersionResponseCallback cb) {
E_ASSERT(data != NULL);
data->version_response_cb = cb;
}
void bugzilla_set_callback_data(BugzillaData *data, void *param) {
E_ASSERT(data != NULL);
data->cb_data = param;
}
void bugzilla_event_loop_finish_timeout(BugzillaData *data, unsigned long ms) {
E_ASSERT(data != NULL);
xmlrpc_client_event_loop_finish_timeout(data->xcli, ms);
}
void bugzilla_event_loop_finish(BugzillaData *data) {
E_ASSERT(data != NULL);
xmlrpc_client_event_loop_finish(data->xcli);
}
void bugzilla_get_version(BugzillaData *data) {
E_ASSERT(data != NULL);
xmlrpc_client_start_rpcf(&data->xenv, data->xcli, data->url.c_str(),
"Bugzilla.version",
_version_response_handler, data, "()");
}
void bugzilla_login(BugzillaData *data, const char *user, const char *passwd) {
E_ASSERT(data != NULL);
const int remember = 0; /* remember login data */
xmlrpc_client_start_rpcf(&data->xenv, data->xcli, data->url.c_str(),
"User.login",
_id_response_handler, data,
"({s:s,s:s,s:b})",
"login", user,
"password", passwd,
"remember", remember);
}
void bugzilla_logout(BugzillaData *data) {
E_ASSERT(data != NULL);
xmlrpc_client_start_rpcf(&data->xenv, data->xcli, data->url.c_str(),
"User.logout", _logout_response_handler, NULL, "()");
}
void bugzilla_submit_bug(BugzillaData *data, const char *product,
const char *component,
const char *summary,
const char *version,
const char *description,
const char *op_sys,
const char *platform,
const char *priority,
const char *severity)
{
E_ASSERT(data != NULL);
xmlrpc_client_start_rpcf(&data->xenv, data->xcli, data->url.c_str(),
"Bug.create",
_id_response_handler, data,
"({s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s})",
"product", product,
"component", component,
"summary", summary,
"version", version,
"description", description,
"op_sys", op_sys,
"platform", platform,
"priority", priority,
"severity", severity);
}

View File

@@ -0,0 +1,70 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef __BUGZILLA_H__
#define __BUGZILLA_H__
/*
* This is asynchronous Bugzilla interface (xmlrpc calls to Bugzilla installation). This means
* that all calls will be processed without blocking and all results will be reported via callbacks.
*
* To keep things simple, we have two type of callbacks, IdResponseCallback and VersionResponseCallback.
* VersionResponseCallback will be called when request is sent via bugzilla_get_version() and
* IdResponseCallback when bugzilla_login() and bugzilla_submit_bug(). In first case, we will get
* user ID or -1 (and set errnum > 0 and err != NULL) if user does not exists or something was wrong
* with the connection. bugzilla_submit_bug() behaves the same, except it returns bug ID if bug was
* created successfully.
*
* Callbacks are sev bia bugzilla_set_id_response_callback() and bugzilla_set_version_response_callback()
* and data passed to the callback is done via bugzilla_set_callback_data().
*
* The reason why IdResponseCallback was used for both bugzilla_login() and bugzilla_submit_bug()
* is because both mark returned values as 'id' and to not clutter things with callbacks types such
* as BugIdResponseCallback or LoginIdResponse-bla-bla... you get it :)
*/
struct BugzillaData;
typedef void (*IdResponseCallback)(int, void *data, int errnum, const char *err);
typedef void (*VersionResponseCallback)(const char *, void *data, int errnum, const char *err);
BugzillaData *bugzilla_new(const char *url);
void bugzilla_free(BugzillaData *data);
/* callbacks when response arrives */
void bugzilla_set_id_response_callback(BugzillaData *data, IdResponseCallback cb);
void bugzilla_set_version_response_callback(BugzillaData *data, VersionResponseCallback cb);
/* data sent to callbacks */
void bugzilla_set_callback_data(BugzillaData *data, void *param);
void bugzilla_event_loop_finish_timeout(BugzillaData *data, unsigned long ms);
void bugzilla_event_loop_finish(BugzillaData *data);
/* get bugzilla version; VersionResponseCallback will be called */
void bugzilla_get_version(BugzillaData *data);
/* login to bugzilla instance; IdResponseCallback will be called */
void bugzilla_login(BugzillaData *data, const char *user, const char *passwd);
void bugzilla_logout(BugzillaData *data);
/* submit bug (must be logged); retuned bug id will be reported via IdResponseCallback */
void bugzilla_submit_bug(BugzillaData *data, const char *product,
const char *component,
const char *summary,
const char *version,
const char *description,
const char *op_sys,
const char *platform,
const char *priority,
const char *severity);
#endif

View File

@@ -0,0 +1,177 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#include <stdio.h>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl.H>
#include <edelib/Nls.h>
#include <edelib/MessageBox.h>
#include "PulseProgress.h"
#include "BugzillaSender.h"
#include "Bugzilla.h"
#define EDE_BUGZILLA_URL "http://bugs.equinox-project.org"
#define EDE_BUGZILLA_XMLRPC_URL "http://bugs.equinox-project.org/xmlrpc.cgi"
/* must match to existing user */
#define EDE_BUGZILLA_USER "ede-bugs@lists.sourceforge.net"
#define EDE_BUGZILLA_PASS "edebugs2709"
#define PROGRESS_STEP_REFRESH 0.06
EDELIB_NS_USING(alert)
enum {
STATE_NEXT = 1,
STATE_LOGIN,
STATE_LOGOUT,
STATE_DONE
};
struct ResponseParams {
int working_state;
const char *bug_title;
const char *bug_content;
};
static Fl_Double_Window *win;
static PulseProgress *progress;
static BugzillaData *bdata;
static void xmlrpc_request_timeout(void*) {
bugzilla_event_loop_finish_timeout(bdata, 20);
/* repeat this function so all pending RPC requests are processed */
Fl::repeat_timeout(0.5, xmlrpc_request_timeout);
}
static void progress_timeout(void*) {
progress->step();
Fl::repeat_timeout(PROGRESS_STEP_REFRESH, progress_timeout);
}
static void clear_timeouts(void) {
Fl::remove_timeout(xmlrpc_request_timeout);
Fl::remove_timeout(progress_timeout);
}
static void cancel_cb(Fl_Widget*, void*) {
win->hide();
}
static void _id_response_cb(int id, void *data, int errnum, const char *err) {
if(errnum) {
alert(_("Received bad response: (%i) : %s"), errnum, err);
/* close dialog */
cancel_cb(0, 0);
return;
}
ResponseParams *rparams = (ResponseParams*) data;
if(rparams->working_state == STATE_LOGIN) {
progress->label("Done. Submitting the data...");
printf("logged in as id: %i\n", id);
/* must match EDE Bugzilla server options */
bugzilla_submit_bug(bdata,
"ede",
"general",
rparams->bug_title,
"unspecified",
rparams->bug_content,
"All",
"All",
"P5",
"normal");
rparams->working_state += STATE_NEXT;
return;
}
if(rparams->working_state == STATE_LOGOUT) {
progress->label("Data sent successfully :). Clearing...");
puts("XXX");
bugzilla_logout(bdata);
rparams->working_state += STATE_NEXT;
return;
}
}
bool bugzilla_send_with_progress(const char *title, const char *content) {
/* used to simplify passing multiple data to the response callback */
ResponseParams rparams;
/*
* we maintain state so knows what we done, since our Bugzilla interface
* supports only one callback for ID's
*/
rparams.working_state = STATE_LOGIN;
rparams.bug_title = title;
rparams.bug_content = content;
bdata = bugzilla_new(EDE_BUGZILLA_XMLRPC_URL);
if(!bdata) {
alert(_("Unable to initialize bugzilla interface!"));
return false;
}
/* set callback and data */
bugzilla_set_id_response_callback(bdata, _id_response_cb);
bugzilla_set_callback_data(bdata, &rparams);
win = new Fl_Double_Window(275, 90, _("Sending report data"));
win->begin();
progress = new PulseProgress(10, 20, 255, 25, _("Sending report..."));
progress->selection_color((Fl_Color)137);
Fl_Button *cancel = new Fl_Button(175, 55, 90, 25, _("&Cancel"));
cancel->callback(cancel_cb);
win->end();
win->set_modal();
win->show();
/*
* try to login; rest of the actions are done in _id_response_cb() due async stuff
* and since events are chained (you can't submit report until get logged in)
*/
progress->label("Logging in...");
bugzilla_login(bdata, EDE_BUGZILLA_USER, EDE_BUGZILLA_PASS);
/* timer for processing RPC requests */
Fl::add_timeout(0.5, xmlrpc_request_timeout);
Fl::add_timeout(PROGRESS_STEP_REFRESH, progress_timeout);
while(win->shown())
Fl::wait();
/*
* make sure the timeout functions are removed because FLTK shares them between loops
* (or: as long as any loop is running, timeout callbacks will be triggered)
*/
clear_timeouts();
/* process all pending requests */
bugzilla_event_loop_finish(bdata);
bugzilla_free(bdata);
bdata = NULL;
/* true if we completed all stages */
return (rparams.working_state == STATE_DONE);
}

View File

@@ -0,0 +1,18 @@
/*
* $Id$
*
* ede-bug-report, a tool to report bugs on EDE bugzilla instance
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2009 EDE Authors.
*
* This program is licensed under terms of the
* GNU General Public License version 2 or newer.
* See COPYING for details.
*/
#ifndef __BUGZILLASENDER_H__
#define __BUGZILLASENDER_H__
bool bugzilla_send_with_progress(const char *title, const char *content);
#endif