public LocalEpisode Augment(LocalEpisode localEpisode, DownloadClientItem downloadClientItem, bool otherFiles) { var isMediaFile = MediaFileExtensions.Extensions.Contains(Path.GetExtension(localEpisode.Path)); if (localEpisode.DownloadClientEpisodeInfo == null && localEpisode.FolderEpisodeInfo == null && localEpisode.FileEpisodeInfo == null) { if (isMediaFile) { throw new AugmentingFailedException("Unable to parse episode info from path: {0}", localEpisode.Path); } } localEpisode.Size = _diskProvider.GetFileSize(localEpisode.Path); if (isMediaFile && (!localEpisode.ExistingFile || _configService.EnableMediaInfo)) { localEpisode.MediaInfo = _videoFileInfoReader.GetMediaInfo(localEpisode.Path); } foreach (var augmenter in _augmenters) { try { augmenter.Aggregate(localEpisode, downloadClientItem, otherFiles); } catch (Exception ex) { _logger.Warn(ex, ex.Message); } } return(localEpisode); }
private IEnumerable <ImportDecision> GetDecisions(IEnumerable <String> videoFiles, Series series, bool sceneSource, QualityModel quality = null) { foreach (var file in videoFiles) { ImportDecision decision = null; try { var localEpisode = _parsingService.GetLocalEpisode(file, series, sceneSource); if (localEpisode != null) { if (quality != null && new QualityModelComparer(localEpisode.Series.Profile).Compare(quality, localEpisode.Quality) > 0) { _logger.Debug("Using quality from folder: {0}", quality); localEpisode.Quality = quality; } localEpisode.Size = _diskProvider.GetFileSize(file); _logger.Debug("Size: {0}", localEpisode.Size); //TODO: make it so media info doesn't ruin the import process of a new series if (sceneSource) { localEpisode.MediaInfo = _videoFileInfoReader.GetMediaInfo(file); } decision = GetDecision(localEpisode); } else { localEpisode = new LocalEpisode(); localEpisode.Path = file; decision = new ImportDecision(localEpisode, "Unable to parse file"); } } catch (EpisodeNotFoundException e) { var localEpisode = new LocalEpisode(); localEpisode.Path = file; decision = new ImportDecision(localEpisode, e.Message); } catch (Exception e) { _logger.ErrorException("Couldn't import file. " + file, e); } if (decision != null) { yield return(decision); } } }
private ImportDecision GetDecision(string file, Series series, DownloadClientItem downloadClientItem, ParsedEpisodeInfo folderInfo, bool sceneSource, bool shouldUseFolderName) { ImportDecision decision = null; try { var localEpisode = _parsingService.GetLocalEpisode(file, series, shouldUseFolderName ? folderInfo : null, sceneSource); if (localEpisode != null) { localEpisode.Quality = GetQuality(folderInfo, localEpisode.Quality, series); localEpisode.Size = _diskProvider.GetFileSize(file); _logger.Debug("Size: {0}", localEpisode.Size); //TODO: make it so media info doesn't ruin the import process of a new series if (sceneSource) { localEpisode.MediaInfo = _videoFileInfoReader.GetMediaInfo(file); } if (localEpisode.Episodes.Empty()) { decision = new ImportDecision(localEpisode, new Rejection("Invalid season or episode")); } else { decision = GetDecision(localEpisode, downloadClientItem); } } else { localEpisode = new LocalEpisode(); localEpisode.Path = file; decision = new ImportDecision(localEpisode, new Rejection("Unable to parse file")); } } catch (Exception e) { _logger.Error(e, "Couldn't import file. {0}", file); var localEpisode = new LocalEpisode { Path = file }; decision = new ImportDecision(localEpisode, new Rejection("Unexpected error processing file")); } if (decision == null) { _logger.Error("Unable to make a decision on {0}", file); } return(decision); }
private ImportDecision GetDecision(string file, Series series, ParsedEpisodeInfo folderInfo, bool sceneSource, bool shouldUseFolderName) { ImportDecision decision = null; try { var localEpisode = _parsingService.GetLocalEpisode(file, series, shouldUseFolderName ? folderInfo : null, sceneSource); if (localEpisode != null) { localEpisode.Quality = GetQuality(folderInfo, localEpisode.Quality, series); localEpisode.Size = _diskProvider.GetFileSize(file); _logger.Debug("Size: {0}", localEpisode.Size); //TODO: make it so media info doesn't ruin the import process of a new series if (sceneSource) { localEpisode.MediaInfo = _videoFileInfoReader.GetMediaInfo(file); } decision = GetDecision(localEpisode); } else { localEpisode = new LocalEpisode(); localEpisode.Path = file; decision = new ImportDecision(localEpisode, new Rejection("Unable to parse file")); } } catch (EpisodeNotFoundException e) { var localEpisode = new LocalEpisode(); localEpisode.Path = file; decision = new ImportDecision(localEpisode, new Rejection(e.Message)); } catch (Exception e) { _logger.ErrorException("Couldn't import file. " + file, e); } return(decision); }
private void UpdateMediaInfo(EpisodeFile episodeFile, Series series) { var path = Path.Combine(series.Path, episodeFile.RelativePath); if (!_diskProvider.FileExists(path)) { _logger.Debug("Can't update MediaInfo because '{0}' does not exist", path); return; } var updatedMediaInfo = _videoFileInfoReader.GetMediaInfo(path); if (updatedMediaInfo != null) { episodeFile.MediaInfo = updatedMediaInfo; _mediaFileService.Update(episodeFile); _logger.Debug("Updated MediaInfo for '{0}'", path); } }
private void UpdateMediaInfo(Series series, List <EpisodeFile> mediaFiles) { foreach (var mediaFile in mediaFiles) { var path = Path.Combine(series.Path, mediaFile.RelativePath); if (!_diskProvider.FileExists(path)) { _logger.Debug("Can't update MediaInfo because '{0}' does not exist", path); continue; } mediaFile.MediaInfo = _videoFileInfoReader.GetMediaInfo(path); if (mediaFile.MediaInfo != null) { _mediaFileService.Update(mediaFile); _logger.Debug("Updated MediaInfo for '{0}'", path); } } }
private void UpdateMediaInfo(Movie series, List <MovieFile> mediaFiles) { foreach (var mediaFile in mediaFiles) { var path = Path.Combine(series.Path, mediaFile.RelativePath); if (!_diskProvider.FileExists(path)) { _logger.Debug("Can't update MediaInfo because '{0}' does not exist", path); continue; } mediaFile.MediaInfo = _videoFileInfoReader.GetMediaInfo(path); if (mediaFile.MediaInfo != null) { mediaFile.MediaInfo.SchemaRevision = CURRENT_MEDIA_INFO_SCHEMA_REVISION; _mediaFileService.Update(mediaFile); _logger.Debug("Updated MediaInfo for '{0}'", path); } } }
private bool UpdateMediaInfo(MovieFile movieFile, Movie movie) { var path = Path.Combine(movie.Path, movieFile.RelativePath); if (!_diskProvider.FileExists(path)) { _logger.Debug("Can't update MediaInfo because '{0}' does not exist", path); return(false); } var updatedMediaInfo = _videoFileInfoReader.GetMediaInfo(path); if (updatedMediaInfo == null) { return(false); } movieFile.MediaInfo = updatedMediaInfo; _mediaFileService.Update(movieFile); _logger.Debug("Updated MediaInfo for '{0}'", path); return(true); }
public void Execute(ManualImportCommand message) { _logger.ProgressTrace("Manually importing {0} files", message.Files.Count); var imported = new List <ImportResult>(); var importedTrackedDownload = new List <ManuallyImportedFile>(); for (int i = 0; i < message.Files.Count; i++) { _logger.ProgressTrace("Processing file {0} of {1}", i + 1, message.Files.Count); var file = message.Files[i]; var series = _seriesService.GetSeries(file.SeriesId); var episodes = _episodeService.GetEpisodes(file.EpisodeIds); var parsedEpisodeInfo = Parser.Parser.ParsePath(file.Path) ?? new ParsedEpisodeInfo(); var mediaInfo = _videoFileInfoReader.GetMediaInfo(file.Path); var existingFile = series.Path.IsParentPath(file.Path); var localEpisode = new LocalEpisode { ExistingFile = false, Episodes = episodes, MediaInfo = mediaInfo, ParsedEpisodeInfo = parsedEpisodeInfo, Path = file.Path, Quality = file.Quality, Series = series, Size = 0 }; //TODO: Option to copy instead of import //TODO: Cleanup non-tracked downloads var importDecision = new ImportDecision(localEpisode); if (file.DownloadId.IsNullOrWhiteSpace()) { imported.AddRange(_importApprovedEpisodes.Import(new List <ImportDecision> { importDecision }, !existingFile)); } else { var trackedDownload = _trackedDownloadService.Find(file.DownloadId); var importResult = _importApprovedEpisodes.Import(new List <ImportDecision> { importDecision }, true, trackedDownload.DownloadItem).First(); imported.Add(importResult); importedTrackedDownload.Add(new ManuallyImportedFile { TrackedDownload = trackedDownload, ImportResult = importResult }); } } _logger.ProgressTrace("Manually imported {0} files", imported.Count); foreach (var groupedTrackedDownload in importedTrackedDownload.GroupBy(i => i.TrackedDownload.DownloadItem.DownloadId).ToList()) { var trackedDownload = groupedTrackedDownload.First().TrackedDownload; if (_diskProvider.FolderExists(trackedDownload.DownloadItem.OutputPath.FullPath)) { if (_downloadedEpisodesImportService.ShouldDeleteFolder( new DirectoryInfo(trackedDownload.DownloadItem.OutputPath.FullPath), trackedDownload.RemoteEpisode.Series) && !trackedDownload.DownloadItem.IsReadOnly) { _diskProvider.DeleteFolder(trackedDownload.DownloadItem.OutputPath.FullPath, true); } } if (groupedTrackedDownload.Select(c => c.ImportResult).Count(c => c.Result == ImportResultType.Imported) >= Math.Max(1, trackedDownload.RemoteEpisode.Episodes.Count)) { trackedDownload.State = TrackedDownloadStage.Imported; _eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload)); } } }
private ImportDecision GetDecision(string file, Movie movie, DownloadClientItem downloadClientItem, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldUseFolderName, bool shouldCheckQuality = false) { ImportDecision decision = null; try { var minimalInfo = shouldUseFolderName ? folderInfo.JsonClone() : _parsingService.ParseMinimalPathMovieInfo(file); LocalMovie localMovie = null; //var localMovie = _parsingService.GetLocalMovie(file, movie, shouldUseFolderName ? folderInfo : null, sceneSource); if (minimalInfo != null) { //TODO: make it so media info doesn't ruin the import process of a new movie var mediaInfo = _config.EnableMediaInfo ? _videoFileInfoReader.GetMediaInfo(file) : null; var size = _diskProvider.GetFileSize(file); var historyItems = _historyService.FindByDownloadId(downloadClientItem?.DownloadId ?? ""); var firstHistoryItem = historyItems.OrderByDescending(h => h.Date).FirstOrDefault(); var sizeMovie = new LocalMovie(); sizeMovie.Size = size; localMovie = _parsingService.GetLocalMovie(file, minimalInfo, movie, new List <object> { mediaInfo, firstHistoryItem, sizeMovie }, sceneSource); localMovie.Quality = GetQuality(folderInfo, localMovie.Quality, movie); localMovie.Size = size; _logger.Debug("Size: {0}", localMovie.Size); decision = GetDecision(localMovie, downloadClientItem); } else { localMovie = new LocalMovie(); localMovie.Path = file; if (MediaFileExtensions.Extensions.Contains(Path.GetExtension(file))) { _logger.Warn("Unable to parse movie info from path {0}", file); } decision = new ImportDecision(localMovie, new Rejection("Unable to parse file")); } } catch (Exception e) { _logger.Error(e, "Couldn't import file. " + file); var localMovie = new LocalMovie { Path = file }; decision = new ImportDecision(localMovie, new Rejection("Unexpected error processing file")); } //LocalMovie nullMovie = null; //decision = new ImportDecision(nullMovie, new Rejection("IMPLEMENTATION MISSING!!!")); return(decision); }
private ImportDecision GetDecision(string file, Movie movie, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldUseFolderName, bool shouldCheckQuality = false) { ImportDecision decision = null; try { var localMovie = _parsingService.GetLocalMovie(file, movie, shouldUseFolderName ? folderInfo : null, sceneSource); if (localMovie != null) { localMovie.Quality = GetQuality(folderInfo, localMovie.Quality, movie); localMovie.Size = _diskProvider.GetFileSize(file); _logger.Debug("Size: {0}", localMovie.Size); var current = localMovie.Quality; //TODO: make it so media info doesn't ruin the import process of a new series if (sceneSource && ShouldCheckQualityForParsedQuality(current.Quality)) { localMovie.MediaInfo = _videoFileInfoReader.GetMediaInfo(file); if (shouldCheckQuality) { _logger.Debug("Checking quality for this video file to make sure nothing mismatched."); var width = localMovie.MediaInfo.Width; var qualityName = current.Quality.Name.ToLower(); QualityModel updated = null; if (width > 2000) { if (qualityName.Contains("bluray")) { updated = new QualityModel(Quality.Bluray2160p); } else if (qualityName.Contains("webdl")) { updated = new QualityModel(Quality.WEBDL2160p); } else if (qualityName.Contains("hdtv")) { updated = new QualityModel(Quality.HDTV2160p); } else { var def = _qualitiesService.Get(Quality.HDTV2160p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.HDTV2160p); } def = _qualitiesService.Get(Quality.WEBDL2160p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.WEBDL2160p); } def = _qualitiesService.Get(Quality.Bluray2160p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.Bluray2160p); } if (updated == null) { updated = new QualityModel(Quality.Bluray2160p); } } } else if (width > 1400) { if (qualityName.Contains("bluray")) { updated = new QualityModel(Quality.Bluray1080p); } else if (qualityName.Contains("webdl")) { updated = new QualityModel(Quality.WEBDL1080p); } else if (qualityName.Contains("hdtv")) { updated = new QualityModel(Quality.HDTV1080p); } else { var def = _qualitiesService.Get(Quality.HDTV1080p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.HDTV1080p); } def = _qualitiesService.Get(Quality.WEBDL1080p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.WEBDL1080p); } def = _qualitiesService.Get(Quality.Bluray1080p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.Bluray1080p); } if (updated == null) { updated = new QualityModel(Quality.Bluray1080p); } } } else if (width > 900) { if (qualityName.Contains("bluray")) { updated = new QualityModel(Quality.Bluray720p); } else if (qualityName.Contains("webdl")) { updated = new QualityModel(Quality.WEBDL720p); } else if (qualityName.Contains("hdtv")) { updated = new QualityModel(Quality.HDTV720p); } else { var def = _qualitiesService.Get(Quality.HDTV720p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.HDTV720p); } def = _qualitiesService.Get(Quality.WEBDL720p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.WEBDL720p); } def = _qualitiesService.Get(Quality.Bluray720p); if (localMovie.Size > def.MinSize && def.MaxSize > localMovie.Size) { updated = new QualityModel(Quality.Bluray720p); } if (updated == null) { updated = new QualityModel(Quality.Bluray720p); } } } if (updated != null && updated != current) { _logger.Debug("Quality ({0}) of the file is different than the one we have ({1})", updated, current); updated.QualitySource = QualitySource.MediaInfo; localMovie.Quality = updated; } } decision = GetDecision(localMovie); } else { decision = GetDecision(localMovie); } } else { localMovie = new LocalMovie(); localMovie.Path = file; decision = new ImportDecision(localMovie, new Rejection("Unable to parse file")); } } catch (Exception e) { _logger.Error(e, "Couldn't import file. " + file); var localMovie = new LocalMovie { Path = file }; decision = new ImportDecision(localMovie, new Rejection("Unexpected error processing file")); } //LocalMovie nullMovie = null; //decision = new ImportDecision(nullMovie, new Rejection("IMPLEMENTATION MISSING!!!")); return(decision); }
private ImportDecision GetDecision(string file, Movie movie, DownloadClientItem downloadClientItem, ParsedMovieInfo folderInfo, bool sceneSource, bool shouldUseFolderName, bool shouldCheckQuality = false) { ImportDecision decision = null; try { ParsedMovieInfo modifiedFolderInfo = null; if (folderInfo != null) { modifiedFolderInfo = folderInfo.JsonClone(); // We want the filename to be used for parsing quality, etc. even if we didn't get any movie info from there. modifiedFolderInfo.SimpleReleaseTitle = Path.GetFileName(file); } var minimalInfo = _parsingService.ParseMinimalPathMovieInfo(file) ?? modifiedFolderInfo; LocalMovie localMovie = null; if (minimalInfo != null) { //TODO: make it so media info doesn't ruin the import process of a new movie var mediaInfo = (_config.EnableMediaInfo || !movie.Path?.IsParentPath(file) == true) ? _videoFileInfoReader.GetMediaInfo(file) : null; var size = _diskProvider.GetFileSize(file); var historyItems = _historyService.FindByDownloadId(downloadClientItem?.DownloadId ?? ""); var firstHistoryItem = historyItems?.OrderByDescending(h => h.Date)?.FirstOrDefault(); var sizeMovie = new LocalMovie(); sizeMovie.Size = size; localMovie = _parsingService.GetLocalMovie(file, minimalInfo, movie, new List <object> { mediaInfo, firstHistoryItem, sizeMovie, folderInfo }, sceneSource); localMovie.Quality = GetQuality(folderInfo, localMovie.Quality, movie); localMovie.Size = size; _logger.Debug("Size: {0}", localMovie.Size); decision = GetDecision(localMovie, downloadClientItem); } else { localMovie = new LocalMovie(); localMovie.Path = file; if (MediaFileExtensions.Extensions.Contains(Path.GetExtension(file))) { if (_warnedFiles.Find(file) == null) { _warnedFiles.Set(file, "warned"); _logger.Warn("Unable to parse movie info from path {0}", file); } else { _logger.Trace("Already warned user that we are unable to parse movie info from path: {0}", file); } } decision = new ImportDecision(localMovie, new Rejection("Unable to parse file")); } } catch (Exception e) { _logger.Error(e, "Couldn't import file. {0}", file); var localMovie = new LocalMovie { Path = file }; decision = new ImportDecision(localMovie, new Rejection("Unexpected error processing file")); } //LocalMovie nullMovie = null; //decision = new ImportDecision(nullMovie, new Rejection("IMPLEMENTATION MISSING!!!")); return(decision); }
public void Execute(ManualImportCommand message) { _logger.ProgressTrace("Manually importing {0} files using mode {1}", message.Files.Count, message.ImportMode); var imported = new List <ImportResult>(); var importedTrackedDownload = new List <ManuallyImportedFile>(); for (int i = 0; i < message.Files.Count; i++) { _logger.ProgressTrace("Processing file {0} of {1}", i + 1, message.Files.Count); var file = message.Files[i]; var movie = _movieService.GetMovie(file.MovieId); var parsedMovieInfo = _parsingService.ParseMoviePathInfo(file.Path, new List <object>()) ?? new ParsedMovieInfo(); var mediaInfo = _videoFileInfoReader.GetMediaInfo(file.Path); var existingFile = movie.Path.IsParentPath(file.Path); var localMovie = new LocalMovie { ExistingFile = false, MediaInfo = mediaInfo, ParsedMovieInfo = parsedMovieInfo, Path = file.Path, Quality = file.Quality, Movie = movie, Size = 0 }; //TODO: Cleanup non-tracked downloads var importDecision = new ImportDecision(localMovie); if (file.DownloadId.IsNullOrWhiteSpace()) { imported.AddRange(_importApprovedMovie.Import(new List <ImportDecision> { importDecision }, !existingFile, null, message.ImportMode)); } else { var trackedDownload = _trackedDownloadService.Find(file.DownloadId); var importResult = _importApprovedMovie.Import(new List <ImportDecision> { importDecision }, true, trackedDownload.DownloadItem, message.ImportMode).First(); imported.Add(importResult); importedTrackedDownload.Add(new ManuallyImportedFile { TrackedDownload = trackedDownload, ImportResult = importResult }); } } _logger.ProgressTrace("Manually imported {0} files", imported.Count); foreach (var groupedTrackedDownload in importedTrackedDownload.GroupBy(i => i.TrackedDownload.DownloadItem.DownloadId).ToList()) { var trackedDownload = groupedTrackedDownload.First().TrackedDownload; if (_diskProvider.FolderExists(trackedDownload.DownloadItem.OutputPath.FullPath)) { if (_downloadedMovieImportService.ShouldDeleteFolder( new DirectoryInfo(trackedDownload.DownloadItem.OutputPath.FullPath), trackedDownload.RemoteMovie.Movie) && trackedDownload.DownloadItem.CanMoveFiles) { _diskProvider.DeleteFolder(trackedDownload.DownloadItem.OutputPath.FullPath, true); } } if (groupedTrackedDownload.Select(c => c.ImportResult).Count(c => c.Result == ImportResultType.Imported) >= Math.Max(1, 1)) //TODO: trackedDownload.RemoteMovie.Movie.Count is always 1? { trackedDownload.State = TrackedDownloadStage.Imported; _eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload)); } } }