mirror of
https://github.com/ShareX/ShareX.git
synced 2024-10-02 18:26:27 +13:00
Merge pull request #3297 from SupSuper/youtube-uploader
Add support for Youtube uploading
This commit is contained in:
commit
c44611e9fc
15 changed files with 656 additions and 16 deletions
40
ShareX.HelpersLib/Properties/Resources.Designer.cs
generated
40
ShareX.HelpersLib/Properties/Resources.Designer.cs
generated
|
@ -137,15 +137,7 @@ internal static string ActionsCodeMenuEntry_OutputFilePath_File_path_without_ext
|
|||
///easygoing
|
||||
///ecstatic
|
||||
///edible
|
||||
///educated
|
||||
///fabulous
|
||||
///failing
|
||||
///faint
|
||||
///fair
|
||||
///faithful
|
||||
///fake
|
||||
///familiar
|
||||
///fam [rest of string was truncated]";.
|
||||
///educat [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string adjectives {
|
||||
get {
|
||||
|
@ -421,8 +413,7 @@ internal static string AmazonS3StorageClass_STANDARD_IA {
|
|||
///africanjacana
|
||||
///africanmolesnake
|
||||
///africanparadiseflycatcher
|
||||
///africanpiedkingfisher
|
||||
///africanporcu [rest of string was truncated]";.
|
||||
///a [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string animals {
|
||||
get {
|
||||
|
@ -3296,5 +3287,32 @@ internal static string WavFileNameEditor_EditValue_Browse_for_a_sound_file___ {
|
|||
return ResourceManager.GetString("WavFileNameEditor_EditValue_Browse_for_a_sound_file___", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Private.
|
||||
/// </summary>
|
||||
internal static string YouTubeVideoPrivacy_Private {
|
||||
get {
|
||||
return ResourceManager.GetString("YouTubeVideoPrivacy_Private", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Public.
|
||||
/// </summary>
|
||||
internal static string YouTubeVideoPrivacy_Public {
|
||||
get {
|
||||
return ResourceManager.GetString("YouTubeVideoPrivacy_Public", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Unlisted.
|
||||
/// </summary>
|
||||
internal static string YouTubeVideoPrivacy_Unlisted {
|
||||
get {
|
||||
return ResourceManager.GetString("YouTubeVideoPrivacy_Unlisted", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1163,4 +1163,13 @@ Would you like to download it?</value>
|
|||
<data name="AfterCaptureTasks_ScanQRCode" xml:space="preserve">
|
||||
<value>Scan QR code</value>
|
||||
</data>
|
||||
<data name="YouTubeVideoPrivacy_Private" xml:space="preserve">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="YouTubeVideoPrivacy_Public" xml:space="preserve">
|
||||
<value>Public</value>
|
||||
</data>
|
||||
<data name="YouTubeVideoPrivacy_Unlisted" xml:space="preserve">
|
||||
<value>Unlisted</value>
|
||||
</data>
|
||||
</root>
|
|
@ -189,7 +189,7 @@ protected bool SendRequestDownload(HttpMethod method, string url, Stream downloa
|
|||
return false;
|
||||
}
|
||||
|
||||
protected string SendRequestMultiPart(string url, Dictionary<string, string> args, NameValueCollection headers = null, CookieCollection cookies = null,
|
||||
public string SendRequestMultiPart(string url, Dictionary<string, string> args, NameValueCollection headers = null, CookieCollection cookies = null,
|
||||
ResponseType responseType = ResponseType.Text)
|
||||
{
|
||||
string boundary = CreateBoundary();
|
||||
|
|
|
@ -139,6 +139,8 @@ public enum FileDestination
|
|||
Transfersh,
|
||||
[Description("Plik")]
|
||||
Plik,
|
||||
[Description("YouTube")]
|
||||
YouTube,
|
||||
SharedFolder, // Localized
|
||||
Email, // Localized
|
||||
CustomFileUploader // Localized
|
||||
|
|
BIN
ShareX.UploadersLib/Favicons/YouTube.ico
Normal file
BIN
ShareX.UploadersLib/Favicons/YouTube.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
183
ShareX.UploadersLib/FileUploaders/YouTube.cs
Normal file
183
ShareX.UploadersLib/FileUploaders/YouTube.cs
Normal file
|
@ -0,0 +1,183 @@
|
|||
#region License Information (GPL v3)
|
||||
|
||||
/*
|
||||
ShareX - A program that allows you to take screenshots and share any file type
|
||||
Copyright (c) 2007-2018 ShareX Team
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#endregion License Information (GPL v3)
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using ShareX.HelpersLib;
|
||||
using ShareX.UploadersLib.Properties;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ShareX.UploadersLib.FileUploaders
|
||||
{
|
||||
public class YouTubeFileUploaderService : FileUploaderService
|
||||
{
|
||||
public override FileDestination EnumValue { get; } = FileDestination.YouTube;
|
||||
|
||||
public override Icon ServiceIcon => Resources.YouTube;
|
||||
|
||||
public override bool CheckConfig(UploadersConfig config)
|
||||
{
|
||||
return OAuth2Info.CheckOAuth(config.YouTubeOAuth2Info);
|
||||
}
|
||||
|
||||
public override GenericUploader CreateUploader(UploadersConfig config, TaskReferenceHelper taskInfo)
|
||||
{
|
||||
return new YouTube(config.YouTubeOAuth2Info)
|
||||
{
|
||||
PrivacyType = config.YouTubePrivacyType
|
||||
};
|
||||
}
|
||||
|
||||
public override TabPage GetUploadersConfigTabPage(UploadersConfigForm form) => form.tpYouTube;
|
||||
}
|
||||
|
||||
public sealed class YouTube : FileUploader, IOAuth2
|
||||
{
|
||||
private GoogleOAuth2 GoogleAuth { get; set; }
|
||||
public YouTubeVideoPrivacy PrivacyType { get; set; }
|
||||
|
||||
public YouTube(OAuth2Info oauth)
|
||||
{
|
||||
GoogleAuth = new GoogleOAuth2(oauth, this)
|
||||
{
|
||||
Scope = "youtube.upload"
|
||||
};
|
||||
}
|
||||
|
||||
public OAuth2Info AuthInfo => GoogleAuth.AuthInfo;
|
||||
|
||||
public bool RefreshAccessToken()
|
||||
{
|
||||
return GoogleAuth.RefreshAccessToken();
|
||||
}
|
||||
|
||||
public bool CheckAuthorization()
|
||||
{
|
||||
return GoogleAuth.CheckAuthorization();
|
||||
}
|
||||
|
||||
public string GetAuthorizationURL()
|
||||
{
|
||||
return GoogleAuth.GetAuthorizationURL();
|
||||
}
|
||||
|
||||
public bool GetAccessToken(string code)
|
||||
{
|
||||
return GoogleAuth.GetAccessToken(code);
|
||||
}
|
||||
|
||||
private string GetMetadata(string title)
|
||||
{
|
||||
object metadata;
|
||||
|
||||
metadata = new
|
||||
{
|
||||
snippet = new
|
||||
{
|
||||
title = title
|
||||
},
|
||||
status = new
|
||||
{
|
||||
privacyStatus = PrivacyType
|
||||
}
|
||||
};
|
||||
|
||||
return JsonConvert.SerializeObject(metadata);
|
||||
}
|
||||
|
||||
public override UploadResult Upload(Stream stream, string fileName)
|
||||
{
|
||||
if (!CheckAuthorization()) return null;
|
||||
|
||||
if (!Helpers.IsVideoFile(fileName))
|
||||
{
|
||||
Errors.Add("YouTube only supports video files");
|
||||
return null;
|
||||
}
|
||||
|
||||
string metadata = GetMetadata(fileName);
|
||||
|
||||
UploadResult result = SendRequestFile("https://www.googleapis.com/upload/youtube/v3/videos?part=id,snippet,status", stream, fileName,
|
||||
headers: GoogleAuth.GetAuthHeaders(), metadata: metadata);
|
||||
|
||||
if (!string.IsNullOrEmpty(result.Response))
|
||||
{
|
||||
YouTubeVideo upload = JsonConvert.DeserializeObject<YouTubeVideo>(result.Response);
|
||||
|
||||
if (upload != null)
|
||||
{
|
||||
AllowReportProgress = false;
|
||||
|
||||
result.URL = "https://youtu.be/" + upload.id;
|
||||
|
||||
switch (upload.status.uploadStatus)
|
||||
{
|
||||
case YouTubeVideoStatus.UploadFailed:
|
||||
Errors.Add("Upload failed: " + upload.status.failureReason);
|
||||
break;
|
||||
case YouTubeVideoStatus.UploadRejected:
|
||||
Errors.Add("Upload rejected: " + upload.status.rejectionReason);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class YouTubeVideo
|
||||
{
|
||||
public string id { get; set; }
|
||||
public YouTubeVideoSnippet snippet { get; set; }
|
||||
public YouTubeVideoStatus status { get; set; }
|
||||
}
|
||||
|
||||
public class YouTubeVideoSnippet
|
||||
{
|
||||
public string title { get; set; }
|
||||
}
|
||||
|
||||
public class YouTubeVideoStatus
|
||||
{
|
||||
public const string UploadFailed = "failed";
|
||||
public const string UploadRejected = "rejected";
|
||||
|
||||
public YouTubeVideoPrivacy privacyStatus { get; set; }
|
||||
public string uploadStatus { get; set; }
|
||||
public string failureReason { get; set; }
|
||||
public string rejectionReason { get; set; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum YouTubeVideoPrivacy // Localized
|
||||
{
|
||||
Public,
|
||||
Unlisted,
|
||||
Private
|
||||
}
|
||||
}
|
|
@ -481,6 +481,10 @@ private void InitializeComponent()
|
|||
this.lblPlikUsername = new System.Windows.Forms.Label();
|
||||
this.txtPlikPassword = new System.Windows.Forms.TextBox();
|
||||
this.txtPlikLogin = new System.Windows.Forms.TextBox();
|
||||
this.tpYouTube = new System.Windows.Forms.TabPage();
|
||||
this.oauth2YouTube = new ShareX.UploadersLib.OAuthControl();
|
||||
this.cbYouTubePrivacyType = new System.Windows.Forms.ComboBox();
|
||||
this.lblYouTubePrivacyType = new System.Windows.Forms.Label();
|
||||
this.tpSharedFolder = new System.Windows.Forms.TabPage();
|
||||
this.lblSharedFolderFiles = new System.Windows.Forms.Label();
|
||||
this.lblSharedFolderText = new System.Windows.Forms.Label();
|
||||
|
@ -700,6 +704,7 @@ private void InitializeComponent()
|
|||
this.gbPlikSettings.SuspendLayout();
|
||||
this.gbPlikLoginCredentials.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudPlikTTL)).BeginInit();
|
||||
this.tpYouTube.SuspendLayout();
|
||||
this.tpSharedFolder.SuspendLayout();
|
||||
this.tpEmail.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudEmailSmtpPort)).BeginInit();
|
||||
|
@ -1848,6 +1853,7 @@ private void InitializeComponent()
|
|||
this.tcFileUploaders.Controls.Add(this.tpSul);
|
||||
this.tcFileUploaders.Controls.Add(this.tpLithiio);
|
||||
this.tcFileUploaders.Controls.Add(this.tpPlik);
|
||||
this.tcFileUploaders.Controls.Add(this.tpYouTube);
|
||||
this.tcFileUploaders.Controls.Add(this.tpSharedFolder);
|
||||
this.tcFileUploaders.Controls.Add(this.tpEmail);
|
||||
resources.ApplyResources(this.tcFileUploaders, "tcFileUploaders");
|
||||
|
@ -4064,6 +4070,37 @@ private void InitializeComponent()
|
|||
this.txtPlikLogin.Name = "txtPlikLogin";
|
||||
this.txtPlikLogin.TextChanged += new System.EventHandler(this.txtPlikLogin_TextChanged);
|
||||
//
|
||||
// tpYouTube
|
||||
//
|
||||
this.tpYouTube.Controls.Add(this.oauth2YouTube);
|
||||
this.tpYouTube.Controls.Add(this.cbYouTubePrivacyType);
|
||||
this.tpYouTube.Controls.Add(this.lblYouTubePrivacyType);
|
||||
resources.ApplyResources(this.tpYouTube, "tpYouTube");
|
||||
this.tpYouTube.Name = "tpYouTube";
|
||||
this.tpYouTube.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// oauth2YouTube
|
||||
//
|
||||
resources.ApplyResources(this.oauth2YouTube, "oauth2YouTube");
|
||||
this.oauth2YouTube.Name = "oauth2YouTube";
|
||||
this.oauth2YouTube.OpenButtonClicked += new ShareX.UploadersLib.OAuthControl.OpenButtonClickedEventHandler(this.oauth2YouTube_OpenButtonClicked);
|
||||
this.oauth2YouTube.CompleteButtonClicked += new ShareX.UploadersLib.OAuthControl.CompleteButtonClickedEventHandler(this.oauth2YouTube_CompleteButtonClicked);
|
||||
this.oauth2YouTube.ClearButtonClicked += new ShareX.UploadersLib.OAuthControl.ClearButtonclickedEventHandler(this.oauth2YouTube_ClearButtonClicked);
|
||||
this.oauth2YouTube.RefreshButtonClicked += new ShareX.UploadersLib.OAuthControl.RefreshButtonClickedEventHandler(this.oauth2YouTube_RefreshButtonClicked);
|
||||
//
|
||||
// cbYouTubePrivacyType
|
||||
//
|
||||
this.cbYouTubePrivacyType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cbYouTubePrivacyType.FormattingEnabled = true;
|
||||
resources.ApplyResources(this.cbYouTubePrivacyType, "cbYouTubePrivacyType");
|
||||
this.cbYouTubePrivacyType.Name = "cbYouTubePrivacyType";
|
||||
this.cbYouTubePrivacyType.SelectedIndexChanged += new System.EventHandler(this.cbYouTubePrivacyType_SelectedIndexChanged);
|
||||
//
|
||||
// lblYouTubePrivacyType
|
||||
//
|
||||
resources.ApplyResources(this.lblYouTubePrivacyType, "lblYouTubePrivacyType");
|
||||
this.lblYouTubePrivacyType.Name = "lblYouTubePrivacyType";
|
||||
//
|
||||
// tpSharedFolder
|
||||
//
|
||||
this.tpSharedFolder.BackColor = System.Drawing.SystemColors.Window;
|
||||
|
@ -5301,6 +5338,8 @@ private void InitializeComponent()
|
|||
this.gbPlikLoginCredentials.ResumeLayout(false);
|
||||
this.gbPlikLoginCredentials.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudPlikTTL)).EndInit();
|
||||
this.tpYouTube.ResumeLayout(false);
|
||||
this.tpYouTube.PerformLayout();
|
||||
this.tpSharedFolder.ResumeLayout(false);
|
||||
this.tpSharedFolder.PerformLayout();
|
||||
this.tpEmail.ResumeLayout(false);
|
||||
|
@ -5957,5 +5996,9 @@ private void InitializeComponent()
|
|||
private System.Windows.Forms.TextBox txtFirebaseDomain;
|
||||
private System.Windows.Forms.TextBox txtFirebaseWebAPIKey;
|
||||
private System.Windows.Forms.Label lblFirebaseWebAPIKey;
|
||||
private OAuthControl oauth2YouTube;
|
||||
private System.Windows.Forms.ComboBox cbYouTubePrivacyType;
|
||||
private System.Windows.Forms.Label lblYouTubePrivacyType;
|
||||
internal System.Windows.Forms.TabPage tpYouTube;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -398,6 +398,8 @@ public void LoadSettings()
|
|||
if (OAuth2Info.CheckOAuth(Config.OneDriveOAuth2Info))
|
||||
{
|
||||
oAuth2OneDrive.Status = OAuthLoginStatus.LoginSuccessful;
|
||||
|
||||
tvOneDrive.Enabled = true;
|
||||
}
|
||||
|
||||
cbOneDriveCreateShareableLink.Checked = Config.OneDriveAutoCreateShareableLink;
|
||||
|
@ -412,8 +414,6 @@ public void LoadSettings()
|
|||
{
|
||||
oauth2GoogleDrive.Status = OAuthLoginStatus.LoginSuccessful;
|
||||
btnGoogleDriveRefreshFolders.Enabled = true;
|
||||
|
||||
tvOneDrive.Enabled = true;
|
||||
}
|
||||
|
||||
cbGoogleDriveIsPublic.Checked = Config.GoogleDriveIsPublic;
|
||||
|
@ -718,6 +718,19 @@ public void LoadSettings()
|
|||
|
||||
#endregion Gfycat
|
||||
|
||||
#region YouTube
|
||||
|
||||
if (OAuth2Info.CheckOAuth(Config.YouTubeOAuth2Info))
|
||||
{
|
||||
oauth2YouTube.Status = OAuthLoginStatus.LoginSuccessful;
|
||||
}
|
||||
|
||||
cbYouTubePrivacyType.Items.Clear();
|
||||
cbYouTubePrivacyType.Items.AddRange(Helpers.GetLocalizedEnumDescriptions<YouTubeVideoPrivacy>());
|
||||
cbYouTubePrivacyType.SelectedIndex = (int)Config.YouTubePrivacyType;
|
||||
|
||||
#endregion YouTube
|
||||
|
||||
#endregion File uploaders
|
||||
|
||||
#region URL shorteners
|
||||
|
@ -2993,6 +3006,36 @@ private void cbGfycatIsPublic_CheckedChanged(object sender, EventArgs e)
|
|||
|
||||
#endregion Gfycat
|
||||
|
||||
#region YouTube
|
||||
|
||||
private void oauth2YouTube_OpenButtonClicked()
|
||||
{
|
||||
OAuth2Info oauth = new OAuth2Info(APIKeys.GoogleClientID, APIKeys.GoogleClientSecret);
|
||||
Config.YouTubeOAuth2Info = OAuth2Open(new YouTube(oauth));
|
||||
}
|
||||
|
||||
private void oauth2YouTube_CompleteButtonClicked(string code)
|
||||
{
|
||||
OAuth2Complete(new YouTube(Config.YouTubeOAuth2Info), oauth2YouTube, code);
|
||||
}
|
||||
|
||||
private void oauth2YouTube_RefreshButtonClicked()
|
||||
{
|
||||
OAuth2Refresh(new YouTube(Config.YouTubeOAuth2Info), oauth2YouTube);
|
||||
}
|
||||
|
||||
private void oauth2YouTube_ClearButtonClicked()
|
||||
{
|
||||
Config.YouTubeOAuth2Info = null;
|
||||
}
|
||||
|
||||
private void cbYouTubePrivacyType_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
Config.YouTubePrivacyType = (YouTubeVideoPrivacy)cbYouTubePrivacyType.SelectedIndex;
|
||||
}
|
||||
|
||||
#endregion YouTube
|
||||
|
||||
#endregion File uploaders
|
||||
|
||||
#region URL shorteners
|
||||
|
|
|
@ -11762,6 +11762,99 @@ Using an encrypted library disables sharing.</value>
|
|||
<data name=">>tpPlik.ZOrder" xml:space="preserve">
|
||||
<value>23</value>
|
||||
</data>
|
||||
<data name="oauth2YouTube.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>16, 16</value>
|
||||
</data>
|
||||
<data name="oauth2YouTube.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>326, 238</value>
|
||||
</data>
|
||||
<data name="oauth2YouTube.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>oauth2YouTube.Name" xml:space="preserve">
|
||||
<value>oauth2YouTube</value>
|
||||
</data>
|
||||
<data name=">>oauth2YouTube.Type" xml:space="preserve">
|
||||
<value>ShareX.UploadersLib.OAuthControl, ShareX.UploadersLib, Version=12.2.0.0, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>oauth2YouTube.Parent" xml:space="preserve">
|
||||
<value>tpYouTube</value>
|
||||
</data>
|
||||
<data name=">>oauth2YouTube.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="cbYouTubePrivacyType.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>16, 273</value>
|
||||
</data>
|
||||
<data name="cbYouTubePrivacyType.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>128, 21</value>
|
||||
</data>
|
||||
<data name="cbYouTubePrivacyType.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>cbYouTubePrivacyType.Name" xml:space="preserve">
|
||||
<value>cbYouTubePrivacyType</value>
|
||||
</data>
|
||||
<data name=">>cbYouTubePrivacyType.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>cbYouTubePrivacyType.Parent" xml:space="preserve">
|
||||
<value>tpYouTube</value>
|
||||
</data>
|
||||
<data name=">>cbYouTubePrivacyType.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="lblYouTubePrivacyType.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="lblYouTubePrivacyType.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>13, 257</value>
|
||||
</data>
|
||||
<data name="lblYouTubePrivacyType.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>68, 13</value>
|
||||
</data>
|
||||
<data name="lblYouTubePrivacyType.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="lblYouTubePrivacyType.Text" xml:space="preserve">
|
||||
<value>Privacy type:</value>
|
||||
</data>
|
||||
<data name=">>lblYouTubePrivacyType.Name" xml:space="preserve">
|
||||
<value>lblYouTubePrivacyType</value>
|
||||
</data>
|
||||
<data name=">>lblYouTubePrivacyType.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>lblYouTubePrivacyType.Parent" xml:space="preserve">
|
||||
<value>tpYouTube</value>
|
||||
</data>
|
||||
<data name=">>lblYouTubePrivacyType.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="tpYouTube.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 40</value>
|
||||
</data>
|
||||
<data name="tpYouTube.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>972, 519</value>
|
||||
</data>
|
||||
<data name="tpYouTube.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>31</value>
|
||||
</data>
|
||||
<data name="tpYouTube.Text" xml:space="preserve">
|
||||
<value>YouTube</value>
|
||||
</data>
|
||||
<data name=">>tpYouTube.Name" xml:space="preserve">
|
||||
<value>tpYouTube</value>
|
||||
</data>
|
||||
<data name=">>tpYouTube.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tpYouTube.Parent" xml:space="preserve">
|
||||
<value>tcFileUploaders</value>
|
||||
</data>
|
||||
<data name=">>tpYouTube.ZOrder" xml:space="preserve">
|
||||
<value>24</value>
|
||||
</data>
|
||||
<data name="lblSharedFolderFiles.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
|
@ -11967,7 +12060,7 @@ Using an encrypted library disables sharing.</value>
|
|||
<value>tcFileUploaders</value>
|
||||
</data>
|
||||
<data name=">>tpSharedFolder.ZOrder" xml:space="preserve">
|
||||
<value>24</value>
|
||||
<value>25</value>
|
||||
</data>
|
||||
<data name="txtEmailAutomaticSendTo.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>16, 408</value>
|
||||
|
@ -12387,7 +12480,7 @@ Using an encrypted library disables sharing.</value>
|
|||
<value>tcFileUploaders</value>
|
||||
</data>
|
||||
<data name=">>tpEmail.ZOrder" xml:space="preserve">
|
||||
<value>25</value>
|
||||
<value>26</value>
|
||||
</data>
|
||||
<data name="tcFileUploaders.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
|
|
|
@ -2100,5 +2100,91 @@ private void GfycatAuthRefresh()
|
|||
}
|
||||
|
||||
#endregion Gfycat
|
||||
|
||||
#region Generic OAuth2
|
||||
|
||||
public OAuth2Info OAuth2Open(IOAuth2 uploader)
|
||||
{
|
||||
try
|
||||
{
|
||||
string url = uploader.GetAuthorizationURL();
|
||||
|
||||
if (!string.IsNullOrEmpty(url))
|
||||
{
|
||||
URLHelpers.OpenURL(url);
|
||||
DebugHelper.WriteLine(uploader.ToString() + " - Authorization URL is opened: " + url);
|
||||
return uploader.AuthInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugHelper.WriteLine(uploader.ToString() + " - Authorization URL is empty.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.ShowError();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool OAuth2Complete(IOAuth2 uploader, OAuthControl oauth2, string code)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(code) && uploader.AuthInfo != null)
|
||||
{
|
||||
bool result = uploader.GetAccessToken(code);
|
||||
|
||||
if (result)
|
||||
{
|
||||
oauth2.Status = OAuthLoginStatus.LoginSuccessful;
|
||||
MessageBox.Show(Resources.UploadersConfigForm_Login_successful, "ShareX", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
oauth2.Status = OAuthLoginStatus.LoginFailed;
|
||||
MessageBox.Show(Resources.UploadersConfigForm_Login_failed, "ShareX", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.ShowError();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool OAuth2Refresh(IOAuth2 uploader, OAuthControl oauth2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (OAuth2Info.CheckOAuth(uploader.AuthInfo))
|
||||
{
|
||||
bool result = uploader.RefreshAccessToken();
|
||||
|
||||
if (result)
|
||||
{
|
||||
oauth2.Status = OAuthLoginStatus.LoginSuccessful;
|
||||
MessageBox.Show(Resources.UploadersConfigForm_Login_successful, "ShareX", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
oauth2.Status = OAuthLoginStatus.LoginFailed;
|
||||
MessageBox.Show(Resources.UploadersConfigForm_Login_failed, "ShareX", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.ShowError();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion Generic OAuth2
|
||||
}
|
||||
}
|
138
ShareX.UploadersLib/Helpers/GoogleOAuth2.cs
Normal file
138
ShareX.UploadersLib/Helpers/GoogleOAuth2.cs
Normal file
|
@ -0,0 +1,138 @@
|
|||
#region License Information (GPL v3)
|
||||
|
||||
/*
|
||||
ShareX - A program that allows you to take screenshots and share any file type
|
||||
Copyright (c) 2007-2018 ShareX Team
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#endregion License Information (GPL v3)
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using ShareX.HelpersLib;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace ShareX.UploadersLib
|
||||
{
|
||||
public class GoogleOAuth2 : IOAuth2
|
||||
{
|
||||
public OAuth2Info AuthInfo { get; private set; }
|
||||
private Uploader GoogleUploader { get; set; }
|
||||
public string Scope { get; set; }
|
||||
|
||||
public GoogleOAuth2(OAuth2Info oauth, Uploader uploader)
|
||||
{
|
||||
AuthInfo = oauth;
|
||||
GoogleUploader = uploader;
|
||||
}
|
||||
|
||||
public string GetAuthorizationURL()
|
||||
{
|
||||
Dictionary<string, string> args = new Dictionary<string, string>();
|
||||
args.Add("response_type", "code");
|
||||
args.Add("client_id", AuthInfo.Client_ID);
|
||||
args.Add("redirect_uri", "urn:ietf:wg:oauth:2.0:oob");
|
||||
args.Add("scope", "https://www.googleapis.com/auth/" + Scope);
|
||||
|
||||
return URLHelpers.CreateQuery("https://accounts.google.com/o/oauth2/auth", args);
|
||||
}
|
||||
|
||||
public bool GetAccessToken(string code)
|
||||
{
|
||||
Dictionary<string, string> args = new Dictionary<string, string>();
|
||||
args.Add("code", code);
|
||||
args.Add("client_id", AuthInfo.Client_ID);
|
||||
args.Add("client_secret", AuthInfo.Client_Secret);
|
||||
args.Add("redirect_uri", "urn:ietf:wg:oauth:2.0:oob");
|
||||
args.Add("grant_type", "authorization_code");
|
||||
|
||||
string response = GoogleUploader.SendRequestMultiPart("https://accounts.google.com/o/oauth2/token", args);
|
||||
|
||||
if (!string.IsNullOrEmpty(response))
|
||||
{
|
||||
OAuth2Token token = JsonConvert.DeserializeObject<OAuth2Token>(response);
|
||||
|
||||
if (token != null && !string.IsNullOrEmpty(token.access_token))
|
||||
{
|
||||
token.UpdateExpireDate();
|
||||
AuthInfo.Token = token;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool RefreshAccessToken()
|
||||
{
|
||||
if (OAuth2Info.CheckOAuth(AuthInfo) && !string.IsNullOrEmpty(AuthInfo.Token.refresh_token))
|
||||
{
|
||||
Dictionary<string, string> args = new Dictionary<string, string>();
|
||||
args.Add("refresh_token", AuthInfo.Token.refresh_token);
|
||||
args.Add("client_id", AuthInfo.Client_ID);
|
||||
args.Add("client_secret", AuthInfo.Client_Secret);
|
||||
args.Add("grant_type", "refresh_token");
|
||||
|
||||
string response = GoogleUploader.SendRequestMultiPart("https://accounts.google.com/o/oauth2/token", args);
|
||||
|
||||
if (!string.IsNullOrEmpty(response))
|
||||
{
|
||||
OAuth2Token token = JsonConvert.DeserializeObject<OAuth2Token>(response);
|
||||
|
||||
if (token != null && !string.IsNullOrEmpty(token.access_token))
|
||||
{
|
||||
token.UpdateExpireDate();
|
||||
string refresh_token = AuthInfo.Token.refresh_token;
|
||||
AuthInfo.Token = token;
|
||||
AuthInfo.Token.refresh_token = refresh_token;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CheckAuthorization()
|
||||
{
|
||||
if (OAuth2Info.CheckOAuth(AuthInfo))
|
||||
{
|
||||
if (AuthInfo.Token.IsExpired && !RefreshAccessToken())
|
||||
{
|
||||
GoogleUploader.Errors.Add("Refresh access token failed.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GoogleUploader.Errors.Add("Login is required.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public NameValueCollection GetAuthHeaders()
|
||||
{
|
||||
NameValueCollection headers = new NameValueCollection();
|
||||
headers.Add("Authorization", "Bearer " + AuthInfo.Token.access_token);
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
}
|
10
ShareX.UploadersLib/Properties/Resources.Designer.cs
generated
10
ShareX.UploadersLib/Properties/Resources.Designer.cs
generated
|
@ -986,5 +986,15 @@ internal static System.Drawing.Icon Yourls {
|
|||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
|
||||
/// </summary>
|
||||
internal static System.Drawing.Icon YouTube {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("YouTube", resourceCulture);
|
||||
return ((System.Drawing.Icon)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -410,4 +410,7 @@ Created folders:</value>
|
|||
<data name="Firebase" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\favicons\firebase.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="YouTube" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\favicons\youtube.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
|
@ -168,6 +168,7 @@
|
|||
<Compile Include="FileUploaders\Transfersh.cs" />
|
||||
<Compile Include="FileUploaders\Uguu.cs" />
|
||||
<Compile Include="FileUploaders\VideoBin.cs" />
|
||||
<Compile Include="FileUploaders\YouTube.cs" />
|
||||
<Compile Include="Forms\OCRSpaceForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -240,6 +241,7 @@
|
|||
<Compile Include="FileUploaders\GfycatUploader.cs" />
|
||||
<Compile Include="Helpers\CustomUploaderArgumentInput.cs" />
|
||||
<Compile Include="Helpers\EscapeHelper.cs" />
|
||||
<Compile Include="Helpers\GoogleOAuth2.cs" />
|
||||
<Compile Include="Helpers\OAuth\IOAuthBase.cs" />
|
||||
<Compile Include="Helpers\SSLBypassHelper.cs" />
|
||||
<Compile Include="BaseServices\URLSharingService.cs" />
|
||||
|
@ -933,6 +935,9 @@
|
|||
<ItemGroup>
|
||||
<None Include="Favicons\Firebase.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Favicons\YouTube.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>cd $(ProjectDir)APIKeys\
|
||||
|
|
|
@ -381,6 +381,13 @@ public class UploadersConfig : SettingsBase<UploadersConfig>
|
|||
|
||||
#endregion Plik
|
||||
|
||||
#region YouTube
|
||||
|
||||
public OAuth2Info YouTubeOAuth2Info = null;
|
||||
public YouTubeVideoPrivacy YouTubePrivacyType = YouTubeVideoPrivacy.Public;
|
||||
|
||||
#endregion YouTube
|
||||
|
||||
#endregion File uploaders
|
||||
|
||||
#region URL shorteners
|
||||
|
|
Loading…
Reference in a new issue