[gnome-boxes/wip/download: 3/3] TMP: Move download functionality to download.vala
- From: Lasse Schuirmann <lschuirma src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-boxes/wip/download: 3/3] TMP: Move download functionality to download.vala
- Date: Mon, 13 Oct 2014 13:43:25 +0000 (UTC)
commit b40e6ce254c80622857dfba411a34a7657781a35
Author: Lasse Schuirmann <lasse schuirmann gmail com>
Date: Mon Oct 13 14:38:14 2014 +0200
TMP: Move download functionality to download.vala
Let the downloader only handle all downloads.
This commit may not compile, it is work in progress.
src/download.vala | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 133 insertions(+), 7 deletions(-)
---
diff --git a/src/download.vala b/src/download.vala
index 9dd10e2..334b0b3 100644
--- a/src/download.vala
+++ b/src/download.vala
@@ -1,16 +1,142 @@
// This file is part of GNOME Boxes. License: LGPLv2+
-private class Boxes.Download {
- public string uri;
- public File remote_file;
- public File cached_file;
- public ActivityProgress progress;
+private class Boxes.Download : GLib.Object {
+ private string uri { public get; }
+ protected File remote_file;
+ protected File local_file;
+ protected File cache_file;
- public Download (File remote_file, File cached_file, ActivityProgress progress) {
+ protected ActivityProgress progress;
+ protected Cancellable? cancellable;
+
+ protected bool downloading { public get; }
+
+ public signal void download_successful ();
+ public signal void download_failed (GLib.Error error);
+
+ protected Mutex mutex = new Mutex ();
+
+
+ /**
+ * Can be used to download files.
+ *
+ * @param uri: The URI to download.
+ * @param local_file: The target file. (Will be overwritten.)
+ * @param cache_file: The temporary download file. Defaults to null which will be a file corresponding
to the
+ * local_file.get_uri () + "~" path.
+ * @param progress: The ActivityProgress object to report progress to.
+ * @param cancellable: The Cancellable object for cancellation.
+ */
+ public Download (File remote_file,
+ File local_file,
+ File? cache_file = null,
+ ActivityProgress? progress = new ActivityProgress (),
+ Cancellable? cancellable = null) {
this.remote_file = remote_file;
this.uri = remote_file.get_uri ();
- this.cached_file = cached_file;
+ this.local_file = local_file;
+ this.cache_file = cache_file ?? GLib.File.new_for_path (local_file.get_uri () + "~");
this.progress = progress;
+ this.cancellable = cancellable;
+ this.downloading = false;
+ }
+
+ /**
+ * Downloads the file.
+ *
+ * If you want to override how the download works, override the download_cached () method and take a
look at its
+ * documentation comment.
+ *
+ * @return The File object corresponding to the downloaded file.
+ */
+ public async File download () throws GLib.Error {
+ mutex.lock ();
+ {
+ downloading = true;
+ }
+ mutex.unlock ();
+
+ try {
+ download_cached ();
+
+ cache_file.move (local_file, FileCopyFlags.OVERWRITE, cancellable);
+ } catch (GLib.Error error) {
+ mutex.lock ();
+ {
+ downloading = false;
+ download_failed (error);
+ }
+ mutex.unlock ();
+
+ throw error;
+ }
+
+ mutex.lock ();
+ {
+ downloading = false;
+ download_successful ();
+ }
+ mutex.unlock ();
+
+ return local_file;
+ }
+
+ /**
+ * Waits until the current download is finished. This allows also to monitor the download.
+ *
+ * @param progress: An ActivityProgress object to monitor the download. It will not be connected to the
download if
+ * the download is not active.
+ * @return The downloaded File object. Will be null if the download is not downloading anything.
+ */
+ public async File? await_download (ActivityProgress? progress = null) throws GLib.Error {
+ // Make sure that download_complete isnt called while we're preparing to listen
+ mutex.lock ();
+
+ if (!downloading)
+ mutex.unlock ();
+ debug ("Won't wait for download '%s' to finish since it is no active download.", uri);
+ return null;
+
+ try {
+ if (progress != null)
+ this.progress.bind_property ("progress", progress, "progress", BindingFlags.SYNC_CREATE);
+
+ GLib.Error download_error = null;
+ SourceFunc callback = await_download.callback;
+ var successful_id = download_successful.connect (() => { callback (); });
+ var failed_id = download_failed.connect((error) => { download_error = error; callback ();}
+ } finally {
+ mutex.unlock ();
+ }
+
+ debug ("'%s' already being downloaded. Waiting for download to complete..", uri);
+ // ATTENTION: Dont lock this.mutex below this yield statement since this will cause a deadlock
+ yield;
+ debug ("Finished waiting for '%s' to download.", uri);
+
+ disconnect (successful_id);
+ disconnect (failed_id);
+
+ if (download_error != null)
+ throw download_error;
+
+ return local_file;
+ }
+
+ protected async abstract void download_cached () throws GLib.Error;
+}
+
+private class Boxes.FilesystemDownload : GLib.Object, Boxes.Download {
+ public async override File download_cached () throws GLib.Error {
+ debug ("Copying '%s' to '%s'..", remote_file.get_path (), cache_file.get_path ());
+ yield remote_file.copy_async (cache_file,
+ FileCopyFlags.OVERWRITE,
+ Priority.DEFAULT,
+ cancellable,
+ (current, total) => {
+ progress.progress = (double) current / total;
+ });
+ debug ("Copied '%s' to '%s'.", remote_file.get_path (), cache_file.get_path ());
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]