setup fetcher: Show download speed on initial project fetch. #1361

This commit is contained in:
Hylke Bons 2013-08-25 18:46:06 +02:00
parent 0f36b3c412
commit 452dc783e4
7 changed files with 68 additions and 28 deletions

View file

@ -29,9 +29,12 @@ namespace SparkleLib.Git {
private SparkleGit git;
private bool use_git_bin;
private string cached_salt;
private Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled);
private Regex speed_regex = new Regex (@"([0-9\.]+) ([KM])iB/s", RegexOptions.Compiled);
private string crypto_salt {
get {
if (!string.IsNullOrEmpty (this.cached_salt))
@ -123,7 +126,6 @@ namespace SparkleLib.Git {
this.git.Start ();
double percentage = 1.0;
Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled);
DateTime last_change = DateTime.Now;
TimeSpan change_interval = new TimeSpan (0, 0, 0, 1);
@ -131,19 +133,42 @@ namespace SparkleLib.Git {
try {
while (!this.git.StandardError.EndOfStream) {
string line = this.git.StandardError.ReadLine ();
Match match = progress_regex.Match (line);
Match match = this.progress_regex.Match (line);
double number = 0.0;
double speed = 0.0;
if (match.Success) {
number = double.Parse (match.Groups [1].Value, new CultureInfo ("en-US"));
try {
number = double.Parse (match.Groups [1].Value, new CultureInfo ("en-US"));
} catch (FormatException) {
SparkleLogger.LogInfo ("Git", "Error parsing progress: \"" + match.Groups [1] + "\"");
}
// The cloning progress consists of two stages: the "Compressing
// objects" stage which we count as 20% of the total progress, and
// the "Receiving objects" stage which we count as the last 80%
if (line.Contains ("|"))
number = (number / 100 * 80 + 20); // "Receiving objects" stage
else
number = (number / 100 * 20); // "Compressing objects" stage
// The pushing progress consists of two stages: the "Compressing
// objects" stage which we count as 20% of the total progress, and
// the "Writing objects" stage which we count as the last 80%
if (line.Contains ("Compressing")) {
// "Compressing objects" stage
number = (number / 100 * 20);
} else {
// "Writing objects" stage
number = (number / 100 * 80 + 20);
Match speed_match = this.speed_regex.Match (line);
if (speed_match.Success) {
try {
speed = double.Parse (speed_match.Groups [1].Value, new CultureInfo ("en-US")) * 1024;
} catch (FormatException) {
SparkleLogger.LogInfo ("Git", "Error parsing speed: \"" + speed_match.Groups [1] + "\"");
}
if (speed_match.Groups [2].Value.Equals ("M"))
speed = speed * 1024;
}
}
} else {
SparkleLogger.LogInfo ("Fetcher", line);
@ -166,7 +191,7 @@ namespace SparkleLib.Git {
percentage = number;
if (DateTime.Compare (last_change, DateTime.Now.Subtract (change_interval)) < 0) {
base.OnProgressChanged (percentage);
base.OnProgressChanged (percentage, speed);
last_change = DateTime.Now;
}
}
@ -187,10 +212,10 @@ namespace SparkleLib.Git {
break;
Thread.Sleep (500);
base.OnProgressChanged (percentage);
base.OnProgressChanged (percentage, 0);
}
base.OnProgressChanged (100);
base.OnProgressChanged (100, 0);
InstallConfiguration ();
InstallExcludeRules ();

View file

@ -60,11 +60,11 @@ namespace SparkleLib {
public static string ToSize (this double byte_count)
{
if (byte_count >= 1099511627776)
return String.Format ("{0:##.##} ᴛʙ", Math.Round (byte_count / 1099511627776, 1));
return String.Format ("{0:##.##} ᴛʙ", Math.Round (byte_count / 1099511627776, 2));
else if (byte_count >= 1073741824)
return String.Format ("{0:##.##} ɢʙ", Math.Round (byte_count / 1073741824, 1));
else if (byte_count >= 1048576)
return String.Format ("{0:##.##} ᴍʙ", Math.Round (byte_count / 1048576, 0));
return String.Format ("{0:##.##} ᴍʙ", Math.Round (byte_count / 1048576, 1));
else if (byte_count >= 1024)
return String.Format ("{0:##.##} ᴋʙ", Math.Round (byte_count / 1024, 0));
else

View file

@ -44,7 +44,7 @@ namespace SparkleLib {
public delegate void FinishedEventHandler (bool repo_is_encrypted, bool repo_is_empty, string [] warnings);
public event ProgressChangedEventHandler ProgressChanged = delegate { };
public delegate void ProgressChangedEventHandler (double percentage);
public delegate void ProgressChangedEventHandler (double percentage, double speed);
public abstract bool Fetch ();
@ -53,6 +53,9 @@ namespace SparkleLib {
public abstract bool IsFetchedRepoPasswordCorrect (string password);
public abstract void EnableFetchedRepoCrypto (string password);
public double ProgressPercentage { get; private set; }
public double ProgressSpeed { get; private set; }
public Uri RemoteUrl { get; protected set; }
public string RequiredFingerprint { get; protected set; }
public readonly bool FetchPriorHistory = false;
@ -232,8 +235,8 @@ namespace SparkleLib {
}
protected void OnProgressChanged (double percentage) {
ProgressChanged (percentage);
protected void OnProgressChanged (double percentage, double speed) {
ProgressChanged (percentage, speed);
}

View file

@ -16,11 +16,12 @@ namespace SparkleLib {
public override bool Fetch ()
{
if (RemoteUrl.Host.EndsWith(".onion")) {
if (RemoteUrl.Host.EndsWith (".onion")) {
// Tor has special domain names called ".onion addresses". They can only be
// resolved by using a proxy via tor. While the rest of the openssh suite
// fully supports proxying, ssh-keyscan does not, so we can't use it for .onion
SparkleLogger.LogInfo ("Auth", "using tor .onion address skipping ssh-keyscan");
} else if (!RemoteUrl.Scheme.StartsWith ("http")) {
string host_key = FetchHostKey ();

View file

@ -37,7 +37,7 @@ namespace SparkleShare {
private NSTextField FullNameTextField, FullNameLabel, EmailLabel, EmailTextField,
LinkCodeTextField, AddressTextField, AddressLabel, AddressHelpLabel, PathTextField, PathLabel,
PathHelpLabel, PasswordTextField, VisiblePasswordTextField, PasswordLabel, WarningTextField;
PathHelpLabel, ProgressLabel, PasswordTextField, VisiblePasswordTextField, PasswordLabel, WarningTextField;
private NSButton StartupCheckButton, HistoryCheckButton, ShowPasswordCheckButton;
private NSProgressIndicator ProgressIndicator;
@ -368,16 +368,22 @@ namespace SparkleShare {
Enabled = false
};
ProgressLabel = new SparkleLabel ("", NSTextAlignment.Right);
ProgressLabel.Frame = new RectangleF (Frame.Width - 40 - 75, 185, 75, 25);
Controller.UpdateProgressBarEvent += delegate (double percentage) {
Controller.UpdateProgressBarEvent += delegate (double percentage, string speed) {
Program.Controller.Invoke (() => {
ProgressIndicator.DoubleValue = percentage;
ProgressLabel.StringValue = speed;
});
};
CancelButton.Activated += delegate { Controller.SyncingCancelled (); };
ContentView.AddSubview (ProgressLabel);
ContentView.AddSubview (ProgressIndicator);
Buttons.Add (FinishButton);

View file

@ -57,7 +57,7 @@ namespace SparkleShare {
public delegate void FolderFetchErrorHandler (string remote_url, string [] errors);
public event FolderFetchingHandler FolderFetching = delegate { };
public delegate void FolderFetchingHandler (double percentage);
public delegate void FolderFetchingHandler (double percentage, double speed);
public event Action FolderListChanged = delegate { };
@ -433,6 +433,7 @@ namespace SparkleShare {
};
this.repositories.Add (repo);
this.repositories.Sort ((x, y) => string.Compare (x.Name, y.Name));
repo.Initialize ();
}
@ -587,8 +588,8 @@ namespace SparkleShare {
StopFetcher ();
};
this.fetcher.ProgressChanged += delegate (double percentage) {
FolderFetching (percentage);
this.fetcher.ProgressChanged += delegate (double percentage, double speed) {
FolderFetching (percentage, speed);
};
this.fetcher.Start ();

View file

@ -53,7 +53,7 @@ namespace SparkleShare {
public delegate void ChangePageEventHandler (PageType page, string [] warnings);
public event UpdateProgressBarEventHandler UpdateProgressBarEvent = delegate { };
public delegate void UpdateProgressBarEventHandler (double percentage);
public delegate void UpdateProgressBarEventHandler (double percentage, string speed);
public event UpdateSetupContinueButtonEventHandler UpdateSetupContinueButtonEvent = delegate { };
public delegate void UpdateSetupContinueButtonEventHandler (bool button_enabled);
@ -409,10 +409,14 @@ namespace SparkleShare {
Program.Controller.FolderFetching -= SyncingPageFetchingDelegate;
}
private void SyncingPageFetchingDelegate (double percentage)
private void SyncingPageFetchingDelegate (double percentage, double speed)
{
ProgressBarPercentage = percentage;
UpdateProgressBarEvent (ProgressBarPercentage);
if (speed == 0.0)
UpdateProgressBarEvent (ProgressBarPercentage, "");
else
UpdateProgressBarEvent (ProgressBarPercentage, speed.ToSize () + "/s");
}