public void Process(TrackedDownload trackedDownload, bool ignoreWarnings = false) { if (trackedDownload.DownloadItem.Status != DownloadItemStatus.Completed) { return; } if (!ignoreWarnings) { var historyItem = _historyService.MostRecentForDownloadId(trackedDownload.DownloadItem.DownloadId); if (historyItem == null && trackedDownload.DownloadItem.Category.IsNullOrWhiteSpace()) { trackedDownload.Warn("Download wasn't grabbed by Sonarr and not in a category, Skipping."); return; } var downloadItemOutputPath = trackedDownload.DownloadItem.OutputPath; if (downloadItemOutputPath.IsEmpty) { trackedDownload.Warn("Download doesn't contain intermediate path, Skipping."); return; } if ((OsInfo.IsWindows && !downloadItemOutputPath.IsWindowsPath) || (OsInfo.IsNotWindows && !downloadItemOutputPath.IsUnixPath)) { trackedDownload.Warn("[{0}] is not a valid local path. You may need a Remote Path Mapping.", downloadItemOutputPath); return; } var downloadedEpisodesFolder = new OsPath(_configService.DownloadedEpisodesFolder); if (downloadedEpisodesFolder.Contains(downloadItemOutputPath)) { trackedDownload.Warn("Intermediate Download path inside drone factory, Skipping."); return; } var series = _parsingService.GetSeries(trackedDownload.DownloadItem.Title); if (series == null) { if (historyItem != null) { series = _seriesService.GetSeries(historyItem.SeriesId); } if (series == null) { trackedDownload.Warn("Series title mismatch, automatic import is not possible."); return; } } } Import(trackedDownload); }
public void Process(TrackedDownload trackedDownload) { string failure = null; if (trackedDownload.DownloadItem.IsEncrypted) { failure = "Encrypted download detected"; } else if (trackedDownload.DownloadItem.Status == DownloadItemStatus.Failed) { failure = trackedDownload.DownloadItem.Message ?? "Failed download detected"; } if (failure != null) { var grabbedItems = _historyService.Find(trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed) .ToList(); if (grabbedItems.Empty()) { trackedDownload.Warn("Download wasn't grabbed by sonarr, skipping"); return; } trackedDownload.State = TrackedDownloadStage.DownloadFailed; PublishDownloadFailedEvent(grabbedItems, failure, trackedDownload); } }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadState.Downloading) { LogItemChange(existingItem, existingItem.DownloadItem, downloadItem); existingItem.DownloadItem = downloadItem; existingItem.IsTrackable = true; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol, IsTrackable = true }; try { var parsedAlbumInfo = Parser.Parser.ParseAlbumTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); if (parsedAlbumInfo != null) { trackedDownload.RemoteAlbum = _parsingService.Map(parsedAlbumInfo); } if (historyItems.Any()) { var firstHistoryItem = historyItems.First(); var state = GetStateFromHistory(firstHistoryItem); // One potential issue here is if the latest is imported, but other episodes are ignored or never imported. // It's unlikely that will happen, but could happen if additional episodes are added to season after it's already imported. if (state == TrackedDownloadState.Imported) { var allImported = _trackedDownloadAlreadyImported.IsImported(trackedDownload, historyItems); trackedDownload.State = allImported ? TrackedDownloadState.Imported : TrackedDownloadState.Downloading; } else { trackedDownload.State = state; } if (firstHistoryItem.EventType == HistoryEventType.AlbumImportIncomplete) { var messages = Json.Deserialize <List <TrackedDownloadStatusMessage> >(firstHistoryItem?.Data["statusMessages"]).ToArray(); trackedDownload.Warn(messages); } var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == HistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedAlbumInfo == null || trackedDownload.RemoteAlbum == null || trackedDownload.RemoteAlbum.Artist == null || trackedDownload.RemoteAlbum.Albums.Empty()) { // Try parsing the original source title and if that fails, try parsing it as a special // TODO: Pass the TVDB ID and TVRage IDs in as well so we have a better chance for finding the item var historyArtist = firstHistoryItem.Artist; var historyAlbums = new List <Album> { firstHistoryItem.Album }; parsedAlbumInfo = Parser.Parser.ParseAlbumTitle(firstHistoryItem.SourceTitle); if (parsedAlbumInfo != null) { trackedDownload.RemoteAlbum = _parsingService.Map(parsedAlbumInfo, firstHistoryItem.ArtistId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.AlbumId) .Distinct()); } else { parsedAlbumInfo = Parser.Parser.ParseAlbumTitleWithSearchCriteria(firstHistoryItem.SourceTitle, historyArtist, historyAlbums); if (parsedAlbumInfo != null) { trackedDownload.RemoteAlbum = _parsingService.Map(parsedAlbumInfo, firstHistoryItem.ArtistId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.AlbumId) .Distinct()); } } } } // Track it so it can be displayed in the queue even though we can't determine which artist it is for if (trackedDownload.RemoteAlbum == null) { _logger.Trace("No Album found for download '{0}'", trackedDownload.DownloadItem.Title); trackedDownload.Warn("No Album found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find album for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
private void Import(TrackedDownload trackedDownload) { var outputPath = trackedDownload.DownloadItem.OutputPath.FullPath; var importResults = _downloadedEpisodesImportService.ProcessPath(outputPath, trackedDownload.RemoteEpisode.Series, trackedDownload.DownloadItem); if (importResults.Empty()) { trackedDownload.Warn("No files found are eligible for import in {0}", outputPath); return; } if (importResults.Count(c => c.Result == ImportResultType.Imported) >= Math.Max(1, trackedDownload.RemoteEpisode.Episodes.Count)) { trackedDownload.State = TrackedDownloadStage.Imported; _eventAggregator.PublishEvent(new DownloadCompletedEvent(trackedDownload)); return; } if (importResults.Any(c => c.Result != ImportResultType.Imported)) { var statusMessages = importResults .Where(v => v.Result != ImportResultType.Imported) .Select(v => new TrackedDownloadStatusMessage(Path.GetFileName(v.ImportDecision.LocalEpisode.Path), v.Errors)) .ToArray(); trackedDownload.Warn(statusMessages); } }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadState.Downloading) { LogItemChange(existingItem, existingItem.DownloadItem, downloadItem); existingItem.DownloadItem = downloadItem; existingItem.IsTrackable = true; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol, IsTrackable = true }; try { var parsedBookInfo = Parser.Parser.ParseBookTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); if (parsedBookInfo != null) { trackedDownload.RemoteBook = _parsingService.Map(parsedBookInfo); } var downloadHistory = _downloadHistoryService.GetLatestDownloadHistoryItem(downloadItem.DownloadId); if (downloadHistory != null) { var state = GetStateFromHistory(downloadHistory.EventType); trackedDownload.State = state; if (downloadHistory.EventType == DownloadHistoryEventType.DownloadImportIncomplete) { var messages = Json.Deserialize <List <TrackedDownloadStatusMessage> >(downloadHistory.Data["statusMessages"]).ToArray(); trackedDownload.Warn(messages); } } if (historyItems.Any()) { var firstHistoryItem = historyItems.First(); var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == EntityHistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedBookInfo == null || trackedDownload.RemoteBook == null || trackedDownload.RemoteBook.Author == null || trackedDownload.RemoteBook.Books.Empty()) { // Try parsing the original source title and if that fails, try parsing it as a special var historyAuthor = firstHistoryItem.Author; var historyBooks = new List <Book> { firstHistoryItem.Book }; parsedBookInfo = Parser.Parser.ParseBookTitle(firstHistoryItem.SourceTitle); if (parsedBookInfo != null) { trackedDownload.RemoteBook = _parsingService.Map(parsedBookInfo, firstHistoryItem.AuthorId, historyItems.Where(v => v.EventType == EntityHistoryEventType.Grabbed).Select(h => h.BookId) .Distinct()); } else { parsedBookInfo = Parser.Parser.ParseBookTitleWithSearchCriteria(firstHistoryItem.SourceTitle, historyAuthor, historyBooks); if (parsedBookInfo != null) { trackedDownload.RemoteBook = _parsingService.Map(parsedBookInfo, firstHistoryItem.AuthorId, historyItems.Where(v => v.EventType == EntityHistoryEventType.Grabbed).Select(h => h.BookId) .Distinct()); } } } } // Track it so it can be displayed in the queue even though we can't determine which author it is for if (trackedDownload.RemoteBook == null) { _logger.Trace("No Book found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find book for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }