diff options
author | ByteHamster <info@bytehamster.com> | 2020-05-25 11:34:01 +0200 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2020-05-25 11:34:03 +0200 |
commit | 382a54028029fe6297ebab405010d7e5229331d4 (patch) | |
tree | 3848b3fb636b46534e45bd94a91f2fb97e63e598 /core | |
parent | 3ee3ba3f6e770d03791fa3f0ed68e09778291437 (diff) | |
download | AntennaPod-382a54028029fe6297ebab405010d7e5229331d4.zip |
Basic local feeds support
Co-authored-by: Igor Almeida <igor.contato@gmail.com>
Diffstat (limited to 'core')
4 files changed, 125 insertions, 1 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java index 0889e5182..9c1c55d76 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java @@ -24,6 +24,7 @@ public class Feed extends FeedFile implements ImageResource { public static final int FEEDFILETYPE_FEED = 0; public static final String TYPE_RSS2 = "rss"; public static final String TYPE_ATOM1 = "atom"; + public static final String PREFIX_LOCAL_FOLDER = "antennapod_local:"; /* title as defined by the feed */ private String feedTitle; @@ -551,4 +552,7 @@ public class Feed extends FeedFile implements ImageResource { this.lastUpdateFailed = lastUpdateFailed; } + public boolean isLocalFeed() { + return download_url.startsWith(PREFIX_LOCAL_FOLDER); + } } diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java new file mode 100644 index 000000000..f024601d5 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/feed/LocalFeedUpdater.java @@ -0,0 +1,111 @@ +package de.danoeh.antennapod.core.feed; + +import android.content.Context; +import android.media.MediaMetadataRetriever; +import android.net.Uri; +import android.util.Log; +import androidx.documentfile.provider.DocumentFile; +import de.danoeh.antennapod.core.service.download.DownloadStatus; +import de.danoeh.antennapod.core.storage.DBTasks; +import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.core.util.DownloadError; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +public class LocalFeedUpdater { + + public static void updateFeed(Feed feed, Context context) { + String uriString = feed.getDownload_url().replace(Feed.PREFIX_LOCAL_FOLDER, ""); + DocumentFile documentFolder = DocumentFile.fromTreeUri(context, Uri.parse(uriString)); + if (documentFolder == null) { + reportError(feed, "Unable to retrieve document tree"); + return; + } + if (!documentFolder.exists() || !documentFolder.canRead()) { + reportError(feed, "Cannot read local directory"); + return; + } + + if (feed.getItems() == null) { + feed.setItems(new ArrayList<>()); + } + //make sure it is the latest 'version' of this feed from the db (all items etc) + feed = DBTasks.updateFeed(context, feed)[0]; + + List<DocumentFile> mediaFiles = new ArrayList<>(); + for (DocumentFile file : documentFolder.listFiles()) { + String mime = file.getType(); + if (mime != null && (mime.startsWith("audio/") || mime.startsWith("video/"))) { + mediaFiles.add(file); + } + } + + List<FeedItem> newItems = feed.getItems(); + for (DocumentFile f : mediaFiles) { + FeedItem found = feedContainsFile(feed, f.getName()); + if (found != null) { + //TODO make sure the media has not changed (type, duration) + } else { + FeedItem item = createFeedItem(feed, f, context); + newItems.add(item); + } + } + + List<String> iconLocations = Arrays.asList("folder.jpg", "Folder.jpg", "folder.png", "Folder.png"); + for (String iconLocation : iconLocations) { + DocumentFile image = documentFolder.findFile(iconLocation); + if (image != null) { + feed.setImageUrl(image.getUri().toString()); + break; + } + } + + DBTasks.updateFeed(context, feed); + } + + private static FeedItem feedContainsFile(Feed feed, String filename) { + List<FeedItem> items = feed.getItems(); + for (FeedItem i : items) { + if (i.getMedia() != null && i.getLink().equals(filename)) { + return i; + } + } + return null; + } + + private static FeedItem createFeedItem(Feed feed, DocumentFile file, Context context) { + //create item + long globalId = 0; + Date date = new Date(); + String uuid = UUID.randomUUID().toString(); + FeedItem item = new FeedItem(globalId, file.getName(), uuid, file.getName(), date, FeedItem.UNPLAYED, feed); + item.setAutoDownload(false); + + //add the media to the item + long duration = getFileDuration(file, context); + long size = file.length(); + FeedMedia media = new FeedMedia(0, item, (int) duration, 0, size, file.getType(), + file.getUri().toString(), file.getUri().toString(), true, null, 0, 0); + item.setMedia(media); + + return item; + } + + private static void reportError(Feed feed, String reasonDetailed) { + DownloadStatus status = new DownloadStatus(feed, feed.getTitle(), + DownloadError.ERROR_IO_ERROR, false, reasonDetailed, true); + DBWriter.addDownloadStatus(status); + DBWriter.setFeedLastUpdateFailed(feed.getId(), true); + } + + private static long getFileDuration(DocumentFile f, Context context) { + MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); + mediaMetadataRetriever.setDataSource(context, f.getUri()); + String durationStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); + return Long.parseLong(durationStr); + } +} diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java index 16e2825b4..323e34b6a 100644 --- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java +++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java @@ -16,6 +16,7 @@ import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; +import de.danoeh.antennapod.core.feed.LocalFeedUpdater; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadStatus; import de.danoeh.antennapod.core.sync.SyncService; @@ -241,7 +242,12 @@ public final class DBTasks { feed.getPreferences().getUsername(), feed.getPreferences().getPassword()); } f.setId(feed.getId()); - DownloadRequester.getInstance().downloadFeed(context, f, loadAllPages, force, initiatedByUser); + + if (f.isLocalFeed()) { + new Thread(() -> LocalFeedUpdater.updateFeed(f, context)).start(); + } else { + DownloadRequester.getInstance().downloadFeed(context, f, loadAllPages, force, initiatedByUser); + } } /** diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 2827f666e..4f94a141a 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -718,6 +718,9 @@ <string name="discover">Discover</string> <string name="discover_more">more ยป</string> <string name="search_powered_by">Search powered by %1$s</string> + <string name="add_local_folder">Add local folder</string> + <string name="add_local_folder_success">Adding local folder succeeded</string> + <string name="local_feed_description">This virtual podcast was created by adding a folder to AntennaPod.</string> <string name="filter">Filter</string> |