diff options
author | daniel oeh <daniel.oeh@gmail.com> | 2013-08-03 13:58:31 +0200 |
---|---|---|
committer | daniel oeh <daniel.oeh@gmail.com> | 2013-08-03 13:58:31 +0200 |
commit | 9ba3dc0d823b786700010a60d38f47c802101d27 (patch) | |
tree | 89b74eff993fdcb3b373c64695c72d534f1a80cd /src/de/danoeh/antennapod/storage | |
parent | 2071793e6aa1a106744078fcbcf7c0529ed315c4 (diff) | |
download | AntennaPod-9ba3dc0d823b786700010a60d38f47c802101d27.zip |
Improved DownloadService, several bugfixes
- DownloadService should now terminate properly as soon as all downloads have been completed.
- Notification bug ("0 downloads left" notification) should be fixed
Diffstat (limited to 'src/de/danoeh/antennapod/storage')
-rw-r--r-- | src/de/danoeh/antennapod/storage/DBReader.java | 97 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/DBTasks.java | 23 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/DBWriter.java | 8 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/DownloadRequester.java | 540 | ||||
-rw-r--r-- | src/de/danoeh/antennapod/storage/PodDBAdapter.java | 41 |
5 files changed, 397 insertions, 312 deletions
diff --git a/src/de/danoeh/antennapod/storage/DBReader.java b/src/de/danoeh/antennapod/storage/DBReader.java index c8135bea1..c69607473 100644 --- a/src/de/danoeh/antennapod/storage/DBReader.java +++ b/src/de/danoeh/antennapod/storage/DBReader.java @@ -188,41 +188,45 @@ public final class DBReader { List<FeedItem> items, ArrayList<String> itemIds) { List<FeedItem> itemsCopy = new ArrayList<FeedItem>(items); - Cursor cursor = adapter.getFeedMediaCursor(itemIds - .toArray(new String[itemIds.size()])); + Cursor cursor = adapter.getFeedMediaCursorByItemID(itemIds + .toArray(new String[itemIds.size()])); if (cursor.moveToFirst()) { do { - long mediaId = cursor.getLong(PodDBAdapter.KEY_ID_INDEX); long itemId = cursor.getLong(PodDBAdapter.KEY_MEDIA_FEEDITEM_INDEX); // find matching feed item FeedItem item = getMatchingItemForMedia(itemId, itemsCopy); if (item != null) { - Date playbackCompletionDate = null; - long playbackCompletionTime = cursor - .getLong(PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE_INDEX); - if (playbackCompletionTime > 0) { - playbackCompletionDate = new Date( - playbackCompletionTime); - } - - item.setMedia(new FeedMedia( - mediaId, - item, - cursor.getInt(PodDBAdapter.KEY_DURATION_INDEX), - cursor.getInt(PodDBAdapter.KEY_POSITION_INDEX), - cursor.getLong(PodDBAdapter.KEY_SIZE_INDEX), - cursor.getString(PodDBAdapter.KEY_MIME_TYPE_INDEX), - cursor.getString(PodDBAdapter.KEY_FILE_URL_INDEX), - cursor.getString(PodDBAdapter.KEY_DOWNLOAD_URL_INDEX), - cursor.getInt(PodDBAdapter.KEY_DOWNLOADED_INDEX) > 0, - playbackCompletionDate)); - + item.setMedia(extractFeedMediaFromCursorRow(cursor)); + item.getMedia().setItem(item); } } while (cursor.moveToNext()); cursor.close(); } } + private static FeedMedia extractFeedMediaFromCursorRow(final Cursor cursor) { + long mediaId = cursor.getLong(PodDBAdapter.KEY_ID_INDEX); + Date playbackCompletionDate = null; + long playbackCompletionTime = cursor + .getLong(PodDBAdapter.KEY_PLAYBACK_COMPLETION_DATE_INDEX); + if (playbackCompletionTime > 0) { + playbackCompletionDate = new Date( + playbackCompletionTime); + } + + return new FeedMedia( + mediaId, + null, + cursor.getInt(PodDBAdapter.KEY_DURATION_INDEX), + cursor.getInt(PodDBAdapter.KEY_POSITION_INDEX), + cursor.getLong(PodDBAdapter.KEY_SIZE_INDEX), + cursor.getString(PodDBAdapter.KEY_MIME_TYPE_INDEX), + cursor.getString(PodDBAdapter.KEY_FILE_URL_INDEX), + cursor.getString(PodDBAdapter.KEY_DOWNLOAD_URL_INDEX), + cursor.getInt(PodDBAdapter.KEY_DOWNLOADED_INDEX) > 0, + playbackCompletionDate); + } + private static Feed extractFeedFromCursorRow(PodDBAdapter adapter, Cursor cursor) { Date lastUpdate = new Date( @@ -481,6 +485,21 @@ public final class DBReader { return result; } + /** + * Searches the DB for a FeedImage of the given id. + * + * @param imageId + * The id of the object + * @return The found object + * */ + public static FeedImage getFeedImage(final Context context, final long imageId) { + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + FeedImage result = getFeedImage(adapter, imageId); + adapter.close(); + return result; + } + /** * Searches the DB for a FeedImage of the given id. * @@ -488,7 +507,7 @@ public final class DBReader { * The id of the object * @return The found object * */ - public static FeedImage getFeedImage(PodDBAdapter adapter, final long id) { + static FeedImage getFeedImage(PodDBAdapter adapter, final long id) { Cursor cursor = adapter.getImageOfFeedCursor(id); if ((cursor.getCount() == 0) || !cursor.moveToFirst()) { throw new SQLException("No FeedImage found at index: " + id); @@ -504,4 +523,34 @@ public final class DBReader { cursor.close(); return image; } + + /** + * Searches the DB for a FeedMedia of the given id. + * + * @param mediaId + * The id of the object + * @return The found object + * */ + public static FeedMedia getFeedMedia(final Context context, final long mediaId) { + PodDBAdapter adapter = new PodDBAdapter(context); + + adapter.open(); + Cursor mediaCursor = adapter.getSingleFeedMediaCursor(mediaId); + + FeedMedia media = null; + if (mediaCursor.moveToFirst()) { + final long itemId = mediaCursor.getLong(PodDBAdapter.KEY_MEDIA_FEEDITEM_INDEX); + media = extractFeedMediaFromCursorRow(mediaCursor); + FeedItem item = getFeedItem(context, itemId); + if (media != null && item != null) { + media.setItem(item); + item.setMedia(media); + } + } + + mediaCursor.close(); + adapter.close(); + + return media; + } } diff --git a/src/de/danoeh/antennapod/storage/DBTasks.java b/src/de/danoeh/antennapod/storage/DBTasks.java index 39c30445e..45ce4298a 100644 --- a/src/de/danoeh/antennapod/storage/DBTasks.java +++ b/src/de/danoeh/antennapod/storage/DBTasks.java @@ -7,6 +7,7 @@ import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.concurrent.ExecutionException; import java.util.concurrent.locks.ReentrantLock; import android.content.Context; @@ -25,6 +26,7 @@ import de.danoeh.antennapod.service.PlaybackService; import de.danoeh.antennapod.service.download.DownloadStatus; import de.danoeh.antennapod.util.DownloadError; import de.danoeh.antennapod.util.NetworkUtils; +import de.danoeh.antennapod.util.QueueAccess; import de.danoeh.antennapod.util.exception.MediaFileNotFoundException; public final class DBTasks { @@ -397,6 +399,11 @@ public final class DBTasks { return result; } + public static boolean isInQueue(Context context, final long feedItemId) { + List<Long> queue = DBReader.getQueueIDList(context); + return QueueAccess.IDListAccess(queue).contains(feedItemId); + } + private static Feed searchFeedByIdentifyingValue(Context context, String identifier) { List<Feed> feeds = DBReader.getFeedList(context); @@ -430,7 +437,13 @@ public final class DBTasks { "Found no existing Feed with title " + newFeed.getTitle() + ". Adding as new one."); // Add a new Feed - DBWriter.addNewFeed(context, newFeed); + try { + DBWriter.addNewFeed(context, newFeed).get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } return newFeed; } else { if (AppConfig.DEBUG) @@ -462,7 +475,13 @@ public final class DBTasks { // update attributes savedFeed.setLastUpdate(newFeed.getLastUpdate()); savedFeed.setType(newFeed.getType()); - DBWriter.setCompleteFeed(context, savedFeed); + try { + DBWriter.setCompleteFeed(context, savedFeed).get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } new Thread() { @Override public void run() { diff --git a/src/de/danoeh/antennapod/storage/DBWriter.java b/src/de/danoeh/antennapod/storage/DBWriter.java index 76f6306f8..a60694f35 100644 --- a/src/de/danoeh/antennapod/storage/DBWriter.java +++ b/src/de/danoeh/antennapod/storage/DBWriter.java @@ -488,8 +488,8 @@ public class DBWriter { } - static void addNewFeed(final Context context, final Feed feed) { - dbExec.submit(new Runnable() { + static Future<?> addNewFeed(final Context context, final Feed feed) { + return dbExec.submit(new Runnable() { @Override public void run() { @@ -503,8 +503,8 @@ public class DBWriter { }); } - static void setCompleteFeed(final Context context, final Feed feed) { - dbExec.submit(new Runnable() { + static Future<?> setCompleteFeed(final Context context, final Feed feed) { + return dbExec.submit(new Runnable() { @Override public void run() { diff --git a/src/de/danoeh/antennapod/storage/DownloadRequester.java b/src/de/danoeh/antennapod/storage/DownloadRequester.java index a27fbf8e4..4e74d5e98 100644 --- a/src/de/danoeh/antennapod/storage/DownloadRequester.java +++ b/src/de/danoeh/antennapod/storage/DownloadRequester.java @@ -24,273 +24,277 @@ import de.danoeh.antennapod.util.FileNameGenerator; import de.danoeh.antennapod.util.URLChecker; public class DownloadRequester { - private static final String TAG = "DownloadRequester"; - - public static String IMAGE_DOWNLOADPATH = "images/"; - public static String FEED_DOWNLOADPATH = "cache/"; - public static String MEDIA_DOWNLOADPATH = "media/"; - - private static DownloadRequester downloader; - - Map<String, DownloadRequest> downloads; - - private DownloadRequester() { - downloads = new ConcurrentHashMap<String, DownloadRequest>(); - } - - public static DownloadRequester getInstance() { - if (downloader == null) { - downloader = new DownloadRequester(); - } - return downloader; - } - - private void download(Context context, FeedFile item, File dest, - boolean overwriteIfExists) { - if (!isDownloadingFile(item)) { - if (!isFilenameAvailable(dest.toString()) || dest.exists()) { - if (AppConfig.DEBUG) - Log.d(TAG, "Filename already used."); - if (isFilenameAvailable(dest.toString()) && overwriteIfExists) { - boolean result = dest.delete(); - if (AppConfig.DEBUG) - Log.d(TAG, "Deleting file. Result: " + result); - } else { - // find different name - File newDest = null; - for (int i = 1; i < Integer.MAX_VALUE; i++) { - String newName = FilenameUtils.getBaseName(dest - .getName()) - + "-" - + i - + "." - + FilenameUtils.getExtension(dest.getName()); - if (AppConfig.DEBUG) - Log.d(TAG, "Testing filename " + newName); - newDest = new File(dest.getParent(), newName); - if (!newDest.exists() - && isFilenameAvailable(newDest.toString())) { - if (AppConfig.DEBUG) - Log.d(TAG, "File doesn't exist yet. Using " - + newName); - break; - } - } - if (newDest != null) { - dest = newDest; - } - } - } - if (AppConfig.DEBUG) - Log.d(TAG, - "Requesting download of url " + item.getDownload_url()); - item.setDownload_url(URLChecker.prepareURL(item.getDownload_url())); - - DownloadRequest request = new DownloadRequest(dest.toString(), - item.getDownload_url(), item.getHumanReadableIdentifier(), - item.getId(), item.getTypeAsInt()); - - downloads.put(request.getSource(), request); - - - if (!DownloadService.isRunning) { - Intent launchIntent = new Intent(context, DownloadService.class); - launchIntent.putExtra(DownloadService.EXTRA_REQUEST, request); - context.startService(launchIntent); - } else { - Intent queueIntent = new Intent( - DownloadService.ACTION_ENQUEUE_DOWNLOAD); - queueIntent.putExtra(DownloadService.EXTRA_REQUEST, request); - context.sendBroadcast(queueIntent); - } - EventDistributor.getInstance().sendDownloadQueuedBroadcast(); - } else { - Log.e(TAG, "URL " + item.getDownload_url() - + " is already being downloaded"); - } - } - - /** - * Returns true if a filename is available and false if it has already been - * taken by another requested download. - */ - private boolean isFilenameAvailable(String path) { - for (String key : downloads.keySet()) { - DownloadRequest r = downloads.get(key); - if (StringUtils.equals(r.getDestination(), path)) { - if (AppConfig.DEBUG) - Log.d(TAG, path - + " is already used by another requested download"); - return false; - } - } - if (AppConfig.DEBUG) - Log.d(TAG, path + " is available as a download destination"); - return true; - } - - public void downloadFeed(Context context, Feed feed) - throws DownloadRequestException { - if (feedFileValid(feed)) { - download(context, feed, new File(getFeedfilePath(context), - getFeedfileName(feed)), true); - } - } - - public void downloadImage(Context context, FeedImage image) - throws DownloadRequestException { - if (feedFileValid(image)) { - download(context, image, new File(getImagefilePath(context), - getImagefileName(image)), true); - } - } - - public void downloadMedia(Context context, FeedMedia feedmedia) - throws DownloadRequestException { - if (feedFileValid(feedmedia)) { - download(context, feedmedia, - new File(getMediafilePath(context, feedmedia), - getMediafilename(feedmedia)), false); - } - } - - /** - * Throws a DownloadRequestException if the feedfile or the download url of - * the feedfile is null. - * - * @throws DownloadRequestException - */ - private boolean feedFileValid(FeedFile f) throws DownloadRequestException { - if (f == null) { - throw new DownloadRequestException("Feedfile was null"); - } else if (f.getDownload_url() == null) { - throw new DownloadRequestException("File has no download URL"); - } else { - return true; - } - } - - /** - * Cancels a running download. - * */ - public void cancelDownload(final Context context, final FeedFile f) { - cancelDownload(context, f.getDownload_url()); - } - - /** - * Cancels a running download. - * */ - public void cancelDownload(final Context context, final String downloadUrl) { - if (AppConfig.DEBUG) - Log.d(TAG, "Cancelling download with url " + downloadUrl); - Intent cancelIntent = new Intent(DownloadService.ACTION_CANCEL_DOWNLOAD); - cancelIntent.putExtra(DownloadService.EXTRA_DOWNLOAD_URL, downloadUrl); - context.sendBroadcast(cancelIntent); - } - - /** Cancels all running downloads */ - public void cancelAllDownloads(Context context) { - if (AppConfig.DEBUG) - Log.d(TAG, "Cancelling all running downloads"); - context.sendBroadcast(new Intent( - DownloadService.ACTION_CANCEL_ALL_DOWNLOADS)); - } - - /** Returns true if there is at least one Feed in the downloads queue. */ - public boolean isDownloadingFeeds() { - for (DownloadRequest r : downloads.values()) { - if (r.getFeedfileType() == Feed.FEEDFILETYPE_FEED) { - return true; - } - } - return false; - } - - /** Checks if feedfile is in the downloads list */ - public boolean isDownloadingFile(FeedFile item) { - if (item.getDownload_url() != null) { - return downloads.containsKey(item.getDownload_url()); - } - return false; - } - - public DownloadRequest getDownload(String downloadUrl) { - return downloads.get(downloadUrl); - } - - /** Checks if feedfile with the given download url is in the downloads list */ - public boolean isDownloadingFile(String downloadUrl) { - return downloads.get(downloadUrl) != null; - } - - public boolean hasNoDownloads() { - return downloads.isEmpty(); - } - - /** Remove an object from the downloads-list of the requester. */ - public void removeDownload(DownloadRequest r) { - if (downloads.remove(r.getSource()) == null) { - Log.e(TAG, - "Could not remove object with url " + r.getSource()); - } - } - - /** Get the number of uncompleted Downloads */ - public int getNumberOfDownloads() { - return downloads.size(); - } - - public String getFeedfilePath(Context context) - throws DownloadRequestException { - return getExternalFilesDirOrThrowException(context, FEED_DOWNLOADPATH) - .toString() + "/"; - } - - public String getFeedfileName(Feed feed) { - String filename = feed.getDownload_url(); - if (feed.getTitle() != null && !feed.getTitle().isEmpty()) { - filename = feed.getTitle(); - } - return "feed-" + FileNameGenerator.generateFileName(filename); - } - - public String getImagefilePath(Context context) - throws DownloadRequestException { - return getExternalFilesDirOrThrowException(context, IMAGE_DOWNLOADPATH) - .toString() + "/"; - } - - public String getImagefileName(FeedImage image) { - String filename = image.getDownload_url(); - if (image.getFeed() != null && image.getFeed().getTitle() != null) { - filename = image.getFeed().getTitle(); - } - return "image-" + FileNameGenerator.generateFileName(filename); - } - - public String getMediafilePath(Context context, FeedMedia media) - throws DownloadRequestException { - File externalStorage = getExternalFilesDirOrThrowException( - context, - MEDIA_DOWNLOADPATH - + FileNameGenerator.generateFileName(media.getItem() - .getFeed().getTitle()) + "/"); - return externalStorage.toString(); - } - - private File getExternalFilesDirOrThrowException(Context context, - String type) throws DownloadRequestException { - File result = UserPreferences.getDataFolder(context, type); - if (result == null) { - throw new DownloadRequestException( - "Failed to access external storage"); - } - return result; - } - - public String getMediafilename(FeedMedia media) { - return URLUtil.guessFileName(media.getDownload_url(), null, - media.getMime_type()); - } + private static final String TAG = "DownloadRequester"; + + public static String IMAGE_DOWNLOADPATH = "images/"; + public static String FEED_DOWNLOADPATH = "cache/"; + public static String MEDIA_DOWNLOADPATH = "media/"; + + private static DownloadRequester downloader; + + Map<String, DownloadRequest> downloads; + + private DownloadRequester() { + downloads = new ConcurrentHashMap<String, DownloadRequest>(); + } + + public static DownloadRequester getInstance() { + if (downloader == null) { + downloader = new DownloadRequester(); + } + return downloader; + } + + private void download(Context context, FeedFile item, File dest, + boolean overwriteIfExists) { + if (!isDownloadingFile(item)) { + if (!isFilenameAvailable(dest.toString()) || dest.exists()) { + if (AppConfig.DEBUG) + Log.d(TAG, "Filename already used."); + if (isFilenameAvailable(dest.toString()) && overwriteIfExists) { + boolean result = dest.delete(); + if (AppConfig.DEBUG) + Log.d(TAG, "Deleting file. Result: " + result); + } else { + // find different name + File newDest = null; + for (int i = 1; i < Integer.MAX_VALUE; i++) { + String newName = FilenameUtils.getBaseName(dest + .getName()) + + "-" + + i + + "." + + FilenameUtils.getExtension(dest.getName()); + if (AppConfig.DEBUG) + Log.d(TAG, "Testing filename " + newName); + newDest = new File(dest.getParent(), newName); + if (!newDest.exists() + && isFilenameAvailable(newDest.toString())) { + if (AppConfig.DEBUG) + Log.d(TAG, "File doesn't exist yet. Using " + + newName); + break; + } + } + if (newDest != null) { + dest = newDest; + } + } + } + if (AppConfig.DEBUG) + Log.d(TAG, + "Requesting download of url " + item.getDownload_url()); + item.setDownload_url(URLChecker.prepareURL(item.getDownload_url())); + + DownloadRequest request = new DownloadRequest(dest.toString(), + item.getDownload_url(), item.getHumanReadableIdentifier(), + item.getId(), item.getTypeAsInt()); + + downloads.put(request.getSource(), request); + + Intent launchIntent = new Intent(context, DownloadService.class); + launchIntent.putExtra(DownloadService.EXTRA_REQUEST, request); + context.startService(launchIntent); + EventDistributor.getInstance().sendDownloadQueuedBroadcast(); + } else { + Log.e(TAG, "URL " + item.getDownload_url() + + " is already being downloaded"); + } + } + + /** + * Returns true if a filename is available and false if it has already been + * taken by another requested download. + */ + private boolean isFilenameAvailable(String path) { + for (String key : downloads.keySet()) { + DownloadRequest r = downloads.get(key); + if (StringUtils.equals(r.getDestination(), path)) { + if (AppConfig.DEBUG) + Log.d(TAG, path + + " is already used by another requested download"); + return false; + } + } + if (AppConfig.DEBUG) + Log.d(TAG, path + " is available as a download destination"); + return true; + } + + public void downloadFeed(Context context, Feed feed) + throws DownloadRequestException { + if (feedFileValid(feed)) { + download(context, feed, new File(getFeedfilePath(context), + getFeedfileName(feed)), true); + } + } + + public void downloadImage(Context context, FeedImage image) + throws DownloadRequestException { + if (feedFileValid(image)) { + download(context, image, new File(getImagefilePath(context), + getImagefileName(image)), true); + } + } + + public void downloadMedia(Context context, FeedMedia feedmedia) + throws DownloadRequestException { + if (feedFileValid(feedmedia)) { + download(context, feedmedia, + new File(getMediafilePath(context, feedmedia), + getMediafilename(feedmedia)), false); + } + } + + /** + * Throws a DownloadRequestException if the feedfile or the download url of + * the feedfile is null. + * + * @throws DownloadRequestException + */ + private boolean feedFileValid(FeedFile f) throws DownloadRequestException { + if (f == null) { + throw new DownloadRequestException("Feedfile was null"); + } else if (f.getDownload_url() == null) { + throw new DownloadRequestException("File has no download URL"); + } else { + return true; + } + } + + /** + * Cancels a running download. + */ + public void cancelDownload(final Context context, final FeedFile f) { + cancelDownload(context, f.getDownload_url()); + } + + /** + * Cancels a running download. + */ + public void cancelDownload(final Context context, final String downloadUrl) { + if (AppConfig.DEBUG) + Log.d(TAG, "Cancelling download with url " + downloadUrl); + Intent cancelIntent = new Intent(DownloadService.ACTION_CANCEL_DOWNLOAD); + cancelIntent.putExtra(DownloadService.EXTRA_DOWNLOAD_URL, downloadUrl); + context.sendBroadcast(cancelIntent); + } + + /** + * Cancels all running downloads + */ + public void cancelAllDownloads(Context context) { + if (AppConfig.DEBUG) + Log.d(TAG, "Cancelling all running downloads"); + context.sendBroadcast(new Intent( + DownloadService.ACTION_CANCEL_ALL_DOWNLOADS)); + } + + /** + * Returns true if there is at least one Feed in the downloads queue. + */ + public boolean isDownloadingFeeds() { + for (DownloadRequest r : downloads.values()) { + if (r.getFeedfileType() == Feed.FEEDFILETYPE_FEED) { + return true; + } + } + return false; + } + + /** + * Checks if feedfile is in the downloads list + */ + public boolean isDownloadingFile(FeedFile item) { + if (item.getDownload_url() != null) { + return downloads.containsKey(item.getDownload_url()); + } + return false; + } + + public DownloadRequest getDownload(String downloadUrl) { + return downloads.get(downloadUrl); + } + + /** + * Checks if feedfile with the given download url is in the downloads list + */ + public boolean isDownloadingFile(String downloadUrl) { + return downloads.get(downloadUrl) != null; + } + + public boolean hasNoDownloads() { + return downloads.isEmpty(); + } + + /** + * Remove an object from the downloads-list of the requester. + */ + public void removeDownload(DownloadRequest r) { + if (downloads.remove(r.getSource()) == null) { + Log.e(TAG, + "Could not remove object with url " + r.getSource()); + } + } + + /** + * Get the number of uncompleted Downloads + */ + public int getNumberOfDownloads() { + return downloads.size(); + } + + public String getFeedfilePath(Context context) + throws DownloadRequestException { + return getExternalFilesDirOrThrowException(context, FEED_DOWNLOADPATH) + .toString() + "/"; + } + + public String getFeedfileName(Feed feed) { + String filename = feed.getDownload_url(); + if (feed.getTitle() != null && !feed.getTitle().isEmpty()) { + filename = feed.getTitle(); + } + return "feed-" + FileNameGenerator.generateFileName(filename); + } + + public String getImagefilePath(Context context) + throws DownloadRequestException { + return getExternalFilesDirOrThrowException(context, IMAGE_DOWNLOADPATH) + .toString() + "/"; + } + + public String getImagefileName(FeedImage image) { + String filename = image.getDownload_url(); + if (image.getFeed() != null && image.getFeed().getTitle() != null) { + filename = image.getFeed().getTitle(); + } + return "image-" + FileNameGenerator.generateFileName(filename); + } + + public String getMediafilePath(Context context, FeedMedia media) + throws DownloadRequestException { + File externalStorage = getExternalFilesDirOrThrowException( + context, + MEDIA_DOWNLOADPATH + + FileNameGenerator.generateFileName(media.getItem() + .getFeed().getTitle()) + "/"); + return externalStorage.toString(); + } + + private File getExternalFilesDirOrThrowException(Context context, + String type) throws DownloadRequestException { + File result = UserPreferences.getDataFolder(context, type); + if (result == null) { + throw new DownloadRequestException( + "Failed to access external storage"); + } + return result; + } + + public String getMediafilename(FeedMedia media) { + return URLUtil.guessFileName(media.getDownload_url(), null, + media.getMime_type()); + } } diff --git a/src/de/danoeh/antennapod/storage/PodDBAdapter.java b/src/de/danoeh/antennapod/storage/PodDBAdapter.java index 1aa8c93d4..14ef07c34 100644 --- a/src/de/danoeh/antennapod/storage/PodDBAdapter.java +++ b/src/de/danoeh/antennapod/storage/PodDBAdapter.java @@ -201,6 +201,13 @@ public class PodDBAdapter { TABLE_NAME_FEED_ITEMS + "." + KEY_HAS_CHAPTERS, TABLE_NAME_FEED_ITEMS + "." + KEY_ITEM_IDENTIFIER }; + /** Contains SEL_FI_SMALL as comma-separated list. Useful for raw queries. */ + private static final String SEL_FI_SMALL_STR; + static { + String selFiSmall = Arrays.toString(SEL_FI_SMALL); + SEL_FI_SMALL_STR = selFiSmall.substring(1, selFiSmall.length() - 1); + } + // column indices for SEL_FI_SMALL public static final int IDX_FI_SMALL_ID = 0; @@ -601,7 +608,7 @@ public class PodDBAdapter { public final Cursor getAllFeedsCursor() { open(); Cursor c = db.query(TABLE_NAME_FEEDS, null, null, null, null, null, - null); + KEY_TITLE + " ASC"); return c; } @@ -692,9 +699,8 @@ public class PodDBAdapter { */ public final Cursor getQueueCursor() { open(); - String selFiSmall = Arrays.toString(SEL_FI_SMALL); Object[] args = (Object[]) new String[] { - selFiSmall.substring(1, selFiSmall.length() - 1) + "," + TABLE_NAME_QUEUE + "." + KEY_ID, + SEL_FI_SMALL_STR + "," + TABLE_NAME_QUEUE + "." + KEY_ID, TABLE_NAME_FEED_ITEMS, TABLE_NAME_QUEUE, TABLE_NAME_FEED_ITEMS + "." + KEY_ID, TABLE_NAME_QUEUE + "." + KEY_FEEDITEM, @@ -738,12 +744,12 @@ public class PodDBAdapter { public Cursor getDownloadedItemsCursor() { open(); - Cursor c = db.rawQuery("SELECT ? FROM " + TABLE_NAME_FEED_ITEMS - + "FULL JOIN " + TABLE_NAME_FEED_MEDIA + " ON " - + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "=" - + TABLE_NAME_FEED_MEDIA + "." + KEY_ID + " WHERE " - + TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOADED + ">0", - SEL_FI_SMALL); + final String query = "SELECT " + SEL_FI_SMALL_STR + " FROM " + TABLE_NAME_FEED_ITEMS + + " INNER JOIN " + TABLE_NAME_FEED_MEDIA + " ON " + + TABLE_NAME_FEED_ITEMS + "." + KEY_ID + "=" + + TABLE_NAME_FEED_MEDIA + "." + KEY_ID + " WHERE " + + TABLE_NAME_FEED_MEDIA + "." + KEY_DOWNLOADED + ">0"; + Cursor c = db.rawQuery(query, null); return c; } @@ -768,7 +774,11 @@ public class PodDBAdapter { return c; } - public final Cursor getFeedMediaCursor(String... mediaIds) { + public final Cursor getSingleFeedMediaCursor(long id) { + return db.query(TABLE_NAME_FEED_MEDIA, null, KEY_ID + "=?", new String[] {Long.toString(id)}, null, null, null); + } + + public final Cursor getFeedMediaCursorByItemID(String... mediaIds) { int length = mediaIds.length; if (length > IN_OPERATOR_MAXIMUM) { Log.w(TAG, "Length of id array is larger than " @@ -837,11 +847,14 @@ public class PodDBAdapter { } public final int getNumberOfDownloadedEpisodes() { + final String query = "SELECT COUNT(DISTINCT " + KEY_ID + ") AS count FROM " + TABLE_NAME_FEED_MEDIA + + " WHERE " + KEY_DOWNLOADED + " > 0"; - Cursor c = db.rawQuery( - "SELECT COUNT(DISTINCT ?) AS count FROM ? WHERE ?>0", - new String[] { KEY_ID, TABLE_NAME_FEED_MEDIA, KEY_DOWNLOADED }); - final int result = c.getInt(0); + Cursor c = db.rawQuery(query, null); + int result = 0; + if (c.moveToFirst()) { + result = c.getInt(0); + } c.close(); return result; } |