Пример #1
0
        private void setupFileWithMetadata(DropboxFileInfo file, JToken metadata)
        {
            file.Provider = this;
            file.IsReadOnly = false;
            file.IsDirectory = (bool)metadata["is_dir"];
            file.Size = (long)metadata["bytes"];

            string hash = metadata.Value<string>("hash");
            if (hash != null) file.Hash = hash;

            string path = (string)metadata["path"];
            if (path == "/") file.Name = this.Name;
            else file.Name = path.Substring(path.LastIndexOf('/') + 1);
        }
Пример #2
0
 private void addFile(string[] folders, JToken metadata)
 {
     DropboxFileInfo currentFile = _root;
     for(int i = 1; i < folders.Length; ++i)
     {
         string name = folders[i];
         DFileInfo nextFile;
         if (!currentFile.Contents.TryGetValue(name, out nextFile))
         {
             // There is a guarantee that if file/folder doesn't already exist, metadata for it will 
             // arrive later. Thus all wrong assumptions made at this step (if any) will be corrected. 
             nextFile = new DropboxFileInfo() { IsDirectory = true, Parent = currentFile };
             currentFile.Contents.Add(name, nextFile);
         }
         currentFile = (DropboxFileInfo)nextFile;
     }
     setupFileWithMetadata(currentFile, metadata);
 }
Пример #3
0
        public async Task<DFileInfo> CreateFolderAsync(DFileInfo destinationFolder, string name)
        {
            string nameKey = name.ToLowerInvariant();
            if (destinationFolder.Contents.ContainsKey(nameKey))
                throw new FileConflictException("Entry with name specified is already present.");

            var dParent = (DropboxFileInfo)destinationFolder;
            string path = concatenatePath(dParent.Path, name);

            var url = new ParamUrl(DropboxConfig.CreateFolderUrl);
            url.Add("root", DropboxConfig.AccessType);
            url.Add("path", path);

            var response = await queryServer(url).ConfigureAwait(false);
            var metadata = JObject.Parse(response);

            var newFolder = new DropboxFileInfo() { Parent = dParent };
            setupFileWithMetadata(newFolder, metadata);

            dParent.Contents.Add(nameKey, newFolder);
            return newFolder;
        }
Пример #4
0
        public async Task<DFileInfo> UploadFileAsync(DFileInfo destinationFolder, string name, Stream stream, 
            CancellationToken cancellationToken, IProgress<int> progress, long fileSize)
        {
            var dDestFolder = (DropboxFileInfo)destinationFolder;
            string uploadId = null;

            using (stream)
            {
                if (progress != null) progress.Report(0);
                var buffer = new byte[DropboxConfig.ChunkSize];
                long totalUploaded = 0, offset = 0;

                // Some data is read from the buffer until it is full and we 
                // attempt to push it to the server until it acknowledges all of it.
                while (true)
                {
                    int bytesRead = 0, bytesReadThisTime = 0;
                    while (bytesRead < buffer.Length)
                    {
                        bytesReadThisTime =
                            await stream.ReadAsync(buffer, bytesRead, buffer.Length - bytesRead).ConfigureAwait(false);
                        bytesRead += bytesReadThisTime;
                        if (bytesReadThisTime == 0) break;
                    }

                    if (bytesRead == 0) break;

                    int relativeOffset = 0;
                    // relativeOffset shows how many bytes server already accepted.
                    while (relativeOffset < bytesRead)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        var url = new ParamUrl(DropboxConfig.UploadUrl);
                        url.Add("offset", (offset + relativeOffset).ToString());
                        if (uploadId != null) url.Add("upload_id", uploadId);

                        var signedUrl = await signAsync(url).ConfigureAwait(false);
                        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(signedUrl);
                        request.Method = WebRequestMethods.Http.Put;
                        request.ContentLength = bytesRead - relativeOffset;

                        using (var requestStream = await request.GetRequestStreamAsync().ConfigureAwait(false))
                        {
                            requestStream.Write(buffer, relativeOffset, bytesRead - relativeOffset);
                        }

                        JToken response;
                        try
                        {
                            var webResponse = await request.GetResponseAsync().ConfigureAwait(false);
                            StreamReader reader = new StreamReader(webResponse.GetResponseStream());
                            var jsonResult = reader.ReadToEnd();
                            reader.Close();
                            response = JToken.Parse(jsonResult);
                        }
                        catch (WebException e)
                        {
                            string message = e.ResponseString();
                            if (e.HttpStatusCode() == 400 && !string.IsNullOrEmpty(message))
                            {
                                response = JToken.Parse(message);
                            }
                            else throw parseException(e);
                        }

                        uploadId = (string)response["upload_id"];
                        relativeOffset = (int)((long)response["offset"] - offset);
                        totalUploaded = offset + relativeOffset;
                        if (progress != null) progress.Report((int)(totalUploaded * 100 / fileSize));
                    } 

                    offset += bytesRead;
                }           

            }

            var baseUrl = new StringBuilder(DropboxConfig.UploadFinishUrl);
            baseUrl.Append(DropboxConfig.AccessType);
            baseUrl.Append(concatenatePath(dDestFolder.Path, name));

            var finalUrl = new ParamUrl(baseUrl.ToString());
            finalUrl.Add("upload_id", uploadId);
            var finishResponse = await queryServer(finalUrl, WebRequestMethods.Http.Post).ConfigureAwait(false);

            DropboxFileInfo file = new DropboxFileInfo() { Parent = destinationFolder };
            setupFileWithMetadata(file, JToken.Parse(finishResponse));
            destinationFolder.Contents.Add(name.ToLowerInvariant(), file);
            return file;
        }
Пример #5
0
        private async Task<DFileInfo> copyOperation(DropboxFileInfo file, 
            DropboxFileInfo destFolder, bool move, string newName = null)
        {
            string nameKey = file.Name.ToLowerInvariant();
            string newNameKey = (newName == null)? nameKey : newName.ToLowerInvariant();
            // Storage provider should check possible file conflicts by itself, because
            // the outer system doesn't know how to access keys in dictionary correctly.
            if (destFolder.Contents.ContainsKey(newNameKey))
                throw new FileConflictException("Entry with specified name is already present.");

            string path = concatenatePath(destFolder.Path, newName ?? file.Name);

            var url = new ParamUrl(move ? DropboxConfig.MoveUrl : DropboxConfig.CopyUrl);
            url.Add("root", DropboxConfig.AccessType);
            url.Add("from_path", percentEncoding(file.Path));
            url.Add("to_path", percentEncoding(path));

            var response = await queryServer(url).ConfigureAwait(false);
            var metadata = JObject.Parse(response);
            
            if (move)
            {
                file.Parent.Contents.Remove(nameKey);
                file.Parent = destFolder;
                setupFileWithMetadata(file, metadata);
                destFolder.Contents.Add(newNameKey, file);
                return file;
            }
            else
            {
                var newFile = (DropboxFileInfo)file.Clone();
                newFile.Parent = destFolder;
                setupFileWithMetadata(newFile, metadata);
                destFolder.Contents.Add(newNameKey, newFile);
                return newFile;
            }
        }