diff options
Diffstat (limited to 'core/src/main')
8 files changed, 99 insertions, 26 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java index c54cc1d5b..00b32de5f 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/FeedItem.java @@ -11,6 +11,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; import de.danoeh.antennapod.core.asynctask.ImageResource; import de.danoeh.antennapod.core.storage.DBReader; @@ -75,7 +76,13 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr private List<Chapter> chapters; private FeedImage image; - private boolean autoDownload = true; + /* + * 0: auto download disabled + * 1: auto download enabled + * > 1: auto download enabled, (approx.) timestamp of the last failed attempt + * where last digit denotes the number of failed attempts + */ + private long autoDownload = 0; /** * Any tags assigned to this item @@ -93,7 +100,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr * */ public FeedItem(long id, String title, String link, Date pubDate, String paymentLink, long feedId, FlattrStatus flattrStatus, boolean hasChapters, FeedImage image, int state, - String itemIdentifier, boolean autoDownload) { + String itemIdentifier, long autoDownload) { this.id = id; this.title = title; this.link = link; @@ -162,7 +169,7 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr FlattrStatus flattrStatus = new FlattrStatus(cursor.getLong(indexFlattrStatus)); int state = cursor.getInt(indexRead); String itemIdentifier = cursor.getString(indexItemIdentifier); - boolean autoDownload = cursor.getInt(indexAutoDownload) > 0; + long autoDownload = cursor.getLong(indexAutoDownload); FeedItem item = new FeedItem(id, title, link, pubDate, paymentLink, feedId, flattrStatus, hasChapters, null, state, itemIdentifier, autoDownload); @@ -449,18 +456,37 @@ public class FeedItem extends FeedComponent implements ShownotesProvider, Flattr } public void setAutoDownload(boolean autoDownload) { - this.autoDownload = autoDownload; + this.autoDownload = autoDownload ? 1 : 0; } public boolean getAutoDownload() { - return this.autoDownload; + return this.autoDownload > 0; + } + + public int getFailedAutoDownloadAttempts() { + if (autoDownload <= 1) { + return 0; + } + int failedAttempts = (int)(autoDownload % 10); + if (failedAttempts == 0) { + failedAttempts = 10; + } + return failedAttempts; } public boolean isAutoDownloadable() { - return this.hasMedia() && - false == this.getMedia().isPlaying() && - false == this.getMedia().isDownloaded() && - this.getAutoDownload(); + if (media == null || media.isPlaying() || media.isDownloaded() || autoDownload == 0) { + return false; + } + if (autoDownload == 1) { + return true; + } + int failedAttempts = getFailedAutoDownloadAttempts(); + double magicValue = 1.767; // 1.767^(10[=#maxNumAttempts]-1) = 168 hours / 7 days + int millisecondsInHour = 3600000; + long waitingTime = (long) (Math.pow(magicValue, failedAttempts - 1) * millisecondsInHour); + long grace = TimeUnit.MINUTES.toMillis(5); + return System.currentTimeMillis() > (autoDownload + waitingTime - grace); } /** diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java index 29c44207d..c3afff276 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java +++ b/core/src/main/java/de/danoeh/antennapod/core/service/download/DownloadService.java @@ -26,6 +26,7 @@ import org.xml.sax.SAXException; import java.io.File; import java.io.IOException; +import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.Collections; import java.util.Date; @@ -196,11 +197,19 @@ public class DownloadService extends Service { saveDownloadStatus(status); handleFailedDownload(status, downloader.getDownloadRequest()); - // to make lists reload the failed item, we fake an item update if(type == FeedMedia.FEEDFILETYPE_FEEDMEDIA) { long id = status.getFeedfileId(); FeedMedia media = DBReader.getFeedMedia(id); - EventBus.getDefault().post(FeedItemEvent.updated(media.getItem())); + if(media == null || media.getItem() == null) { + return; + } + FeedItem item = media.getItem(); + if (status.getReason() == DownloadError.ERROR_HTTP_DATA_ERROR && + Integer.valueOf(status.getReasonDetailed()) == HttpURLConnection.HTTP_NOT_FOUND) { + DBWriter.saveFeedItemAutoDownloadFailed(item).get(); + } + // to make lists reload the failed item, we fake an item update + EventBus.getDefault().post(FeedItemEvent.updated(item)); } } } else { diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java index fe5b177ab..16e65f9f3 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java @@ -1015,7 +1015,9 @@ public final class DBReader { Collections.sort(feeds, comparator); int queueSize = adapter.getQueueSize(); int numNewItems = adapter.getNumberOfNewItems(); - NavDrawerData result = new NavDrawerData(feeds, queueSize, numNewItems, feedCounters); + int numDownloadedItems = adapter.getNumberOfDownloadedEpisodes(); + + NavDrawerData result = new NavDrawerData(feeds, queueSize, numNewItems, numDownloadedItems, feedCounters); adapter.close(); return result; } @@ -1024,15 +1026,18 @@ public final class DBReader { public List<Feed> feeds; public int queueSize; public int numNewItems; + public int numDownloadedItems; public LongIntMap feedCounters; public NavDrawerData(List<Feed> feeds, int queueSize, int numNewItems, + int numDownloadedItems, LongIntMap feedIndicatorValues) { this.feeds = feeds; this.queueSize = queueSize; this.numNewItems = numNewItems; + this.numDownloadedItems = numDownloadedItems; this.feedCounters = feedIndicatorValues; } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java index f74064cfc..d1d6bd750 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBWriter.java @@ -977,13 +977,35 @@ public class DBWriter { * Sets the 'auto_download'-attribute of specific FeedItem. * * @param feedItem FeedItem. + * @param autoDownload true enables auto download, false disables it */ public static Future<?> setFeedItemAutoDownload(final FeedItem feedItem, final boolean autoDownload) { - Log.d(TAG, "FeedItem[id=" + feedItem.getId() + "] SET auto_download " + autoDownload); return dbExec.submit(() -> { final PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); + adapter.setFeedItemAutoDownload(feedItem, autoDownload ? 1 : 0); + adapter.close(); + EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); + }); + } + + public static Future<?> saveFeedItemAutoDownloadFailed(final FeedItem feedItem) { + return dbExec.submit(() -> { + int failedAttempts = feedItem.getFailedAutoDownloadAttempts() + 1; + Log.d(TAG, "failedAttempts: " + failedAttempts); + long autoDownload; + if(!feedItem.getAutoDownload() || failedAttempts >= 10) { + autoDownload = 0; // giving up, disable auto download + feedItem.setAutoDownload(false); + } else { + long now = System.currentTimeMillis(); + autoDownload = (now / 10) * 10 + failedAttempts; + Log.d(TAG, "now: " + now); + Log.d(TAG, "autoDownload: " + autoDownload); + } + final PodDBAdapter adapter = PodDBAdapter.getInstance(); + adapter.open(); adapter.setFeedItemAutoDownload(feedItem, autoDownload); adapter.close(); EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); @@ -992,7 +1014,8 @@ public class DBWriter { /** * Sets the 'auto_download'-attribute of specific FeedItem. - * @param feed This feed's episodes will be processed. + * + * @param feed This feed's episodes will be processed. * @param autoDownload If true, auto download will be enabled for the feed's episodes. Else, */ public static Future<?> setFeedsItemsAutoDownload(final Feed feed, diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java index 629b73668..915ca14c7 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java @@ -794,7 +794,7 @@ public class PodDBAdapter { return status.getId(); } - public void setFeedItemAutoDownload(FeedItem feedItem, boolean autoDownload) { + public void setFeedItemAutoDownload(FeedItem feedItem, long autoDownload) { ContentValues values = new ContentValues(); values.put(KEY_AUTO_DOWNLOAD, autoDownload); db.update(TABLE_NAME_FEED_ITEMS, values, KEY_ID + "=?", diff --git a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java index 6406295c1..9b9849c49 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java +++ b/core/src/main/java/de/danoeh/antennapod/core/syndication/namespace/NSITunes.java @@ -1,5 +1,7 @@ package de.danoeh.antennapod.core.syndication.namespace; +import android.text.TextUtils; + import org.xml.sax.Attributes; import java.util.concurrent.TimeUnit; @@ -36,8 +38,10 @@ public class NSITunes extends Namespace { } else { // this is the feed image // prefer to all other images - image.setOwner(state.getFeed()); - state.getFeed().setImage(image); + if(!TextUtils.isEmpty(image.getDownload_url())) { + image.setOwner(state.getFeed()); + state.getFeed().setImage(image); + } } } diff --git a/core/src/main/res/values/arrays.xml b/core/src/main/res/values/arrays.xml index 341a7e520..6e885c0bb 100644 --- a/core/src/main/res/values/arrays.xml +++ b/core/src/main/res/values/arrays.xml @@ -11,8 +11,9 @@ <item>0</item> <item>15</item> <item>30</item> - <item>45</item> <item>60</item> + <item>120</item> + <item>300</item> </string-array> diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 69acdcc4a..726697602 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -26,6 +26,8 @@ <string name="gpodnet_main_label">gpodder.net</string> <string name="gpodnet_auth_label">gpodder.net Login</string> <string name="free_space_label">%1$s free</string> + <string name="episode_cache_full_title">Episode cache full</string> + <string name="episode_cache_full_message">The episode cache limit has been reached. You can increase the cache size in the Settings.</string> <!-- New episodes fragment --> <string name="recently_published_episodes_label">Recently published</string> @@ -75,7 +77,7 @@ <string name="length_prefix">Length:\u0020</string> <string name="size_prefix">Size:\u0020</string> <string name="processing_label">Processing</string> - <string name="loading_label">Loading...</string> + <string name="loading_label">Loading…</string> <string name="save_username_password_label">Save username and password</string> <string name="close_label">Close</string> <string name="retry_label">Retry</string> @@ -87,7 +89,7 @@ <string name="feed_auto_download_global">Global</string> <string name="feed_auto_download_always">Always</string> <string name="feed_auto_download_never">Never</string> - <string name="send_label">Send...</string> + <string name="send_label">Send…</string> <string name="episode_cleanup_never">Never</string> <string name="episode_cleanup_queue_removal">When not in queue</string> <string name="episode_cleanup_after_listening">After finishing</string> @@ -112,7 +114,7 @@ <string name="mark_all_seen_label">Mark all as seen</string> <string name="show_info_label">Show information</string> <string name="remove_feed_label">Remove Podcast</string> - <string name="share_label">Share...</string> + <string name="share_label">Share…</string> <string name="share_link_label">Share Link</string> <string name="share_link_with_position_label">Share Link with Position</string> <string name="share_feed_url_label">Share Feed URL</string> @@ -299,6 +301,8 @@ <string name="pref_autoUpdateIntervallOrTime_Disable">Disable</string> <string name="pref_autoUpdateIntervallOrTime_Interval">Set Interval</string> <string name="pref_autoUpdateIntervallOrTime_TimeOfDay">Set Time of Day</string> + <string name="pref_autoUpdateIntervallOrTime_every">every %1$s</string> + <string name="pref_autoUpdateIntervallOrTime_at">at %1$s</string> <string name="pref_downloadMediaOnWifiOnly_sum">Download media files only over WiFi</string> <string name="pref_followQueue_title">Continuous Playback</string> <string name="pref_downloadMediaOnWifiOnly_title">WiFi media download</string> @@ -374,6 +378,7 @@ <string name="experimental_pref">Experimental</string> <string name="pref_sonic_title">Sonic media player</string> <string name="pref_sonic_message">Use built-in sonic media player as a replacement for Prestissimo</string> + <string name="pref_current_value">Current value: %1$s</string> <!-- Auto-Flattr dialog --> <string name="auto_flattr_enable">Enable automatic flattring</string> @@ -402,11 +407,11 @@ <string name="opml_import_error_dir_empty">The import directory is empty.</string> <string name="select_all_label">Select all</string> <string name="deselect_all_label">Deselect all</string> - <string name="select_options_label">Select ...</string> + <string name="select_options_label">Select…</string> <string name="choose_file_from_filesystem">From local filesystem</string> <string name="choose_file_from_external_application">Use external application</string> <string name="opml_export_label">OPML export</string> - <string name="exporting_label">Exporting...</string> + <string name="exporting_label">Exporting…</string> <string name="export_error_label">Export error</string> <string name="opml_export_success_title">OPML Export successful.</string> <string name="opml_export_success_sum">The .opml file was written to:\u0020</string> @@ -494,7 +499,7 @@ <!-- Online feed view --> <string name="subscribe_label">Subscribe</string> <string name="subscribed_label">Subscribed</string> - <string name="downloading_label">Downloading...</string> + <string name="downloading_label">Downloading…</string> <!-- Content descriptions for image buttons --> <string name="show_chapters_label">Show chapters</string> @@ -529,7 +534,7 @@ <string name="sp_apps_importing_feeds_msg">Importing subscriptions from single-purpose apps…</string> <string name="search_itunes_label">Search iTunes</string> - <string name="select_label"><b>Select ...</b></string> + <string name="select_label"><b>Select…</b></string> <string name="all_label">All</string> <string name="selected_all_label">Selected all Episodes</string> <string name="none_label">None</string> @@ -542,7 +547,7 @@ <string name="selected_downloaded_label">Selected downloaded Episodes</string> <string name="not_downloaded_label">Not downloaded</string> <string name="selected_not_downloaded_label">Selected not downloaded Episodes</string> - <string name="sort_title"><b>Sort by ...</b></string> + <string name="sort_title"><b>Sort by…</b></string> <string name="sort_title_a_z">Title (A \u2192 Z)</string> <string name="sort_title_z_a">Title (Z \u2192 A)</string> <string name="sort_date_new_old">Date (New \u2192 Old)</string> |