Implement cleanup that only removes epiosdes older than a certain number of days
Also set the stage for the queue cleanup algorithm.
This commit is contained in:
parent
057900bc1b
commit
f5801c2181
|
@ -442,12 +442,14 @@ public class PreferenceController implements SharedPreferences.OnSharedPreferenc
|
|||
String[] entries = new String[values.length];
|
||||
for (int x = 0; x < values.length; x++) {
|
||||
int v = Integer.parseInt(values[x]);
|
||||
if (v == 0) {
|
||||
entries[x] = res.getString(R.string.episode_cleanup_immediately);
|
||||
} else if (v == -1){
|
||||
if (v == -1) {
|
||||
entries[x] = res.getString(R.string.episode_cleanup_queue_removal);
|
||||
} else if (v == -2){
|
||||
entries[x] = res.getString(R.string.episode_cleanup_never);
|
||||
} else if (v == 0) {
|
||||
entries[x] = res.getString(R.string.episode_cleanup_after_listening);
|
||||
} else {
|
||||
entries[x] = res.getQuantityString(R.plurals.time_days_quantified, v, v);
|
||||
entries[x] = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, v, v);
|
||||
}
|
||||
}
|
||||
pref.setEntries(entries);
|
||||
|
|
|
@ -27,6 +27,10 @@ import java.util.concurrent.TimeUnit;
|
|||
import de.danoeh.antennapod.core.ClientConfig;
|
||||
import de.danoeh.antennapod.core.R;
|
||||
import de.danoeh.antennapod.core.receiver.FeedUpdateReceiver;
|
||||
import de.danoeh.antennapod.core.storage.APCleanupAlgorithm;
|
||||
import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm;
|
||||
import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm;
|
||||
import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;
|
||||
|
||||
/**
|
||||
* Provides access to preferences set by the user in the settings screen. A
|
||||
|
@ -218,8 +222,6 @@ public class UserPreferences {
|
|||
return prefs.getBoolean(PREF_FOLLOW_QUEUE, true);
|
||||
}
|
||||
|
||||
public static int getEpisodeCleanupDays() { return Integer.valueOf(prefs.getString(PREF_EPISODE_CLEANUP, "3")); }
|
||||
|
||||
public static boolean shouldSkipRemoveFromQueue() { return prefs.getBoolean(PREF_SKIP_REMOVES, false); }
|
||||
|
||||
public static boolean isAutoDelete() {
|
||||
|
@ -489,6 +491,18 @@ public class UserPreferences {
|
|||
.apply();
|
||||
}
|
||||
|
||||
|
||||
public static EpisodeCleanupAlgorithm<Integer> getEpisodeCleanupAlgorithm() {
|
||||
int cleanupValue = prefs.getInt(PREF_EPISODE_CLEANUP, -1);
|
||||
if (cleanupValue == -1) {
|
||||
return new APQueueCleanupAlgorithm();
|
||||
} else if (cleanupValue == -2) {
|
||||
return new APNullCleanupAlgorithm();
|
||||
} else {
|
||||
return new APCleanupAlgorithm(cleanupValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the folder where the app stores all of its data. This method will
|
||||
* return the standard data folder if none has been set by the user.
|
||||
|
@ -648,5 +662,4 @@ public class UserPreferences {
|
|||
public static int readEpisodeCacheSize(String valueFromPrefs) {
|
||||
return readEpisodeCacheSizeInternal(valueFromPrefs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,12 +4,14 @@ import android.content.Context;
|
|||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.feed.FeedMedia;
|
||||
import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
|
||||
|
@ -19,19 +21,34 @@ import de.danoeh.antennapod.core.util.LongList;
|
|||
public class APCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
|
||||
|
||||
private static final String TAG = "APCleanupAlgorithm";
|
||||
/** the number of days after playback to wait before an item is eligible to be cleaned up */
|
||||
private final int numberOfDaysAfterPlayback;
|
||||
|
||||
public APCleanupAlgorithm(int numberOfDaysAfterPlayback) {
|
||||
this.numberOfDaysAfterPlayback = numberOfDaysAfterPlayback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int performCleanup(Context context, Integer episodeNumber) {
|
||||
public int performCleanup(Context context, Integer numberOfEpisodesToDelete) {
|
||||
List<FeedItem> candidates = new ArrayList<>();
|
||||
List<FeedItem> downloadedItems = DBReader.getDownloadedItems();
|
||||
LongList queue = DBReader.getQueueIDList();
|
||||
List<FeedItem> delete;
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_MONTH, -1 * numberOfDaysAfterPlayback);
|
||||
Date mostRecentDateForDeletion = cal.getTime();
|
||||
for (FeedItem item : downloadedItems) {
|
||||
if (item.hasMedia() && item.getMedia().isDownloaded()
|
||||
&& !queue.contains(item.getId()) && item.isPlayed()) {
|
||||
candidates.add(item);
|
||||
FeedMedia media = item.getMedia();
|
||||
// make sure this candidate was played at least the proper amount of days prior
|
||||
// to now
|
||||
if (media != null
|
||||
&& media.getPlaybackCompletionDate() != null
|
||||
&& media.getPlaybackCompletionDate().before(mostRecentDateForDeletion)) {
|
||||
candidates.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Collections.sort(candidates, (lhs, rhs) -> {
|
||||
|
@ -47,8 +64,8 @@ public class APCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
|
|||
return l.compareTo(r);
|
||||
});
|
||||
|
||||
if (candidates.size() > episodeNumber) {
|
||||
delete = candidates.subList(0, episodeNumber);
|
||||
if (candidates.size() > numberOfEpisodesToDelete) {
|
||||
delete = candidates.subList(0, numberOfEpisodesToDelete);
|
||||
} else {
|
||||
delete = candidates;
|
||||
}
|
||||
|
@ -66,34 +83,13 @@ public class APCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
|
|||
|
||||
Log.i(TAG, String.format(
|
||||
"Auto-delete deleted %d episodes (%d requested)", counter,
|
||||
episodeNumber));
|
||||
numberOfEpisodesToDelete));
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getDefaultCleanupParameter() {
|
||||
return getPerformAutoCleanupArgs(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPerformCleanupParameter(List<FeedItem> items) {
|
||||
return getPerformAutoCleanupArgs(items.size());
|
||||
}
|
||||
|
||||
static int getPerformAutoCleanupArgs(final int episodeNumber) {
|
||||
if (episodeNumber >= 0
|
||||
&& UserPreferences.getEpisodeCacheSize() != UserPreferences
|
||||
.getEpisodeCacheSizeUnlimited()) {
|
||||
int downloadedEpisodes = DBReader
|
||||
.getNumberOfDownloadedEpisodes();
|
||||
if (downloadedEpisodes + episodeNumber >= UserPreferences
|
||||
.getEpisodeCacheSize()) {
|
||||
|
||||
return downloadedEpisodes + episodeNumber
|
||||
- UserPreferences.getEpisodeCacheSize();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ import de.danoeh.antennapod.core.util.PowerUtils;
|
|||
public class APDownloadAlgorithm implements AutomaticDownloadAlgorithm {
|
||||
private static final String TAG = "APDownloadAlgorithm";
|
||||
|
||||
private final APCleanupAlgorithm cleanupAlgorithm = new APCleanupAlgorithm();
|
||||
|
||||
/**
|
||||
* Looks for undownloaded episodes in the queue or list of new items and request a download if
|
||||
* 1. Network is available
|
||||
|
@ -72,8 +70,8 @@ public class APDownloadAlgorithm implements AutomaticDownloadAlgorithm {
|
|||
|
||||
int autoDownloadableEpisodes = candidates.size();
|
||||
int downloadedEpisodes = DBReader.getNumberOfDownloadedEpisodes();
|
||||
int deletedEpisodes = cleanupAlgorithm.performCleanup(context,
|
||||
APCleanupAlgorithm.getPerformAutoCleanupArgs(autoDownloadableEpisodes));
|
||||
int deletedEpisodes = UserPreferences.getEpisodeCleanupAlgorithm().performCleanup(context,
|
||||
getPerformAutoCleanupArgs(autoDownloadableEpisodes));
|
||||
boolean cacheIsUnlimited = UserPreferences.getEpisodeCacheSize() == UserPreferences
|
||||
.getEpisodeCacheSizeUnlimited();
|
||||
int episodeCacheSize = UserPreferences.getEpisodeCacheSize();
|
||||
|
@ -102,4 +100,20 @@ public class APDownloadAlgorithm implements AutomaticDownloadAlgorithm {
|
|||
};
|
||||
}
|
||||
|
||||
private int getPerformAutoCleanupArgs(final int numberOfEpisodesToDownload) {
|
||||
if (numberOfEpisodesToDownload >= 0
|
||||
&& UserPreferences.getEpisodeCacheSize() != UserPreferences
|
||||
.getEpisodeCacheSizeUnlimited()) {
|
||||
int downloadedEpisodes = DBReader
|
||||
.getNumberOfDownloadedEpisodes();
|
||||
if (downloadedEpisodes + numberOfEpisodesToDownload >= UserPreferences
|
||||
.getEpisodeCacheSize()) {
|
||||
|
||||
return downloadedEpisodes + numberOfEpisodesToDownload
|
||||
- UserPreferences.getEpisodeCacheSize();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package de.danoeh.antennapod.core.storage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* A cleanup algorithm that never removes anything
|
||||
*/
|
||||
public class APNullCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
|
||||
@Override
|
||||
public int performCleanup(Context context, Integer parameter) {
|
||||
// never clean anything up
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getDefaultCleanupParameter() {
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package de.danoeh.antennapod.core.storage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* A cleanup algorithm that removes any item that isn't in the queue and isn't a favorite
|
||||
* but only if space is needed.
|
||||
*/
|
||||
public class APQueueCleanupAlgorithm implements EpisodeCleanupAlgorithm<Integer> {
|
||||
@Override
|
||||
public int performCleanup(Context context, Integer parameter) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getDefaultCleanupParameter() {
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -334,7 +334,7 @@ public final class DBTasks {
|
|||
ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm()
|
||||
.performCleanup(context,
|
||||
ClientConfig.dbTasksCallbacks.getEpisodeCacheCleanupAlgorithm()
|
||||
.getPerformCleanupParameter(Arrays.asList(items)));
|
||||
.getPerformCleanupParameter(items.length));
|
||||
}
|
||||
|
||||
}.start();
|
||||
|
|
|
@ -17,20 +17,12 @@ public interface EpisodeCleanupAlgorithm<T> {
|
|||
* or getPerformCleanupParameter.
|
||||
* @return The number of episodes that were deleted.
|
||||
*/
|
||||
public int performCleanup(Context context, T parameter);
|
||||
int performCleanup(Context context, T parameter);
|
||||
|
||||
/**
|
||||
* Returns a parameter for performCleanup. The implementation of this interface should decide how much
|
||||
* space to free to satisfy the episode cache conditions. If the conditions are already satisfied, this
|
||||
* method should not have any effects.
|
||||
*/
|
||||
public T getDefaultCleanupParameter();
|
||||
|
||||
/**
|
||||
* Returns a parameter for performCleanup.
|
||||
*
|
||||
* @param items A list of FeedItems that are about to be downloaded. The implementation of this interface
|
||||
* should decide how much space to free to satisfy the episode cache conditions.
|
||||
*/
|
||||
public T getPerformCleanupParameter(List<FeedItem> items);
|
||||
T getDefaultCleanupParameter();
|
||||
}
|
||||
|
|
|
@ -55,7 +55,8 @@
|
|||
</string-array>
|
||||
|
||||
<string-array name="episode_cleanup_entries">
|
||||
<item>@string/episode_cleanup_immediately</item>
|
||||
<item>@string/episode_cleanup_queue_removal</item>
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>3</item>
|
||||
<item>5</item>
|
||||
|
@ -64,12 +65,13 @@
|
|||
</string-array>
|
||||
|
||||
<string-array name="episode_cleanup_values">
|
||||
<item>-1</item>
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>3</item>
|
||||
<item>5</item>
|
||||
<item>7</item>
|
||||
<item>-1</item>
|
||||
<item>-2</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="playback_speed_values">
|
||||
|
|
|
@ -87,7 +87,12 @@
|
|||
<string name="feed_auto_download_never">Never</string>
|
||||
<string name="send_label">Send...</string>
|
||||
<string name="episode_cleanup_never">Never</string>
|
||||
<string name="episode_cleanup_immediately">when not in queue</string>
|
||||
<string name="episode_cleanup_queue_removal">When not in queue</string>
|
||||
<string name="episode_cleanup_after_listening">After listening</string>
|
||||
<plurals name="episode_cleanup_days_after_listening">
|
||||
<item quantity="one">1 day after listening</item>
|
||||
<item quantity="other">%d days after listening</item>
|
||||
</plurals>
|
||||
|
||||
<!-- 'Add Feed' Activity labels -->
|
||||
<string name="feedurl_label">Feed URL</string>
|
||||
|
@ -421,10 +426,6 @@
|
|||
<item quantity="other">%d hours</item>
|
||||
</plurals>
|
||||
|
||||
<plurals name="time_days_quantified">
|
||||
<item quantity="one">1 day</item>
|
||||
<item quantity="other">%d days</item>
|
||||
</plurals>
|
||||
<!-- gpodder.net -->
|
||||
<string name="gpodnet_taglist_header">CATEGORIES</string>
|
||||
<string name="gpodnet_toplist_header">TOP PODCASTS</string>
|
||||
|
|
Loading…
Reference in New Issue