[evolution-rss] queue enclosure downloads (fixes #599528)
- From: Lucian Langa <lucilanga src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [evolution-rss] queue enclosure downloads (fixes #599528)
- Date: Wed, 27 Jan 2010 21:43:13 +0000 (UTC)
commit eed62d936179d56053277bfb936d42712d27a3d7
Author: Lucian Langa <lucilanga gnome org>
Date: Wed Jan 27 23:42:11 2010 +0200
queue enclosure downloads (fixes #599528)
src/debug.h | 6 +-
src/evolution-rss.schemas.in | 14 ++++
src/misc.c | 154 +++++++++++++++++++-------------------
src/network-soup.c | 60 ++++++++++++++-
src/network-soup.h | 1 +
src/network.h | 1 +
src/parser.c | 22 +++---
src/rss.c | 173 ++++++++++++++++++++++++------------------
src/rss.h | 153 +++++++++++++++++++------------------
9 files changed, 340 insertions(+), 244 deletions(-)
---
diff --git a/src/debug.h b/src/debug.h
index 98f2a78..e44b622 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -19,11 +19,11 @@
#ifndef __DEBUG_H__
#define __DEBUG_H__ 1
-#define d(f, x...) if (rss_verbose_debug) { g_print("%s(%d) %s():", __FILE__, __LINE__, __FUNCTION__);\
- g_print(f, ## x);}
+#define d(f, x...) if (rss_verbose_debug) { g_print("%s(%d) in %s():", __FILE__, __LINE__, __FUNCTION__);\
+ g_print(f, ## x);}
#define dp(f, x...) { g_print("%s(%d) %s():", __FILE__, __LINE__, __FUNCTION__);\
- g_print(f, ## x);}
+ g_print(f, ## x);}
#endif /*__DEBUG_H__*/
diff --git a/src/evolution-rss.schemas.in b/src/evolution-rss.schemas.in
index bcf5f04..87d46cf 100644
--- a/src/evolution-rss.schemas.in
+++ b/src/evolution-rss.schemas.in
@@ -88,6 +88,20 @@
</schema>
<schema>
+ <key>/schemas/apps/evolution/evolution-rss/network_queue_size</key>
+ <applyto>/apps/evolution/evolution-rss/network_queue_size</applyto>
+ <owner>evolution-rss</owner>
+ <type>int</type>
+ <default>5</default>
+ <locale name="C">
+ <short>Network queue size</short>
+ <long>
+ How many simultaneous downloads.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/apps/evolution/evolution-rss/html_js</key>
<applyto>/apps/evolution/evolution-rss/html_js</applyto>
<owner>evolution-rss</owner>
diff --git a/src/misc.c b/src/misc.c
index b985bcf..9038a20 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -1,5 +1,5 @@
/* Evoution RSS Reader Plugin
- * Copyright (C) 2007-2009 Lucian Langa <cooly gnome eu org>
+ * Copyright (C) 2007-2010 Lucian Langa <cooly gnome eu org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -66,35 +66,35 @@ void
free_hash(gpointer key, gpointer value, gpointer user_data)
{
g_print("FREE - key:%p, value:%p\n", (gchar *)key, (gchar *)value);
- // xmlFreeDoc(key);
+// xmlFreeDoc(key);
}
gboolean
check_key_match (gpointer key, gpointer value, gpointer user_data)
{
- char *sf_href = (char *)key;
- char *int_uri = (char *)user_data;
+ char *sf_href = (char *)key;
+ char *int_uri = (char *)user_data;
d("checking hay:%s for neddle:%s\n", sf_href, int_uri);
- if (!strcmp (sf_href, int_uri))
- return TRUE; /* Quit calling the callback */
+ if (!strcmp (sf_href, int_uri))
+ return TRUE; /* Quit calling the callback */
- return FALSE; /* Continue calling the callback till end of table */
+ return FALSE; /* Continue calling the callback till end of table */
}
gboolean
check_if_match (gpointer key, gpointer value, gpointer user_data)
{
- char *sf_href = (char *)value;
- char *int_uri = (char *)user_data;
+ char *sf_href = (char *)value;
+ char *int_uri = (char *)user_data;
d("checking hay:%s for neddle:%s\n", sf_href, int_uri);
- if (!strcmp (sf_href, int_uri))
- return TRUE; /* Quit calling the callback */
+ if (!strcmp (sf_href, int_uri))
+ return TRUE; /* Quit calling the callback */
- return FALSE; /* Continue calling the callback till end of table */
+ return FALSE; /* Continue calling the callback till end of table */
}
gchar *
@@ -208,9 +208,9 @@ get_port_from_uri(gchar *uri)
if (strstr(uri, "://") == NULL)
return NULL;
str = g_strsplit(uri, "://", 2);
- str2 = g_strsplit(str[1], "/", 2);
- str3 = g_strsplit(str2[0], ":", 2);
- port = g_strdup(str3[1]);
+ str2 = g_strsplit(str[1], "/", 2);
+ str3 = g_strsplit(str2[0], ":", 2);
+ port = g_strdup(str3[1]);
g_strfreev(str);
g_strfreev(str2);
g_strfreev(str3);
@@ -227,8 +227,8 @@ get_server_from_uri(gchar *uri)
if (strstr(uri, "://") == NULL)
return NULL;
str = g_strsplit(uri, "://", 2);
- str2 = g_strsplit(str[1], "/", 2);
- server = g_strdup_printf("%s://%s", str[0], str2[0]);
+ str2 = g_strsplit(str[1], "/", 2);
+ server = g_strdup_printf("%s://%s", str[0], str2[0]);
g_strfreev(str);
g_strfreev(str2);
return server;
@@ -239,17 +239,17 @@ strplchr(gchar *source)
{
GString *str = g_string_new(NULL);
gchar *string;
- const unsigned char *s = (const unsigned char *)source;
- guint len = strlen(source);
- while (*s != 0 || len) {
- if (*s == 0x3f) {
- g_string_append(str, "%3F");
- s++;
- } else
- g_string_append_c (str, *s++);
- len--;
- }
- g_string_append_c(str, 0);
+ const unsigned char *s = (const unsigned char *)source;
+ guint len = strlen(source);
+ while (*s != 0 || len) {
+ if (*s == 0x3f) {
+ g_string_append(str, "%3F");
+ s++;
+ } else
+ g_string_append_c (str, *s++);
+ len--;
+ }
+ g_string_append_c(str, 0);
string = str->str;
g_string_free(str, 0);
return string;
@@ -303,26 +303,26 @@ markup_decode (gchar *str)
gchar *
gen_crc(const char *msg)
{
- register unsigned long crc, poly;
- uint32_t crc_tab[256];
- int i,j;
-
- poly = 0xEDB88320L;
- for (i = 0; i < 256; i++) {
- crc = i;
- for (j = 8; j > 0; j--) {
- if (crc & 1)
- crc = (crc >> 1) ^ poly;
- else
- crc >>= 1;
- }
- crc_tab[i] = crc;
- }
+ register unsigned long crc, poly;
+ uint32_t crc_tab[256];
+ int i,j;
+
+ poly = 0xEDB88320L;
+ for (i = 0; i < 256; i++) {
+ crc = i;
+ for (j = 8; j > 0; j--) {
+ if (crc & 1)
+ crc = (crc >> 1) ^ poly;
+ else
+ crc >>= 1;
+ }
+ crc_tab[i] = crc;
+ }
- crc = 0xFFFFFFFF;
- for (i = 0; i < strlen(msg); i++)
- crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *msg++) & 0xFF];
- return g_strdup_printf("%x", (unsigned int)(crc ^ 0xFFFFFFFF));
+ crc = 0xFFFFFFFF;
+ for (i = 0; i < strlen(msg); i++)
+ crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *msg++) & 0xFF];
+ return g_strdup_printf("%x", (unsigned int)(crc ^ 0xFFFFFFFF));
}
gchar *
@@ -484,10 +484,10 @@ notrfc: return 0;
gchar *
encode_rfc2047(gchar *str)
{
- gchar *tmp = decode_entities(str);
- gchar *rfctmp = camel_header_encode_string((unsigned char*)tmp);
- g_free(tmp);
- return (gchar *)rfctmp;
+ gchar *tmp = decode_entities(str);
+ gchar *rfctmp = camel_header_encode_string((unsigned char*)tmp);
+ g_free(tmp);
+ return (gchar *)rfctmp;
}
//check if feed already exists in feed file
@@ -495,46 +495,46 @@ encode_rfc2047(gchar *str)
gboolean
feed_is_new(gchar *file_name, gchar *needle)
{
- gchar rfeed[513];
+ gchar rfeed[513];
FILE *fr;
int occ;
gchar *tmpneedle, *port, *tp;
- memset(rfeed, 0, 512);
+ memset(rfeed, 0, 512);
fr = fopen(file_name, "r");
occ = 0;
tmpneedle = NULL;
port = get_port_from_uri(needle);
- if (port && atoi(port) == 80) {
+ if (port && atoi(port) == 80) {
tp = g_strconcat(":", port, NULL);
- g_free(port);
- tmpneedle = strextr(needle, tp);
- g_free(tp);
- } else
- tmpneedle = g_strdup(needle);
-
- if (fr) {
- while (fgets(rfeed, 511, fr) != NULL) {
- if (strstr(rfeed, tmpneedle)) {
- occ=1;
- break;
- }
- }
- fclose(fr);
- }
- g_free(tmpneedle);
- return occ;
+ g_free(port);
+ tmpneedle = strextr(needle, tp);
+ g_free(tp);
+ } else
+ tmpneedle = g_strdup(needle);
+
+ if (fr) {
+ while (fgets(rfeed, 511, fr) != NULL) {
+ if (strstr(rfeed, tmpneedle)) {
+ occ=1;
+ break;
+ }
+ }
+ fclose(fr);
+ }
+ g_free(tmpneedle);
+ return occ;
}
void
write_feed_status_line(gchar *file, gchar *needle)
{
- FILE *fw = fopen(file, "a+");
- if (fw) {
- fputs(g_strstrip(needle), fw);
- fputs("\n", fw);
- fclose(fw);
- }
+ FILE *fw = fopen(file, "a+");
+ if (fw) {
+ fputs(g_strstrip(needle), fw);
+ fputs("\n", fw);
+ fclose(fw);
+ }
}
#endif
diff --git a/src/network-soup.c b/src/network-soup.c
index 610f56c..312dcb4 100644
--- a/src/network-soup.c
+++ b/src/network-soup.c
@@ -1,5 +1,5 @@
/* Evolution RSS Reader Plugin
- * Copyright (C) 2007-2009 Lucian Langa <cooly gnome eu org>
+ * Copyright (C) 2007-2010 Lucian Langa <cooly gnome eu org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -62,6 +62,18 @@ typedef struct {
gchar *chunk;
} CallbackInfo;
+typedef struct {
+ SoupSession *ss;
+ SoupMessage *sm;
+ gpointer cb2;
+ gpointer cbdata2;
+ gchar *url;
+} STNET;
+
+#define DOWNLOAD_QUEUE_SIZE 5
+guint net_qid = 0; // net queue dispatcher
+guint net_queue_run_count = 0; //downloads in progress
+
static void
#if LIBSOUP_VERSION < 2003000
got_chunk_blocking_cb(SoupMessage *msg, CallbackInfo *info) {
@@ -622,7 +634,9 @@ net_get_unblocking(gchar *url,
return TRUE;
}
+
// same stuff as net_get_* but without accumulating headers
+// push all donwloads to a customizable length queue
gboolean
download_unblocking(
gchar *url,
@@ -637,6 +651,7 @@ download_unblocking(
CallbackInfo *info = NULL;
SoupSession *soup_sess;
gchar *agstr;
+ STNET *stnet;
soup_sess = soup_session_async_new();
@@ -705,8 +720,16 @@ download_unblocking(
}
soup_message_body_set_accumulate (msg->response_body, FALSE);
- soup_session_queue_message (soup_sess, msg,
- cb2, cbdata2);
+ stnet = g_new0(STNET, 1);
+ stnet->ss = soup_sess;
+ stnet->sm = msg;
+ stnet->cb2 = cb2;
+ stnet->cbdata2 = cbdata2;
+ stnet->url = g_strdup(url);
+ g_queue_push_tail (rf->stqueue, stnet);
+ rf->enclist = g_list_append (rf->enclist, g_strdup(url));
+ if (!net_qid)
+ net_qid = g_idle_add((GSourceFunc)net_queue_dispatcher, NULL);
//// g_object_add_weak_pointer (G_OBJECT(msg), (gpointer)info);
g_object_weak_ref (G_OBJECT(msg), unblock_free, soup_sess);
@@ -716,6 +739,35 @@ download_unblocking(
return TRUE;
}
+gboolean
+net_queue_dispatcher(void)
+{
+ STNET *_stnet;
+ guint qlen = g_queue_get_length(rf->stqueue);
+
+ dp("net queue size:%d messages processing:%d\n",
+ g_queue_get_length(rf->stqueue),
+ net_queue_run_count);
+
+ if (qlen && net_queue_run_count < gconf_client_get_int (
+ rss_gconf,
+ GCONF_KEY_DOWNLOAD_QUEUE_SIZE,
+ NULL)) {
+ net_queue_run_count++;
+ _stnet = g_queue_pop_head(rf->stqueue);
+ soup_session_queue_message (
+ _stnet->ss,
+ _stnet->sm,
+ _stnet->cb2,
+ _stnet->cbdata2);
+ g_free(_stnet);
+ return TRUE;
+ }
+ dp("workers full, disable queue run!\n");
+ net_qid = 0;
+ return FALSE;
+}
+
GString*
net_post_blocking(gchar *url,
GSList *headers,
@@ -911,6 +963,8 @@ rss_soup_init(void)
}
g_free(cookie_path);
g_free(moz_cookie_path);
+ if (!rf->stqueue)
+ rf->stqueue = g_queue_new();
}
#endif
}
diff --git a/src/network-soup.h b/src/network-soup.h
index c6c74a9..09df863 100644
--- a/src/network-soup.h
+++ b/src/network-soup.h
@@ -57,6 +57,7 @@ GString *net_post_blocking(
#define NET_ERROR net_error_quark()
int net_error_quark(void);
+gboolean net_queue_dispatcher(void);
#if (DATASERVER_VERSION >= 2023001)
EProxy *proxy_init(void);
diff --git a/src/network.h b/src/network.h
index e34fb36..ecf8790 100644
--- a/src/network.h
+++ b/src/network.h
@@ -30,6 +30,7 @@
#define GCONF_KEY_USER_PROXY "/apps/evolution/evolution-rss/user_proxy"
#define GCONF_KEY_PASS_PROXY "/apps/evolution/evolution-rss/pass_proxy"
#define GCONF_KEY_NETWORK_TIMEOUT "/apps/evolution/evolution-rss/network_timeout"
+#define GCONF_KEY_DOWNLOAD_QUEUE_SIZE "/apps/evolution/evolution-rss/network_queue_size"
/* GConf paths and keys from e-d-s e-proxy.c*/
#define PATH_GCONF_EVO_NETWORK_CONFIG "/apps/evolution/shell/network_config"
diff --git a/src/parser.c b/src/parser.c
index 65373a6..45048b7 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1062,7 +1062,7 @@ update_channel(RDF *r)
GtkWidget *progress = r->progress;
gchar *buf, *safes, *feed_dir, *feed_name;
gchar *uid, *msg;
- gchar *tmpdir, *name, *enclurl;
+ gchar *tmpdir, *name;
GError *err = NULL;
safes = encode_rfc2047(chn_name);
@@ -1117,30 +1117,30 @@ update_channel(RDF *r)
if (!feed_is_new(feed_name, CF->feed_uri)) {
ftotal++;
if (CF->encl) {
+ if (g_list_find_custom(rf->enclist,
+ CF->encl,
+ (GCompareFunc)strcmp))
+ continue;
tmpdir = e_mkdtemp("evo-rss-XXXXXX");
if ( tmpdir == NULL)
continue;
- name = g_build_filename(tmpdir, g_path_get_basename(CF->encl), NULL);
+ name = g_build_filename(tmpdir,
+ g_path_get_basename(CF->encl),
+ NULL);
g_free(tmpdir);
- enclurl = CF->encl;
- //replace encl with filename generated
- // this will be a weak ref and get feed by free_cf
+ CF->enclurl = CF->encl;
CF->encl = name;
- dp("enclosure file:%s\n", name)
+ d("enclosure file:%s\n", name)
CF->efile = fopen(name, "w");
if (!CF->efile) continue;
- //*************************************************************************//
- //we need to disable mail filter for large enclosures as it burns cpu a lot//
- //*************************************************************************//
download_unblocking(
- enclurl,
+ CF->enclurl,
download_chunk,
CF->efile,
(gpointer)finish_enclosure,
CF,
0,
&err);
- g_free(enclurl);
} else {
create_mail(CF);
write_feed_status_line(CF->feed_fname, CF->feed_uri);
diff --git a/src/rss.c b/src/rss.c
index 0d8528e..ec3d16d 100644
--- a/src/rss.c
+++ b/src/rss.c
@@ -1,5 +1,5 @@
/* Evoution RSS Reader Plugin
- * Copyright (C) 2007-2009 Lucian Langa <cooly gnome eu org>
+ * Copyright (C) 2007-2010 Lucian Langa <cooly gnome eu org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -541,7 +541,7 @@ create_user_pass_dialog(RSS_AUTH *auth)
GtkWidget *container, *container2;
GtkWidget *widget, *action_area;
GtkWidget *content_area, *password_dialog;
- AtkObject *a11y;
+ AtkObject *a11y;
gchar *markup;
widget = gtk_dialog_new_with_buttons (
@@ -593,32 +593,32 @@ create_user_pass_dialog(RSS_AUTH *auth)
GTK_TABLE (container), widget,
0, 1, 0, 3, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
- widget = gtk_label_new (NULL);
- gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
+ widget = gtk_label_new (NULL);
+ gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
markup = g_markup_printf_escaped (_("Enter your username and password for:\n '%s'"), auth->url);
gtk_label_set_markup (GTK_LABEL (widget), markup);
g_free (markup);
- gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
- gtk_widget_show (widget);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_widget_show (widget);
gtk_table_attach (
GTK_TABLE (container), widget,
1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- container2 = gtk_table_new (2, 2, FALSE);
+ container2 = gtk_table_new (2, 2, FALSE);
gtk_widget_show (container2);
- gtk_table_attach (
- GTK_TABLE (container), container2,
- 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+ gtk_table_attach (
+ GTK_TABLE (container), container2,
+ 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0);
- widget = gtk_label_new (NULL);
- gtk_label_set_markup (GTK_LABEL (widget), _("Username: "));
- gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
- gtk_widget_show (widget);
- gtk_table_attach (
- GTK_TABLE (container2), widget,
- 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+ widget = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (widget), _("Username: "));
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_widget_show (widget);
+ gtk_table_attach (
+ GTK_TABLE (container2), widget,
+ 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
username = gtk_entry_new ();
a11y = gtk_widget_get_accessible (username);
@@ -710,9 +710,9 @@ web_auth_dialog(RSS_AUTH *auth_info)
user_pass_cb(auth_info, response, dialog);
} else
g_signal_connect_swapped (dialog,
- "response",
- G_CALLBACK (user_pass_cb),
- auth_info);
+ "response",
+ G_CALLBACK (user_pass_cb),
+ auth_info);
}
gboolean
@@ -984,27 +984,27 @@ xml_set_prop (xmlNodePtr node, const char *name, char **val)
static gboolean
xml_set_bool (xmlNodePtr node, const char *name, gboolean *val)
{
- gboolean gbool;
- char *buf;
+ gboolean gbool;
+ char *buf;
- if ((buf = (char *)xmlGetProp (node, (xmlChar *)name))) {
- gbool = (!strcmp (buf, "true") || !strcmp (buf, "yes"));
- xmlFree (buf);
+ if ((buf = (char *)xmlGetProp (node, (xmlChar *)name))) {
+ gbool = (!strcmp (buf, "true") || !strcmp (buf, "yes"));
+ xmlFree (buf);
- if (gbool != *val) {
- *val = gbool;
- return TRUE;
- }
- }
+ if (gbool != *val) {
+ *val = gbool;
+ return TRUE;
+ }
+ }
- return FALSE;
+ return FALSE;
}
gboolean
feed_new_from_xml(char *xml)
{
xmlNodePtr node;
- xmlDocPtr doc = NULL;
+ xmlDocPtr doc = NULL;
char *uid = NULL;
char *name = NULL;
char *url = NULL;
@@ -1040,7 +1040,7 @@ feed_new_from_xml(char *xml)
if (!strcmp ((char *)node->name, "url")) {
xml_set_content (node, &url);
}
- if (!strcmp ((char *)node->name, "type")) {
+ if (!strcmp ((char *)node->name, "type")) {
xml_set_content (node, &type);
}
if (!strcmp ((char *)node->name, "delete")) {
@@ -1572,12 +1572,12 @@ webkit_click (GtkEntry *entry,
{
GtkWidget *separator, *redo_menuitem;
redo_menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_REDO, NULL);
- gtk_widget_set_sensitive (redo_menuitem, TRUE);
- gtk_widget_show (redo_menuitem);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), redo_menuitem, 1);
+ gtk_widget_set_sensitive (redo_menuitem, TRUE);
+ gtk_widget_show (redo_menuitem);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), redo_menuitem, 1);
separator = gtk_separator_menu_item_new ();
- gtk_widget_show (separator);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), separator, 2);
+ gtk_widget_show (separator);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), separator, 2);
return TRUE;
}
#endif
@@ -1624,23 +1624,25 @@ gecko_click(GtkMozEmbed *mozembed, gpointer dom_event, gpointer user_data)
GtkMenu *menu;
gchar *link = NULL;
#if EVOLUTION_VERSION < 22900
- EMPopup *emp = NULL;
- GSList *menus = NULL;
+ EMPopup *emp = NULL;
+ GSList *menus = NULL;
gint i=0, menu_size;
#endif
if (-1 == (button = gecko_get_mouse_event_button (dom_event))) {
- g_warning ("Cannot determine mouse button!\n");
- return FALSE;
- }
+ g_warning ("Cannot determine mouse button!\n");
+ return FALSE;
+ }
link = gtk_moz_embed_get_link_message((GtkMozEmbed *)rf->mozembed);
#if EVOLUTION_VERSION >= 22900
- menu = e_popup_menu_create_with_domain (rss_menu_items,
- 0, (guint32)(strlen(link) ? 3:4),
- link,
- GETTEXT_PACKAGE);
+ menu = e_popup_menu_create_with_domain (
+ rss_menu_items,
+ 0,
+ (guint32)(strlen(link) ? 3:4),
+ link,
+ GETTEXT_PACKAGE);
if (button == 2)
gtk_menu_popup (
GTK_MENU (menu),
@@ -1657,8 +1659,8 @@ gecko_click(GtkMozEmbed *mozembed, gpointer dom_event, gpointer user_data)
for (; i<menu_size; i++)
menus = g_slist_prepend(menus, &rss_menu_items[i]);
- e_popup_add_items((EPopup *)emp, menus, NULL, rss_menu_items_free, link);
- menu = e_popup_create_menu_once((EPopup *)emp, NULL, 0);
+ e_popup_add_items((EPopup *)emp, menus, NULL, rss_menu_items_free, link);
+ menu = e_popup_create_menu_once((EPopup *)emp, NULL, 0);
if (button == 2)
gtk_menu_popup(menu, NULL, NULL, NULL, NULL, button, gtk_get_current_event_time());
@@ -1690,7 +1692,7 @@ org_gnome_rss_browser (EMFormatHTML *efh, void *eb, EMFormatHTMLPObject *pobject
guint engine = fallback_engine();
moz = gtk_scrolled_window_new(NULL,NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(moz),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
#ifdef HAVE_WEBKIT
if (engine == 1) {
@@ -1759,7 +1761,7 @@ org_gnome_rss_browser (EMFormatHTML *efh, void *eb, EMFormatHTMLPObject *pobject
if (engine == 2)
gtk_widget_show_all(moz);
- gtk_container_add ((GtkContainer *) eb, moz);
+ gtk_container_add ((GtkContainer *) eb, moz);
/// gtk_container_check_resize ((GtkContainer *) eb);
// gtk_widget_set_size_request((GtkWidget *)rf->mozembed, 330, 330);
// gtk_container_add ((GtkContainer *) eb, rf->mozembed);
@@ -1776,7 +1778,7 @@ org_gnome_rss_browser (EMFormatHTML *efh, void *eb, EMFormatHTMLPObject *pobject
static gboolean
org_gnome_rss_rfrcomm (EMFormatHTML *efh, void *eb, EMFormatHTMLPObject *pobject)
{
- struct _org_gnome_rss_controls_pobject *po =
+ struct _org_gnome_rss_controls_pobject *po =
(struct _org_gnome_rss_controls_pobject *) pobject;
GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
GtkWidget *button;
@@ -3999,8 +4001,8 @@ check_feed_folder(gchar *folder_name)
} while (NULL != path[++i]);
g_strfreev(path);
}
- mail_folder = camel_store_get_folder (store, real_name, 0, NULL);
- }
+ mail_folder = camel_store_get_folder (store, real_name, 0, NULL);
+ }
g_free(real_name);
return mail_folder;
@@ -4009,9 +4011,9 @@ check_feed_folder(gchar *folder_name)
void
rss_delete_feed(gchar *full_path, gboolean folder)
{
- CamelException ex;
+ CamelException ex;
gchar *tmp, *tkey, *url;
- CamelStore *store;
+ CamelStore *store;
gchar *name, *real_name, *buf, *feed_dir, *feed_name;
store = rss_component_peek_local_store();
@@ -4022,7 +4024,7 @@ rss_delete_feed(gchar *full_path, gboolean folder)
real_name = g_hash_table_lookup(rf->feed_folders, name);
if (!real_name)
real_name = name;
- camel_exception_init (&ex);
+ camel_exception_init (&ex);
rss_delete_folders (store, full_path, &ex);
if (camel_exception_is_set (&ex)) {
#if EVOLUTION_VERSION < 22904
@@ -4035,33 +4037,33 @@ rss_delete_feed(gchar *full_path, gboolean folder)
#endif
camel_exception_clear (&ex);
}
- //also remove status file
- tkey = g_hash_table_lookup(rf->hrname, real_name);
+ //also remove status file
+ tkey = g_hash_table_lookup(rf->hrname, real_name);
if (!tkey)
return;
- url = g_hash_table_lookup(rf->hr, tkey);
+ url = g_hash_table_lookup(rf->hr, tkey);
if (!url)
goto out;
- buf = gen_md5(url);
+ buf = gen_md5(url);
feed_dir = rss_component_peek_base_directory();
- feed_name = g_strdup_printf("%s/%s", feed_dir, buf);
- g_free(feed_dir);
- g_free(buf);
- unlink(feed_name);
+ feed_name = g_strdup_printf("%s/%s", feed_dir, buf);
+ g_free(feed_dir);
+ g_free(buf);
+ unlink(feed_name);
tmp = g_strdup_printf("%s.img", feed_name);
- unlink(tmp);
+ unlink(tmp);
g_free(tmp);
tmp = g_strdup_printf("%s.fav", feed_name);
- unlink(tmp);
+ unlink(tmp);
g_free(tmp);
out: if (folder) {
d("print folder:%s\n", real_name);
remove_feed_hash(real_name);
}
- delete_feed_folder_alloc(name);
+ delete_feed_folder_alloc(name);
g_free(name);
g_idle_add((GSourceFunc)store_redraw, GTK_TREE_VIEW(rf->treeview));
- save_gconf_feed();
+ save_gconf_feed();
}
static void
@@ -5036,7 +5038,7 @@ create_mail(create_feed *CF)
/* no point in filtering mails at import time as it just
* wastes time, user can setup his own afterwards
*/
- if (appended_uid != NULL && !rf->import) {
+ if (appended_uid != NULL && !rf->import && !CF->encl) { //do not filter enclosure at this time
filter_uids = g_ptr_array_sized_new(1);
g_ptr_array_add(filter_uids, appended_uid);
mail_filter_on_demand (mail_folder, filter_uids);
@@ -5143,6 +5145,7 @@ free_cf(create_feed *CF)
g_free(CF->website);
g_free(CF->feedid);
g_free(CF->encl);
+ g_free(CF->enclurl);
g_free(CF->feed_fname);
g_free(CF->feed_uri);
if (CF->comments)
@@ -5154,27 +5157,47 @@ free_cf(create_feed *CF)
g_free(CF);
}
+extern guint net_queue_run_count;
+extern guint net_qid;
+
void
#if LIBSOUP_VERSION < 2003000
-finish_enclosure (SoupMessage *msg, create_feed *user_data)
+finish_enclosure (SoupMessage *msg,
+ create_feed *user_data)
#else
-finish_enclosure (SoupSession *soup_sess, SoupMessage *msg, create_feed *user_data)
+finish_enclosure (SoupSession *soup_sess,
+ SoupMessage *msg,
+ create_feed *user_data)
#endif
{
#if LIBSOUP_VERSION < 2003000
- fwrite(msg->response.body, msg->response.length, 1, user_data->efile);
+ fwrite(msg->response.body,
+ msg->response.length,
+ 1,
+ user_data->efile);
#else
- fwrite(msg->response_body->data, msg->response_body->length, 1, user_data->efile);
+ fwrite(msg->response_body->data,
+ msg->response_body->length,
+ 1,
+ user_data->efile);
#endif
fclose(user_data->efile);
if (!feed_is_new(user_data->feed_fname, user_data->feed_uri)) {
create_mail(user_data);
- write_feed_status_line(user_data->feed_fname, user_data->feed_uri);
+ write_feed_status_line(
+ user_data->feed_fname,
+ user_data->feed_uri);
}
+ rf->enclist = g_list_remove(rf->enclist, user_data->enclurl);
free_cf(user_data);
//g_free(msg->response_body->data);
//g_object_unref(msg);
+ if (net_queue_run_count) net_queue_run_count--;
+ if (!net_qid)
+ net_qid = g_idle_add(
+ (GSourceFunc)net_queue_dispatcher,
+ NULL);
}
static void
diff --git a/src/rss.h b/src/rss.h
index 94d8151..f2054c7 100644
--- a/src/rss.h
+++ b/src/rss.h
@@ -1,5 +1,5 @@
/* Evoution RSS Reader Plugin
- * Copyright (C) 2007-2009 Lucian Langa <cooly gnome eu org>
+ * Copyright (C) 2007-2010 Lucian Langa <cooly gnome eu org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -65,14 +65,14 @@
#define HTTP_CACHE_PATH "http"
typedef struct _RDF {
- char *uri;
- char *html;
- xmlDocPtr cache;
- gboolean shown;
- gchar *type; //char type
- guint type_id; //num type
+ char *uri;
+ char *html;
+ xmlDocPtr cache;
+ gboolean shown;
+ gchar *type; //char type
+ guint type_id; //num type
gchar *version; //feed version
- gchar *feedid; //md5 string id of feed
+ gchar *feedid; //md5 string id of feed
gchar *title; //title of the feed
gchar *prefix; //directory path
gchar *maindate; //channel date
@@ -81,8 +81,8 @@ typedef struct _RDF {
GtkWidget *progress;
guint total; //total articles
guint ttl; //feed specified refresh interval
- /* Soup stuff */
- SoupMessage *message;
+ /* Soup stuff */
+ SoupMessage *message;
guint error; //invalid feed
char *strerror; //error msg
GArray *uids;
@@ -108,56 +108,56 @@ typedef struct _hrfeed {
} hrfeed;
typedef struct _rssfeed {
- GHashTable *hrname; //bind feed name to key
- GHashTable *hrname_r; //and mirrored structure for faster lookups
- GHashTable *hrcrc; //crc32 to key binding
- GHashTable *hr; //feeds hash
- GHashTable *hn; //feeds hash
- GHashTable *hre; //enabled feeds hash
- GHashTable *hrt; //feeds name hash
- GHashTable *hrh; //fetch html flag
- GHashTable *hruser; //auth user hash
- GHashTable *hrpass; //auth pass hash
+ GHashTable *hrname; //bind feed name to key
+ GHashTable *hrname_r; //and mirrored structure for faster lookups
+ GHashTable *hrcrc; //crc32 to key binding
+ GHashTable *hr; //feeds hash
+ GHashTable *hn; //feeds hash
+ GHashTable *hre; //enabled feeds hash
+ GHashTable *hrt; //feeds name hash
+ GHashTable *hrh; //fetch html flag
+ GHashTable *hruser; //auth user hash
+ GHashTable *hrpass; //auth pass hash
gboolean soup_auth_retry; //wether to retry auth after an unsucessful auth
- GHashTable *hrdel_feed; //option to delete messages in current feed
- GHashTable *hrdel_days; //option to delete messages older then days
- GHashTable *hrdel_messages; //option to keep last messages
- GHashTable *hrdel_unread; //option to delete unread messages too
- GHashTable *hrttl;
- GHashTable *hrttl_multiply;
- GHashTable *hrupdate; //feeds update method
- GtkWidget *feed_dialog;
- GtkWidget *progress_dialog;
- GtkWidget *progress_bar;
- GtkWidget *label;
- GtkWidget *sr_feed; //s&r upper text (feed)
- GtkWidget *treeview;
- GtkWidget *edbutton;
+ GHashTable *hrdel_feed; //option to delete messages in current feed
+ GHashTable *hrdel_days; //option to delete messages older then days
+ GHashTable *hrdel_messages; //option to keep last messages
+ GHashTable *hrdel_unread; //option to delete unread messages too
+ GHashTable *hrttl;
+ GHashTable *hrttl_multiply;
+ GHashTable *hrupdate; //feeds update method
+ GtkWidget *feed_dialog;
+ GtkWidget *progress_dialog;
+ GtkWidget *progress_bar;
+ GtkWidget *label;
+ GtkWidget *sr_feed; //s&r upper text (feed)
+ GtkWidget *treeview;
+ GtkWidget *edbutton;
GtkWidget *errdialog;
GtkWidget *preferences;
gchar *err; //if using soup _unblocking error goes here
gchar *err_feed; //name of the feed that caused above err
- gchar *cfeed; //current feed name
+ gchar *cfeed; //current feed name
gboolean online; //networkmanager dependant
gboolean fe; //feed enabled (at least one)
#ifdef EVOLUTION_2_12
EMEventTargetSendReceive *t;
#else
- EMPopupTargetSelect *t;
+ EMPopupTargetSelect *t;
#endif
- gboolean setup;
- gboolean pending;
- gboolean import; //import going on
+ gboolean setup;
+ gboolean pending;
+ gboolean import; //import going on
gboolean autoupdate; //feed is currently auto fetched
guint feed_queue;
- gboolean cancel; //cancelation signal
- gboolean cancel_all; //cancelation signal
- GHashTable *session; //queue of active unblocking sessions
- GHashTable *abort_session; //this is a hack to be able to iterate when
+ gboolean cancel; //cancelation signal
+ gboolean cancel_all; //cancelation signal
+ GHashTable *session; //queue of active unblocking sessions
+ GHashTable *abort_session; //this is a hack to be able to iterate when
//we remove keys from seesion with weak_ref
- GHashTable *key_session; //queue of active unblocking sessions and keys linked
- SoupSession *b_session; //active blocking session
- SoupMessage *b_msg_session; //message running in the blocking session
+ GHashTable *key_session; //queue of active unblocking sessions and keys linked
+ SoupSession *b_session; //active blocking session
+ SoupMessage *b_msg_session; //message running in the blocking session
guint rc_id;
struct _send_info *info; //s&r data
struct userpass *un;
@@ -173,6 +173,8 @@ typedef struct _rssfeed {
GHashTable *error_hash;
guint test;
char *current_uid; // currently read article
+ GQueue *stqueue; // network downloads tracking
+ GList *enclist; // network downloads tracking
#if HAVE_DBUS
DBusConnection *bus; // DBUS
#endif
@@ -230,51 +232,51 @@ typedef struct USERPASS {
} userpass;
struct _send_data {
- GList *infos;
+ GList *infos;
- GtkDialog *gd;
- int cancelled;
+ GtkDialog *gd;
+ int cancelled;
- CamelFolder *inbox; /* since we're never asked to update this one, do it ourselves */
- time_t inbox_update;
+ CamelFolder *inbox; /* since we're never asked to update this one, do it ourselves */
+ time_t inbox_update;
- GMutex *lock;
- GHashTable *folders;
+ GMutex *lock;
+ GHashTable *folders;
- GHashTable *active; /* send_info's by uri */
+ GHashTable *active; /* send_info's by uri */
};
typedef enum {
- SEND_RECEIVE, /* receiver */
- SEND_SEND, /* sender */
- SEND_UPDATE, /* imap-like 'just update folder info' */
- SEND_INVALID
+ SEND_RECEIVE, /* receiver */
+ SEND_SEND, /* sender */
+ SEND_UPDATE, /* imap-like 'just update folder info' */
+ SEND_INVALID
} send_info_t ;
typedef enum {
- SEND_ACTIVE,
- SEND_CANCELLED,
- SEND_COMPLETE
+ SEND_ACTIVE,
+ SEND_CANCELLED,
+ SEND_COMPLETE
} send_state_t;
struct _send_info {
- send_info_t type; /* 0 = fetch, 1 = send */
- CamelOperation *cancel;
- char *uri;
- int keep;
- send_state_t state;
- GtkWidget *progress_bar;
- GtkWidget *cancel_button;
- GtkWidget *status_label;
-
- int again; /* need to run send again */
-
- int timeout_id;
- char *what;
- int pc;
-
- /*time_t update;*/
- struct _send_data *data;
+ send_info_t type; /* 0 = fetch, 1 = send */
+ CamelOperation *cancel;
+ char *uri;
+ int keep;
+ send_state_t state;
+ GtkWidget *progress_bar;
+ GtkWidget *cancel_button;
+ GtkWidget *status_label;
+
+ int again; /* need to run send again */
+
+ int timeout_id;
+ char *what;
+ int pc;
+
+ /*time_t update;*/
+ struct _send_data *data;
};
typedef struct CREATE_FEED { /* used by create_mail function when called by unblocking fetch */
@@ -291,6 +293,7 @@ typedef struct CREATE_FEED { /* used by create_mail function when called by unbl
gchar *feed_fname; // feed name file
gchar *feed_uri;
gchar *encl;
+ gchar *enclurl;
FILE *efile; //enclosure file
gchar *comments;
GList *category; // list of categories article is posted under
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]