private T ExecuteAsync <T>(WsPath path, Func <Task <T> > asyncFunc)
 {
     using (ThreadKeeper exec = new ThreadKeeper())
     {
         try
         {
             return(exec.ExecAsync(async(cancellationToken) =>
             {
                 await EnsureLogin();
                 return await asyncFunc();
             }));
         }
         catch (Exception ex)
         {
             try
             {
                 if (ex.InnerException != null)
                 {
                     throw ex.InnerException;
                 }
                 throw;
             }
             catch (FileNotFoundException)
             {
                 ShowError($"Path {path} not found.", null, false);
                 return(default(T));
             }
             catch (DirectoryNotFoundException)
             {
                 ShowError($"Folder {path} not found.", null, false);
                 return(default(T));
             }
         }
     }
 }
        public override bool RemoveDir(RemotePath remoteName)
        {
            if (_moveInProgress)
            {
                return(true);
            }
            WsPath wsPath = remoteName;

            switch (wsPath.Level)
            {
            case WsPathLevel.Root:
                return(false);

            case WsPathLevel.Account:
                if (_uiProvider.ShowMessage(string.Format(Resources.TextResource.UnregisterAccount, wsPath.AccountName), true))
                {
                    return(_accountRepository.UnRegisterAccount(_accountRepository[wsPath.AccountName]));
                }
                return(true);

            case WsPathLevel.AccessLevel:
                return(false);

            default:
                return(_accountRepository[wsPath.AccountName].DeleteFolder(wsPath));
            }
        }
        public override async Task <FileSystemExitCode> GetFileAsync(RemotePath remoteName, string localName, CopyFlags copyFlags, RemoteInfo remoteInfo, Action <int> setProgress, CancellationToken cancellationToken)
        {
            WsPath wsPath = remoteName;

            if (wsPath.Level == WsPathLevel.Account && wsPath.AccountName == ADD_NEW_ACCOUNT_TITLE)
            {
                return(FileSystemExitCode.NotSupported);
            }

            FileInfo localFileName = new FileInfo(localName);
            bool     overWrite     = (CopyFlags.Overwrite & copyFlags) != 0;
            bool     performMove   = (CopyFlags.Move & copyFlags) != 0;
            bool     resume        = (CopyFlags.Resume & copyFlags) != 0;

            if (resume)
            {
                return(FileSystemExitCode.NotSupported);
            }
            if (localFileName.Exists && !overWrite)
            {
                return(FileSystemExitCode.FileExists);
            }

            return(await _accountRepository[wsPath.AccountName].DownloadFile(
                       wsPath,
                       localFileName,
                       overWrite,
                       new Progress <int>(setProgress),
                       performMove,
                       cancellationToken
                       ));
        }
        public async Task <FileSystemExitCode> UploadFile(FileInfo sourceFileName, WsPath targetFileName, bool overwrite, IProgress <int> progress, CancellationToken cancellationToken)
        {
            try
            {
                await EnsureLogin();

                bool       uploadDirect   = overwrite;
                WsFilePath targetFilePath = targetFileName.GetFilePath();
                if (overwrite == false)
                {
                    WsFile file = await _apiClient.FindFile(targetFilePath);

                    if (file != null)
                    {
                        if (overwrite == false)
                        {
                            return(FileSystemExitCode.FileExists);
                        }
                        using (FileStream sourceStream = sourceFileName.OpenRead())
                        {
                            await file.Replace(sourceStream, cancellationToken, progress);
                        }
                    }
                    else
                    {
                        uploadDirect = true;
                    }
                }
                if (uploadDirect)
                {
                    using (FileStream sourceStream = sourceFileName.OpenRead())
                    {
                        await _apiClient.UploadFile(sourceStream, sourceStream.Length, targetFilePath, cancellationToken, progress);
                    }
                }
                return(FileSystemExitCode.OK);
            }
            catch (TaskCanceledException)
            {
                return(FileSystemExitCode.UserAbort);
            }
            catch (FileNotFoundException)
            {
                return(FileSystemExitCode.FileNotFound);
            }
            // TODO: dialog for file password, Exception throw in WsApiClient.CheckResultStatus
            //catch (??)
            //{
            //    return ??;
            //}
            catch (Exception ex)
            {
                if (ShowError("Upload file error", ex, true) == false)
                {
                    return(FileSystemExitCode.UserAbort);
                }
                return(FileSystemExitCode.ReadError);
            }
        }
        public override PreviewBitmapResult GetPreviewBitmap(RemotePath remoteName, int width, int height)
        {
            WsPath sourcePath = remoteName;

            if (sourcePath.Level == WsPathLevel.Folder && sourcePath.Parent != "/") // Preview for root folder not supported
            {
                return(_accountRepository[sourcePath.AccountName].GetPreviewBitmap(sourcePath, width, height));
            }
            return(base.GetPreviewBitmap(remoteName, width, height));
        }
 public WsFolder CreateFolder(WsPath folderPath)
 {
     try
     {
         return(ExecuteAsync(folderPath, () => _apiClient.CreateFolder(folderPath, folderPath.IsPrivate)));
     }
     catch (Exception ex)
     {
         ShowError("Create folder error", ex, false);
         return(null);
     }
 }
 public IDisposableEnumerable <FindData> GetFolderAllFilesRecursive(WsPath folderPath, int depth = int.MaxValue)
 {
     try
     {
         return(ExecuteAsync(folderPath, async() => (IDisposableEnumerable <FindData>) new FolderItems(await _apiClient.GetFolderAllFilesRecursive(folderPath.GetFolderPath(), depth))));
     }
     catch (Exception ex)
     {
         ShowError("Get all files recursive error", ex, false);
         return(FolderItems.Empty);
     }
 }
        public override ExecResult ExecuteOpen(TcWindow mainWin, RemotePath remoteName)
        {
            WsPath wsPath = remoteName;

            switch (wsPath.Level)
            {
            case WsPathLevel.Account when wsPath.AccountName == ADD_NEW_ACCOUNT_TITLE:
                return(_accountRepository.AddNewAccount());

            default:
                return(ExecResult.Yourself);
            }
        }
        public override bool DeleteFile(RemotePath remoteName)
        {
            WsPath wsPath = remoteName;

            if (wsPath.Level <= WsPathLevel.AccessLevel)
            {
                return(false);
            }
            if (wsPath.Path.EndsWith(_virtualEmptyFile.FileName))
            {
                return(true);
            }
            return(_accountRepository[wsPath.AccountName].DeleteFile(wsPath));
        }
        public override ExecResult ExecuteProperties(TcWindow mainWin, RemotePath remoteName)
        {
            WsPath wsPath = remoteName;

            switch (wsPath.Level)
            {
            case WsPathLevel.Account when wsPath.AccountName != ADD_NEW_ACCOUNT_TITLE:
                Prompt.MsgOk("TODO:", "Show account properties");
                return(ExecResult.Ok);

            default:
                return(ExecResult.Yourself);
            }
        }
        public override IEnumerable <FindData> GetFiles(RemotePath path)
        {
            WsPath wsPath = path;

            switch (wsPath.Level)
            {
            case WsPathLevel.Root:
                return(new[] { new FindData(ADD_NEW_ACCOUNT_TITLE, FileAttributes.Normal | FileAttributes.ReadOnly) }.Concat(_accountRepository));

            case WsPathLevel.Account:
                return(new[]
                {
                    new FindData(Resources.TextResource.PublicFolder, FileAttributes.Directory),
                    new FindData(Resources.TextResource.PrivateFolder, FileAttributes.Directory)
                });

            default:
                // return only one virtual file for non empty indication during deletion
                if (_deleteInProgress)
                {
                    if (wsPath.Level == WsPathLevel.AccessLevel)
                    {
                        return new[] { _backFolder }
                    }
                    ;
                    using (IDisposableEnumerable <FindData> allFiles = _accountRepository[wsPath.AccountName].GetFolderAllFilesRecursive(wsPath))
                    {
                        FindData firstItem = allFiles.FirstOrDefault();

                        if (firstItem == null)
                        {
                            firstItem = _backFolder;
                        }
                        else
                        {
                            firstItem = _virtualEmptyFile;
                        }
                        return(new[] { firstItem });
                    }
                }
                // return only one virtual file for move all folder on server, not file by file from client
                if (_moveInProgress)
                {
                    return new[] { _virtualEmptyFile }
                }
                ;
                // standard content
                return(_accountRepository[wsPath.AccountName].GetFolderItems(wsPath)?.DefaultIfEmpty(_backFolder) ?? new FindData[0]);
            }
        }
        public FileSystemExitCode CopyFile(WsPath sourceFilePath, WsPath targetPath, bool overwrite, IProgress <int> progress)
        {
            try
            {
                using (ThreadKeeper exec = new ThreadKeeper())
                {
                    return(exec.ExecAsync(async(cancellationToken) =>
                    {
                        await EnsureLogin();
                        WsFile sourceFile = await _apiClient.FindFile(sourceFilePath.GetFilePath());
                        if (sourceFile != null)
                        {
                            if (overwrite == false)
                            {
                                if (await _apiClient.FindFile(targetPath.GetFilePath()) != null)
                                {
                                    return FileSystemExitCode.FileExists;
                                }
                            }
                        }

                        if (sourceFile == null)
                        {
                            return FileSystemExitCode.FileNotFound;
                        }
                        WsFolder targetFolder = await _apiClient.FindFolder(targetPath.Parent.GetFolderPath());
                        if (targetFolder == null)
                        {
                            return FileSystemExitCode.FileNotFound;
                        }

                        await sourceFile.Copy(targetFolder, cancellationToken, new ThreadKeeperCancellableProgress(exec, progress));
                        return FileSystemExitCode.OK;
                    }));
                }
            }
            catch (TaskCanceledException)
            {
                return(FileSystemExitCode.UserAbort);
            }
            catch (Exception ex)
            {
                ShowError("Copy file error", ex, false);
                return(FileSystemExitCode.WriteError);
            }
        }
 public IDisposableEnumerable <FindData> GetFolderItems(WsPath folderPath)
 {
     try
     {
         _filesPreviewCache.Clear();
         return(ExecuteAsync(folderPath, async() => (IDisposableEnumerable <FindData>) new FolderItems(await _apiClient.GetFolderItems(folderPath.GetFolderPath()))));
     }
     catch (OperationCanceledException)
     {
         return(null);
     }
     catch (Exception ex)
     {
         ShowError("Get folder content error", ex, false);
         return(FolderItems.Empty);
     }
 }
        public override FileSystemExitCode RenMovFile(RemotePath oldRemoteName, RemotePath newRemoteName, bool move, bool overwrite, RemoteInfo remoteSourceInfo)
        {
            WsPath sourcePath     = oldRemoteName;
            WsPath targetPath     = newRemoteName;
            bool   sourceIsFolder = (remoteSourceInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory;

            if (sourcePath.Level <= WsPathLevel.AccessLevel)
            {
                return(FileSystemExitCode.NotSupported);
            }
            if (sourcePath.Name == _virtualEmptyFile.FileName)
            {
                sourcePath     = sourcePath.Parent;
                targetPath     = targetPath.Parent;
                sourceIsFolder = true;
            }
            if (sourcePath.AccountName != targetPath.AccountName)
            {
                // TODO: dodělat
                // Server not support it. Use standard copy by download/upload.
                return(FileSystemExitCode.NotSupported);
            }
            if (ProgressProc(oldRemoteName, newRemoteName, 0))
            {
                return(FileSystemExitCode.UserAbort);
            }
            try
            {
                if (move)
                {
                    return(_accountRepository[sourcePath.AccountName].MoveOrRenameItem(sourcePath, targetPath, overwrite, sourceIsFolder));
                }
                else if (sourceIsFolder == false)
                {
                    return(_accountRepository[sourcePath.AccountName].CopyFile(sourcePath, targetPath, overwrite, new CancellableProgress(this, oldRemoteName, newRemoteName)));
                }

                _uiProvider.ShowMessage(Resources.TextResource.FolderCopyInWsNotSupported, false);
                return(FileSystemExitCode.NotSupported);
            }
            finally
            {
                ProgressProc(oldRemoteName, newRemoteName, 100);
            }
        }
 public PreviewBitmapResult GetPreviewBitmap(WsPath filePath, int width, int height)
 {
     try
     {
         return(ExecuteAsync(filePath, async() =>
         {
             WsFile file = await _apiClient.FindFile(filePath.GetFilePath());
             if (file != null)
             {
                 WsFolder folder = await _apiClient.FindFolder(filePath.Parent.GetFolderPath());
                 if (folder != null)
                 {
                     WsFilePreview filePreview = await _filesPreviewCache.FindFilePreview(folder, filePath.Name);
                     byte[] jpgData = await filePreview.JpgData;
                     if (jpgData?.Length > 0)
                     {
                         using (MemoryStream jpgStream = new MemoryStream(jpgData))
                         {
                             Image jpg = Image.FromStream(jpgStream);
                             decimal ratio = (decimal)jpg.Width / jpg.Height;
                             if (ratio > 1)
                             {
                                 height = (int)(height / ratio);
                             }
                             if (ratio < 1)
                             {
                                 width = (int)(width / ratio);
                             }
                             Bitmap bmp = new Bitmap(jpg, width, height);
                             return PreviewBitmapResult.Extracted(bmp, null, false);
                         }
                     }
                 }
             }
             return PreviewBitmapResult.None;
         }));
     }
     catch
     {
         return(PreviewBitmapResult.None);
     }
 }
 public bool DeleteFolder(WsPath folderPath)
 {
     try
     {
         return(ExecuteAsync(folderPath, async() =>
         {
             WsFolder folder = await _apiClient.FindFolder(folderPath.GetFolderPath());
             if (folder == null)
             {
                 return false;
             }
             await folder.Delete();
             return true;
         }));
     }
     catch (Exception ex)
     {
         ShowError("Delete folder error", ex, false);
         return(false);
     }
 }
 public bool DeleteFile(WsPath filePath)
 {
     try
     {
         return(ExecuteAsync(filePath, async() =>
         {
             WsFile file = await _apiClient.FindFile(filePath.GetFilePath());
             if (file == null)
             {
                 return false;
             }
             await file.Delete();
             return true;
         }));
     }
     catch (Exception ex)
     {
         ShowError("Delete file error", ex, false);
         return(false);
     }
 }
        public async Task <FileSystemExitCode> DownloadFile(WsPath sourceFileName, FileInfo targetFileName, bool overwrite, IProgress <int> progress, bool deleteAfter, CancellationToken cancellationToken)
        {
            try
            {
                await EnsureLogin();

                WsFile file = await _apiClient.GetFile(sourceFileName.GetFilePath());

                FileMode mode = overwrite ? FileMode.Create : FileMode.CreateNew;

                using (FileStream targetStream = targetFileName.Open(mode, FileAccess.Write))
                {
                    await file.Download(targetStream, cancellationToken, progress);
                }
                targetFileName.CreationTime = targetFileName.LastWriteTime = file.Created;
                if (deleteAfter)
                {
                    await file.Delete();
                }
                return(FileSystemExitCode.OK);
            }
            catch (TaskCanceledException)
            {
                targetFileName.Delete();
                return(FileSystemExitCode.UserAbort);
            }
            catch (FileNotFoundException)
            {
                return(FileSystemExitCode.FileNotFound);
            }
            catch (Exception ex)
            {
                targetFileName.Delete();
                if (ShowError("Download file error", ex, true) == false)
                {
                    return(FileSystemExitCode.UserAbort);
                }
                return(FileSystemExitCode.ReadError);
            }
        }
        public override ExtractIconResult ExtractCustomIcon(RemotePath remoteName, ExtractIconFlags extractFlags)
        {
            WsPath wsPath = remoteName;

            switch (wsPath.Level)
            {
            case WsPathLevel.Account when wsPath.AccountName == ADD_NEW_ACCOUNT_TITLE:
                return(ExtractIconResult.Extracted(new System.Drawing.Icon(typeof(Resources.TextResource), "Add.ico")));

            case WsPathLevel.Account when remoteName.Path.EndsWith(@"\..\") == false:
                return(ExtractIconResult.Extracted(new System.Drawing.Icon(typeof(Resources.TextResource), "Account.ico")));

            case WsPathLevel.AccessLevel when wsPath.IsPrivate == true && remoteName.Path.EndsWith(@"\..\") == false:
                return(ExtractIconResult.Extracted(new System.Drawing.Icon(typeof(Resources.TextResource), "FolderPrivate.ico")));

            case WsPathLevel.AccessLevel when wsPath.IsPrivate == false:
                return(ExtractIconResult.Extracted(new System.Drawing.Icon(typeof(Resources.TextResource), "FolderPublic.ico")));

            default:
                return(ExtractIconResult.UseDefault);
            }
        }
        public override async Task <FileSystemExitCode> PutFileAsync(string localName, RemotePath remoteName, CopyFlags copyFlags, Action <int> setProgress, CancellationToken cancellationToken)
        {
            WsPath wsPath = remoteName;

            if (wsPath.Level <= WsPathLevel.AccessLevel)
            {
                return(FileSystemExitCode.NotSupported);
            }

            FileInfo localFileName = new FileInfo(localName);
            bool     overWrite     = (CopyFlags.Overwrite & copyFlags) != 0;
            bool     performMove   = (CopyFlags.Move & copyFlags) != 0;
            bool     resume        = (CopyFlags.Resume & copyFlags) != 0;

            if (resume)
            {
                return(FileSystemExitCode.NotSupported);
            }
            if (!localFileName.Exists)
            {
                return(FileSystemExitCode.FileNotFound);
            }

            FileSystemExitCode result = await _accountRepository[wsPath.AccountName].UploadFile(
                localFileName,
                wsPath,
                overWrite,
                new Progress <int>(setProgress),
                cancellationToken
                );

            if (performMove && result == FileSystemExitCode.OK)
            {
                localFileName.Delete();
            }
            return(result);
        }
        public override bool MkDir(RemotePath remoteName)
        {
            if (_moveInProgress)
            {
                return(true);
            }
            WsPath wsPath = remoteName;

            switch (wsPath.Level)
            {
            case WsPathLevel.Root:
                return(false);

            case WsPathLevel.Account:
                // TODO: nefunguje return true, nedojde k refresh root složky
                return(_accountRepository.AddNewAccount(wsPath.AccountName).Equals(ExecResult.Yourself) == false);

            case WsPathLevel.AccessLevel:
                return(false);

            default:
                return(_accountRepository[wsPath.AccountName].CreateFolder(wsPath) != null);
            }
        }
        public FileSystemExitCode MoveOrRenameItem(WsPath sourcePath, WsPath targetPath, bool overwrite, bool sourceIsFolder)
        {
            try
            {
                return(ExecuteAsync(sourcePath, async() =>
                {
                    WsItem sourceItem;
                    if (sourceIsFolder)
                    {
                        sourceItem = await _apiClient.FindFolder(sourcePath.GetFolderPath());
                        if (sourceItem != null)
                        {
                            if (overwrite == false)
                            {
                                if (await _apiClient.FindFolder(targetPath.GetFolderPath()) != null)
                                {
                                    return FileSystemExitCode.FileExists; // TODO: not work for renaming to existing folder
                                }
                            }
                        }
                    }
                    else
                    {
                        sourceItem = await _apiClient.FindFile(sourcePath.GetFilePath());
                        if (sourceItem != null)
                        {
                            if (overwrite == false)
                            {
                                if (await _apiClient.FindFile(targetPath.GetFilePath()) != null)
                                {
                                    return FileSystemExitCode.FileExists; // TODO: not work for renaming to existing file
                                }
                            }
                        }
                    }
                    if (sourceItem == null)
                    {
                        return FileSystemExitCode.FileNotFound;
                    }

                    if (sourcePath.Parent.Path == targetPath.Parent.Path)
                    {
                        await sourceItem.Rename(targetPath.Name);
                    }
                    else
                    {
                        WsFolder targetFolder = await _apiClient.FindFolder(targetPath.Parent.GetFolderPath());
                        if (targetFolder == null)
                        {
                            return FileSystemExitCode.FileNotFound;
                        }
                        await sourceItem.Move(targetFolder);
                    }
                    return FileSystemExitCode.OK;
                }));
            }
            catch (Exception ex)
            {
                ShowError("Move/rename file/folder error", ex, false);
                return(FileSystemExitCode.WriteError);
            }
        }