Prevent media files from being deleted after a failed download
This commit is contained in:
parent
8769d29cef
commit
6f77dea838
|
@ -146,7 +146,7 @@ public abstract class OnlineFeedViewActivity extends ActionBarActivity {
|
|||
.toString();
|
||||
feed.setFile_url(fileUrl);
|
||||
final DownloadRequest request = new DownloadRequest(feed.getFile_url(),
|
||||
feed.getDownload_url(), "OnlineFeed", 0, Feed.FEEDFILETYPE_FEED, username, password);
|
||||
feed.getDownload_url(), "OnlineFeed", 0, Feed.FEEDFILETYPE_FEED, username, password, true);
|
||||
downloader = new HttpDownloader(
|
||||
request);
|
||||
new Thread() {
|
||||
|
|
|
@ -10,6 +10,7 @@ public class DownloadRequest implements Parcelable {
|
|||
private final String title;
|
||||
private String username;
|
||||
private String password;
|
||||
private boolean deleteOnFailure;
|
||||
private final long feedfileId;
|
||||
private final int feedfileType;
|
||||
|
||||
|
@ -19,7 +20,7 @@ public class DownloadRequest implements Parcelable {
|
|||
protected int statusMsg;
|
||||
|
||||
public DownloadRequest(String destination, String source, String title,
|
||||
long feedfileId, int feedfileType, String username, String password) {
|
||||
long feedfileId, int feedfileType, String username, String password, boolean deleteOnFailure) {
|
||||
if (destination == null) {
|
||||
throw new IllegalArgumentException("Destination must not be null");
|
||||
}
|
||||
|
@ -37,11 +38,12 @@ public class DownloadRequest implements Parcelable {
|
|||
this.feedfileType = feedfileType;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.deleteOnFailure = deleteOnFailure;
|
||||
}
|
||||
|
||||
public DownloadRequest(String destination, String source, String title,
|
||||
long feedfileId, int feedfileType) {
|
||||
this(destination, source, title, feedfileId, feedfileType, null, null);
|
||||
this(destination, source, title, feedfileId, feedfileType, null, null, true);
|
||||
}
|
||||
|
||||
private DownloadRequest(Parcel in) {
|
||||
|
@ -50,6 +52,7 @@ public class DownloadRequest implements Parcelable {
|
|||
title = in.readString();
|
||||
feedfileId = in.readLong();
|
||||
feedfileType = in.readInt();
|
||||
deleteOnFailure = (in.readByte() > 0);
|
||||
if (in.dataAvail() > 0) {
|
||||
username = in.readString();
|
||||
} else {
|
||||
|
@ -74,6 +77,7 @@ public class DownloadRequest implements Parcelable {
|
|||
dest.writeString(title);
|
||||
dest.writeLong(feedfileId);
|
||||
dest.writeInt(feedfileType);
|
||||
dest.writeByte((deleteOnFailure) ? (byte) 1 : 0);
|
||||
if (username != null) {
|
||||
dest.writeString(username);
|
||||
}
|
||||
|
@ -93,59 +97,43 @@ public class DownloadRequest implements Parcelable {
|
|||
};
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result
|
||||
+ ((destination == null) ? 0 : destination.hashCode());
|
||||
result = prime * result + (int) (feedfileId ^ (feedfileId >>> 32));
|
||||
result = prime * result + feedfileType;
|
||||
result = prime * result + progressPercent;
|
||||
result = prime * result + (int) (size ^ (size >>> 32));
|
||||
result = prime * result + (int) (soFar ^ (soFar >>> 32));
|
||||
result = prime * result + ((source == null) ? 0 : source.hashCode());
|
||||
result = prime * result + statusMsg;
|
||||
result = prime * result + ((title == null) ? 0 : title.hashCode());
|
||||
return result;
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
DownloadRequest that = (DownloadRequest) o;
|
||||
|
||||
if (deleteOnFailure != that.deleteOnFailure) return false;
|
||||
if (feedfileId != that.feedfileId) return false;
|
||||
if (feedfileType != that.feedfileType) return false;
|
||||
if (progressPercent != that.progressPercent) return false;
|
||||
if (size != that.size) return false;
|
||||
if (soFar != that.soFar) return false;
|
||||
if (statusMsg != that.statusMsg) return false;
|
||||
if (destination != null ? !destination.equals(that.destination) : that.destination != null) return false;
|
||||
if (password != null ? !password.equals(that.password) : that.password != null) return false;
|
||||
if (source != null ? !source.equals(that.source) : that.source != null) return false;
|
||||
if (title != null ? !title.equals(that.title) : that.title != null) return false;
|
||||
if (username != null ? !username.equals(that.username) : that.username != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
DownloadRequest other = (DownloadRequest) obj;
|
||||
if (destination == null) {
|
||||
if (other.destination != null)
|
||||
return false;
|
||||
} else if (!destination.equals(other.destination))
|
||||
return false;
|
||||
if (feedfileId != other.feedfileId)
|
||||
return false;
|
||||
if (feedfileType != other.feedfileType)
|
||||
return false;
|
||||
if (progressPercent != other.progressPercent)
|
||||
return false;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
if (soFar != other.soFar)
|
||||
return false;
|
||||
if (source == null) {
|
||||
if (other.source != null)
|
||||
return false;
|
||||
} else if (!source.equals(other.source))
|
||||
return false;
|
||||
if (statusMsg != other.statusMsg)
|
||||
return false;
|
||||
if (title == null) {
|
||||
if (other.title != null)
|
||||
return false;
|
||||
} else if (!title.equals(other.title))
|
||||
return false;
|
||||
return true;
|
||||
public int hashCode() {
|
||||
int result = destination != null ? destination.hashCode() : 0;
|
||||
result = 31 * result + (source != null ? source.hashCode() : 0);
|
||||
result = 31 * result + (title != null ? title.hashCode() : 0);
|
||||
result = 31 * result + (username != null ? username.hashCode() : 0);
|
||||
result = 31 * result + (password != null ? password.hashCode() : 0);
|
||||
result = 31 * result + (deleteOnFailure ? 1 : 0);
|
||||
result = 31 * result + (int) (feedfileId ^ (feedfileId >>> 32));
|
||||
result = 31 * result + feedfileType;
|
||||
result = 31 * result + progressPercent;
|
||||
result = 31 * result + (int) (soFar ^ (soFar >>> 32));
|
||||
result = 31 * result + (int) (size ^ (size >>> 32));
|
||||
result = 31 * result + statusMsg;
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getDestination() {
|
||||
|
@ -215,4 +203,8 @@ public class DownloadRequest implements Parcelable {
|
|||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public boolean isDeleteOnFailure() {
|
||||
return deleteOnFailure;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ public class DownloadService extends Service {
|
|||
} else {
|
||||
Log.e(TAG, "Download failed");
|
||||
saveDownloadStatus(status);
|
||||
handleFailedDownload(status, downloader.getDownloadRequest());
|
||||
}
|
||||
}
|
||||
sendDownloadHandledIntent();
|
||||
|
@ -608,6 +609,11 @@ public class DownloadService extends Service {
|
|||
syncExecutor.execute(new MediaHandlerThread(status, request));
|
||||
}
|
||||
|
||||
private void handleFailedDownload(DownloadStatus status, DownloadRequest request) {
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, "Handling failed download");
|
||||
syncExecutor.execute(new FailedDownloadHandler(status, request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a single Feed, parses the corresponding file and refreshes
|
||||
* information in the manager
|
||||
|
@ -791,6 +797,46 @@ public class DownloadService extends Service {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles failed downloads.
|
||||
* <p/>
|
||||
* If the file has been partially downloaded, this handler will set the file_url of the FeedFile to the location
|
||||
* of the downloaded file.
|
||||
* <p/>
|
||||
* Currently, this handler only handles FeedMedia objects, because Feeds and FeedImages are deleted if the download fails.
|
||||
*/
|
||||
class FailedDownloadHandler implements Runnable {
|
||||
|
||||
private DownloadRequest request;
|
||||
private DownloadStatus status;
|
||||
|
||||
FailedDownloadHandler(DownloadStatus status, DownloadRequest request) {
|
||||
this.request = request;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (request.isDeleteOnFailure()) {
|
||||
if (BuildConfig.DEBUG) Log.d(TAG, "Ignoring failed download, deleteOnFailure=true");
|
||||
} else {
|
||||
File dest = new File(request.getDestination());
|
||||
if (dest.exists() && request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||
Log.d(TAG, "File has been partially downloaded. Writing file url");
|
||||
FeedMedia media = DBReader.getFeedMedia(DownloadService.this, request.getFeedfileId());
|
||||
media.setFile_url(request.getDestination());
|
||||
try {
|
||||
DBWriter.setFeedMedia(DownloadService.this, media).get();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a completed image download.
|
||||
*/
|
||||
|
|
|
@ -182,7 +182,9 @@ public class HttpDownloader extends Downloader {
|
|||
Log.d(TAG, "Download failed");
|
||||
}
|
||||
result.setFailed(reason, reasonDetailed);
|
||||
cleanup();
|
||||
if (request.isDeleteOnFailure()) {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
private void onCancelled() {
|
||||
|
|
|
@ -12,6 +12,7 @@ import de.danoeh.antennapod.service.download.DownloadService;
|
|||
import de.danoeh.antennapod.util.FileNameGenerator;
|
||||
import de.danoeh.antennapod.util.URLChecker;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -72,9 +73,9 @@ public class DownloadRequester {
|
|||
}
|
||||
|
||||
private void download(Context context, FeedFile item, File dest,
|
||||
boolean overwriteIfExists, String username, String password) {
|
||||
boolean overwriteIfExists, String username, String password, boolean deleteOnFailure) {
|
||||
if (!isDownloadingFile(item)) {
|
||||
if (!isFilenameAvailable(dest.toString()) || dest.exists()) {
|
||||
if (!isFilenameAvailable(dest.toString()) || (deleteOnFailure && dest.exists())) {
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.d(TAG, "Filename already used.");
|
||||
if (isFilenameAvailable(dest.toString()) && overwriteIfExists) {
|
||||
|
@ -114,7 +115,7 @@ public class DownloadRequester {
|
|||
|
||||
DownloadRequest request = new DownloadRequest(dest.toString(),
|
||||
item.getDownload_url(), item.getHumanReadableIdentifier(),
|
||||
item.getId(), item.getTypeAsInt(), username, password);
|
||||
item.getId(), item.getTypeAsInt(), username, password, deleteOnFailure);
|
||||
|
||||
download(context, request);
|
||||
} else {
|
||||
|
@ -149,7 +150,7 @@ public class DownloadRequester {
|
|||
String password = (feed.getPreferences() != null) ? feed.getPreferences().getPassword() : null;
|
||||
|
||||
download(context, feed, new File(getFeedfilePath(context),
|
||||
getFeedfileName(feed)), true, username, password);
|
||||
getFeedfileName(feed)), true, username, password, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +158,7 @@ public class DownloadRequester {
|
|||
throws DownloadRequestException {
|
||||
if (feedFileValid(image)) {
|
||||
download(context, image, new File(getImagefilePath(context),
|
||||
getImagefileName(image)), false, null, null);
|
||||
getImagefileName(image)), false, null, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,9 +175,16 @@ public class DownloadRequester {
|
|||
username = null;
|
||||
password = null;
|
||||
}
|
||||
|
||||
File dest;
|
||||
if (feedmedia.getFile_url() != null) {
|
||||
dest = new File(feedmedia.getFile_url());
|
||||
} else {
|
||||
dest = new File(getMediafilePath(context, feedmedia),
|
||||
getMediafilename(feedmedia));
|
||||
}
|
||||
download(context, feedmedia,
|
||||
new File(getMediafilePath(context, feedmedia),
|
||||
getMediafilename(feedmedia)), false, username, password
|
||||
dest, false, username, password, false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue