use of de.danoeh.antennapod.core.service.download.DownloadStatus in project AntennaPod by AntennaPod.
the class FeedParserTask method call.
@Override
public FeedHandlerResult call() {
Feed feed = new Feed(request.getSource(), request.getLastModified());
feed.setFile_url(request.getDestination());
feed.setId(request.getFeedfileId());
feed.setDownloaded(true);
feed.setPreferences(new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL, VolumeAdaptionSetting.OFF, request.getUsername(), request.getPassword()));
feed.setPageNr(request.getArguments().getInt(DownloadRequest.REQUEST_ARG_PAGE_NR, 0));
DownloadError reason = null;
String reasonDetailed = null;
FeedHandler feedHandler = new FeedHandler();
FeedHandlerResult result = null;
try {
result = feedHandler.parseFeed(feed);
Log.d(TAG, feed.getTitle() + " parsed");
checkFeedData(feed);
} catch (SAXException | IOException | ParserConfigurationException e) {
successful = false;
e.printStackTrace();
reason = DownloadError.ERROR_PARSER_EXCEPTION;
reasonDetailed = e.getMessage();
} catch (UnsupportedFeedtypeException e) {
e.printStackTrace();
successful = false;
reason = DownloadError.ERROR_UNSUPPORTED_TYPE;
if ("html".equalsIgnoreCase(e.getRootElement())) {
reason = DownloadError.ERROR_UNSUPPORTED_TYPE_HTML;
}
reasonDetailed = e.getMessage();
} catch (InvalidFeedException e) {
e.printStackTrace();
successful = false;
reason = DownloadError.ERROR_PARSER_EXCEPTION;
reasonDetailed = e.getMessage();
} finally {
File feedFile = new File(request.getDestination());
if (feedFile.exists()) {
boolean deleted = feedFile.delete();
Log.d(TAG, "Deletion of file '" + feedFile.getAbsolutePath() + "' " + (deleted ? "successful" : "FAILED"));
}
}
if (successful) {
downloadStatus = new DownloadStatus(feed, feed.getHumanReadableIdentifier(), DownloadError.SUCCESS, successful, reasonDetailed, request.isInitiatedByUser());
return result;
} else {
downloadStatus = new DownloadStatus(feed, feed.getTitle(), reason, successful, reasonDetailed, request.isInitiatedByUser());
return null;
}
}
use of de.danoeh.antennapod.core.service.download.DownloadStatus in project AntennaPod by AntennaPod.
the class DBReader method getDownloadLog.
/**
* Loads the download log from the database.
*
* @return A list with DownloadStatus objects that represent the download log.
* The size of the returned list is limited by {@link #DOWNLOAD_LOG_SIZE}.
*/
public static List<DownloadStatus> getDownloadLog() {
Log.d(TAG, "getDownloadLog() called");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
try (Cursor cursor = adapter.getDownloadLogCursor(DOWNLOAD_LOG_SIZE)) {
List<DownloadStatus> downloadLog = new ArrayList<>(cursor.getCount());
while (cursor.moveToNext()) {
downloadLog.add(DownloadStatus.fromCursor(cursor));
}
Collections.sort(downloadLog, new DownloadStatusComparator());
return downloadLog;
} finally {
adapter.close();
}
}
use of de.danoeh.antennapod.core.service.download.DownloadStatus in project AntennaPod by AntennaPod.
the class DBTasks method updateFeed.
/**
* Adds new Feeds to the database or updates the old versions if they already exists. If another Feed with the same
* identifying value already exists, this method will add new FeedItems from the new Feed to the existing Feed.
* These FeedItems will be marked as unread with the exception of the most recent FeedItem.
* <p/>
* This method can update multiple feeds at once. Submitting a feed twice in the same method call can result in undefined behavior.
* <p/>
* This method should NOT be executed on the GUI thread.
*
* @param context Used for accessing the DB.
* @param newFeed The new Feed object.
* @param removeUnlistedItems The item list in the new Feed object is considered to be exhaustive.
* I.e. items are removed from the database if they are not in this item list.
* @return The updated Feed from the database if it already existed, or the new Feed from the parameters otherwise.
*/
public static synchronized Feed updateFeed(Context context, Feed newFeed, boolean removeUnlistedItems) {
Feed resultFeed;
List<FeedItem> unlistedItems = new ArrayList<>();
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
// Look up feed in the feedslist
final Feed savedFeed = searchFeedByIdentifyingValueOrID(adapter, newFeed);
if (savedFeed == null) {
Log.d(TAG, "Found no existing Feed with title " + newFeed.getTitle() + ". Adding as new one.");
// Add a new Feed
// all new feeds will have the most recent item marked as unplayed
FeedItem mostRecent = newFeed.getMostRecentItem();
if (mostRecent != null) {
mostRecent.setNew();
}
resultFeed = newFeed;
} else {
Log.d(TAG, "Feed with title " + newFeed.getTitle() + " already exists. Syncing new with existing one.");
Collections.sort(newFeed.getItems(), new FeedItemPubdateComparator());
if (newFeed.getPageNr() == savedFeed.getPageNr()) {
if (savedFeed.compareWithOther(newFeed)) {
Log.d(TAG, "Feed has updated attribute values. Updating old feed's attributes");
savedFeed.updateFromOther(newFeed);
}
} else {
Log.d(TAG, "New feed has a higher page number.");
savedFeed.setNextPageLink(newFeed.getNextPageLink());
}
if (savedFeed.getPreferences().compareWithOther(newFeed.getPreferences())) {
Log.d(TAG, "Feed has updated preferences. Updating old feed's preferences");
savedFeed.getPreferences().updateFromOther(newFeed.getPreferences());
}
// get the most recent date now, before we start changing the list
FeedItem priorMostRecent = savedFeed.getMostRecentItem();
Date priorMostRecentDate = null;
if (priorMostRecent != null) {
priorMostRecentDate = priorMostRecent.getPubDate();
}
// Look for new or updated Items
for (int idx = 0; idx < newFeed.getItems().size(); idx++) {
final FeedItem item = newFeed.getItems().get(idx);
FeedItem possibleDuplicate = searchFeedItemGuessDuplicate(newFeed.getItems(), item);
if (!newFeed.isLocalFeed() && possibleDuplicate != null && item != possibleDuplicate) {
// Canonical episode is the first one returned (usually oldest)
DBWriter.addDownloadStatus(new DownloadStatus(savedFeed, item.getTitle(), DownloadError.ERROR_PARSER_EXCEPTION_DUPLICATE, false, "The podcast host appears to have added the same episode twice. " + "AntennaPod still refreshed the feed and attempted to repair it." + "\n\nOriginal episode:\n" + duplicateEpisodeDetails(item) + "\n\nSecond episode that is also in the feed:\n" + duplicateEpisodeDetails(possibleDuplicate), false));
continue;
}
FeedItem oldItem = searchFeedItemByIdentifyingValue(savedFeed.getItems(), item);
if (!newFeed.isLocalFeed() && oldItem == null) {
oldItem = searchFeedItemGuessDuplicate(savedFeed.getItems(), item);
if (oldItem != null) {
Log.d(TAG, "Repaired duplicate: " + oldItem + ", " + item);
DBWriter.addDownloadStatus(new DownloadStatus(savedFeed, item.getTitle(), DownloadError.ERROR_PARSER_EXCEPTION_DUPLICATE, false, "The podcast host changed the ID of an existing episode instead of just " + "updating the episode itself. AntennaPod still refreshed the feed and " + "attempted to repair it." + "\n\nOriginal episode:\n" + duplicateEpisodeDetails(oldItem) + "\n\nNow the feed contains:\n" + duplicateEpisodeDetails(item), false));
oldItem.setItemIdentifier(item.getItemIdentifier());
if (oldItem.isPlayed() && oldItem.getMedia() != null) {
EpisodeAction action = new EpisodeAction.Builder(oldItem, EpisodeAction.PLAY).currentTimestamp().started(oldItem.getMedia().getDuration() / 1000).position(oldItem.getMedia().getDuration() / 1000).total(oldItem.getMedia().getDuration() / 1000).build();
SynchronizationQueueSink.enqueueEpisodeActionIfSynchronizationIsActive(context, action);
}
}
}
if (oldItem != null) {
oldItem.updateFromOther(item);
} else {
// item is new
item.setFeed(savedFeed);
if (idx >= savedFeed.getItems().size()) {
savedFeed.getItems().add(item);
} else {
savedFeed.getItems().add(idx, item);
}
// New items that do not have a pubDate set are always marked as new
if (item.getPubDate() == null || priorMostRecentDate == null || priorMostRecentDate.before(item.getPubDate()) || priorMostRecentDate.equals(item.getPubDate())) {
Log.d(TAG, "Marking item published on " + item.getPubDate() + " new, prior most recent date = " + priorMostRecentDate);
item.setNew();
}
}
}
// identify items to be removed
if (removeUnlistedItems) {
Iterator<FeedItem> it = savedFeed.getItems().iterator();
while (it.hasNext()) {
FeedItem feedItem = it.next();
if (searchFeedItemByIdentifyingValue(newFeed.getItems(), feedItem) == null) {
unlistedItems.add(feedItem);
it.remove();
}
}
}
// update attributes
savedFeed.setLastUpdate(newFeed.getLastUpdate());
savedFeed.setType(newFeed.getType());
savedFeed.setLastUpdateFailed(false);
resultFeed = savedFeed;
}
try {
if (savedFeed == null) {
DBWriter.addNewFeed(context, newFeed).get();
// Update with default values that are set in database
resultFeed = searchFeedByIdentifyingValueOrID(adapter, newFeed);
} else {
DBWriter.setCompleteFeed(savedFeed).get();
}
if (removeUnlistedItems) {
DBWriter.deleteFeedItems(context, unlistedItems).get();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
adapter.close();
if (savedFeed != null) {
EventBus.getDefault().post(new FeedListUpdateEvent(savedFeed));
} else {
EventBus.getDefault().post(new FeedListUpdateEvent(Collections.emptyList()));
}
return resultFeed;
}
use of de.danoeh.antennapod.core.service.download.DownloadStatus in project AntennaPod by AntennaPod.
the class HttpDownloaderTest method download.
private Downloader download(String url, String title, boolean expectedResult, boolean deleteExisting, String username, String password, boolean deleteOnFail) {
FeedFile feedFile = setupFeedFile(url, title, deleteExisting);
DownloadRequest request = new DownloadRequest(feedFile.getFile_url(), url, title, 0, feedFile.getTypeAsInt(), username, password, deleteOnFail, null, false);
Downloader downloader = new HttpDownloader(request);
downloader.call();
DownloadStatus status = downloader.getResult();
assertNotNull(status);
assertEquals(expectedResult, status.isSuccessful());
assertTrue(status.isDone());
// the file should not exist if the download has failed and deleteExisting was true
assertTrue(!deleteExisting || new File(feedFile.getFile_url()).exists() == expectedResult);
return downloader;
}
use of de.danoeh.antennapod.core.service.download.DownloadStatus in project AntennaPod by AntennaPod.
the class DownloadLogAdapter method getView.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
DownloadLogItemViewHolder holder;
if (convertView == null) {
holder = new DownloadLogItemViewHolder(context, parent);
holder.itemView.setTag(holder);
} else {
holder = (DownloadLogItemViewHolder) convertView.getTag();
}
Object item = getItem(position);
if (item instanceof DownloadStatus) {
bind(holder, (DownloadStatus) item, position);
} else if (item instanceof Downloader) {
bind(holder, (Downloader) item, position);
}
return holder.itemView;
}
Aggregations