use of de.danoeh.antennapod.model.feed.FeedItem in project AntennaPod by AntennaPod.
the class DBReader method getQueue.
@NonNull
static List<FeedItem> getQueue(PodDBAdapter adapter) {
Log.d(TAG, "getQueue()");
try (Cursor cursor = adapter.getQueueCursor()) {
List<FeedItem> items = extractItemlistFromCursor(adapter, cursor);
loadAdditionalFeedItemListData(items);
return items;
}
}
use of de.danoeh.antennapod.model.feed.FeedItem in project AntennaPod by AntennaPod.
the class DBReader method getNextInQueue.
/**
* Get next feed item in queue following a particular feeditem
*
* @param item The FeedItem
* @return The FeedItem next in queue or null if the FeedItem could not be found.
*/
@Nullable
public static FeedItem getNextInQueue(FeedItem item) {
Log.d(TAG, "getNextInQueue() called with: " + "itemId = [" + item.getId() + "]");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
try {
FeedItem nextItem = null;
try (Cursor cursor = adapter.getNextInQueue(item)) {
List<FeedItem> list = extractItemlistFromCursor(adapter, cursor);
if (!list.isEmpty()) {
nextItem = list.get(0);
loadAdditionalFeedItemListData(list);
}
return nextItem;
} catch (Exception e) {
return null;
}
} finally {
adapter.close();
}
}
use of de.danoeh.antennapod.model.feed.FeedItem in project AntennaPod by AntennaPod.
the class DBTasks method enqueueFeedItemsToDownload.
public static List<FeedItem> enqueueFeedItemsToDownload(final Context context, List<FeedItem> items) throws InterruptedException, ExecutionException {
List<FeedItem> itemsToEnqueue = new ArrayList<>();
if (UserPreferences.enqueueDownloadedEpisodes()) {
LongList queueIDList = DBReader.getQueueIDList();
for (FeedItem item : items) {
if (!queueIDList.contains(item.getId())) {
itemsToEnqueue.add(item);
}
}
DBWriter.addQueueItem(context, false, itemsToEnqueue.toArray(new FeedItem[0])).get();
}
return itemsToEnqueue;
}
use of de.danoeh.antennapod.model.feed.FeedItem 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.model.feed.FeedItem in project AntennaPod by AntennaPod.
the class DBWriter method addQueueItem.
/**
* Appends FeedItem objects to the end of the queue. The 'read'-attribute of all items will be set to true.
* If a FeedItem is already in the queue, the FeedItem will not change its position in the queue.
*
* @param context A context that is used for opening a database connection.
* @param performAutoDownload true if an auto-download process should be started after the operation.
* @param markAsUnplayed true if the items should be marked as unplayed when enqueueing
* @param itemIds IDs of the FeedItem objects that should be added to the queue.
*/
public static Future<?> addQueueItem(final Context context, final boolean performAutoDownload, final boolean markAsUnplayed, final long... itemIds) {
return dbExec.submit(() -> {
if (itemIds.length < 1) {
return;
}
final PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
final List<FeedItem> queue = DBReader.getQueue(adapter);
boolean queueModified = false;
LongList markAsUnplayedIds = new LongList();
List<QueueEvent> events = new ArrayList<>();
List<FeedItem> updatedItems = new ArrayList<>();
ItemEnqueuePositionCalculator positionCalculator = new ItemEnqueuePositionCalculator(UserPreferences.getEnqueueLocation());
Playable currentlyPlaying = PlayableUtils.createInstanceFromPreferences(context);
int insertPosition = positionCalculator.calcPosition(queue, currentlyPlaying);
for (long itemId : itemIds) {
if (!itemListContains(queue, itemId)) {
final FeedItem item = DBReader.getFeedItem(itemId);
if (item != null) {
queue.add(insertPosition, item);
events.add(QueueEvent.added(item, insertPosition));
item.addTag(FeedItem.TAG_QUEUE);
updatedItems.add(item);
queueModified = true;
if (item.isNew()) {
markAsUnplayedIds.add(item.getId());
}
insertPosition++;
}
}
}
if (queueModified) {
applySortOrder(queue, events);
adapter.setQueue(queue);
for (QueueEvent event : events) {
EventBus.getDefault().post(event);
}
EventBus.getDefault().post(FeedItemEvent.updated(updatedItems));
if (markAsUnplayed && markAsUnplayedIds.size() > 0) {
DBWriter.markItemPlayed(FeedItem.UNPLAYED, markAsUnplayedIds.toArray());
}
}
adapter.close();
if (performAutoDownload) {
DBTasks.autodownloadUndownloadedItems(context);
}
});
}
Aggregations