diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a461263
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+################################################################################
+# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
+################################################################################
+
+/.vs
+/packages
+/LibgenDesktop
+/LibgenDesktop.Setup/obj/Debug x64
diff --git a/LibgenDesktop/LibgenDesktop.csproj b/LibgenDesktop/LibgenDesktop.csproj
index 27ee3ac..f55c2c5 100644
--- a/LibgenDesktop/LibgenDesktop.csproj
+++ b/LibgenDesktop/LibgenDesktop.csproj
@@ -98,14 +98,9 @@
-
- ..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll
-
-
-
4.0
@@ -252,6 +247,7 @@
+
diff --git a/LibgenDesktop/Models/Localization/Localizators/LibraryTabLocalizator.cs b/LibgenDesktop/Models/Localization/Localizators/LibraryTabLocalizator.cs
index 8305b1b..d17f5e8 100644
--- a/LibgenDesktop/Models/Localization/Localizators/LibraryTabLocalizator.cs
+++ b/LibgenDesktop/Models/Localization/Localizators/LibraryTabLocalizator.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using LibgenDesktop.Models.ProgressArgs;
namespace LibgenDesktop.Models.Localization.Localizators
{
@@ -22,6 +23,8 @@ public LibraryTabLocalizator(List prioritizedTranslationList, Langu
ColumnsFile = Format(translation => translation?.File);
ColumnsAuthors = Format(translation => translation?.Authors);
ColumnsTitle = Format(translation => translation?.Title);
+ ColumnsErrorType = Format(translation => translation?.ErrorType);
+ ColumnsErrorDescription = Format(translation => translation?.ErrorDescription);
}
public string TabTitle { get; }
@@ -35,6 +38,8 @@ public LibraryTabLocalizator(List prioritizedTranslationList, Langu
public string Added { get; }
public string ScanLog { get; }
public string Error { get; }
+ public string ColumnsErrorType { get; }
+ public string ColumnsErrorDescription { get; }
public string ColumnsFile { get; }
public string ColumnsAuthors { get; }
public string ColumnsTitle { get; }
@@ -42,6 +47,37 @@ public LibraryTabLocalizator(List prioritizedTranslationList, Langu
public string GetScanStartedString(string directory) => Format(translation => translation?.ScanStarted, new { directory });
public string GetFoundString(int count) => Format(translation => translation?.Found, new { count });
public string GetNotFoundString(int count) => Format(translation => translation?.NotFound, new { count });
+ public string GetErrorsString(int count) => Format(translation => translation?.Errors, new { count });
+ public string GetErrorDescription(ErrorTypes errorType)
+ {
+ switch (errorType)
+ {
+ case ErrorTypes.ERROR_NONE:
+ return "";
+ case ErrorTypes.ERROR_DIRECTORY_ACCESS:
+ return Format(translation => translation?.Library.ErrorDescriptions.DirectoryAccess);
+ case ErrorTypes.ERROR_DIRECTORY_NOT_FOUND:
+ return Format(translation => translation?.Library.ErrorDescriptions.DirectoryNotFound);
+ case ErrorTypes.ERROR_FILE_SIZE_ZERO:
+ return Format(translation => translation?.Library.ErrorDescriptions.FileSize);
+ case ErrorTypes.ERROR_FILE_NOT_FOUND:
+ return Format(translation => translation?.Library.ErrorDescriptions.FileNotFound);
+ case ErrorTypes.ERROR_FILE_PATH_TOO_LONG:
+ return Format(translation => translation?.Library.ErrorDescriptions.FilePathTooLong);
+ case ErrorTypes.ERROR_FILE_ACCESS:
+ return Format(translation => translation?.Library.ErrorDescriptions.FileAccess);
+ case ErrorTypes.ERROR_FILE_IN_USE:
+ return Format(translation => translation?.Library.ErrorDescriptions.FileInUse);
+ case ErrorTypes.ERROR_IO_EXCEPTION:
+ return Format(translation => translation?.Library.ErrorDescriptions.IoException);
+ case ErrorTypes.ERROR_MD5_HASH_NOT_IN_DB:
+ return Format(translation => translation?.Library.ErrorDescriptions.MD5HashError);
+ case ErrorTypes.ERROR_OTHER:
+ return Format(translation => translation?.Library.ErrorDescriptions.OtherException);
+ default: throw new ArgumentOutOfRangeException();
+ }
+ }
+
public string GetScanCompleteString(int found, int notFound, int errors) => Format(translation => translation?.ScanComplete,
new { found = Formatter.ToFormattedString(found), notFound = Formatter.ToFormattedString(notFound),
errors = Formatter.ToFormattedString(errors) });
diff --git a/LibgenDesktop/Models/Localization/Translation.cs b/LibgenDesktop/Models/Localization/Translation.cs
index 15e9bf3..420323e 100644
--- a/LibgenDesktop/Models/Localization/Translation.cs
+++ b/LibgenDesktop/Models/Localization/Translation.cs
@@ -570,6 +570,22 @@ internal class LibraryColumnsTranslation
public string File { get; set; }
public string Authors { get; set; }
public string Title { get; set; }
+ public string ErrorType { get; set; }
+ public string ErrorDescription { get; set; }
+ }
+
+ internal class LibraryErrorDescriptionsTranslation
+ {
+ public string DirectoryAccess { get; set; }
+ public string DirectoryNotFound { get; set; }
+ public string FileSize { get; set; }
+ public string FileNotFound { get; set; }
+ public string FilePathTooLong { get; set; }
+ public string FileAccess { get; set; }
+ public string FileInUse { get; set; }
+ public string IoException { get; set; }
+ public string MD5HashError { get; set; }
+ public string OtherException { get; set; }
}
internal class LibraryTranslation
@@ -588,8 +604,10 @@ internal class LibraryTranslation
public string NotFound { get; set; }
public string ScanLog { get; set; }
public string Error { get; set; }
+ public string Errors { get; set; }
public string ScanComplete { get; set; }
public LibraryColumnsTranslation Columns { get; set; }
+ public LibraryErrorDescriptionsTranslation ErrorDescriptions { get; set; }
}
internal class DatabaseTranslation
diff --git a/LibgenDesktop/Models/MainModel.cs b/LibgenDesktop/Models/MainModel.cs
index d3ade15..4de5e8a 100644
--- a/LibgenDesktop/Models/MainModel.cs
+++ b/LibgenDesktop/Models/MainModel.cs
@@ -648,7 +648,7 @@ public Task GetDatabaseStatsAsync()
public async Task CheckForApplicationUpdateAsync()
{
- Updater.UpdateCheckResult result = await updater.CheckForUpdateAsync(ignoreSpecifiedRelease: false);
+ Updater.UpdateCheckResult result = await updater.CheckForUpdateAsync(false);
if (result != null && result.NewReleaseName != AppSettings.LastUpdate.IgnoreReleaseName)
{
LastApplicationUpdateCheckResult = result;
@@ -1083,27 +1083,83 @@ private void ScanDirectory(string rootScanDirectory, string scanDirectory, IP
{
relativeFilePath = relativeFilePath.Substring(rootScanDirectory.Length + 1);
}
+
+ if (!StringExtensions.HasEbookExtension(relativeFilePath))
+ {
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, false, ErrorTypes.ERROR_NONE));
+ notFound++;
+ continue;
+ }
+
string md5Hash;
try
{
- using (MD5 md5 = MD5.Create())
- using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
+ using (var md5 = MD5.Create())
+ using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 8192, true))
+ {
+ if (fileStream.Length <= 0)
+ {
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, true, ErrorTypes.ERROR_FILE_SIZE_ZERO));
+ errors++;
+ continue;
+ }
+ var md5HashArray = md5.ComputeHash(fileStream);
+ md5Hash = BitConverter.ToString(md5HashArray).Replace("-", "").ToLowerInvariant();
+ }
+ }
+ catch (IOException ex)
+ {
+ int hresult = ExceptionUtils.GetHRForException(ex);
+ const int E_PATHTOOLONG = unchecked((int) 0x800700CE);
+ const int E_FILENOTFOUND = unchecked((int) 0x80070002);
+ const int E_ACCESSDENIED = unchecked((int) 0x80070005);
+ const int E_SHARING_VIOLATION = unchecked((int) 0x80070020);
+
+ switch (hresult)
{
- byte[] md5HashArray = md5.ComputeHash(fileStream);
- md5Hash = BitConverter.ToString(md5HashArray).Replace("-", String.Empty).ToLowerInvariant();
+ case E_PATHTOOLONG:
+ Logger.Debug($"Error: {nameof(ErrorTypes.ERROR_FILE_PATH_TOO_LONG).Replace("_", " ")}, length: {filePath.Length}");
+ Logger.Exception(ex);
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, true, ErrorTypes.ERROR_FILE_PATH_TOO_LONG));
+ errors++;
+ continue;
+ case E_FILENOTFOUND:
+ Logger.Debug($"Error: {nameof(ErrorTypes.ERROR_FILE_NOT_FOUND).Replace("_", " ")}, filePath: {filePath}");
+ Logger.Exception(ex);
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, true, ErrorTypes.ERROR_FILE_NOT_FOUND));
+ errors++;
+ continue;
+ case E_ACCESSDENIED:
+ Logger.Debug($"Error: {nameof(ErrorTypes.ERROR_FILE_ACCESS).Replace("_", " ")}, filePath: {filePath}");
+ Logger.Exception(ex);
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, true, ErrorTypes.ERROR_FILE_ACCESS));
+ errors++;
+ continue;
+ case E_SHARING_VIOLATION:
+ Logger.Debug($"Error: {nameof(ErrorTypes.ERROR_FILE_IN_USE).Replace("_", " ")}, filePath: {filePath}");
+ Logger.Exception(ex);
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, true, ErrorTypes.ERROR_FILE_IN_USE));
+ errors++;
+ continue;
}
+
+ Logger.Debug($"Error: {nameof(ErrorTypes.ERROR_IO_EXCEPTION).Replace("_", " ")}, IOException: {ex}");
+ Logger.Exception(ex);
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, true, ErrorTypes.ERROR_IO_EXCEPTION));
+ errors++;
+ continue;
}
catch (Exception exception)
{
Logger.Debug($"Couldn't calculate MD5 hash for the file: {filePath}");
Logger.Exception(exception);
- progressHandler.Report(new ScanUnknownProgress(relativeFilePath, error: true));
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, true, ErrorTypes.ERROR_OTHER));
errors++;
continue;
}
try
{
- T libgenObject = getObjectByMd5HashFunction(md5Hash);
+ var libgenObject = getObjectByMd5HashFunction(md5Hash);
if (libgenObject != null)
{
progressHandler.Report(new ScanProgress(relativeFilePath, libgenObject));
@@ -1111,17 +1167,16 @@ private void ScanDirectory(string rootScanDirectory, string scanDirectory, IP
}
else
{
- progressHandler.Report(new ScanUnknownProgress(relativeFilePath, error: false));
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, false, ErrorTypes.ERROR_NONE));
notFound++;
}
}
catch (Exception exception)
{
- Logger.Debug($"Couldn't lookup the MD5 hash: {md5Hash} in the database for the file: {filePath}");
+ Logger.Debug($"Error: {nameof(ErrorTypes.ERROR_MD5_HASH_NOT_IN_DB).Replace("_", " ")}, MD5 hash: {md5Hash} in the database for the file: {filePath}");
Logger.Exception(exception);
- progressHandler.Report(new ScanUnknownProgress(relativeFilePath, error: true));
+ progressHandler.Report(new ScanUnknownProgress(relativeFilePath, true, ErrorTypes.ERROR_MD5_HASH_NOT_IN_DB));
errors++;
- continue;
}
}
foreach (string directoryPath in Directory.EnumerateDirectories(scanDirectory))
@@ -1129,10 +1184,30 @@ private void ScanDirectory(string rootScanDirectory, string scanDirectory, IP
ScanDirectory(rootScanDirectory, directoryPath, progressHandler, getObjectByMd5HashFunction, ref found, ref notFound, ref errors);
}
}
+ catch (UnauthorizedAccessException ex)
+ {
+ Logger.Debug($"Error: {nameof(ErrorTypes.ERROR_DIRECTORY_ACCESS).Replace("_", " ")}, filePath: {scanDirectory}");
+ Logger.Exception(ex);
+ progressHandler.Report(new ScanUnknownProgress(scanDirectory, true, ErrorTypes.ERROR_DIRECTORY_ACCESS));
+ errors++;
+ }
+ catch (IOException ex)
+ {
+ int hresult = ExceptionUtils.GetHRForException(ex);
+ const int E_DIRECTORYNOTFOUND = unchecked((int)0x80070003);
+
+ if (hresult == E_DIRECTORYNOTFOUND)
+ {
+ Logger.Debug($"Error: {nameof(ErrorTypes.ERROR_DIRECTORY_NOT_FOUND).Replace("_", " ")}, filePath: {scanDirectory}");
+ Logger.Exception(ex);
+ progressHandler.Report(new ScanUnknownProgress(scanDirectory, true, ErrorTypes.ERROR_DIRECTORY_NOT_FOUND));
+ errors++;
+ }
+ }
catch (Exception exception)
{
Logger.Exception(exception);
- progressHandler.Report(new ScanUnknownProgress(scanDirectory, error: true));
+ progressHandler.Report(new ScanUnknownProgress(scanDirectory, true, ErrorTypes.ERROR_OTHER));
errors++;
}
}
diff --git a/LibgenDesktop/Models/ProgressArgs/ScanUnknownProgress.cs b/LibgenDesktop/Models/ProgressArgs/ScanUnknownProgress.cs
index 73e6935..37a9e38 100644
--- a/LibgenDesktop/Models/ProgressArgs/ScanUnknownProgress.cs
+++ b/LibgenDesktop/Models/ProgressArgs/ScanUnknownProgress.cs
@@ -1,14 +1,31 @@
namespace LibgenDesktop.Models.ProgressArgs
{
+ internal enum ErrorTypes
+ {
+ ERROR_NONE,
+ ERROR_DIRECTORY_ACCESS,
+ ERROR_DIRECTORY_NOT_FOUND,
+ ERROR_FILE_NOT_FOUND,
+ ERROR_FILE_PATH_TOO_LONG,
+ ERROR_FILE_ACCESS,
+ ERROR_FILE_IN_USE,
+ ERROR_FILE_SIZE_ZERO,
+ ERROR_IO_EXCEPTION,
+ ERROR_MD5_HASH_NOT_IN_DB,
+ ERROR_OTHER
+ }
+
internal class ScanUnknownProgress
{
- public ScanUnknownProgress(string relativeFilePath, bool error)
+ public ScanUnknownProgress(string relativeFilePath, bool error, ErrorTypes errorType)
{
RelativeFilePath = relativeFilePath;
Error = error;
+ ErrorType = errorType;
}
public string RelativeFilePath { get; }
public bool Error { get; }
+ public ErrorTypes ErrorType {get;}
}
-}
+}
\ No newline at end of file
diff --git a/LibgenDesktop/Models/Utils/ExceptionUtils.cs b/LibgenDesktop/Models/Utils/ExceptionUtils.cs
index 767e309..2f76b82 100644
--- a/LibgenDesktop/Models/Utils/ExceptionUtils.cs
+++ b/LibgenDesktop/Models/Utils/ExceptionUtils.cs
@@ -1,9 +1,21 @@
using System;
+using System.Runtime.InteropServices;
namespace LibgenDesktop.Models.Utils
{
internal static class ExceptionUtils
{
+ public static int GetHRForException(Exception exception)
+ {
+ if (exception == null) throw new ArgumentNullException();
+
+ //on first call there is possible pollution of thread IErrorInfo with sensitive data
+ int hr = Marshal.GetHRForException(exception);
+ //therefore call with empty ex. obj. to cleanup IErrorInfo
+ Marshal.GetHRForException(new Exception());
+ return hr;
+ }
+
public static Exception GetInnermostException(this Exception exception)
{
while (exception.InnerException != null)
diff --git a/LibgenDesktop/Models/Utils/StringExtensions.cs b/LibgenDesktop/Models/Utils/StringExtensions.cs
index ac2ebdb..717e254 100644
--- a/LibgenDesktop/Models/Utils/StringExtensions.cs
+++ b/LibgenDesktop/Models/Utils/StringExtensions.cs
@@ -6,6 +6,11 @@ namespace LibgenDesktop.Models.Utils
{
internal static class StringExtensions
{
+ public static bool HasEbookExtension(string source)
+ {
+ return (source.EndsWith(".djvu") || source.EndsWith(".mobi") || source.EndsWith(".pdf") || source.EndsWith(".epub")|| source.EndsWith(".doc") || source.EndsWith(".docx") );
+ }
+
public static bool CompareOrdinalIgnoreCase(this string currentString, string otherString)
{
return String.Compare(currentString, otherString, StringComparison.OrdinalIgnoreCase) == 0;
diff --git a/LibgenDesktop/Resources/Languages/English.lng b/LibgenDesktop/Resources/Languages/English.lng
index 0487d07..2049b24 100644
--- a/LibgenDesktop/Resources/Languages/English.lng
+++ b/LibgenDesktop/Resources/Languages/English.lng
@@ -1,768 +1,735 @@
{
- "General":
- {
- "Name": "English",
- "LocalizedName": "US English",
- "CultureCode": "en-US",
- "TranslatorName": "libgenapps"
- },
- "Formatting":
- {
- "DecimalSeparator": ".",
- "ThousandsSeparator": ",",
- "DateFormat": "MM/dd/yyyy",
- "TimeFormat": "hh:mm:ss tt",
- "FileSizePostfixes":
- {
- "Byte": "bytes",
- "Kilobyte": "KB",
- "Megabyte": "MB",
- "Gigabyte": "GB",
- "Terabyte": "TB"
- }
- },
- "MainWindow":
- {
- "WindowTitle": "Libgen Desktop",
- "MainMenu":
- {
- "DownloadManagerTooltip": "Download Manager",
- "BookmarksTooltip": "Bookmarks",
- "NoBookmarks": "No bookmarks",
- "Update": "Update...",
- "Import": "Import...",
- "Synchronize": "Synchronization...",
- "Library": "Library",
- "Database": "Database...",
- "SqlDebugger": "SQL debugger",
- "Settings": "Settings",
- "About": "About"
- }
- },
- "CreateDatabaseWindow":
- {
- "WindowTitle": "Libgen Desktop",
- "FirstRunMessage": "Welcome to Libgen Desktop.",
- "DatabaseNotFound": "Database {database} not found.",
- "DatabaseCorrupted": "Database {database} is corrupted.",
- "LibgenServerDatabase": "Database {database} is a Libgen Server database which is not compatible with the Libgen Desktop database structure.",
- "ChooseOption": "Choose an action",
- "CreateNewDatabase": "Create a new database",
- "OpenExistingDatabase": "Open an existing database",
- "BrowseNewDatabaseDialogTitle": "New database location",
- "BrowseExistingDatabaseDialogTitle": "Existing database location",
- "Databases": "Databases",
- "AllFiles": "All files",
- "Error": "Error",
- "CannotCreateDatabase": "Couldn't create database.",
- "Ok": "OK",
- "Cancel": "CANCEL"
- },
- "SearchTab":
- {
- "TabTitle": "Search",
- "SearchPlaceHolder": "Search",
- "NonFictionSelector": "Non-fiction books",
- "FictionSelector": "Fiction books",
- "SciMagSelector": "Scientific articles",
- "NonFictionSearchBoxTooltip": "Search by title, authors, series, publisher, and ISBN without dashes",
- "FictionSearchBoxTooltip": "Search by title, authors, series, publisher, and ISBN with dashes",
- "SciMagSearchBoxTooltip": "Search by title, authors, magazine name, DOI, Pubmed ID, and ISSN (p/e)",
- "SearchInProgress": "Search in progress...",
- "NonFictionSearchProgress": "Books found: {count}",
- "FictionSearchProgress": "Books found: {count}",
- "SciMagSearchProgress": "Articles found: {count}",
- "Interrupt": "INTERRUPT",
- "Interrupting": "INTERRUPTING...",
- "DatabaseIsEmpty": "The database is empty. Download a database dump from the Library Genesis web site and import it here.",
- "ImportButton": "Import"
- },
- "SearchResultsTabs":
- {
- "SearchPlaceHolder": "Search",
- "SearchInProgress": "Search in progress...",
- "Interrupt": "INTERRUPT",
- "Interrupting": "INTERRUPTING...",
- "AddToBookmarksTooltip": "Add to bookmarks",
- "RemoveFromBookmarksTooltip": "Remove from bookmarks",
- "ExportButtonTooltip": "Export search results to a file",
- "Details": "Details",
- "Open": "Open",
- "Download": "Download",
- "ErrorMessageTitle": "Error",
- "FileNotFoundError": "File {file} not found.",
- "OfflineModeIsOnMessageTitle": "Offline mode is on",
- "OfflineModeIsOnMessageText": "Downloading is disabled while the offline mode is on. You can turn it off in the settings window.",
- "NoDownloadMirrorError": "No download mirror has been selected. Please choose one of the mirrors in the settings window.",
- "LargeNumberOfItemsToDownloadPromptTitle": "Large number of items to download",
- "LargeNumberOfItemsToDownloadPromptText": "You are about to download {number} items. Are you sure?"
- },
- "NonFictionSearchResultsTab":
- {
- "SearchBoxTooltip": "Search by title, authors, series, publisher, and ISBN without dashes",
- "SearchProgress": "Books found: {count}",
- "StatusBar": "Books found: {count}",
- "Columns":
- {
- "Title": "Title",
- "Authors": "Authors",
- "Series": "Series",
- "Year": "Year",
- "Publisher": "Publisher",
- "Format": "Format",
- "FileSize": "File Size",
- "Ocr": "OCR",
- "InLocalLibrary": "In local library"
- }
- },
- "FictionSearchResultsTab":
- {
- "SearchBoxTooltip": "Search by title, authors, series, publisher, and ISBN with dashes",
- "SearchProgress": "Books found: {count}",
- "StatusBar": "Books found: {count}",
- "Columns":
- {
- "Title": "Title",
- "Authors": "Authors",
- "Series": "Series",
- "Year": "Year",
- "Publisher": "Publisher",
- "Format": "Format",
- "FileSize": "File Size",
- "InLocalLibrary": "In local library"
- }
- },
- "SciMagSearchResultsTab":
- {
- "SearchBoxTooltip": "Search by title, authors, magazine name, DOI, Pubmed ID, and ISSN (p/e)",
- "SearchProgress": "Articles found: {count}",
- "StatusBar": "Articles found: {count}",
- "Columns":
- {
- "Title": "Title",
- "Authors": "Authors",
- "Magazine": "Magazine",
- "Year": "Year",
- "FileSize": "File Size",
- "Doi": "DOI",
- "InLocalLibrary": "In local library"
- }
- },
- "DetailsTabs":
- {
- "CoverIsLoading": "Loading cover...",
- "NoCover": "No cover available",
- "NoCoverMirror": "No mirror has been selected{new-line}to load this cover",
- "NoCoverDueToOfflineMode": "Offline mode is on.{new-line}Cover not loaded.",
- "CoverLoadingError": "Couldn't load the cover",
- "Yes": "yes",
- "No": "no",
- "Unknown": "unknown",
- "Portrait": "portrait",
- "Landscape": "landscape",
- "CopyContextMenu": "Copy \"{text}\"",
- "Download": "DOWNLOAD",
- "DownloadFromMirror": "DOWNLOAD FROM {mirror}",
- "Queued": "QUEUED",
- "Downloading": "DOWNLOADING",
- "Stopped": "STOPPED",
- "Error": "DOWNLOAD ERROR",
- "Open": "OPEN FILE",
- "ErrorMessageTitle": "Error",
- "FileNotFoundError": "File {file} not found.",
- "NoDownloadMirrorTooltip": "No mirror has been selected",
- "OfflineModeIsOnTooltip": "Offline mode is on",
- "Close": "CLOSE"
- },
- "NonFictionDetailsTab":
- {
- "Title": "Title",
- "Authors": "Authors",
- "Series": "Series",
- "Publisher": "Publisher",
- "Year": "Year",
- "Language": "Language",
- "Format": "Format",
- "Isbn": "ISBN",
- "Added": "Added",
- "LastModified": "Last Modified",
- "Library": "Library",
- "FileSize": "File Size",
- "Topics": "Topics",
- "Volume": "Volume",
- "Magazine": "Magazine",
- "City": "City",
- "Edition": "Edition",
- "Pages": "Pages",
- "BodyMatterPages": "body matter",
- "TotalPages": "total",
- "Tags": "Tags",
- "Md5Hash": "MD5 hash",
- "Comments": "Comments",
- "Identifiers": "Identifiers",
- "LibgenId": "Libgen ID",
- "Issn": "ISSN",
- "Udc": "UDC",
- "Lbc": "LBC",
- "Lcc": "LCC",
- "Ddc": "DDC",
- "Doi": "DOI",
- "OpenLibraryId": "Open Library ID",
- "GoogleBookId": "Google Books ID",
- "Asin": "ASIN",
- "AdditionalAttributes": "Additional Attributes",
- "Dpi": "DPI",
- "Ocr": "OCR",
- "TableOfContents": "Table Of Contents",
- "Scanned": "Scanned",
- "Orientation": "Orientation",
- "Paginated": "Paginated",
- "Colored": "Colored",
- "Cleaned": "Cleaned"
- },
- "FictionDetailsTab":
- {
- "Title": "Title",
- "Authors": "Authors",
- "RussianAuthor": "Author in Russian",
- "Series": "Series",
- "Publisher": "Publisher",
- "Edition": "Edition",
- "Year": "Year",
- "Language": "Language",
- "Format": "Format",
- "Pages": "Pages",
- "Version": "Version",
- "FileSize": "File Size",
- "Added": "Added",
- "LastModified": "Last Modified",
- "Md5Hash": "MD5 hash",
- "Comments": "Comments",
- "Identifiers": "Identifiers",
- "LibgenId": "Libgen ID",
- "Isbn": "ISBN",
- "GoogleBookId": "Google Books ID",
- "Asin": "ASIN"
- },
- "SciMagDetailsTab":
- {
- "Title": "Title",
- "Authors": "Authors",
- "Magazine": "Magazine",
- "Year": "Year",
- "Month": "Month",
- "Day": "Day",
- "Volume": "Volume",
- "Issue": "Issue",
- "Pages": "Pages",
- "FileSize": "File Size",
- "AddedDateTime": "Added",
- "Md5Hash": "MD5 hash",
- "AbstractUrl": "Abstract URL",
- "Identifiers": "Identifiers",
- "LibgenId": "Libgen ID",
- "Doi": "DOI",
- "Isbn": "ISBN",
- "MagazineId": "Magazine ID",
- "Issnp": "ISSN (p)",
- "Issne": "ISSN (e)",
- "PubmedId": "Pubmed ID",
- "Pmc": "PMC",
- "Pii": "PII",
- "AdditionalAttributes": "Additional Attributes",
- "Attribute1": "Attribute 1",
- "Attribute2": "Attribute 2",
- "Attribute3": "Attribute 3",
- "Attribute4": "Attribute 4",
- "Attribute5": "Attribute 5",
- "Attribute6": "Attribute 6"
- },
- "Import":
- {
- "WindowTitle": "Import from SQL dump",
- "BrowseImportFileDialogTitle": "SQL dump file location",
- "AllSupportedFiles": "All supported files",
- "SqlDumps": "SQL dumps",
- "Archives": "Archives",
- "AllFiles": "All files",
- "Elapsed": "Time elapsed: {elapsed}",
- "FreeSpace": "Free space left on device: {freeSpace}",
- "Unknown": "unknown",
- "Interrupt": "INTERRUPT",
- "Interrupting": "INTERRUPTING...",
- "Close": "CLOSE",
- "StatusMessages":
- {
- "Step": "Step {current} of {total}.",
- "DataLookup": "Table definition lookup",
- "CreatingIndexes": "Creating indexes",
- "LoadingIds": "Loading identifiers",
- "ImportingData": "Importing data",
- "ImportComplete": "Import complete",
- "ImportCancelled": "Import has been cancelled",
- "DataNotFound": "Data not found",
- "ImportError": "Import failed"
- },
- "LogMessages":
- {
- "Step": "Step {step}",
- "DataLookup": "Searching for the table definitions",
- "Scanning": "Scanning...",
- "ScannedProgress": "{percent}% of the file have been scanned...",
- "NonFictionTableFound": "Non-fiction book table found.",
- "FictionTableFound": "Fiction book table found.",
- "SciMagTableFound": "Scientific article table found.",
- "CreatingIndexes": "Creating missing indexes",
- "CreatingIndexForColumn": "Creating index for {column} column...",
- "LoadingIds": "Loading existing data identifiers",
- "LoadingColumnValues": "Loading data for {column} column...",
- "ImportingData": "Importing data",
- "ImportBooksProgressNoUpdate": "Books added: {added}.",
- "ImportBooksProgressWithUpdate": "Books added: {added}, updated: {updated}.",
- "ImportArticlesProgressNoUpdate": "Articles added: {added}.",
- "ImportArticlesProgressWithUpdate": "Articles added: {added}, updated: {updated}.",
- "ImportSuccessful": "Import completed successfully.",
- "ImportCancelled": "Import has been cancelled by the user.",
- "DataNotFound": "Couldn't find the data to import.",
- "InsufficientDiskSpace": "Insufficient disk space.",
- "ImportError": "An error occurred during the import."
- }
+ "General": {
+ "Name": "English",
+ "LocalizedName": "US English",
+ "CultureCode": "en-US",
+ "TranslatorName": "libgenapps"
+ },
+ "Formatting": {
+ "DecimalSeparator": ".",
+ "ThousandsSeparator": ",",
+ "DateFormat": "MM/dd/yyyy",
+ "TimeFormat": "hh:mm:ss tt",
+ "FileSizePostfixes": {
+ "Byte": "bytes",
+ "Kilobyte": "KB",
+ "Megabyte": "MB",
+ "Gigabyte": "GB",
+ "Terabyte": "TB"
+ }
+ },
+ "MainWindow": {
+ "WindowTitle": "Libgen Desktop",
+ "MainMenu": {
+ "DownloadManagerTooltip": "Download Manager",
+ "BookmarksTooltip": "Bookmarks",
+ "NoBookmarks": "No bookmarks",
+ "Update": "Update...",
+ "Import": "Import...",
+ "Synchronize": "Synchronization...",
+ "Library": "Library",
+ "Database": "Database...",
+ "SqlDebugger": "SQL debugger",
+ "Settings": "Settings",
+ "About": "About"
+ }
+ },
+ "CreateDatabaseWindow": {
+ "WindowTitle": "Libgen Desktop",
+ "FirstRunMessage": "Welcome to Libgen Desktop.",
+ "DatabaseNotFound": "Database {database} not found.",
+ "DatabaseCorrupted": "Database {database} is corrupted.",
+ "LibgenServerDatabase": "Database {database} is a Libgen Server database which is not compatible with the Libgen Desktop database structure.",
+ "ChooseOption": "Choose an action",
+ "CreateNewDatabase": "Create a new database",
+ "OpenExistingDatabase": "Open an existing database",
+ "BrowseNewDatabaseDialogTitle": "New database location",
+ "BrowseExistingDatabaseDialogTitle": "Existing database location",
+ "Databases": "Databases",
+ "AllFiles": "All files",
+ "Error": "Error",
+ "CannotCreateDatabase": "Couldn't create database.",
+ "Ok": "OK",
+ "Cancel": "CANCEL"
+ },
+ "SearchTab": {
+ "TabTitle": "Search",
+ "SearchPlaceHolder": "Search",
+ "NonFictionSelector": "Non-fiction books",
+ "FictionSelector": "Fiction books",
+ "SciMagSelector": "Scientific articles",
+ "NonFictionSearchBoxTooltip": "Search by title, authors, series, publisher, and ISBN without dashes",
+ "FictionSearchBoxTooltip": "Search by title, authors, series, publisher, and ISBN with dashes",
+ "SciMagSearchBoxTooltip": "Search by title, authors, magazine name, DOI, Pubmed ID, and ISSN (p/e)",
+ "SearchInProgress": "Search in progress...",
+ "NonFictionSearchProgress": "Books found: {count}",
+ "FictionSearchProgress": "Books found: {count}",
+ "SciMagSearchProgress": "Articles found: {count}",
+ "Interrupt": "INTERRUPT",
+ "Interrupting": "INTERRUPTING...",
+ "DatabaseIsEmpty": "The database is empty. Download a database dump from the Library Genesis web site and import it here.",
+ "ImportButton": "Import"
+ },
+ "SearchResultsTabs": {
+ "SearchPlaceHolder": "Search",
+ "SearchInProgress": "Search in progress...",
+ "Interrupt": "INTERRUPT",
+ "Interrupting": "INTERRUPTING...",
+ "AddToBookmarksTooltip": "Add to bookmarks",
+ "RemoveFromBookmarksTooltip": "Remove from bookmarks",
+ "ExportButtonTooltip": "Export search results to a file",
+ "Details": "Details",
+ "Open": "Open",
+ "Download": "Download",
+ "ErrorMessageTitle": "Error",
+ "FileNotFoundError": "File {file} not found.",
+ "OfflineModeIsOnMessageTitle": "Offline mode is on",
+ "OfflineModeIsOnMessageText": "Downloading is disabled while the offline mode is on. You can turn it off in the settings window.",
+ "NoDownloadMirrorError": "No download mirror has been selected. Please choose one of the mirrors in the settings window.",
+ "LargeNumberOfItemsToDownloadPromptTitle": "Large number of items to download",
+ "LargeNumberOfItemsToDownloadPromptText": "You are about to download {number} items. Are you sure?"
+ },
+ "NonFictionSearchResultsTab": {
+ "SearchBoxTooltip": "Search by title, authors, series, publisher, and ISBN without dashes",
+ "SearchProgress": "Books found: {count}",
+ "StatusBar": "Books found: {count}",
+ "Columns": {
+ "Title": "Title",
+ "Authors": "Authors",
+ "Series": "Series",
+ "Year": "Year",
+ "Publisher": "Publisher",
+ "Format": "Format",
+ "FileSize": "File Size",
+ "Ocr": "OCR",
+ "InLocalLibrary": "In local library"
+ }
+ },
+ "FictionSearchResultsTab": {
+ "SearchBoxTooltip": "Search by title, authors, series, publisher, and ISBN with dashes",
+ "SearchProgress": "Books found: {count}",
+ "StatusBar": "Books found: {count}",
+ "Columns": {
+ "Title": "Title",
+ "Authors": "Authors",
+ "Series": "Series",
+ "Year": "Year",
+ "Publisher": "Publisher",
+ "Format": "Format",
+ "FileSize": "File Size",
+ "InLocalLibrary": "In local library"
+ }
+ },
+ "SciMagSearchResultsTab": {
+ "SearchBoxTooltip": "Search by title, authors, magazine name, DOI, Pubmed ID, and ISSN (p/e)",
+ "SearchProgress": "Articles found: {count}",
+ "StatusBar": "Articles found: {count}",
+ "Columns": {
+ "Title": "Title",
+ "Authors": "Authors",
+ "Magazine": "Magazine",
+ "Year": "Year",
+ "FileSize": "File Size",
+ "Doi": "DOI",
+ "InLocalLibrary": "In local library"
+ }
+ },
+ "DetailsTabs": {
+ "CoverIsLoading": "Loading cover...",
+ "NoCover": "No cover available",
+ "NoCoverMirror": "No mirror has been selected{new-line}to load this cover",
+ "NoCoverDueToOfflineMode": "Offline mode is on.{new-line}Cover not loaded.",
+ "CoverLoadingError": "Couldn't load the cover",
+ "Yes": "yes",
+ "No": "no",
+ "Unknown": "unknown",
+ "Portrait": "portrait",
+ "Landscape": "landscape",
+ "CopyContextMenu": "Copy \"{text}\"",
+ "Download": "DOWNLOAD",
+ "DownloadFromMirror": "DOWNLOAD FROM {mirror}",
+ "Queued": "QUEUED",
+ "Downloading": "DOWNLOADING",
+ "Stopped": "STOPPED",
+ "Error": "DOWNLOAD ERROR",
+ "Open": "OPEN FILE",
+ "ErrorMessageTitle": "Error",
+ "FileNotFoundError": "File {file} not found.",
+ "NoDownloadMirrorTooltip": "No mirror has been selected",
+ "OfflineModeIsOnTooltip": "Offline mode is on",
+ "Close": "CLOSE"
+ },
+ "NonFictionDetailsTab": {
+ "Title": "Title",
+ "Authors": "Authors",
+ "Series": "Series",
+ "Publisher": "Publisher",
+ "Year": "Year",
+ "Language": "Language",
+ "Format": "Format",
+ "Isbn": "ISBN",
+ "Added": "Added",
+ "LastModified": "Last Modified",
+ "Library": "Library",
+ "FileSize": "File Size",
+ "Topics": "Topics",
+ "Volume": "Volume",
+ "Magazine": "Magazine",
+ "City": "City",
+ "Edition": "Edition",
+ "Pages": "Pages",
+ "BodyMatterPages": "body matter",
+ "TotalPages": "total",
+ "Tags": "Tags",
+ "Md5Hash": "MD5 hash",
+ "Comments": "Comments",
+ "Identifiers": "Identifiers",
+ "LibgenId": "Libgen ID",
+ "Issn": "ISSN",
+ "Udc": "UDC",
+ "Lbc": "LBC",
+ "Lcc": "LCC",
+ "Ddc": "DDC",
+ "Doi": "DOI",
+ "OpenLibraryId": "Open Library ID",
+ "GoogleBookId": "Google Books ID",
+ "Asin": "ASIN",
+ "AdditionalAttributes": "Additional Attributes",
+ "Dpi": "DPI",
+ "Ocr": "OCR",
+ "TableOfContents": "Table Of Contents",
+ "Scanned": "Scanned",
+ "Orientation": "Orientation",
+ "Paginated": "Paginated",
+ "Colored": "Colored",
+ "Cleaned": "Cleaned"
+ },
+ "FictionDetailsTab": {
+ "Title": "Title",
+ "Authors": "Authors",
+ "RussianAuthor": "Author in Russian",
+ "Series": "Series",
+ "Publisher": "Publisher",
+ "Edition": "Edition",
+ "Year": "Year",
+ "Language": "Language",
+ "Format": "Format",
+ "Pages": "Pages",
+ "Version": "Version",
+ "FileSize": "File Size",
+ "Added": "Added",
+ "LastModified": "Last Modified",
+ "Md5Hash": "MD5 hash",
+ "Comments": "Comments",
+ "Identifiers": "Identifiers",
+ "LibgenId": "Libgen ID",
+ "Isbn": "ISBN",
+ "GoogleBookId": "Google Books ID",
+ "Asin": "ASIN"
+ },
+ "SciMagDetailsTab": {
+ "Title": "Title",
+ "Authors": "Authors",
+ "Magazine": "Magazine",
+ "Year": "Year",
+ "Month": "Month",
+ "Day": "Day",
+ "Volume": "Volume",
+ "Issue": "Issue",
+ "Pages": "Pages",
+ "FileSize": "File Size",
+ "AddedDateTime": "Added",
+ "Md5Hash": "MD5 hash",
+ "AbstractUrl": "Abstract URL",
+ "Identifiers": "Identifiers",
+ "LibgenId": "Libgen ID",
+ "Doi": "DOI",
+ "Isbn": "ISBN",
+ "MagazineId": "Magazine ID",
+ "Issnp": "ISSN (p)",
+ "Issne": "ISSN (e)",
+ "PubmedId": "Pubmed ID",
+ "Pmc": "PMC",
+ "Pii": "PII",
+ "AdditionalAttributes": "Additional Attributes",
+ "Attribute1": "Attribute 1",
+ "Attribute2": "Attribute 2",
+ "Attribute3": "Attribute 3",
+ "Attribute4": "Attribute 4",
+ "Attribute5": "Attribute 5",
+ "Attribute6": "Attribute 6"
+ },
+ "Import": {
+ "WindowTitle": "Import from SQL dump",
+ "BrowseImportFileDialogTitle": "SQL dump file location",
+ "AllSupportedFiles": "All supported files",
+ "SqlDumps": "SQL dumps",
+ "Archives": "Archives",
+ "AllFiles": "All files",
+ "Elapsed": "Time elapsed: {elapsed}",
+ "FreeSpace": "Free space left on device: {freeSpace}",
+ "Unknown": "unknown",
+ "Interrupt": "INTERRUPT",
+ "Interrupting": "INTERRUPTING...",
+ "Close": "CLOSE",
+ "StatusMessages": {
+ "Step": "Step {current} of {total}.",
+ "DataLookup": "Table definition lookup",
+ "CreatingIndexes": "Creating indexes",
+ "LoadingIds": "Loading identifiers",
+ "ImportingData": "Importing data",
+ "ImportComplete": "Import complete",
+ "ImportCancelled": "Import has been cancelled",
+ "DataNotFound": "Data not found",
+ "ImportError": "Import failed"
},
- "ExportPanel":
- {
- "Header": "Export search results to a file",
- "Format": "File Format",
- "Excel": "Microsoft Excel 2007-2016 (XLSX)",
- "Csv": "Comma-separated values (CSV)",
- "Separator": "Separator",
- "Comma": "Comma",
- "Semicolon": "Semicolon",
- "Tab": "Tab character",
- "SaveAs": "Save as",
- "Browse": "Browse...",
- "BrowseDialogTitle": "Export search results",
- "ExcelFiles": "Microsoft Excel files",
- "CsvFiles": "CSV files",
- "TsvFiles": "TSV files",
- "AllFiles": "All files",
- "ExportRange": "Export range",
- "NoLimit": "all",
- "Limit": "first {count} results only",
- "Export": "EXPORT",
- "Cancel": "CANCEL",
- "SavingFile": "Saving the file.",
- "RowCountSingleFile": "Exported rows: {rows}.",
- "RowCountMultipleFiles": "Exported rows: {rows}, files created: {files}.",
- "ErrorWarningTitle": "Error",
- "InvalidExportPath": "Invalid export file path.",
- "DirectoryNotFound": "Directory {directory} doesn't exist.",
- "InvalidExportFileName": "Invalid export file name.",
- "OverwritePromptTitle": "Overwrite the file?",
- "OverwritePromptText": "File {file} already exists. Do you want to overwrite it?",
- "RowLimitWarningTitle": "Row limit",
- "RowLimitWarningText": "Microsoft Excel maximum row count has been reached. Export cannot be continued. In order to export more rows please enable \"Split into multiple files\" option in the application settings.",
- "ExportError": "An error occurred during the export.",
- "Interrupt": "INTERRUPT",
- "Interrupting": "INTERRUPTING...",
- "ExportInterrupted": "Export has been interrupted.",
- "Results": "OPEN RESULTS",
- "Close": "CLOSE"
+ "LogMessages": {
+ "Step": "Step {step}",
+ "DataLookup": "Searching for the table definitions",
+ "Scanning": "Scanning...",
+ "ScannedProgress": "{percent}% of the file have been scanned...",
+ "NonFictionTableFound": "Non-fiction book table found.",
+ "FictionTableFound": "Fiction book table found.",
+ "SciMagTableFound": "Scientific article table found.",
+ "CreatingIndexes": "Creating missing indexes",
+ "CreatingIndexForColumn": "Creating index for {column} column...",
+ "LoadingIds": "Loading existing data identifiers",
+ "LoadingColumnValues": "Loading data for {column} column...",
+ "ImportingData": "Importing data",
+ "ImportBooksProgressNoUpdate": "Books added: {added}.",
+ "ImportBooksProgressWithUpdate": "Books added: {added}, updated: {updated}.",
+ "ImportArticlesProgressNoUpdate": "Articles added: {added}.",
+ "ImportArticlesProgressWithUpdate": "Articles added: {added}, updated: {updated}.",
+ "ImportSuccessful": "Import completed successfully.",
+ "ImportCancelled": "Import has been cancelled by the user.",
+ "DataNotFound": "Couldn't find the data to import.",
+ "InsufficientDiskSpace": "Insufficient disk space.",
+ "ImportError": "An error occurred during the import."
+ }
+ },
+ "ExportPanel": {
+ "Header": "Export search results to a file",
+ "Format": "File Format",
+ "Excel": "Microsoft Excel 2007-2016 (XLSX)",
+ "Csv": "Comma-separated values (CSV)",
+ "Separator": "Separator",
+ "Comma": "Comma",
+ "Semicolon": "Semicolon",
+ "Tab": "Tab character",
+ "SaveAs": "Save as",
+ "Browse": "Browse...",
+ "BrowseDialogTitle": "Export search results",
+ "ExcelFiles": "Microsoft Excel files",
+ "CsvFiles": "CSV files",
+ "TsvFiles": "TSV files",
+ "AllFiles": "All files",
+ "ExportRange": "Export range",
+ "NoLimit": "all",
+ "Limit": "first {count} results only",
+ "Export": "EXPORT",
+ "Cancel": "CANCEL",
+ "SavingFile": "Saving the file.",
+ "RowCountSingleFile": "Exported rows: {rows}.",
+ "RowCountMultipleFiles": "Exported rows: {rows}, files created: {files}.",
+ "ErrorWarningTitle": "Error",
+ "InvalidExportPath": "Invalid export file path.",
+ "DirectoryNotFound": "Directory {directory} doesn't exist.",
+ "InvalidExportFileName": "Invalid export file name.",
+ "OverwritePromptTitle": "Overwrite the file?",
+ "OverwritePromptText": "File {file} already exists. Do you want to overwrite it?",
+ "RowLimitWarningTitle": "Row limit",
+ "RowLimitWarningText": "Microsoft Excel maximum row count has been reached. Export cannot be continued. In order to export more rows please enable \"Split into multiple files\" option in the application settings.",
+ "ExportError": "An error occurred during the export.",
+ "Interrupt": "INTERRUPT",
+ "Interrupting": "INTERRUPTING...",
+ "ExportInterrupted": "Export has been interrupted.",
+ "Results": "OPEN RESULTS",
+ "Close": "CLOSE"
+ },
+ "Exporter": {
+ "Yes": "yes",
+ "No": "no",
+ "Unknown": "unknown",
+ "Portrait": "portrait",
+ "Landscape": "landscape",
+ "NonFictionColumns": {
+ "Id": "ID",
+ "Title": "Title",
+ "Authors": "Authors",
+ "Series": "Series",
+ "Publisher": "Publisher",
+ "Year": "Year",
+ "Language": "Language",
+ "Format": "Format",
+ "Isbn": "ISBN",
+ "Added": "Added",
+ "LastModified": "Last Modified",
+ "Library": "Library",
+ "FileSize": "File Size",
+ "Topics": "Topics",
+ "Volume": "Volume",
+ "Magazine": "Magazine",
+ "City": "City",
+ "Edition": "Edition",
+ "BodyMatterPages": "Pages (Body Matter)",
+ "TotalPages": "Pages (Total)",
+ "Tags": "Tags",
+ "Md5Hash": "MD5 hash",
+ "Comments": "Comments",
+ "LibgenId": "Libgen ID",
+ "Issn": "ISSN",
+ "Udc": "UDC",
+ "Lbc": "LBC",
+ "Lcc": "LCC",
+ "Ddc": "DDC",
+ "Doi": "DOI",
+ "OpenLibraryId": "Open Library ID",
+ "GoogleBookId": "Google Books ID",
+ "Asin": "ASIN",
+ "Dpi": "DPI",
+ "Ocr": "OCR",
+ "TableOfContents": "Table Of Contents",
+ "Scanned": "Scanned",
+ "Orientation": "Orientation",
+ "Paginated": "Paginated",
+ "Colored": "Colored",
+ "Cleaned": "Cleaned"
},
- "Exporter":
- {
- "Yes": "yes",
- "No": "no",
- "Unknown": "unknown",
- "Portrait": "portrait",
- "Landscape": "landscape",
- "NonFictionColumns":
- {
- "Id": "ID",
- "Title": "Title",
- "Authors": "Authors",
- "Series": "Series",
- "Publisher": "Publisher",
- "Year": "Year",
- "Language": "Language",
- "Format": "Format",
- "Isbn": "ISBN",
- "Added": "Added",
- "LastModified": "Last Modified",
- "Library": "Library",
- "FileSize": "File Size",
- "Topics": "Topics",
- "Volume": "Volume",
- "Magazine": "Magazine",
- "City": "City",
- "Edition": "Edition",
- "BodyMatterPages": "Pages (Body Matter)",
- "TotalPages": "Pages (Total)",
- "Tags": "Tags",
- "Md5Hash": "MD5 hash",
- "Comments": "Comments",
- "LibgenId": "Libgen ID",
- "Issn": "ISSN",
- "Udc": "UDC",
- "Lbc": "LBC",
- "Lcc": "LCC",
- "Ddc": "DDC",
- "Doi": "DOI",
- "OpenLibraryId": "Open Library ID",
- "GoogleBookId": "Google Books ID",
- "Asin": "ASIN",
- "Dpi": "DPI",
- "Ocr": "OCR",
- "TableOfContents": "Table Of Contents",
- "Scanned": "Scanned",
- "Orientation": "Orientation",
- "Paginated": "Paginated",
- "Colored": "Colored",
- "Cleaned": "Cleaned"
- },
- "FictionColumns":
- {
- "Id": "ID",
- "Title": "Title",
- "Authors": "Authors",
- "RussianAuthor": "Author in Russian",
- "Series": "Series",
- "Publisher": "Publisher",
- "Edition": "Edition",
- "Year": "Year",
- "Language": "Language",
- "Format": "Format",
- "Pages": "Pages",
- "Version": "Version",
- "FileSize": "File Size",
- "Added": "Added",
- "LastModified": "Last Modified",
- "Md5Hash": "MD5 hash",
- "Comments": "Comments",
- "LibgenId": "Libgen ID",
- "Isbn": "ISBN",
- "GoogleBookId": "Google Books ID",
- "Asin": "ASIN"
- },
- "SciMagColumns":
- {
- "Id": "ID",
- "Title": "Title",
- "Authors": "Authors",
- "Magazine": "Magazine",
- "Year": "Year",
- "Month": "Month",
- "Day": "Day",
- "Volume": "Volume",
- "Issue": "Issue",
- "Pages": "Pages",
- "FileSize": "File Size",
- "AddedDateTime": "Added",
- "Md5Hash": "MD5 hash",
- "AbstractUrl": "Abstract URL",
- "LibgenId": "Libgen ID",
- "Doi1": "DOI 1",
- "Doi2": "DOI 2",
- "Isbn": "ISBN",
- "MagazineId": "Magazine ID",
- "Issnp": "ISSN (p)",
- "Issne": "ISSN (e)",
- "PubmedId": "Pubmed ID",
- "Pmc": "PMC",
- "Pii": "PII",
- "Attribute1": "Attribute 1",
- "Attribute2": "Attribute 2",
- "Attribute3": "Attribute 3",
- "Attribute4": "Attribute 4",
- "Attribute5": "Attribute 5",
- "Attribute6": "Attribute 6"
- }
+ "FictionColumns": {
+ "Id": "ID",
+ "Title": "Title",
+ "Authors": "Authors",
+ "RussianAuthor": "Author in Russian",
+ "Series": "Series",
+ "Publisher": "Publisher",
+ "Edition": "Edition",
+ "Year": "Year",
+ "Language": "Language",
+ "Format": "Format",
+ "Pages": "Pages",
+ "Version": "Version",
+ "FileSize": "File Size",
+ "Added": "Added",
+ "LastModified": "Last Modified",
+ "Md5Hash": "MD5 hash",
+ "Comments": "Comments",
+ "LibgenId": "Libgen ID",
+ "Isbn": "ISBN",
+ "GoogleBookId": "Google Books ID",
+ "Asin": "ASIN"
},
- "Synchronization":
- {
- "WindowTitle": "Non-fiction book list synchronization",
- "ErrorMessageTitle": "Error",
- "ImportRequired": "Non-fiction database dump import needs to be completed in order to start the synchronization.",
- "NoSynchronizationMirror": "No non-fiction book synchronization mirror has been selected.",
- "OfflineModePromptTitle": "Offline mode",
- "OfflineModePromptText": "Synchronization cannot be started while the offline mode is on. Do you want to turn it off?",
- "Elapsed": "Time elapsed: {elapsed}",
- "FreeSpace": "Free space left on device: {freeSpace}",
- "Unknown": "unknown",
- "Interrupt": "INTERRUPT",
- "Interrupting": "INTERRUPTING...",
- "Close": "CLOSE",
- "StatusMessages":
- {
- "Step": "Step {current} of {total}.",
- "Preparation": "Preparing for synchronization",
- "CreatingIndexes": "Creating indexes",
- "LoadingIds": "Loading identifiers",
- "SynchronizingData": "Synchronizing the data",
- "SynchronizationComplete": "Synchronization complete",
- "SynchronizationCancelled": "Synchronization has been cancelled",
- "SynchronizationError": "Synchronization failed"
- },
- "LogMessages":
- {
- "Step": "Step {step}",
- "CreatingIndexes": "Creating missing indexes",
- "CreatingIndexForColumn": "Creating index for {column} column...",
- "LoadingIds": "Loading existing data identifiers",
- "LoadingColumnValues": "Loading data for {column} column...",
- "SynchronizingBookList": "Synchronizing the book list",
- "DownloadingNewBooks": "Downloading new book metadata",
- "SynchronizationProgressNoAddedNoUpdated": "Books downloaded: {downloaded}.",
- "SynchronizationProgressAdded": "Books downloaded: {downloaded}, added: {added}.",
- "SynchronizationProgressUpdated": "Books downloaded: {downloaded}, updated: {updated}.",
- "SynchronizationProgressAddedAndUpdated": "Books downloaded: {downloaded}, added: {added}, updated: {updated}.",
- "SynchronizationSuccessful": "Synchronization completed successfully.",
- "SynchronizationCancelled": "Synchronization has been cancelled by the user.",
- "InsufficientDiskSpace": "Insufficient disk space.",
- "SynchronizationError": "An error occurred during the synchronization: {error}"
- }
+ "SciMagColumns": {
+ "Id": "ID",
+ "Title": "Title",
+ "Authors": "Authors",
+ "Magazine": "Magazine",
+ "Year": "Year",
+ "Month": "Month",
+ "Day": "Day",
+ "Volume": "Volume",
+ "Issue": "Issue",
+ "Pages": "Pages",
+ "FileSize": "File Size",
+ "AddedDateTime": "Added",
+ "Md5Hash": "MD5 hash",
+ "AbstractUrl": "Abstract URL",
+ "LibgenId": "Libgen ID",
+ "Doi1": "DOI 1",
+ "Doi2": "DOI 2",
+ "Isbn": "ISBN",
+ "MagazineId": "Magazine ID",
+ "Issnp": "ISSN (p)",
+ "Issne": "ISSN (e)",
+ "PubmedId": "Pubmed ID",
+ "Pmc": "PMC",
+ "Pii": "PII",
+ "Attribute1": "Attribute 1",
+ "Attribute2": "Attribute 2",
+ "Attribute3": "Attribute 3",
+ "Attribute4": "Attribute 4",
+ "Attribute5": "Attribute 5",
+ "Attribute6": "Attribute 6"
+ }
+ },
+ "Synchronization": {
+ "WindowTitle": "Non-fiction book list synchronization",
+ "ErrorMessageTitle": "Error",
+ "ImportRequired": "Non-fiction database dump import needs to be completed in order to start the synchronization.",
+ "NoSynchronizationMirror": "No non-fiction book synchronization mirror has been selected.",
+ "OfflineModePromptTitle": "Offline mode",
+ "OfflineModePromptText": "Synchronization cannot be started while the offline mode is on. Do you want to turn it off?",
+ "Elapsed": "Time elapsed: {elapsed}",
+ "FreeSpace": "Free space left on device: {freeSpace}",
+ "Unknown": "unknown",
+ "Interrupt": "INTERRUPT",
+ "Interrupting": "INTERRUPTING...",
+ "Close": "CLOSE",
+ "StatusMessages": {
+ "Step": "Step {current} of {total}.",
+ "Preparation": "Preparing for synchronization",
+ "CreatingIndexes": "Creating indexes",
+ "LoadingIds": "Loading identifiers",
+ "SynchronizingData": "Synchronizing the data",
+ "SynchronizationComplete": "Synchronization complete",
+ "SynchronizationCancelled": "Synchronization has been cancelled",
+ "SynchronizationError": "Synchronization failed"
},
- "Library":
- {
- "TabTitle": "Library",
- "ScanNonFiction": "SCAN FOR NON-FICTION BOOKS...",
- "ScanFiction": "SCAN FOR FICTION BOOKS...",
- "ScanSciMag": "SCAN FOR SCIENTIFIC ARTICLES...",
- "BrowseDirectoryDialogTitle": "Scan in...",
- "ScanStarted": "Scan started in {directory}",
- "CreatingIndexes": "Please wait. Creating missing database indexes...",
- "Found": "Found ({count})",
- "AddAll": "ADD ALL FOUND FILES TO THE LIBRARY",
- "Adding": "ADDING FILES TO THE LIBRARY...",
- "Added": "ALL FILES HAVE BEEN ADDED TO THE LIBRARY",
- "NotFound": "Not found ({count})",
- "ScanLog": "Scan log",
- "Error": "error",
- "ScanComplete": "Scan complete. Found: {found}, not found: {notFound}, errors: {errors}.",
- "Columns":
- {
- "File": "File",
- "Authors": "Authors",
- "Title": "Title"
- }
+ "LogMessages": {
+ "Step": "Step {step}",
+ "CreatingIndexes": "Creating missing indexes",
+ "CreatingIndexForColumn": "Creating index for {column} column...",
+ "LoadingIds": "Loading existing data identifiers",
+ "LoadingColumnValues": "Loading data for {column} column...",
+ "SynchronizingBookList": "Synchronizing the book list",
+ "DownloadingNewBooks": "Downloading new book metadata",
+ "SynchronizationProgressNoAddedNoUpdated": "Books downloaded: {downloaded}.",
+ "SynchronizationProgressAdded": "Books downloaded: {downloaded}, added: {added}.",
+ "SynchronizationProgressUpdated": "Books downloaded: {downloaded}, updated: {updated}.",
+ "SynchronizationProgressAddedAndUpdated": "Books downloaded: {downloaded}, added: {added}, updated: {updated}.",
+ "SynchronizationSuccessful": "Synchronization completed successfully.",
+ "SynchronizationCancelled": "Synchronization has been cancelled by the user.",
+ "InsufficientDiskSpace": "Insufficient disk space.",
+ "SynchronizationError": "An error occurred during the synchronization: {error}"
+ }
+ },
+ "Library": {
+ "TabTitle": "Library",
+ "ScanNonFiction": "SCAN FOR NON-FICTION BOOKS...",
+ "ScanFiction": "SCAN FOR FICTION BOOKS...",
+ "ScanSciMag": "SCAN FOR SCIENTIFIC ARTICLES...",
+ "BrowseDirectoryDialogTitle": "Scan in...",
+ "ScanStarted": "Scan started in {directory}",
+ "CreatingIndexes": "Please wait. Creating missing database indexes...",
+ "AddAll": "ADD ALL FOUND FILES TO THE LIBRARY",
+ "Adding": "ADDING FILES TO THE LIBRARY...",
+ "Added": "ALL FILES HAVE BEEN ADDED TO THE LIBRARY",
+ "Found": "Found ({count})",
+ "NotFound": "Not found ({count})",
+ "Errors": "Errors ({count})",
+ "ScanLog": "Scan log",
+ "Error": "error",
+ "ScanComplete": "Scan complete. Found: {found}, not found: {notFound}, errors: {errors}.",
+ "Columns": {
+ "File": "File",
+ "Authors": "Authors",
+ "Title": "Title",
+ "ErrorType": "Error Type",
+ "ErrorDescription": "Error Description"
},
- "Database":
- {
- "WindowTitle": "Database information",
- "CurrentDatabase": "Current database:",
- "NonFiction": "Non-fiction books",
- "Fiction": "Fiction books",
- "SciMagArticles": "Scientific articles",
- "TotalBooks": "Total books",
- "TotalArticles": "Total articles",
- "LastUpdate": "Last update",
+ "ErrorDescriptions": {
+ "DirectoryNotFound": "Directory not found",
+ "DirectoryAccess": "Insufficient access rights to directory",
+ "FileSize": "File size is 0 bytes",
+ "FileNotFound": "File not found",
+ "FilePathTooLong": "File path is too long",
+ "FileAccess": "Insufficient access rights to file",
+ "FileInUse": "File is being used by another process",
+ "IoException": "Unhandled IO exception occured",
+ "MD5HashError": "Error creating MD5 hash for file",
+ "OtherException": "Unhandled exception occured"
+ }
+ },
+ "Database": {
+ "WindowTitle": "Database information",
+ "CurrentDatabase": "Current database:",
+ "NonFiction": "Non-fiction books",
+ "Fiction": "Fiction books",
+ "SciMagArticles": "Scientific articles",
+ "TotalBooks": "Total books",
+ "TotalArticles": "Total articles",
+ "LastUpdate": "Last update",
+ "Never": "never",
+ "IndexesRequiredTitle": "Database indexes",
+ "IndexesRequiredText": "Libgen Desktop needs to create missing database indexes. This operation can take a long time (up to an hour) and cannot be interrupted. Do you want to continue?",
+ "CreatingIndexes": "Please wait. Creating missing database indexes...{new-line}This operation cannot be interrupted.",
+ "ChangeDatabase": "CHANGE DATABASE...",
+ "BrowseDatabaseDialogTitle": "Database file location",
+ "Databases": "Databases",
+ "AllFiles": "All files",
+ "Error": "Error",
+ "CannotOpenDatabase": "An error occurred while trying to open database file: {file}",
+ "Close": "CLOSE"
+ },
+ "SqlDebugger": {
+ "WindowTitle": "SQL debugger",
+ "SqlQueryTextBoxHeader": "Enter SQL query",
+ "Copy": "COPY TO CLIPBOARD",
+ "Close": "CLOSE"
+ },
+ "DownloadManager": {
+ "TabTitle": "Downloads",
+ "Start": "START",
+ "Stop": "STOP",
+ "Remove": "REMOVE",
+ "StartAll": "START ALL",
+ "StopAll": "STOP ALL",
+ "RemoveCompleted": "REMOVE COMPLETED",
+ "QueuedStatus": "Queued",
+ "DownloadingStatus": "Downloading",
+ "StoppedStatus": "Stopped",
+ "RetryDelayStatus": "Retry delay",
+ "ErrorStatus": "Error",
+ "DownloadProgressKnownFileSize": "Downloaded {downloaded} of {total} bytes ({percent}%)",
+ "DownloadProgressUnknownFileSize": "Downloaded {downloaded} bytes of unknown",
+ "Log": "Log",
+ "TechnicalDetails": "Technical details",
+ "Copy": "Copy to clipboard",
+ "FileNotFoundErrorTitle": "Error",
+ "FileNotFoundErrorText": "File {file} not found.",
+ "LogMessages": {
+ "Queued": "Added to the download queue.",
+ "Started": "Started.",
+ "Stopped": "Stopped.",
+ "RetryDelay": "Delay {count} seconds...",
+ "Completed": "Download complete.",
+ "OfflineModeIsOn": "Offline mode is on.",
+ "TransformationError": "Transformation {transformation} failed.",
+ "TransformationReturnedIncorrectUrl": "Transformation {transformation} returned an invalid URL.",
+ "Attempt": "Attempt {current} of {total}.",
+ "MaximumDownloadAttempts": "Maximum download attempts have been reached.",
+ "DownloadingPage": "Downloading page: {url}",
+ "DownloadingFile": "Downloading file: {url}",
+ "StartingFileDownloadKnownFileSize": "File download started, file size: {size} bytes.",
+ "StartingFileDownloadUnknownFileSize": "File download started, file size: unknown.",
+ "ResumingFileDownloadKnownFileSize": "File download resumed, remaining size: {remaining} bytes.",
+ "ResumingFileDownloadUnknownFileSize": "File download resumed, remaining size: unknown.",
+ "Request": "Request",
+ "Response": "Server response",
+ "Redirect": "Redirect to {url}",
+ "TooManyRedirects": "Too many redirect responses have been received from the server.",
+ "NonSuccessfulStatusCode": "Server returned: {status}.",
+ "CannotCreateDownloadDirectory": "Couldn't create directory {directory}",
+ "CannotCreateOrOpenFile": "Couldn't create or open file {file}",
+ "CannotRenamePartFile": "Couldn't rename file {source} to {destination}.",
+ "HtmlPageReturned": "Server returned HTML page instead of the file.",
+ "NoPartialDownloadSupport": "Server doesn't support partial downloads.",
+ "NoContentLengthWarning": "Warning: server did not provide the file size.",
+ "ServerResponseTimeout": "Server response timeout.",
+ "DownloadIncompleteError": "Server indicates that file download is complete, but it is not.",
+ "FileWriteError": "File write error.",
+ "LogLineRequestError": "Couldn't send request to {url}",
+ "IncorrectRedirectUrl": "Server returned incorrect redirect URL: {url}",
+ "UnexpectedError": "An unexpected error occurred: {error}"
+ }
+ },
+ "ApplicationUpdate": {
+ "WindowTitle": "Application update",
+ "UpdateAvailable": "New version of Libgen Desktop is available",
+ "NewVersion": "New version: {version} released on {date}",
+ "Download": "DOWNLOAD",
+ "DownloadAndInstall": "DOWNLOAD AND INSTALL",
+ "SkipThisVersion": "SKIP THIS VERSION",
+ "Cancel": "CANCEL",
+ "Interrupt": "INTERRUPT",
+ "Interrupting": "INTERRUPTING...",
+ "InterruptPromptTitle": "Cancel the download?",
+ "InterruptPromptText": "Do you want to cancel downloading the update?",
+ "Error": "Error",
+ "IncompleteDownload": "Update download is not complete.",
+ "Close": "CLOSE"
+ },
+ "Settings": {
+ "WindowTitle": "Settings",
+ "Ok": "OK",
+ "Cancel": "CANCEL",
+ "DiscardChangesPromptTitle": "Discard changes?",
+ "DiscardChangesPromptText": "Settings have been changed. Are you sure to discard the changes?",
+ "General": {
+ "TabHeader": "General",
+ "Language": "Language",
+ "CheckUpdates": "Check for the application updates",
+ "UpdateCheckIntervals": {
"Never": "never",
- "IndexesRequiredTitle": "Database indexes",
- "IndexesRequiredText": "Libgen Desktop needs to create missing database indexes. This operation can take a long time (up to an hour) and cannot be interrupted. Do you want to continue?",
- "CreatingIndexes": "Please wait. Creating missing database indexes...{new-line}This operation cannot be interrupted.",
- "ChangeDatabase": "CHANGE DATABASE...",
- "BrowseDatabaseDialogTitle": "Database file location",
- "Databases": "Databases",
- "AllFiles": "All files",
- "Error": "Error",
- "CannotOpenDatabase": "An error occurred while trying to open database file: {file}",
- "Close": "CLOSE"
- },
- "SqlDebugger":
- {
- "WindowTitle": "SQL debugger",
- "SqlQueryTextBoxHeader": "Enter SQL query",
- "Copy": "COPY TO CLIPBOARD",
- "Close": "CLOSE"
+ "Daily": "daily",
+ "Weekly": "weekly",
+ "Monthly": "monthly"
+ }
},
- "DownloadManager":
- {
- "TabTitle": "Downloads",
- "Start": "START",
- "Stop": "STOP",
- "Remove": "REMOVE",
- "StartAll": "START ALL",
- "StopAll": "STOP ALL",
- "RemoveCompleted": "REMOVE COMPLETED",
- "QueuedStatus": "Queued",
- "DownloadingStatus": "Downloading",
- "StoppedStatus": "Stopped",
- "RetryDelayStatus": "Retry delay",
- "ErrorStatus": "Error",
- "DownloadProgressKnownFileSize": "Downloaded {downloaded} of {total} bytes ({percent}%)",
- "DownloadProgressUnknownFileSize": "Downloaded {downloaded} bytes of unknown",
- "Log": "Log",
- "TechnicalDetails": "Technical details",
- "Copy": "Copy to clipboard",
- "FileNotFoundErrorTitle": "Error",
- "FileNotFoundErrorText": "File {file} not found.",
- "LogMessages":
- {
- "Queued": "Added to the download queue.",
- "Started": "Started.",
- "Stopped": "Stopped.",
- "RetryDelay": "Delay {count} seconds...",
- "Completed": "Download complete.",
- "OfflineModeIsOn": "Offline mode is on.",
- "TransformationError": "Transformation {transformation} failed.",
- "TransformationReturnedIncorrectUrl": "Transformation {transformation} returned an invalid URL.",
- "Attempt": "Attempt {current} of {total}.",
- "MaximumDownloadAttempts": "Maximum download attempts have been reached.",
- "DownloadingPage": "Downloading page: {url}",
- "DownloadingFile": "Downloading file: {url}",
- "StartingFileDownloadKnownFileSize": "File download started, file size: {size} bytes.",
- "StartingFileDownloadUnknownFileSize": "File download started, file size: unknown.",
- "ResumingFileDownloadKnownFileSize": "File download resumed, remaining size: {remaining} bytes.",
- "ResumingFileDownloadUnknownFileSize": "File download resumed, remaining size: unknown.",
- "Request": "Request",
- "Response": "Server response",
- "Redirect": "Redirect to {url}",
- "TooManyRedirects": "Too many redirect responses have been received from the server.",
- "NonSuccessfulStatusCode": "Server returned: {status}.",
- "CannotCreateDownloadDirectory": "Couldn't create directory {directory}",
- "CannotCreateOrOpenFile": "Couldn't create or open file {file}",
- "CannotRenamePartFile": "Couldn't rename file {source} to {destination}.",
- "HtmlPageReturned": "Server returned HTML page instead of the file.",
- "NoPartialDownloadSupport": "Server doesn't support partial downloads.",
- "NoContentLengthWarning": "Warning: server did not provide the file size.",
- "ServerResponseTimeout": "Server response timeout.",
- "DownloadIncompleteError": "Server indicates that file download is complete, but it is not.",
- "FileWriteError": "File write error.",
- "LogLineRequestError": "Couldn't send request to {url}",
- "IncorrectRedirectUrl": "Server returned incorrect redirect URL: {url}",
- "UnexpectedError": "An unexpected error occurred: {error}"
- }
+ "Network": {
+ "TabHeader": "Network",
+ "OfflineMode": "Offline mode",
+ "UseHttpProxy": "Use HTTP proxy",
+ "ProxyAddress": "Address",
+ "ProxyAddressRequired": "Required field",
+ "ProxyPort": "Port",
+ "ProxyPortValidation": "Numbers from {min} to {max}",
+ "ProxyUserName": "User name",
+ "ProxyPassword": "Password",
+ "ProxyPasswordWarning": "Storing the password here is insecure."
},
- "ApplicationUpdate":
- {
- "WindowTitle": "Application update",
- "UpdateAvailable": "New version of Libgen Desktop is available",
- "NewVersion": "New version: {version} released on {date}",
- "Download": "DOWNLOAD",
- "DownloadAndInstall": "DOWNLOAD AND INSTALL",
- "SkipThisVersion": "SKIP THIS VERSION",
- "Cancel": "CANCEL",
- "Interrupt": "INTERRUPT",
- "Interrupting": "INTERRUPTING...",
- "InterruptPromptTitle": "Cancel the download?",
- "InterruptPromptText": "Do you want to cancel downloading the update?",
- "Error": "Error",
- "IncompleteDownload": "Update download is not complete.",
- "Close": "CLOSE"
+ "Download": {
+ "TabHeader": "Downloads",
+ "DownloadMode": "Download mode",
+ "OpenInBrowser": "open download URL in the browser",
+ "UseDownloadManager": "use internal download manager",
+ "DownloadDirectory": "Download into",
+ "BrowseDirectoryDialogTitle": "Download directory",
+ "DownloadDirectoryNotFound": "Directory doesn't exist",
+ "Timeout": "Download timeout",
+ "TimeoutValidation": "Numbers: {min} — {max}",
+ "Seconds": "seconds",
+ "DownloadAttempts": "Download attempts",
+ "DownloadAttemptsValidation": "Numbers: {min} — {max}",
+ "Times": "times",
+ "RetryDelay": "Download retry delay",
+ "RetryDelayValidation": "Numbers: {min} — {max}"
},
- "Settings":
- {
- "WindowTitle": "Settings",
- "Ok": "OK",
- "Cancel": "CANCEL",
- "DiscardChangesPromptTitle": "Discard changes?",
- "DiscardChangesPromptText": "Settings have been changed. Are you sure to discard the changes?",
- "General":
- {
- "TabHeader": "General",
- "Language": "Language",
- "CheckUpdates": "Check for the application updates",
- "UpdateCheckIntervals":
- {
- "Never": "never",
- "Daily": "daily",
- "Weekly": "weekly",
- "Monthly": "monthly"
- }
- },
- "Network":
- {
- "TabHeader": "Network",
- "OfflineMode": "Offline mode",
- "UseHttpProxy": "Use HTTP proxy",
- "ProxyAddress": "Address",
- "ProxyAddressRequired": "Required field",
- "ProxyPort": "Port",
- "ProxyPortValidation": "Numbers from {min} to {max}",
- "ProxyUserName": "User name",
- "ProxyPassword": "Password",
- "ProxyPasswordWarning": "Storing the password here is insecure."
- },
- "Download":
- {
- "TabHeader": "Downloads",
- "DownloadMode": "Download mode",
- "OpenInBrowser": "open download URL in the browser",
- "UseDownloadManager": "use internal download manager",
- "DownloadDirectory": "Download into",
- "BrowseDirectoryDialogTitle": "Download directory",
- "DownloadDirectoryNotFound": "Directory doesn't exist",
- "Timeout": "Download timeout",
- "TimeoutValidation": "Numbers: {min} — {max}",
- "Seconds": "seconds",
- "DownloadAttempts": "Download attempts",
- "DownloadAttemptsValidation": "Numbers: {min} — {max}",
- "Times": "times",
- "RetryDelay": "Download retry delay",
- "RetryDelayValidation": "Numbers: {min} — {max}"
- },
- "Mirrors":
- {
- "TabHeader": "Mirrors",
- "NonFiction": "Non-fiction books",
- "Fiction": "Fiction books",
- "SciMagArticles": "Scientific articles",
- "Books": "Books",
- "Articles": "Articles",
- "Covers": "Covers",
- "Synchronization": "Synchronization",
- "NoMirror": "no mirror"
- },
- "Search":
- {
- "TabHeader": "Search",
- "LimitResults": "Limit search results",
- "MaximumResults": "Maximum result count",
- "PositiveNumbersOnly": "Positive numbers only",
- "OpenDetails": "Open book / article details:",
- "InModalWindow": "in a modal window",
- "InNonModalWindow": "in a non-modal window",
- "InNewTab": "in a new tab"
- },
- "Export":
- {
- "TabHeader": "Export",
- "OpenResults": "Open results after the export",
- "SplitIntoMultipleFiles": "Split into multiple files",
- "MaximumRowsPerFile": "Maximum rows per file",
- "MaximumRowsPerFileValidation": "Numbers from {min} to {max}",
- "ExcelLimitNote": "Note: Microsoft Excel doesn't support files with more than {count} rows."
- },
- "Advanced":
- {
- "TabHeader": "Advanced",
- "UseLogging": "Write diagnostic information into a file",
- "EnableSqlDebugger": "Enable SQL debugger"
- }
+ "Mirrors": {
+ "TabHeader": "Mirrors",
+ "NonFiction": "Non-fiction books",
+ "Fiction": "Fiction books",
+ "SciMagArticles": "Scientific articles",
+ "Books": "Books",
+ "Articles": "Articles",
+ "Covers": "Covers",
+ "Synchronization": "Synchronization",
+ "NoMirror": "no mirror"
},
- "About":
- {
- "WindowTitle": "About Libgen Desktop",
- "ApplicationName": "Libgen Desktop",
- "Version": "Current version: {version} released on {date}",
- "CheckForUpdates": "CHECK FOR UPDATES",
- "CheckingUpdates": "CHECKING UPDATES...",
- "OfflineModeIsOnTooltip": "Offline mode is on",
- "LatestVersion": "You are using the latest version.",
- "NewVersionAvailable": "New version is available: {version} released on {date}",
- "Update": "UPDATE",
- "Translators": "Translators:"
+ "Search": {
+ "TabHeader": "Search",
+ "LimitResults": "Limit search results",
+ "MaximumResults": "Maximum result count",
+ "PositiveNumbersOnly": "Positive numbers only",
+ "OpenDetails": "Open book / article details:",
+ "InModalWindow": "in a modal window",
+ "InNonModalWindow": "in a non-modal window",
+ "InNewTab": "in a new tab"
},
- "MessageBox":
- {
- "Ok": "OK",
- "Yes": "YES",
- "No": "NO"
+ "Export": {
+ "TabHeader": "Export",
+ "OpenResults": "Open results after the export",
+ "SplitIntoMultipleFiles": "Split into multiple files",
+ "MaximumRowsPerFile": "Maximum rows per file",
+ "MaximumRowsPerFileValidation": "Numbers from {min} to {max}",
+ "ExcelLimitNote": "Note: Microsoft Excel doesn't support files with more than {count} rows."
},
- "ErrorWindow":
- {
- "WindowTitle": "Error",
- "UnexpectedError": "An unexpected error occurred",
- "Copy": "COPY TO CLIPBOARD",
- "Close": "CLOSE"
+ "Advanced": {
+ "TabHeader": "Advanced",
+ "UseLogging": "Write diagnostic information into a file",
+ "EnableSqlDebugger": "Enable SQL debugger"
}
+ },
+ "About": {
+ "WindowTitle": "About Libgen Desktop",
+ "ApplicationName": "Libgen Desktop",
+ "Version": "Current version: {version} released on {date}",
+ "CheckForUpdates": "CHECK FOR UPDATES",
+ "CheckingUpdates": "CHECKING UPDATES...",
+ "OfflineModeIsOnTooltip": "Offline mode is on",
+ "LatestVersion": "You are using the latest version.",
+ "NewVersionAvailable": "New version is available: {version} released on {date}",
+ "Update": "UPDATE",
+ "Translators": "Translators:"
+ },
+ "MessageBox": {
+ "Ok": "OK",
+ "Yes": "YES",
+ "No": "NO"
+ },
+ "ErrorWindow": {
+ "WindowTitle": "Error",
+ "UnexpectedError": "An unexpected error occurred",
+ "Copy": "COPY TO CLIPBOARD",
+ "Close": "CLOSE"
+ }
}
diff --git a/LibgenDesktop/ViewModels/Library/ScanResultErrorItemViewModel.cs b/LibgenDesktop/ViewModels/Library/ScanResultErrorItemViewModel.cs
new file mode 100644
index 0000000..da9624a
--- /dev/null
+++ b/LibgenDesktop/ViewModels/Library/ScanResultErrorItemViewModel.cs
@@ -0,0 +1,17 @@
+using LibgenDesktop.Models.ProgressArgs;
+
+namespace LibgenDesktop.ViewModels.Library
+{
+ internal class ScanResultErrorItemViewModel : ViewModel
+ {
+ public ScanResultErrorItemViewModel(string relativeFilePath, ErrorTypes errorTypes)
+ {
+ RelativeFilePath = relativeFilePath;
+ ErrorType = errorTypes;
+ }
+
+ public ErrorTypes ErrorType { get; }
+ public string RelativeFilePath { get; }
+ public string Description { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/LibgenDesktop/ViewModels/Tabs/LibraryTabViewModel.cs b/LibgenDesktop/ViewModels/Tabs/LibraryTabViewModel.cs
index 036ba31..33ed490 100644
--- a/LibgenDesktop/ViewModels/Tabs/LibraryTabViewModel.cs
+++ b/LibgenDesktop/ViewModels/Tabs/LibraryTabViewModel.cs
@@ -30,6 +30,7 @@ private enum Mode
private bool isResultsPanelVisible;
private string foundTabHeaderTitle;
private string notFoundTabHeaderTitle;
+ private string errorsTabHeaderTitle;
private bool isScanLogTabSelected;
private bool isAddAllFilesToLibraryButtonVisible;
private bool isAddAllFilesToLibraryButtonEnabled;
@@ -37,6 +38,7 @@ private enum Mode
private ObservableCollection foundItems;
private ScanResultItemViewModel selectedFoundItem;
private ObservableCollection notFoundItems;
+ private ObservableCollection errors;
private ObservableCollection scanLogs;
private string scanDirectory;
private bool hasFilesToAdd;
@@ -121,6 +123,19 @@ public string NotFoundTabHeaderTitle
}
}
+ public string ErrorsTabHeaderTitle
+ {
+ get
+ {
+ return errorsTabHeaderTitle;
+ }
+ set
+ {
+ errorsTabHeaderTitle = value;
+ NotifyPropertyChanged();
+ }
+ }
+
public bool IsScanLogTabSelected
{
get
@@ -212,6 +227,19 @@ public ObservableCollection NotFoundItems
}
}
+ public ObservableCollection Errors
+ {
+ get
+ {
+ return errors;
+ }
+ set
+ {
+ errors = value;
+ NotifyPropertyChanged();
+ }
+ }
+
public ObservableCollection ScanLogs
{
get
@@ -277,6 +305,7 @@ private async void Scan(Func, Task> scanFunction) wh
mode = Mode.SCANNING;
FoundItems = new ObservableCollection();
NotFoundItems = new ObservableCollection();
+ Errors = new ObservableCollection();
UpdateResultTabHeaders();
UpdateAddAllFilesToLibraryButton();
IsScanLogTabSelected = true;
@@ -317,12 +346,15 @@ private void HandleScanProgress(object progress) where T : LibgenObject
FoundItems.Add(new SciMagScanResultItemViewModel(scanProgress.RelativeFilePath, sciMagArticle));
break;
}
- UpdateResultTabHeaders();
+ UpdateResultTabHeaders();
break;
case ScanUnknownProgress scanUnknownProgress:
if (scanUnknownProgress.Error)
{
- ScanLogs.Add($"{scanUnknownProgress.RelativeFilePath} — {Localization.Error}.");
+ var error = new ScanResultErrorItemViewModel(scanUnknownProgress.RelativeFilePath, scanUnknownProgress.ErrorType);
+ ResolveErrorDescription(error);
+ Errors.Add(error);
+ UpdateResultTabHeaders();
}
else
{
@@ -346,6 +378,16 @@ private void UpdateResultTabHeaders()
{
NotFoundTabHeaderTitle = Localization.GetNotFoundString(NotFoundItems.Count);
}
+ if (Errors != null)
+ {
+ ErrorsTabHeaderTitle = Localization.GetErrorsString(Errors.Count);
+ }
+ }
+
+ private void ResolveErrorDescription(ScanResultErrorItemViewModel error)
+ {
+ if (Errors == null || error == null) return;
+ error.Description = Localization.GetErrorDescription(error.ErrorType);
}
private void UpdateAddAllFilesToLibraryButton()
diff --git a/LibgenDesktop/Views/Tabs/LibraryTab.xaml b/LibgenDesktop/Views/Tabs/LibraryTab.xaml
index 8628ef4..f28fec6 100644
--- a/LibgenDesktop/Views/Tabs/LibraryTab.xaml
+++ b/LibgenDesktop/Views/Tabs/LibraryTab.xaml
@@ -95,6 +95,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/LibgenDesktop/packages.config b/LibgenDesktop/packages.config
index 85bade8..709ce1e 100644
--- a/LibgenDesktop/packages.config
+++ b/LibgenDesktop/packages.config
@@ -9,7 +9,6 @@
-
\ No newline at end of file