diff options
author | daniel oeh <daniel.oeh@gmail.com> | 2012-07-13 12:23:47 +0200 |
---|---|---|
committer | daniel oeh <daniel.oeh@gmail.com> | 2012-07-13 12:23:47 +0200 |
commit | ba2d2afbbc6cbb79fc75493703425b5d6d040530 (patch) | |
tree | e731a1209160e8224679cb238c0a964c3e757590 /src/de/danoeh/antennapod/feed | |
parent | 1ae00a0f2531fdb05a44877dda88ee2300e3ffec (diff) | |
download | AntennaPod-ba2d2afbbc6cbb79fc75493703425b5d6d040530.zip |
Renamed package and application
Diffstat (limited to 'src/de/danoeh/antennapod/feed')
-rw-r--r-- | src/de/danoeh/antennapod/feed/Feed.java | 129 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/feed/FeedCategory.java | 20 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/feed/FeedComponent.java | 26 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/feed/FeedFile.java | 55 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/feed/FeedImage.java | 32 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/feed/FeedItem.java | 117 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/feed/FeedManager.java | 744 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/feed/FeedMedia.java | 73 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/feed/SimpleChapter.java | 22 |
9 files changed, 1218 insertions, 0 deletions
diff --git a/src/de/danoeh/antennapod/feed/Feed.java b/src/de/danoeh/antennapod/feed/Feed.java new file mode 100644 index 000000000..9d732a81f --- /dev/null +++ b/src/de/danoeh/antennapod/feed/Feed.java @@ -0,0 +1,129 @@ +package de.danoeh.antennapod.feed; + +import java.util.ArrayList; +import java.util.Date; + +/** + * Data Object for a whole feed + * + * @author daniel + * + */ +public class Feed extends FeedFile { + private String title; + /** Link to the website. */ + private String link; + private String description; + private String language; + /** Name of the author */ + private String author; + private FeedImage image; + private FeedCategory category; + private ArrayList<FeedItem> items; + /** Date of last refresh. */ + private Date lastUpdate; + private String paymentLink; + + public Feed(Date lastUpdate) { + super(); + items = new ArrayList<FeedItem>(); + this.lastUpdate = lastUpdate; + } + + public Feed(String url, Date lastUpdate) { + this(lastUpdate); + this.download_url = url; + } + + /** Returns the number of FeedItems where 'read' is false. */ + public int getNumOfNewItems() { + int count = 0; + for (FeedItem item : items) { + if (!item.isRead()) { + count++; + } + } + return count; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public FeedImage getImage() { + return image; + } + + public void setImage(FeedImage image) { + this.image = image; + } + + public FeedCategory getCategory() { + return category; + } + + public void setCategory(FeedCategory category) { + this.category = category; + } + + public ArrayList<FeedItem> getItems() { + return items; + } + + public void setItems(ArrayList<FeedItem> items) { + this.items = items; + } + + public Date getLastUpdate() { + return lastUpdate; + } + + public void setLastUpdate(Date lastUpdate) { + this.lastUpdate = lastUpdate; + } + + public String getPaymentLink() { + return paymentLink; + } + + public void setPaymentLink(String paymentLink) { + this.paymentLink = paymentLink; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + +} diff --git a/src/de/danoeh/antennapod/feed/FeedCategory.java b/src/de/danoeh/antennapod/feed/FeedCategory.java new file mode 100644 index 000000000..fc3d8d79b --- /dev/null +++ b/src/de/danoeh/antennapod/feed/FeedCategory.java @@ -0,0 +1,20 @@ +package de.danoeh.antennapod.feed; + +public class FeedCategory extends FeedComponent{ + protected String name; + + public FeedCategory(String name) { + super(); + this.name = name; + } + + public String getName() { + return name; + } + + + + + + +} diff --git a/src/de/danoeh/antennapod/feed/FeedComponent.java b/src/de/danoeh/antennapod/feed/FeedComponent.java new file mode 100644 index 000000000..a192f4bc8 --- /dev/null +++ b/src/de/danoeh/antennapod/feed/FeedComponent.java @@ -0,0 +1,26 @@ +package de.danoeh.antennapod.feed; + +/** + * Represents every possible component of a feed + * @author daniel + * + */ +public class FeedComponent { + + protected long id; + + public FeedComponent() { + super(); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + + +}
\ No newline at end of file diff --git a/src/de/danoeh/antennapod/feed/FeedFile.java b/src/de/danoeh/antennapod/feed/FeedFile.java new file mode 100644 index 000000000..c7a9b7bc1 --- /dev/null +++ b/src/de/danoeh/antennapod/feed/FeedFile.java @@ -0,0 +1,55 @@ +package de.danoeh.antennapod.feed; + +/** Represents a component of a Feed that has to be downloaded*/ +public abstract class FeedFile extends FeedComponent { + protected String file_url; + protected String download_url; + protected long downloadId; // temporary id given by the Android DownloadManager + protected boolean downloaded; + + public FeedFile(String file_url, String download_url, boolean downloaded) { + super(); + this.file_url = file_url; + this.download_url = download_url; + this.downloaded = downloaded; + } + + public FeedFile() { + this(null, null, false); + } + + public String getFile_url() { + return file_url; + } + public void setFile_url(String file_url) { + this.file_url = file_url; + } + public String getDownload_url() { + return download_url; + } + public void setDownload_url(String download_url) { + this.download_url = download_url; + } + + public long getDownloadId() { + return downloadId; + } + + public void setDownloadId(long downloadId) { + this.downloadId = downloadId; + } + + public boolean isDownloaded() { + return downloaded; + } + + public void setDownloaded(boolean downloaded) { + this.downloaded = downloaded; + } + + public boolean isDownloading() { + return downloadId != 0; + } + + +} diff --git a/src/de/danoeh/antennapod/feed/FeedImage.java b/src/de/danoeh/antennapod/feed/FeedImage.java new file mode 100644 index 000000000..4b53f3da4 --- /dev/null +++ b/src/de/danoeh/antennapod/feed/FeedImage.java @@ -0,0 +1,32 @@ +package de.danoeh.antennapod.feed; + + +public class FeedImage extends FeedFile { + protected String title; + + public FeedImage(String download_url, String title) { + super(null, download_url, false); + this.download_url = download_url; + this.title = title; + } + + public FeedImage(long id, String title, String file_url, + String download_url, boolean downloaded) { + super(file_url, download_url, downloaded); + this.id = id; + this.title = title; + } + + public FeedImage() { + super(); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + +} diff --git a/src/de/danoeh/antennapod/feed/FeedItem.java b/src/de/danoeh/antennapod/feed/FeedItem.java new file mode 100644 index 000000000..732c61380 --- /dev/null +++ b/src/de/danoeh/antennapod/feed/FeedItem.java @@ -0,0 +1,117 @@ +package de.danoeh.antennapod.feed; + +import java.util.ArrayList; +import java.util.Date; + + +/** + * Data Object for a XML message + * @author daniel + * + */ +public class FeedItem extends FeedComponent{ + + private String title; + private String description; + private String contentEncoded; + private String link; + private Date pubDate; + private FeedMedia media; + private Feed feed; + protected boolean read; + private String paymentLink; + private ArrayList<SimpleChapter> simpleChapters; + + public FeedItem() { + this.read = true; + } + + public FeedItem(String title, String description, String link, + Date pubDate, FeedMedia media, Feed feed) { + super(); + this.title = title; + this.description = description; + this.link = link; + this.pubDate = pubDate; + this.media = media; + this.feed = feed; + this.read = true; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public Date getPubDate() { + return pubDate; + } + + public void setPubDate(Date pubDate) { + this.pubDate = pubDate; + } + + public FeedMedia getMedia() { + return media; + } + + public void setMedia(FeedMedia media) { + this.media = media; + } + + public Feed getFeed() { + return feed; + } + + public void setFeed(Feed feed) { + this.feed = feed; + } + + public boolean isRead() { + return read; + } + + public String getContentEncoded() { + return contentEncoded; + } + + public void setContentEncoded(String contentEncoded) { + this.contentEncoded = contentEncoded; + } + + public String getPaymentLink() { + return paymentLink; + } + + public void setPaymentLink(String paymentLink) { + this.paymentLink = paymentLink; + } + + public ArrayList<SimpleChapter> getSimpleChapters() { + return simpleChapters; + } + + public void setSimpleChapters(ArrayList<SimpleChapter> simpleChapters) { + this.simpleChapters = simpleChapters; + } + +} diff --git a/src/de/danoeh/antennapod/feed/FeedManager.java b/src/de/danoeh/antennapod/feed/FeedManager.java new file mode 100644 index 000000000..26a3ffa77 --- /dev/null +++ b/src/de/danoeh/antennapod/feed/FeedManager.java @@ -0,0 +1,744 @@ +package de.danoeh.antennapod.feed; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; + +import de.danoeh.antennapod.activity.MediaplayerActivity; +import de.danoeh.antennapod.asynctask.DownloadStatus; +import de.danoeh.antennapod.service.PlaybackService; +import de.danoeh.antennapod.storage.*; +import de.danoeh.antennapod.util.FeedItemPubdateComparator; +import de.danoeh.antennapod.util.FeedtitleComparator; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.os.Debug; +import android.util.Log; + +/** + * Singleton class Manages all feeds, categories and feeditems + * + * + * */ +public class FeedManager { + private static final String TAG = "FeedManager"; + + public static final String ACTION_UNREAD_ITEMS_UPDATE = "de.danoeh.antennapod.action.feed.unreadItemsUpdate"; + public static final String ACTION_QUEUE_UPDATE = "de.danoeh.antennapod.action.feed.queueUpdate"; + public static final String EXTRA_FEED_ITEM_ID = "de.danoeh.antennapod.extra.feed.feedItemId"; + public static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feed.feedId"; + + /** Number of completed Download status entries to store. */ + private static final int DOWNLOAD_LOG_SIZE = 25; + + private static FeedManager singleton; + + private ArrayList<Feed> feeds; + private ArrayList<FeedCategory> categories; + + /** Contains all items where 'read' is false */ + private ArrayList<FeedItem> unreadItems; + + /** Contains completed Download status entries */ + private ArrayList<DownloadStatus> downloadLog; + + /** Contains the queue of items to be played. */ + private ArrayList<FeedItem> queue; + + private DownloadRequester requester; + + private FeedManager() { + feeds = new ArrayList<Feed>(); + categories = new ArrayList<FeedCategory>(); + unreadItems = new ArrayList<FeedItem>(); + requester = DownloadRequester.getInstance(); + downloadLog = new ArrayList<DownloadStatus>(); + queue = new ArrayList<FeedItem>(); + } + + public static FeedManager getInstance() { + if (singleton == null) { + singleton = new FeedManager(); + } + return singleton; + } + + /** + * Play FeedMedia and start the playback service + launch Mediaplayer + * Activity. + * + * @param context + * for starting the playbackservice + * @param media + * that shall be played + * @param showPlayer + * if Mediaplayer activity shall be started + * @param startWhenPrepared + * if Mediaplayer shall be started after it has been prepared + */ + public void playMedia(Context context, FeedMedia media, boolean showPlayer, + boolean startWhenPrepared, boolean shouldStream) { + // Start playback Service + Intent launchIntent = new Intent(context, PlaybackService.class); + launchIntent.putExtra(PlaybackService.EXTRA_MEDIA_ID, media.getId()); + launchIntent.putExtra(PlaybackService.EXTRA_FEED_ID, media.getItem() + .getFeed().getId()); + launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, + startWhenPrepared); + launchIntent + .putExtra(PlaybackService.EXTRA_SHOULD_STREAM, shouldStream); + context.startService(launchIntent); + if (showPlayer) { + // Launch Mediaplayer + Intent playerIntent = new Intent(context, MediaplayerActivity.class); + context.startActivity(playerIntent); + } + } + + /** Remove media item that has been downloaded. */ + public boolean deleteFeedMedia(Context context, FeedMedia media) { + boolean result = false; + if (media.isDownloaded()) { + File mediaFile = new File(media.file_url); + if (mediaFile.exists()) { + result = mediaFile.delete(); + } + media.setDownloaded(false); + media.setFile_url(null); + setFeedMedia(context, media); + } + Log.d(TAG, "Deleting File. Result: " + result); + return result; + } + + /** Remove a feed with all its items and media files and its image. */ + public boolean deleteFeed(Context context, Feed feed) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + // delete image file + if (feed.getImage() != null) { + if (feed.getImage().isDownloaded() + && feed.getImage().getFile_url() == null) { + File imageFile = new File(feed.getImage().getFile_url()); + imageFile.delete(); + } + } + // delete stored media files and mark them as read + for (FeedItem item : feed.getItems()) { + if (!item.isRead()) { + unreadItems.remove(item); + } + if (queue.contains(item)) { + removeQueueItem(item, adapter); + } + if (item.getMedia() != null && item.getMedia().isDownloaded()) { + File mediaFile = new File(item.getMedia().getFile_url()); + mediaFile.delete(); + } + } + + adapter.removeFeed(feed); + adapter.close(); + return feeds.remove(feed); + + } + + private void sendUnreadItemsUpdateBroadcast(Context context, FeedItem item) { + Intent update = new Intent(ACTION_UNREAD_ITEMS_UPDATE); + if (item != null) { + update.putExtra(EXTRA_FEED_ID, item.getFeed().getId()); + update.putExtra(EXTRA_FEED_ITEM_ID, item.getId()); + } + context.sendBroadcast(update); + } + + private void sendQueueUpdateBroadcast(Context context, FeedItem item) { + Intent update = new Intent(ACTION_QUEUE_UPDATE); + if (item != null) { + update.putExtra(EXTRA_FEED_ID, item.getFeed().getId()); + update.putExtra(EXTRA_FEED_ITEM_ID, item.getId()); + } + context.sendBroadcast(update); + } + + /** + * Sets the 'read'-attribute of a FeedItem. Should be used by all Classes + * instead of the setters of FeedItem. + */ + public void markItemRead(Context context, FeedItem item, boolean read) { + Log.d(TAG, "Setting item with title " + item.getTitle() + + " as read/unread"); + item.read = read; + setFeedItem(context, item); + if (read == true) { + unreadItems.remove(item); + } else { + unreadItems.add(item); + Collections.sort(unreadItems, new FeedItemPubdateComparator()); + } + sendUnreadItemsUpdateBroadcast(context, item); + } + + /** + * Sets the 'read' attribute of all FeedItems of a specific feed to true + * + * @param context + */ + public void markFeedRead(Context context, Feed feed) { + for (FeedItem item : feed.getItems()) { + if (unreadItems.contains(item)) { + markItemRead(context, item, true); + } + } + } + + /** Marks all items in the unread items list as read */ + public void markAllItemsRead(Context context) { + Log.d(TAG, "marking all items as read"); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + for (FeedItem item : unreadItems) { + item.read = true; + setFeedItem(item, adapter); + } + adapter.close(); + unreadItems.clear(); + sendUnreadItemsUpdateBroadcast(context, null); + } + + public void refreshAllFeeds(Context context) { + Log.d(TAG, "Refreshing all feeds."); + for (Feed feed : feeds) { + refreshFeed(context, feed); + } + } + + /** + * Notifies the feed manager that the an image file is invalid. It will try + * to redownload it + */ + public void notifyInvalidImageFile(Context context, FeedImage image) { + Log.i(TAG, + "The feedmanager was notified about an invalid image download. It will now try to redownload the image file"); + image.setDownloaded(false); + image.setFile_url(null); + requester.downloadImage(context, image); + } + + public void refreshFeed(Context context, Feed feed) { + requester.downloadFeed(context, new Feed(feed.getDownload_url(), + new Date())); + } + + public long addDownloadStatus(Context context, DownloadStatus status) { + PodDBAdapter adapter = new PodDBAdapter(context); + downloadLog.add(status); + adapter.open(); + if (downloadLog.size() > DOWNLOAD_LOG_SIZE) { + adapter.removeDownloadStatus(downloadLog.remove(0)); + } + long result = adapter.setDownloadStatus(status); + adapter.close(); + return result; + } + + public void addQueueItem(Context context, FeedItem item) { + PodDBAdapter adapter = new PodDBAdapter(context); + queue.add(item); + adapter.open(); + adapter.setQueue(queue); + adapter.close(); + sendQueueUpdateBroadcast(context, item); + } + + /** Removes all items in queue */ + public void clearQueue(Context context) { + Log.d(TAG, "Clearing queue"); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + queue.clear(); + adapter.setQueue(queue); + adapter.close(); + sendQueueUpdateBroadcast(context, null); + } + + /** Uses external adapter. */ + public void removeQueueItem(FeedItem item, PodDBAdapter adapter) { + boolean removed = queue.remove(item); + if (removed) { + adapter.setQueue(queue); + } + + } + + /** Uses its own adapter. */ + public void removeQueueItem(Context context, FeedItem item) { + boolean removed = queue.remove(item); + if (removed) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setQueue(queue); + adapter.close(); + } + sendQueueUpdateBroadcast(context, item); + } + + public void moveQueueItem(Context context, FeedItem item, int delta) { + Log.d(TAG, "Moving queue item"); + int itemIndex = queue.indexOf(item); + int newIndex = itemIndex + delta; + if (newIndex >= 0 && newIndex < queue.size()) { + FeedItem oldItem = queue.set(newIndex, item); + queue.set(itemIndex, oldItem); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setQueue(queue); + adapter.close(); + } + sendQueueUpdateBroadcast(context, item); + } + + public boolean isInQueue(FeedItem item) { + return queue.contains(item); + } + + public FeedItem getFirstQueueItem() { + if (queue.isEmpty()) { + return null; + } else { + return queue.get(0); + } + } + + private void addNewFeed(Context context, Feed feed) { + feeds.add(feed); + Collections.sort(feeds, new FeedtitleComparator()); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setCompleteFeed(feed); + adapter.close(); + } + + /** + * Updates an existing feed or adds it as a new one if it doesn't exist. + * + * @return The saved Feed with a database ID + */ + public Feed updateFeed(Context context, final Feed newFeed) { + // Look up feed in the feedslist + final Feed savedFeed = searchFeedByLink(newFeed.getLink()); + if (savedFeed == null) { + Log.d(TAG, + "Found no existing Feed with title " + newFeed.getTitle() + + ". Adding as new one."); + // Add a new Feed + addNewFeed(context, newFeed); + markItemRead(context, newFeed.getItems().get(0), false); + + return newFeed; + } else { + Log.d(TAG, "Feed with title " + newFeed.getTitle() + + " already exists. Syncing new with existing one."); + // Look for new or updated Items + for (int idx = 0; idx < newFeed.getItems().size(); idx++) { + FeedItem item = newFeed.getItems().get(idx); + FeedItem oldItem = searchFeedItemByTitle(savedFeed, + item.getTitle()); + if (oldItem == null) { + // item is new + item.setFeed(savedFeed); + savedFeed.getItems().add(idx, item); + markItemRead(context, item, false); + } + } + savedFeed.setLastUpdate(newFeed.getLastUpdate()); + setFeed(context, savedFeed); + return savedFeed; + } + + } + + /** Get a Feed by its link */ + private Feed searchFeedByLink(String link) { + for (Feed feed : feeds) { + if (feed.getLink().equals(link)) { + return feed; + } + } + return null; + } + + /** Get a FeedItem by its link */ + private FeedItem searchFeedItemByTitle(Feed feed, String title) { + for (FeedItem item : feed.getItems()) { + if (item.getTitle().equals(title)) { + return item; + } + } + return null; + } + + /** Updates Information of an existing Feed. Uses external adapter. */ + public long setFeed(Feed feed, PodDBAdapter adapter) { + if (adapter != null) { + return adapter.setFeed(feed); + } else { + Log.w(TAG, "Adapter in setFeed was null"); + return 0; + } + } + + /** Updates Information of an existing Feeditem. Uses external adapter. */ + public long setFeedItem(FeedItem item, PodDBAdapter adapter) { + if (adapter != null) { + return adapter.setSingleFeedItem(item); + } else { + Log.w(TAG, "Adapter in setFeedItem was null"); + return 0; + } + } + + /** Updates Information of an existing Feedimage. Uses external adapter. */ + public long setFeedImage(FeedImage image, PodDBAdapter adapter) { + if (adapter != null) { + return adapter.setImage(image); + } else { + Log.w(TAG, "Adapter in setFeedImage was null"); + return 0; + } + } + + /** + * Updates Information of an existing Feedmedia object. Uses external + * adapter. + */ + public long setFeedImage(FeedMedia media, PodDBAdapter adapter) { + if (adapter != null) { + return adapter.setMedia(media); + } else { + Log.w(TAG, "Adapter in setFeedMedia was null"); + return 0; + } + } + + /** + * Updates Information of an existing Feed. Creates and opens its own + * adapter. + */ + public long setFeed(Context context, Feed feed) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + long result = adapter.setFeed(feed); + adapter.close(); + return result; + } + + /** + * Updates information of an existing FeedItem. Creates and opens its own + * adapter. + */ + public long setFeedItem(Context context, FeedItem item) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + long result = adapter.setSingleFeedItem(item); + adapter.close(); + return result; + } + + /** + * Updates information of an existing FeedImage. Creates and opens its own + * adapter. + */ + public long setFeedImage(Context context, FeedImage image) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + long result = adapter.setImage(image); + adapter.close(); + return result; + } + + /** + * Updates information of an existing FeedMedia object. Creates and opens + * its own adapter. + */ + public long setFeedMedia(Context context, FeedMedia media) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + long result = adapter.setMedia(media); + adapter.close(); + return result; + } + + /** Get a Feed by its id */ + public Feed getFeed(long id) { + for (Feed f : feeds) { + if (f.id == id) { + return f; + } + } + Log.e(TAG, "Couldn't find Feed with id " + id); + return null; + } + + /** Get a Feed Image by its id */ + public FeedImage getFeedImage(long id) { + for (Feed f : feeds) { + FeedImage image = f.getImage(); + if (image != null && image.getId() == id) { + return image; + } + } + return null; + } + + /** Get a Feed Item by its id and its feed */ + public FeedItem getFeedItem(long id, Feed feed) { + for (FeedItem item : feed.getItems()) { + if (item.getId() == id) { + return item; + } + } + Log.e(TAG, "Couldn't find FeedItem with id " + id); + return null; + } + + /** Get a FeedMedia object by the id of the Media object and the feed object */ + public FeedMedia getFeedMedia(long id, Feed feed) { + if (feed != null) { + for (FeedItem item : feed.getItems()) { + if (item.getMedia().getId() == id) { + return item.getMedia(); + } + } + } + Log.e(TAG, "Couldn't find FeedMedia with id " + id); + if (feed == null) + Log.e(TAG, "Feed was null"); + return null; + } + + /** Get a FeedMedia object by the id of the Media object. */ + public FeedMedia getFeedMedia(long id) { + for (Feed feed : feeds) { + for (FeedItem item : feed.getItems()) { + if (item.getMedia() != null && item.getMedia().getId() == id) { + return item.getMedia(); + } + } + } + Log.w(TAG, "Couldn't find FeedMedia with id " + id); + return null; + } + + public DownloadStatus getDownloadStatus(long statusId) { + for (DownloadStatus status : downloadLog) { + if (status.getId() == statusId) { + return status; + } + } + return null; + } + + /** Reads the database */ + public void loadDBData(Context context) { + updateArrays(context); + } + + public void updateArrays(Context context) { + feeds.clear(); + categories.clear(); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + extractFeedlistFromCursor(context, adapter); + extractDownloadLogFromCursor(context, adapter); + extractQueueFromCursor(context, adapter); + adapter.close(); + Collections.sort(feeds, new FeedtitleComparator()); + Collections.sort(unreadItems, new FeedItemPubdateComparator()); + } + + private void extractFeedlistFromCursor(Context context, PodDBAdapter adapter) { + Log.d(TAG, "Extracting Feedlist"); + Cursor feedlistCursor = adapter.getAllFeedsCursor(); + if (feedlistCursor.moveToFirst()) { + do { + Date lastUpdate = new Date( + feedlistCursor.getLong(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_LASTUPDATE))); + Feed feed = new Feed(lastUpdate); + + feed.id = feedlistCursor.getLong(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_ID)); + feed.setTitle(feedlistCursor.getString(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_TITLE))); + feed.setLink(feedlistCursor.getString(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_LINK))); + feed.setDescription(feedlistCursor.getString(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_DESCRIPTION))); + feed.setPaymentLink(feedlistCursor.getString(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_PAYMENT_LINK))); + feed.setAuthor(feedlistCursor.getString(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_AUTHOR))); + feed.setLanguage(feedlistCursor.getString(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_LANGUAGE))); + feed.setImage(adapter.getFeedImage(feedlistCursor + .getLong(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_IMAGE)))); + feed.file_url = feedlistCursor.getString(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_FILE_URL)); + feed.download_url = feedlistCursor.getString(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL)); + feed.setDownloaded(feedlistCursor.getInt(feedlistCursor + .getColumnIndex(PodDBAdapter.KEY_DOWNLOADED)) > 0); + // Get FeedItem-Object + Cursor itemlistCursor = adapter.getAllItemsOfFeedCursor(feed); + feed.setItems(extractFeedItemsFromCursor(context, feed, + itemlistCursor, adapter)); + itemlistCursor.close(); + + feeds.add(feed); + } while (feedlistCursor.moveToNext()); + } + feedlistCursor.close(); + + } + + private ArrayList<FeedItem> extractFeedItemsFromCursor(Context context, + Feed feed, Cursor itemlistCursor, PodDBAdapter adapter) { + Log.d(TAG, "Extracting Feeditems of feed " + feed.getTitle()); + ArrayList<FeedItem> items = new ArrayList<FeedItem>(); + if (itemlistCursor.moveToFirst()) { + do { + FeedItem item = new FeedItem(); + + item.id = itemlistCursor.getLong(itemlistCursor + .getColumnIndex(PodDBAdapter.KEY_ID)); + item.setFeed(feed); + item.setTitle(itemlistCursor.getString(itemlistCursor + .getColumnIndex(PodDBAdapter.KEY_TITLE))); + item.setLink(itemlistCursor.getString(itemlistCursor + .getColumnIndex(PodDBAdapter.KEY_LINK))); + item.setDescription(itemlistCursor.getString(itemlistCursor + .getColumnIndex(PodDBAdapter.KEY_DESCRIPTION))); + item.setContentEncoded(itemlistCursor.getString(itemlistCursor + .getColumnIndex(PodDBAdapter.KEY_CONTENT_ENCODED))); + item.setPubDate(new Date(itemlistCursor.getLong(itemlistCursor + .getColumnIndex(PodDBAdapter.KEY_PUBDATE)))); + item.setPaymentLink(itemlistCursor.getString(itemlistCursor + .getColumnIndex(PodDBAdapter.KEY_PAYMENT_LINK))); + long mediaId = itemlistCursor.getLong(itemlistCursor + .getColumnIndex(PodDBAdapter.KEY_MEDIA)); + if (mediaId != 0) { + item.setMedia(adapter.getFeedMedia(mediaId, item)); + } + item.read = (itemlistCursor.getInt(itemlistCursor + .getColumnIndex(PodDBAdapter.KEY_READ)) > 0) ? true + : false; + if (!item.read) { + unreadItems.add(item); + } + + // extract chapters + Cursor chapterCursor = adapter + .getSimpleChaptersOfFeedItemCursor(item); + if (chapterCursor.moveToFirst()) { + item.setSimpleChapters(new ArrayList<SimpleChapter>()); + do { + SimpleChapter chapter = new SimpleChapter( + chapterCursor + .getLong(chapterCursor + .getColumnIndex(PodDBAdapter.KEY_START)), + chapterCursor.getString(chapterCursor + .getColumnIndex(PodDBAdapter.KEY_TITLE))); + item.getSimpleChapters().add(chapter); + } while (chapterCursor.moveToNext()); + } + chapterCursor.close(); + + items.add(item); + } while (itemlistCursor.moveToNext()); + } + Collections.sort(items, new FeedItemPubdateComparator()); + return items; + } + + private void extractDownloadLogFromCursor(Context context, + PodDBAdapter adapter) { + Log.d(TAG, "Extracting DownloadLog"); + Cursor logCursor = adapter.getDownloadLogCursor(); + if (logCursor.moveToFirst()) { + do { + long id = logCursor.getLong(logCursor + .getColumnIndex(PodDBAdapter.KEY_ID)); + long feedfileId = logCursor.getLong(logCursor + .getColumnIndex(PodDBAdapter.KEY_FEEDFILE)); + int feedfileType = logCursor.getInt(logCursor + .getColumnIndex(PodDBAdapter.KEY_FEEDFILETYPE)); + FeedFile feedfile = null; + switch (feedfileType) { + case PodDBAdapter.FEEDFILETYPE_FEED: + feedfile = getFeed(feedfileId); + break; + case PodDBAdapter.FEEDFILETYPE_FEEDIMAGE: + feedfile = getFeedImage(feedfileId); + break; + case PodDBAdapter.FEEDFILETYPE_FEEDMEDIA: + feedfile = getFeedMedia(feedfileId); + } + if (feedfile != null) { // otherwise ignore status + boolean successful = logCursor.getInt(logCursor + .getColumnIndex(PodDBAdapter.KEY_SUCCESSFUL)) > 0; + int reason = logCursor.getInt(logCursor + .getColumnIndex(PodDBAdapter.KEY_REASON)); + Date completionDate = new Date(logCursor.getLong(logCursor + .getColumnIndex(PodDBAdapter.KEY_COMPLETION_DATE))); + downloadLog.add(new DownloadStatus(id, feedfile, + successful, reason, completionDate)); + } + + } while (logCursor.moveToNext()); + } + logCursor.close(); + } + + private void extractQueueFromCursor(Context context, PodDBAdapter adapter) { + Log.d(TAG, "Extracting Queue"); + Cursor cursor = adapter.getQueueCursor(); + if (cursor.moveToFirst()) { + do { + int index = cursor.getInt(cursor + .getColumnIndex(PodDBAdapter.KEY_ID)); + Feed feed = getFeed(cursor.getLong(cursor + .getColumnIndex(PodDBAdapter.KEY_FEED))); + if (feed != null) { + FeedItem item = getFeedItem(cursor.getLong(cursor + .getColumnIndex(PodDBAdapter.KEY_FEEDITEM)), feed); + if (item != null) { + queue.add(index, item); + } + } + + } while (cursor.moveToNext()); + } + cursor.close(); + } + + public ArrayList<Feed> getFeeds() { + return feeds; + } + + public ArrayList<FeedItem> getUnreadItems() { + return unreadItems; + } + + public ArrayList<DownloadStatus> getDownloadLog() { + return downloadLog; + } + + public ArrayList<FeedItem> getQueue() { + return queue; + } + +} diff --git a/src/de/danoeh/antennapod/feed/FeedMedia.java b/src/de/danoeh/antennapod/feed/FeedMedia.java new file mode 100644 index 000000000..92059b712 --- /dev/null +++ b/src/de/danoeh/antennapod/feed/FeedMedia.java @@ -0,0 +1,73 @@ +package de.danoeh.antennapod.feed; + +public class FeedMedia extends FeedFile{ + private int duration; + private int position; // Current position in file + private long size; // File size in Byte + private String mime_type; + private FeedItem item; + + public FeedMedia(FeedItem i, String download_url, long size, String mime_type) { + super(null, download_url, false); + this.item = i; + this.size = size; + this.mime_type = mime_type; + } + + public FeedMedia(long id, FeedItem item, int duration, int position, long size, String mime_type, + String file_url, String download_url, boolean downloaded) { + super(file_url, download_url, downloaded); + this.id = id; + this.item = item; + this.duration = duration; + this.position = position; + this.size = size; + this.mime_type = mime_type; + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public int getPosition() { + return position; + } + + public void setPosition(int position) { + this.position = position; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public String getMime_type() { + return mime_type; + } + + public void setMime_type(String mime_type) { + this.mime_type = mime_type; + } + + public FeedItem getItem() { + return item; + } + + public void setItem(FeedItem item) { + this.item = item; + } + + + + + + +} diff --git a/src/de/danoeh/antennapod/feed/SimpleChapter.java b/src/de/danoeh/antennapod/feed/SimpleChapter.java new file mode 100644 index 000000000..5e43bfeb6 --- /dev/null +++ b/src/de/danoeh/antennapod/feed/SimpleChapter.java @@ -0,0 +1,22 @@ +package de.danoeh.antennapod.feed; + +public class SimpleChapter extends FeedComponent { + public long getStart() { + return start; + } + + public SimpleChapter(long start, String title) { + super(); + this.start = start; + this.title = title; + } + + public String getTitle() { + return title; + } + /** Defines starting point in milliseconds. */ + private long start; + private String title; + + +} |