Rewrote the update check.

This commit is contained in:
Robin 2018-06-01 16:53:40 +02:00
commit f57e49d781
20 changed files with 450 additions and 637 deletions

View file

@ -103,6 +103,7 @@ namespace Greenshot.Addons.Core
/// <summary>
/// Supply values we can't put as defaults
/// </summary>
/// <param name="coreConfiguration">ICoreConfiguration</param>
/// <param name="property">The property to return a default for</param>
/// <returns>object with the default value for the supplied property</returns>
public static object GetDefault(this ICoreConfiguration coreConfiguration, string property)

View file

@ -1,235 +0,0 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// 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 1 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, see <http://www.gnu.org/licenses/>.
#endregion
#region Usings
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Xml;
using Dapplo.Log;
#endregion
namespace Greenshot.Addons.Core
{
public class RssFile
{
private readonly DateTime _pubdate;
public RssFile(string file, string pubdate, string link)
{
File = file;
if (!DateTime.TryParse(pubdate, out _pubdate))
{
DateTime.TryParseExact(pubdate.Replace(" UT", ""), "ddd, dd MMM yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out _pubdate);
}
Link = link;
}
public string File { get; }
public DateTime Pubdate => _pubdate;
public string Link { get; }
public Version Version { get; set; }
public string Language { get; set; }
public bool IsExe
{
get
{
if (File != null)
{
return File.ToLower().EndsWith(".exe");
}
return false;
}
}
public bool IsAlpha => File?.ToLowerInvariant().Contains("alpha") == true;
public bool IsBeta => File?.ToLowerInvariant().Contains("beta") == true;
public bool IsReleaseCandidate
{
get
{
if (File != null)
{
return Regex.IsMatch(File.ToLower(), "rc[0-9]+");
}
return false;
}
}
}
/// <summary>
/// Description of RssHelper.
/// </summary>
public class RssHelper
{
private const string Rssfeed = "http://getgreenshot.org/project-feed/";
private static readonly LogSource Log = new LogSource();
/// <summary>
/// This is using the HTTP HEAD Method to check if the RSS Feed is modified after the supplied date
/// </summary>
/// <param name="updateTime">DateTime</param>
/// <returns>true if the feed is newer</returns>
public static bool IsRssModifiedAfter(DateTime updateTime)
{
var lastModified = NetworkHelper.GetLastModified(new Uri(Rssfeed));
if (lastModified == DateTime.MinValue)
{
// Time could not be read, just take now and add one hour to it.
// This assist BUG-1850
lastModified = DateTime.Now.AddHours(1);
}
return updateTime.CompareTo(lastModified) < 0;
}
/// <summary>
/// Read the Greenshot RSS feed, so we can use this information to check for updates
/// </summary>
/// <returns>List with RssFile(s)</returns>
public static IList<RssFile> ReadRss()
{
var rssDoc = new XmlDocument();
try
{
var webRequest = NetworkHelper.CreateWebRequest(Rssfeed);
var rssReader = new XmlTextReader(webRequest.GetResponse().GetResponseStream());
// Load the XML content into a XmlDocument
rssDoc.Load(rssReader);
}
catch (Exception wE)
{
Log.Warn().WriteLine("Problem reading RSS from {0}", Rssfeed);
Log.Warn().WriteLine(wE.Message);
return null;
}
// Loop for the <rss> tag
XmlNode nodeRss = null;
for (var i = 0; i < rssDoc.ChildNodes.Count; i++)
{
// If it is the rss tag
if (rssDoc.ChildNodes[i].Name == "rss")
{
// <rss> tag found
nodeRss = rssDoc.ChildNodes[i];
}
}
if (nodeRss == null)
{
Log.Debug().WriteLine("No RSS Feed!");
return null;
}
// Loop for the <channel> tag
XmlNode nodeChannel = null;
for (var i = 0; i < nodeRss.ChildNodes.Count; i++)
{
// If it is the channel tag
if (nodeRss.ChildNodes[i].Name == "channel")
{
// <channel> tag found
nodeChannel = nodeRss.ChildNodes[i];
}
}
if (nodeChannel == null)
{
Log.Debug().WriteLine("No channel in RSS feed!");
return null;
}
IList<RssFile> rssFiles = new List<RssFile>();
// Loop for the <title>, <link>, <description> and all the other tags
for (var i = 0; i < nodeChannel.ChildNodes.Count; i++)
{
// If it is the item tag, then it has children tags which we will add as items to the ListView
if (nodeChannel.ChildNodes[i].Name != "item")
{
continue;
}
var nodeItem = nodeChannel.ChildNodes[i];
var link = nodeItem["link"]?.InnerText;
var pubdate = nodeItem["pubDate"]?.InnerText;
try
{
if (link == null)
{
continue;
}
var match = Regex.Match(Uri.UnescapeDataString(link), @"^.*\/(Greenshot.+)\/download$");
if (!match.Success)
{
continue;
}
var file = match.Groups[1].Value;
var rssFile = new RssFile(file, pubdate, link);
if (file.EndsWith(".exe") || file.EndsWith(".zip"))
{
var version = Regex.Replace(file, @".*[a-zA-Z_]\-", "");
version = version.Replace(@"\-[a-zA-Z]+.*", "");
version = Regex.Replace(version, @"\.exe$", "");
version = Regex.Replace(version, @"\.zip$", "");
version = Regex.Replace(version, @"RC[0-9]+", "");
if (version.Trim().Length > 0)
{
version = version.Replace('-', '.');
version = version.Replace(',', '.');
version = Regex.Replace(version, @"^[a-zA-Z_]*\.", "");
version = Regex.Replace(version, @"\.[a-zA-Z_]*$", "");
try
{
rssFile.Version = new Version(version);
}
catch (Exception)
{
Log.Debug().WriteLine("Found invalid version {0} in file {1}", version, file);
}
}
rssFiles.Add(rssFile);
}
}
catch (Exception ex)
{
Log.Warn().WriteLine("Couldn't read RSS entry for: {0}", nodeChannel["title"]?.InnerText);
Log.Warn().WriteLine(ex, "Reason: ");
}
}
return rssFiles;
}
}
}

View file

@ -363,7 +363,6 @@
<Compile Include="Core\NetworkHelper.cs" />
<Compile Include="Core\ObjectExtensions.cs" />
<Compile Include="Core\PluginUtils.cs" />
<Compile Include="Core\RssHelper.cs" />
<Compile Include="Core\WindowCapture.cs" />
<Compile Include="Interfaces\ICaptureDetails.cs" />
<Compile Include="Interfaces\Drawing\IDrawableContainer.cs" />

View file

@ -83,6 +83,9 @@
<Reference Include="Dapplo.CaliburnMicro.Translations, Version=1.0.46.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.CaliburnMicro.Translations.1.0.46\lib\net46\Dapplo.CaliburnMicro.Translations.dll</HintPath>
</Reference>
<Reference Include="Dapplo.HttpExtensions, Version=0.8.35.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.HttpExtensions.0.8.35\lib\net46\Dapplo.HttpExtensions.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Ini, Version=0.5.28.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Ini.0.5.28\lib\net45\Dapplo.Ini.dll</HintPath>
</Reference>
@ -173,6 +176,7 @@
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Management" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Numerics" />
<Reference Include="System.Reactive, Version=4.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reactive.4.0.0\lib\net46\System.Reactive.dll</HintPath>
@ -200,6 +204,7 @@
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net46\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.ServiceModel" />
<Reference Include="System.Text.Encoding.CodePages, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Text.Encoding.CodePages.4.5.0\lib\net46\System.Text.Encoding.CodePages.dll</HintPath>
</Reference>
@ -262,11 +267,13 @@
<Compile Include="Murmur3Tests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StitchTests.cs" />
<Compile Include="UpdateTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Greenshot.Addons\Greenshot.Addons.csproj">
<Project>{5b924697-4dcd-4f98-85f1-105cb84b7341}</Project>
<Name>Greenshot.Addons</Name>
</ProjectReference>
<ProjectReference Include="..\Greenshot.Gfx.Experimental\Greenshot.Gfx.Experimental.csproj">
<Project>{14894a45-aa2c-4bc3-85a3-e388d0bdc1ca}</Project>
<Name>Greenshot.Gfx.Experimental</Name>
@ -306,6 +313,12 @@
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
<Analyzer Include="..\packages\xunit.analyzers.0.9.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
</ItemGroup>
<ItemGroup>
<None Include="TestFiles\project-feed.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<SubType>Designer</SubType>
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Greenshot</title>
<link>https://getgreenshot.org</link>
<description>Greenshot update feed</description>
<item>
<title>Greenshot-INSTALLER-1.2.9.129-RELEASE.exe</title>
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.9.129-RELEASE.exe/download</link>
<pubDate>Sat, 28 Jan 2017 15:59:07 +0000</pubDate>
<description></description>
</item>
<item>
<title>Greenshot-INSTALLER-1.2.10.6-RELEASE.exe</title>
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.10.6-RELEASE.exe/download</link>
<pubDate>Wed, 09 Aug 2017 15:35:30 +0000</pubDate>
<description></description>
</item>
<item>
<title>Greenshot-INSTALLER-1.2.9.112-RELEASE.exe</title>
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.9.112-RELEASE.exe/download</link>
<pubDate>Fri, 30 Dec 2016 21:39:18 +0000</pubDate>
<description></description>
</item>
<item>
<title>Greenshot-INSTALLER-1.2.9.104-RELEASE.exe</title>
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.9.104-RELEASE.exe/download</link>
<pubDate>Thu, 15 Dec 2016 19:35:59 +0000</pubDate>
<description></description>
</item>
<item>
<title>Greenshot-INSTALLER-1.3.0.14-BETA.exe</title>
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.3.0.0-BETA.exe/download</link>
<pubDate>Thu, 03 Nov 2016 20:59:15 +0000</pubDate>
<description></description>
</item>
<item>
<title>Greenshot-INSTALLER-1.2.8.12-RELEASE.exe</title>
<link>http://sourceforge/projects/greenshot/files/release/Greenshot/Greenshot-INSTALLER-1.2.8.12-RELEASE.exe/download</link>
<pubDate>Tue, 10 Nov 2015 10:58:37 +0000</pubDate>
<description></description>
</item>
<item>
<title>Greenshot-INSTALLER-1.2.10.6-RELEASE.exe</title>
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.10.6/Greenshot-INSTALLER-1.2.10.6-RELEASE.exe</link>
<pubDate>Wed, 09 Aug 2017 15:35:30 +0000</pubDate>
<description></description>
</item><item>
<title>Greenshot-INSTALLER-1.2.9.129-RELEASE.exe</title>
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.9.129/Greenshot-INSTALLER-1.2.9.129-RELEASE.exe</link>
<pubDate>Sat, 28 Jan 2017 15:59:07 +0000</pubDate>
<description></description>
</item><item>
<title>Greenshot-INSTALLER-1.2.9.112-RELEASE.exe</title>
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.9.112/Greenshot-INSTALLER-1.2.9.112-RELEASE.exe</link>
<pubDate>Fri, 30 Dec 2016 21:39:18 +0000</pubDate>
<description></description>
</item><item>
<title>Greenshot-INSTALLER-1.2.9.104-RELEASE.exe</title>
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.9.104/Greenshot-INSTALLER-1.2.9.104-RELEASE.exe</link>
<pubDate>Thu, 15 Dec 2016 19:35:59 +0000</pubDate>
<description></description>
</item><item>
<title>Greenshot-INSTALLER-1.2.20.99-RC1.exe</title>
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RC1-1.2.20.99/Greenshot-INSTALLER-1.2.20.99-RC1.exe</link>
<pubDate>Thu, 03 Nov 2016 20:59:15 +0000</pubDate>
<description></description>
</item><item>
<title>Greenshot-INSTALLER-1.2.8.12-RELEASE.exe</title>
<link>https://github.com/greenshot/greenshot/releases/download/Greenshot-RELEASE-1.2.8.12/Greenshot-INSTALLER-1.2.8.12-RELEASE.exe</link>
<pubDate>Tue, 10 Nov 2015 10:58:37 +0000</pubDate>
<description></description>
</item>
</channel>
</rss>

View file

@ -0,0 +1,35 @@
using System;
using System.ServiceModel.Syndication;
using System.Threading.Tasks;
using System.Xml;
using Dapplo.HttpExtensions;
using Dapplo.Log;
using Greenshot.Components;
using Xunit;
namespace Greenshot.Tests
{
public class UpdateTests
{
[Fact]
public async Task UpdateTest_GetFeed()
{
var updateFeed = await new Uri("http://getgreenshot.org/project-feed/").GetAsAsync<SyndicationFeed>();
Assert.True(updateFeed.Links.Count >0);
}
[Fact]
public void UpdateTest()
{
var updateService = new UpdateService(null, null);
using (var reader = XmlReader.Create(@"TestFiles\project-feed.xml"))
{
var feed = SyndicationFeed.Load(reader);
updateService.ProcessFeed(feed);
Assert.Equal(new Version("1.2.10.6"), updateService.LatestVersion);
Assert.Equal(new Version("1.3.0.0"), updateService.BetaVersion);
Assert.Equal(new Version("1.2.20.99"), updateService.ReleaseCandidateVersion);
}
}
}
}

View file

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.3.0" newVersion="1.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.FileSystem" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.FileSystem.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Cryptography.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.FileVersionInfo" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.DotNet.PlatformAbstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.CodeAnalysis" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.8.0.0" newVersion="2.8.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.CodeAnalysis.CSharp" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.8.0.0" newVersion="2.8.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="xunit.core" publicKeyToken="8d05b1bb7a6fdb6c" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.3.1.3858" newVersion="2.3.1.3858" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="xunit.execution.desktop" publicKeyToken="8d05b1bb7a6fdb6c" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.3.1.3858" newVersion="2.3.1.3858" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Metadata" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.4.3.0" newVersion="1.4.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="CommonServiceLocator" publicKeyToken="489b6accfaf20ef0" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.3.0" newVersion="2.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reactive.Linq" publicKeyToken="94bc3704cddfc263" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reactive.Core" publicKeyToken="94bc3704cddfc263" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.3000.0" newVersion="3.0.3000.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.8.1.0" newVersion="4.8.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View file

@ -14,6 +14,7 @@
<package id="Dapplo.Addons.Bootstrapper" version="1.0.47" targetFramework="net46" />
<package id="Dapplo.CaliburnMicro" version="1.0.46" targetFramework="net46" />
<package id="Dapplo.CaliburnMicro.Translations" version="1.0.46" targetFramework="net46" />
<package id="Dapplo.HttpExtensions" version="0.8.35" targetFramework="net46" />
<package id="Dapplo.Ini" version="0.5.28" targetFramework="net46" />
<package id="Dapplo.InterfaceImpl" version="0.2.12" targetFramework="net46" />
<package id="Dapplo.Language" version="0.5.28" targetFramework="net46" />

View file

@ -36,7 +36,6 @@ namespace Greenshot.Components
public static void Capture(string parameters)
{
using (var factory = ChannelFactory)
{
var client = factory.CreateChannel();

View file

@ -34,6 +34,7 @@ namespace Greenshot.Components
/// Start the forms initialization before the shell is initialized!
/// </summary>
Forms = CaliburnStartOrder.Shell-1,
User = CaliburnStartOrder.User,
Server = CaliburnStartOrder.User + 100,
Sound = CaliburnStartOrder.User + 200
}

View file

@ -29,7 +29,7 @@ namespace Greenshot.Components
public enum GreenshotUiStartupOrder
{
TrayIcon = 100,
Plugins = 200,
Addons = 200,
Hotkeys = 300
}
}

View file

@ -25,6 +25,7 @@
using System;
using System.Linq;
using System.Windows.Forms;
using Autofac.Features.OwnedInstances;
using Dapplo.Addons;
using Dapplo.CaliburnMicro;
using Dapplo.Log;
@ -45,12 +46,18 @@ namespace Greenshot.Components
private static readonly LogSource Log = new LogSource();
private readonly ICoreConfiguration _coreConfiguration;
private readonly MainForm _mainForm;
private readonly Func<Owned<LanguageDialog>> _languageDialogFactory;
private readonly WindowHandle _windowHandle;
public MainFormStartup(ICoreConfiguration coreConfiguration, MainForm mainForm, WindowHandle windowHandle)
public MainFormStartup(
ICoreConfiguration coreConfiguration,
MainForm mainForm,
Func<Owned<LanguageDialog>> languageDialogFactory,
WindowHandle windowHandle)
{
_coreConfiguration = coreConfiguration;
_mainForm = mainForm;
_languageDialogFactory = languageDialogFactory;
_windowHandle = windowHandle;
}
@ -61,9 +68,11 @@ namespace Greenshot.Components
// if language is not set, show language dialog
if (string.IsNullOrEmpty(_coreConfiguration.Language))
{
var languageDialog = LanguageDialog.GetInstance();
languageDialog.ShowDialog();
_coreConfiguration.Language = languageDialog.SelectedLanguage;
using (var ownedLanguageDialog = _languageDialogFactory())
{
ownedLanguageDialog.Value.ShowDialog();
_coreConfiguration.Language = ownedLanguageDialog.Value.SelectedLanguage;
}
}
// This makes sure the MainForm can initialize, calling show first would create the "Handle" and causing e.g. the DPI Handler to be to late.

View file

@ -0,0 +1,233 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// 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 1 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, see <http://www.gnu.org/licenses/>.
#endregion
#region Usings
using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Dapplo.Addons;
using Dapplo.CaliburnMicro;
using Dapplo.HttpExtensions;
using Dapplo.Log;
using Dapplo.Utils;
using Greenshot.Addons;
using Greenshot.Addons.Core;
using Greenshot.Forms;
#endregion
namespace Greenshot.Components
{
/// <summary>
/// This processes the information, if there are updates available.
/// </summary>
[ServiceOrder(GreenshotStartupOrder.User)]
public class UpdateService : IStartup, IShutdown, IVersionProvider
{
private static readonly LogSource Log = new LogSource();
private static readonly Regex VersionRegex = new Regex(@"^.*[^-]-(?<version>[0-9\.]+)\-(?<type>(release|beta|rc[0-9]+))\.exe.*", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private const string StableDownloadLink = "https://getgreenshot.org/downloads/";
private static readonly Uri UpdateFeed = new Uri("http://getgreenshot.org/project-feed/");
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private readonly ICoreConfiguration _coreConfiguration;
private readonly IGreenshotLanguage _greenshotLanguage;
/// <inheritdoc />
public Version CurrentVersion { get; }
/// <inheritdoc />
public Version LatestVersion { get; private set; }
/// <summary>
/// The latest beta version
/// </summary>
public Version BetaVersion { get; private set; }
/// <summary>
/// The latest RC version
/// </summary>
public Version ReleaseCandidateVersion { get; private set; }
/// <inheritdoc />
public bool IsUpdateAvailable => LatestVersion > CurrentVersion;
/// <summary>
/// Constructor with dependencies
/// </summary>
/// <param name="coreConfiguration">ICoreConfiguration</param>
/// <param name="greenshotLanguage">IGreenshotLanguage</param>
public UpdateService(
ICoreConfiguration coreConfiguration,
IGreenshotLanguage greenshotLanguage)
{
_coreConfiguration = coreConfiguration;
_greenshotLanguage = greenshotLanguage;
LatestVersion = CurrentVersion = GetType().Assembly.GetName().Version;
_coreConfiguration.LastSaveWithVersion = CurrentVersion.ToString();
}
/// <inheritdoc />
public void Start()
{
var ignore = BackgroundTask(() => TimeSpan.FromDays(_coreConfiguration.UpdateCheckInterval), UpdateCheck, _cancellationTokenSource.Token);
}
/// <inheritdoc />
public void Shutdown()
{
_cancellationTokenSource.Cancel();
}
/// <summary>
/// This runs a periodic task in the background
/// </summary>
/// <param name="intervalFactory">Func which returns a TimeSpan</param>
/// <param name="reoccurringTask">Func which returns a task</param>
/// <param name="cancellationToken">CancellationToken</param>
/// <returns>Task</returns>
private async Task BackgroundTask(Func<TimeSpan> intervalFactory, Func<CancellationToken, Task> reoccurringTask, CancellationToken cancellationToken = default)
{
Log.Info().WriteLine("Starting background task");
await Task.Run(async () =>
{
while (true)
{
var interval = intervalFactory();
var task = reoccurringTask;
if (TimeSpan.Zero == interval)
{
interval = TimeSpan.FromMinutes(10);
task = c => Task.FromResult(true);
}
try
{
await Task.WhenAll(Task.Delay(interval, cancellationToken), task(cancellationToken));
}
catch (Exception ex)
{
Log.Error().WriteLine(ex, "Error occured when trying to check for updates.");
}
if (cancellationToken.IsCancellationRequested)
{
break;
}
}
}, cancellationToken);
Log.Info().WriteLine("Finished background task");
}
private async Task UpdateCheck(CancellationToken cancellationToken = default)
{
Log.Info().WriteLine("Checking for updates");
var updateFeed = await UpdateFeed.GetAsAsync<SyndicationFeed>(cancellationToken);
if (updateFeed == null)
{
return;
}
_coreConfiguration.LastUpdateCheck = DateTime.Now;
ProcessFeed(updateFeed);
if (IsUpdateAvailable)
{
await UiContext.RunOn(() =>
{
// TODO: Show update
MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", string.Format(_greenshotLanguage.UpdateFound, LatestVersion), ToolTipIcon.Info);
}, cancellationToken);
}
}
/// <summary>
/// Process the update feed to get the latest version
/// </summary>
/// <param name="updateFeed"></param>
public void ProcessFeed(SyndicationFeed updateFeed)
{
var versions =
from link in updateFeed.Items.SelectMany(i => i.Links)
select VersionRegex.Match(link.Uri.AbsoluteUri) into match
where match.Success
group match by Regex.Replace(match.Groups["type"].Value, @"[\d-]", string.Empty) into groupedVersions
select groupedVersions.OrderByDescending(m => new Version(m.Groups["version"].Value)).First();
foreach (var versionMatch in versions)
{
var version = new Version(versionMatch.Groups["version"].Value);
var type = versionMatch.Groups["type"].Value;
if (string.IsNullOrEmpty(type))
{
continue;
}
Log.Debug().WriteLine("Got {0} {1}", type, version);
if ("release".Equals(type, StringComparison.OrdinalIgnoreCase))
{
LatestVersion = version;
}
if ("beta".Equals(type, StringComparison.OrdinalIgnoreCase))
{
BetaVersion = version;
}
if ("rc".Equals(type, StringComparison.OrdinalIgnoreCase))
{
ReleaseCandidateVersion = version;
}
}
}
private void CleanupBalloonTipClick(object sender, EventArgs e)
{
MainForm.Instance.NotifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
}
private void HandleBalloonTipClick(object sender, EventArgs e)
{
try
{
// "Direct" download link
// Process.Start(latestGreenshot.Link);
// Go to getgreenshot.org
Process.Start(StableDownloadLink);
}
catch (Exception)
{
MessageBox.Show(string.Format(_greenshotLanguage.ErrorOpenlink, StableDownloadLink), _greenshotLanguage.Error);
}
finally
{
CleanupBalloonTipClick(sender, e);
}
}
}
}

View file

@ -28,11 +28,11 @@ using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using Autofac.Features.OwnedInstances;
using Greenshot.Addons;
using Greenshot.Addons.Components;
using Greenshot.Addons.Core;
using Greenshot.Addons.Interfaces;
using Greenshot.Configuration;
using Greenshot.Helpers;
#endregion
@ -46,19 +46,23 @@ namespace Greenshot.Destinations
public class PrinterDestination : AbstractDestination
{
private readonly IGreenshotLanguage _greenshotLanguage;
private readonly Func<ISurface, ICaptureDetails, Owned<PrintHelper>> _printHelperFactory;
private readonly string _printerName;
public PrinterDestination(ICoreConfiguration coreConfiguration,
IGreenshotLanguage greenshotLanguage
): base(coreConfiguration, greenshotLanguage)
IGreenshotLanguage greenshotLanguage,
Func<ISurface, ICaptureDetails, Owned<PrintHelper>> printHelperFactory
) : base(coreConfiguration, greenshotLanguage)
{
_greenshotLanguage = greenshotLanguage;
_printHelperFactory = printHelperFactory;
}
protected PrinterDestination(
ICoreConfiguration coreConfiguration,
IGreenshotLanguage greenshotLanguage,
string printerName) : this(coreConfiguration, greenshotLanguage)
Func<ISurface, ICaptureDetails, Owned<PrintHelper>> printHelperFactory,
string printerName) : this(coreConfiguration, greenshotLanguage, printHelperFactory)
{
_printerName = printerName;
}
@ -110,7 +114,7 @@ namespace Greenshot.Destinations
});
foreach (var printer in printers)
{
yield return new PrinterDestination(CoreConfiguration, GreenshotLanguage, printer);
yield return new PrinterDestination(CoreConfiguration, GreenshotLanguage, _printHelperFactory, printer);
}
}
@ -127,25 +131,26 @@ namespace Greenshot.Destinations
PrinterSettings printerSettings;
if (!string.IsNullOrEmpty(_printerName))
{
using (var printHelper = new PrintHelper(CoreConfiguration, GreenshotLanguage,surface, captureDetails))
using (var ownedPrintHelper = _printHelperFactory(surface, captureDetails))
{
printerSettings = printHelper.PrintTo(_printerName);
printerSettings = ownedPrintHelper.Value.PrintTo(_printerName);
}
}
else if (!manuallyInitiated)
{
var settings = new PrinterSettings();
using (var printHelper = new PrintHelper(CoreConfiguration, GreenshotLanguage, surface, captureDetails))
{
printerSettings = printHelper.PrintTo(settings.PrinterName);
}
using (var ownedPrintHelper = _printHelperFactory(surface, captureDetails))
{
printerSettings = ownedPrintHelper.Value.PrintTo(settings.PrinterName);
}
}
else
{
using (var printHelper = new PrintHelper(CoreConfiguration, GreenshotLanguage, surface, captureDetails))
{
printerSettings = printHelper.PrintWithDialog();
}
using (var ownedPrintHelper = _printHelperFactory(surface, captureDetails))
{
printerSettings = ownedPrintHelper.Value.PrintWithDialog();
}
}
if (printerSettings != null)
{

View file

@ -41,7 +41,6 @@ namespace Greenshot.Forms
public partial class LanguageDialog : Form
{
private static readonly LogSource Log = new LogSource();
private static LanguageDialog _uniqueInstance;
private bool _properOkPressed;
private LanguageDialog()
@ -108,10 +107,5 @@ namespace Greenshot.Forms
Language.CurrentLanguage = SelectedLanguage;
Close();
}
public static LanguageDialog GetInstance()
{
return _uniqueInstance ?? (_uniqueInstance = new LanguageDialog());
}
}
}

View file

@ -74,11 +74,11 @@ namespace Greenshot.Forms
private static readonly LogSource Log = new LogSource();
private readonly ICoreConfiguration _coreConfiguration;
private readonly IWindowManager _windowManager;
private readonly ConfigViewModel _configViewModel;
private readonly Func<Owned<ConfigViewModel>> _configViewModelFactory;
private readonly Func<Owned<AboutForm>> _aboutFormFactory;
// Timer for the double click test
private readonly Timer _doubleClickTimer = new Timer();
private readonly Func<Owned<AboutForm>> _aboutFormFactory;
private readonly DestinationHolder _destinationHolder;
// Thumbnail preview
@ -89,13 +89,13 @@ namespace Greenshot.Forms
public MainForm(ICoreConfiguration coreConfiguration,
IWindowManager windowManager,
IGreenshotLanguage greenshotLanguage,
ConfigViewModel configViewModel,
Func<Owned<ConfigViewModel>> configViewModelFactory,
Func<Owned<AboutForm>> aboutFormFactory,
DestinationHolder destinationHolder) : base(greenshotLanguage)
{
_coreConfiguration = coreConfiguration;
_windowManager = windowManager;
_configViewModel = configViewModel;
_configViewModelFactory = configViewModelFactory;
_aboutFormFactory = aboutFormFactory;
_destinationHolder = destinationHolder;
Instance = this;
@ -365,17 +365,7 @@ namespace Greenshot.Forms
{
PsApi.EmptyWorkingSet();
}
if (UpdateHelper.IsUpdateCheckNeeded())
{
Log.Debug().WriteLine("BackgroundWorkerTimerTick checking for update");
// Start update check in the background
var backgroundTask = new Thread(UpdateHelper.CheckAndAskForUpdate)
{
Name = "Update check",
IsBackground = true
};
backgroundTask.Start();
}
}
@ -841,10 +831,9 @@ namespace Greenshot.Forms
/// </summary>
public void ShowSetting()
{
// The new MVVM Configuration
if (!_configViewModel.IsActive)
using(var ownedConfigViewModel = _configViewModelFactory())
{
_windowManager.ShowDialog(_configViewModel);
_windowManager.ShowDialog(ownedConfigViewModel.Value);
}
InitializeQuickSettingsMenu();
}

View file

@ -289,7 +289,7 @@
<Compile Include="Help\HelpFileLoader.cs" />
<Compile Include="Processors\TitleFixProcessor.cs" />
<Compile Include="Helpers\WindowWrapper.cs" />
<Compile Include="Helpers\UpdateHelper.cs" />
<Compile Include="Components\UpdateService.cs" />
<Compile Include="Helpers\EnvironmentInfo.cs" />
<Compile Include="Helpers\MailHelper.cs" />
<Compile Include="Helpers\PrintHelper.cs" />

View file

@ -29,6 +29,7 @@ using Dapplo.CaliburnMicro.Security;
using Greenshot.Addons.Components;
using Greenshot.Components;
using Greenshot.Forms;
using Greenshot.Helpers;
using Greenshot.Ui.Configuration.ViewModels;
using Greenshot.Ui.Misc.ViewModels;
@ -41,8 +42,8 @@ namespace Greenshot
{
builder
.RegisterType<ConfigViewModel>()
.AsSelf()
.SingleInstance();
.AsSelf();
builder
.RegisterType<AuthenticationProvider>()
.As<IAuthenticationProvider>()
@ -53,6 +54,18 @@ namespace Greenshot
.AsSelf()
.SingleInstance();
builder
.RegisterType<PrintHelper>()
.AsSelf();
builder
.RegisterType<PrintOptionsDialog>()
.AsSelf();
builder
.RegisterType<LanguageDialog>()
.AsSelf();
builder
.RegisterType<HotkeyHandler>()
.As<IUiStartup>()

View file

@ -27,6 +27,7 @@ using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using Autofac.Features.OwnedInstances;
using Greenshot.Forms;
using Dapplo.Log;
using Dapplo.Windows.Common.Extensions;
@ -52,6 +53,7 @@ namespace Greenshot.Helpers
private static readonly LogSource Log = new LogSource();
private readonly ICoreConfiguration _coreConfig;
private readonly IGreenshotLanguage _greenshotLanguage;
private readonly Func<Owned<PrintOptionsDialog>> _printOptionsDialogFactory;
private readonly ICaptureDetails _captureDetails;
private PrintDialog _printDialog = new PrintDialog();
private PrintDocument _printDocument = new PrintDocument();
@ -61,11 +63,13 @@ namespace Greenshot.Helpers
public PrintHelper(
ICoreConfiguration coreConfiguration,
IGreenshotLanguage greenshotLanguage,
Func<Owned<PrintOptionsDialog>> printOptionsDialogFactory,
ISurface surface,
ICaptureDetails captureDetails)
{
_coreConfig = coreConfiguration;
_greenshotLanguage = greenshotLanguage;
_printOptionsDialogFactory = printOptionsDialogFactory;
_surface = surface;
_captureDetails = captureDetails;
@ -83,16 +87,6 @@ namespace Greenshot.Helpers
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/**
* Destructor
*/
~PrintHelper()
{
Dispose(false);
}
/**
@ -149,29 +143,30 @@ namespace Greenshot.Helpers
/// <returns>printer settings if actually printed, or null if print was cancelled or has failed</returns>
public PrinterSettings PrintWithDialog()
{
PrinterSettings returnPrinterSettings = null;
if (_printDialog.ShowDialog() == DialogResult.OK)
{
var printOptionsResult = ShowPrintOptionsDialog();
try
{
if (printOptionsResult == null || printOptionsResult == DialogResult.OK)
{
if (!IsColorPrint())
{
_printDocument.DefaultPageSettings.Color = false;
}
_printDocument.Print();
returnPrinterSettings = _printDialog.PrinterSettings;
}
}
catch (Exception e)
{
Log.Error().WriteLine(e, "An error ocurred while trying to print");
MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error));
}
}
return returnPrinterSettings;
if (_printDialog.ShowDialog() != DialogResult.OK)
{
return null;
}
PrinterSettings returnPrinterSettings = null;
var printOptionsResult = ShowPrintOptionsDialog();
try
{
if (printOptionsResult == null || printOptionsResult == DialogResult.OK)
{
if (!IsColorPrint())
{
_printDocument.DefaultPageSettings.Color = false;
}
_printDocument.Print();
returnPrinterSettings = _printDialog.PrinterSettings;
}
}
catch (Exception e)
{
Log.Error().WriteLine(e, "An error ocurred while trying to print");
MessageBox.Show(Language.GetString(LangKey.print_error), Language.GetString(LangKey.error));
}
return returnPrinterSettings;
}
private bool IsColorPrint()
@ -190,9 +185,9 @@ namespace Greenshot.Helpers
return null;
}
using (var printOptionsDialog = new PrintOptionsDialog(_coreConfig, _greenshotLanguage))
using (var ownedPrintOptionsDialog = _printOptionsDialogFactory())
{
return printOptionsDialog.ShowDialog();
return ownedPrintOptionsDialog.Value.ShowDialog();
}
}

View file

@ -1,223 +0,0 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// 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 1 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, see <http://www.gnu.org/licenses/>.
#endregion
#region Usings
using System;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;
using Dapplo.Ini;
using Dapplo.Log;
using Greenshot.Addons.Core;
using Greenshot.Addons.Core.Enums;
using Greenshot.Configuration;
using Greenshot.Forms;
#endregion
namespace Greenshot.Helpers
{
/// <summary>
/// Description of RssFeedHelper.
/// </summary>
public static class UpdateHelper
{
private const string StableDownloadLink = "https://getgreenshot.org/downloads/";
private const string VersionHistoryLink = "https://getgreenshot.org/version-history/";
private static readonly LogSource Log = new LogSource();
private static readonly ICoreConfiguration CoreConfig = IniConfig.Current.Get<ICoreConfiguration>();
private static readonly object LockObject = new object();
private static RssFile _latestGreenshot;
private static string _downloadLink = StableDownloadLink;
/// <summary>
/// Is an update check needed?
/// </summary>
/// <returns>bool true if yes</returns>
public static bool IsUpdateCheckNeeded()
{
lock (LockObject)
{
if (CoreConfig.UpdateCheckInterval == 0)
{
return false;
}
var checkTime = CoreConfig.LastUpdateCheck;
checkTime = checkTime.AddDays(CoreConfig.UpdateCheckInterval);
if (DateTime.Now.CompareTo(checkTime) < 0)
{
Log.Debug().WriteLine("No need to check RSS feed for updates, feed check will be after {0}", checkTime);
return false;
}
Log.Debug().WriteLine("Update check is due, last check was {0} check needs to be made after {1} (which is one {2} later)", CoreConfig.LastUpdateCheck, checkTime,
CoreConfig.UpdateCheckInterval);
if (!RssHelper.IsRssModifiedAfter(CoreConfig.LastUpdateCheck))
{
Log.Debug().WriteLine("RSS feed has not been updated since after {0}", CoreConfig.LastUpdateCheck);
return false;
}
}
return true;
}
/// <summary>
/// Read the RSS feed to see if there is a Greenshot update
/// </summary>
public static void CheckAndAskForUpdate()
{
lock (LockObject)
{
var currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
// Test like this:
// currentVersion = new Version("0.8.1.1198");
try
{
_latestGreenshot = null;
ProcessRssInfo(currentVersion);
if (_latestGreenshot != null)
{
MainForm.Instance.NotifyIcon.BalloonTipClicked += HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed += CleanupBalloonTipClick;
MainForm.Instance.NotifyIcon.ShowBalloonTip(10000, "Greenshot", Language.GetFormattedString(LangKey.update_found, "'" + _latestGreenshot.File + "'"),
ToolTipIcon.Info);
}
CoreConfig.LastUpdateCheck = DateTime.Now;
}
catch (Exception e)
{
Log.Error().WriteLine(e, "An error occured while checking for updates, the error will be ignored: ");
}
}
}
private static void CleanupBalloonTipClick(object sender, EventArgs e)
{
MainForm.Instance.NotifyIcon.BalloonTipClicked -= HandleBalloonTipClick;
MainForm.Instance.NotifyIcon.BalloonTipClosed -= CleanupBalloonTipClick;
}
private static void HandleBalloonTipClick(object sender, EventArgs e)
{
try
{
if (_latestGreenshot != null)
{
// "Direct" download link
// Process.Start(latestGreenshot.Link);
// Go to getgreenshot.org
Process.Start(_downloadLink);
}
}
catch (Exception)
{
MessageBox.Show(Language.GetFormattedString(LangKey.error_openlink, _downloadLink), Language.GetString(LangKey.error));
}
finally
{
CleanupBalloonTipClick(sender, e);
}
}
private static void ProcessRssInfo(Version currentVersion)
{
// Reset latest Greenshot
var rssFiles = RssHelper.ReadRss();
if (rssFiles == null)
{
return;
}
// Retrieve the current and latest greenshot
foreach (var rssFile in rssFiles)
{
if (rssFile.File.StartsWith("Greenshot"))
{
// check for exe
if (!rssFile.IsExe)
{
continue;
}
// do we have a version?
if (rssFile.Version == null)
{
Log.Debug().WriteLine("Skipping unversioned exe {0} which is published at {1} : {2}", rssFile.File, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
continue;
}
// if the file is unstable, we will skip it when:
// the current version is a release or release candidate AND check unstable is turned off.
if (rssFile.IsAlpha)
{
// Skip if we shouldn't check unstables
if (CoreConfigurationExtensions.BuildState == BuildStates.RELEASE && !CoreConfig.CheckForUnstable)
{
continue;
}
}
// if the file is a release candidate, we will skip it when:
// the current version is a release AND check unstable is turned off.
if (rssFile.IsReleaseCandidate)
{
if (CoreConfigurationExtensions.BuildState == BuildStates.RELEASE && !CoreConfig.CheckForUnstable)
{
continue;
}
}
// Compare versions
var versionCompare = rssFile.Version.CompareTo(currentVersion);
if (versionCompare > 0)
{
Log.Debug().WriteLine("Found newer Greenshot '{0}' with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(), rssFile.Link);
if (_latestGreenshot == null || rssFile.Version.CompareTo(_latestGreenshot.Version) > 0)
{
_latestGreenshot = rssFile;
if (rssFile.IsReleaseCandidate || rssFile.IsAlpha)
{
_downloadLink = VersionHistoryLink;
}
else
{
_downloadLink = StableDownloadLink;
}
}
}
else if (versionCompare < 0)
{
Log.Debug().WriteLine("Skipping older greenshot with version {0}", rssFile.Version);
}
else if (versionCompare == 0)
{
Log.Debug().WriteLine("Found current version as exe {0} with version {1} published at {2} : {3}", rssFile.File, rssFile.Version, rssFile.Pubdate.ToLocalTime(),
rssFile.Link);
}
}
}
}
}
}