Exemplo n.º 1
0
        /// <summary>
        /// Put's a file as a stream using the REST API documented at https://developers.google.com/drive/v3/web/manage-uploads#multipart
        /// </summary>
        /// <param name="szFileName">The file name to use</param>
        /// <param name="ms">The stream of the data</param>
        /// <param name="szMimeType">The mime type for the data</param>
        /// <returns>True for success</returns>
        /// <exception cref="MyFlightbookException"></exception>
        /// <exception cref="System.Net.Http.HttpRequestException"></exception>
        public async Task <IReadOnlyDictionary <string, string> > PutFile(Stream ms, string szFileName, string szMimeType)
        {
            if (!CheckAccessToken())
            {
                throw new MyFlightbookException("Google drive: access token missing or expired");
            }

            bool fIsCSV = szMimeType.CompareCurrentCultureIgnoreCase("text/csv") == 0;

            ms.Seek(0, SeekOrigin.Begin);   // write out the whole stream.  UploadAsync appears to pick up from the current location, which is the end-of-file after writing to a ZIP.

            string szResult = string.Empty;
            HttpResponseMessage response = null;

            using (HttpClient httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + AuthState.AccessToken);

                if (String.IsNullOrEmpty(RootFolderID))
                {
                    RootFolderID = await IDForFolder(RootPath);

                    if (String.IsNullOrEmpty(RootFolderID))
                    {
                        RootFolderID = await CreateFolder(Branding.CurrentBrand.AppName);
                    }
                }

                // CSV loses its extension when uploaded because we map it to a google spreadsheet.  So if it's CSV AND we are patching an existing file, drop the extension so that we ov
                // update the existing file if it is present.  If CSV, strip the extension
                string szFileNameToCheck = fIsCSV ? Path.GetFileNameWithoutExtension(szFileName) : szFileName;
                string idExisting        = null;
                if (!String.IsNullOrEmpty(RootFolderID))
                {
                    idExisting = await IDForFile(szFileNameToCheck, RootFolderID);
                }

                // If we got a hit, use that filename for the udpate
                if (!String.IsNullOrEmpty(idExisting))
                {
                    szFileName = szFileNameToCheck;
                }

                // Create the metadata.  Name is most important, but we can also specify mimeType for CSV to import into GoogleDocs
                Dictionary <string, object> dictMeta = new Dictionary <string, object>()
                {
                    { "name", szFileName }
                };
                if (fIsCSV)
                {
                    dictMeta["mimeType"] = "application/vnd.google-apps.spreadsheet";   // get it to show up in google drive sheets.
                }
                if (String.IsNullOrEmpty(idExisting) && !String.IsNullOrEmpty(RootFolderID))
                {
                    dictMeta["parents"] = new List <string>()
                    {
                        RootFolderID
                    }
                }
                ;

                // Create the form.  The form itself needs the authtoken header
                using (MultipartContent form = new MultipartContent("related"))
                {
                    // Next add the metadata - it is in Json format
                    string        szJSonMeta = JsonConvert.SerializeObject(dictMeta);
                    StringContent metadata   = new StringContent(szJSonMeta, System.Text.Encoding.UTF8);
                    metadata.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json")
                    {
                        CharSet = "UTF-8"
                    };
                    form.Add(metadata);

                    // Finally, add the body, with its appropriate mime type.
                    StreamContent body = new StreamContent(ms);
                    body.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(szMimeType);
                    form.Add(body);

                    try
                    {
                        response = (String.IsNullOrEmpty(idExisting)) ?
                                   await httpClient.PostAsync(szURLUploadEndpoint, form) :
                                   await httpClient.PatchAsync(new Uri(String.Format(szURLUpdateEndpointTemplate, idExisting)), form);

                        szResult = response.Content.ReadAsStringAsync().Result;
                        response.EnsureSuccessStatusCode();
                        return((String.IsNullOrEmpty(szResult)) ? null : JsonConvert.DeserializeObject <Dictionary <string, string> >(szResult));
                    }
                    catch (System.Net.Http.HttpRequestException ex)
                    {
                        if (response == null)
                        {
                            throw new MyFlightbookException("Unknown error in GoogleDrive.PutFile", ex);
                        }

                        Dictionary <string, GoogleDriveError> d = String.IsNullOrEmpty(szResult) ? null : JsonConvert.DeserializeObject <Dictionary <string, GoogleDriveError> >(szResult);
                        GoogleDriveError gde = (d == null || !d.ContainsKey("error")) ? null : d["error"];

                        if (gde != null && gde.code == 403 && gde.errors != null && gde.errors.Length > 0 && gde.errors[0].reason != null && gde.errors[0].reason.CompareCurrentCultureIgnoreCase("storageQuotaExceeded") == 0)
                        {
                            throw new MyFlightbookException(Resources.LocalizedText.GoogleDriveOutOfSpace);
                        }
                        else
                        {
                            throw new MyFlightbookException(response.ReasonPhrase + " " + (szResult ?? string.Empty));
                        }
                    }
                }
            }
        }
    }
Exemplo n.º 2
0
        private static async Task <GoogleDriveResultDictionary> SendForm(HttpClient httpClient, Stream ms, Dictionary <string, object> dictMeta, string szMimeType, string idExisting)
        {
            string szResult = string.Empty;
            HttpResponseMessage response = null;

            // Create the form.  The form itself needs the authtoken header
            using (MultipartContent form = new MultipartContent("related"))
            {
                // Next add the metadata - it is in Json format
                string szJSonMeta = JsonConvert.SerializeObject(dictMeta);
                using (StringContent metadata = new StringContent(szJSonMeta, System.Text.Encoding.UTF8))
                {
                    metadata.Headers.ContentType = new MediaTypeHeaderValue("application/json")
                    {
                        CharSet = "UTF-8"
                    };
                    form.Add(metadata);

                    // Finally, add the body, with its appropriate mime type.
                    using (StreamContent body = new StreamContent(ms))
                    {
                        body.Headers.ContentType = new MediaTypeHeaderValue(szMimeType);
                        form.Add(body);

                        try
                        {
                            response = (String.IsNullOrEmpty(idExisting)) ?
                                       await httpClient.PostAsync(new Uri(szURLUploadEndpoint), form).ConfigureAwait(false) :
                                       await httpClient.PatchAsync(new Uri(String.Format(CultureInfo.InvariantCulture, szURLUpdateEndpointTemplate, idExisting)), form, false).ConfigureAwait(false);

                            szResult = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                            response.EnsureSuccessStatusCode();
                            return((String.IsNullOrEmpty(szResult)) ? null : JsonConvert.DeserializeObject <GoogleDriveResultDictionary>(szResult));
                        }
                        catch (HttpRequestException ex)
                        {
                            if (response == null)
                            {
                                throw new MyFlightbookException("Unknown error in GoogleDrive.PutFile", ex);
                            }

                            Dictionary <string, GoogleDriveError> d = String.IsNullOrEmpty(szResult) ? null : JsonConvert.DeserializeObject <Dictionary <string, GoogleDriveError> >(szResult);
                            GoogleDriveError gde = (d == null || !d.ContainsKey("error")) ? null : d["error"];

                            if (gde != null && gde.code == 403 && gde.errors != null && gde.errors.Count > 0 && gde.errors[0].reason != null && gde.errors[0].reason.CompareCurrentCultureIgnoreCase("storageQuotaExceeded") == 0)
                            {
                                throw new MyFlightbookException(Resources.LocalizedText.GoogleDriveOutOfSpace);
                            }
                            else
                            {
                                throw new MyFlightbookException(response.ReasonPhrase + " " + (szResult ?? string.Empty));
                            }
                        }
                        finally
                        {
                            if (response != null)
                            {
                                response.Dispose();
                            }
                        }
                    }
                }
            }
        }