mirror of
https://github.com/ShareX/ShareX.git
synced 2024-09-30 01:07:21 +13:00
Google photos update for Picasa deprecation (#3890)
* Add new object classes Update scope Update album list url Remove extra headers * Implement new albums * Update GooglePhotos to new API * Add create album button * Fix redundancy
This commit is contained in:
parent
017c19cd21
commit
5e9c3c43b6
6 changed files with 9895 additions and 2113 deletions
|
@ -712,6 +712,7 @@ private void InitializeComponent()
|
|||
this.txtPhotobucketVerificationCode = new System.Windows.Forms.TextBox();
|
||||
this.lblPhotobucketAccountStatus = new System.Windows.Forms.Label();
|
||||
this.tpGooglePhotos = new System.Windows.Forms.TabPage();
|
||||
this.cbGooglePhotosIsPublic = new System.Windows.Forms.CheckBox();
|
||||
this.txtPicasaAlbumID = new System.Windows.Forms.TextBox();
|
||||
this.lblPicasaAlbumID = new System.Windows.Forms.Label();
|
||||
this.lvPicasaAlbumList = new System.Windows.Forms.ListView();
|
||||
|
@ -742,6 +743,9 @@ private void InitializeComponent()
|
|||
this.tsmiCustomUploaderExamples = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.tsmiCustomUploaderExportAll = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.actRapidShareAccountType = new ShareX.UploadersLib.AccountTypeControl();
|
||||
this.btnGooglePhotosCreateAlbum = new System.Windows.Forms.Button();
|
||||
this.txtGooglePhotosCreateAlbumName = new System.Windows.Forms.TextBox();
|
||||
this.lblGooglePhotosCreateAlbumName = new System.Windows.Forms.Label();
|
||||
this.tscCustomUploaderResponseText.ContentPanel.SuspendLayout();
|
||||
this.tscCustomUploaderResponseText.TopToolStripPanel.SuspendLayout();
|
||||
this.tscCustomUploaderResponseText.SuspendLayout();
|
||||
|
@ -5727,6 +5731,10 @@ private void InitializeComponent()
|
|||
// tpGooglePhotos
|
||||
//
|
||||
this.tpGooglePhotos.BackColor = System.Drawing.SystemColors.Window;
|
||||
this.tpGooglePhotos.Controls.Add(this.lblGooglePhotosCreateAlbumName);
|
||||
this.tpGooglePhotos.Controls.Add(this.txtGooglePhotosCreateAlbumName);
|
||||
this.tpGooglePhotos.Controls.Add(this.btnGooglePhotosCreateAlbum);
|
||||
this.tpGooglePhotos.Controls.Add(this.cbGooglePhotosIsPublic);
|
||||
this.tpGooglePhotos.Controls.Add(this.txtPicasaAlbumID);
|
||||
this.tpGooglePhotos.Controls.Add(this.lblPicasaAlbumID);
|
||||
this.tpGooglePhotos.Controls.Add(this.lvPicasaAlbumList);
|
||||
|
@ -5735,6 +5743,13 @@ private void InitializeComponent()
|
|||
resources.ApplyResources(this.tpGooglePhotos, "tpGooglePhotos");
|
||||
this.tpGooglePhotos.Name = "tpGooglePhotos";
|
||||
//
|
||||
// cbGooglePhotosIsPublic
|
||||
//
|
||||
resources.ApplyResources(this.cbGooglePhotosIsPublic, "cbGooglePhotosIsPublic");
|
||||
this.cbGooglePhotosIsPublic.Name = "cbGooglePhotosIsPublic";
|
||||
this.cbGooglePhotosIsPublic.UseVisualStyleBackColor = true;
|
||||
this.cbGooglePhotosIsPublic.CheckedChanged += new System.EventHandler(this.cbGooglePhotosIsPublic_CheckedChanged);
|
||||
//
|
||||
// txtPicasaAlbumID
|
||||
//
|
||||
resources.ApplyResources(this.txtPicasaAlbumID, "txtPicasaAlbumID");
|
||||
|
@ -5945,6 +5960,23 @@ private void InitializeComponent()
|
|||
this.actRapidShareAccountType.Name = "actRapidShareAccountType";
|
||||
this.actRapidShareAccountType.SelectedAccountType = ShareX.UploadersLib.AccountType.Anonymous;
|
||||
//
|
||||
// btnGooglePhotosCreateAlbum
|
||||
//
|
||||
resources.ApplyResources(this.btnGooglePhotosCreateAlbum, "btnGooglePhotosCreateAlbum");
|
||||
this.btnGooglePhotosCreateAlbum.Name = "btnGooglePhotosCreateAlbum";
|
||||
this.btnGooglePhotosCreateAlbum.UseVisualStyleBackColor = true;
|
||||
this.btnGooglePhotosCreateAlbum.Click += new System.EventHandler(this.btnGooglePhotosCreateAlbum_Click);
|
||||
//
|
||||
// txtGooglePhotosCreateAlbumName
|
||||
//
|
||||
resources.ApplyResources(this.txtGooglePhotosCreateAlbumName, "txtGooglePhotosCreateAlbumName");
|
||||
this.txtGooglePhotosCreateAlbumName.Name = "txtGooglePhotosCreateAlbumName";
|
||||
//
|
||||
// lblGooglePhotosCreateAlbumName
|
||||
//
|
||||
resources.ApplyResources(this.lblGooglePhotosCreateAlbumName, "lblGooglePhotosCreateAlbumName");
|
||||
this.lblGooglePhotosCreateAlbumName.Name = "lblGooglePhotosCreateAlbumName";
|
||||
//
|
||||
// UploadersConfigForm
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
|
@ -6841,5 +6873,9 @@ private void InitializeComponent()
|
|||
private System.Windows.Forms.ToolStripButton tsbCustomUploaderJSONFormat;
|
||||
private System.Windows.Forms.ToolStripButton tsbCustomUploaderXMLFormat;
|
||||
private System.Windows.Forms.ToolStripButton tsbCustomUploaderCopyResponseText;
|
||||
private System.Windows.Forms.CheckBox cbGooglePhotosIsPublic;
|
||||
private System.Windows.Forms.Label lblGooglePhotosCreateAlbumName;
|
||||
private System.Windows.Forms.TextBox txtGooglePhotosCreateAlbumName;
|
||||
private System.Windows.Forms.Button btnGooglePhotosCreateAlbum;
|
||||
}
|
||||
}
|
|
@ -299,6 +299,7 @@ private void LoadImageUploaderSettings()
|
|||
}
|
||||
|
||||
txtPicasaAlbumID.Text = Config.PicasaAlbumID;
|
||||
cbGooglePhotosIsPublic.Checked = Config.GooglePhotosIsPublic;
|
||||
|
||||
#endregion Google Photos
|
||||
|
||||
|
@ -1190,6 +1191,17 @@ private void lvPicasaAlbumList_SelectedIndexChanged(object sender, EventArgs e)
|
|||
}
|
||||
}
|
||||
|
||||
private void cbGooglePhotosIsPublic_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
Config.GooglePhotosIsPublic = cbGooglePhotosIsPublic.Checked;
|
||||
}
|
||||
|
||||
private void btnGooglePhotosCreateAlbum_Click(object sender, EventArgs e)
|
||||
{
|
||||
GooglePhotosCreateAlbum(txtGooglePhotosCreateAlbumName.Text);
|
||||
GooglePhotosRefreshAlbumList();
|
||||
}
|
||||
|
||||
#endregion Google Photos
|
||||
|
||||
#region Chevereto
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -244,6 +244,14 @@ public void GooglePhotosRefreshAlbumList()
|
|||
}
|
||||
}
|
||||
|
||||
public void GooglePhotosCreateAlbum(string albumName)
|
||||
{
|
||||
if (OAuth2Info.CheckOAuth(Config.PicasaOAuth2Info))
|
||||
{
|
||||
new GooglePhotos(Config.PicasaOAuth2Info).CreateAlbum(albumName);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Google Photos
|
||||
|
||||
#region Amazon S3
|
||||
|
|
|
@ -23,14 +23,13 @@ You should have received a copy of the GNU General Public License
|
|||
|
||||
#endregion License Information (GPL v3)
|
||||
|
||||
using ShareX.HelpersLib;
|
||||
using ShareX.UploadersLib.Properties;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ShareX.UploadersLib.ImageUploaders
|
||||
{
|
||||
|
@ -49,27 +48,25 @@ public override GenericUploader CreateUploader(UploadersConfig config, TaskRefer
|
|||
{
|
||||
return new GooglePhotos(config.PicasaOAuth2Info)
|
||||
{
|
||||
AlbumID = config.PicasaAlbumID
|
||||
AlbumID = config.PicasaAlbumID,
|
||||
IsPublic = config.GooglePhotosIsPublic
|
||||
};
|
||||
}
|
||||
|
||||
public override TabPage GetUploadersConfigTabPage(UploadersConfigForm form) => form.tpGooglePhotos;
|
||||
}
|
||||
|
||||
public class GooglePhotos : ImageUploader, IOAuth2
|
||||
public sealed class GooglePhotos : ImageUploader, IOAuth2
|
||||
{
|
||||
private GoogleOAuth2 GoogleAuth { get; set; }
|
||||
public string AlbumID { get; set; }
|
||||
|
||||
private static readonly XNamespace AtomNS = "http://www.w3.org/2005/Atom";
|
||||
private static readonly XNamespace MediaNS = "http://search.yahoo.com/mrss/";
|
||||
private static readonly XNamespace GPhotoNS = "http://schemas.google.com/photos/2007";
|
||||
public bool IsPublic { get; set; }
|
||||
|
||||
public GooglePhotos(OAuth2Info oauth)
|
||||
{
|
||||
GoogleAuth = new GoogleOAuth2(oauth, this)
|
||||
{
|
||||
Scope = "https://picasaweb.google.com/data"
|
||||
Scope = "https://www.googleapis.com/auth/photoslibrary https://www.googleapis.com/auth/photoslibrary.sharing"
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -95,11 +92,22 @@ public bool GetAccessToken(string code)
|
|||
return GoogleAuth.GetAccessToken(code);
|
||||
}
|
||||
|
||||
private NameValueCollection GetAuthHeaders()
|
||||
public GooglePhotosAlbum CreateAlbum(string albumName)
|
||||
{
|
||||
NameValueCollection headers = GoogleAuth.GetAuthHeaders();
|
||||
headers.Add("GData-Version", "3");
|
||||
return headers;
|
||||
GooglePhotosNewAlbum newItemAlbum = new GooglePhotosNewAlbum
|
||||
{
|
||||
album = new GooglePhotosAlbum
|
||||
{
|
||||
title = albumName
|
||||
}
|
||||
};
|
||||
|
||||
string serializedNewItemAlbum = JsonConvert.SerializeObject(newItemAlbum);
|
||||
string serializedNewItemAlbumResponse = SendRequest(HttpMethod.POST, "https://photoslibrary.googleapis.com/v1/albums", serializedNewItemAlbum, headers: GoogleAuth.GetAuthHeaders(), contentType: UploadHelpers.ContentTypeJSON);
|
||||
|
||||
GooglePhotosAlbum newItemAlbumResponse = JsonConvert.DeserializeObject<GooglePhotosAlbum>(serializedNewItemAlbumResponse);
|
||||
|
||||
return newItemAlbumResponse;
|
||||
}
|
||||
|
||||
public List<GooglePhotosAlbumInfo> GetAlbumList()
|
||||
|
@ -108,24 +116,40 @@ public List<GooglePhotosAlbumInfo> GetAlbumList()
|
|||
|
||||
List<GooglePhotosAlbumInfo> albumList = new List<GooglePhotosAlbumInfo>();
|
||||
|
||||
string response = SendRequest(HttpMethod.GET, "https://picasaweb.google.com/data/feed/api/user/default", headers: GetAuthHeaders());
|
||||
|
||||
if (!string.IsNullOrEmpty(response))
|
||||
Dictionary<string, string> args = new Dictionary<string, string>
|
||||
{
|
||||
XDocument xd = XDocument.Parse(response);
|
||||
{ "excludeNonAppCreatedData", "true" }
|
||||
};
|
||||
|
||||
if (xd != null)
|
||||
string pageToken = "";
|
||||
|
||||
do
|
||||
{
|
||||
args["pageToken"] = pageToken;
|
||||
string response = SendRequest(HttpMethod.GET, "https://photoslibrary.googleapis.com/v1/albums", args, headers: GoogleAuth.GetAuthHeaders());
|
||||
pageToken = "";
|
||||
|
||||
if (!string.IsNullOrEmpty(response))
|
||||
{
|
||||
foreach (XElement entry in xd.Descendants(AtomNS + "entry"))
|
||||
GooglePhotosAlbums albums = JsonConvert.DeserializeObject<GooglePhotosAlbums>(response);
|
||||
|
||||
if (albums.albums != null)
|
||||
{
|
||||
GooglePhotosAlbumInfo album = new GooglePhotosAlbumInfo();
|
||||
album.ID = entry.GetElementValue(GPhotoNS + "id");
|
||||
album.Name = entry.GetElementValue(AtomNS + "title");
|
||||
album.Summary = entry.GetElementValue(AtomNS + "summary");
|
||||
albumList.Add(album);
|
||||
foreach (GooglePhotosAlbum album in albums.albums)
|
||||
{
|
||||
GooglePhotosAlbumInfo AlbumInfo = new GooglePhotosAlbumInfo
|
||||
{
|
||||
ID = album.id,
|
||||
Name = album.title
|
||||
};
|
||||
|
||||
albumList.Add(AlbumInfo);
|
||||
}
|
||||
pageToken = albums.nextPageToken;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!string.IsNullOrEmpty(pageToken));
|
||||
|
||||
return albumList;
|
||||
}
|
||||
|
@ -134,48 +158,57 @@ public override UploadResult Upload(Stream stream, string fileName)
|
|||
{
|
||||
if (!CheckAuthorization()) return null;
|
||||
|
||||
if (string.IsNullOrEmpty(AlbumID))
|
||||
UploadResult result = new UploadResult();
|
||||
|
||||
if (IsPublic)
|
||||
{
|
||||
AlbumID = "default";
|
||||
AlbumID = CreateAlbum(fileName).id;
|
||||
|
||||
GooglePhotosAlbumOptions albumOptions = new GooglePhotosAlbumOptions();
|
||||
|
||||
string serializedAlbumOptions = JsonConvert.SerializeObject(albumOptions);
|
||||
string serializedAlbumOptionsResponse = SendRequest(HttpMethod.POST, $"https://photoslibrary.googleapis.com/v1/albums/{AlbumID}:share", content: serializedAlbumOptions, headers: GoogleAuth.GetAuthHeaders(), contentType: UploadHelpers.ContentTypeJSON);
|
||||
GooglePhotosAlbumOptionsResponse albumOptionsResponse = JsonConvert.DeserializeObject<GooglePhotosAlbumOptionsResponse>(serializedAlbumOptionsResponse);
|
||||
|
||||
result.URL = albumOptionsResponse.shareInfo.shareableUrl;
|
||||
}
|
||||
|
||||
UploadResult ur = new UploadResult();
|
||||
|
||||
string url = string.Format("https://picasaweb.google.com/data/feed/api/user/default/albumid/" + AlbumID);
|
||||
string contentType = UploadHelpers.GetMimeType(fileName);
|
||||
|
||||
NameValueCollection headers = GetAuthHeaders();
|
||||
headers.Add("Slug", URLHelpers.URLEncode(fileName));
|
||||
|
||||
ur.Response = SendRequest(HttpMethod.POST, url, stream, contentType, null, headers);
|
||||
|
||||
if (ur.Response != null)
|
||||
NameValueCollection uploadTokenHeaders = new NameValueCollection
|
||||
{
|
||||
XDocument xd = XDocument.Parse(ur.Response);
|
||||
{ "X-Goog-Upload-File-Name", fileName },
|
||||
{ "X-Goog-Upload-Protocol", "raw" },
|
||||
{ "Authorization", GoogleAuth.GetAuthHeaders()["Authorization"] }
|
||||
};
|
||||
|
||||
XElement entry_element = xd.Element(AtomNS + "entry");
|
||||
string uploadToken = SendRequest(HttpMethod.POST, "https://photoslibrary.googleapis.com/v1/uploads", stream, contentType: UploadHelpers.ContentTypeOctetStream, headers: uploadTokenHeaders);
|
||||
|
||||
if (entry_element != null)
|
||||
GooglePhotosNewMediaItemRequest newMediaItemRequest = new GooglePhotosNewMediaItemRequest
|
||||
{
|
||||
albumId = AlbumID,
|
||||
newMediaItems = new GooglePhotosNewMediaItem[]
|
||||
{
|
||||
XElement group_element = entry_element.Element(MediaNS + "group");
|
||||
|
||||
if (group_element != null)
|
||||
new GooglePhotosNewMediaItem
|
||||
{
|
||||
XElement content_element = group_element.Element(MediaNS + "content");
|
||||
|
||||
if (content_element != null)
|
||||
simpleMediaItem = new GooglePhotosSimpleMediaItem
|
||||
{
|
||||
ur.ThumbnailURL = content_element.GetAttributeValue("url");
|
||||
|
||||
int last_slash_index = ur.ThumbnailURL.LastIndexOf(@"/");
|
||||
|
||||
ur.URL = ur.ThumbnailURL.Insert(last_slash_index, @"/s0");
|
||||
uploadToken = uploadToken
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
string serializedNewMediaItemRequest = JsonConvert.SerializeObject(newMediaItemRequest);
|
||||
|
||||
result.Response = SendRequest(HttpMethod.POST, "https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate", serializedNewMediaItemRequest, headers: GoogleAuth.GetAuthHeaders(), contentType: UploadHelpers.ContentTypeJSON);
|
||||
|
||||
GooglePhotosNewMediaItemResults newMediaItemResult = JsonConvert.DeserializeObject<GooglePhotosNewMediaItemResults>(result.Response);
|
||||
|
||||
if (!IsPublic)
|
||||
{
|
||||
result.URL = newMediaItemResult.newMediaItemResults[0].mediaItem.productUrl;
|
||||
}
|
||||
|
||||
return ur;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,4 +218,106 @@ public class GooglePhotosAlbumInfo
|
|||
public string Name { get; set; }
|
||||
public string Summary { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosAlbums
|
||||
{
|
||||
public GooglePhotosAlbum[] albums { get; set; }
|
||||
public string nextPageToken { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosAlbum
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string title { get; set; }
|
||||
public string productUrl { get; set; }
|
||||
public string coverPhotoBaseUrl { get; set; }
|
||||
public string coverPhotoMediaItemId { get; set; }
|
||||
public string isWriteable { get; set; }
|
||||
public string mediaItemsCount { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosNewMediaItemRequest
|
||||
{
|
||||
public string albumId { get; set; }
|
||||
public GooglePhotosNewMediaItem[] newMediaItems { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosNewMediaItem
|
||||
{
|
||||
public string description { get; set; }
|
||||
public GooglePhotosSimpleMediaItem simpleMediaItem { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosSimpleMediaItem
|
||||
{
|
||||
public string uploadToken { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosNewMediaItemResults
|
||||
{
|
||||
public GooglePhotosNewMediaItemResult[] newMediaItemResults { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosNewMediaItemResult
|
||||
{
|
||||
public string uploadToken { get; set; }
|
||||
public GooglePhotosStatus status { get; set; }
|
||||
public GooglePhotosMediaItem mediaItem { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosStatus
|
||||
{
|
||||
public string message { get; set; }
|
||||
public int code { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosMediaItem
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string productUrl { get; set; }
|
||||
public string description { get; set; }
|
||||
public string baseUrl { get; set; }
|
||||
public GooglePhotosMediaMetaData mediaMetadata { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosMediaMetaData
|
||||
{
|
||||
public string width { get; set; }
|
||||
public string height { get; set; }
|
||||
public string creationTime { get; set; }
|
||||
public GooglePhotosPhoto photo { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosPhoto
|
||||
{
|
||||
}
|
||||
|
||||
public class GooglePhotosNewAlbum
|
||||
{
|
||||
public GooglePhotosAlbum album { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosAlbumOptions
|
||||
{
|
||||
public GooglePhotosSharedAlbumOptions sharedAlbumOptions { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosSharedAlbumOptions
|
||||
{
|
||||
public string isCollaborative { get; set; }
|
||||
public string isCommentable { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosAlbumOptionsResponse
|
||||
{
|
||||
public GooglePhotosShareInfo shareInfo { get; set; }
|
||||
}
|
||||
|
||||
public class GooglePhotosShareInfo
|
||||
{
|
||||
public GooglePhotosSharedAlbumOptions sharedAlbumOptions { get; set; }
|
||||
public string shareableUrl { get; set; }
|
||||
public string shareToken { get; set; }
|
||||
public string isJoined { get; set; }
|
||||
}
|
||||
}
|
|
@ -83,6 +83,7 @@ public class UploadersConfig : SettingsBase<UploadersConfig>
|
|||
|
||||
public OAuth2Info PicasaOAuth2Info = null;
|
||||
public string PicasaAlbumID = "";
|
||||
public bool GooglePhotosIsPublic = false;
|
||||
|
||||
#endregion Google Photos
|
||||
|
||||
|
|
Loading…
Reference in a new issue