private async Task <OperationResult <bool> > ScanFolder(DirectoryInfo d, DirectoryInfo dest, ApplicationUser user, bool isReadOnly) { var sw = new Stopwatch(); sw.Start(); long processedFiles = 0; await this.LogAndPublish($"** Processing Folder: [{d.FullName}]"); long processedFolders = 0; var folderProcessor = new FolderProcessor(this.Configuration, this.HttpEncoder, this.Configuration.LibraryFolder, this.DbContext, this.CacheManager, this.MessageLogger, this.ArtistLookupEngine, this.ArtistFactory, this.ReleaseFactory, this.ImageFactory, this.ReleaseLookupEngine, this.AudioMetaDataHelper); var newArtists = 0; var newReleases = 0; var newTracks = 0; OperationResult <bool> result = null; foreach (var folder in Directory.EnumerateDirectories(d.FullName).ToArray()) { result = await folderProcessor.Process(new DirectoryInfo(folder), isReadOnly); // Between folders flush cache, the caching for folder processing was intended for caching artist metadata lookups. Most of the time artists are in the same folder. this.CacheManager.Clear(); processedFolders++; } if (result.AdditionalData != null) { newArtists = SafeParser.ToNumber <int>(result.AdditionalData["newArtists"]); newReleases = SafeParser.ToNumber <int>(result.AdditionalData["newReleases"]); newTracks = SafeParser.ToNumber <int>(result.AdditionalData["newTracks"]); } if (!isReadOnly) { FolderProcessor.DeleteEmptyFolders(d, this.Logger); } sw.Stop(); this.DbContext.ScanHistories.Add(new data.ScanHistory { UserId = user.Id, NewArtists = newArtists, NewReleases = newReleases, NewTracks = newTracks, TimeSpanInSeconds = (int)sw.Elapsed.TotalSeconds }); await this.DbContext.SaveChangesAsync(); this.CacheManager.Clear(); await this.LogAndPublish($"**Completed!Processed Folders[{ processedFolders }], Processed Files[{ processedFiles}] : Elapsed Time[{ sw.Elapsed}]"); return(new OperationResult <bool> { Data = true, IsSuccess = true, OperationTime = sw.ElapsedMilliseconds }); }
public async Task <OperationResult <bool> > ScanArtistReleasesFolders(Guid artistId, string destinationFolder, bool doJustInfo) { SimpleContract.Requires <ArgumentOutOfRangeException>(artistId != Guid.Empty, "Invalid ArtistId"); var result = true; var resultErrors = new List <Exception>(); var sw = new Stopwatch(); sw.Start(); try { var artist = this.DbContext.Artists .Include("Releases") .Include("Releases.Labels") .FirstOrDefault(x => x.RoadieId == artistId); if (artist == null) { this.Logger.LogWarning("Unable To Find Artist [{0}]", artistId); return(new OperationResult <bool>()); } var releaseScannedCount = 0; var artistFolder = artist.ArtistFileFolder(this.Configuration, destinationFolder); var scannedArtistFolders = new List <string>(); // Scan known releases for changes if (artist.Releases != null) { foreach (var release in artist.Releases) { try { result = result && (await this.ReleaseFactory.ScanReleaseFolder(Guid.Empty, destinationFolder, doJustInfo, release)).Data; releaseScannedCount++; scannedArtistFolders.Add(release.ReleaseFileFolder(artistFolder)); } catch (Exception ex) { this.Logger.LogError(ex, ex.Serialize()); } } } // Any folder found in Artist folder not already scanned scan var folderProcessor = new FolderProcessor(this.Configuration, this.HttpEncoder, destinationFolder, this.DbContext, this.CacheManager, this.Logger, this.ArtistLookupEngine, this, this.ReleaseFactory, this.ImageFactory, this.ReleaseLookupEngine, this.AudioMetaDataHelper); var nonReleaseFolders = (from d in Directory.EnumerateDirectories(artistFolder) where !(from r in scannedArtistFolders select r).Contains(d) orderby d select d); foreach (var folder in nonReleaseFolders) { await folderProcessor.Process(new DirectoryInfo(folder), doJustInfo); } if (!doJustInfo) { FolderProcessor.DeleteEmptyFolders(new DirectoryInfo(artistFolder), this.Logger); } // Always update artist image if artist image is found on an artist rescan var imageFiles = ImageHelper.ImageFilesInFolder(artistFolder, SearchOption.AllDirectories); if (imageFiles != null && imageFiles.Any()) { var imageFile = imageFiles.First(); var i = new FileInfo(imageFile); var iName = i.Name.ToLower().Trim(); var isArtistImage = iName.Contains("artist") || iName.Contains(artist.Name.ToLower()); if (isArtistImage) { // Read image and convert to jpeg artist.Thumbnail = File.ReadAllBytes(i.FullName); artist.Thumbnail = ImageHelper.ResizeImage(artist.Thumbnail, this.Configuration.MediumImageSize.Width, this.Configuration.MediumImageSize.Height); artist.Thumbnail = ImageHelper.ConvertToJpegFormat(artist.Thumbnail); if (artist.Thumbnail.Length >= ImageHelper.MaximumThumbnailByteSize) { Logger.LogWarning($"Artist Thumbnail larger than maximum size after resizing to [{ this.Configuration.ThumbnailImageSize.Width }x{ this.Configuration.ThumbnailImageSize.Height}] Thumbnail Size [{ artist.Thumbnail.Length }]"); artist.Thumbnail = null; } artist.LastUpdated = DateTime.UtcNow; await this.DbContext.SaveChangesAsync(); this.CacheManager.ClearRegion(artist.CacheRegion); this.Logger.LogInformation("Update Thumbnail using Artist File [{0}]", iName); } } sw.Stop(); this.CacheManager.ClearRegion(artist.CacheRegion); this.Logger.LogInformation("Scanned Artist [{0}], Releases Scanned [{1}], OperationTime [{2}]", artist.ToString(), releaseScannedCount, sw.ElapsedMilliseconds); } catch (Exception ex) { this.Logger.LogError(ex, ex.Serialize()); resultErrors.Add(ex); } return(new OperationResult <bool> { Data = result, IsSuccess = result, Errors = resultErrors, OperationTime = sw.ElapsedMilliseconds }); }