diff --git a/src/managed/OpenLiveWriter.BlogClient/Clients/GoogleBloggerv3Client.cs b/src/managed/OpenLiveWriter.BlogClient/Clients/GoogleBloggerv3Client.cs index af7bab40..4d814b1c 100644 --- a/src/managed/OpenLiveWriter.BlogClient/Clients/GoogleBloggerv3Client.cs +++ b/src/managed/OpenLiveWriter.BlogClient/Clients/GoogleBloggerv3Client.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; +using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Xml; @@ -781,38 +782,52 @@ namespace OpenLiveWriter.BlogClient.Clients private void PostNewImage(string albumName, string filename, string blogId, out string srcUrl, out string editUri) { - for (int retry = 0; retry < MaxRetries; retry++) - { - var transientCredentials = Login(); - try - { - string albumUrl = GetBlogImagesAlbum(albumName, blogId); - throw new ApplicationException(albumUrl); - /*HttpWebResponse response = RedirectHelper.GetResponse(albumUrl, new RedirectHelper.RequestFactory(new UploadFileRequestFactory(this, filename, "POST").Create)); - using (Stream s = response.GetResponseStream()) - { - ParseMediaEntry(s, out srcUrl, out editUri); - return; - }*/ - } - catch (WebException we) - { - if (retry < MaxRetries - 1 && - we.Response as HttpWebResponse != null && - ((HttpWebResponse)we.Response).StatusCode == HttpStatusCode.Forbidden) - { - // HTTP 403 Forbidden means our OAuth access token is not valid. - RefreshAccessToken(transientCredentials); - } - else - { - throw; - } - } - } + var albumId = GetBlogImagesAlbum(albumName, blogId); + var library = GetPhotosLibraryService(); - Trace.Fail("Should never get here"); - throw new ApplicationException("Should never get here"); + /* Uploading an image to Google Photos from a filename is a multiple step process + * 1. Create a reading System.IO.FileStream on the given filename + * 2. begin the file upload + * 3. Execute a MediaItems BatchCreate request to create the metadata on Google Photos */ + + + // Create a FileStream + var imageFileStream = new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read); + + // Upload the image by POSTing to https://photoslibrary.googleapis.com/v1/uploads + // Wish this could be nicer but the relevant message was not autogenerated into our PhotosLibrary API package + var uploadRequest = new HttpRequestMessage() + { + RequestUri = new Uri("https://photoslibrary.googleapis.com/v1/uploads"), + Method = HttpMethod.Post + }; + uploadRequest.Headers.Add("X-Goog-Upload-File-Name", Path.GetFileName(filename)); + uploadRequest.Headers.Add("X-Goog-Upload-Protocol", "raw"); + uploadRequest.Content = new StreamContent(imageFileStream); + // Send the request. Sending through library.HttpClient inserts the Authorization headers for us + var uploadResponse = library.HttpClient.SendAsync(uploadRequest).Result; + if (uploadResponse.StatusCode != HttpStatusCode.OK) throw new ApplicationException("Failed to upload image to Google Photos"); + var uploadToken = uploadResponse.Content.ReadAsStringAsync().Result; + + // Create the MediaItem on GooglePhotos + var batchCreateResponse = library.MediaItems.BatchCreate(new BatchCreateMediaItemsRequest() + { + AlbumId = albumId, + NewMediaItems = new NewMediaItem[] { + new NewMediaItem() + { + SimpleMediaItem = new SimpleMediaItem() + { + UploadToken = uploadToken + } + } + } + }).Execute(); + + // TODO correctly format baseUrl to include width parameter + srcUrl = batchCreateResponse.NewMediaItemResults.First().MediaItem.BaseUrl; + // TODO change from edit URI into and edit token or ID + editUri = ""; } private void UpdateImage(string editUri, string filename, out string srcUrl, out string newEditUri)