Beispiel #1
0
        private void PushDirectory(LocalDirectory localDirectory, FtpPath ftpParentPath)
        {
            var ftpPath = ftpParentPath.GetChildPath(localDirectory.Name);

            FtpRetry.ConnectedCall(_mainClient, ftpParentPath.Absolute, c => c.CreateDirectory(localDirectory.Name));
            PushDirectoryContents(localDirectory, ftpPath);
        }
Beispiel #2
0
        private bool DeleteFtpDirectory(FtpPath path)
        {
            Log(path.Depth, ItemAction.Delete, path.Name);
            var parentWorkingDirectory = _remoteWorkingDirectory;
            var itemsRemain            = false;

            foreach (var child in _mainClient.GetListing(path.Name, FtpListOption.AllFiles))
            {
                var childPath = path.GetChildPath(child.Name);
                var exclude   = MatchExcludes(childPath.Relative);
                if (exclude != null)
                {
                    Log(path.Depth + 1, ItemAction.Skip, child.Name, $"excluded ({exclude.Original})");
                    itemsRemain = true;
                    continue;
                }

                EnsureRemoteWorkingDirectory(path.Absolute);
                if (!DeleteFtpAny(childPath, child.Type))
                {
                    itemsRemain = true;
                }
            }
            EnsureRemoteWorkingDirectory(parentWorkingDirectory);
            if (itemsRemain)
            {
                Log(path.Depth + 1, ItemAction.Skip, $"# dir '{path.Name}' not deleted (items remain)");
                return(false);
            }
            FtpRetry.ConnectedCall(_mainClient, parentWorkingDirectory, c => c.DeleteDirectory(path.Name));
            return(true);
        }
Beispiel #3
0
        private Task SynchronizeFileAsync(LocalFile localFile, FtpPath parentPath, FtpListItem remote)
        {
            if (remote == null)
            {
                Log(localFile.Depth, ItemAction.Add, localFile.Name);
                return(PushFileAsync(localFile));
            }

            if (remote.Type == FtpFileSystemObjectType.Directory)
            {
                DeleteFtpDirectory(parentPath.GetChildPath(remote.Name));
                Log(localFile.Depth, ItemAction.Replace, localFile.Name);
                return(PushFileAsync(localFile));
            }

            if (remote.Type == FtpFileSystemObjectType.Link)
            {
                Log(localFile.Depth, ItemAction.Replace, localFile.Name, "remote is a link");
                return(PushFileAsync(localFile));
            }

            if (remote.Modified.ToLocalTime().TruncateToMinutes() != localFile.LastWriteTime.TruncateToMinutes())
            {
                Log(localFile.Depth, ItemAction.Replace, localFile.Name);
                return(PushFileAsync(localFile));
            }

            Log(localFile.Depth, ItemAction.Skip, localFile.Name);
            return(null); // I know it's bad style, but it optimizes the collection/wait for a common case when everything is up to date
        }
Beispiel #4
0
        private void SynchronizeDirectory(LocalDirectory localDirectory, FtpPath ftpPath)
        {
            Log(localDirectory.Depth, ItemAction.Synchronize, localDirectory.Name);

            EnsureRemoteWorkingDirectory(ftpPath.Absolute);
            var allRemote = FtpRetry.ConnectedCall(_mainClient, ftpPath.Absolute, c => c.GetListing(".", FtpListOption.AllFiles))
                            .ToDictionary(l => l.Name, StringComparer.OrdinalIgnoreCase);
            var allRemoteFound = new HashSet <FtpListItem>();

            var pushTasks = new List <Task>();

            foreach (var local in localDirectory.EnumerateChildren())
            {
                var remote  = allRemote.GetValueOrDefault(local.Name);
                var exclude = MatchExcludes(local.RelativePath);
                if (exclude != null)
                {
                    Log(localDirectory.Depth + 1, ItemAction.Skip, local.Name, $"excluded ({exclude.Original})");
                    allRemoteFound.Add(remote);
                    continue;
                }

                EnsureRemoteWorkingDirectory(ftpPath.Absolute);

                if (remote != null)
                {
                    allRemoteFound.Add(remote);
                }

                var localAsDirectory = local as LocalDirectory;
                if (localAsDirectory != null)
                {
                    if (remote == null)
                    {
                        Log(localDirectory.Depth + 1, ItemAction.Add, localAsDirectory.Name);
                        PushDirectory(localAsDirectory, ftpPath);
                        continue;
                    }

                    if (remote.Type == FtpFileSystemObjectType.Directory)
                    {
                        SynchronizeDirectory(localAsDirectory, ftpPath.GetChildPath(remote.Name));
                        continue;
                    }

                    DeleteFtpFile(ftpPath.GetChildPath(remote.Name));
                    Log(localDirectory.Depth + 1, ItemAction.Add, localAsDirectory.Name);
                    PushDirectory(localAsDirectory, ftpPath);
                    continue;
                }

                var localAsFile = (LocalFile)local;
                var pushTask    = SynchronizeFileAsync(localAsFile, ftpPath, remote);
                if (pushTask != null)
                {
                    pushTasks.Add(pushTask);
                }
            }
            if (pushTasks.Count > 0)
            {
                Task.WaitAll(pushTasks.ToArray());
            }

            EnsureRemoteWorkingDirectory(ftpPath.Absolute);
            foreach (var missing in allRemote.Values.Except(allRemoteFound))
            {
                var missingPath = ftpPath.GetChildPath(missing.Name);
                var exclude     = MatchExcludes(missingPath.Relative);
                if (exclude != null)
                {
                    Log(localDirectory.Depth + 1, ItemAction.Skip, missing.Name, $"excluded ({exclude.Original})");
                    continue;
                }
                DeleteFtpAny(missingPath, missing.Type);
            }
        }