summaryrefslogtreecommitdiff
path: root/src/de/danoeh/antennapod/feed
diff options
context:
space:
mode:
authordaniel oeh <daniel.oeh@gmail.com>2012-07-13 12:23:47 +0200
committerdaniel oeh <daniel.oeh@gmail.com>2012-07-13 12:23:47 +0200
commitba2d2afbbc6cbb79fc75493703425b5d6d040530 (patch)
treee731a1209160e8224679cb238c0a964c3e757590 /src/de/danoeh/antennapod/feed
parent1ae00a0f2531fdb05a44877dda88ee2300e3ffec (diff)
downloadAntennaPod-ba2d2afbbc6cbb79fc75493703425b5d6d040530.zip
Renamed package and application
Diffstat (limited to 'src/de/danoeh/antennapod/feed')
-rw-r--r--src/de/danoeh/antennapod/feed/Feed.java129
-rw-r--r--src/de/danoeh/antennapod/feed/FeedCategory.java20
-rw-r--r--src/de/danoeh/antennapod/feed/FeedComponent.java26
-rw-r--r--src/de/danoeh/antennapod/feed/FeedFile.java55
-rw-r--r--src/de/danoeh/antennapod/feed/FeedImage.java32
-rw-r--r--src/de/danoeh/antennapod/feed/FeedItem.java117
-rw-r--r--src/de/danoeh/antennapod/feed/FeedManager.java744
-rw-r--r--src/de/danoeh/antennapod/feed/FeedMedia.java73
-rw-r--r--src/de/danoeh/antennapod/feed/SimpleChapter.java22
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;
+
+
+}