From 11fb8589090d0715bb907b5f1e2c77644e3c86ff Mon Sep 17 00:00:00 2001 From: daniel oeh Date: Fri, 17 May 2013 23:20:23 +0200 Subject: [PATCH] Implemented several DBTasks and DBWriter methods --- .classpath | 1 + .../danoeh/antennapod/storage/DBReader.java | 15 ++ src/de/danoeh/antennapod/storage/DBTasks.java | 183 +++++++++++++++--- .../danoeh/antennapod/storage/DBWriter.java | 101 +++++++++- .../antennapod/storage/PodDBAdapter.java | 53 ++++- 5 files changed, 315 insertions(+), 38 deletions(-) diff --git a/.classpath b/.classpath index 3f9691c5d..3a0c88fe4 100644 --- a/.classpath +++ b/.classpath @@ -4,5 +4,6 @@ + diff --git a/src/de/danoeh/antennapod/storage/DBReader.java b/src/de/danoeh/antennapod/storage/DBReader.java index 97c52d749..739ecd4be 100644 --- a/src/de/danoeh/antennapod/storage/DBReader.java +++ b/src/de/danoeh/antennapod/storage/DBReader.java @@ -290,6 +290,21 @@ public final class DBReader { return items; } + + public static long[] getUnreadItemIds(Context context) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor cursor = adapter.getUnreadItemIdsCursor(); + long[] itemIds = new long[cursor.getCount()]; + int i = 0; + if (cursor.moveToFirst()) { + do { + itemIds[i] = cursor.getLong(PodDBAdapter.KEY_ID_INDEX); + i++; + } while (cursor.moveToNext()); + } + return itemIds; + } public static List getPlaybackHistory(final Context context) { if (AppConfig.DEBUG) diff --git a/src/de/danoeh/antennapod/storage/DBTasks.java b/src/de/danoeh/antennapod/storage/DBTasks.java index 75477d463..d71a5498b 100644 --- a/src/de/danoeh/antennapod/storage/DBTasks.java +++ b/src/de/danoeh/antennapod/storage/DBTasks.java @@ -1,29 +1,58 @@ package de.danoeh.antennapod.storage; +import java.util.Iterator; +import java.util.List; + import android.content.Context; +import android.content.Intent; +import android.util.Log; +import de.danoeh.antennapod.AppConfig; import de.danoeh.antennapod.feed.Feed; import de.danoeh.antennapod.feed.FeedItem; +import de.danoeh.antennapod.feed.FeedMedia; +import de.danoeh.antennapod.service.PlaybackService; +import de.danoeh.antennapod.util.exception.MediaFileNotFoundException; public final class DBTasks { private static final String TAG = "DBTasks"; - + private DBTasks() { } - public static void playMedia(final Context context, final long mediaId, + public static void playMedia(final Context context, final FeedMedia media, boolean showPlayer, boolean startWhenPrepared, boolean shouldStream) { - - } - - public static void markItemRead(final Context context, final long itemId, - final boolean read, boolean resetMediaPosition) { - } - - public static void markFeedRead(final Context context, final long feedId) { - - } - - public static void markAllItemsRead(final Context context) { + try { + if (!shouldStream) { + if (media.fileExists() == false) { + throw new MediaFileNotFoundException( + "No episode was found at " + media.getFile_url(), + media); + } + } + // Start playback Service + Intent launchIntent = new Intent(context, PlaybackService.class); + launchIntent.putExtra(PlaybackService.EXTRA_PLAYABLE, media); + launchIntent.putExtra(PlaybackService.EXTRA_START_WHEN_PREPARED, + startWhenPrepared); + launchIntent.putExtra(PlaybackService.EXTRA_SHOULD_STREAM, + shouldStream); + launchIntent.putExtra(PlaybackService.EXTRA_PREPARE_IMMEDIATELY, + true); + context.startService(launchIntent); + if (showPlayer) { + // Launch Mediaplayer + context.startActivity(PlaybackService.getPlayerActivityIntent( + context, media)); + } + DBWriter.addQueueItemAt(context, media.getItem().getId(), 0, false); + } catch (MediaFileNotFoundException e) { + e.printStackTrace(); + if (media.isPlaying()) { + context.sendBroadcast(new Intent( + PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE)); + } + notifyMissingFeedMediaFile(context, media); + } } public static void refreshAllFeeds(final Context context) { @@ -37,41 +66,137 @@ public final class DBTasks { } public static void notifyMissingFeedMediaFile(final Context context, - final long mediaId) { + final FeedMedia media) { + } + + public static void downloadAllItemsInQueue(final Context context) { } - - public static void downloadAllItemsInQueue(final Context context) {} public static void refreshFeed(final Context context, final long feedId) { } - - public static void downloadFeedItem(final Context context, long... itemIds) {} - + + public static void downloadFeedItem(final Context context, long... itemIds) { + } + static void downloadFeedItem(boolean performAutoCleanup, final Context context, final long... itemIds) - throws DownloadRequestException {} + throws DownloadRequestException { + } public static void autodownloadUndownloadedItems(Context context) { } - + private static int getPerformAutoCleanupArgs(final int episodeNumber) { return 0; } - - public static void performAutoCleanup(final Context context) {} - - private static int performAutoCleanup(final Context context, final int episodeNumber) { + + public static void performAutoCleanup(final Context context) { + } + + private static int performAutoCleanup(final Context context, + final int episodeNumber) { return 0; } - public static void enqueueAllNewItems(final Context context) {} + public static void enqueueAllNewItems(final Context context) { + long[] unreadItems = DBReader.getUnreadItemIds(context); + DBWriter.addQueueItem(context, unreadItems); + } - public static FeedItem getQueueSuccessorOfItem(final long itemId) { + public static FeedItem getQueueSuccessorOfItem(Context context, + final long itemId) { + FeedItem result = null; + List queue = DBReader.getQueue(context); + if (queue != null) { + Iterator iterator = queue.iterator(); + while (iterator.hasNext()) { + FeedItem item = iterator.next(); + if (item.getId() == itemId) { + if (iterator.hasNext()) { + result = iterator.next(); + } + break; + } + } + } + return result; + } + + private static Feed searchFeedByIdentifyingValue(Context context, + String identifier) { + List feeds = DBReader.getFeedList(context); + for (Feed feed : feeds) { + if (feed.getIdentifyingValue().equals(identifier)) { + return feed; + } + } return null; } - public static Feed updateFeed(final Context context, final long feedId) { + /** Get a FeedItem by its identifying value. */ + private static FeedItem searchFeedItemByIdentifyingValue(Feed feed, + String identifier) { + for (FeedItem item : feed.getItems()) { + if (item.getIdentifyingValue().equals(identifier)) { + return item; + } + } return null; } + + public static synchronized Feed updateFeed(final Context context, final Feed newFeed) { + // Look up feed in the feedslist + final Feed savedFeed = searchFeedByIdentifyingValue(context, + newFeed.getIdentifyingValue()); + if (savedFeed == null) { + if (AppConfig.DEBUG) + Log.d(TAG, + "Found no existing Feed with title " + + newFeed.getTitle() + ". Adding as new one."); + // Add a new Feed + DBWriter.addNewFeed(context, newFeed); + return newFeed; + } else { + if (AppConfig.DEBUG) + Log.d(TAG, "Feed with title " + newFeed.getTitle() + + " already exists. Syncing new with existing one."); + + savedFeed.setItems(DBReader.getFeedItemList(context, savedFeed)); + if (savedFeed.compareWithOther(newFeed)) { + if (AppConfig.DEBUG) + Log.d(TAG, + "Feed has updated attribute values. Updating old feed's attributes"); + savedFeed.updateFromOther(newFeed); + } + // Look for new or updated Items + for (int idx = 0; idx < newFeed.getItems().size(); idx++) { + final FeedItem item = newFeed.getItems().get(idx); + FeedItem oldItem = searchFeedItemByIdentifyingValue(savedFeed, + item.getIdentifyingValue()); + if (oldItem == null) { + // item is new + final int i = idx; + item.setFeed(savedFeed); + savedFeed.getItems().add(i, item); + DBWriter.markItemRead(context, item.getId(), false); + } else { + oldItem.updateFromOther(item); + } + } + // update attributes + savedFeed.setLastUpdate(newFeed.getLastUpdate()); + savedFeed.setType(newFeed.getType()); + DBWriter.setCompleteFeed(context, savedFeed); + new Thread() { + @Override + public void run() { + autodownloadUndownloadedItems(context); + } + }.start(); + return savedFeed; + } + + } + } diff --git a/src/de/danoeh/antennapod/storage/DBWriter.java b/src/de/danoeh/antennapod/storage/DBWriter.java index 996c3e028..aece811ca 100644 --- a/src/de/danoeh/antennapod/storage/DBWriter.java +++ b/src/de/danoeh/antennapod/storage/DBWriter.java @@ -10,6 +10,7 @@ import java.util.concurrent.ThreadFactory; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.database.Cursor; import android.preference.PreferenceManager; import android.util.Log; import de.danoeh.antennapod.AppConfig; @@ -406,7 +407,76 @@ public class DBWriter { }); } - void addNewFeed(final Context context, final Feed feed) { + public static void markItemRead(final Context context, final long itemId, + final boolean read) { + markItemRead(context, itemId, read, 0, false); + } + + public static void markItemRead(final Context context, final long itemId, + final boolean read, final long mediaId, + final boolean resetMediaPosition) { + dbExec.submit(new Runnable() { + + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setFeedItemRead(read, itemId, mediaId, + resetMediaPosition); + adapter.close(); + + EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); + } + }); + } + + public static void markFeedRead(final Context context, final long feedId) { + dbExec.submit(new Runnable() { + + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor itemCursor = adapter.getAllItemsOfFeedCursor(feedId); + long[] itemIds = new long[itemCursor.getCount()]; + itemCursor.moveToFirst(); + for (int i = 0; i < itemIds.length; i++) { + itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX); + } + itemCursor.close(); + adapter.setFeedItemRead(true, itemIds); + adapter.close(); + + EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); + } + }); + + } + + public static void markAllItemsRead(final Context context) { + dbExec.submit(new Runnable() { + + @Override + public void run() { + final PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + Cursor itemCursor = adapter.getUnreadItemsCursor(); + long[] itemIds = new long[itemCursor.getCount()]; + itemCursor.moveToFirst(); + for (int i = 0; i < itemIds.length; i++) { + itemIds[i] = itemCursor.getLong(PodDBAdapter.KEY_ID_INDEX); + } + itemCursor.close(); + adapter.setFeedItemRead(true, itemIds); + adapter.close(); + + EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast(); + } + }); + + } + + static void addNewFeed(final Context context, final Feed feed) { dbExec.submit(new Runnable() { @Override @@ -420,13 +490,34 @@ public class DBWriter { } }); } + + static void setCompleteFeed(final Context context, final Feed feed) { + dbExec.submit(new Runnable() { + + @Override + public void run() { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setCompleteFeed(feed); + adapter.close(); + + EventDistributor.getInstance().sendFeedUpdateBroadcast(); + }}); + + } private static void setFeedMedia(final Context context, final FeedMedia media) { - PodDBAdapter adapter = new PodDBAdapter(context); - adapter.open(); - adapter.setMedia(media); - adapter.close(); + dbExec.submit(new Runnable() { + + @Override + public void run() { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setMedia(media); + adapter.close(); + }}); + } diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java index ef9b4bfe0..72c96b961 100644 --- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java +++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java @@ -340,7 +340,7 @@ public class PodDBAdapter { db.setTransactionSuccessful(); db.endTransaction(); } - + public void setFeedItemlist(List items) { db.beginTransaction(); for (FeedItem item : items) { @@ -400,6 +400,39 @@ public class PodDBAdapter { return item.getId(); } + public void setFeedItemRead(boolean read, long itemId, long mediaId, + boolean resetMediaPosition) { + db.beginTransaction(); + ContentValues values = new ContentValues(); + + values.put(KEY_READ, read); + db.update(TABLE_NAME_FEED_ITEMS, values, "?=?", new String[] { KEY_ID, + Long.toString(itemId) }); + + if (resetMediaPosition) { + values.clear(); + values.put(KEY_POSITION, 0); + db.update(TABLE_NAME_FEED_MEDIA, values, "?=?", new String[] { + KEY_ID, Long.toString(mediaId) }); + } + + db.setTransactionSuccessful(); + db.endTransaction(); + } + + public void setFeedItemRead(boolean read, long... itemIds) { + db.beginTransaction(); + ContentValues values = new ContentValues(); + for (long id : itemIds) { + values.clear(); + values.put(KEY_READ, read); + db.update(TABLE_NAME_FEED_ITEMS, values, "?=?", new String[] { + KEY_ID, Long.toString(id) }); + } + db.setTransactionSuccessful(); + db.endTransaction(); + } + public void setChapters(FeedItem item) { ContentValues values = new ContentValues(); for (Chapter chapter : item.getChapters()) { @@ -479,7 +512,7 @@ public class PodDBAdapter { db.setTransactionSuccessful(); db.endTransaction(); } - + public void clearQueue() { db.delete(TABLE_NAME_QUEUE, null, null); } @@ -557,10 +590,14 @@ public class PodDBAdapter { * @return The cursor of the query * */ public final Cursor getAllItemsOfFeedCursor(final Feed feed) { + return getAllItemsOfFeedCursor(feed.getId()); + } + + public final Cursor getAllItemsOfFeedCursor(final long feedId) { open(); Cursor c = db.query(TABLE_NAME_FEED_ITEMS, SEL_FI_SMALL, KEY_FEED - + "=?", new String[] { String.valueOf(feed.getId()) }, null, - null, null); + + "=?", new String[] { String.valueOf(feedId) }, null, null, + null); return c; } @@ -642,6 +679,14 @@ public class PodDBAdapter { + "=0", null, null, null, KEY_PUBDATE + " DESC"); return c; } + + public final Cursor getUnreadItemIdsCursor() { + open(); + Cursor c = db.query(TABLE_NAME_FEED_ITEMS, new String[]{KEY_ID}, KEY_READ + + "=0", null, null, null, KEY_PUBDATE + " DESC"); + return c; + + } /** * Returns a cursor which contains feed media objects with a playback