Improved performance calculating "liberated" status
This commit is contained in:
parent
d5d72a13f6
commit
1375da2065
12 changed files with 92 additions and 194 deletions
|
|
@ -2,7 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.RegularExpressions;
|
||||
using Dinah.Core;
|
||||
using Dinah.Core.Collections.Generic;
|
||||
|
||||
|
|
@ -21,23 +21,6 @@ namespace FileManager
|
|||
public sealed class AudibleFileStorage : Enumeration<AudibleFileStorage>
|
||||
{
|
||||
#region static
|
||||
// centralize filetype mappings to ensure uniqueness
|
||||
private static Dictionary<string, FileType> extensionMap => new Dictionary<string, FileType>
|
||||
{
|
||||
[".m4b"] = FileType.Audio,
|
||||
[".mp3"] = FileType.Audio,
|
||||
[".aac"] = FileType.Audio,
|
||||
[".mp4"] = FileType.Audio,
|
||||
[".m4a"] = FileType.Audio,
|
||||
[".ogg"] = FileType.Audio,
|
||||
[".flac"] = FileType.Audio,
|
||||
|
||||
[".aax"] = FileType.AAX,
|
||||
|
||||
[".pdf"] = FileType.PDF,
|
||||
[".zip"] = FileType.PDF,
|
||||
};
|
||||
|
||||
public static AudibleFileStorage Audio { get; }
|
||||
public static AudibleFileStorage AAX { get; }
|
||||
public static AudibleFileStorage PDF { get; }
|
||||
|
|
@ -81,9 +64,9 @@ namespace FileManager
|
|||
|
||||
// must do this in static ctor, not w/inline properties
|
||||
// static properties init before static ctor so these dir.s would still be null
|
||||
Audio = new AudibleFileStorage(FileType.Audio, BooksDirectory);
|
||||
AAX = new AudibleFileStorage(FileType.AAX, DownloadsFinal);
|
||||
PDF = new AudibleFileStorage(FileType.PDF, BooksDirectory);
|
||||
Audio = new AudibleFileStorage(FileType.Audio, BooksDirectory, "m4b", "mp3", "aac", "mp4", "m4a", "ogg", "flac");
|
||||
AAX = new AudibleFileStorage(FileType.AAX, DownloadsFinal, "aax");
|
||||
PDF = new AudibleFileStorage(FileType.PDF, BooksDirectory, "pdf", "zip");
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
@ -92,9 +75,14 @@ namespace FileManager
|
|||
|
||||
public string StorageDirectory => DisplayName;
|
||||
|
||||
public IEnumerable<string> Extensions => extensionMap.Where(kvp => kvp.Value == FileType).Select(kvp => kvp.Key);
|
||||
private IEnumerable<string> extensions_noDots { get; }
|
||||
private string extAggr { get; }
|
||||
|
||||
private AudibleFileStorage(FileType fileType, string storageDirectory) : base((int)fileType, storageDirectory) { }
|
||||
private AudibleFileStorage(FileType fileType, string storageDirectory, params string[] extensions) : base((int)fileType, storageDirectory)
|
||||
{
|
||||
extensions_noDots = extensions.Select(ext => ext.Trim('.')).ToList();
|
||||
extAggr = extensions_noDots.Aggregate((a, b) => $"{a}|{b}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Example for full books:
|
||||
|
|
@ -102,78 +90,30 @@ namespace FileManager
|
|||
/// - a directory name has the product id and an audio file is immediately inside
|
||||
/// - any audio filename contains the product id
|
||||
/// </summary>
|
||||
public async Task<bool> ExistsAsync(string productId)
|
||||
=> (await GetAsync(productId).ConfigureAwait(false)) != null;
|
||||
public bool Exists(string productId)
|
||||
=> GetPath(productId) != null;
|
||||
|
||||
public async Task<string> GetAsync(string productId)
|
||||
=> await getAsync(productId).ConfigureAwait(false);
|
||||
|
||||
private async Task<string> getAsync(string productId)
|
||||
public string GetPath(string productId)
|
||||
{
|
||||
{
|
||||
{
|
||||
var cachedFile = FilePathCache.GetPath(productId, FileType);
|
||||
if (cachedFile != null)
|
||||
return cachedFile;
|
||||
}
|
||||
|
||||
// this is how files are saved by default. check this method first
|
||||
{
|
||||
var diskFile_byDirName = (await Task.Run(() => getFile_checkDirName(productId)).ConfigureAwait(false));
|
||||
if (diskFile_byDirName != null)
|
||||
{
|
||||
FilePathCache.Upsert(productId, FileType, diskFile_byDirName);
|
||||
return diskFile_byDirName;
|
||||
}
|
||||
}
|
||||
var firstOrNull =
|
||||
Directory
|
||||
.EnumerateFiles(StorageDirectory, "*.*", SearchOption.AllDirectories)
|
||||
.FirstOrDefault(s => Regex.IsMatch(s, $@"{productId}.*?\.({extAggr})$", RegexOptions.IgnoreCase));
|
||||
|
||||
{
|
||||
var diskFile_byFileName = (await Task.Run(() => getFile_checkFileName(productId, StorageDirectory, SearchOption.AllDirectories)).ConfigureAwait(false));
|
||||
if (diskFile_byFileName != null)
|
||||
{
|
||||
FilePathCache.Upsert(productId, FileType, diskFile_byFileName);
|
||||
return diskFile_byFileName;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
if (firstOrNull is null)
|
||||
return null;
|
||||
FilePathCache.Upsert(productId, FileType, firstOrNull);
|
||||
return firstOrNull;
|
||||
}
|
||||
|
||||
// returns audio file if there is a directory where both are true
|
||||
// - the directory name contains the productId
|
||||
// - the directory contains an audio file in it's top dir (not recursively)
|
||||
private string getFile_checkDirName(string productId)
|
||||
{
|
||||
foreach (var d in Directory.EnumerateDirectories(StorageDirectory, "*.*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (!fileHasId(d, productId))
|
||||
continue;
|
||||
|
||||
var firstAudio = Directory
|
||||
.EnumerateFiles(d, "*.*", SearchOption.TopDirectoryOnly)
|
||||
.FirstOrDefault(f => IsFileTypeMatch(f));
|
||||
if (firstAudio != null)
|
||||
return firstAudio;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// returns audio file if there is an file where both are true
|
||||
// - the file name contains the productId
|
||||
// - the file is an audio type
|
||||
private string getFile_checkFileName(string productId, string dir, SearchOption searchOption)
|
||||
=> Directory
|
||||
.EnumerateFiles(dir, "*.*", searchOption)
|
||||
.FirstOrDefault(f => fileHasId(f, productId) && IsFileTypeMatch(f));
|
||||
|
||||
public bool IsFileTypeMatch(string filename)
|
||||
=> Extensions.ContainsInsensative(Path.GetExtension(filename));
|
||||
|
||||
public bool IsFileTypeMatch(FileInfo fileInfo)
|
||||
=> Extensions.ContainsInsensative(fileInfo.Extension);
|
||||
|
||||
// use GetFileName, NOT GetFileNameWithoutExtension. This tests files AND directories. if the dir has a dot in the final part of the path, it will be treated like the file extension
|
||||
private static bool fileHasId(string file, string productId)
|
||||
=> Path.GetFileName(file).ContainsInsensitive(productId);
|
||||
=> extensions_noDots.ContainsInsensative(fileInfo.Extension.Trim('.'));
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue