private RemoteAlbum GivenRemoteAlbum(List <Album> albums, QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet) { var remoteAlbum = new RemoteAlbum(); remoteAlbum.ParsedAlbumInfo = new ParsedAlbumInfo(); remoteAlbum.ParsedAlbumInfo.Quality = quality; remoteAlbum.Albums = new List <Album>(); remoteAlbum.Albums.AddRange(albums); remoteAlbum.Release = new ReleaseInfo(); remoteAlbum.Release.PublishDate = DateTime.Now.AddDays(-age); remoteAlbum.Release.Size = size; remoteAlbum.Release.DownloadProtocol = downloadProtocol; remoteAlbum.Artist = Builder <Artist> .CreateNew() .With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() }).Build(); remoteAlbum.DownloadAllowed = true; return(remoteAlbum); }
public virtual Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria) { if (subject.Release.DownloadProtocol != Indexers.DownloadProtocol.Usenet) { _logger.Debug("Not checking minimum age requirement for non-usenet report"); return(Decision.Accept()); } var age = subject.Release.AgeMinutes; var minimumAge = _configService.MinimumAge; var ageRounded = Math.Round(age, 1); if (minimumAge == 0) { _logger.Debug("Minimum age is not set."); return(Decision.Accept()); } _logger.Debug("Checking if report meets minimum age requirements. {0}", ageRounded); if (age < minimumAge) { _logger.Debug("Only {0} minutes old, minimum age is {1} minutes", ageRounded, minimumAge); return(Decision.Reject("Only {0} minutes old, minimum age is {1} minutes", ageRounded, minimumAge)); } _logger.Debug("Release is {0} minutes old, greater than minimum age of {1} minutes", ageRounded, minimumAge); return(Decision.Accept()); }
private string DownloadFromMagnetUrl(RemoteAlbum remoteAlbum, string magnetUrl) { string hash = null; string actualHash = null; try { hash = new MagnetLink(magnetUrl).InfoHash.ToHex(); } catch (FormatException ex) { _logger.Error(ex, "Failed to parse magnetlink for release '{0}': '{1}'", remoteAlbum.Release.Title, magnetUrl); return(null); } if (hash != null) { actualHash = AddFromMagnetLink(remoteAlbum, hash, magnetUrl); } if (actualHash.IsNotNullOrWhiteSpace() && hash != actualHash) { _logger.Debug( "{0} did not return the expected InfoHash for '{1}', Lidarr could potentially lose track of the download in progress.", Definition.Implementation, remoteAlbum.Release.DownloadUrl); } return(actualHash); }
public void Setup() { var artist = Builder <Artist> .CreateNew().With(s => s.Id = 1234).Build(); _remoteAlbum = new RemoteAlbum { ParsedAlbumInfo = new ParsedAlbumInfo { Discography = true }, Albums = Builder <Album> .CreateListOfSize(3) .All() .With(e => e.ReleaseDate = DateTime.UtcNow.AddDays(-8)) .With(s => s.ArtistId = artist.Id) .BuildList(), Artist = artist, Release = new ReleaseInfo { Title = "Artist.Discography.1978.2005.FLAC-RlsGrp" } }; Mocker.GetMock <IAlbumService>().Setup(s => s.AlbumsBetweenDates(It.IsAny <DateTime>(), It.IsAny <DateTime>(), false)) .Returns(new List <Album>()); }
public void Setup() { _artist = Builder <Artist> .CreateNew().With(s => s.Id = 1).Build(); _remoteAlbum = new RemoteAlbum { Artist = _artist, Release = new TorrentInfo { IndexerId = 1, Title = "Artist - Album [FLAC-RlsGrp]", Seeders = 0 } }; _indexerDefinition = new IndexerDefinition { Settings = new TorrentRssIndexerSettings { MinimumSeeders = 5 } }; Mocker.GetMock <IIndexerFactory>() .Setup(v => v.Get(1)) .Returns(_indexerDefinition); }
public void Setup() { _downloadClients = new List <IDownloadClient>(); Mocker.GetMock <IProvideDownloadClient>() .Setup(v => v.GetDownloadClients()) .Returns(_downloadClients); Mocker.GetMock <IProvideDownloadClient>() .Setup(v => v.GetDownloadClient(It.IsAny <DownloadProtocol>())) .Returns <DownloadProtocol>(v => _downloadClients.FirstOrDefault(d => d.Protocol == v)); var episodes = Builder <Album> .CreateListOfSize(2) .TheFirst(1).With(s => s.Id = 12) .TheNext(1).With(s => s.Id = 99) .All().With(s => s.ArtistId = 5) .Build().ToList(); var releaseInfo = Builder <ReleaseInfo> .CreateNew() .With(v => v.DownloadProtocol = DownloadProtocol.Usenet) .With(v => v.DownloadUrl = "http://test.site/download1.ext") .Build(); _parseResult = Builder <RemoteAlbum> .CreateNew() .With(c => c.Artist = Builder <Artist> .CreateNew().Build()) .With(c => c.Release = releaseInfo) .With(c => c.Albums = episodes) .Build(); }
public virtual Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria) { var qualityProfile = subject.Artist.QualityProfile.Value; foreach (var album in subject.Albums) { var tracksMissing = _missingFilesCache.Get(album.Id.ToString(), () => _trackService.TracksWithoutFiles(album.Id).Any(), TimeSpan.FromSeconds(30)); var trackFiles = _mediaFileService.GetFilesByAlbum(album.Id); if (!tracksMissing && trackFiles.Any()) { // Get a distinct list of all current track qualities for a given album var currentQualities = trackFiles.Select(c => c.Quality).Distinct().ToList(); _logger.Debug("Comparing file quality with report. Existing files contain {0}", currentQualities.ConcatToString()); if (!_upgradableSpecification.IsUpgradeAllowed(qualityProfile, currentQualities, subject.ParsedAlbumInfo.Quality)) { _logger.Debug("Upgrading is not allowed by the quality profile"); return(Decision.Reject("Existing files and the Quality profile does not allow upgrades")); } } } return(Decision.Accept()); }
public void Setup() { var completed = Builder <DownloadClientItem> .CreateNew() .With(h => h.Status = DownloadItemStatus.Completed) .With(h => h.OutputPath = new OsPath(@"C:\DropFolder\MyDownload".AsOsAgnostic())) .With(h => h.Title = "Drone.S01E01.HDTV") .Build(); _grabHistory = Builder <History.History> .CreateListOfSize(2).BuildList(); var remoteAlbum = new RemoteAlbum { Artist = new Artist(), Albums = new List <Album> { new Album { Id = 1 } } }; _trackedDownload = Builder <TrackedDownload> .CreateNew() .With(c => c.State = TrackedDownloadState.DownloadFailedPending) .With(c => c.DownloadItem = completed) .With(c => c.RemoteAlbum = remoteAlbum) .Build(); Mocker.GetMock <IHistoryService>() .Setup(s => s.Find(_trackedDownload.DownloadItem.DownloadId, HistoryEventType.Grabbed)) .Returns(_grabHistory); }
public virtual Decision IsSatisfiedBy(RemoteAlbum remoteAlbum, SearchCriteriaBase searchCriteria) { if (searchCriteria == null) { return(Decision.Accept()); } var singleAlbumSpec = searchCriteria as AlbumSearchCriteria; if (singleAlbumSpec == null) { return(Decision.Accept()); } if (Parser.Parser.CleanArtistName(singleAlbumSpec.AlbumTitle) != Parser.Parser.CleanArtistName(remoteAlbum.ParsedAlbumInfo.AlbumTitle)) { _logger.Debug("Album does not match searched album title, skipping."); return(Decision.Reject("Wrong album")); } if (!remoteAlbum.ParsedAlbumInfo.AlbumTitle.Any()) { _logger.Debug("Full discography result during single album search, skipping."); return(Decision.Reject("Full artist pack")); } return(Decision.Accept()); }
private void RemoveGrabbed(RemoteAlbum remoteAlbum) { var pendingReleases = GetPendingReleases(remoteAlbum.Artist.Id); var albumIds = remoteAlbum.Albums.Select(e => e.Id); var existingReports = pendingReleases.Where(r => r.RemoteAlbum.Albums.Select(e => e.Id) .Intersect(albumIds) .Any()) .ToList(); if (existingReports.Empty()) { return; } var profile = remoteAlbum.Artist.QualityProfile.Value; foreach (var existingReport in existingReports) { var compare = new QualityModelComparer(profile).Compare(remoteAlbum.ParsedAlbumInfo.Quality, existingReport.RemoteAlbum.ParsedAlbumInfo.Quality); //Only remove lower/equal quality pending releases //It is safer to retry these releases on the next round than remove it and try to re-add it (if its still in the feed) if (compare >= 0) { _logger.Debug("Removing previously pending release, as it was grabbed."); Delete(existingReport); } } }
public override string Download(RemoteAlbum remoteAlbum) { var url = remoteAlbum.Release.DownloadUrl; var title = remoteAlbum.Release.Title; if (remoteAlbum.ParsedAlbumInfo.Discography) { throw new NotSupportedException("Discography releases are not supported with Pneumatic."); } title = FileNameBuilder.CleanFileName(title); //Save to the Pneumatic directory (The user will need to ensure its accessible by XBMC) var nzbFile = Path.Combine(Settings.NzbFolder, title + ".nzb"); _logger.Debug("Downloading NZB from: {0} to: {1}", url, nzbFile); _httpClient.DownloadFile(url, nzbFile); _logger.Debug("NZB Download succeeded, saved to: {0}", nzbFile); var strmFile = WriteStrmFile(title, nzbFile); return(GetDownloadClientId(strmFile)); }
public virtual Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria) { var qualityProfile = subject.Artist.QualityProfile.Value; foreach (var album in subject.Albums) { var tracksMissing = _missingFilesCache.Get(album.Id.ToString(), () => _trackService.TracksWithoutFiles(album.Id).Any(), TimeSpan.FromSeconds(30)); var trackFiles = _mediaFileService.GetFilesByAlbum(album.Id); if (!tracksMissing && trackFiles.Any()) { // Get a distinct list of all current track qualities for a given album var currentQualities = trackFiles.Select(c => c.Quality).Distinct().ToList(); _logger.Debug("Comparing file quality with report. Existing files contain {0}", currentQualities.ConcatToString()); if (!_upgradableSpecification.CutoffNotMet(qualityProfile, currentQualities, _preferredWordServiceCalculator.Calculate(subject.Artist, trackFiles[0].GetSceneOrFileName()), subject.ParsedAlbumInfo.Quality, subject.PreferredWordScore)) { _logger.Debug("Cutoff already met by existing files, rejecting."); var qualityCutoffIndex = qualityProfile.GetIndex(qualityProfile.Cutoff); var qualityCutoff = qualityProfile.Items[qualityCutoffIndex.Index]; return(Decision.Reject("Existing files meets cutoff: {0}", qualityCutoff)); } } } return(Decision.Accept()); }
protected override string AddFromMagnetLink(RemoteAlbum remoteAlbum, string hash, string magnetLink) { var actualHash = _proxy.AddTorrentFromMagnet(magnetLink, Settings); if (actualHash.IsNullOrWhiteSpace()) { throw new DownloadClientException("Deluge failed to add magnet " + magnetLink); } if (!Settings.MusicCategory.IsNullOrWhiteSpace()) { _proxy.SetLabel(actualHash, Settings.MusicCategory, Settings); } _proxy.SetTorrentSeedingConfiguration(actualHash, remoteAlbum.SeedConfiguration, Settings); var isRecentAlbum = remoteAlbum.IsRecentAlbum(); if (isRecentAlbum && Settings.RecentTvPriority == (int)DelugePriority.First || !isRecentAlbum && Settings.OlderTvPriority == (int)DelugePriority.First) { _proxy.MoveTorrentToTopInQueue(actualHash, Settings); } return(actualHash.ToUpper()); }
public virtual Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria) { foreach (var album in subject.Albums) { var tracksMissing = _missingFilesCache.Get(album.Id.ToString(), () => _trackService.TracksWithoutFiles(album.Id).Any(), TimeSpan.FromSeconds(30)); var trackFiles = _mediaFileService.GetFilesByAlbum(album.Id); if (!tracksMissing && trackFiles.Any()) { var currentQualities = trackFiles.Select(c => c.Quality).Distinct().ToList(); if (!_upgradableSpecification.IsUpgradable(subject.Artist.QualityProfile, currentQualities, _preferredWordServiceCalculator.Calculate(subject.Artist, trackFiles[0].GetSceneOrFileName(), subject.Release?.IndexerId ?? 0), subject.ParsedAlbumInfo.Quality, subject.PreferredWordScore)) { return(Decision.Reject("Existing files on disk is of equal or higher preference: {0}", currentQualities.ConcatToString())); } } } return(Decision.Accept()); }
public virtual Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria) { if (!_configService.AutoUnmonitorPreviouslyDownloadedTracks) { return(Decision.Accept()); } if (searchCriteria != null) { _logger.Debug("Skipping deleted trackfile check during search"); return(Decision.Accept()); } var missingTrackFiles = subject.Albums .SelectMany(v => _albumService.GetFilesByAlbum(v.Id)) .DistinctBy(v => v.Id) .Where(v => IsTrackFileMissing(subject.Artist, v)) .ToArray(); if (missingTrackFiles.Any()) { foreach (var missingTrackFile in missingTrackFiles) { _logger.Trace("Track file {0} is missing from disk.", missingTrackFile.Path); } _logger.Debug("Files for this album exist in the database but not on disk, will be unmonitored on next diskscan. skipping."); return(Decision.Reject("Artist is not monitored")); } return(Decision.Accept()); }
public Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria) { var size = subject.Release.Size; var maximumSize = _configService.MaximumSize.Megabytes(); if (maximumSize == 0) { _logger.Debug("Maximum size is not set."); return(Decision.Accept()); } if (subject.Release.Size == 0) { _logger.Debug("Release has unknown size, skipping size check."); return(Decision.Accept()); } _logger.Debug("Checking if release meets maximum size requirements. {0}", size.SizeSuffix()); if (size > maximumSize) { var message = $"{size.SizeSuffix()} is too big, maximum size is {maximumSize.SizeSuffix()}"; _logger.Debug(message); return(Decision.Reject(message)); } return(Decision.Accept()); }
public void Setup() { _monitoredAlbumSpecification = Mocker.Resolve <MonitoredAlbumSpecification>(); _fakeArtist = Builder <Artist> .CreateNew() .With(c => c.Monitored = true) .Build(); _firstAlbum = new Album { Monitored = true }; _secondAlbum = new Album { Monitored = true }; var singleAlbumList = new List <Album> { _firstAlbum }; var doubleAlbumList = new List <Album> { _firstAlbum, _secondAlbum }; _parseResultMulti = new RemoteAlbum { Artist = _fakeArtist, Albums = doubleAlbumList }; _parseResultSingle = new RemoteAlbum { Artist = _fakeArtist, Albums = singleAlbumList }; }
protected override string AddFromTorrentFile(RemoteAlbum remoteAlbum, string hash, string filename, byte[] fileContent) { var actualHash = _proxy.AddTorrentFromFile(filename, fileContent, Settings); if (actualHash.IsNullOrWhiteSpace()) { throw new DownloadClientException("Deluge failed to add torrent " + filename); } _proxy.SetTorrentSeedingConfiguration(actualHash, remoteAlbum.SeedConfiguration, Settings); if (Settings.MusicCategory.IsNotNullOrWhiteSpace()) { _proxy.SetTorrentLabel(actualHash, Settings.MusicCategory, Settings); } var isRecentAlbum = remoteAlbum.IsRecentAlbum(); if ((isRecentAlbum && Settings.RecentTvPriority == (int)DelugePriority.First) || (!isRecentAlbum && Settings.OlderTvPriority == (int)DelugePriority.First)) { _proxy.MoveTorrentToTopInQueue(actualHash, Settings); } return(actualHash.ToUpper()); }
protected override string AddFromMagnetLink(RemoteAlbum remoteAlbum, string hash, string magnetLink) { if (!Proxy.GetConfig(Settings).DhtEnabled&& !magnetLink.Contains("&tr=")) { throw new NotSupportedException("Magnet Links without trackers not supported if DHT is disabled"); } Proxy.AddTorrentFromUrl(magnetLink, Settings); if (Settings.MusicCategory.IsNotNullOrWhiteSpace()) { Proxy.SetTorrentLabel(hash.ToLower(), Settings.MusicCategory, Settings); } var isRecentAlbum = remoteAlbum.IsRecentAlbum(); if (isRecentAlbum && Settings.RecentTvPriority == (int)QBittorrentPriority.First || !isRecentAlbum && Settings.OlderTvPriority == (int)QBittorrentPriority.First) { Proxy.MoveTorrentToTopInQueue(hash.ToLower(), Settings); } SetInitialState(hash.ToLower()); if (remoteAlbum.SeedConfiguration != null && (remoteAlbum.SeedConfiguration.Ratio.HasValue || remoteAlbum.SeedConfiguration.SeedTime.HasValue)) { Proxy.SetTorrentSeedingConfiguration(hash.ToLower(), remoteAlbum.SeedConfiguration, Settings); } return(hash); }
private Rejection EvaluateSpec(IDecisionEngineSpecification spec, RemoteAlbum remoteAlbum, SearchCriteriaBase searchCriteriaBase = null) { try { var result = spec.IsSatisfiedBy(remoteAlbum, searchCriteriaBase); if (!result.Accepted) { return(new Rejection(result.Reason, spec.Type)); } } catch (NotImplementedException) { _logger.Trace("Spec " + spec.GetType().Name + " not implemented."); } catch (Exception e) { e.Data.Add("report", remoteAlbum.Release.ToJson()); e.Data.Add("parsed", remoteAlbum.ParsedAlbumInfo.ToJson()); _logger.Error(e, "Couldn't evaluate decision on {0}", remoteAlbum.Release.Title); return(new Rejection($"{spec.GetType().Name}: {e.Message}")); } return(null); }
public void Setup() { _artist = Builder <Artist> .CreateNew().With(s => s.Id = 1).Build(); _album1 = Builder <Album> .CreateNew().With(s => s.ReleaseDate = DateTime.Today).Build(); _album2 = Builder <Album> .CreateNew().With(s => s.ReleaseDate = DateTime.Today).Build(); _remoteAlbum = new RemoteAlbum { Artist = _artist, Albums = new List <Album> { _album1 }, Release = new TorrentInfo { IndexerId = 1, Title = "Artist - Album [FLAC-RlsGrp]", PublishDate = DateTime.Today } }; _indexerDefinition = new IndexerDefinition { Settings = new TorrentRssIndexerSettings { EarlyReleaseLimit = 5 } }; Mocker.GetMock <IIndexerFactory>() .Setup(v => v.Get(1)) .Returns(_indexerDefinition); }
public void Setup() { _remoteAlbum = new RemoteAlbum() { Release = new ReleaseInfo() }; }
public void Setup() { Mocker.Resolve <UpgradableSpecification>(); _firstFile = new TrackFile { Quality = new QualityModel(Quality.FLAC, new Revision(version: 2)), DateAdded = DateTime.Now }; _secondFile = new TrackFile { Quality = new QualityModel(Quality.FLAC, new Revision(version: 2)), DateAdded = DateTime.Now }; var singleAlbumList = new List <Album> { new Album { } }; var doubleAlbumList = new List <Album> { new Album { }, new Album { }, new Album { } }; var fakeArtist = Builder <Artist> .CreateNew() .With(c => c.QualityProfile = new QualityProfile { UpgradeAllowed = true, Cutoff = Quality.MP3_320.Id, Items = Qualities.QualityFixture.GetDefaultQualities() }) .Build(); Mocker.GetMock <ITrackService>() .Setup(c => c.TracksWithoutFiles(It.IsAny <int>())) .Returns(new List <Track>()); Mocker.GetMock <IMediaFileService>() .Setup(c => c.GetFilesByAlbum(It.IsAny <int>())) .Returns(new List <TrackFile> { _firstFile, _secondFile }); _parseResultMulti = new RemoteAlbum { Artist = fakeArtist, ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_256, new Revision(version: 2)) }, Albums = doubleAlbumList }; _parseResultSingle = new RemoteAlbum { Artist = fakeArtist, ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_256, new Revision(version: 2)) }, Albums = singleAlbumList }; }
private int GetDelay(RemoteAlbum remoteAlbum) { var delayProfile = _delayProfileService.AllForTags(remoteAlbum.Artist.Tags).OrderBy(d => d.Order).First(); var delay = delayProfile.GetProtocolDelay(remoteAlbum.Release.DownloadProtocol); var minimumAge = _configService.MinimumAge; return(new[] { delay, minimumAge }.Max()); }
public Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria) { var queue = _queueService.GetQueue(); var matchingAlbum = queue.Where(q => q.RemoteAlbum != null && q.RemoteAlbum.Artist != null && q.RemoteAlbum.Artist.Id == subject.Artist.Id && q.RemoteAlbum.Albums.Select(e => e.Id).Intersect(subject.Albums.Select(e => e.Id)).Any()) .ToList(); foreach (var queueItem in matchingAlbum) { var remoteAlbum = queueItem.RemoteAlbum; var qualityProfile = subject.Artist.QualityProfile.Value; _logger.Debug("Checking if existing release in queue meets cutoff. Queued quality is: {0}", remoteAlbum.ParsedAlbumInfo.Quality); var queuedItemPreferredWordScore = _preferredWordServiceCalculator.Calculate(subject.Artist, queueItem.Title); if (!_upgradableSpecification.CutoffNotMet(qualityProfile, new List <QualityModel> { remoteAlbum.ParsedAlbumInfo.Quality }, queuedItemPreferredWordScore, subject.ParsedAlbumInfo.Quality, subject.PreferredWordScore)) { return(Decision.Reject("Release in queue already meets cutoff: {0}", remoteAlbum.ParsedAlbumInfo.Quality)); } _logger.Debug("Checking if release is higher quality than queued release. Queued: {0}", remoteAlbum.ParsedAlbumInfo.Quality); if (!_upgradableSpecification.IsUpgradable(qualityProfile, new List <QualityModel> { remoteAlbum.ParsedAlbumInfo.Quality }, queuedItemPreferredWordScore, subject.ParsedAlbumInfo.Quality, subject.PreferredWordScore)) { return(Decision.Reject("Release in queue is of equal or higher preference: {0}", remoteAlbum.ParsedAlbumInfo.Quality)); } _logger.Debug("Checking if profiles allow upgrading. Queued: {0}", remoteAlbum.ParsedAlbumInfo.Quality); if (!_upgradableSpecification.IsUpgradeAllowed(qualityProfile, new List <QualityModel> { remoteAlbum.ParsedAlbumInfo.Quality }, subject.ParsedAlbumInfo.Quality)) { return(Decision.Reject("Another release is queued and the Quality profile does not allow upgrades")); } } return(Decision.Accept()); }
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", }; // 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)); // verify download has null remote album var trackedDownloads = Subject.GetTrackedDownloads(); trackedDownloads.Should().HaveCount(1); trackedDownloads.First().RemoteAlbum.Should().BeNull(); }
public void Setup() { Mocker.Resolve <UpgradableSpecification>(); _upgradeHistory = Mocker.Resolve <HistorySpecification>(); var singleAlbumList = new List <Album> { new Album { Id = FIRST_ALBUM_ID } }; var doubleAlbumList = new List <Album> { new Album { Id = FIRST_ALBUM_ID }, new Album { Id = SECOND_ALBUM_ID }, new Album { Id = 3 } }; _fakeArtist = Builder <Artist> .CreateNew() .With(c => c.QualityProfile = new QualityProfile { UpgradeAllowed = true, Cutoff = Quality.MP3_320.Id, Items = Qualities.QualityFixture.GetDefaultQualities() }) .Build(); _parseResultMulti = new RemoteAlbum { Artist = _fakeArtist, ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) }, Albums = doubleAlbumList }; _parseResultSingle = new RemoteAlbum { Artist = _fakeArtist, ParsedAlbumInfo = new ParsedAlbumInfo { Quality = new QualityModel(Quality.MP3_192, new Revision(version: 2)) }, Albums = singleAlbumList }; _upgradableQuality = new QualityModel(Quality.MP3_192, new Revision(version: 1)); _notupgradableQuality = new QualityModel(Quality.MP3_320, new Revision(version: 2)); Mocker.GetMock <IConfigService>() .SetupGet(s => s.EnableCompletedDownloadHandling) .Returns(true); }
public WebhookRelease(QualityModel quality, RemoteAlbum remoteAlbum) { Quality = quality.Quality.Name; QualityVersion = quality.Revision.Version; ReleaseGroup = remoteAlbum.ParsedAlbumInfo.ReleaseGroup; ReleaseTitle = remoteAlbum.Release.Title; Indexer = remoteAlbum.Release.Indexer; Size = remoteAlbum.Release.Size; }
public Decision IsSatisfiedBy(RemoteAlbum subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Beginning size check for: {0}", subject); var quality = subject.ParsedAlbumInfo.Quality.Quality; if (subject.Release.Size == 0) { _logger.Debug("Release has unknown size, skipping size check."); return(Decision.Accept()); } var qualityDefinition = _qualityDefinitionService.Get(quality); if (qualityDefinition.MinSize.HasValue) { var minSize = qualityDefinition.MinSize.Value.Kilobits(); var minReleaseDuration = subject.Albums.Select(a => a.AlbumReleases.Value.Where(r => r.Monitored || a.AnyReleaseOk).Select(r => r.Duration).Min()).Sum() / 1000; //Multiply minSize by smallest release duration minSize = minSize * minReleaseDuration; //If the parsed size is smaller than minSize we don't want it if (subject.Release.Size < minSize) { var runtimeMessage = $"{minReleaseDuration}sec"; _logger.Debug("Item: {0}, Size: {1} is smaller than minimum allowed size ({2} bytes for {3}), rejecting.", subject, subject.Release.Size, minSize, runtimeMessage); return(Decision.Reject("{0} is smaller than minimum allowed {1}", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix())); } } if (!qualityDefinition.MaxSize.HasValue || qualityDefinition.MaxSize.Value == 0) { _logger.Debug("Max size is unlimited - skipping check."); } else { var maxSize = qualityDefinition.MaxSize.Value.Kilobits(); var maxReleaseDuration = subject.Albums.Select(a => a.AlbumReleases.Value.Where(r => r.Monitored || a.AnyReleaseOk).Select(r => r.Duration).Max()).Sum() / 1000; //Multiply maxSize by Album.Duration maxSize = maxSize * maxReleaseDuration; //If the parsed size is greater than maxSize we don't want it if (subject.Release.Size > maxSize) { var runtimeMessage = $"{maxReleaseDuration}sec"; _logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2} bytes for {3}), rejecting.", subject, subject.Release.Size, maxSize, runtimeMessage); return(Decision.Reject("{0} is larger than maximum allowed {1}", subject.Release.Size.SizeSuffix(), maxSize.SizeSuffix())); } } _logger.Debug("Item: {0}, meets size constraints.", subject); return(Decision.Accept()); }
protected override string AddFromTorrentFile(RemoteAlbum remoteAlbum, string hash, string filename, byte[] fileContent) { var setShareLimits = remoteAlbum.SeedConfiguration != null && (remoteAlbum.SeedConfiguration.Ratio.HasValue || remoteAlbum.SeedConfiguration.SeedTime.HasValue); var addHasSetShareLimits = setShareLimits && ProxyApiVersion >= new Version(2, 8, 1); var isRecentAlbum = remoteAlbum.IsRecentAlbum(); var moveToTop = (isRecentAlbum && Settings.RecentTvPriority == (int)QBittorrentPriority.First) || (!isRecentAlbum && Settings.OlderTvPriority == (int)QBittorrentPriority.First); var forceStart = (QBittorrentState)Settings.InitialState == QBittorrentState.ForceStart; Proxy.AddTorrentFromFile(filename, fileContent, addHasSetShareLimits ? remoteAlbum.SeedConfiguration : null, Settings); if ((!addHasSetShareLimits && setShareLimits) || moveToTop || forceStart) { if (!WaitForTorrent(hash)) { return(hash); } if (!addHasSetShareLimits && setShareLimits) { try { Proxy.SetTorrentSeedingConfiguration(hash.ToLower(), remoteAlbum.SeedConfiguration, Settings); } catch (Exception ex) { _logger.Warn(ex, "Failed to set the torrent seed criteria for {0}.", hash); } } if (moveToTop) { try { Proxy.MoveTorrentToTopInQueue(hash.ToLower(), Settings); } catch (Exception ex) { _logger.Warn(ex, "Failed to set the torrent priority for {0}.", hash); } } if (forceStart) { try { Proxy.SetForceStart(hash.ToLower(), true, Settings); } catch (Exception ex) { _logger.Warn(ex, "Failed to set ForceStart for {0}.", hash); } } } return(hash); }