Example #1
0
        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();
            }
        }
Example #2
0
        // 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();
        }