[evolution-rss] make displaying of articles asynchronous
- From: Lucian Langa <lucilanga src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-rss] make displaying of articles asynchronous
- Date: Thu, 7 Apr 2011 19:26:07 +0000 (UTC)
commit 1c1957cef824d62d1019cf3669116b2dd49f21c0
Author: Lucian Langa <lucilanga gnome org>
Date: Thu Apr 7 20:50:50 2011 +0300
make displaying of articles asynchronous
src/parser.c | 108 +++++++++++++++++++++++++++++++++++++++--------
src/parser.h | 7 +++-
src/rss-status-icon.c | 113 ++++++++++++++++++++++++++++++-------------------
src/rss-status-icon.h | 10 ++++-
src/rss.c | 94 ++++++++++++++++++++--------------------
5 files changed, 220 insertions(+), 112 deletions(-)
---
diff --git a/src/parser.c b/src/parser.c
index 2d7b2a3..844946f 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -44,7 +44,14 @@ extern int rss_verbose_debug;
#include "misc.h"
#include "network-soup.h"
+typedef struct {
+ RDF *r;
+ GQueue *status_msg;
+} AsyncData;
+
extern GConfClient *rss_gconf;
+void asyncr_context_free(AsyncData *asyncr);
+GQueue *display_channel_items_sync(AsyncData *ayncr);
/************ RDF Parser *******************/
@@ -1217,24 +1224,26 @@ refresh_mail_folder(CamelFolder *mail_folder)
camel_folder_thaw(mail_folder);
}
-gchar *
-update_channel(RDF *r)
+GQueue *
+display_channel_items_sync(AsyncData *asyncr)
{
FILE *fr, *fw;
- guint i;
- gchar *sender;
- xmlNodePtr el;
- gchar *subj;
- create_feed *CF;
+ RDF *r = asyncr->r;
+ GQueue *status_msg = asyncr->status_msg;
+ GtkWidget *progress = r->progress;
gchar *chn_name = r->title;
gchar *url = r->uri;
GArray *item = r->item;
- GtkWidget *progress = r->progress;
- gchar *buf, *safes, *feed_dir, *feed_name;
- gchar *msg, *safchn;
- gboolean freeze = FALSE;
CamelFolder *mail_folder = NULL;
+ gchar *sender;
+ gboolean freeze = FALSE;
gchar *article_uid = NULL;
+ gchar *safes, *feed_dir, *feed_name;
+ gchar *msg, *safchn;
+ create_feed *CF;
+ gchar *subj;
+ xmlNodePtr el;
+ guint i;
safes = encode_rfc2047(chn_name);
safchn = g_strchomp (g_strdup(chn_name));
@@ -1243,19 +1252,18 @@ update_channel(RDF *r)
g_free(safes);
migrate_crc_md5(chn_name, url);
- buf = gen_md5(url);
+ r->feedid = gen_md5(url);
feed_dir = rss_component_peek_base_directory();
if (!g_file_test(feed_dir, G_FILE_TEST_EXISTS))
g_mkdir_with_parents (feed_dir, 0755);
- feed_name = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", feed_dir, buf);
+ feed_name = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", feed_dir, r->feedid);
g_free(feed_dir);
fr = fopen(feed_name, "r");
fw = fopen(feed_name, "a+");
for (i=0; NULL != (el = g_array_index(item, xmlNodePtr, i)); i++) {
- update_sr_message();
update_progress_text(chn_name);
if (rf->cancel || rf->cancel_all || rf->display_cancel)
break;
@@ -1279,7 +1287,7 @@ update_channel(RDF *r)
r, &article_uid);
g_array_append_val(r->uids, article_uid);
if (!CF) continue;
- CF->feedid = g_strdup(buf);
+ CF->feedid = g_strdup(r->feedid);
CF->sender = g_strdup(sender);
if (r->prefix)
CF->full_path = g_build_path(
@@ -1291,7 +1299,6 @@ update_channel(RDF *r)
if (!mail_folder) {
mail_folder = check_feed_folder(CF->full_path);
}
-
subj = g_strdup(CF->subj);
ftotal++;
@@ -1316,11 +1323,12 @@ update_channel(RDF *r)
done: farticle++;
d("put success()\n");
- update_status_icon(chn_name, subj);
+ update_status_icon_text(status_msg, chn_name, subj);
g_free(subj);
}
if (freeze)
refresh_mail_folder(mail_folder);
+
if (mail_folder) {
if ((rf->import || feed_new)
&& (!rf->cancel && !rf->cancel_all && !rf->display_cancel)) {
@@ -1340,7 +1348,71 @@ done: farticle++;
if (fw) fclose(fw);
g_free(feed_name);
- return buf;
+ return status_msg;
+}
+
+static void
+display_channel_items_thread (GSimpleAsyncResult *simple,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ AsyncData *asyncr;
+ GError *error = NULL;
+
+ asyncr = g_simple_async_result_get_op_res_gpointer (simple);
+ asyncr->status_msg = display_channel_items_sync(asyncr);
+
+ if (error != NULL) {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+}
+
+void
+asyncr_context_free(AsyncData *asyncr)
+{
+ d("free r-> components\n");
+ if (asyncr->r->maindate)
+ g_free(asyncr->r->maindate);
+ g_array_free(asyncr->r->item, TRUE);
+ g_free(asyncr->r->feedid);
+ if (asyncr->r->uids)
+ g_array_free(asyncr->r->uids, TRUE);
+ if (asyncr->r->cache)
+ xmlFreeDoc(asyncr->r->cache);
+ if (asyncr->r->type)
+ g_free(asyncr->r->type);
+ if (asyncr->r->version)
+ g_free(asyncr->r->version);
+ g_free(asyncr->r);
+ g_free(asyncr);
+}
+
+
+void
+display_channel_items (RDF *r,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ AsyncData *data;
+
+ data = g_new0(AsyncData, 1);
+ data->r = r;
+ data->status_msg = user_data;
+
+ simple = g_simple_async_result_new (
+ NULL, callback, user_data, display_channel_items);
+
+ g_simple_async_result_set_op_res_gpointer (
+ simple, data, (GDestroyNotify)asyncr_context_free);
+
+ g_simple_async_result_run_in_thread (
+ simple, display_channel_items_thread, io_priority, cancellable);
+
+ g_object_unref (simple);
}
gchar *
diff --git a/src/parser.h b/src/parser.h
index 0889355..b52c9db 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -21,7 +21,12 @@
#include <mail/em-format-html.h>
-gchar *update_channel(RDF *r);
+void display_channel_items (RDF *r,
+ gint io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
xmlDoc *rss_html_url_decode(const char *html, int len);
const char *layer_find (xmlNodePtr node,
diff --git a/src/rss-status-icon.c b/src/rss-status-icon.c
index 93d77b8..35cd411 100644
--- a/src/rss-status-icon.c
+++ b/src/rss-status-icon.c
@@ -25,10 +25,19 @@
GtkStatusIcon *status_icon = NULL;
gboolean winstatus;
-gchar *flat_status_msg;
extern GtkWidget *evo_window;
extern GQueue *status_msg;
+void status_text_free(StatusText *st);
+
+void
+status_text_free(StatusText *st)
+{
+ g_free(st->chn_name);
+ g_free(st->title);
+ g_free(st);
+}
+
void
icon_activated (GtkStatusIcon *icon, gpointer pnotify)
{
@@ -51,6 +60,8 @@ icon_activated (GtkStatusIcon *icon, gpointer pnotify)
g_free(folder_name);
rss_select_folder(real_name);
}
+ g_queue_foreach(status_msg, (GFunc)status_text_free, NULL);
+ status_msg = g_queue_new();
}
gboolean
@@ -102,19 +113,27 @@ flicker_stop(gpointer user_data)
return FALSE;
}
-
void
-flaten_status(gpointer msg, gpointer user_data)
+flatten_status(StatusText *st, gchar **user_data)
{
- if (strlen(msg)) {
- if (flat_status_msg)
- flat_status_msg = g_strconcat(
- flat_status_msg,
- msg,
+ gchar *temp = NULL;
+ if (strlen(st->chn_name)) {
+ gchar *total;
+ gchar *tchn, *ttit;
+ tchn = g_markup_escape_text (st->chn_name, -1);
+ ttit = g_markup_escape_text (st->title, -1);
+ total = g_strdup_printf("<b>%s</b>\n%s\n", tchn, ttit);
+ g_free(tchn);
+ g_free(ttit);
+ if (*user_data)
+ temp = g_strconcat(
+ *user_data,
+ total,
NULL);
else
- flat_status_msg = g_strdup(msg);
+ temp = g_strdup(total);
}
+ *user_data = temp;
}
void
@@ -155,50 +174,56 @@ toggle_window(void)
}
void
-update_status_icon(const char *channel, gchar *title)
+update_status_icon(GQueue *status)
{
- gchar *total;
gchar *iconfile;
- gchar *tchn, *ttit;
- GConfClient *client = gconf_client_get_default();
- if (gconf_client_get_bool (client, GCONF_KEY_STATUS_ICON, NULL)) {
- tchn = g_markup_escape_text (channel, -1);
- ttit = g_markup_escape_text (title, -1);
- total = g_strdup_printf("<b>%s</b>\n%s\n", tchn, ttit);
- g_free(tchn);
- g_free(ttit);
- create_status_icon();
- iconfile = g_build_filename (EVOLUTION_ICONDIR,
+ StatusText *channel;
+ gchar *flat = NULL;
+ if (g_queue_is_empty(status))
+ return;
+ create_status_icon();
+ iconfile = g_build_filename (EVOLUTION_ICONDIR,
"rss-icon-unread.png",
NULL);
- gtk_status_icon_set_from_file (
- status_icon,
- iconfile);
- g_free(iconfile);
- g_queue_push_tail(status_msg, total);
- if (g_queue_get_length(status_msg) == 6)
- g_queue_pop_head(status_msg);
- g_queue_foreach(status_msg, flaten_status, flat_status_msg);
+ gtk_status_icon_set_from_file (
+ status_icon,
+ iconfile);
+ g_free(iconfile);
+ channel = g_queue_peek_tail(status);
+ g_queue_foreach(status, (GFunc)flatten_status, &flat);
+ if (flat)
#if GTK_CHECK_VERSION (2,16,0)
- gtk_status_icon_set_tooltip_markup (status_icon, flat_status_msg);
+ gtk_status_icon_set_tooltip_markup (status_icon, flat);
#else
- gtk_status_icon_set_tooltip (status_icon, flat_status_msg);
+ gtk_status_icon_set_tooltip (status_icon, flat);
#endif
#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 22
- if (gconf_client_get_bool (client, GCONF_KEY_BLINK_ICON, NULL)
- && !gtk_status_icon_get_blinking(status_icon))
- gtk_status_icon_set_blinking (status_icon, TRUE);
- g_timeout_add(15 * 1000, flicker_stop, NULL);
+ if (gconf_client_get_bool (client, GCONF_KEY_BLINK_ICON, NULL)
+ && !gtk_status_icon_get_blinking(status_icon))
+ gtk_status_icon_set_blinking (status_icon, TRUE);
+ g_timeout_add(15 * 1000, flicker_stop, NULL);
#endif
- gtk_status_icon_set_has_tooltip (status_icon, TRUE);
- g_object_set_data_full (
- G_OBJECT (status_icon), "uri",
- lookup_feed_folder((gchar *)channel),
- (GDestroyNotify) g_free);
- g_free(flat_status_msg);
-// g_free(total);
- flat_status_msg = NULL;
+ gtk_status_icon_set_has_tooltip (status_icon, TRUE);
+ g_object_set_data_full (
+ G_OBJECT (status_icon), "uri",
+ lookup_feed_folder((gchar *)channel->chn_name),
+ (GDestroyNotify) g_free);
+ g_free(flat);
+}
+
+void
+update_status_icon_text(GQueue *status, const char *channel, gchar *title)
+{
+ StatusText *st = g_new0 (StatusText, 1);
+ st->chn_name = g_strdup(channel);
+ st->title = g_strdup(title);
+ g_queue_push_tail(status, st);
+ if (g_queue_get_length(status) == 6) {
+ StatusText *tmp = g_queue_peek_head(status);
+ g_free(tmp->chn_name);
+ g_free(tmp->title);
+ g_free(tmp);
+ g_queue_pop_head(status);
}
- g_object_unref(client);
}
diff --git a/src/rss-status-icon.h b/src/rss-status-icon.h
index 0fa11fe..54ae7c5 100644
--- a/src/rss-status-icon.h
+++ b/src/rss-status-icon.h
@@ -16,10 +16,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+typedef struct {
+ gchar *chn_name;
+ gchar *title;
+} StatusText;
+
void icon_activated (GtkStatusIcon *icon, gpointer pnotify);
gboolean button_press_cb (GtkWidget *widget, GdkEventButton *event, gpointer data);
void create_status_icon(void);
gboolean flicker_stop(gpointer user_data);
-void flaten_status(gpointer msg, gpointer user_data);
+void flatten_status(StatusText *st, gchar **user_data);
void toggle_window(void);
-void update_status_icon(const char *channel, gchar *title);
+void update_status_icon(GQueue *status);
+void update_status_icon_text(GQueue *status_msg, const char *channel, gchar *title);
diff --git a/src/rss.c b/src/rss.c
index 0855d1b..8447327 100644
--- a/src/rss.c
+++ b/src/rss.c
@@ -247,7 +247,6 @@ gboolean browser_fetching = 0; //mycall event could be triggered
gint browser_fill = 0; //how much data currently written to browser
gchar *process_feed(RDF *r);
-gboolean display_feed(RDF *r);
gchar *display_doc (RDF *r);
gchar *display_comments (RDF *r, EMFormatHTML *format);
void check_folders(void);
@@ -1686,7 +1685,8 @@ gecko_click(GtkMozEmbed *mozembed, gpointer dom_event, gpointer user_data)
if (button == 2)
gtk_menu_popup (
GTK_MENU (menu),
- NULL, NULL, NULL, NULL,
+ NULL, NULL,
+ gtk_status_icon_position_menu, user_data,
0, GDK_CURRENT_TIME);
#else
emp = em_popup_new("org.gnome.evolution.mail.formathtmldisplay.popup");
@@ -1703,9 +1703,10 @@ gecko_click(GtkMozEmbed *mozembed, gpointer dom_event, gpointer user_data)
menu = e_popup_create_menu_once((EPopup *)emp, NULL, 0);
if (button == 2)
- gtk_menu_popup(
- menu,
- NULL, NULL, NULL, NULL,
+ gtk_menu_popup (
+ GTK_MENU (menu),
+ NULL, NULL,
+ gtk_status_icon_position_menu, user_data,
button,
gtk_get_current_event_time());
#endif
@@ -3139,8 +3140,6 @@ add:
store_redraw(GTK_TREE_VIEW(rf->treeview));
save_gconf_feed();
-// if (feed->validate && !(rf->import && rf->display_cancel))
-// display_feed(r);
g_idle_add(
(GSourceFunc)display_feed_async,
g_strdup(chn_name));
@@ -3160,8 +3159,6 @@ add:
xmlFreeDoc(r->cache);
if (r->type)
g_free(r->type);
- if (r->uids)
- g_array_free(r->uids, TRUE);
if (r)
g_free(r);
if (content)
@@ -3282,12 +3279,14 @@ setup_feed(add_feed *feed)
void
update_sr_message(void)
{
- if (flabel && farticle) {
- gchar *fmsg = g_strdup_printf(
+ gchar *fmsg = NULL;
+ if (G_IS_OBJECT(rf->label) && farticle) {
+ fmsg = g_strdup_printf(
_("Getting message %d of %d"),
farticle,
ftotal);
- gtk_label_set_text (GTK_LABEL (flabel), fmsg);
+ if (G_IS_OBJECT(rf->label))
+ gtk_label_set_text (GTK_LABEL (rf->label), fmsg);
g_free(fmsg);
}
}
@@ -3470,7 +3469,6 @@ generic_finish_feed(rfMessage *msg, gpointer user_data)
if (msg->status_code == SOUP_STATUS_CANCELLED)
goto out;
-
response = g_string_new_len(msg->body, msg->length);
g_print("feed %s\n", (gchar *)user_data);
@@ -3490,15 +3488,15 @@ generic_finish_feed(rfMessage *msg, gpointer user_data)
NULL, title, tmsg);
g_free(tmsg);
g_free(title);
- goto cleanup;
+ goto out;
}
if (msg->status_code == SOUP_STATUS_CANCELLED)
- goto cleanup;
+ goto out;
if (!deleted) {
if (!user_data || !lookup_key(user_data))
- goto cleanup;
+ goto out;
r->uri = g_hash_table_lookup(
rf->hr, lookup_key(user_data));
@@ -3519,19 +3517,15 @@ generic_finish_feed(rfMessage *msg, gpointer user_data)
g_strdup(chn_name));
save_gconf_feed();
update_ttl(md5, r->ttl);
- //save_data = user_data;
user_data = chn_name;
}
if (g_hash_table_lookup(rf->hrdel_feed, lookup_key(user_data)))
get_feed_age(r, user_data);
}
}
- //ftotal+=r->total;
update_sr_message();
g_string_free(response, 1);
-//tout:
-
if (rf->sr_feed && !deleted) {
gchar *furl = g_markup_printf_escaped(
"<b>%s</b>: %s",
@@ -3564,15 +3558,6 @@ generic_finish_feed(rfMessage *msg, gpointer user_data)
rf->progress_bar = NULL;
rf->info = NULL;
}
-cleanup:if (r->cache)
- xmlFreeDoc(r->cache);
- if (r->type)
- g_free(r->type);
- if (r->version)
- g_free(r->version);
- if (r->uids)
- g_array_free(r->uids, TRUE);
- g_free(r);
out: if (chn_name) { //user_data
//not sure why it dies here
if (!rf->cancel && !rf->cancel_all)
@@ -4750,9 +4735,6 @@ org_gnome_evolution_rss(void *ep, EMEventTargetSendReceive *t)
cancel_button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
status_label = gtk_label_new (_("Waiting..."));
-// status_label = e_clipped_label_new (
-// "www",
-// PANGO_WEIGHT_BOLD, 1.0);
gtk_misc_set_alignment (GTK_MISC (label), 0, .5);
gtk_misc_set_alignment (GTK_MISC (status_label), 0, .5);
@@ -4969,7 +4951,7 @@ e_plugin_lib_enable(EPlugin *ep, int enable)
#endif
rss_soup_init();
d("init_gdbus()\n");
- /*G D-BUS init*/
+ /*GD-BUS init*/
init_gdbus ();
prepare_hashes();
if (gconf_client_get_bool (rss_gconf, GCONF_KEY_STATUS_ICON, NULL))
@@ -5431,7 +5413,7 @@ process_attachments(create_feed *CF)
CFL = g_new0(cfl, 1);
CFL->url = l->data;
CFL->CF = CF;
- d("attachment file:%s\n", l->data)
+ d("attachment file:%s\n", (gchar *)l->data)
CF->attachmentsqueue++;
download_unblocking(
CFL->url,
@@ -5475,7 +5457,8 @@ finish_attachment (SoupSession *soup_sess,
1,
user_data->file);
#endif
-out: fclose(user_data->file);
+out: if (user_data->file)
+ fclose(user_data->file);
rf->enclist = g_list_remove(rf->enclist, user_data->url);
if (user_data->CF->attachmentsqueue)
@@ -5549,7 +5532,8 @@ finish_enclosure (SoupSession *soup_sess,
1,
CFL->file);
#endif
-out: fclose(CFL->file);
+out: if (CFL->file)
+ fclose(CFL->file);
CF->efile = CFL->file;
CF->enclurl = CF->encl;
CF->encl = g_strdup(CFL->name);
@@ -5641,24 +5625,40 @@ process_feed(RDF *r)
return NULL;
}
-gboolean
-display_feed(RDF *r)
+typedef struct {
+ RDF *r;
+ GQueue *status_msg;
+} AsyncData;
+
+void
+display_doc_finish (GObject *o, GAsyncResult *result, gpointer user_data);
+
+void
+display_doc_finish (GObject *o, GAsyncResult *result, gpointer user_data)
{
- r->feedid = update_channel(r);
- if (r->maindate)
- g_free(r->maindate);
- g_array_free(r->item, TRUE);
- g_free(r->feedid);
- return 0;
+ GSimpleAsyncResult *simple;
+ AsyncData *asyncr;
+ GConfClient *client = gconf_client_get_default();
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ asyncr = g_simple_async_result_get_op_res_gpointer (simple);
+ if (gconf_client_get_bool (client, GCONF_KEY_STATUS_ICON, NULL)) {
+ update_status_icon(asyncr->status_msg);
+ }
+ g_object_unref(client);
}
gchar *
display_doc (RDF *r)
{
gchar *title = NULL;
- if ((title = process_feed(r)))
- display_feed(r);
- return title;
+ if ((title = process_feed(r))) {
+ update_sr_message();
+ display_channel_items (r,
+ 0,
+ G_PRIORITY_DEFAULT, display_doc_finish, status_msg);
+ }
+ return g_strdup(title);
}
void delete_oldest_article(CamelFolder *folder, guint unread);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]