diff --git a/API/Parser/Parser.cs b/API/Parser/Parser.cs
index 914508f9f..6b5a79b4b 100644
--- a/API/Parser/Parser.cs
+++ b/API/Parser/Parser.cs
@@ -16,6 +16,7 @@ namespace API.Parser
public const string ImageFileExtensions = @"^(\.png|\.jpeg|\.jpg)";
public const string ArchiveFileExtensions = @"\.cbz|\.zip|\.rar|\.cbr|\.tar.gz|\.7zip|\.7z|\.cb7|\.cbt";
public const string BookFileExtensions = @"\.epub|\.pdf";
+ public const string MacOsMetadataFileStartsWith = @"._";
public const string SupportedExtensions =
ArchiveFileExtensions + "|" + ImageFileExtensions + "|" + BookFileExtensions;
diff --git a/API/Services/ArchiveService.cs b/API/Services/ArchiveService.cs
index a03188a5d..36eded36b 100644
--- a/API/Services/ArchiveService.cs
+++ b/API/Services/ArchiveService.cs
@@ -117,7 +117,8 @@ namespace API.Services
{
var result = entryFullNames
.FirstOrDefault(x => !Path.EndsInDirectorySeparator(x) && !Parser.Parser.HasBlacklistedFolderInPath(x)
- && Parser.Parser.IsCoverImage(x));
+ && Parser.Parser.IsCoverImage(x)
+ && !x.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith));
return string.IsNullOrEmpty(result) ? null : result;
}
@@ -131,7 +132,8 @@ namespace API.Services
{
var result = entryFullNames.OrderBy(Path.GetFileName, _comparer)
.FirstOrDefault(x => !Parser.Parser.HasBlacklistedFolderInPath(x)
- && Parser.Parser.IsImage(x));
+ && Parser.Parser.IsImage(x)
+ && !x.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith));
return string.IsNullOrEmpty(result) ? null : result;
}
@@ -295,7 +297,11 @@ namespace API.Services
{
foreach (var entry in entries)
{
- if (Path.GetFileNameWithoutExtension(entry.Key).ToLower().EndsWith("comicinfo") && !Parser.Parser.HasBlacklistedFolderInPath(entry.Key) && Parser.Parser.IsXml(entry.Key))
+ var filename = Path.GetFileNameWithoutExtension(entry.Key).ToLower();
+ if (filename.EndsWith("comicinfo")
+ && !filename.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith)
+ && !Parser.Parser.HasBlacklistedFolderInPath(entry.Key)
+ && Parser.Parser.IsXml(entry.Key))
{
using var ms = StreamManager.GetStream();
entry.WriteTo(ms);
@@ -328,7 +334,10 @@ namespace API.Services
{
_logger.LogDebug("Using default compression handling");
using var archive = ZipFile.OpenRead(archivePath);
- var entry = archive.Entries.SingleOrDefault(x => !Parser.Parser.HasBlacklistedFolderInPath(x.FullName) && Path.GetFileNameWithoutExtension(x.Name).ToLower() == "comicinfo" && Parser.Parser.IsXml(x.FullName));
+ var entry = archive.Entries.SingleOrDefault(x => !Parser.Parser.HasBlacklistedFolderInPath(x.FullName)
+ && Path.GetFileNameWithoutExtension(x.Name).ToLower() == "comicinfo"
+ && !Path.GetFileNameWithoutExtension(x.Name).StartsWith(Parser.Parser.MacOsMetadataFileStartsWith)
+ && Parser.Parser.IsXml(x.FullName));
if (entry != null)
{
using var stream = entry.Open();
@@ -343,6 +352,7 @@ namespace API.Services
using var archive = ArchiveFactory.Open(archivePath);
info = FindComicInfoXml(archive.Entries.Where(entry => !entry.IsDirectory
&& !Parser.Parser.HasBlacklistedFolderInPath(Path.GetDirectoryName(entry.Key) ?? string.Empty)
+ && !Path.GetFileNameWithoutExtension(entry.Key).StartsWith(Parser.Parser.MacOsMetadataFileStartsWith)
&& Parser.Parser.IsXml(entry.Key)));
break;
}
diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs
index d0e5cce84..80156bd2a 100644
--- a/API/Services/DirectoryService.cs
+++ b/API/Services/DirectoryService.cs
@@ -25,6 +25,7 @@ namespace API.Services
///
/// Given a set of regex search criteria, get files in the given path.
///
+ /// This will always exclude patterns
/// Directory to search
/// Regex version of search pattern (ie \.mp3|\.mp4). Defaults to * meaning all files.
/// SearchOption to use, defaults to TopDirectoryOnly
@@ -35,9 +36,10 @@ namespace API.Services
{
if (!Directory.Exists(path)) return ImmutableList.Empty;
var reSearchPattern = new Regex(searchPatternExpression, RegexOptions.IgnoreCase);
+
return Directory.EnumerateFiles(path, "*", searchOption)
.Where(file =>
- reSearchPattern.IsMatch(Path.GetExtension(file)));
+ reSearchPattern.IsMatch(Path.GetExtension(file)) && !Path.GetFileName(file).StartsWith(Parser.Parser.MacOsMetadataFileStartsWith));
}
@@ -98,7 +100,7 @@ namespace API.Services
var reSearchPattern = new Regex(searchPatternExpression, RegexOptions.IgnoreCase);
return Directory.EnumerateFiles(path, "*", searchOption)
.Where(file =>
- reSearchPattern.IsMatch(file));
+ reSearchPattern.IsMatch(file) && !file.StartsWith(Parser.Parser.MacOsMetadataFileStartsWith));
}
return !Directory.Exists(path) ? Array.Empty() : Directory.GetFiles(path);
diff --git a/Kavita.Common/Kavita.Common.csproj b/Kavita.Common/Kavita.Common.csproj
index dd2a776da..b24530f56 100644
--- a/Kavita.Common/Kavita.Common.csproj
+++ b/Kavita.Common/Kavita.Common.csproj
@@ -4,7 +4,7 @@
net5.0
kavitareader.com
Kavita
- 0.4.3.3
+ 0.4.3.4
en