public void ScanDirectory(string directory, string[] fileExtensions, bool includeSubdirectories) { if (includeSubdirectories) { foreach (var subDirectory in Directory.GetDirectories(directory)) { ScanDirectory(subDirectory, fileExtensions, includeSubdirectories); } } DirectoryInfo directoryInfo = new DirectoryInfo(directory); if (directoryInfo.EnumerateFiles().Any()) { ScanActions.Add(() => ProcessDirectory(directoryInfo)); foreach (string extension in fileExtensions) { foreach (var file in directoryInfo.GetFiles("*." + extension.ToLower())) { ScanActions.Add(() => ProcessFile(file)); } } } }
public void ScanFolder(string path, string[] fileExtensions, bool includeSubdirectories = true, bool clearDatabase = false) { ScanComplete = false; ScanStart = DateTime.Now; try { if (Directory.Exists(path)) { if (clearDatabase) { using (DatabaseContext db = new DatabaseContext(Logger)) { db.MediaFiles.Clear(); db.Albums.Clear(); db.SaveChanges(); } } ScanDirectory(path, fileExtensions, includeSubdirectories); Logger.Info("Directory load complete, beginning scanning files."); var scanOptions = new ParallelOptions { MaxDegreeOfParallelism = 20 }; Parallel.Invoke(scanOptions, ScanActions.ToArray()); Logger.Info($"Scaned {FilesProcessed} files."); Logger.Info($"Scaned {DirectoriesProcessed} albums."); Logger.Info($"Encountered {Errors.Count} errors."); foreach (var error in Errors) { Logger.Info(error.Details); } } else { throw new Exception($"Directory '{path}' does not exist."); } } catch (Exception ex) { Logger.Error($"Error scanning files: {path}", ex); Errors.Add(new FileError(ex, path, "Error scanning files.")); } ScanEnd = DateTime.Now; ScanComplete = true; }
private void ScanDirectory(string directory, string[] fileExtensions, bool includeSubdirectories) { if (IgnoreDirectories.Contains(directory)) { if (Globals.VerboseLogging) { Logger.Info($"Skipping directory '{directory}' as set in ignore file."); } return; } if (includeSubdirectories) { foreach (var subDirectory in Directory.GetDirectories(directory)) { ScanDirectory(subDirectory, fileExtensions, includeSubdirectories); } } if (Globals.VerboseLogging) { Logger.Info($"Scanning directory '{directory}'."); } DirectoryInfo directoryInfo = new DirectoryInfo(directory); if (directoryInfo.EnumerateFiles("*.mp3", SearchOption.TopDirectoryOnly).Any()) { ScanActions.Add(() => ProcessDirectory(directoryInfo)); foreach (string extension in fileExtensions) { foreach (var file in directoryInfo.GetFiles("*." + extension.ToLower())) { ScanActions.Add(() => ProcessFile(file)); } } } }
public void ScanFolder(string path, string[] fileExtensions, bool includeSubdirectories = true, bool clearDatabase = false, bool resetDatabase = false) { ScanComplete = false; ScanStart = DateTime.Now; MySQLContext databaseContext = null; LastScan = DateTime.Parse("1/1/1990"); DirectoriesProcessed = 0; DirectoriesSkipped = 0; FilesProcessed = 0; FilesSkipped = 0; try { if (Directory.Exists(path)) { if (resetDatabase) { Logger.Info("Resetting database..."); using (MySQLContext db = new MySQLContext(Logger)) { db.DropTablesIfExist(); } Globals.TablesChecked = false; } else if (clearDatabase) { Logger.Info("Clearing database..."); using (MySQLContext db = new MySQLContext(Logger)) { db.MediaFiles.Clear(); db.Albums.Clear(); db.Scans.Clear(); db.SaveChanges(); } } Logger.Info("Getting last scan date..."); using (MySQLContext db = new MySQLContext(Logger)) { if (db.Scans.Any(s => s.FolderPath == path)) { LastScan = db.Scans.Where(s => s.FolderPath == path).Select(s => s.LastScanned).Max(); } try { var scanData = new Repository.Scan(Logger, path); scanData.AddOrUpdate(); } catch (Exception scanEx) { Logger.Fatal($"There was an error updating the last scan information. Error: {scanEx.Message}", scanEx); } } Logger.Info("Beginning loading directories..."); ScanDirectory(path, fileExtensions, includeSubdirectories); Logger.Info($"Loaded {ScanActions.Count()} files and directories."); Logger.Info("Beginning scanning files and directories."); while (ScanActionsRetry.Any() || ScanActions.Any()) { if (!string.IsNullOrEmpty(ParallelThreads)) { Logger.Info($"Running with maximum number of threads: {ParallelThreads}."); var scanOptions = new ParallelOptions { MaxDegreeOfParallelism = int.Parse(ParallelThreads) }; Parallel.Invoke(scanOptions, ScanActions.ToArray()); } else { Parallel.Invoke(ScanActions.ToArray()); } ScanActions.Clear(); if (ScanActionsRetry.Any()) { Logger.Info($"Processes to retry: {ScanActionsRetry.Count()}. Re-running errored processes."); ScanActions.Clear(); ScanActions.AddRange(ScanActionsRetry); ScanActionsRetry = new ConcurrentBag <Action>(); } } Logger.Info($"Scanned {FilesProcessed} files, skipped {FilesSkipped} files."); Logger.Info($"Scanned {DirectoriesProcessed} albums, skipped {DirectoriesSkipped} directories."); Logger.Info($"Encountered {Errors.Count} errors."); Logger.Info($"Cleaning up database..."); using (var db = new MySQLContext(Logger)) { foreach (var album in db.Albums.Where(a => a.LastScanned < LastScan)) { if (Directory.Exists(album.FolderPath)) { album.LastScanned = LastScan; } else { db.Albums.Remove(album); } } db.SaveChanges(); foreach (var mp3File in db.MediaFiles.Where(f => f.LastScanned < LastScan)) { if (File.Exists(mp3File.FilePath)) { mp3File.LastScanned = LastScan; } else { db.MediaFiles.Remove(mp3File); } } db.SaveChanges(); } foreach (var error in Errors) { Logger.Info($"File: {error.FilePath}; Error: {error.Details}"); } } else { throw new Exception($"Directory '{path}' does not exist."); } } catch (Exception ex) { Logger.Error($"Error scanning files: {path}", ex); Errors.Add(new FileError(ex, path, "Error scanning files.")); } ScanEnd = DateTime.Now; ScanComplete = true; if (databaseContext != null) { try { databaseContext.Dispose(); } catch { } finally { databaseContext = null; } } }