From ede5bfef97e2b7b0dcf41bb755671a18ef65a8ce Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 16 Nov 2016 09:09:28 +0100 Subject: [PATCH] BUG-1894: Postponing history loading as long as possible, this reduces the Imgur activity dramatically (as it's not loaded during start) and should at least prevent a 429 early on... hopefully. It would be better to cache everything locally on the user's PC, but this is unrealistic with .NET 2.0 technology (not impossible, but so time consuming that it would be better to wait for the next Greenshot version with 4.5). --- .../additional_files/readme.txt.template | 2 +- GreenshotImgurPlugin/Forms/ImgurHistory.cs | 29 ++++++++--- GreenshotImgurPlugin/Forms/SettingsForm.cs | 6 +-- .../GreenshotImgurPlugin.csproj | 5 ++ GreenshotImgurPlugin/ImgurConfiguration.cs | 14 +----- GreenshotImgurPlugin/ImgurPlugin.cs | 18 ++----- GreenshotImgurPlugin/ImgurUtils.cs | 49 +++++++++++++------ GreenshotPlugin/IniFile/IniValue.cs | 14 ++++++ 8 files changed, 85 insertions(+), 52 deletions(-) diff --git a/Greenshot/releases/additional_files/readme.txt.template b/Greenshot/releases/additional_files/readme.txt.template index cbc4bce74..6f55b4038 100644 --- a/Greenshot/releases/additional_files/readme.txt.template +++ b/Greenshot/releases/additional_files/readme.txt.template @@ -46,7 +46,7 @@ Added features: * FEATURE-946 Updated to Inno-Setup 5.5.9 for improved installer security * FEATURE-958 Greenshot is now using code signing certificates -Added translation: +Added or changed translation: * CatalĂ  by Gabriel Guix. * Nederlands by Stephan Paternotte diff --git a/GreenshotImgurPlugin/Forms/ImgurHistory.cs b/GreenshotImgurPlugin/Forms/ImgurHistory.cs index 4d67ab528..517bb165f 100644 --- a/GreenshotImgurPlugin/Forms/ImgurHistory.cs +++ b/GreenshotImgurPlugin/Forms/ImgurHistory.cs @@ -29,22 +29,37 @@ using Greenshot.IniFile; namespace GreenshotImgurPlugin { /// - /// Description of ImgurHistory. + /// Imgur history form /// public sealed partial class ImgurHistory : ImgurForm { private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurHistory)); private readonly GreenshotColumnSorter _columnSorter; + private static readonly object Lock = new object(); private static readonly ImgurConfiguration Config = IniConfig.GetIniSection(); private static ImgurHistory _instance; public static void ShowHistory() { - // Make sure the history is loaded, will be done only once - ImgurUtils.LoadHistory(); - if (_instance == null) { - _instance = new ImgurHistory(); + lock (Lock) + { + if (ImgurUtils.IsHistoryLoadingNeeded()) + { + // Run upload in the background + new PleaseWaitForm().ShowAndWait("Imgur " + Language.GetString("imgur", LangKey.history), Language.GetString("imgur", LangKey.communication_wait), + ImgurUtils.LoadHistory + ); + } + + // Make sure the history is loaded, will be done only once + if (_instance == null) + { + _instance = new ImgurHistory(); + } + if (!_instance.Visible) + { + _instance.Show(); + } + _instance.Redraw(); } - _instance.Show(); - _instance.Redraw(); } private ImgurHistory() { diff --git a/GreenshotImgurPlugin/Forms/SettingsForm.cs b/GreenshotImgurPlugin/Forms/SettingsForm.cs index e7afda70c..f68a50794 100644 --- a/GreenshotImgurPlugin/Forms/SettingsForm.cs +++ b/GreenshotImgurPlugin/Forms/SettingsForm.cs @@ -25,7 +25,7 @@ namespace GreenshotImgurPlugin { /// Description of PasswordRequestForm. /// public partial class SettingsForm : ImgurForm { - public SettingsForm(ImgurConfiguration config) + public SettingsForm() { // // The InitializeComponent() call is required for Windows Forms designer support. @@ -34,9 +34,7 @@ namespace GreenshotImgurPlugin { CancelButton = buttonCancel; AcceptButton = buttonOK; - ImgurUtils.LoadHistory(); - - historyButton.Enabled = config.runtimeImgurHistory.Count > 0; + historyButton.Enabled = ImgurUtils.IsHistoryLoadingNeeded(); } private void ButtonHistoryClick(object sender, EventArgs e) { diff --git a/GreenshotImgurPlugin/GreenshotImgurPlugin.csproj b/GreenshotImgurPlugin/GreenshotImgurPlugin.csproj index 16a2690f1..6e4f81932 100644 --- a/GreenshotImgurPlugin/GreenshotImgurPlugin.csproj +++ b/GreenshotImgurPlugin/GreenshotImgurPlugin.csproj @@ -22,6 +22,10 @@ + + ..\packages\LinqBridge.1.3.0\lib\net20\LinqBridge.dll + True + ..\Greenshot\Lib\log4net.dll @@ -70,6 +74,7 @@ ImgurPlugin.cs + diff --git a/GreenshotImgurPlugin/ImgurConfiguration.cs b/GreenshotImgurPlugin/ImgurConfiguration.cs index 2889c9501..a65c3e7b2 100644 --- a/GreenshotImgurPlugin/ImgurConfiguration.cs +++ b/GreenshotImgurPlugin/ImgurConfiguration.cs @@ -23,7 +23,6 @@ using System; using System.Collections.Generic; using System.Windows.Forms; using Greenshot.IniFile; -using GreenshotPlugin.Controls; using GreenshotPlugin.Core; namespace GreenshotImgurPlugin { @@ -95,18 +94,9 @@ namespace GreenshotImgurPlugin { /// /// bool true if OK was pressed, false if cancel public bool ShowConfigDialog() { - SettingsForm settingsForm = null; - - new PleaseWaitForm().ShowAndWait(ImgurPlugin.Attributes.Name, Language.GetString("imgur", LangKey.communication_wait), - delegate { - settingsForm = new SettingsForm(this); - } - ); + SettingsForm settingsForm = new SettingsForm(); DialogResult result = settingsForm.ShowDialog(); - if (result == DialogResult.OK) { - return true; - } - return false; + return result == DialogResult.OK; } } } diff --git a/GreenshotImgurPlugin/ImgurPlugin.cs b/GreenshotImgurPlugin/ImgurPlugin.cs index 93b8ede40..ec1d41b9e 100644 --- a/GreenshotImgurPlugin/ImgurPlugin.cs +++ b/GreenshotImgurPlugin/ImgurPlugin.cs @@ -23,7 +23,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.IO; -using System.Threading; using System.Windows.Forms; using Greenshot.IniFile; using Greenshot.Plugin; @@ -75,7 +74,7 @@ namespace GreenshotImgurPlugin { /// Use the IGreenshotPluginHost interface to register events /// My own attributes /// true if plugin is initialized, false if not (doesn't show) - public virtual bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) { + public bool Initialize(IGreenshotHost pluginHost, PluginAttribute myAttributes) { _host = pluginHost; Attributes = myAttributes; @@ -109,14 +108,8 @@ namespace GreenshotImgurPlugin { PluginUtils.AddToContextMenu(_host, itemPlugInRoot); Language.LanguageChanged += OnLanguageChanged; - // retrieve history in the background - Thread backgroundTask = new Thread(CheckHistory) - { - Name = "Imgur History", - IsBackground = true - }; - backgroundTask.SetApartmentState(ApartmentState.STA); - backgroundTask.Start(); + // Enable history if there are items available + UpdateHistoryMenuItem(); return true; } @@ -129,9 +122,8 @@ namespace GreenshotImgurPlugin { } } - private void CheckHistory() { + private void UpdateHistoryMenuItem() { try { - ImgurUtils.LoadHistory(); _host.GreenshotForm.BeginInvoke((MethodInvoker)delegate { if (_config.ImgurUploadHistory.Count > 0) { _historyMenuItem.Enabled = true; @@ -178,7 +170,7 @@ namespace GreenshotImgurPlugin { Log.InfoFormat("Storing imgur upload for hash {0} and delete hash {1}", imgurInfo.Hash, imgurInfo.DeleteHash); _config.ImgurUploadHistory.Add(imgurInfo.Hash, imgurInfo.DeleteHash); _config.runtimeImgurHistory.Add(imgurInfo.Hash, imgurInfo); - CheckHistory(); + UpdateHistoryMenuItem(); } } ); diff --git a/GreenshotImgurPlugin/ImgurUtils.cs b/GreenshotImgurPlugin/ImgurUtils.cs index aee304ec3..95bbfc806 100644 --- a/GreenshotImgurPlugin/ImgurUtils.cs +++ b/GreenshotImgurPlugin/ImgurUtils.cs @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Linq; using System.Net; using Greenshot.IniFile; using Greenshot.Plugin; @@ -29,7 +30,7 @@ using GreenshotPlugin.Core; namespace GreenshotImgurPlugin { /// - /// Description of ImgurUtils. + /// A collection of Imgur helper methods /// public static class ImgurUtils { private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurUtils)); @@ -38,44 +39,62 @@ namespace GreenshotImgurPlugin { private const string AuthUrlPattern = "https://api.imgur.com/oauth2/authorize?response_type=code&client_id={ClientId}&redirect_uri={RedirectUrl}&state={State}"; private const string TokenUrl = "https://api.imgur.com/oauth2/token"; + /// + /// Check if we need to load the history + /// + /// + public static bool IsHistoryLoadingNeeded() + { + Log.InfoFormat("Checking if imgur cache loading needed, configuration has {0} imgur hashes, loaded are {1} hashes.", Config.ImgurUploadHistory.Count, Config.runtimeImgurHistory.Count); + return Config.runtimeImgurHistory.Count != Config.ImgurUploadHistory.Count; + } + /// /// Load the complete history of the imgur uploads, with the corresponding information /// public static void LoadHistory() { - if (Config.runtimeImgurHistory.Count == Config.ImgurUploadHistory.Count) { + if (!IsHistoryLoadingNeeded()) + { return; } - // Load the ImUr history - IList hashes = new List(); - foreach(string hash in Config.ImgurUploadHistory.Keys) { - hashes.Add(hash); - } - + bool saveNeeded = false; - foreach(string hash in hashes) { + // Load the ImUr history + foreach (string hash in Config.ImgurUploadHistory.Keys.ToList()) { if (Config.runtimeImgurHistory.ContainsKey(hash)) { // Already loaded continue; } - try { - ImgurInfo imgurInfo = RetrieveImgurInfo(hash, Config.ImgurUploadHistory[hash]); + + try + { + var deleteHash = Config.ImgurUploadHistory[hash]; + ImgurInfo imgurInfo = RetrieveImgurInfo(hash, deleteHash); if (imgurInfo != null) { RetrieveImgurThumbnail(imgurInfo); Config.runtimeImgurHistory[hash] = imgurInfo; } else { - Log.DebugFormat("Deleting not found ImgUr {0} from config.", hash); + Log.InfoFormat("Deleting unknown ImgUr {0} from config, delete hash was {1}.", hash, deleteHash); Config.ImgurUploadHistory.Remove(hash); + Config.runtimeImgurHistory.Remove(hash); saveNeeded = true; } } catch (WebException wE) { bool redirected = false; if (wE.Status == WebExceptionStatus.ProtocolError) { - HttpWebResponse response = ((HttpWebResponse)wE.Response); - // Image no longer available + HttpWebResponse response = (HttpWebResponse)wE.Response; + + if (response.StatusCode == HttpStatusCode.Forbidden) + { + Log.Error("Imgur loading forbidden", wE); + break; + } + // Image no longer available? if (response.StatusCode == HttpStatusCode.Redirect) { - Log.InfoFormat("ImgUr image for hash {0} is no longer available", hash); + Log.InfoFormat("ImgUr image for hash {0} is no longer available, removing it from the history", hash); Config.ImgurUploadHistory.Remove(hash); + Config.runtimeImgurHistory.Remove(hash); redirected = true; } } diff --git a/GreenshotPlugin/IniFile/IniValue.cs b/GreenshotPlugin/IniFile/IniValue.cs index b01e87f19..2ad6c356b 100644 --- a/GreenshotPlugin/IniFile/IniValue.cs +++ b/GreenshotPlugin/IniFile/IniValue.cs @@ -353,6 +353,20 @@ namespace Greenshot.IniFile { return null; } + // The following makes the enum string values a bit less restrictive + if (valueType.IsEnum) + { + string searchingEnumString = valueString.Replace("_", "").ToLowerInvariant(); + foreach (var possibleValue in Enum.GetValues(valueType)) + { + var possibleString = possibleValue.ToString().Replace("_", "").ToLowerInvariant(); + if (possibleString.Equals(searchingEnumString)) + { + return possibleValue; + } + } + } + if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(List<>)) { string arraySeparator = separator; object list = Activator.CreateInstance(valueType);