diff --git a/SparkleLib/Git/SparkleFetcherGit.cs b/SparkleLib/Git/SparkleFetcherGit.cs index f9241956..5b0e0098 100755 --- a/SparkleLib/Git/SparkleFetcherGit.cs +++ b/SparkleLib/Git/SparkleFetcherGit.cs @@ -93,7 +93,10 @@ namespace SparkleLib { 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); + while (!this.git.StandardError.EndOfStream) { string line = this.git.StandardError.ReadLine (); Match match = progress_regex.Match (line); @@ -107,7 +110,7 @@ namespace SparkleLib { // the "Receiving objects" stage which we count as the last 80% if (line.Contains ("|")) // "Receiving objects" stage - number = (number / 100 * 75 + 20); + number = (number / 100 * 80 + 20); else // "Compressing objects" stage number = (number / 100 * 20); @@ -115,20 +118,21 @@ namespace SparkleLib { if (number >= percentage) { percentage = number; - - // FIXME: for some reason it doesn't go above 95% - base.OnProgressChanged (percentage); + + if (DateTime.Compare (last_change, DateTime.Now.Subtract (change_interval)) < 0) { + base.OnProgressChanged (percentage); + last_change = DateTime.Now; + } } - - System.Threading.Thread.Sleep (100); } this.git.WaitForExit (); - SparkleHelpers.DebugInfo ("Git", "Exit code " + this.git.ExitCode.ToString ()); + if (this.git.ExitCode != 0) { return false; + } else { InstallConfiguration (); InstallExcludeRules (); diff --git a/SparkleLib/Git/SparkleRepoGit.cs b/SparkleLib/Git/SparkleRepoGit.cs index d25bdb19..7d220e18 100755 --- a/SparkleLib/Git/SparkleRepoGit.cs +++ b/SparkleLib/Git/SparkleRepoGit.cs @@ -172,11 +172,66 @@ namespace SparkleLib { Commit (message); } - SparkleGit git = new SparkleGit (LocalPath, "push origin master"); + + SparkleGit git = new SparkleGit (LocalPath, + "push --progress " + // Redirects progress stats to standarderror + "origin master"); + + git.StartInfo.RedirectStandardError = true; git.Start (); - git.StandardOutput.ReadToEnd (); + + 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); + + while (!git.StandardError.EndOfStream) { + string line = git.StandardError.ReadLine (); + Match match = progress_regex.Match (line); + string speed = ""; + double number = 0.0; + + if (match.Success) { + number = double.Parse (match.Groups [1].Value); + + // The cloning 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.StartsWith ("Compressing")) { + // "Compressing objects" stage + number = (number / 100 * 20); + + } else { + // "Writing objects" stage + number = (number / 100 * 80 + 20); + + if (line.Contains ("|")) { + speed = line.Substring (line.IndexOf ("|") + 1).Trim (); + speed = speed.Replace (", done.", "").Trim (); + speed = speed.Replace ("i", ""); + speed = speed.Replace ("KB/s", "ᴋʙ/s"); + speed = speed.Replace ("MB/s", "ᴍʙ/s"); + } + } + } + + if (number >= percentage) { + percentage = number; + + if (percentage == 100.0) + percentage = 99.0; + + if (DateTime.Compare (last_change, DateTime.Now.Subtract (change_interval)) < 0) { + base.OnSyncProgressChanged (percentage, speed); + last_change = DateTime.Now; + } + } + } + git.WaitForExit (); + if (git.ExitCode == 0) return true; else @@ -239,6 +294,7 @@ namespace SparkleLib { if (value) { if (!File.Exists (unsynced_file_path)) File.Create (unsynced_file_path).Close (); + } else { File.Delete (unsynced_file_path); } diff --git a/SparkleLib/SparkleRepoBase.cs b/SparkleLib/SparkleRepoBase.cs index 867e602b..67f4d735 100755 --- a/SparkleLib/SparkleRepoBase.cs +++ b/SparkleLib/SparkleRepoBase.cs @@ -44,11 +44,13 @@ namespace SparkleLib { private TimeSpan poll_interval; private System.Timers.Timer local_timer = new System.Timers.Timer () { Interval = 0.25 * 1000 }; private System.Timers.Timer remote_timer = new System.Timers.Timer () { Interval = 10 * 1000 }; - private DateTime last_poll = DateTime.Now; - private List sizebuffer = new List (); - private bool has_changed = false; - private Object change_lock = new Object (); - private Object watch_lock = new Object (); + private DateTime last_poll = DateTime.Now; + private List sizebuffer = new List (); + private bool has_changed = false; + private Object change_lock = new Object (); + private Object watch_lock = new Object (); + private double progress_percentage = 0.0; + private string progress_speed = ""; protected SparkleListenerBase listener; protected SyncStatus status; @@ -74,6 +76,9 @@ namespace SparkleLib { public delegate void SyncStatusChangedEventHandler (SyncStatus new_status); public event SyncStatusChangedEventHandler SyncStatusChanged; + public delegate void SyncProgressChangedEventHandler (double percentage, string speed); + public event SyncProgressChangedEventHandler SyncProgressChanged; + public delegate void NewChangeSetEventHandler (SparkleChangeSet change_set); public event NewChangeSetEventHandler NewChangeSet; @@ -156,6 +161,20 @@ namespace SparkleLib { } + public double ProgressPercentage { + get { + return this.progress_percentage; + } + } + + + public string ProgressSpeed { + get { + return this.progress_speed; + } + } + + public virtual string [] UnsyncedFilePaths { get { return new string [0]; @@ -297,7 +316,7 @@ namespace SparkleLib { } - private bool IsSyncing { + public bool IsSyncing { get { return (Status == SyncStatus.SyncUp || Status == SyncStatus.SyncDown || @@ -461,6 +480,9 @@ namespace SparkleLib { } finally { this.remote_timer.Start (); EnableWatching (); + + this.progress_percentage = 0.0; + this.progress_speed = ""; } } @@ -526,6 +548,9 @@ namespace SparkleLib { this.remote_timer.Start (); EnableWatching (); + + this.progress_percentage = 0.0; + this.progress_speed = ""; } @@ -596,6 +621,16 @@ namespace SparkleLib { } + protected void OnSyncProgressChanged (double progress_percentage, string progress_speed) + { + this.progress_percentage = progress_percentage; + this.progress_speed = progress_speed; + + if (SyncProgressChanged != null) + SyncProgressChanged (progress_percentage, progress_speed); + } + + // Creates a SHA-1 hash of input private string SHA1 (string s) { diff --git a/SparkleShare/Mac/SparkleStatusIcon.cs b/SparkleShare/Mac/SparkleStatusIcon.cs index 7e57f662..1e414857 100755 --- a/SparkleShare/Mac/SparkleStatusIcon.cs +++ b/SparkleShare/Mac/SparkleStatusIcon.cs @@ -110,7 +110,10 @@ namespace SparkleShare { case IconState.Syncing: - StateText = _("Syncing…"); + StateText = _("Syncing… " + + Controller.ProgressPercentage + "% " + + Controller.ProgressSpeed); + StateMenuItem.Title = StateText; if (!Animation.Enabled) diff --git a/SparkleShare/SparkleControllerBase.cs b/SparkleShare/SparkleControllerBase.cs index fd6c6524..16676e18 100755 --- a/SparkleShare/SparkleControllerBase.cs +++ b/SparkleShare/SparkleControllerBase.cs @@ -37,6 +37,9 @@ namespace SparkleShare { public List Repositories; public readonly string SparklePath = SparkleConfig.DefaultConfig.FoldersPath; + public double ProgressPercentage = 0.0; + public string ProgressSpeed = ""; + public event OnQuitWhileSyncingHandler OnQuitWhileSyncing; public delegate void OnQuitWhileSyncingHandler (); @@ -586,11 +589,11 @@ namespace SparkleShare { }; repo.SyncStatusChanged += delegate (SyncStatus status) { -/* if (status == SyncStatus.SyncUp) { - foreach (string path in repo.UnsyncedFilePaths) - Console.WriteLine (path); + if (status == SyncStatus.Idle) { + ProgressPercentage = 0.0; + ProgressSpeed = ""; } -*/ + if (status == SyncStatus.Idle || status == SyncStatus.SyncUp || status == SyncStatus.SyncDown || @@ -600,6 +603,13 @@ namespace SparkleShare { } }; + repo.SyncProgressChanged += delegate (double percentage, string speed) { + ProgressPercentage = percentage; + ProgressSpeed = speed; + + UpdateState (); + }; + repo.ChangesDetected += delegate { UpdateState (); }; diff --git a/SparkleShare/SparkleStatusIconController.cs b/SparkleShare/SparkleStatusIconController.cs index e322348c..e8394139 100755 --- a/SparkleShare/SparkleStatusIconController.cs +++ b/SparkleShare/SparkleStatusIconController.cs @@ -58,6 +58,19 @@ namespace SparkleShare { } + public int ProgressPercentage { + get { + return (int) Program.Controller.ProgressPercentage; + } + } + + public string ProgressSpeed { + get { + return Program.Controller.ProgressSpeed; + } + } + + public SparkleStatusIconController () { Program.Controller.FolderListChanged += delegate { @@ -65,6 +78,7 @@ namespace SparkleShare { UpdateMenuEvent (CurrentState); }; + Program.Controller.OnIdle += delegate { if (CurrentState != IconState.Error) CurrentState = IconState.Idle; @@ -73,6 +87,7 @@ namespace SparkleShare { UpdateMenuEvent (CurrentState); }; + Program.Controller.OnSyncing += delegate { CurrentState = IconState.Syncing; @@ -80,6 +95,7 @@ namespace SparkleShare { UpdateMenuEvent (IconState.Syncing); }; + Program.Controller.OnError += delegate { CurrentState = IconState.Error;