talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 24a7d15ed475beb0483874974739f3b1163542cb
parent 803450e8a64324eb0767fe69411a2518426f3e8d
Author: wwp <subscript@free.fr>
Date:   Fri, 21 Mar 2025 11:15:09 +0100

RSSyl plugin: change the default User Agent used to retrieve feeds to ClawsMailRSSyl/$VERSION ($URL),
allow users to make use of a custom User Agent (in preferences) to override the default one,
allow users to override the User Agent on a per-feed basis as well.

Diffstat:
Msrc/plugins/rssyl/libfeed/feed.c | 19++++++++++---------
Msrc/plugins/rssyl/libfeed/feed.h | 4++--
Msrc/plugins/rssyl/rssyl.c | 24+++++++++++++++++++++++-
Msrc/plugins/rssyl/rssyl.h | 6+++++-
Msrc/plugins/rssyl/rssyl_feed.h | 4++--
Msrc/plugins/rssyl/rssyl_feed_props.c | 59++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/plugins/rssyl/rssyl_feed_props.h | 4+++-
Msrc/plugins/rssyl/rssyl_prefs.c | 70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Msrc/plugins/rssyl/rssyl_prefs.h | 15++++-----------
Msrc/plugins/rssyl/rssyl_update_comments.c | 5++++-
Msrc/plugins/rssyl/rssyl_update_feed.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++----
11 files changed, 230 insertions(+), 38 deletions(-)

diff --git a/src/plugins/rssyl/libfeed/feed.c b/src/plugins/rssyl/libfeed/feed.c @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2006-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2006-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -24,6 +24,7 @@ #include <expat.h> #include "feed.h" +#include "../rssyl_prefs.h" #include "parser.h" /* feed_new() @@ -68,13 +69,13 @@ static void _free_auth(Feed *feed) return; if (feed->auth != NULL) { - if (feed->auth->username != NULL) - g_free(feed->auth->username); - if (feed->auth->password != NULL) - g_free(feed->auth->password); - g_free(feed->auth); + if (feed->auth->username != NULL) + g_free(feed->auth->username); + if (feed->auth->password != NULL) + g_free(feed->auth->password); + g_free(feed->auth); feed->auth = NULL; - } + } } void feed_free(Feed *feed) @@ -245,7 +246,7 @@ FeedItem *feed_nth_item(Feed *feed, guint n) * Takes initialized feed with url set, fetches the feed from this url, * updates rest of Feed struct members and returns HTTP response code * we got from url's server. */ -guint feed_update(Feed *feed, time_t last_update) +guint feed_update(Feed *feed, time_t last_update, const gchar *user_agent) { CURL *eh = NULL; CURLcode res; @@ -291,7 +292,7 @@ guint feed_update(Feed *feed, time_t last_update) curl_easy_setopt(eh, CURLOPT_TIMEOUT, feed->timeout); curl_easy_setopt(eh, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(eh, CURLOPT_ENCODING, ""); - curl_easy_setopt(eh, CURLOPT_USERAGENT, "libfeed 0.1"); + curl_easy_setopt(eh, CURLOPT_USERAGENT, user_agent); curl_easy_setopt(eh, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); /* Use HTTP's If-Modified-Since feature, if application provided diff --git a/src/plugins/rssyl/libfeed/feed.h b/src/plugins/rssyl/libfeed/feed.h @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2006-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2006-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -129,7 +129,7 @@ gboolean feed_prepend_item(Feed *feed, FeedItem *item); gboolean feed_append_item(Feed *feed, FeedItem *item); gboolean feed_insert_item(Feed *feed, FeedItem *item, gint pos); -guint feed_update(Feed *feed, time_t last_update); +guint feed_update(Feed *feed, time_t last_update, const gchar *user_agent); #define FILL(n) do { g_free(n); n = g_strdup(text); } while(0); diff --git a/src/plugins/rssyl/rssyl.c b/src/plugins/rssyl/rssyl.c @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2005-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2005-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -324,6 +324,13 @@ static void rssyl_item_set_xml(Folder *folder, FolderItem *item, XMLTag *tag) /* (bool) Verify SSL peer */ if( !strcmp(attr->name, "ssl_verify_peer")) ritem->ssl_verify_peer = (atoi(attr->value) == 0 ? FALSE : TRUE ); + /* User Agent */ + if( !strcmp(attr->name, "use_default_user_agent")) + ritem->use_default_user_agent = (atoi(attr->value) == 0 ? FALSE : TRUE ); + if( !strcmp(attr->name, "specific_user_agent")) { + g_free(ritem->specific_user_agent); + ritem->specific_user_agent = g_strdup(attr->value); + } } } @@ -378,6 +385,11 @@ static XMLTag *rssyl_item_get_xml(Folder *folder, FolderItem *item) /* (bool) Verify SSL peer */ xml_tag_add_attr(tag, xml_attr_new("ssl_verify_peer", (ri->ssl_verify_peer ? "1" : "0")) ); + /* User Agent */ + xml_tag_add_attr(tag, xml_attr_new("use_default_user_agent", + (ri->use_default_user_agent ? "1" : "0")) ); + if( ri->specific_user_agent != NULL ) + xml_tag_add_attr(tag, xml_attr_new("specific_user_agent", ri->specific_user_agent)); return tag; } @@ -444,6 +456,8 @@ static FolderItem *rssyl_item_new(Folder *folder) ritem->ssl_verify_peer = TRUE; ritem->feedprop = NULL; ritem->refresh_id = 0; + ritem->use_default_user_agent = 1; + ritem->specific_user_agent = NULL; return (FolderItem *)ritem; } @@ -462,6 +476,7 @@ static void rssyl_item_destroy(Folder *folder, FolderItem *item) g_free(ritem->auth); g_free(ritem->official_title); g_slist_free(ritem->items); + g_free(ritem->specific_user_agent); /* Remove a scheduled refresh, if any */ if( ritem->refresh_id != 0) @@ -980,6 +995,13 @@ static void rssyl_copy_private_data(Folder *folder, FolderItem *oldi, newitem->fetching_comments = olditem->fetching_comments; newitem->last_update = olditem->last_update; + /* User Agent */ + newitem->use_default_user_agent = olditem->use_default_user_agent; + if (olditem->specific_user_agent != NULL) { + g_free(newitem->specific_user_agent); + newitem->specific_user_agent = g_strdup(olditem->specific_user_agent); + } + pathold = rssyl_item_get_path(oldi->folder, oldi); dpathold = g_strconcat(pathold, G_DIR_SEPARATOR_S, RSSYL_DELETED_FILE, NULL); pathnew = rssyl_item_get_path(newi->folder, newi); diff --git a/src/plugins/rssyl/rssyl.h b/src/plugins/rssyl/rssyl.h @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2005-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2005-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -67,6 +67,9 @@ struct _RFolderItem { gboolean fetching_comments; time_t last_update; + gboolean use_default_user_agent; + gchar *specific_user_agent; + struct _RFeedProp *feedprop; GSList *items; @@ -88,6 +91,7 @@ struct _RFetchCtx { gchar *error; gboolean success; gboolean ready; + RFolderItem *ritem; }; typedef struct _RFetchCtx RFetchCtx; diff --git a/src/plugins/rssyl/rssyl_feed.h b/src/plugins/rssyl/rssyl_feed.h @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2005-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2005-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -27,7 +27,7 @@ #define RSSYL_LOG_SUBSCRIBING _("RSSyl: Subscribing new feed: %s\n") #define RSSYL_LOG_SUBSCRIBED _("RSSyl: New feed subscribed: '%s' (%s)\n") -#define RSSYL_LOG_UPDATING _("RSSyl: Updating feed: %s\n") +#define RSSYL_LOG_UPDATING _("RSSyl: Updating feed: %s (User Agent: %s)\n") #define RSSYL_LOG_UPDATED _("RSSyl: Feed update finished: %s\n") #define RSSYL_LOG_ERROR_FETCH _("RSSyl: Error fetching feed at '%s': %s\n") #define RSSYL_LOG_ERROR_NOFEED _("RSSyl: No valid feed found at '%s'\n") diff --git a/src/plugins/rssyl/rssyl_feed_props.c b/src/plugins/rssyl/rssyl_feed_props.c @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2005-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2005-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -40,9 +40,9 @@ static void rssyl_gtk_prop_store(RFolderItem *ritem) { - gchar *url, *auth_user, *auth_pass; + gchar *url, *auth_user, *auth_pass, *specific_user_agent; gint x, old_ri, old_fetch_comments; - gboolean use_default_ri = FALSE, keep_old = FALSE; + gboolean use_default_ri = FALSE, keep_old = FALSE, use_default_user_agent = TRUE; FolderItem *item; g_return_if_fail(ritem != NULL); @@ -125,6 +125,21 @@ static void rssyl_gtk_prop_store(RFolderItem *ritem) ritem->ssl_verify_peer = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(ritem->feedprop->ssl_verify_peer)); + /* User Agent */ + use_default_user_agent = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(ritem->feedprop->use_default_user_agent)); + ritem->use_default_user_agent = use_default_user_agent; + debug_print("store: use default user agent is %s\n", + ( use_default_user_agent ? "ON" : "OFF" ) ); + + specific_user_agent = (gchar *)gtk_entry_get_text(GTK_ENTRY(ritem->feedprop->specific_user_agent)); + if (specific_user_agent != NULL) { + if (ritem->specific_user_agent) { + g_free(ritem->specific_user_agent); + } + ritem->specific_user_agent = g_strdup(specific_user_agent); + } + /* Store updated properties */ item = &ritem->item; item->folder->klass->item_get_xml(item->folder, item); @@ -143,6 +158,9 @@ rssyl_feedprop_togglebutton_toggled_cb(GtkToggleButton *tb, sb = feedprop->refresh_interval; } else if( (GtkWidget *)tb == feedprop->fetch_comments ) { sb = feedprop->fetch_comments_max_age; + } else if((GtkWidget *)tb == feedprop->use_default_user_agent ) { + active = !active; + sb = feedprop->specific_user_agent; } g_return_val_if_fail(sb != NULL, FALSE); @@ -356,6 +374,17 @@ void rssyl_gtk_prop(RFolderItem *ritem) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(feedprop->ssl_verify_peer), ritem->ssl_verify_peer); + /* User Agent */ + feedprop->use_default_user_agent = gtk_check_button_new_with_mnemonic( + _("Use default User Agent")); + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(feedprop->use_default_user_agent), + ritem->use_default_user_agent); + + feedprop->specific_user_agent = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(feedprop->specific_user_agent), + (ritem->specific_user_agent != NULL ? ritem->specific_user_agent : "")); + /* === Now pack all the widgets */ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); gtk_container_add(GTK_CONTAINER(feedprop->window), vbox); @@ -467,6 +496,30 @@ void rssyl_gtk_prop(RFolderItem *ritem) gtk_container_set_border_width(GTK_CONTAINER(inner_vbox), 7); gtk_container_add(GTK_CONTAINER(frame), inner_vbox); + inner_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 7); + /* Use default User Agent - checkbutton */ + gtk_box_pack_start(GTK_BOX(inner_vbox), feedprop->use_default_user_agent, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(feedprop->use_default_user_agent), "toggled", + G_CALLBACK(rssyl_feedprop_togglebutton_toggled_cb), + (gpointer)feedprop); + + /* User Agent - label */ + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 7); + label = gtk_label_new(_("User Agent")); + gtk_widget_set_tooltip_text(feedprop->use_default_user_agent, + _("Disable this to use a User Agent specific to this feed")); + gtk_widget_set_tooltip_text(feedprop->specific_user_agent, + _("Specific User Agent to use for this feed. If empty, the User Agent string set in 'Preferences/Plugins/RSSyl' will be used")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), feedprop->specific_user_agent, FALSE, FALSE, 0); + gtk_widget_set_sensitive(feedprop->specific_user_agent, + !ritem->use_default_user_agent); + gtk_box_pack_start(GTK_BOX(hbox), feedprop->use_default_user_agent, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(inner_vbox), hbox, FALSE, FALSE, 0); + PACK_FRAME (vbox, frame, _("User Agent")); + gtk_container_set_border_width(GTK_CONTAINER(inner_vbox), 7); + gtk_container_add(GTK_CONTAINER(frame), inner_vbox); + /* Buttonbox */ bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); diff --git a/src/plugins/rssyl/rssyl_feed_props.h b/src/plugins/rssyl/rssyl_feed_props.h @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2005-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2005-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -38,6 +38,8 @@ struct _RFeedProp { GtkWidget *auth_type; GtkWidget *auth_username; GtkWidget *auth_password; + GtkWidget *use_default_user_agent; + GtkWidget *specific_user_agent; }; typedef struct _RFeedProp RFeedProp; diff --git a/src/plugins/rssyl/rssyl_prefs.c b/src/plugins/rssyl/rssyl_prefs.c @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2005-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2005-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -35,7 +35,6 @@ #include "rssyl_prefs.h" #include "rssyl_feed.h" -static RPrefsPage rssyl_gtk_prefs_page; RPrefs rssyl_prefs; static void destroy_rssyl_prefs_page(PrefsPage *page); @@ -55,9 +54,28 @@ static PrefParam param[] = { P_STRING, NULL, NULL, NULL }, { "ssl_verify_peer", "TRUE", &rssyl_prefs.ssl_verify_peer, P_BOOL, NULL, NULL, NULL }, + { "use_custom_user_agent", "FALSE", &rssyl_prefs.use_custom_user_agent, + P_BOOL, NULL, NULL, NULL }, + { "custom_user_agent", "", &rssyl_prefs.custom_user_agent, + P_STRING, NULL, NULL, NULL }, { 0, 0, 0, 0, 0, 0, 0 } }; +static struct _RPrefsPage { + PrefsPage page; + GtkWidget *refresh_enabled; + GtkWidget *refresh; + GtkWidget *refresh_on_startup; + GtkWidget *cookies_path; + GtkWidget *ssl_verify_peer; + GtkWidget *use_custom_user_agent; + GtkWidget *custom_user_agent; +}; + +typedef struct _RPrefsPage RPrefsPage; + +static RPrefsPage rssyl_gtk_prefs_page; + void rssyl_prefs_init(void) { static gchar *path[3]; @@ -96,6 +114,16 @@ rssyl_refresh_enabled_toggled_cb(GtkToggleButton *tb, gpointer data) return FALSE; } +/* Toggle the custom user agent entry sensitivity after the + * checkbutton was toggled. */ +static gboolean +rssyl_use_custom_user_agent_toggled_cb(GtkToggleButton *tb, gpointer data) +{ + gtk_widget_set_sensitive(GTK_WIDGET(data), + gtk_toggle_button_get_active(tb)); + return FALSE; +} + /* Open a file select dialog and set file path to cookies entry */ static void rssyl_prefs_cookies_browse_cb(GtkWidget* widget, gpointer data) @@ -120,7 +148,7 @@ static void create_rssyl_prefs_page(PrefsPage *page, GtkWindow *window, gpointer data) { RPrefsPage *prefs_page = (RPrefsPage *) page; - GtkWidget *vbox, *vbox1, *vbox2; + GtkWidget *vbox, *vbox1, *vbox2, *vbox3; GtkWidget *frame; GtkWidget *refresh, *refresh_enabled, *refresh_hbox; GtkWidget *label; @@ -128,6 +156,7 @@ static void create_rssyl_prefs_page(PrefsPage *page, GtkAdjustment *refresh_adj; GtkWidget *cookies_path, *cookies_btn, *cookies_hbox; GtkWidget *ssl_verify_peer; + GtkWidget *use_custom_user_agent, *custom_user_agent, *user_agent_hbox; vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); @@ -185,6 +214,29 @@ static void create_rssyl_prefs_page(PrefsPage *page, G_CALLBACK(rssyl_prefs_cookies_browse_cb), cookies_path); gtk_box_pack_start(GTK_BOX(vbox2), cookies_hbox, FALSE, FALSE, 0); + vbox3 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); + + user_agent_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start(GTK_BOX(user_agent_hbox), label, FALSE, FALSE, 0); + + use_custom_user_agent = gtk_check_button_new_with_label( + _("Use a custom User Agent")); + gtk_widget_set_tooltip_text(use_custom_user_agent, + _("Instead of using the default User Agent for feed retrieval, you can enter a custom value")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_custom_user_agent), + rssyl_prefs.use_custom_user_agent); + gtk_box_pack_start(GTK_BOX(user_agent_hbox), use_custom_user_agent, FALSE, FALSE, 0); + + custom_user_agent = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(custom_user_agent), rssyl_prefs.custom_user_agent); + gtk_box_pack_start(GTK_BOX(user_agent_hbox), custom_user_agent, TRUE, TRUE, 0); + gtk_widget_set_tooltip_text(custom_user_agent, + _("Custom User Agent to use for feed retrieval. If empty, the default User Agent string will be used")); + + g_signal_connect(G_OBJECT(use_custom_user_agent), "toggled", + G_CALLBACK(rssyl_use_custom_user_agent_toggled_cb), custom_user_agent); + gtk_box_pack_start(GTK_BOX(vbox3), user_agent_hbox, FALSE, FALSE, 0); + vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); @@ -196,6 +248,12 @@ static void create_rssyl_prefs_page(PrefsPage *page, gtk_container_set_border_width(GTK_CONTAINER(vbox2), 6); gtk_container_add(GTK_CONTAINER(frame), vbox2); + PACK_FRAME (vbox, frame, _("User Agent")); + gtk_container_set_border_width(GTK_CONTAINER(vbox3), 6); + gtk_container_add(GTK_CONTAINER(frame), vbox3); + + SET_TOGGLE_SENSITIVITY(use_custom_user_agent, custom_user_agent); + gtk_widget_show_all(vbox); /* Store pointers to relevant widgets */ @@ -205,6 +263,8 @@ static void create_rssyl_prefs_page(PrefsPage *page, prefs_page->refresh_on_startup = refresh_on_startup; prefs_page->cookies_path = cookies_path; prefs_page->ssl_verify_peer = ssl_verify_peer; + prefs_page->use_custom_user_agent = use_custom_user_agent; + prefs_page->custom_user_agent = custom_user_agent; } static void destroy_rssyl_prefs_page(PrefsPage *page) @@ -231,6 +291,10 @@ static void save_rssyl_prefs(PrefsPage *page) GTK_ENTRY(prefs_page->cookies_path))); rssyl_prefs.ssl_verify_peer = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(prefs_page->ssl_verify_peer)); + rssyl_prefs.use_custom_user_agent = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(prefs_page->use_custom_user_agent)); + rssyl_prefs.custom_user_agent = g_strdup(gtk_entry_get_text( + GTK_ENTRY(prefs_page->custom_user_agent))); /* Store prefs in rc file */ pref_file = prefs_write_open(rc_file_path); diff --git a/src/plugins/rssyl/rssyl_prefs.h b/src/plugins/rssyl/rssyl_prefs.h @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2005-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2005-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -31,18 +31,11 @@ struct _RPrefs { gboolean refresh_on_startup; gchar *cookies_path; gboolean ssl_verify_peer; + gboolean use_custom_user_agent; + gchar *custom_user_agent; }; -typedef struct _RPrefsPage RPrefsPage; - -struct _RPrefsPage { - PrefsPage page; - GtkWidget *refresh_enabled; - GtkWidget *refresh; - GtkWidget *refresh_on_startup; - GtkWidget *cookies_path; - GtkWidget *ssl_verify_peer; -}; +extern RPrefs rssyl_prefs; void rssyl_prefs_init(void); void rssyl_prefs_done(void); diff --git a/src/plugins/rssyl/rssyl_update_comments.c b/src/plugins/rssyl/rssyl_update_comments.c @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2006-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2006-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -113,6 +113,9 @@ void rssyl_update_comments(RFolderItem *ritem) fetchctx = rssyl_prep_fetchctx_from_url(feed_item_get_comments_url(fi)); if (fetchctx != NULL) { + /* rssyl_prep_fetchctx_from_url does not initialize fetchctx->ritem, + do it now for later calls to rssyl_get_user_agent() */ + fetchctx->ritem = ritem; feed_set_ssl_verify_peer(fetchctx->feed, ritem->ssl_verify_peer); rssyl_fetch_feed(fetchctx, 0); diff --git a/src/plugins/rssyl/rssyl_update_feed.c b/src/plugins/rssyl/rssyl_update_feed.c @@ -1,6 +1,6 @@ /* * Claws Mail -- a GTK based, lightweight, and fast e-mail client - * Copyright (C) 2006-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> + * Copyright (C) 2006-2025 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk> * * 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 @@ -34,6 +34,7 @@ #include <prefs_common.h> #include <inc.h> #include <main.h> +#include <defs.h> /* Local includes */ #include "libfeed/feed.h" @@ -44,14 +45,59 @@ #include "rssyl_prefs.h" #include "rssyl_update_comments.h" -/* rssyl_fetch_feed_thr() */ +extern const gchar *plugin_version(void); + +/* rssyl_get_user_agent + returns a ptr to a newly allocated string containing either the feed's specific user agent string + (if set and if trimmed string is non-empty), + or the custom user agent string set in global preferences (if prefs tells so and if trimmed string + is not empty), otherwise the default user agent string. + caller has to free the allocated string from pointer after use. +*/ +gchar *rssyl_get_user_agent(RFolderItem *ritem) +{ + gchar *user_agent = NULL; + + /* check if feed properties has a user agent enabled and set */ + /* ritem may be NULL when call comes from an initial fetch from url (when subscribing) */ + if (ritem != NULL && ritem->use_default_user_agent == FALSE) { + gchar *specific = g_strstrip(g_strdup(ritem->specific_user_agent)); + + if (strlen(specific) > 0) + user_agent = specific; + else + debug_print("RSSyl: feed-specific User Agent is empty, trying custom value from global prefs\n"); + } + + /* fallback to user agent value from preferences (if enabled and set) */ + if (user_agent == NULL) { + if (rssyl_prefs.use_custom_user_agent) { + gchar *custom = g_strstrip(g_strdup(rssyl_prefs.custom_user_agent)); + if (strlen(custom) > 0) + user_agent = custom; + else + debug_print("RSSyl: custom User Agent is empty, assuming default value\n"); + } + } + + /* fallback to default User Agent */ + if (user_agent == NULL) + user_agent = g_strdup_printf("ClawsMailRSSyl/%s (%s)", (gchar *)plugin_version(), HOMEPAGE_URI); + + debug_print("RSSyl: User Agent is %s\n", user_agent); + return user_agent; +} + +/* rssyl_fetch_feed_thr() */ static void *rssyl_fetch_feed_thr(void *arg) { RFetchCtx *ctx = (RFetchCtx *)arg; + gchar *user_agent = rssyl_get_user_agent(ctx->ritem); /* Fetch and parse the feed. */ - ctx->response_code = feed_update(ctx->feed, -1); + ctx->response_code = feed_update(ctx->feed, -1, user_agent); + g_free(user_agent); /* Signal main thread that we're done here. */ ctx->ready = TRUE; @@ -169,6 +215,7 @@ RFetchCtx *rssyl_prep_fetchctx_from_item(RFolderItem *ritem) ctx->error = NULL; ctx->success = TRUE; ctx->ready = FALSE; + ctx->ritem = ritem; if (ritem->auth->type != FEED_AUTH_NONE) ritem->auth->password = rssyl_passwd_get(ritem); @@ -198,6 +245,7 @@ RFetchCtx *rssyl_prep_fetchctx_from_url(gchar *url) ctx->error = NULL; ctx->success = TRUE; ctx->ready = FALSE; + ctx->ritem = NULL; feed_set_timeout(ctx->feed, prefs_common_get_prefs()->io_timeout_secs); feed_set_cookies_path(ctx->feed, rssyl_prefs_get()->cookies_path); @@ -220,6 +268,7 @@ gboolean rssyl_update_feed(RFolderItem *ritem, RSSylVerboseFlags verbose) MainWindow *mainwin = mainwindow_get_mainwindow(); gchar *msg = NULL; gboolean success = FALSE; + gchar *user_agent = rssyl_get_user_agent(ritem); g_return_val_if_fail(ritem != NULL, FALSE); g_return_val_if_fail(ritem->url != NULL, FALSE); @@ -227,7 +276,8 @@ gboolean rssyl_update_feed(RFolderItem *ritem, RSSylVerboseFlags verbose) debug_print("RSSyl: starting to update '%s' (%s)\n", ritem->item.name, ritem->url); - log_print(LOG_PROTOCOL, RSSYL_LOG_UPDATING, ritem->url); + log_print(LOG_PROTOCOL, RSSYL_LOG_UPDATING, ritem->url, user_agent); + g_free(user_agent); msg = g_strdup_printf(_("Updating feed '%s'..."), ritem->item.name); STATUSBAR_PUSH(mainwin, msg);