Exemple #1
0
        /// <summary>
        /// Returns a fully recursive listing inside the specified (directory) item
        /// </summary>
        /// <param name="p">The clientItem (should be of type directory) to list inside</param>
        /// <param name="skipIgnored">if true, ignored items are not returned</param>
        private IEnumerable <ClientItem> ListRecursiveInside(ClientItem p, bool skipIgnored = true)
        {
            yield return(p);

            var cpath = controller.GetCommonPath(p.FullPath, false);

            var list = new List <ClientItem>(List(cpath, skipIgnored).ToList());

            if (ListingFailed)
            {
                yield break;
            }

            if (skipIgnored)
            {
                list.RemoveAll(x => !controller.ItemGetsSynced(x.FullPath, false));
            }

            foreach (var f in list.Where(x => x.Type == ClientItemType.File))
            {
                yield return(f);
            }

            foreach (var d in list.Where(x => x.Type == ClientItemType.Folder))
            {
                foreach (var f in ListRecursiveInside(d, skipIgnored))
                {
                    yield return(f);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Raised when a file was changed
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void FileChanged(object source, FileSystemEventArgs e)
        {
            string cpath = controller.GetCommonPath(e.FullPath, true);

            if (!controller.ItemGetsSynced(cpath) || !File.Exists(e.FullPath))
            {
                return;
            }

            int retries = 0;

            while (true)
            {
                if (!Common.FileIsUsed(e.FullPath))
                {
                    break;
                }
                // Exit after 5 retries
                if (retries > 5)
                {
                    return;
                }
                // Sleep for half a second, then check again
                System.Threading.Thread.Sleep(500);
                retries++;
            }

        #if __MonoCs__
            // Ignore temp files on linux
            if (Common._name(cpath).StartsWith(".goutputstream-") || Common._name(cpath).EndsWith("~"))
            {
                return;
            }
        #endif

            var fli = new FileInfo(e.FullPath);

            controller.SyncQueue.Add(new SyncQueueItem(controller)
            {
                Item = new ClientItem
                {
                    Name          = e.Name,
                    FullPath      = e.FullPath,
                    Type          = ClientItemType.File,
                    Size          = fli.Length,
                    LastWriteTime = fli.LastWriteTime
                },
                SyncTo     = SyncTo.Remote,
                ActionType = e.ChangeType == WatcherChangeTypes.Changed ? ChangeAction.changed : ChangeAction.created
            });
        }
Exemple #3
0
        /// <summary>
        /// Raised when file/folder is renamed
        /// </summary>
        private async void OnRenamed(object source, RenamedEventArgs e)
        {
            Log.Write(l.Debug, $"Item was renamed: {e.OldName}");

            if (!_controller.ItemGetsSynced(e.FullPath, true))
            {
                return;
            }

            var isFile = Common.PathIsFile(e.FullPath);
            // Find if renamed from/to temporary file
            var renamedFromTempFile = new FileInfo(e.OldFullPath).Attributes.HasFlag(FileAttributes.Temporary);
            var renamedToTempFile   = new FileInfo(e.FullPath).Attributes.HasFlag(FileAttributes.Temporary);
            // Get common path to old (renamed) file
            var oldCommon = _controller.GetCommonPath(e.OldFullPath, true);

            Log.Write(l.Debug, $"isFile: {isFile} renamedFromTempFile: {renamedFromTempFile} renamedToTempFile: {renamedToTempFile} inFileLog: {_controller.FileLog.Contains(oldCommon)}");

            // Add to queue
            if (isFile && renamedFromTempFile && !renamedToTempFile && !_controller.FileLog.Contains(oldCommon))
            {
                await AddToQueue(e, ChangeAction.changed);
            }
            else
            {
                await AddToQueue(e, ChangeAction.renamed);
            }
        }
Exemple #4
0
        /// <summary>
        ///     Returns a fully recursive listing inside the specified (directory) item
        /// </summary>
        /// <param name="p">The clientItem (should be of type directory) to list inside</param>
        /// <param name="skipIgnored">if true, ignored items are not returned</param>
        private async Task <IEnumerable <ClientItem> > ListRecursiveInside(ClientItem p, bool skipIgnored = true)
        {
            var cpath = Controller.GetCommonPath(p.FullPath, false);

            var list = await List(cpath, skipIgnored);

            if (ListingFailed)
            {
                return(default(IEnumerable <ClientItem>));
            }

            if (skipIgnored)
            {
                list = list.Where(x => !Controller.ItemSkipped(x));
            }

            var subItems = list.Where(x => x.Type == ClientItemType.File).ToList();

            foreach (var d in list.Where(x => x.Type == ClientItemType.Folder))
            {
                subItems.Add(d);
                foreach (var f in await ListRecursiveInside(d, skipIgnored))
                {
                    subItems.Add(f);
                }
            }

            return(subItems);
        }
Exemple #5
0
        /// <summary>
        /// Check a local folder and all of its subitems for changes
        /// </summary>
        private void CheckLocalFolder(SyncQueueItem folder)
        {
            if (!_controller.ItemGetsSynced(folder.CommonPath) && folder.CommonPath != ".")
            {
                return;
            }

            var cp = (folder.Item.FullPath == _controller.Paths.Local) ? "." : folder.CommonPath;

            var cpExists = cp == "." || _controller.Client.Exists(cp);

            if (!cpExists)
            {
                folder.AddedOn = DateTime.Now;
                base.Add(folder);
            }

            var remoteFilesList = cpExists ? new List <string>(_controller.Client.ListRecursive(cp).Select(x => x.FullPath)) : new List <string>();

            remoteFilesList = remoteFilesList.ConvertAll(x => _controller.GetCommonPath(x, false));

            if (_controller.Client.ListingFailed)
            {
                folder.Status      = StatusType.Failure;
                folder.CompletedOn = DateTime.Now;
                _completedList.Add(folder);
                _controller.Client.Reconnect();
                return;
            }

            var di = new DirectoryInfo(folder.LocalPath);

            foreach (var d in di.GetDirectories("*", SearchOption.AllDirectories).Where(x => !remoteFilesList.Contains(_controller.GetCommonPath(x.FullName, true))))
            {
                if (!_controller.ItemGetsSynced(d.FullName, true))
                {
                    continue;
                }

                // TODO: Base add instead?
                Add(new SyncQueueItem(_controller)
                {
                    Item = new ClientItem {
                        Name          = d.Name,
                        FullPath      = d.FullName,
                        Type          = ClientItemType.Folder,
                        LastWriteTime = DateTime.Now,   // Doesn't matter
                        Size          = 0x0             // Doesn't matter
                    },
                    ActionType = ChangeAction.changed,
                    Status     = StatusType.Waiting,
                    SyncTo     = SyncTo.Remote
                });
            }

            foreach (var f in di.GetFiles("*", SearchOption.AllDirectories))
            {
                var cpath = _controller.GetCommonPath(f.FullName, true);
                if (!_controller.ItemGetsSynced(cpath))
                {
                    continue;
                }

                if (!remoteFilesList.Contains(cpath) || _controller.FileLog.GetLocal(cpath) != f.LastWriteTime)
                {
                    // TODO: Base add instead?
                    Add(new SyncQueueItem(_controller)
                    {
                        Item = new ClientItem
                        {
                            Name          = f.Name,
                            FullPath      = f.FullName,
                            Type          = ClientItemType.File,
                            LastWriteTime = File.GetLastWriteTime(f.FullName),
                            Size          = new FileInfo(f.FullName).Length
                        },
                        ActionType = ChangeAction.changed,
                        Status     = StatusType.Waiting,
                        SyncTo     = SyncTo.Remote
                    });
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Check a local folder and all of its subitems for changes
        /// </summary>
        private async Task CheckLocalFolder(SyncQueueItem folder)
        {
            if (!_controller.ItemGetsSynced(folder.CommonPath) && folder.CommonPath != ".")
            {
                return;
            }

            var cp = (folder.Item.FullPath == _controller.Paths.Local) ? "." : folder.CommonPath;

            var cpExists = cp == "." || _controller.Client.Exists(cp);

            if (!cpExists)
            {
                folder.AddedOn = DateTime.Now;
                base.Add(folder);
            }

            var remoteFilesList = cpExists
                ? (await _controller.Client.ListRecursive(cp)).Select(x => x.FullPath).ToList()
                : new List <string>();

            remoteFilesList = remoteFilesList.ConvertAll(x => _controller.GetCommonPath(x, false));

            if (_controller.Client.ListingFailed)
            {
                folder.Status      = StatusType.Failure;
                folder.CompletedOn = DateTime.Now;
                _completedList.Add(folder, StatusType.Failure);
                await _controller.Client.Reconnect();

                return;
            }

            var di = new DirectoryInfo(folder.LocalPath);

            foreach (var d in di.GetDirectories("*", SearchOption.AllDirectories))
            {
                var cpath = _controller.GetCommonPath(d.FullName, true);

                if (remoteFilesList.Contains(cpath))
                {
                    continue;
                }
                if (!_controller.ItemGetsSynced(d.FullName, true))
                {
                    continue;
                }

                base.Add(new SyncQueueItem(_controller)
                {
                    Item = new ClientItem(d)
                    {
                        FullPath = d.FullName
                    },
                    ActionType = ChangeAction.changed,
                    Status     = StatusType.Waiting,
                    SyncTo     = SyncTo.Remote
                });
            }

            foreach (var f in di.GetFiles("*", SearchOption.AllDirectories))
            {
                var cpath = _controller.GetCommonPath(f.FullName, true);
                if (!_controller.ItemGetsSynced(cpath))
                {
                    continue;
                }

                if (!remoteFilesList.Contains(cpath) || _controller.FileLog.GetLocal(cpath) != f.LastWriteTime)
                {
                    base.Add(new SyncQueueItem(_controller)
                    {
                        Item       = new ClientItem(f),
                        ActionType = ChangeAction.changed,
                        Status     = StatusType.Waiting,
                        SyncTo     = SyncTo.Remote
                    });
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Check a local folder and all of its subitems for changes
        /// </summary>
        private async Task CheckLocalFolder(SyncQueueItem folder)
        {
            if (_controller.ItemSkipped(folder.Item) && folder.CommonPath != ".")
            {
                return;
            }

            var cp = (folder.Item.FullPath == _controller.Paths.Local) ? "." : folder.CommonPath;

            var cpExists = cp == "." || _controller.Client.Exists(cp);

            if (!cpExists)
            {
                folder.AddedOn = DateTime.Now;
                base.Add(folder);
            }

            var remoteFilesList = cpExists
                ? (await _controller.Client.ListRecursive(cp)).Select(x => x.FullPath).ToList()
                : new List <string>();

            remoteFilesList = remoteFilesList.ConvertAll(x => _controller.GetCommonPath(x, false));

            if (_controller.Client.ListingFailed)
            {
                folder.Status      = StatusType.Failure;
                folder.CompletedOn = DateTime.Now;
                _completedList.Add(folder, StatusType.Failure);
                await _controller.Client.Reconnect();

                return;
            }

            var di = new DirectoryInfo(folder.LocalPath);

            foreach (var d in di.GetDirectories("*", SearchOption.AllDirectories))
            {
                var cpath = _controller.GetCommonPath(d.FullName, true);

                if (remoteFilesList.Contains(cpath))
                {
                    continue;
                }
                if (_controller.ItemSkipped(d))
                {
                    continue;
                }

                base.Add(new SyncQueueItem(_controller)
                {
                    Item = new ClientItem(d)
                    {
                        FullPath = d.FullName
                    },
                    ActionType = ChangeAction.changed,
                    Status     = StatusType.Waiting,
                    SyncTo     = SyncTo.Remote
                });
            }

            foreach (var f in di.GetFiles("*", SearchOption.AllDirectories))
            {
                if (_controller.ItemSkipped(f))
                {
                    continue;
                }

                var sqi = new SyncQueueItem(_controller)
                {
                    Item       = new ClientItem(f),
                    ActionType = ChangeAction.changed,
                    Status     = StatusType.Waiting,
                    SyncTo     = SyncTo.Remote
                };
                var cpath = sqi.CommonPath;

                if (!_controller.FileLog.Contains(cpath) && remoteFilesList.Contains(cpath))
                {
                    // untracked file, exists both locally and on server.
                    var areIdentical = await _controller.Client.FilesAreIdentical(cpath, f.FullName);

                    if (areIdentical)
                    {
                        _controller.FileLog.PutFile(sqi);
                        continue;
                    }
                }
                else if (remoteFilesList.Contains(cpath) && _controller.FileLog.GetLocal(cpath) == f.LastWriteTime)
                {
                    // tracked file, local file unmodified.
                    continue;
                }
                // local file should be uploaded.
                base.Add(sqi);
            }
        }