예제 #1
0
        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;
                }
            }
        }