예제 #1
0
        internal async Task <WsItem> CopyItem(WsItem sourceItem, WsFolder targetFolder, CancellationToken cancellationToken, IProgress <int> progress)
        {
            if (sourceItem == null)
            {
                throw new ArgumentNullException(nameof(sourceItem));
            }
            if (targetFolder == null)
            {
                throw new ArgumentNullException(nameof(targetFolder));
            }
            if (cancellationToken == null)
            {
                throw new ArgumentNullException(nameof(cancellationToken));
            }

            progress?.Report(0);

            if (sourceItem is WsFile sourceFile)
            {
                using (HttpResponseMessage response = await DownloadFile(sourceFile, cancellationToken))
                {
                    long       fileSize       = response.Content.Headers.ContentLength ?? sourceFile.Size;
                    int        bufferSize     = CalculateBuffer(fileSize);
                    WsFilePath targetFilePath = new WsFilePath(targetFolder.PathInfo, sourceItem.PathInfoGeneric.Name);
                    using (TransportStream sourceTrasportStream = new TransportStream(await response.Content.ReadAsStreamAsync(), fileSize, null))
                    {
                        return(await UploadFile(sourceTrasportStream, fileSize, targetFilePath, cancellationToken, progress));
                    }
                }
            }
            else
            {
                throw new NotSupportedException("Copy folder not supported.");
            }
        }
예제 #2
0
        public async Task <WsFolder> GetFolder(WsFolderPath folderPath)
        {
            WsFolder folder = await FindFolder(folderPath);

            if (folder == null)
            {
                throw new DirectoryNotFoundException($"Required folder {folderPath} not found on server.");
            }
            return(folder);
        }
예제 #3
0
 private async Task ExecuteReader(WsFolder folder)
 {
     using (WsFilesPreviewReader reader = await folder.GetFilesPreview())
     {
         foreach (WsFilePreview filePreview in reader)
         {
             if (_clearRequest)
             {
                 break;
             }
             _filesPreview.AddOrUpdate(filePreview.Name, filePreview, (fileName, filePreviewExists) => filePreviewExists);
         }
     }
 }
예제 #4
0
        public async Task <bool> Login(string userName, ISecretProvider secretProvider, ISecretPersistor secretPersistor = null)
        {
            if (string.IsNullOrWhiteSpace(userName))
            {
                throw new ArgumentException($"{nameof(userName)} not specified.", nameof(userName));
            }
            if (secretProvider == null)
            {
                throw new ArgumentNullException(nameof(secretProvider));
            }
            if (IsLoggedIn)
            {
                throw new InvalidOperationException("The client is already logged in.");
            }

            if (secretProvider.TryGetUserPasswordHash(out string userPasswordHash) == false)
            {
                string userPassword = await secretProvider.GetPassword();

                FormUrlEncodedContent formContent = CreateFormContent(new[]
                {
                    new KeyValuePair <string, string>("username_or_email", userName)
                });
                SaltResult saltResult = await _httpClient.PostFormData <SaltResult>(API_SALT_URI, formContent);

                if (CheckResultStatus(saltResult))
                {
                    userPasswordHash = BCrypt.HashPassword(userPassword, saltResult.Salt);
                }
                else
                {
                    return(false);
                }
            }

            LoginInfo loginInfo = new LoginInfo(userName, userPasswordHash, secretProvider, secretPersistor);

            if (await TryLogin(loginInfo))
            {
                _loginInfo         = loginInfo;
                _privateRootFolder = WsFolder.CreateRootFolder(this, true);
                _publicRootFolder  = WsFolder.CreateRootFolder(this, false);
                secretPersistor?.SaveUserPasswordHash(userPasswordHash);
                return(true);
            }
            return(false);
        }
예제 #5
0
        internal async Task MoveItem(WsItem sourceItem, WsFolder targetFolder)
        {
            if (sourceItem == null)
            {
                throw new ArgumentNullException(nameof(sourceItem));
            }
            if (targetFolder == null)
            {
                throw new ArgumentNullException(nameof(targetFolder));
            }
            if (sourceItem.PathInfoGeneric.Folder.Equals(targetFolder.PathInfo))
            {
                throw new ArgumentException($"{nameof(sourceItem)} and {nameof(targetFolder)} are equal folder.");
            }
            CheckConnected();

            Task <Result> MoveFunc()
            {
                FormUrlEncodedContent formContent = CreateFormContent(new[]
                {
                    new KeyValuePair <string, string>("src", sourceItem.PathInfoGeneric.FullPath),
                    new KeyValuePair <string, string>("src_private", sourceItem.PathInfoGeneric.IsPrivate ? "1" : "0"),
                    new KeyValuePair <string, string>("dest", targetFolder.PathInfo.FullPath),
                    new KeyValuePair <string, string>("dest_private", targetFolder.PathInfo.IsPrivate ? "1" : "0"),
                });

                return(_httpClient.PostFormData <Result>(API_MOVE_FILE_URI, formContent));
            }

            if (sourceItem is WsFile file)
            {
                WsFile targetFile = await FindFile(new WsFilePath(targetFolder.PathInfo, file.PathInfo.Name));

                if (targetFile != null)
                {
                    await targetFile.Delete();
                }
                await PostFormDataWithNotFoundAndLoginRetry(file, MoveFunc);
            }
            else
            {
                await PostFormDataWithLoginRetry(MoveFunc);
            }

            _createdFileResolver.MoveItem(sourceItem, targetFolder);
            sourceItem.ChangePathInInstance(targetFolder.PathInfo.FullPath + sourceItem.PathInfoGeneric.Name, targetFolder.PathInfo.IsPrivate);
        }
        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);
            }
        }
예제 #7
0
        public async Task <bool> Logout()
        {
            CheckConnected();
            FormUrlEncodedContent formContent = CreateFormContent();

            try
            {
                await _createdFileResolver.Clear();

                return((await _httpClient.PostFormData <Result>(API_LOGOUT_URI, formContent)).Status == ResultStatus.OK);
            }
            finally
            {
                _uploadFileUrl     = null;
                _privateRootFolder = null;
                _publicRootFolder  = null;
                _loginInfo         = null;
            }
        }
 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);
     }
 }
예제 #9
0
        public void MoveItem(WsItem item, WsFolder targetFolder)
        {
            FolderItemsResolver sourceFolderItemsResolver = (FindFolderItemsResolver(item.PathInfoGeneric.Folder) as FolderItemsResolver);

            if (sourceFolderItemsResolver == null)
            {
                return;
            }
            if (item is WsFile file)
            {
                sourceFolderItemsResolver.RemoveFileAndFolderIfEmpty(file);
                if (file.IsReady == false)
                {
                    Add(targetFolder.PathInfo, file.PathInfo.Name, file.Ident, file.Size);
                }
            }
            else if (item is WsFolder folder)
            {
                MoveFolder(folder.PathInfo, targetFolder.PathInfo);
            }
        }
 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);
     }
 }
예제 #11
0
        internal async Task <WsFilesPreviewReader> GetFolderFilesPreview(WsFolder folder)
        {
            if (folder == null)
            {
                throw new ArgumentNullException(nameof(folder));
            }
            CheckConnected();

            Task <WsFilesReader>       filesReaderTask = folder.GetAllFilesRecursive(0);
            WsFilesPreviewReaderEngine readerEngine    = await PostFormDataWithLoginRetry(async() =>
            {
                FormUrlEncodedContent formContent = CreateFormContent(new[]
                {
                    new KeyValuePair <string, string>("ident", folder.Ident),
                    new KeyValuePair <string, string>("limit", "99999999"),
                    //new KeyValuePair<string, string>("offset", "0")
                });
                HttpResponseMessage response = await _httpClient.PostFormData(API_FOLDER_URI, formContent);
                return(await WsFilesPreviewReaderEngine.Create(_httpClient, filesReaderTask, response));
            });

            CheckResultStatus(readerEngine);
            return(new WsFilesPreviewReader(readerEngine));
        }
예제 #12
0
 public WsFolderCache(WsFolder folder)
 {
     _readerTask = ExecuteReader(folder);
 }
예제 #13
0
        public Task <WsFilePreview> FindFilePreview(WsFolder folder, string fileName)
        {
            WsFolderCache folderCache = _folders.GetOrAdd(folder, (folder) => new WsFolderCache(folder));

            return(folderCache.FindFilePreview(fileName));
        }
        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);
            }
        }