public List<ImportResult> ProcessPath(string path, Series series = null, DownloadClientItem downloadClientItem = null)
        {
            if (_diskProvider.FolderExists(path))
            {
                var directoryInfo = new DirectoryInfo(path);

                if (series == null)
                {
                    return ProcessFolder(directoryInfo, downloadClientItem);
                }

                return ProcessFolder(directoryInfo, series, downloadClientItem);
            }

            if (_diskProvider.FileExists(path))
            {
                var fileInfo = new FileInfo(path);

                if (series == null)
                {
                    return ProcessFile(fileInfo, downloadClientItem);
                }

                return ProcessFile(fileInfo, series, downloadClientItem);
            }

            _logger.Error("Import failed, path does not exist or is not accessible by Sonarr: {0}", path);
            return new List<ImportResult>();
        }
Exemplo n.º 2
0
        public List<ImportResult> Import(List<ImportDecision> decisions, bool newDownload, DownloadClientItem downloadClientItem = null)
        {
            var qualifiedImports = decisions.Where(c => c.Approved)
               .GroupBy(c => c.LocalEpisode.Series.Id, (i, s) => s
                   .OrderByDescending(c => c.LocalEpisode.Quality, new QualityModelComparer(s.First().LocalEpisode.Series.Profile))
                   .ThenByDescending(c => c.LocalEpisode.Size))
               .SelectMany(c => c)
               .ToList();

            var importResults = new List<ImportResult>();

            foreach (var importDecision in qualifiedImports.OrderByDescending(e => e.LocalEpisode.Episodes.Select(episode => episode.EpisodeNumber).MinOrDefault())
                                                           .ThenByDescending(e => e.LocalEpisode.Size))
            {
                var localEpisode = importDecision.LocalEpisode;
                var oldFiles = new List<EpisodeFile>();

                try
                {
                    //check if already imported
                    if (importResults.SelectMany(r => r.ImportDecision.LocalEpisode.Episodes)
                                         .Select(e => e.Id)
                                         .Intersect(localEpisode.Episodes.Select(e => e.Id))
                                         .Any())
                    {
                        importResults.Add(new ImportResult(importDecision, "Episode has already been imported"));
                        continue;
                    }

                    var episodeFile = new EpisodeFile();
                    episodeFile.DateAdded = DateTime.UtcNow;
                    episodeFile.SeriesId = localEpisode.Series.Id;
                    episodeFile.Path = localEpisode.Path.CleanFilePath();
                    episodeFile.Size = _diskProvider.GetFileSize(localEpisode.Path);
                    episodeFile.Quality = localEpisode.Quality;
                    episodeFile.MediaInfo = localEpisode.MediaInfo;
                    episodeFile.SeasonNumber = localEpisode.SeasonNumber;
                    episodeFile.Episodes = localEpisode.Episodes;
                    episodeFile.ReleaseGroup = localEpisode.ParsedEpisodeInfo.ReleaseGroup;

                    if (newDownload)
                    {
                        bool copyOnly = downloadClientItem != null && downloadClientItem.IsReadOnly;

                        episodeFile.SceneName = GetSceneName(downloadClientItem, localEpisode);

                        var moveResult = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode, copyOnly);
                        oldFiles = moveResult.OldFiles;
                    }
                    else
                    {
                        episodeFile.RelativePath = localEpisode.Series.Path.GetRelativePath(episodeFile.Path);
                    }

                    _mediaFileService.Add(episodeFile);
                    importResults.Add(new ImportResult(importDecision));

                    if (downloadClientItem != null)
                    {
                        _eventAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile, newDownload, downloadClientItem.DownloadClient, downloadClientItem.DownloadId));
                    }
                    else
                    {
                        _eventAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile, newDownload));
                    }

                    if (newDownload)
                    {
                        _eventAggregator.PublishEvent(new EpisodeDownloadedEvent(localEpisode, episodeFile, oldFiles));
                    }
                }
                catch (Exception e)
                {
                    _logger.WarnException("Couldn't import episode " + localEpisode, e);
                    importResults.Add(new ImportResult(importDecision, "Failed to import episode"));
                }
            }

            //Adding all the rejected decisions
            importResults.AddRange(decisions.Where(c => !c.Approved)
                                            .Select(d => new ImportResult(d, d.Rejections.Select(r => r.Reason).ToArray())));

            return importResults;
        }
Exemplo n.º 3
0
        private string GetSceneName(DownloadClientItem downloadClientItem, LocalEpisode localEpisode)
        {
            if (downloadClientItem != null)
            {
                var title = Parser.Parser.RemoveFileExtension(downloadClientItem.Title);

                var parsedTitle = Parser.Parser.ParseTitle(title);

                if (parsedTitle != null && !parsedTitle.FullSeason)
                {
                    return title;
                }
            }

            var fileName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath());

            if (SceneChecker.IsSceneTitle(fileName))
            {
                return fileName;
            }

            return null;
        }
        private List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, Series series,
                                                 DownloadClientItem downloadClientItem = null)
        {
            if (_seriesService.SeriesPathExists(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 folderInfo = Parser.Parser.ParseTitle(directoryInfo.Name);

            if (folderInfo != null)
            {
                _logger.Debug("{0} folder quality: {1}", cleanedUpName, folderInfo.Quality);
            }

            var videoFiles = _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, folderInfo, true);
            var importResults = _importApprovedEpisodes.Import(decisions, true, downloadClientItem);

            if ((downloadClientItem == null || !downloadClientItem.IsReadOnly) &&
                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 List<ImportResult> ProcessFile(FileInfo fileInfo, Series series, DownloadClientItem downloadClientItem = null)
        {
            if (Path.GetFileNameWithoutExtension(fileInfo.Name).StartsWith("._"))
            {
                _logger.Debug("[{0}] starts with '._', skipping", fileInfo.FullName);

                return new List<ImportResult>
                       {
                           new ImportResult(new ImportDecision(new LocalEpisode { Path = fileInfo.FullName }, new Rejection("Invalid video file, filename starts with '._'")), "Invalid video file, filename starts with '._'")
                       };
            }

            if (downloadClientItem == null)
            {
                if (_diskProvider.IsFileLocked(fileInfo.FullName))
                {
                    return new List<ImportResult>
                           {
                               FileIsLockedResult(fileInfo.FullName)
                           };
                }
            }

            var decisions = _importDecisionMaker.GetImportDecisions(new List<string>() { fileInfo.FullName }, series, null, true);

            return _importApprovedEpisodes.Import(decisions, true, downloadClientItem);
        }
        private List<ImportResult> ProcessFolder(DirectoryInfo directoryInfo, DownloadClientItem downloadClientItem = null)
        {
            var cleanedUpName = GetCleanedUpFolderName(directoryInfo.Name);
            var series = _parsingService.GetSeries(cleanedUpName);

            if (series == null)
            {
                _logger.Debug("Unknown Series {0}", cleanedUpName);

                return new List<ImportResult>
                       {
                           UnknownSeriesResult("Unknown Series")
                       };
            }

            return ProcessFolder(directoryInfo, series, downloadClientItem);
        }
Exemplo n.º 7
0
 public abstract void RemoveItem(DownloadClientItem item, bool deleteData);
        private List<ImportResult> ProcessFile(FileInfo fileInfo, DownloadClientItem downloadClientItem = null)
        {
            var series = _parsingService.GetSeries(Path.GetFileNameWithoutExtension(fileInfo.Name));

            if (series == null)
            {
                _logger.Debug("Unknown Series for file: {0}", fileInfo.Name);

                return new List<ImportResult>
                       {
                           UnknownSeriesResult(string.Format("Unknown Series for file: {0}", fileInfo.Name), fileInfo.FullName)
                       };
            }

            return ProcessFile(fileInfo, series, downloadClientItem);
        }
Exemplo n.º 9
0
 public virtual DownloadClientItem GetImportItem(DownloadClientItem item, DownloadClientItem previousImportAttempt)
 {
     return(item);
 }
Exemplo n.º 10
0
 public virtual void MarkItemAsImported(DownloadClientItem downloadClientItem)
 {
     throw new NotSupportedException(Name + " does not support marking items as imported");
 }
        private List<ImportResult> ProcessFile(FileInfo fileInfo, Series series, DownloadClientItem downloadClientItem = null)
        {
            if (downloadClientItem == null)
            {
                if (_diskProvider.IsFileLocked(fileInfo.FullName))
                {
                    return new List<ImportResult>
                           {
                               FileIsLockedResult(fileInfo.FullName)
                           };
                }
            }

            var decisions = _importDecisionMaker.GetImportDecisions(new List<string>() { fileInfo.FullName }, series, null, true);

            return _importApprovedEpisodes.Import(decisions, true, downloadClientItem);
        }
Exemplo n.º 12
0
        public List<ImportDecision> Import(List<ImportDecision> decisions, bool newDownload, DownloadClientItem historyItem = null)
        {
            var qualifiedImports = decisions.Where(c => c.Approved)
               .GroupBy(c => c.LocalEpisode.Series.Id, (i, s) => s
                   .OrderByDescending(c => c.LocalEpisode.Quality, new QualityModelComparer(s.First().LocalEpisode.Series.QualityProfile))
                   .ThenByDescending(c => c.LocalEpisode.Size))
               .SelectMany(c => c)
               .ToList();

            var imported = new List<ImportDecision>();

            foreach (var importDecision in qualifiedImports.OrderByDescending(e => e.LocalEpisode.Size))
            {
                var localEpisode = importDecision.LocalEpisode;
                var oldFiles = new List<EpisodeFile>();

                try
                {
                    //check if already imported
                    if (imported.SelectMany(r => r.LocalEpisode.Episodes)
                                         .Select(e => e.Id)
                                         .Intersect(localEpisode.Episodes.Select(e => e.Id))
                                         .Any())
                    {
                        continue;
                    }

                    var episodeFile = new EpisodeFile();
                    episodeFile.DateAdded = DateTime.UtcNow;
                    episodeFile.SeriesId = localEpisode.Series.Id;
                    episodeFile.Path = localEpisode.Path.CleanFilePath();
                    episodeFile.Size = _diskProvider.GetFileSize(localEpisode.Path);
                    episodeFile.Quality = localEpisode.Quality;
                    episodeFile.SeasonNumber = localEpisode.SeasonNumber;
                    episodeFile.Episodes = localEpisode.Episodes;
                    episodeFile.ReleaseGroup = localEpisode.ParsedEpisodeInfo.ReleaseGroup;

                    if (newDownload)
                    {
                        bool copyOnly = historyItem != null && historyItem.IsReadOnly;
                        episodeFile.SceneName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath());
                        var moveResult = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode, copyOnly);
                        oldFiles = moveResult.OldFiles;
                    }

                    _mediaFileService.Add(episodeFile);
                    imported.Add(importDecision);

                    if (historyItem != null)
                    {
                        _eventAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile, newDownload, historyItem.DownloadClient, historyItem.DownloadClientId));
                    }
                    else
                    {
                        _eventAggregator.PublishEvent(new EpisodeImportedEvent(localEpisode, episodeFile, newDownload));
                    }

                    if (newDownload)
                    {
                        _eventAggregator.PublishEvent(new EpisodeDownloadedEvent(localEpisode, episodeFile, oldFiles));
                    }
                }
                catch (Exception e)
                {
                    _logger.WarnException("Couldn't import episode " + localEpisode, e);
                }
            }

            return imported;
        }
Exemplo n.º 13
0
        private TrackedDownload GetTrackedDownload(String trackingId, Int32 downloadClient, DownloadClientItem downloadItem, List <History.History> grabbedHistory)
        {
            var trackedDownload = new TrackedDownload
            {
                TrackingId      = trackingId,
                DownloadClient  = downloadClient,
                DownloadItem    = downloadItem,
                StartedTracking = DateTime.UtcNow,
                State           = TrackedDownloadState.Unknown,
                Status          = TrackedDownloadStatus.Ok,
            };


            try
            {
                var historyItems = grabbedHistory.Where(h =>
                {
                    var downloadClientId = h.Data.GetValueOrDefault(DOWNLOAD_CLIENT_ID);

                    if (downloadClientId == null)
                    {
                        return(false);
                    }

                    return(downloadClientId.Equals(trackedDownload.DownloadItem.DownloadClientId));
                }).ToList();

                var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title);
                if (parsedEpisodeInfo == null)
                {
                    return(null);
                }

                var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
                if (remoteEpisode.Series == null)
                {
                    if (historyItems.Empty())
                    {
                        return(null);
                    }

                    trackedDownload.Status = TrackedDownloadStatus.Warning;
                    trackedDownload.StatusMessages.Add(new TrackedDownloadStatusMessage(
                                                           trackedDownload.DownloadItem.Title,
                                                           "Series title mismatch, automatic import is not possible")
                                                       );

                    remoteEpisode = _parsingService.Map(parsedEpisodeInfo, historyItems.First().SeriesId, historyItems.Select(h => h.EpisodeId));
                }

                trackedDownload.RemoteEpisode = remoteEpisode;
            }
            catch (Exception e)
            {
                _logger.DebugException("Failed to find episode for " + downloadItem.Title, e);
                return(null);
            }

            return(trackedDownload);
        }