/** * This function tries to find a feed link for a given HTTP URI. It * tries to download it. If it finds a valid feed source it parses * this source instead into the given feed parsing context. It also * replaces the HTTP URI with the found feed source. */ static void feed_parser_auto_discover (feedParserCtxtPtr ctxt) { gchar *source; if (ctxt->feed->parseErrors) g_string_truncate (ctxt->feed->parseErrors, 0); else ctxt->feed->parseErrors = g_string_new(NULL); debug1 (DEBUG_UPDATE, "Starting feed auto discovery (%s)", subscription_get_source (ctxt->subscription)); source = html_auto_discover_feed (ctxt->data, subscription_get_source (ctxt->subscription)); /* FIXME: we only need the !g_str_equal as a workaround after a 404 */ if (source && !g_str_equal (source, subscription_get_source (ctxt->subscription))) { debug1 (DEBUG_UPDATE, "Discovered link: %s", source); ctxt->failed = FALSE; subscription_set_source (ctxt->subscription, source); /* The feed that was processed wasn't the correct one, we need to redownload it. * Cancel the update in case there's one in progress */ subscription_cancel_update (ctxt->subscription); subscription_update (ctxt->subscription, FEED_REQ_RESET_TITLE); g_free (source); } else { debug0 (DEBUG_UPDATE, "No feed link found!"); g_string_append (ctxt->feed->parseErrors, _("The URL you want Liferea to subscribe to points to a webpage and the auto discovery found no feeds on this page. Maybe this webpage just does not support feed auto discovery.")); } }
subscriptionPtr subscription_import (xmlNodePtr xml, gboolean trusted) { subscriptionPtr subscription; xmlChar *source, *homepage, *filter, *intervalStr, *tmp; subscription = subscription_new (NULL, NULL, NULL); source = xmlGetProp (xml, BAD_CAST "xmlUrl"); if (!source) source = xmlGetProp (xml, BAD_CAST "xmlurl"); /* e.g. for AmphetaDesk */ if (source) { if (!trusted && source[0] == '|') { /* FIXME: Display warning dialog asking if the command is safe? */ tmp = g_strdup_printf ("unsafe command: %s", source); xmlFree (source); source = tmp; } subscription_set_source (subscription, source); xmlFree (source); homepage = xmlGetProp (xml, BAD_CAST "htmlUrl"); if (homepage && xmlStrcmp (homepage, "")) subscription_set_homepage (subscription, homepage); xmlFree (homepage); if ((filter = xmlGetProp (xml, BAD_CAST "filtercmd"))) { if (!trusted) { /* FIXME: Display warning dialog asking if the command is safe? */ tmp = g_strdup_printf ("unsafe command: %s", filter); xmlFree (filter); filter = tmp; } subscription_set_filter (subscription, filter); xmlFree (filter); } intervalStr = xmlGetProp (xml, BAD_CAST "updateInterval"); subscription_set_update_interval (subscription, common_parse_long (intervalStr, -1)); xmlFree (intervalStr); /* no proxy flag */ tmp = xmlGetProp (xml, BAD_CAST "dontUseProxy"); if (tmp && !xmlStrcmp (tmp, BAD_CAST "true")) subscription->updateOptions->dontUseProxy = TRUE; xmlFree (tmp); /* authentication options */ subscription->updateOptions->username = xmlGetProp (xml, BAD_CAST "username"); subscription->updateOptions->password = xmlGetProp (xml, BAD_CAST "password"); } return subscription; }
subscriptionPtr subscription_new (const gchar *source, const gchar *filter, updateOptionsPtr options) { subscriptionPtr subscription; subscription = g_new0 (struct subscription, 1); subscription->type = feed_get_subscription_type (); subscription->updateOptions = options; if (!subscription->updateOptions) subscription->updateOptions = g_new0 (struct updateOptions, 1); subscription->updateState = g_new0 (struct updateState, 1); subscription->updateInterval = -1; subscription->defaultInterval = -1; if (source) { gboolean feedPrefix = FALSE; gchar *uri = g_strdup (source); g_strstrip (uri); /* strip confusing whitespaces */ /* strip feed protocol prefix variant 1 */ if (uri == strstr (uri, FEED_PROTOCOL_PREFIX)) { gchar *tmp = uri; uri = g_strdup (uri + strlen (FEED_PROTOCOL_PREFIX)); g_free (tmp); feedPrefix = TRUE; } /* strip feed protocol prefix variant 2 */ if (uri == strstr (uri, FEED_PROTOCOL_PREFIX2)) { gchar *tmp = uri; uri = g_strdup (uri + strlen (FEED_PROTOCOL_PREFIX2)); g_free (tmp); feedPrefix = TRUE; } /* ensure protocol prefix (but only for feed:[//] URIs to avoid breaking local file and command line subscriptions) */ if (feedPrefix && !strstr (uri, "://")) { gchar *tmp = uri; uri = g_strdup_printf ("http://%s", uri); g_free (tmp); } subscription_set_source (subscription, uri); g_free (uri); } if (filter) subscription_set_filter (subscription, filter); return subscription; }
static void on_propdialog_response (GtkDialog *dialog, gint response_id, gpointer user_data) { SubscriptionPropDialog *spd = (SubscriptionPropDialog *)user_data; if(response_id == GTK_RESPONSE_OK) { gchar *newSource; const gchar *newFilter; gboolean needsUpdate = FALSE; subscriptionPtr subscription = spd->priv->subscription; nodePtr node = spd->priv->subscription->node; feedPtr feed = (feedPtr)node->data; if (SUBSCRIPTION_TYPE(subscription) == feed_get_subscription_type ()) { /* "General" */ node_set_title(node, gtk_entry_get_text(GTK_ENTRY(spd->priv->feedNameEntry))); /* Source */ newSource = ui_subscription_dialog_decode_source(spd->priv); /* Filter handling */ newFilter = gtk_entry_get_text(GTK_ENTRY(liferea_dialog_lookup(spd->priv->dialog, "filterEntry"))); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(spd->priv->dialog, "filterCheckbox"))) && strcmp(newFilter,"")) { /* Maybe this should be a test to see if the file exists? */ if(subscription_get_filter(subscription) == NULL || strcmp(newFilter, subscription_get_filter(subscription))) { subscription_set_filter(subscription, newFilter); needsUpdate = TRUE; } } else { if(subscription_get_filter(subscription)) { subscription_set_filter(subscription, NULL); needsUpdate = TRUE; } } /* if URL has changed... */ if(strcmp(newSource, subscription_get_source(subscription))) { subscription_set_source(subscription, newSource); needsUpdate = TRUE; } g_free(newSource); /* Update interval handling */ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "updateIntervalNever")))) subscription_set_update_interval (subscription, -2); else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "updateIntervalDefault")))) subscription_set_update_interval (subscription, -1); else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "updateIntervalSpecific")))) { gint intervalUnit = gtk_combo_box_get_active (GTK_COMBO_BOX (spd->priv->refreshIntervalUnit)); gint updateInterval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spd->priv->refreshInterval)); if (intervalUnit == 1) updateInterval *= 60; /* hours */ if (intervalUnit == 2) updateInterval *= 1440; /* days */ subscription_set_update_interval (subscription, updateInterval); db_subscription_update (subscription); } } /* "Archive" handling */ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheDefault")))) feed->cacheLimit = CACHE_DEFAULT; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheDisable")))) feed->cacheLimit = CACHE_DISABLE; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheUnlimited")))) feed->cacheLimit = CACHE_UNLIMITED; else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "feedCacheLimited")))) feed->cacheLimit = gtk_spin_button_get_value(GTK_SPIN_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "cacheItemLimit"))); if (SUBSCRIPTION_TYPE(subscription) == feed_get_subscription_type ()) { /* "Download" Options */ subscription->updateOptions->dontUseProxy = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(liferea_dialog_lookup(GTK_WIDGET(dialog), "dontUseProxyCheck"))); } /* "Advanced" options */ feed->encAutoDownload = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "enclosureDownloadCheck"))); node->loadItemLink = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "loadItemLinkCheck"))); feed->ignoreComments = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "ignoreCommentFeeds"))); feed->enforcePopup = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "enforcePopupCheck"))); feed->preventPopup = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "preventPopupCheck"))); feed->markAsRead = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (liferea_dialog_lookup (GTK_WIDGET (dialog), "markAsReadCheck"))); if (feed->enforcePopup && feed->preventPopup) feed->enforcePopup = FALSE; ui_node_update (node->id); feedlist_schedule_save (); db_subscription_update (subscription); if (needsUpdate) subscription_update (subscription, FEED_REQ_PRIORITY_HIGH); } g_object_unref(spd); }
static void subscription_process_update_result (const struct updateResult * const result, gpointer user_data, guint32 flags) { subscriptionPtr subscription = (subscriptionPtr)user_data; nodePtr node = subscription->node; gboolean processing = FALSE; GTimeVal now; /* 1. preprocessing */ g_assert (subscription->updateJob); /* update the subscription URL on permanent redirects */ if ((301 == result->httpstatus) && result->source && !g_str_equal (result->source, subscription->updateJob->request->source)) { debug2 (DEBUG_UPDATE, "The URL of \"%s\" has changed permanently and was updated with \"%s\"", node_get_title(node), result->source); subscription_set_source (subscription, result->source); liferea_shell_set_status_bar (_("The URL of \"%s\" has changed permanently and was updated"), node_get_title(node)); } if (401 == result->httpstatus) { /* unauthorized */ auth_dialog_new (subscription, flags); } else if (410 == result->httpstatus) { /* gone */ subscription->discontinued = TRUE; node->available = TRUE; liferea_shell_set_status_bar (_("\"%s\" is discontinued. Liferea won't updated it anymore!"), node_get_title (node)); } else if (304 == result->httpstatus) { node->available = TRUE; liferea_shell_set_status_bar (_("\"%s\" has not changed since last update"), node_get_title(node)); } else { processing = TRUE; } subscription_update_error_status (subscription, result->httpstatus, result->returncode, result->filterErrors); subscription->updateJob = NULL; /* 2. call subscription type specific processing */ if (processing) SUBSCRIPTION_TYPE (subscription)->process_update_result (subscription, result, flags); /* 3. call favicon updating after subscription processing to ensure we have valid baseUrl for feed nodes... */ g_get_current_time (&now); if (favicon_update_needed (subscription->node->id, subscription->updateState, &now)) subscription_update_favicon (subscription); /* 4. generic postprocessing */ update_state_set_lastmodified (subscription->updateState, update_state_get_lastmodified (result->updateState)); update_state_set_cookies (subscription->updateState, update_state_get_cookies (result->updateState)); update_state_set_etag (subscription->updateState, update_state_get_etag (result->updateState)); g_get_current_time (&subscription->updateState->lastPoll); // FIXME: use new-items signal in itemview class itemview_update_node_info (subscription->node); itemview_update (); db_subscription_update (subscription); db_node_update (subscription->node); if (subscription->node->newCount > 0) feedlist_new_items (subscription->node); }