mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Added support for receiving notifications.
When issue gets update, reporter can receive mail notifications, but has to have bugzilla account first. The later could not be avoided. Implements #201.
This commit is contained in:
parent
c605359ea1
commit
15dd0b0a80
@ -28,14 +28,18 @@ struct BugzillaData {
|
||||
xmlrpc_env xenv;
|
||||
xmlrpc_client *xcli;
|
||||
String url;
|
||||
|
||||
BugzillaErrorCallback cb;
|
||||
void *cb_data;
|
||||
};
|
||||
|
||||
BugzillaData *bugzilla_new(const char *u) {
|
||||
BugzillaData *bugzilla_new(const char *url, BugzillaErrorCallback cb, void *cb_data) {
|
||||
BugzillaData *data = new BugzillaData;
|
||||
bugzilla_set_error_callback(data, cb, cb_data);
|
||||
|
||||
xmlrpc_env_init(&data->xenv);
|
||||
xmlrpc_client_setup_global_const(&data->xenv);
|
||||
data->url = u;
|
||||
data->url = url;
|
||||
|
||||
/*
|
||||
* to allow https connections; curl by default refuse connections without valid certificate
|
||||
@ -51,6 +55,7 @@ BugzillaData *bugzilla_new(const char *u) {
|
||||
xmlrpc_client_create(&data->xenv, XMLRPC_CLIENT_NO_FLAGS, "ede-bug-report", "0.1", &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);
|
||||
if(cb) cb(data->xenv.fault_string, cb_data);
|
||||
delete data;
|
||||
data = NULL;
|
||||
}
|
||||
@ -68,6 +73,12 @@ void bugzilla_free(BugzillaData *data) {
|
||||
delete data;
|
||||
}
|
||||
|
||||
void bugzilla_set_error_callback(BugzillaData *data, BugzillaErrorCallback cb, void *cb_data) {
|
||||
E_ASSERT(data != NULL);
|
||||
data->cb = cb;
|
||||
data->cb_data = cb_data;
|
||||
}
|
||||
|
||||
char *bugzilla_get_version(BugzillaData *data) {
|
||||
E_ASSERT(data != NULL);
|
||||
|
||||
@ -76,12 +87,12 @@ char *bugzilla_get_version(BugzillaData *data) {
|
||||
|
||||
if(data->xenv.fault_occurred) {
|
||||
E_WARNING(E_STRLOC ": Unable to call xmlrpc function (%s)\n", data->xenv.fault_string);
|
||||
if(data->cb) (data->cb)(data->xenv.fault_string, data->cb_data);
|
||||
return (char*)"";
|
||||
}
|
||||
|
||||
/* this value will be malloc()-ated by xmlrpc_decompose_value() and should be freeed by user */
|
||||
char *ret;
|
||||
|
||||
xmlrpc_decompose_value(&data->xenv, result, "{s:s,*}", "version", &ret);
|
||||
xmlrpc_DECREF(result);
|
||||
|
||||
@ -103,6 +114,7 @@ int bugzilla_login(BugzillaData *data, const char *user, const char *passwd) {
|
||||
|
||||
if(data->xenv.fault_occurred) {
|
||||
E_WARNING(E_STRLOC ": Unable to perform login function (%s)\n", data->xenv.fault_string);
|
||||
if(data->cb) (data->cb)(data->xenv.fault_string, data->cb_data);
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -120,41 +132,70 @@ void bugzilla_logout(BugzillaData *data) {
|
||||
|
||||
if(data->xenv.fault_occurred) {
|
||||
E_WARNING(E_STRLOC ": Unable to call xmlrpc function (%s)\n", data->xenv.fault_string);
|
||||
if(data->cb) (data->cb)(data->xenv.fault_string, data->cb_data);
|
||||
return;
|
||||
}
|
||||
|
||||
xmlrpc_DECREF(result);
|
||||
}
|
||||
|
||||
int 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)
|
||||
int 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,
|
||||
const char *cc)
|
||||
{
|
||||
E_ASSERT(data != NULL);
|
||||
|
||||
int bug_id = -1;
|
||||
xmlrpc_value *result;
|
||||
|
||||
xmlrpc_client_call2f(&data->xenv, data->xcli, data->url.c_str(), "Bug.create", &result,
|
||||
"({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);
|
||||
/* if given CC, add it so bugzilla assign that email as notification receiver */
|
||||
if(cc) {
|
||||
/* as for now we only support single email address */
|
||||
xmlrpc_value *cc_array, *cc_str;
|
||||
|
||||
cc_array = xmlrpc_array_new(&data->xenv);
|
||||
cc_str = xmlrpc_string_new(&data->xenv, (const char *const)cc);
|
||||
xmlrpc_array_append_item(&data->xenv, cc_array, cc_str);
|
||||
xmlrpc_DECREF(cc_str);
|
||||
|
||||
xmlrpc_client_call2f(&data->xenv, data->xcli, data->url.c_str(), "Bug.create", &result,
|
||||
"({s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:A})",
|
||||
"product", product,
|
||||
"component", component,
|
||||
"summary", summary,
|
||||
"version", version,
|
||||
"description", description,
|
||||
"op_sys", op_sys,
|
||||
"platform", platform,
|
||||
"priority", priority,
|
||||
"severity", severity,
|
||||
"cc", cc_array);
|
||||
xmlrpc_DECREF(cc_array);
|
||||
} else {
|
||||
xmlrpc_client_call2f(&data->xenv, data->xcli, data->url.c_str(), "Bug.create", &result,
|
||||
"({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);
|
||||
}
|
||||
|
||||
if(data->xenv.fault_occurred) {
|
||||
E_WARNING(E_STRLOC ": Unable to perform submit function (%s)\n", data->xenv.fault_string);
|
||||
if(data->cb) (data->cb)(data->xenv.fault_string, data->cb_data);
|
||||
return bug_id;
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,11 @@
|
||||
#define __BUGZILLA_H__
|
||||
|
||||
struct BugzillaData;
|
||||
typedef void (*BugzillaErrorCallback)(const char *str, void *data);
|
||||
|
||||
BugzillaData *bugzilla_new(const char *url);
|
||||
BugzillaData *bugzilla_new(const char *url, BugzillaErrorCallback cb = NULL, void *data = NULL);
|
||||
void bugzilla_free(BugzillaData *data);
|
||||
void bugzilla_set_error_callback(BugzillaData *data, BugzillaErrorCallback cb, void *cb_data = NULL);
|
||||
|
||||
/* return bugzilla version or empty string if fails; returned value must be free()-ed */
|
||||
char *bugzilla_get_version(BugzillaData *data);
|
||||
@ -26,13 +28,15 @@ int bugzilla_login(BugzillaData *data, const char *user, const char *
|
||||
void bugzilla_logout(BugzillaData *data);
|
||||
|
||||
/* return bug id or -1 if fails */
|
||||
int 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);
|
||||
int 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,
|
||||
const char *cc);
|
||||
#endif
|
||||
|
@ -27,10 +27,10 @@
|
||||
#include <edelib/String.h>
|
||||
|
||||
#include "PulseProgress.h"
|
||||
#include "BugzillaSender.h"
|
||||
#include "Bugzilla.h"
|
||||
#include "BugzillaSender.h"
|
||||
|
||||
#define EDE_BUGZILLA_XMLRPC_URL "http://bugs.equinox-project.org/xmlrpc.cgi"
|
||||
#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"
|
||||
@ -49,6 +49,7 @@ EDELIB_NS_USING(String)
|
||||
struct BugContent {
|
||||
const char *bug_title;
|
||||
const char *bug_content;
|
||||
const char *bug_sender;
|
||||
};
|
||||
|
||||
static Fl_Double_Window *win;
|
||||
@ -176,13 +177,13 @@ static void* thread_worker(void *d) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* wait some time if user decided to press 'Cancel' */
|
||||
sleep(1);
|
||||
|
||||
pthread_mutex_lock(&runner_mutex);
|
||||
should_cancel = cancel_sending;
|
||||
pthread_mutex_unlock(&runner_mutex);
|
||||
|
||||
/* allow user to cancel it */
|
||||
sleep(1);
|
||||
|
||||
if(should_cancel) {
|
||||
write_string(report_pipe[1], "CANCELED");
|
||||
goto done;
|
||||
@ -190,18 +191,18 @@ static void* thread_worker(void *d) {
|
||||
|
||||
write_string(report_pipe[1], _("Submitting the report..."));
|
||||
ret = bugzilla_submit_bug(bdata,
|
||||
"ede",
|
||||
"general",
|
||||
data->bug_title,
|
||||
"unspecified",
|
||||
data->bug_content,
|
||||
"All",
|
||||
"All",
|
||||
"P5",
|
||||
"normal");
|
||||
|
||||
"ede",
|
||||
"general",
|
||||
data->bug_title,
|
||||
"unspecified",
|
||||
data->bug_content,
|
||||
"All",
|
||||
"All",
|
||||
"P5",
|
||||
"normal",
|
||||
data->bug_sender);
|
||||
if(ret == -1) {
|
||||
write_string_fail(report_pipe[1], _("Unable to properly submit the data. Please try again"));
|
||||
write_string_fail(report_pipe[1], _("Unable to send the data. Either your email address is not registered on EDE Tracker or the host is temporarily down"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -214,11 +215,11 @@ done:
|
||||
delete data;
|
||||
pthread_exit(NULL);
|
||||
|
||||
/* shutup compiler */
|
||||
/* shutup the compiler */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void perform_send(const char *title, const char *content) {
|
||||
static void perform_send(const char *title, const char *content, const char *sender) {
|
||||
pthread_t thread;
|
||||
|
||||
/*
|
||||
@ -228,6 +229,7 @@ static void perform_send(const char *title, const char *content) {
|
||||
BugContent *c = new BugContent;
|
||||
c->bug_title = title;
|
||||
c->bug_content = content;
|
||||
c->bug_sender = sender;
|
||||
|
||||
/* Create joinable thread. Some implementations prefer this explicitly was set. */
|
||||
pthread_attr_t attr;
|
||||
@ -244,33 +246,36 @@ static void perform_send(const char *title, const char *content) {
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
|
||||
bool bugzilla_send_with_progress(const char *title, const char *content) {
|
||||
bool bugzilla_send_with_progress(const char *title, const char *content, const char *cc) {
|
||||
data_submitted = false;
|
||||
cancel_sending = false;
|
||||
|
||||
bdata = bugzilla_new(EDE_BUGZILLA_XMLRPC_URL);
|
||||
if(!bdata) {
|
||||
alert(_("Unable to initialize bugzilla interface!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* setup communication as soon as possible */
|
||||
if(pipe(report_pipe) != 0) {
|
||||
alert(_("Unable to initialize communication pipe"));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* prepare mutex */
|
||||
pthread_mutex_init(&runner_mutex, NULL);
|
||||
Fl_Button *cancel;
|
||||
|
||||
/* register our callback on pipe */
|
||||
Fl::add_fd(report_pipe[0], FL_READ, report_pipe_cb);
|
||||
|
||||
bdata = bugzilla_new(EDE_BUGZILLA_XMLRPC_URL);
|
||||
if(!bdata) {
|
||||
alert(_("Unable to initialize bugzilla interface!"));
|
||||
goto send_done;
|
||||
}
|
||||
|
||||
/* prepare mutex */
|
||||
pthread_mutex_init(&runner_mutex, NULL);
|
||||
|
||||
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 = new Fl_Button(175, 55, 90, 25, _("&Cancel"));
|
||||
cancel->callback(cancel_cb);
|
||||
win->end();
|
||||
|
||||
@ -280,17 +285,18 @@ bool bugzilla_send_with_progress(const char *title, const char *content) {
|
||||
progress->label(_("Preparing data..."));
|
||||
Fl::add_timeout(PROGRESS_STEP_REFRESH, progress_timeout);
|
||||
|
||||
perform_send(title, content);
|
||||
perform_send(title, content, cc);
|
||||
|
||||
while(win->shown())
|
||||
Fl::wait();
|
||||
|
||||
pthread_mutex_destroy(&runner_mutex);
|
||||
|
||||
send_done:
|
||||
/* clear pipe callback */
|
||||
Fl::remove_fd(report_pipe[0]);
|
||||
clear_timeouts();
|
||||
|
||||
pthread_mutex_destroy(&runner_mutex);
|
||||
|
||||
close(report_pipe[0]);
|
||||
close(report_pipe[1]);
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
#ifndef __BUGZILLASENDER_H__
|
||||
#define __BUGZILLASENDER_H__
|
||||
|
||||
bool bugzilla_send_with_progress(const char *title, const char *content);
|
||||
bool bugzilla_send_with_progress(const char *title,
|
||||
const char *content,
|
||||
const char *cc);
|
||||
|
||||
#endif
|
||||
|
@ -43,7 +43,7 @@ void PulseProgress::draw(void) {
|
||||
|
||||
draw_box(box(), x(), y(), w(), h(), color());
|
||||
|
||||
fl_clip(xoff, yoff, woff, hoff);
|
||||
fl_push_clip(xoff, yoff, woff, hoff);
|
||||
Fl_Color c = fl_color();
|
||||
fl_color(color2());
|
||||
|
||||
@ -63,6 +63,7 @@ void PulseProgress::draw(void) {
|
||||
fl_color(c);
|
||||
fl_pop_clip();
|
||||
|
||||
labelcolor(fl_contrast(labelcolor(), color()));
|
||||
draw_label(x() + bx, y() + by, w() - bw, h() - bh);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <FL/Fl_Text_Editor.H>
|
||||
#include <FL/Fl_Text_Buffer.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Check_Button.H>
|
||||
|
||||
#include <edelib/Window.h>
|
||||
#include <edelib/WindowUtils.h>
|
||||
@ -49,6 +50,7 @@ EDELIB_NS_USING(RX_CASELESS)
|
||||
static Fl_Input *bug_title_input;
|
||||
static Fl_Input *email_input;
|
||||
static Fl_Text_Buffer *text_buf;
|
||||
static Fl_Check_Button *notify_reporter;
|
||||
|
||||
/* check if string has spaces */
|
||||
static bool empty_entry(const char *en) {
|
||||
@ -67,7 +69,7 @@ static bool valid_email(const char *e) {
|
||||
Regex r;
|
||||
|
||||
/* regex stolen from http://www.regular-expressions.info/email.html */
|
||||
if(!r.compile("\\b[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b", RX_CASELESS)) {
|
||||
if(!r.compile("^\\b[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b$", RX_CASELESS)) {
|
||||
E_WARNING(E_STRLOC ": Unable to properly compile regex pattern");
|
||||
return false;
|
||||
}
|
||||
@ -81,8 +83,8 @@ static void close_cb(Fl_Widget*, void *w) {
|
||||
}
|
||||
|
||||
static void send_cb(Fl_Widget*, void *w) {
|
||||
const char *txt;
|
||||
String title, content;
|
||||
const char *txt, *cc = NULL;
|
||||
String title, content;
|
||||
|
||||
if(empty_entry(bug_title_input->value())) {
|
||||
alert(_("Report title is missing"));
|
||||
@ -102,7 +104,7 @@ static void send_cb(Fl_Widget*, void *w) {
|
||||
}
|
||||
|
||||
if(!valid_email(email_input->value())) {
|
||||
alert(_("Email address is invalid. Please use the valid email address"));
|
||||
alert(_("Email address is invalid. Please use the valid email address so developers can contact you in case more details are needed"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -126,7 +128,10 @@ static void send_cb(Fl_Widget*, void *w) {
|
||||
|
||||
free((void *) txt);
|
||||
|
||||
if(bugzilla_send_with_progress(title.c_str(), content.c_str()))
|
||||
if(notify_reporter->value())
|
||||
cc = email_input->value();
|
||||
|
||||
if(bugzilla_send_with_progress(title.c_str(), content.c_str(), cc))
|
||||
close_cb(0, w);
|
||||
}
|
||||
#endif /* HAVE_CURL */
|
||||
@ -184,6 +189,10 @@ int main(int argc, char** argv) {
|
||||
E_WARNING(E_STRLOC ": Unable to read '%s' as debugger output. Continuing...\n");
|
||||
}
|
||||
|
||||
notify_reporter = new Fl_Check_Button(10, 330, 265, 25, _("Receive notifications"));
|
||||
notify_reporter->tooltip(_("Receive notifications when developers updates or comments this issue. You have to create EDE Bugzilla account first to get notifications."));
|
||||
notify_reporter->down_box(FL_DOWN_BOX);
|
||||
|
||||
/* resizable box */
|
||||
Fl_Box *rbox = new Fl_Box(180, 273, 55, 37);
|
||||
|
||||
@ -195,9 +204,9 @@ int main(int argc, char** argv) {
|
||||
|
||||
Fl_Group::current()->resizable(rbox);
|
||||
win->window_icon(bug_xpm);
|
||||
/* win->show(argc, argv); */
|
||||
|
||||
window_center_on_screen(win);
|
||||
win->show();
|
||||
win->show(argc, argv);
|
||||
return Fl::run();
|
||||
#endif /* HAVE_CURL */
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
# data file for the Fltk User Interface Designer (fluid)
|
||||
version 1.0108
|
||||
version 1.0300
|
||||
header_name {.h}
|
||||
code_name {.cxx}
|
||||
Function {} {open
|
||||
} {
|
||||
Fl_Window {} {
|
||||
label {EDE Bug Reporting Tool} open
|
||||
xywh {357 193 480 365} type Double resizable visible
|
||||
xywh {353 189 480 365} type Double resizable visible
|
||||
} {
|
||||
Fl_Box {} {
|
||||
image {../icons/bug.png} xywh {10 10 60 59}
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {EDE Bug Reporting Tool}
|
||||
xywh {80 10 390 30} labelfont 1 labelsize 14 align 20
|
||||
xywh {80 10 390 30} labelfont 1 align 20
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {To help us to improve the future EDE versions, please describe the problem with much details as possible.
|
||||
@ -33,6 +33,10 @@ Note: valid email address is required, so developers can contact you for more in
|
||||
label {Detail description of the problem:}
|
||||
xywh {10 215 460 105} align 5
|
||||
}
|
||||
Fl_Check_Button {} {
|
||||
label {Receive notifications} selected
|
||||
tooltip {Receive notifications when developers updates or comments this issue} xywh {10 330 265 25} down_box DOWN_BOX
|
||||
}
|
||||
Fl_Button {} {
|
||||
label {&Send}
|
||||
xywh {285 330 90 25}
|
||||
@ -41,8 +45,8 @@ Note: valid email address is required, so developers can contact you for more in
|
||||
label {&Cancel}
|
||||
xywh {380 330 90 25}
|
||||
}
|
||||
Fl_Box {} {selected
|
||||
xywh {180 273 55 37} labelsize 14 resizable
|
||||
Fl_Box {} {
|
||||
xywh {180 273 55 37} resizable
|
||||
code0 {/* resizable box */}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user