public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading) { existingItem.DownloadItem = downloadItem; return existingItem; } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol }; try { var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0); } if (historyItems.Any()) { var firstHistoryItem = historyItems.OrderByDescending(h => h.Date).First(); trackedDownload.State = GetStateFromHistory(firstHistoryItem.EventType); if (parsedEpisodeInfo == null || trackedDownload.RemoteEpisode == null || trackedDownload.RemoteEpisode.Series == null || trackedDownload.RemoteEpisode.Episodes.Empty()) { parsedEpisodeInfo = Parser.Parser.ParseTitle(firstHistoryItem.SourceTitle); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, firstHistoryItem.SeriesId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.EpisodeId).Distinct()); } } } if (trackedDownload.RemoteEpisode == null) { return null; } } catch (Exception e) { _logger.DebugException("Failed to find episode for " + downloadItem.Title, e); return null; } _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return trackedDownload; }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading) { existingItem.DownloadItem = downloadItem; return existingItem; } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol }; try { var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); if (parsedEpisodeInfo == null) return null; var remoteEpisode = _parsingService.Map(parsedEpisodeInfo); if (remoteEpisode.Series == null || !remoteEpisode.Episodes.Any()) { var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId); if (historyItems.Empty()) { return null; } 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; } var historyItem = _historyService.MostRecentForDownloadId(downloadItem.DownloadId); if (historyItem != null) { trackedDownload.State = GetStateFromHistory(historyItem.EventType); } _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return trackedDownload; }
public void should_track_downloads_using_the_source_title_if_it_cannot_be_found_using_the_download_title() { GivenDownloadHistory(); var remoteEpisode = new RemoteEpisode { Series = new Series() { Id = 5 }, Episodes = new List <Episode> { new Episode { Id = 4 } }, ParsedEpisodeInfo = new ParsedEpisodeInfo() { SeriesTitle = "TV Series", SeasonNumber = 1 } }; Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.Is <ParsedEpisodeInfo>(i => i.SeasonNumber == 1 && i.SeriesTitle == "TV Series"), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())) .Returns(remoteEpisode); var client = new DownloadClientDefinition() { Id = 1, Protocol = DownloadProtocol.Torrent }; var item = new DownloadClientItem() { Title = "The torrent release folder", DownloadId = "35238", }; var trackedDownload = Subject.TrackDownload(client, item); trackedDownload.Should().NotBeNull(); trackedDownload.RemoteEpisode.Should().NotBeNull(); trackedDownload.RemoteEpisode.Series.Should().NotBeNull(); trackedDownload.RemoteEpisode.Series.Id.Should().Be(5); trackedDownload.RemoteEpisode.Episodes.First().Id.Should().Be(4); trackedDownload.RemoteEpisode.ParsedEpisodeInfo.SeasonNumber.Should().Be(1); }
public void should_track_downloads_using_the_source_title_if_it_cannot_be_found_using_the_download_title() { GivenDownloadHistory(); var remoteBook = new RemoteBook { Author = new Author() { Id = 5 }, Books = new List <Book> { new Book { Id = 4 } }, ParsedBookInfo = new ParsedBookInfo() { BookTitle = "Audio Album", AuthorName = "Audio Artist" } }; Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.Is <ParsedBookInfo>(i => i.BookTitle == "Audio Album" && i.AuthorName == "Audio Artist"), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())) .Returns(remoteBook); var client = new DownloadClientDefinition() { Id = 1, Protocol = DownloadProtocol.Torrent }; var item = new DownloadClientItem() { Title = "The torrent release folder", DownloadId = "35238", }; var trackedDownload = Subject.TrackDownload(client, item); trackedDownload.Should().NotBeNull(); trackedDownload.RemoteBook.Should().NotBeNull(); trackedDownload.RemoteBook.Author.Should().NotBeNull(); trackedDownload.RemoteBook.Author.Id.Should().Be(5); trackedDownload.RemoteBook.Books.First().Id.Should().Be(4); }
public void should_track_downloads_using_the_source_title_if_it_cannot_be_found_using_the_download_title() { GivenDownloadHistory(); var remoteEpisode = new RemoteMovie { Movie = new Movie() { Id = 3 }, ParsedMovieInfo = new ParsedMovieInfo() { MovieTitle = "A Movie", Year = 1998 } }; Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.Is <ParsedMovieInfo>(i => i.MovieTitle == "A Movie"), It.IsAny <string>(), null)) .Returns(new MappingResult { RemoteMovie = remoteEpisode }); ParseMovieTitle(); var client = new DownloadClientDefinition() { Id = 1, Protocol = DownloadProtocol.Torrent }; var item = new DownloadClientItem() { Title = "A Movie 1998", DownloadId = "35238", }; var trackedDownload = Subject.TrackDownload(client, item); trackedDownload.Should().NotBeNull(); trackedDownload.RemoteMovie.Should().NotBeNull(); trackedDownload.RemoteMovie.Movie.Should().NotBeNull(); trackedDownload.RemoteMovie.Movie.Id.Should().Be(3); }
public void should_unmap_tracked_download_if_book_deleted() { GivenDownloadHistory(); var remoteBook = new RemoteBook { Author = new Author() { Id = 5 }, Books = new List <Book> { new Book { Id = 4 } }, ParsedBookInfo = new ParsedBookInfo() { BookTitle = "Audio Book", AuthorName = "Audio Author" } }; Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.Is <ParsedBookInfo>(i => i.BookTitle == "Audio Book" && i.AuthorName == "Audio Author"), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())) .Returns(remoteBook); var client = new DownloadClientDefinition() { Id = 1, Protocol = DownloadProtocol.Torrent }; var item = new DownloadClientItem() { Title = "Audio Author - Audio Book [2018 - FLAC]", DownloadId = "35238", DownloadClientInfo = new DownloadClientItemClientInfo { Protocol = client.Protocol, Id = client.Id, Name = client.Name } }; // get a tracked download in place var trackedDownload = Subject.TrackDownload(client, item); Subject.GetTrackedDownloads().Should().HaveCount(1); // simulate deletion - book no longer maps Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.Is <ParsedBookInfo>(i => i.BookTitle == "Audio Book" && i.AuthorName == "Audio Author"), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())) .Returns(default(RemoteBook)); // handle deletion event Subject.Handle(new BookDeletedEvent(remoteBook.Books.First(), false, false)); // verify download has null remote book var trackedDownloads = Subject.GetTrackedDownloads(); trackedDownloads.Should().HaveCount(1); trackedDownloads.First().RemoteBook.Should().BeNull(); }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading) { existingItem.DownloadItem = downloadItem; return existingItem; } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol }; try { var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0); } if (historyItems.Any()) { var firstHistoryItem = historyItems.OrderByDescending(h => h.Date).First(); trackedDownload.State = GetStateFromHistory(firstHistoryItem.EventType); if (parsedEpisodeInfo == null || trackedDownload.RemoteEpisode == null || trackedDownload.RemoteEpisode.Series == null || trackedDownload.RemoteEpisode.Episodes.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 parsedEpisodeInfo = Parser.Parser.ParseTitle(firstHistoryItem.SourceTitle) ?? _parsingService.ParseSpecialEpisodeTitle(firstHistoryItem.SourceTitle, 0, 0); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, firstHistoryItem.SeriesId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.EpisodeId).Distinct()); } } } if (trackedDownload.RemoteEpisode == null) { return null; } } catch (Exception e) { _logger.Debug(e, "Failed to find episode for " + downloadItem.Title); return null; } _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return 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 historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); var grabbedHistoryItem = historyItems.FirstOrDefault(h => h.EventType == MovieHistoryEventType.Grabbed); //TODO: Create release info from history and use that here, so we don't loose indexer flags! var parsedMovieInfo = _parsingService.ParseMovieInfo(trackedDownload.DownloadItem.Title, new List <object> { grabbedHistoryItem }); if (parsedMovieInfo != null) { trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; } var downloadHistory = _downloadHistoryService.GetLatestDownloadHistoryItem(downloadItem.DownloadId); if (downloadHistory != null) { var state = GetStateFromHistory(downloadHistory.EventType); trackedDownload.State = state; } if (historyItems.Any()) { var firstHistoryItem = historyItems.FirstOrDefault(); var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == MovieHistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedMovieInfo == null || trackedDownload.RemoteMovie == null || trackedDownload.RemoteMovie.Movie == null) { parsedMovieInfo = _parsingService.ParseMovieInfo(firstHistoryItem.SourceTitle, new List <object> { grabbedHistoryItem }); if (parsedMovieInfo != null) { trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; } } } // Calculate custom formats if (trackedDownload.RemoteMovie != null) { trackedDownload.RemoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(parsedMovieInfo); } // Track it so it can be displayed in the queue even though we can't determine which movie it is for if (trackedDownload.RemoteMovie == null) { _logger.Trace("No Movie found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find movie for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(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 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); }
public void should_not_throw_when_processing_deleted_series() { GivenDownloadHistory(); var remoteEpisode = new RemoteEpisode { Series = new Series() { Id = 5 }, Episodes = new List <Episode> { new Episode { Id = 4 } }, ParsedEpisodeInfo = new ParsedEpisodeInfo() { SeriesTitle = "TV Series", SeasonNumber = 1, EpisodeNumbers = new[] { 1 } }, MappedSeasonNumber = 0 }; Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.IsAny <ParsedEpisodeInfo>(), It.IsAny <int>(), It.IsAny <int>(), null)) .Returns(default(RemoteEpisode)); Mocker.GetMock <IHistoryService>() .Setup(s => s.FindByDownloadId(It.IsAny <string>())) .Returns(new List <EpisodeHistory>()); var client = new DownloadClientDefinition() { Id = 1, Protocol = DownloadProtocol.Torrent }; var item = new DownloadClientItem() { Title = "TV Series - S01E01", DownloadId = "12345", DownloadClientInfo = new DownloadClientItemClientInfo { Id = 1, Type = "Blackhole", Name = "Blackhole Client", Protocol = DownloadProtocol.Torrent } }; Subject.TrackDownload(client, item); Subject.GetTrackedDownloads().Should().HaveCount(1); Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.IsAny <ParsedEpisodeInfo>(), It.IsAny <int>(), It.IsAny <int>(), null)) .Returns(default(RemoteEpisode)); Subject.Handle(new SeriesDeletedEvent(remoteEpisode.Series, true, true)); var trackedDownloads = Subject.GetTrackedDownloads(); trackedDownloads.Should().HaveCount(1); trackedDownloads.First().RemoteEpisode.Should().BeNull(); }
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); }
public void should_not_throw_when_processing_deleted_series() { GivenDownloadHistory(); var remoteEpisode = new RemoteBook { Author = new Author() { Id = 5 }, Books = new List <Book> { new Book { Id = 4 } }, ParsedBookInfo = new ParsedBookInfo() { BookTitle = "TV Series", } }; Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.IsAny <ParsedBookInfo>(), It.IsAny <int>(), It.IsAny <List <int> >())) .Returns(default(RemoteBook)); Mocker.GetMock <IHistoryService>() .Setup(s => s.FindByDownloadId(It.IsAny <string>())) .Returns(new List <EntityHistory>()); var client = new DownloadClientDefinition() { Id = 1, Protocol = DownloadProtocol.Torrent }; var item = new DownloadClientItem() { Title = "TV Series - S01E01", DownloadId = "12345", DownloadClientInfo = new DownloadClientItemClientInfo { Id = 1, Type = "Blackhole", Name = "Blackhole Client", Protocol = DownloadProtocol.Torrent } }; Subject.TrackDownload(client, item); Subject.GetTrackedDownloads().Should().HaveCount(1); Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.IsAny <ParsedBookInfo>(), It.IsAny <int>(), It.IsAny <List <int> >())) .Returns(default(RemoteBook)); Subject.Handle(new AuthorDeletedEvent(remoteEpisode.Author, true, true)); var trackedDownloads = Subject.GetTrackedDownloads(); trackedDownloads.Should().HaveCount(1); trackedDownloads.First().RemoteBook.Should().BeNull(); }
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 parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0); } var downloadHistory = _downloadHistoryService.GetLatestDownloadHistoryItem(downloadItem.DownloadId); if (downloadHistory != null) { var state = GetStateFromHistory(downloadHistory.EventType); trackedDownload.State = state; } if (historyItems.Any()) { var firstHistoryItem = historyItems.First(); var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == EpisodeHistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedEpisodeInfo == null || trackedDownload.RemoteEpisode == null || trackedDownload.RemoteEpisode.Series == null || trackedDownload.RemoteEpisode.Episodes.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 parsedEpisodeInfo = Parser.Parser.ParseTitle(firstHistoryItem.SourceTitle) ?? _parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, firstHistoryItem.SourceTitle, 0, 0); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, firstHistoryItem.SeriesId, historyItems.Where(v => v.EventType == EpisodeHistoryEventType.Grabbed).Select(h => h.EpisodeId).Distinct()); } } } // Track it so it can be displayed in the queue even though we can't determine which series it is for if (trackedDownload.RemoteEpisode == null) { _logger.Trace("No Episode found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find episode for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { if (downloadItem.DownloadId.IsNullOrWhiteSpace()) { _logger.Warn("The following download client item ({0}) has no download hash (id), so it cannot be tracked: {1}", downloadClient.Name, downloadItem.Title); return(null); } if (downloadItem.Title.IsNullOrWhiteSpace()) { _logger.Warn("The following download client item ({0}) has no title so it cannot be tracked: {1}", downloadClient.Name, downloadItem.Title); return(null); } var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading) { existingItem.DownloadItem = downloadItem; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol }; try { var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId); var grabbedHistoryItem = historyItems.OrderByDescending(h => h.Date).FirstOrDefault(h => h.EventType == HistoryEventType.Grabbed); var firstHistoryItem = historyItems.OrderByDescending(h => h.Date).FirstOrDefault(); //TODO: Create release info from history and use that here, so we don't loose indexer flags! var parsedMovieInfo = _parsingService.ParseMovieInfo(trackedDownload.DownloadItem.Title, new List <object> { grabbedHistoryItem }); if (parsedMovieInfo != null) { trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; } if (firstHistoryItem != null) { trackedDownload.State = GetStateFromHistory(firstHistoryItem.EventType); if (parsedMovieInfo == null || trackedDownload.RemoteMovie == null || trackedDownload.RemoteMovie.Movie == null) { parsedMovieInfo = _parsingService.ParseMovieInfo(firstHistoryItem.SourceTitle, new List <object> { grabbedHistoryItem }); if (parsedMovieInfo != null) { trackedDownload.RemoteMovie = _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; } } } if (trackedDownload.RemoteMovie == null) { return(null); } } catch (Exception e) { _logger.Debug(e, "Failed to find movie for " + downloadItem.Title); return(null); } _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
public void should_unmap_tracked_download_if_album_deleted() { GivenDownloadHistory(); var remoteAlbum = new RemoteAlbum { Artist = new Artist() { Id = 5 }, Albums = new List <Album> { new Album { Id = 4 } }, ParsedAlbumInfo = new ParsedAlbumInfo() { AlbumTitle = "Audio Album", ArtistName = "Audio Artist" } }; Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.Is <ParsedAlbumInfo>(i => i.AlbumTitle == "Audio Album" && i.ArtistName == "Audio Artist"), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())) .Returns(remoteAlbum); var client = new DownloadClientDefinition() { Id = 1, Protocol = DownloadProtocol.Torrent }; var item = new DownloadClientItem() { Title = "Audio Artist - Audio Album [2018 - FLAC]", DownloadId = "35238", DownloadClientInfo = new DownloadClientItemClientInfo { Protocol = client.Protocol, Id = client.Id, Name = client.Name } }; // get a tracked download in place var trackedDownload = Subject.TrackDownload(client, item); Subject.GetTrackedDownloads().Should().HaveCount(1); // simulate deletion - album no longer maps Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.Is <ParsedAlbumInfo>(i => i.AlbumTitle == "Audio Album" && i.ArtistName == "Audio Artist"), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())) .Returns(default(RemoteAlbum)); // handle deletion event Subject.Handle(new AlbumDeletedEvent(remoteAlbum.Albums.First(), false, false)); // verify download has null remote album var trackedDownloads = Subject.GetTrackedDownloads(); trackedDownloads.Should().HaveCount(1); trackedDownloads.First().RemoteAlbum.Should().BeNull(); }
public void should_unmap_tracked_download_if_movie_deleted() { GivenDownloadHistory(); var remoteMovie = new RemoteMovie { Movie = new Movie() { Id = 3 }, ParsedMovieInfo = new ParsedMovieInfo() { MovieTitles = { "A Movie" }, Year = 1998 } }; Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.IsAny <ParsedMovieInfo>(), It.IsAny <string>(), null)) .Returns(new MappingResult { RemoteMovie = remoteMovie }); Mocker.GetMock <IHistoryService>() .Setup(s => s.FindByDownloadId(It.IsAny <string>())) .Returns(new List <MovieHistory>()); ParseMovieTitle(); var client = new DownloadClientDefinition() { Id = 1, Protocol = DownloadProtocol.Torrent }; var item = new DownloadClientItem() { Title = "A Movie 1998", DownloadId = "12345", DownloadClientInfo = new DownloadClientItemClientInfo { Id = 1, Type = "Blackhole", Name = "Blackhole Client", Protocol = DownloadProtocol.Torrent } }; Subject.TrackDownload(client, item); Subject.GetTrackedDownloads().Should().HaveCount(1); Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.IsAny <ParsedMovieInfo>(), It.IsAny <string>(), null)) .Returns(new MappingResult { MappingResultType = MappingResultType.Unknown }); Subject.Handle(new MoviesDeletedEvent(new List <Movie> { remoteMovie.Movie }, false, false)); var trackedDownloads = Subject.GetTrackedDownloads(); trackedDownloads.Should().HaveCount(1); trackedDownloads.First().RemoteMovie.Should().BeNull(); }
public TrackedDownload TrackDownload(DownloadClientDefinition downloadClient, DownloadClientItem downloadItem) { var existingItem = Find(downloadItem.DownloadId); if (existingItem != null && existingItem.State != TrackedDownloadStage.Downloading) { LogItemChange(existingItem, existingItem.DownloadItem, downloadItem); existingItem.DownloadItem = downloadItem; return(existingItem); } var trackedDownload = new TrackedDownload { DownloadClient = downloadClient.Id, DownloadItem = downloadItem, Protocol = downloadClient.Protocol }; try { var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0); } if (historyItems.Any()) { var firstHistoryItem = historyItems.OrderByDescending(h => h.Date).First(); trackedDownload.State = GetStateFromHistory(firstHistoryItem.EventType); if (parsedEpisodeInfo == null || trackedDownload.RemoteEpisode == null || trackedDownload.RemoteEpisode.Series == null || trackedDownload.RemoteEpisode.Episodes.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 parsedEpisodeInfo = Parser.Parser.ParseTitle(firstHistoryItem.SourceTitle) ?? _parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, firstHistoryItem.SourceTitle, 0, 0); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, firstHistoryItem.SeriesId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.EpisodeId).Distinct()); } } } if (trackedDownload.RemoteEpisode == null) { _logger.Trace("No Episode found for download '{0}', not tracking.", trackedDownload.DownloadItem.Title); return(null); } } catch (Exception e) { _logger.Debug(e, "Failed to find episode for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }
public void Setup() { _downloadClient = Builder <DownloadClientDefinition> .CreateNew() .With(c => c.Settings = new FloodSettings()) .BuildNew(); }
public void should_parse_as_special_when_source_title_parsing_fails() { var remoteEpisode = new RemoteEpisode { Series = new Series() { Id = 5 }, Episodes = new List <Episode> { new Episode { Id = 4 } }, ParsedEpisodeInfo = new ParsedEpisodeInfo() { SeriesTitle = "TV Series", SeasonNumber = 0, EpisodeNumbers = new [] { 1 } } }; Mocker.GetMock <IHistoryService>() .Setup(s => s.FindByDownloadId(It.Is <string>(sr => sr == "35238"))) .Returns(new List <History.History>() { new History.History() { DownloadId = "35238", SourceTitle = "TV Series Special", SeriesId = 5, EpisodeId = 4 } }); Mocker.GetMock <IParsingService>() .Setup(s => s.Map(It.Is <ParsedEpisodeInfo>(i => i.SeasonNumber == 0 && i.SeriesTitle == "TV Series"), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())) .Returns(remoteEpisode); Mocker.GetMock <IParsingService>() .Setup(s => s.ParseSpecialEpisodeTitle(It.IsAny <ParsedEpisodeInfo>(), It.IsAny <string>(), It.IsAny <int>(), It.IsAny <int>(), null)) .Returns(remoteEpisode.ParsedEpisodeInfo); var client = new DownloadClientDefinition() { Id = 1, Protocol = DownloadProtocol.Torrent }; var item = new DownloadClientItem() { Title = "The torrent release folder", DownloadId = "35238", }; var trackedDownload = Subject.TrackDownload(client, item); trackedDownload.Should().NotBeNull(); trackedDownload.RemoteEpisode.Should().NotBeNull(); trackedDownload.RemoteEpisode.Series.Should().NotBeNull(); trackedDownload.RemoteEpisode.Series.Id.Should().Be(5); trackedDownload.RemoteEpisode.Episodes.First().Id.Should().Be(4); trackedDownload.RemoteEpisode.ParsedEpisodeInfo.SeasonNumber.Should().Be(0); }
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 parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title); var historyItems = _historyService.FindByDownloadId(downloadItem.DownloadId) .OrderByDescending(h => h.Date) .ToList(); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0, 0); } if (historyItems.Any()) { var firstHistoryItem = historyItems.First(); var state = GetStateFromHistory(firstHistoryItem.EventType); trackedDownload.State = state; // TODO: Restore check to confirm all files were imported // This will treat partially imported downloads as imported (as it was before), which means a partially imported download after a // restart will get marked as imported without importing the restart of the files. // 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) // { // trackedDownload.State = TrackedDownloadState.Imported; // // var allImported = _trackedDownloadAlreadyImported.IsImported(trackedDownload, historyItems); // // trackedDownload.State = allImported ? TrackedDownloadState.Imported : TrackedDownloadState.Downloading; // } // else // { // trackedDownload.State = state; // } var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == HistoryEventType.Grabbed); trackedDownload.Indexer = grabbedEvent?.Data["indexer"]; if (parsedEpisodeInfo == null || trackedDownload.RemoteEpisode == null || trackedDownload.RemoteEpisode.Series == null || trackedDownload.RemoteEpisode.Episodes.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 parsedEpisodeInfo = Parser.Parser.ParseTitle(firstHistoryItem.SourceTitle) ?? _parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, firstHistoryItem.SourceTitle, 0, 0); if (parsedEpisodeInfo != null) { trackedDownload.RemoteEpisode = _parsingService.Map(parsedEpisodeInfo, firstHistoryItem.SeriesId, historyItems.Where(v => v.EventType == HistoryEventType.Grabbed).Select(h => h.EpisodeId).Distinct()); } } } // Track it so it can be displayed in the queue even though we can't determine which serires it is for if (trackedDownload.RemoteEpisode == null) { _logger.Trace("No Episode found for download '{0}'", trackedDownload.DownloadItem.Title); } } catch (Exception e) { _logger.Debug(e, "Failed to find episode for " + downloadItem.Title); return(null); } LogItemChange(trackedDownload, existingItem?.DownloadItem, trackedDownload.DownloadItem); _cache.Set(trackedDownload.DownloadItem.DownloadId, trackedDownload); return(trackedDownload); }