Exemplo n.º 1
0
        public override async Task <UploadResult> UploadAsync(string name, string originalName, string mimeType, string description, Stream data,
                                                              UploadAs uploadAs,
                                                              IProgress <AsyncProgressEntry> progress, CancellationToken cancellation)
        {
            await PrepareAsync(cancellation);

            if (_authToken == null)
            {
                throw new Exception(ToolsStrings.Uploader_AuthenticationTokenIsMissing);
            }

            var path        = DestinationDirectoryId == null ? $"drive/special/approot:/{name}" : $"drive/items/{DestinationDirectoryId}:/{name}";
            var total       = data.Length;
            var bufferSize  = Math.Min(total, 10 * 320 * 1024);
            var totalPieces = ((double)total / bufferSize).Ceiling();

            JObject result = null;

            if (totalPieces == 1)
            {
                // https://graph.microsoft.com/v1.0/drive/root:/3ds%20Max/Newtonsoft.Json.xml:/content
                var bytes = await data.ReadAsBytesAsync();

                cancellation.ThrowIfCancellationRequested();
                result = await Request.Put <JObject>(
                    $@"https://graph.microsoft.com/v1.0/{path}:/[email protected]=rename",
                    bytes, _authToken.AccessToken, progress, cancellation);
            }
            else
            {
                var ended    = false;
                var buffer   = new byte[bufferSize];
                var uploaded = 0;

                async Task <int> NextPiece()
                {
                    if (ended)
                    {
                        return(0);
                    }
                    var piece = await data.ReadAsync(buffer, 0, buffer.Length);

                    cancellation.ThrowIfCancellationRequested();

                    // ReSharper disable once AccessToModifiedClosure
                    ended = piece == 0 || uploaded + piece == total;
                    return(piece);
                }

                progress.Report("Starting upload session…", 0.00001d);
                Logging.Debug(path);

                var uploadUrl = (await Request.Post <JObject>(
                                     $@"https://graph.microsoft.com/v1.0/{path}:/createUploadSession",
                                     new JObject {
                    ["item"] = new JObject {
                        ["@microsoft.graph.conflictBehavior"] = "rename",
                        ["name"] = name,
                    }
                }, _authToken.AccessToken, null, cancellation))?.GetStringValueOnly("uploadUrl");

                try {
                    cancellation.ThrowIfCancellationRequested();
                    if (uploadUrl == null)
                    {
                        RaiseShareFailedException();
                    }

                    for (var index = 1; index < 100000 && !ended; index++)
                    {
                        var rangeFrom = uploaded;
                        var piece     = await NextPiece();

                        result = await Request.Put <JObject>(uploadUrl, buffer.Slice(0, piece), null,
                                                             progress.Subrange((double)uploaded / total, (double)piece / total, $"Uploading piece #{index} out of {totalPieces} ({{0}})…"),
                                                             cancellation,
                                                             new NameValueCollection {
                            ["Content-Range"] = $@"bytes {rangeFrom}-{rangeFrom + piece - 1}/{total}"
                        });

                        uploaded += piece;
                        cancellation.ThrowIfCancellationRequested();
                    }
                } catch (Exception) when(uploadUrl != null)
                {
                    try {
                        Request.Send("DELETE", uploadUrl, new byte[0], null, null, default(CancellationToken), null).Ignore();
                    } catch {
                        // ignored
                    }

                    throw;
                }
            }

            cancellation.ThrowIfCancellationRequested();
            if (result?["id"] == null)
            {
                RaiseUploadFailedException();
            }

            var link = (await Request.Post <JObject>($"https://graph.microsoft.com/v1.0/drive/items/{result["id"]}/createLink", new {
                type = "view"
            }, _authToken.AccessToken, null, cancellation))?["link"] as JObject;

            cancellation.ThrowIfCancellationRequested();
            if (link == null)
            {
                RaiseShareFailedException();
            }

#if DEBUG
            Logging.Debug(link.ToString(Formatting.Indented));
#endif

            return(WrapUrl((string)link["webUrl"], uploadAs));
        }
Exemplo n.º 2
0
#pragma warning restore 0649

        public override async Task <UploadResult> UploadAsync(string name, string originalName, string mimeType, string description, Stream data, UploadAs uploadAs,
                                                              IProgress <AsyncProgressEntry> progress, CancellationToken cancellation)
        {
            await PrepareAsync(cancellation);

            if (_authToken == null)
            {
                throw new Exception(ToolsStrings.Uploader_AuthenticationTokenIsMissing);
            }

            var bytes = await data.ReadAsBytesAsync();

            cancellation.ThrowIfCancellationRequested();

            var entry = await Request.PostMultipart <InsertResult>(@"https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart",
                                                                   new InsertParams {
                Title            = name,
                OriginalFilename = originalName,
                Description      = description,
                MimeType         = mimeType,
                ParentIds        = DestinationDirectoryId == null ? null : new[] {
                    new InsertParamsParent {
                        Id = DestinationDirectoryId
                    }
                }
            },
                                                                   _authToken.AccessToken,
                                                                   bytes,
                                                                   mimeType,
                                                                   progress,
                                                                   cancellation);

            cancellation.ThrowIfCancellationRequested();

            if (entry == null)
            {
                RaiseUploadFailedException();
            }

            var shared = await Request.Post <PermissionResult>($"https://www.googleapis.com/drive/v2/files/fileId/permissions?fileId={entry.Id}",
                                                               new { role = @"reader", type = @"anyone" }, _authToken.AccessToken, cancellation : cancellation);

            cancellation.ThrowIfCancellationRequested();

            if (shared == null)
            {
                RaiseShareFailedException();
            }

            return(new UploadResult {
                Id = $"{(uploadAs == UploadAs.Content ? "Gi" : "RG")}{entry.Id}",
                DirectUrl = $"https://drive.google.com/uc?export=download&id={entry.Id}"
            });
        }