mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Copying ede-bug-report from branches in trunk
This commit is contained in:
208
ede-bug-tools/ede-bug-report/asynch/Bugzilla.cpp
Normal file
208
ede-bug-tools/ede-bug-report/asynch/Bugzilla.cpp
Normal 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);
|
||||
}
|
||||
70
ede-bug-tools/ede-bug-report/asynch/Bugzilla.h
Normal file
70
ede-bug-tools/ede-bug-report/asynch/Bugzilla.h
Normal 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
|
||||
177
ede-bug-tools/ede-bug-report/asynch/BugzillaSender.cpp
Normal file
177
ede-bug-tools/ede-bug-report/asynch/BugzillaSender.cpp
Normal 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);
|
||||
}
|
||||
18
ede-bug-tools/ede-bug-report/asynch/BugzillaSender.h
Normal file
18
ede-bug-tools/ede-bug-report/asynch/BugzillaSender.h
Normal 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
|
||||
Reference in New Issue
Block a user