public SparkleRepo(string path) { LocalPath = path; Name = Path.GetFileName(LocalPath); RemoteOriginUrl = GetRemoteOriginUrl(); RemoteName = Path.GetFileNameWithoutExtension(RemoteOriginUrl); Domain = GetDomain(RemoteOriginUrl); Description = GetDescription(); UserName = GetUserName(); UserEmail = GetUserEmail(); _IsSyncing = false; _IsBuffering = false; _IsPolling = true; _IsFetching = false; _IsPushing = false; _ServerOnline = true; HasChanged = false; ChangeLock = new Object(); FetchQueue = 0; AnnounceQueue = 0; if (IsEmpty) { _CurrentHash = null; } else { _CurrentHash = GetCurrentHash(); } string unsynced_file_path = SparkleHelpers.CombineMore(LocalPath, ".git", "has_unsynced_changes"); if (File.Exists(unsynced_file_path)) { _HasUnsyncedChanges = true; } else { _HasUnsyncedChanges = false; } if (_CurrentHash == null) { CreateInitialCommit(); } // Watch the repository's folder Watcher = new FileSystemWatcher(LocalPath) { IncludeSubdirectories = true, EnableRaisingEvents = true, Filter = "*" }; Watcher.Changed += new FileSystemEventHandler(OnFileActivity); Watcher.Created += new FileSystemEventHandler(OnFileActivity); Watcher.Deleted += new FileSystemEventHandler(OnFileActivity); Watcher.Renamed += new RenamedEventHandler(OnFileActivity); // Listen to the irc channel on the server... if (UsesNotificationCenter) { Listener = new SparkleListener(Domain, RemoteName, UserEmail, NotificationServerType.Central); } else { Listener = new SparkleListener(Domain, RemoteName, UserEmail, NotificationServerType.Own); } // ...fetch remote changes every 60 seconds if that fails RemoteTimer = new Timer() { Interval = 60000 }; RemoteTimer.Elapsed += delegate { if (_IsPolling) { CheckForRemoteChanges(); if (!Listener.Client.IsConnected) { SparkleHelpers.DebugInfo("Irc", "[" + Name + "] Trying to reconnect..."); Listener.Listen(); } } if (_HasUnsyncedChanges) { FetchRebaseAndPush(); } }; // Stop polling when the connection to the irc channel is succesful Listener.Client.OnConnected += delegate { _IsPolling = false; // Check for changes manually one more time CheckForRemoteChanges(); // Push changes that were made since the last disconnect if (_HasUnsyncedChanges) { Push(); } SparkleHelpers.DebugInfo("Irc", "[" + Name + "] Connected. Now listening... (" + Listener.Server + ")"); if (AnnounceQueue > 0) { Listener.Announce(_CurrentHash); AnnounceQueue = 0; SparkleHelpers.DebugInfo("Irc", "[" + Name + "] Queued messages delivered. (" + Listener.Server + ")"); } }; // Start polling when the connection to the irc channel is lost Listener.Client.OnConnectionError += delegate { SparkleHelpers.DebugInfo("Irc", "[" + Name + "] Lost connection. Falling back to polling..."); _IsPolling = true; }; // Start polling when the connection to the irc channel is lost Listener.Client.OnDisconnected += delegate { SparkleHelpers.DebugInfo("Irc", "[" + Name + "] Lost connection. Falling back to polling..."); _IsPolling = true; }; // Fetch changes when there is a message in the irc channel Listener.Client.OnChannelMessage += delegate(object o, IrcEventArgs args) { SparkleHelpers.DebugInfo("Irc", "[" + Name + "] Was notified of a remote change..."); string message = args.Data.Message.Trim(); if (!message.Equals(_CurrentHash) && message.Length == 40) { FetchQueue++; if (_IsBuffering) { SparkleHelpers.DebugInfo("Irc", "[" + Name + "] ...but we're busy adding files. We'll fetch them later."); } else if (!_IsFetching) { while (FetchQueue > 0) { Fetch(); FetchQueue--; } Watcher.EnableRaisingEvents = false; Rebase(); Watcher.EnableRaisingEvents = true; } } else { // Not really needed as we won't be notified about our own messages SparkleHelpers.DebugInfo("Irc", "[" + Name + "] False alarm, already up to date. (" + _CurrentHash + ")"); } }; // Start listening Listener.Listen(); SizeBuffer = new List <double> (); // Keep a timer that checks if there are changes and // whether they have settled LocalTimer = new Timer() { Interval = 250 }; LocalTimer.Elapsed += delegate(object o, ElapsedEventArgs args) { CheckForChanges(); }; RemoteTimer.Start(); LocalTimer.Start(); // Add everything that changed // since SparkleShare was stopped AddCommitAndPush(); if (_CurrentHash == null) { _CurrentHash = GetCurrentHash(); } }
// Pushes the changes to the remote repo public void Push() { _IsSyncing = true; _IsPushing = true; SparkleGit git = new SparkleGit(LocalPath, "push origin master"); SparkleHelpers.DebugInfo("Git", "[" + Name + "] Pushing changes..."); SparkleEventArgs args = new SparkleEventArgs("PushingStarted"); if (PushingStarted != null) { PushingStarted(this, args); } git.Exited += delegate { _IsSyncing = false; _IsPushing = false; if (git.ExitCode != 0) { SparkleHelpers.DebugInfo("Git", "[" + Name + "] Pushing failed."); string unsynced_file_path = SparkleHelpers.CombineMore(LocalPath, ".git", "has_unsynced_changes"); if (!File.Exists(unsynced_file_path)) { File.Create(unsynced_file_path); } _HasUnsyncedChanges = true; args = new SparkleEventArgs("PushingFailed"); if (PushingFailed != null) { PushingFailed(this, args); } CheckForRemoteChanges(); Push(); } else { SparkleHelpers.DebugInfo("Git", "[" + Name + "] Changes pushed."); args = new SparkleEventArgs("PushingFinished"); string unsynced_file_path = SparkleHelpers.CombineMore(LocalPath, ".git", "has_unsynced_changes"); if (File.Exists(unsynced_file_path)) { File.Delete(unsynced_file_path); } _HasUnsyncedChanges = false; if (PushingFinished != null) { PushingFinished(this, args); } if (!_IsPolling) { Listener.Announce(_CurrentHash); } } }; git.Start(); git.WaitForExit(); }