public List <ManualImportItem> GetMediaFiles(int seriesId, int?seasonNumber) { var series = _seriesService.GetSeries(seriesId); var directoryInfo = new DirectoryInfo(series.Path); var seriesFiles = seasonNumber.HasValue ? _mediaFileService.GetFilesBySeason(seriesId, seasonNumber.Value) : _mediaFileService.GetFilesBySeries(seriesId); var items = seriesFiles.Select(episodeFile => MapItem(episodeFile, series, directoryInfo.Name)).ToList(); if (!seasonNumber.HasValue) { var mediaFiles = _diskScanService.FilterPaths(series.Path, _diskScanService.GetVideoFiles(series.Path)).ToList(); var unmappedFiles = MediaFileService.FilterExistingFiles(mediaFiles, seriesFiles, series); items.AddRange(unmappedFiles.Select(file => new ManualImportItem { Path = Path.Combine(series.Path, file), FolderName = directoryInfo.Name, RelativePath = series.Path.GetRelativePath(file), Name = Path.GetFileNameWithoutExtension(file), Series = series, SeasonNumber = null, Episodes = new List <Episode>(), ReleaseGroup = string.Empty, Quality = new QualityModel(Quality.Unknown), Language = Language.Unknown, Size = _diskProvider.GetFileSize(file), Rejections = Enumerable.Empty <Rejection>() } )); } return(items); }
private List <ManualImportItem> ProcessFolder(string rootFolder, string baseFolder, string downloadId, int?seriesId, bool filterExistingFiles) { DownloadClientItem downloadClientItem = null; Series series = null; var directoryInfo = new DirectoryInfo(baseFolder); if (seriesId.HasValue) { series = _seriesService.GetSeries(seriesId.Value); } else { try { series = _parsingService.GetSeries(directoryInfo.Name); } catch (MultipleSeriesFoundException e) { _logger.Warn(e, "Unable to find series from title"); } } if (downloadId.IsNotNullOrWhiteSpace()) { var trackedDownload = _trackedDownloadService.Find(downloadId); downloadClientItem = trackedDownload.DownloadItem; if (series == null) { series = trackedDownload.RemoteEpisode?.Series; } } if (series == null) { // Filter paths based on the rootFolder, so files in subfolders that should be ignored are ignored. // It will lead to some extra directories being checked for files, but it saves the processing of them and is cleaner than // teaching FilterPaths to know whether it's processing a file or a folder and changing it's filtering based on that. var files = _diskScanService.FilterPaths(rootFolder, _diskScanService.GetVideoFiles(baseFolder, false)); var subfolders = _diskScanService.FilterPaths(rootFolder, _diskProvider.GetDirectories(baseFolder)); var processedFiles = files.Select(file => ProcessFile(rootFolder, baseFolder, file, downloadId)); var processedFolders = subfolders.SelectMany(subfolder => ProcessFolder(rootFolder, subfolder, downloadId, null, filterExistingFiles)); return(processedFiles.Concat(processedFolders).Where(i => i != null).ToList()); } var folderInfo = Parser.Parser.ParseTitle(directoryInfo.Name); var seriesFiles = _diskScanService.GetVideoFiles(baseFolder).ToList(); var decisions = _importDecisionMaker.GetImportDecisions(seriesFiles, series, downloadClientItem, folderInfo, SceneSource(series, baseFolder), filterExistingFiles); return(decisions.Select(decision => MapItem(decision, rootFolder, downloadId, directoryInfo.Name)).ToList()); }
private List <ManualImportItem> ProcessFolder(string rootFolder, string baseFolder, string downloadId, int?movieId, bool filterExistingFiles) { DownloadClientItem downloadClientItem = null; var directoryInfo = new DirectoryInfo(baseFolder); var movie = movieId.HasValue ? _movieService.GetMovie(movieId.Value) : _parsingService.GetMovie(directoryInfo.Name); if (downloadId.IsNotNullOrWhiteSpace()) { var trackedDownload = _trackedDownloadService.Find(downloadId); downloadClientItem = trackedDownload.DownloadItem; if (movie == null) { movie = trackedDownload.RemoteMovie?.Movie; } } if (movie == null) { // Filter paths based on the rootFolder, so files in subfolders that should be ignored are ignored. // It will lead to some extra directories being checked for files, but it saves the processing of them and is cleaner than // teaching FilterPaths to know whether it's processing a file or a folder and changing it's filtering based on that. // If the movie is unknown for the directory and there are more than 100 files in the folder don't process the items before returning. var files = _diskScanService.FilterPaths(rootFolder, _diskScanService.GetVideoFiles(baseFolder, false)); if (files.Count() > 100) { return(ProcessDownloadDirectory(rootFolder, files)); } var subfolders = _diskScanService.FilterPaths(rootFolder, _diskProvider.GetDirectories(baseFolder)); var processedFiles = files.Select(file => ProcessFile(rootFolder, baseFolder, file, downloadId)); var processedFolders = subfolders.SelectMany(subfolder => ProcessFolder(rootFolder, subfolder, downloadId, null, filterExistingFiles)); return(processedFiles.Concat(processedFolders).Where(i => i != null).ToList()); } var folderInfo = Parser.Parser.ParseMovieTitle(directoryInfo.Name); var movieFiles = _diskScanService.FilterPaths(rootFolder, _diskScanService.GetVideoFiles(baseFolder).ToList()); var decisions = _importDecisionMaker.GetImportDecisions(movieFiles, movie, downloadClientItem, folderInfo, SceneSource(movie, baseFolder), filterExistingFiles); return(decisions.Select(decision => MapItem(decision, rootFolder, downloadId, directoryInfo.Name)).ToList()); }
public void Handle(MovieScannedEvent message) { var movie = message.Movie; var extraFiles = new List <ExtraFile>(); if (!_diskProvider.FolderExists(movie.Path)) { return; } _logger.Debug("Looking for existing extra files in {0}", movie.Path); var filesOnDisk = _diskScanService.GetNonVideoFiles(movie.Path); var possibleExtraFiles = _diskScanService.FilterPaths(movie.Path, filesOnDisk, false); var filteredFiles = possibleExtraFiles; var importedFiles = new List <string>(); foreach (var existingExtraFileImporter in _existingExtraFileImporters) { var imported = existingExtraFileImporter.ProcessFiles(movie, filteredFiles, importedFiles); importedFiles.AddRange(imported.Select(f => Path.Combine(movie.Path, f.RelativePath))); } _logger.Info("Found {0} extra files", extraFiles.Count); }
public void Handle(SeriesScannedEvent message) { var series = message.Series; if (!_diskProvider.FolderExists(series.Path)) { return; } _logger.Debug("Looking for existing extra files in {0}", series.Path); var filesOnDisk = _diskScanService.GetNonVideoFiles(series.Path); var possibleExtraFiles = _diskScanService.FilterPaths(series.Path, filesOnDisk); var importedFiles = new List <string>(); foreach (var existingExtraFileImporter in _existingExtraFileImporters) { var imported = existingExtraFileImporter.ProcessFiles(series, possibleExtraFiles, importedFiles); importedFiles.AddRange(imported.Select(f => Path.Combine(series.Path, f.RelativePath))); } _logger.Info("Found {0} possible extra files, imported {1} files.", possibleExtraFiles.Count, importedFiles.Count); }
private List <ImportResult> ProcessFolder(DirectoryInfo directoryInfo, ImportMode importMode, Movie movie, DownloadClientItem downloadClientItem) { if (_movieService.MoviePathExists(directoryInfo.FullName)) { _logger.Warn("Unable to process folder that is mapped to an existing show"); return(new List <ImportResult>()); } var cleanedUpName = GetCleanedUpFolderName(directoryInfo.Name); var historyItems = _historyService.FindByDownloadId(downloadClientItem?.DownloadId ?? ""); var firstHistoryItem = historyItems?.OrderByDescending(h => h.Date).FirstOrDefault(); var folderInfo = _parsingService.ParseMovieInfo(cleanedUpName, new List <object> { firstHistoryItem }); if (folderInfo != null) { _logger.Debug("{0} folder quality: {1}", cleanedUpName, folderInfo.Quality); } var videoFiles = _diskScanService.FilterPaths(directoryInfo.FullName, _diskScanService.GetVideoFiles(directoryInfo.FullName)); if (downloadClientItem == null) { foreach (var videoFile in videoFiles) { if (_diskProvider.IsFileLocked(videoFile)) { return(new List <ImportResult> { FileIsLockedResult(videoFile) }); } } } var decisions = _importDecisionMaker.GetImportDecisions(videoFiles.ToList(), movie, downloadClientItem, folderInfo, true); var importResults = _importApprovedMovie.Import(decisions, true, downloadClientItem, importMode); if (importMode == ImportMode.Auto) { importMode = (downloadClientItem == null || downloadClientItem.CanMoveFiles) ? ImportMode.Move : ImportMode.Copy; } if (importMode == ImportMode.Move && importResults.Any(i => i.Result == ImportResultType.Imported) && ShouldDeleteFolder(directoryInfo, movie)) { _logger.Debug("Deleting folder after importing valid files"); _diskProvider.DeleteFolder(directoryInfo.FullName, true); } return(importResults); }
private List <ImportResult> ProcessFolder(DirectoryInfo directoryInfo, ImportMode importMode, Series series, DownloadClientItem downloadClientItem) { if (_seriesService.SeriesPathExists(directoryInfo.FullName)) { _logger.Warn("Unable to process folder that is mapped to an existing show"); return(new List <ImportResult>()); } var folderInfo = Parser.Parser.ParseTitle(directoryInfo.Name); var videoFiles = _diskScanService.FilterPaths(directoryInfo.FullName, _diskScanService.GetVideoFiles(directoryInfo.FullName)); if (downloadClientItem == null) { foreach (var videoFile in videoFiles) { if (_diskProvider.IsFileLocked(videoFile)) { return(new List <ImportResult> { FileIsLockedResult(videoFile) }); } } } var decisions = _importDecisionMaker.GetImportDecisions(videoFiles.ToList(), series, downloadClientItem, folderInfo, true); var importResults = _importApprovedEpisodes.Import(decisions, true, downloadClientItem, importMode); if (importMode == ImportMode.Auto) { importMode = (downloadClientItem == null || downloadClientItem.CanMoveFiles) ? ImportMode.Move : ImportMode.Copy; } if (importMode == ImportMode.Move && importResults.Any(i => i.Result == ImportResultType.Imported) && ShouldDeleteFolder(directoryInfo, series)) { _logger.Debug("Deleting folder after importing valid files"); _diskProvider.DeleteFolder(directoryInfo.FullName, true); } return(importResults); }
private IEnumerable <WatchFolderItem> GetDownloadItems(string watchFolder, Dictionary <string, WatchFolderItem> lastWatchItems, TimeSpan waitPeriod) { foreach (var folder in _diskScanService.FilterPaths(watchFolder, _diskProvider.GetDirectories(watchFolder))) { var title = FileNameBuilder.CleanFileName(Path.GetFileName(folder)); var newWatchItem = new WatchFolderItem { DownloadId = Path.GetFileName(folder) + "_" + _diskProvider.FolderGetCreationTime(folder).Ticks, Title = title, OutputPath = new OsPath(folder), Status = DownloadItemStatus.Completed, RemainingTime = TimeSpan.Zero }; var oldWatchItem = lastWatchItems.GetValueOrDefault(newWatchItem.DownloadId); if (PreCheckWatchItemExpiry(newWatchItem, oldWatchItem)) { var files = _diskProvider.GetFiles(folder, SearchOption.AllDirectories); newWatchItem.TotalSize = files.Select(_diskProvider.GetFileSize).Sum(); newWatchItem.Hash = GetHash(folder, files); if (files.Any(_diskProvider.IsFileLocked)) { newWatchItem.Status = DownloadItemStatus.Downloading; newWatchItem.RemainingTime = null; } UpdateWatchItemExpiry(newWatchItem, oldWatchItem, waitPeriod); } yield return(newWatchItem); } foreach (var videoFile in _diskScanService.FilterPaths(watchFolder, _diskScanService.GetVideoFiles(watchFolder, false))) { var title = FileNameBuilder.CleanFileName(Path.GetFileName(videoFile)); var newWatchItem = new WatchFolderItem { DownloadId = Path.GetFileName(videoFile) + "_" + _diskProvider.FileGetLastWrite(videoFile).Ticks, Title = title, OutputPath = new OsPath(videoFile), Status = DownloadItemStatus.Completed, RemainingTime = TimeSpan.Zero }; var oldWatchItem = lastWatchItems.GetValueOrDefault(newWatchItem.DownloadId); if (PreCheckWatchItemExpiry(newWatchItem, oldWatchItem)) { newWatchItem.TotalSize = _diskProvider.GetFileSize(videoFile); newWatchItem.Hash = GetHash(videoFile); if (_diskProvider.IsFileLocked(videoFile)) { newWatchItem.Status = DownloadItemStatus.Downloading; } UpdateWatchItemExpiry(newWatchItem, oldWatchItem, waitPeriod); } yield return(newWatchItem); } }