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).

This commit is contained in:
Robin 2016-11-16 09:09:28 +01:00
commit ede5bfef97
8 changed files with 85 additions and 52 deletions

View file

@ -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

View file

@ -29,22 +29,37 @@ using Greenshot.IniFile;
namespace GreenshotImgurPlugin {
/// <summary>
/// Description of ImgurHistory.
/// Imgur history form
/// </summary>
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<ImgurConfiguration>();
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() {

View file

@ -25,7 +25,7 @@ namespace GreenshotImgurPlugin {
/// Description of PasswordRequestForm.
/// </summary>
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) {

View file

@ -22,6 +22,10 @@
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<ItemGroup>
<Reference Include="LinqBridge, Version=1.3.0.0, Culture=neutral, PublicKeyToken=c2b14eb747628076, processorArchitecture=MSIL">
<HintPath>..\packages\LinqBridge.1.3.0\lib\net20\LinqBridge.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="log4net">
<HintPath>..\Greenshot\Lib\log4net.dll</HintPath>
</Reference>
@ -70,6 +74,7 @@
<EmbeddedResource Include="ImgurPlugin.resx">
<DependentUpon>ImgurPlugin.cs</DependentUpon>
</EmbeddedResource>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj">

View file

@ -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 {
/// </summary>
/// <returns>bool true if OK was pressed, false if cancel</returns>
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;
}
}
}

View file

@ -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 {
/// <param name="pluginHost">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="myAttributes">My own attributes</param>
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
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();
}
}
);

View file

@ -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 {
/// <summary>
/// Description of ImgurUtils.
/// A collection of Imgur helper methods
/// </summary>
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";
/// <summary>
/// Check if we need to load the history
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// Load the complete history of the imgur uploads, with the corresponding information
/// </summary>
public static void LoadHistory() {
if (Config.runtimeImgurHistory.Count == Config.ImgurUploadHistory.Count) {
if (!IsHistoryLoadingNeeded())
{
return;
}
// Load the ImUr history
IList<string> hashes = new List<string>();
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;
}
}

View file

@ -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);