Skip to content

Commit

Permalink
Search results grid context menu for multiple selected items
Browse files Browse the repository at this point in the history
  • Loading branch information
libgenapps committed May 30, 2019
1 parent fdabef4 commit a61f564
Show file tree
Hide file tree
Showing 40 changed files with 397 additions and 202 deletions.
4 changes: 2 additions & 2 deletions LibgenDesktop.Setup/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
{
internal static class Constants
{
public const string CURRENT_VERSION = "1.3.0";
public const string TITLE_VERSION = "1.3.0";
public const string CURRENT_VERSION = "1.3.1";
public const string TITLE_VERSION = "1.3.1";
public const string PRODUCT_TITLE_FORMAT = "Libgen Desktop " + TITLE_VERSION + " ({0}-bit)";
public const string SHORTCUT_TITLE_FORMAT = "Libgen Desktop ({0}-bit)";
public const string PRODUCT_COMPANY = "Libgen Apps";
Expand Down
7 changes: 4 additions & 3 deletions LibgenDesktop/Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ namespace LibgenDesktop.Common
internal static class Constants
{
public const string DATABASE_METADATA_APP_NAME = "LibgenDesktop";
public const string CURRENT_VERSION = "1.3.0";
public const string CURRENT_GITHUB_RELEASE_NAME = "1.3.0";
public static readonly DateTime CURRENT_GITHUB_RELEASE_DATE = new DateTime(2019, 5, 22);
public const string CURRENT_VERSION = "1.3.1";
public const string CURRENT_GITHUB_RELEASE_NAME = "1.3.1";
public static readonly DateTime CURRENT_GITHUB_RELEASE_DATE = new DateTime(2019, 5, 30);
public const string CURRENT_DATABASE_VERSION = "1.2.1";

public const string APP_SETTINGS_FILE_NAME = "libgen.config";
Expand Down Expand Up @@ -119,6 +119,7 @@ internal static class Constants
public const double SYNCHRONIZATION_PROGRESS_UPDATE_INTERVAL = 0.1;
public const int DATABASE_TRANSACTION_BATCH = 500;
public const int MAX_EXPORT_ROWS_PER_FILE = 1048575;
public const int LARGE_NUMBER_OF_ITEMS_TO_DOWNLOAD_WARNING_THRESHOLD = 1000;
public const int MIN_DOWNLOAD_TIMEOUT = 15;
public const int MAX_DOWNLOAD_TIMEOUT = 9999;
public const int DEFAULT_DOWNLOAD_TIMEOUT = 120;
Expand Down
30 changes: 20 additions & 10 deletions LibgenDesktop/Common/Environment.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Management;
using System.Reflection;
using Microsoft.Win32;
using static LibgenDesktop.Common.Constants;
Expand All @@ -10,6 +8,7 @@ namespace LibgenDesktop.Common
{
internal static class Environment
{
private const string WINDOWS_NT_CURRENT_VERSION_REGISTRY_KEY = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\";
private const string NET_FRAMEWORK_REGISTRY_KEY = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";

static Environment()
Expand Down Expand Up @@ -56,13 +55,16 @@ static Environment()

private static string GetOsVersion()
{
ManagementObject osInfo = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem").Get().OfType<ManagementObject>().FirstOrDefault();
if (osInfo != null)
{
return $"{osInfo.Properties["Caption"].Value.ToString()} {osInfo.Properties["Version"].Value.ToString()} {osInfo.Properties["OSArchitecture"].Value.ToString()}";
}
else
using (RegistryKey windowsNtCurrentVersionRegistryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Default).
OpenSubKey(WINDOWS_NT_CURRENT_VERSION_REGISTRY_KEY))
{
if (windowsNtCurrentVersionRegistryKey != null)
{
string productName = windowsNtCurrentVersionRegistryKey.GetValue("ProductName")?.ToString() ?? "Unknown";
string releaseId = windowsNtCurrentVersionRegistryKey.GetValue("ReleaseId")?.ToString() ?? "Unknown";
string build = windowsNtCurrentVersionRegistryKey.GetValue("CurrentBuildNumber")?.ToString() ?? "Unknown";
return $"{productName} (release: {releaseId}, build: {build})";
}
return "Unknown";
}
}
Expand All @@ -79,9 +81,17 @@ private static string GetNetFrameworkVersion()
{
if (Int32.TryParse(releaseValue.ToString(), out int releaseNumber))
{
if (releaseNumber >= 461308)
if (releaseNumber >= 528040)
{
return "4.8 or later";
}
else if (releaseNumber >= 461808)
{
return "4.7.2";
}
else if (releaseNumber >= 461308)
{
return "4.7.1 or later";
return "4.7.1";
}
else if (releaseNumber >= 460798)
{
Expand Down
6 changes: 5 additions & 1 deletion LibgenDesktop/LibgenDesktop.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Management" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security" />
Expand Down Expand Up @@ -150,6 +149,7 @@
<Compile Include="Models\Download\DownloadItemAddedEventArgs.cs" />
<Compile Include="Models\Download\DownloadItemLogLine.cs" />
<Compile Include="Models\Download\DownloadItemLogLineType.cs" />
<Compile Include="Models\Download\DownloadItemRequest.cs" />
<Compile Include="Models\Download\DownloadItemStatus.cs" />
<Compile Include="Models\Download\DownloadQueueStorage.cs" />
<Compile Include="Models\Entities\DatabaseMetadata.cs" />
Expand Down Expand Up @@ -234,6 +234,7 @@
<Compile Include="Models\SqlDump\TableType.cs" />
<Compile Include="Models\Update\GitHubApiRelease.cs" />
<Compile Include="Models\Update\Updater.cs" />
<Compile Include="Models\Utils\ExceptionUtils.cs" />
<Compile Include="Models\Utils\FileUtils.cs" />
<Compile Include="Models\Utils\NetworkUtils.cs" />
<Compile Include="Models\Utils\StringExtensions.cs" />
Expand All @@ -249,9 +250,11 @@
<Compile Include="ViewModels\Library\FictionScanResultItemViewModel.cs" />
<Compile Include="ViewModels\Library\NonFictionScanResultItemViewModel.cs" />
<Compile Include="ViewModels\Library\ScanResultItemViewModel.cs" />
<Compile Include="ViewModels\Tabs\ISearchResultsTabViewModel.cs" />
<Compile Include="ViewModels\SearchResultItems\SciMagSearchResultItemViewModel.cs" />
<Compile Include="ViewModels\SearchResultItems\FictionSearchResultItemViewModel.cs" />
<Compile Include="ViewModels\SearchResultItems\NonFictionSearchResultItemViewModel.cs" />
<Compile Include="ViewModels\Tabs\ITabViewModel.cs" />
<Compile Include="ViewModels\Windows\ApplicationUpdateWindowViewModel.cs" />
<Compile Include="ViewModels\Tabs\DetailsTabViewModel.cs" />
<Compile Include="ViewModels\Windows\AboutWindowViewModel.cs" />
Expand Down Expand Up @@ -286,6 +289,7 @@
<Compile Include="ViewModels\Tabs\SearchTabViewModel.cs" />
<Compile Include="ViewModels\Windows\SettingsWindowViewModel.cs" />
<Compile Include="ViewModels\Tabs\TabViewModel.cs" />
<Compile Include="Views\Controls\BookDataGrid.cs" />
<Compile Include="Views\Controls\BookDataGridContextMenu.xaml.cs">
<DependentUpon>BookDataGridContextMenu.xaml</DependentUpon>
</Compile>
Expand Down
12 changes: 12 additions & 0 deletions LibgenDesktop/Models/Download/DownloadItemRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace LibgenDesktop.Models.Download
{
internal class DownloadItemRequest
{
public string DownloadPageUrl { get; set; }
public string FileNameWithoutExtension { get; set; }
public string FileExtension { get; set; }
public string Md5Hash { get; set; }
public string DownloadTransformations { get; set; }
public bool RestartSessionOnTimeout { get; set; }
}
}
45 changes: 30 additions & 15 deletions LibgenDesktop/Models/Download/Downloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ public DownloadItem GetDownloadItemByDownloadPageUrl(string downloadPageUrl)
}
}

public void EnqueueDownloadItem(string downloadPageUrl, string fileNameWithoutExtension, string fileExtension, string md5Hash,
string downloadTransformations, bool restartSessionOnTimeout)
public void EnqueueDownloadItem(DownloadItemRequest downloadItemRequest)
{
string fileName = String.Concat(FileUtils.RemoveInvalidFileNameCharacters(fileNameWithoutExtension, md5Hash), ".", fileExtension.ToLower());
string fileName = String.Concat(FileUtils.RemoveInvalidFileNameCharacters(downloadItemRequest.FileNameWithoutExtension,
downloadItemRequest.Md5Hash), ".", downloadItemRequest.FileExtension.ToLower());
lock (downloadQueueLock)
{
DownloadItem newDownloadItem = new DownloadItem(Guid.NewGuid(), downloadPageUrl, downloadSettings.DownloadDirectory, fileName,
downloadTransformations, md5Hash, restartSessionOnTimeout);
DownloadItem newDownloadItem = new DownloadItem(Guid.NewGuid(), downloadItemRequest.DownloadPageUrl, downloadSettings.DownloadDirectory,
fileName, downloadItemRequest.DownloadTransformations, downloadItemRequest.Md5Hash, downloadItemRequest.RestartSessionOnTimeout);
downloadQueue.Add(newDownloadItem);
eventQueue.Add(new DownloadItemAddedEventArgs(newDownloadItem));
AddLogLine(newDownloadItem, DownloadItemLogLineType.INFORMATIONAL, localization.LogLineQueued);
Expand All @@ -109,6 +109,25 @@ public void EnqueueDownloadItem(string downloadPageUrl, string fileNameWithoutEx
}
}

public void EnqueueDownloadItems(List<DownloadItemRequest> downloadItemRequests)
{
lock (downloadQueueLock)
{
foreach (DownloadItemRequest downloadItemRequest in downloadItemRequests)
{
string fileName = String.Concat(FileUtils.RemoveInvalidFileNameCharacters(downloadItemRequest.FileNameWithoutExtension,
downloadItemRequest.Md5Hash), ".", downloadItemRequest.FileExtension.ToLower());
DownloadItem newDownloadItem = new DownloadItem(Guid.NewGuid(), downloadItemRequest.DownloadPageUrl, downloadSettings.DownloadDirectory,
fileName, downloadItemRequest.DownloadTransformations, downloadItemRequest.Md5Hash, downloadItemRequest.RestartSessionOnTimeout);
downloadQueue.Add(newDownloadItem);
eventQueue.Add(new DownloadItemAddedEventArgs(newDownloadItem));
AddLogLine(newDownloadItem, DownloadItemLogLineType.INFORMATIONAL, localization.LogLineQueued);
}
SaveDownloadQueue();
ResumeDownloadTask();
}
}

public void StartDownloads(IEnumerable<Guid> downloadItemIds)
{
lock (downloadQueueLock)
Expand Down Expand Up @@ -571,7 +590,7 @@ private async Task DownloadFileAsync(DownloadItem downloadItem)
catch (Exception exception)
{
Logger.Exception(exception);
ReportError(downloadItem, localization.LogLineUnexpectedError);
ReportError(downloadItem, localization.GetLogLineUnexpectedError(exception.GetInnermostException().Message));
}
}

Expand Down Expand Up @@ -727,7 +746,7 @@ private async Task DownloadFileAsync(DownloadItem downloadItem, FileStream desti
if (!expectedError)
{
Logger.Exception(ioException);
ReportError(downloadItem, localization.LogLineUnexpectedError);
ReportError(downloadItem, localization.GetLogLineUnexpectedError(ioException.GetInnermostException().Message));
}
break;
}
Expand All @@ -739,7 +758,7 @@ private async Task DownloadFileAsync(DownloadItem downloadItem, FileStream desti
break;
}
Logger.Exception(exception);
ReportError(downloadItem, localization.LogLineUnexpectedError);
ReportError(downloadItem, localization.GetLogLineUnexpectedError(exception.GetInnermostException().Message));
break;
}
if (bytesRead == 0)
Expand Down Expand Up @@ -840,14 +859,14 @@ private async Task<HttpResponseMessage> SendDownloadRequestAsync(DownloadItem do
else
{
Logger.Exception(aggregateException);
ReportError(downloadItem, localization.LogLineUnexpectedError);
ReportError(downloadItem, localization.GetLogLineUnexpectedError(aggregateException.GetInnermostException().Message));
}
return null;
}
catch (Exception exception)
{
Logger.Exception(exception);
ReportError(downloadItem, localization.LogLineUnexpectedError);
ReportError(downloadItem, localization.GetLogLineUnexpectedError(exception.GetInnermostException().Message));
return null;
}
Logger.Debug($"Response status code: {(int)response.StatusCode} {response.StatusCode}.");
Expand Down Expand Up @@ -902,11 +921,7 @@ private Task<HttpResponseMessage> SendRequestAsync(HttpRequestMessage request, C
}
catch (Exception exception)
{
while (!(exception is SocketException) && exception.InnerException != null)
{
exception = exception.InnerException;
}
if (exception is SocketException socketException && socketException.SocketErrorCode == SocketError.TimedOut)
if (exception.GetInnermostException() is SocketException socketException && socketException.SocketErrorCode == SocketError.TimedOut)
{
throw new TimeoutException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public DownloadManagerLocalizator(List<Translation> prioritizedTranslationList,
LogLineServerResponseTimeout = Format(translation => translation?.LogMessages?.ServerResponseTimeout);
LogLineDownloadIncompleteError = Format(translation => translation?.LogMessages?.DownloadIncompleteError);
LogLineFileWriteError = Format(translation => translation?.LogMessages?.FileWriteError);
LogLineUnexpectedError = Format(translation => translation?.LogMessages?.UnexpectedError);
}

public string TabTitle { get; }
Expand Down Expand Up @@ -77,7 +76,6 @@ public DownloadManagerLocalizator(List<Translation> prioritizedTranslationList,
public string LogLineServerResponseTimeout { get; }
public string LogLineDownloadIncompleteError { get; }
public string LogLineFileWriteError { get; }
public string LogLineUnexpectedError { get; }

public string GetDownloadProgressKnownFileSize(long downloaded, long total, int percent) =>
Format(translation => translation?.DownloadProgressKnownFileSize,
Expand Down Expand Up @@ -107,6 +105,7 @@ public string GetLogLineCannotCreateOrOpenFile(string file) =>
public string GetLogLineCannotRenamePartFile(string source, string destination) =>
Format(translation => translation?.LogMessages?.CannotRenamePartFile, new { source, destination });
public string GetLogLineRequestError(string url) => Format(translation => translation?.LogMessages?.LogLineRequestError, new { url });
public string GetLogLineUnexpectedError(string error) => Format(translation => translation?.LogMessages?.UnexpectedError, new { error });

private string Format(Func<Translation.DownloadManagerTranslation, string> field, object templateArguments = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public SearchResultsTabLocalizator(List<Translation> prioritizedTranslationList,
OfflineModeIsOnMessageTitle = Format(translation => translation?.OfflineModeIsOnMessageTitle);
OfflineModeIsOnMessageText = Format(translation => translation?.OfflineModeIsOnMessageText);
NoDownloadMirrorError = Format(translation => translation?.NoDownloadMirrorError);
LargeNumberOfItemsToDownloadPromptTitle = Format(translation => translation?.LargeNumberOfItemsToDownloadPromptTitle);
}

public string SearchPlaceHolder { get; }
Expand All @@ -38,9 +39,13 @@ public SearchResultsTabLocalizator(List<Translation> prioritizedTranslationList,
public string OfflineModeIsOnMessageTitle { get; }
public string OfflineModeIsOnMessageText { get; }
public string NoDownloadMirrorError { get; }
public string LargeNumberOfItemsToDownloadPromptTitle { get; }

public string GetFileNotFoundErrorText(string file) => Format(translation => translation?.FileNotFoundError, new { file });

public string GetLargeNumberOfItemsToDownloadPromptText(int number) =>
Format(translation => translation?.LargeNumberOfItemsToDownloadPromptText, new { number });

private string Format(Func<Translation.SearchResultsTabsTranslation, string> field, object templateArguments = null)
{
return Format(translation => field(translation?.SearchResultsTabs), templateArguments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public SynchronizationLocalizator(List<Translation> prioritizedTranslationList,
LogLineDownloadingNewBooks = FormatLogLine(translation => translation?.DownloadingNewBooks);
LogLineSynchronizationSuccessful = FormatLogLine(translation => translation?.SynchronizationSuccessful);
LogLineSynchronizationCancelled = FormatLogLine(translation => translation?.SynchronizationCancelled);
LogLineSynchronizationError = FormatLogLine(translation => translation?.SynchronizationError);
}

public string WindowTitle { get; }
Expand All @@ -55,7 +54,6 @@ public SynchronizationLocalizator(List<Translation> prioritizedTranslationList,
public string LogLineDownloadingNewBooks { get; set; }
public string LogLineSynchronizationSuccessful { get; set; }
public string LogLineSynchronizationCancelled { get; set; }
public string LogLineSynchronizationError { get; set; }

public string GetElapsedString(string elapsed) => Format(translation => translation?.Elapsed, new { elapsed });
public string GetStatusStep(int current, int total) => FormatStatus(translation => translation?.Step, new { current, total });
Expand All @@ -70,6 +68,7 @@ public string GetLogLineSynchronizationProgressUpdated(int downloaded, int updat
FormatLogLine(translation => translation?.SynchronizationProgressUpdated, new { downloaded, updated });
public string GetLogLineSynchronizationProgressAddedAndUpdated(int downloaded, int added, int updated) =>
FormatLogLine(translation => translation?.SynchronizationProgressAddedAndUpdated, new { downloaded, added, updated });
public string GetLogLineSynchronizationError(string error) => FormatLogLine(translation => translation?.SynchronizationError, new { error });

private string Format(Func<Translation.SynchronizationTranslation, string> field, object templateArguments = null)
{
Expand Down
2 changes: 2 additions & 0 deletions LibgenDesktop/Models/Localization/Translation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ internal class SearchResultsTabsTranslation
public string OfflineModeIsOnMessageTitle { get; set; }
public string OfflineModeIsOnMessageText { get; set; }
public string NoDownloadMirrorError { get; set; }
public string LargeNumberOfItemsToDownloadPromptTitle { get; set; }
public string LargeNumberOfItemsToDownloadPromptText { get; set; }
}

internal class NonFictionSearchResultsGridColumnsTranslation
Expand Down
16 changes: 16 additions & 0 deletions LibgenDesktop/Models/Utils/ExceptionUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace LibgenDesktop.Models.Utils
{
internal static class ExceptionUtils
{
public static Exception GetInnermostException(this Exception exception)
{
while (exception.InnerException != null)
{
exception = exception.InnerException;
}
return exception;
}
}
}
Loading

0 comments on commit a61f564

Please sign in to comment.