diff --git a/API.Tests/ParserTest.cs b/API.Tests/ParserTest.cs
index eaebc727a..d551c6393 100644
--- a/API.Tests/ParserTest.cs
+++ b/API.Tests/ParserTest.cs
@@ -19,8 +19,7 @@ namespace API.Tests
[InlineData("[Suihei Kiki]_Kasumi_Otoko_no_Ko_[Taruby]_v1.1.zip", "1")]
public void ParseVolumeTest(string filename, string expected)
{
- var result = ParseVolume(filename);
- Assert.Equal(expected, result);
+ Assert.Equal(expected, ParseVolume(filename));
}
[Theory]
@@ -36,8 +35,7 @@ namespace API.Tests
[InlineData("Akame ga KILL! ZERO (2016-2019) (Digital) (LuCaZ)", "Akame ga KILL! ZERO")]
public void ParseSeriesTest(string filename, string expected)
{
- var result = ParseSeries(filename);
- Assert.Equal(expected, result);
+ Assert.Equal(expected, ParseSeries(filename));
}
[Theory]
@@ -53,8 +51,7 @@ namespace API.Tests
[InlineData("Adding volume 1 with File: Ana Satsujin Vol. 1 Ch. 5 - Manga Box (gb).cbz", "5")]
public void ParseChaptersTest(string filename, string expected)
{
- var result = ParseChapter(filename);
- Assert.Equal(expected, result);
+ Assert.Equal(expected, ParseChapter(filename));
}
@@ -91,6 +88,7 @@ namespace API.Tests
[InlineData("test.cbr", true)]
[InlineData("test.zip", true)]
[InlineData("test.rar", true)]
+ [InlineData("test.rar.!qb", false)]
public void IsArchiveTest(string input, bool expected)
{
Assert.Equal(expected, IsArchive(input));
diff --git a/API/Comparators/StringLogicalComparer.cs b/API/Comparators/StringLogicalComparer.cs
index 957921c4c..f6a8c1249 100644
--- a/API/Comparators/StringLogicalComparer.cs
+++ b/API/Comparators/StringLogicalComparer.cs
@@ -30,7 +30,7 @@ namespace API.Comparators
{
bool c1 = Char.IsDigit(s1, i1);
bool c2 = Char.IsDigit(s2, i2);
- var r = 0; // temp result
+ int r; // temp result
if(!c1 && !c2)
{
bool letter1 = Char.IsLetter(s1, i1);
diff --git a/API/Controllers/ReaderController.cs b/API/Controllers/ReaderController.cs
index b19daddb5..17a5d753d 100644
--- a/API/Controllers/ReaderController.cs
+++ b/API/Controllers/ReaderController.cs
@@ -1,7 +1,5 @@
-using System.Linq;
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using API.DTOs;
-using API.Entities;
using API.Interfaces;
using Microsoft.AspNetCore.Mvc;
diff --git a/API/Extensions/DirectoryInfoExtensions.cs b/API/Extensions/DirectoryInfoExtensions.cs
index ab5766962..257b7c045 100644
--- a/API/Extensions/DirectoryInfoExtensions.cs
+++ b/API/Extensions/DirectoryInfoExtensions.cs
@@ -1,11 +1,65 @@
-namespace API.Extensions
+using System;
+using System.IO;
+
+namespace API.Extensions
{
public static class DirectoryInfoExtensions
{
- public static void Empty(this System.IO.DirectoryInfo directory)
+ public static void Empty(this DirectoryInfo directory)
{
- foreach(System.IO.FileInfo file in directory.EnumerateFiles()) file.Delete();
- foreach(System.IO.DirectoryInfo subDirectory in directory.EnumerateDirectories()) subDirectory.Delete(true);
+ foreach(FileInfo file in directory.EnumerateFiles()) file.Delete();
+ foreach(DirectoryInfo subDirectory in directory.EnumerateDirectories()) subDirectory.Delete(true);
+ }
+
+ ///
+ /// Flattens all files in subfolders to the passed directory recursively.
+ ///
+ ///
+ /// foo
+ /// ├── 1.txt
+ /// ├── 2.txt
+ /// ├── 3.txt
+ /// ├── 4.txt
+ /// └── bar
+ /// ├── 1.txt
+ /// ├── 2.txt
+ /// └── 5.txt
+ ///
+ /// becomes:
+ /// foo
+ /// ├── 1.txt
+ /// ├── 2.txt
+ /// ├── 3.txt
+ /// ├── 4.txt
+ /// ├── bar_1.txt
+ /// ├── bar_2.txt
+ /// └── bar_5.txt
+ ///
+ ///
+ public static void Flatten(this DirectoryInfo directory)
+ {
+ FlattenDirectory(directory, directory);
+ }
+
+ private static void FlattenDirectory(DirectoryInfo root, DirectoryInfo directory)
+ {
+ if (!root.FullName.Equals(directory.FullName)) // I might be able to replace this with root === directory
+ {
+ foreach (var file in directory.EnumerateFiles())
+ {
+ if (file.Directory == null) continue;
+ var newName = $"{file.Directory.Name}_{file.Name}";
+ var newPath = Path.Join(root.FullName, newName);
+ Console.WriteLine($"Renaming/Moving file to: {newPath}");
+ file.MoveTo(newPath);
+
+ }
+ }
+
+ foreach (var subDirectory in directory.EnumerateDirectories())
+ {
+ FlattenDirectory(root, subDirectory);
+ }
}
}
}
\ No newline at end of file
diff --git a/API/Interfaces/IDirectoryService.cs b/API/Interfaces/IDirectoryService.cs
index beeb7cfd0..9592292c4 100644
--- a/API/Interfaces/IDirectoryService.cs
+++ b/API/Interfaces/IDirectoryService.cs
@@ -4,7 +4,6 @@ using API.DTOs;
namespace API.Interfaces
{
- // TODO: Refactor this into IDiskService to encapsulate all disk based IO
public interface IDirectoryService
{
///
diff --git a/API/Services/CacheService.cs b/API/Services/CacheService.cs
index 1a78f1293..a6372bb1f 100644
--- a/API/Services/CacheService.cs
+++ b/API/Services/CacheService.cs
@@ -42,7 +42,7 @@ namespace API.Services
foreach (var file in volume.Files)
{
var extractPath = GetVolumeCachePath(volumeId, file);
-
+
_directoryService.ExtractArchive(file.FilePath, extractPath);
}
diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs
index 7081d1b49..02358862c 100644
--- a/API/Services/DirectoryService.cs
+++ b/API/Services/DirectoryService.cs
@@ -137,6 +137,7 @@ namespace API.Services
{
FilePath = info.FullFilePath,
Chapter = chapter,
+ Format = info.Format,
NumberOfPages = GetNumberOfPagesFromArchive(info.FullFilePath)
};
}
@@ -284,7 +285,13 @@ namespace API.Services
return Path.Join(Directory.GetCurrentDirectory(), $"../cache/{volumeId}/");
}
- public string ExtractArchive(string archivePath, int volumeId)
+ ///
+ /// TODO: Delete this method
+ ///
+ ///
+ ///
+ ///
+ private string ExtractArchive(string archivePath, int volumeId)
{
if (!File.Exists(archivePath) || !Parser.Parser.IsArchive(archivePath))
{
@@ -302,10 +309,18 @@ namespace API.Services
using ZipArchive archive = ZipFile.OpenRead(archivePath);
- if (!archive.HasFiles()) return "";
-
+ // TODO: Throw error if we couldn't extract
+ var needsFlattening = archive.Entries.Count > 0 && !Path.HasExtension(archive.Entries.ElementAt(0).FullName);
+ if (!archive.HasFiles() && !needsFlattening) return "";
+
archive.ExtractToDirectory(extractPath);
_logger.LogInformation($"Extracting archive to {extractPath}");
+
+ if (needsFlattening)
+ {
+ _logger.LogInformation("Extracted archive is nested in root folder, flattening...");
+ new DirectoryInfo(extractPath).Flatten();
+ }
return extractPath;
}
@@ -325,12 +340,18 @@ namespace API.Services
}
using ZipArchive archive = ZipFile.OpenRead(archivePath);
-
- if (!archive.HasFiles()) return "";
+ // TODO: Throw error if we couldn't extract
+ var needsFlattening = archive.Entries.Count > 0 && !Path.HasExtension(archive.Entries.ElementAt(0).FullName);
+ if (!archive.HasFiles() && !needsFlattening) return "";
archive.ExtractToDirectory(extractPath);
_logger.LogDebug($"Extracting archive to {extractPath}");
+ if (!needsFlattening) return extractPath;
+
+ _logger.LogInformation("Extracted archive is nested in root folder, flattening...");
+ new DirectoryInfo(extractPath).Flatten();
+
return extractPath;
}
@@ -343,7 +364,6 @@ namespace API.Services
}
using ZipArchive archive = ZipFile.OpenRead(archivePath);
- Console.WriteLine();
return archive.Entries.Count(e => Parser.Parser.IsImage(e.FullName));
}