mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-18 21:35:51 -04:00
Compare commits
165 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e3dc31cca5 | |||
| ddc6ccbf15 | |||
| 18773bc665 | |||
| 91c71ed6a0 | |||
| f3b5d9a1d6 | |||
| 83deba1c99 | |||
| 9787cf6cdd | |||
| 7433e89467 | |||
| 0aa6066a6f | |||
| 3dd14c72c8 | |||
| 0d85c7435c | |||
| a3c0f4cb3f | |||
| 3f2da1441f | |||
| f49d68ad6a | |||
| f138d4f677 | |||
| aa977eb2d5 | |||
| e0f72e4853 | |||
| 83560ad937 | |||
| 5cace1d857 | |||
| 39322cbbca | |||
| 46daa11c46 | |||
| 98e2bd00ab | |||
| 0f2234bcdc | |||
| 3f05ef810e | |||
| aab425ee5b | |||
| f7bc889723 | |||
| cc4fb5a40b | |||
| bbb4880ba4 | |||
| a2098a5797 | |||
| 93bdac31ea | |||
| 92a588751a | |||
| 272db9d483 | |||
| 9d75fc18a1 | |||
| d8d60c6bb0 | |||
| 8c656626d6 | |||
| b773119193 | |||
| bdc0db3357 | |||
| f3b3c9ff6a | |||
| 7d394dcff2 | |||
| ff11388009 | |||
| b492fece6c | |||
| 5394f1dee9 | |||
| e742371d15 | |||
| d03ee006fc | |||
| 897d76c4a2 | |||
| 349dd12161 | |||
| d84e6c84f5 | |||
| dfcdf8871c | |||
| 7122962dc8 | |||
| 6432928b7d | |||
| ed1d6e59b5 | |||
| 8b2d85aee5 | |||
| 392d63fe57 | |||
| 1c086b057a | |||
| 6bbe55a46c | |||
| 7a269efcbc | |||
| 06bd6db601 | |||
| 3dc9d3a420 | |||
| 91ba503700 | |||
| 28d27dca5c | |||
| e33265b58d | |||
| 22fcb04773 | |||
| f9f67873ad | |||
| b1d345f165 | |||
| 1c6a32b684 | |||
| 55ac2dd1bb | |||
| 997dce288d | |||
| 4d745d3600 | |||
| dbd1080f5c | |||
| 76963d8109 | |||
| 6b106c1b38 | |||
| 0016cc59af | |||
| 8b9d0f7b19 | |||
| 3a4b01cf6f | |||
| 15acb9d204 | |||
| 21fa96f78f | |||
| fe4e11d9c1 | |||
| d22d5fcfc3 | |||
| cdca4a8585 | |||
| 46552785f5 | |||
| 816c62979a | |||
| ca164c2a24 | |||
| bf3c6f95eb | |||
| f07f2e77f6 | |||
| 50fdbd896c | |||
| bab7bd20cd | |||
| 0678908fd9 | |||
| 9d29776e8e | |||
| 140a220340 | |||
| 731e607666 | |||
| 97ee66465d | |||
| a0050fedd3 | |||
| 89e5001bad | |||
| 056fb154a8 | |||
| 3edc2b80cf | |||
| a1745cd02e | |||
| 1c0f9b64ca | |||
| 7d6a518f30 | |||
| 9f2fcebc24 | |||
| 91295f50b0 | |||
| 68bf97f52c | |||
| 363048e68e | |||
| 9c20c0b889 | |||
| 50891e5dd7 | |||
| f393a95501 | |||
| a68dd6d2f7 | |||
| dadf6708ab | |||
| 7a86c78896 | |||
| 81688399c0 | |||
| 1e28a2e5d4 | |||
| c5bb259555 | |||
| 0d5d75d6ea | |||
| 5bae9bbbcc | |||
| a3e681078f | |||
| 758228e159 | |||
| 1b900a006f | |||
| 9b5c5169ef | |||
| e78a55ac6e | |||
| e82cf70399 | |||
| e7d65ee4ae | |||
| 1db3669afa | |||
| 93e55b7575 | |||
| f850c65b56 | |||
| 297348fffe | |||
| 07ff6558d1 | |||
| 85843efcb0 | |||
| 3d4b1c3be5 | |||
| a3f389af5e | |||
| 1aeb3c6fd6 | |||
| 6ab6c016c0 | |||
| a1961603d7 | |||
| 50ac95dec5 | |||
| a16e46cf38 | |||
| ea33b75764 | |||
| 31e657d052 | |||
| fe0dfef83c | |||
| bc1a47ff5a | |||
| 4e8089dd42 | |||
| 6dc9f90a8b | |||
| 1aae3ae2b5 | |||
| 75436bcce4 | |||
| 61df3ef40e | |||
| f45aab27d1 | |||
| f477c46406 | |||
| 2af07d7e0d | |||
| df691488a9 | |||
| 800e7ae508 | |||
| fcf156293e | |||
| 94f44a0eb7 | |||
| 1e2c28f67a | |||
| 62b45f7ea7 | |||
| f577590ad6 | |||
| 0941247f63 | |||
| 3170060f37 | |||
| 35b384439f | |||
| 0d1150d4d2 | |||
| 1f68b46575 | |||
| 32c5c4d741 | |||
| 0cb15121e5 | |||
| 808033a01c | |||
| 736e0d2e70 | |||
| 96741570c5 | |||
| 8feb3fee98 | |||
| 07e3e44a68 | |||
| d67d405024 |
@@ -1,9 +1,12 @@
|
|||||||
|
**Description:**
|
||||||
|
|
||||||
|
Provide a description of the feature request or bug here, the more details the better.
|
||||||
|
Please also try to include the following if you are reporting a bug
|
||||||
|
|
||||||
|
**Radarr Version:**
|
||||||
|
|
||||||
|
**Logs:**
|
||||||
|
|
||||||
|
|
||||||
Please use the search bar and make sure you are not submitting an already submitted issue.
|
Please use the search bar and make sure you are not submitting an already submitted issue.
|
||||||
|
Visit our [Discord server](https://discord.gg/NWYch8M) for support or longer discussions.
|
||||||
Provide a description of the feature request or bug, the more details the better.
|
|
||||||
When possible include a log!
|
|
||||||
|
|
||||||
Please use our [Discord server](https://discord.gg/NWYch8M) for support or longer discussions.
|
|
||||||
|
|||||||
@@ -2,13 +2,11 @@
|
|||||||
YES | NO
|
YES | NO
|
||||||
|
|
||||||
#### Description
|
#### Description
|
||||||
A few sentences describing the overall goals of the pull request's commits.
|
|
||||||
|
|
||||||
#### Todos
|
#### Todos
|
||||||
- [ ] Tests
|
- [ ] Tests
|
||||||
- [ ] Documentation
|
|
||||||
|
|
||||||
|
|
||||||
#### Issues Fixed or Closed by this PR
|
#### Issues Fixed or Closed by this PR
|
||||||
|
|
||||||
*
|
* #
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ addons:
|
|||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- nodejs
|
- nodejs
|
||||||
- npm
|
# - npm apparently not needed anymore.
|
||||||
script:
|
script:
|
||||||
- ./build.sh
|
- ./build.sh
|
||||||
- chmod +x test.sh
|
- chmod +x test.sh
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
"run-sequence": "1.1.1",
|
"run-sequence": "1.1.1",
|
||||||
"streamqueue": "1.1.0",
|
"streamqueue": "1.1.0",
|
||||||
"tar.gz": "0.1.1",
|
"tar.gz": "0.1.1",
|
||||||
|
"url-search-params": "^0.6.1",
|
||||||
"webpack": "1.12.0",
|
"webpack": "1.12.0",
|
||||||
"webpack-stream": "2.1.0"
|
"webpack-stream": "2.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -16,13 +16,13 @@ namespace NzbDrone.Api.Calendar
|
|||||||
{
|
{
|
||||||
public class CalendarFeedModule : NzbDroneFeedModule
|
public class CalendarFeedModule : NzbDroneFeedModule
|
||||||
{
|
{
|
||||||
private readonly IEpisodeService _episodeService;
|
private readonly IMovieService _movieService;
|
||||||
private readonly ITagService _tagService;
|
private readonly ITagService _tagService;
|
||||||
|
|
||||||
public CalendarFeedModule(IEpisodeService episodeService, ITagService tagService)
|
public CalendarFeedModule(IMovieService movieService, ITagService tagService)
|
||||||
: base("calendar")
|
: base("calendar")
|
||||||
{
|
{
|
||||||
_episodeService = episodeService;
|
_movieService = movieService;
|
||||||
_tagService = tagService;
|
_tagService = tagService;
|
||||||
|
|
||||||
Get["/NzbDrone.ics"] = options => GetCalendarFeed();
|
Get["/NzbDrone.ics"] = options => GetCalendarFeed();
|
||||||
@@ -37,7 +37,7 @@ namespace NzbDrone.Api.Calendar
|
|||||||
var start = DateTime.Today.AddDays(-pastDays);
|
var start = DateTime.Today.AddDays(-pastDays);
|
||||||
var end = DateTime.Today.AddDays(futureDays);
|
var end = DateTime.Today.AddDays(futureDays);
|
||||||
var unmonitored = false;
|
var unmonitored = false;
|
||||||
var premiersOnly = false;
|
//var premiersOnly = false;
|
||||||
var tags = new List<int>();
|
var tags = new List<int>();
|
||||||
|
|
||||||
// TODO: Remove start/end parameters in v3, they don't work well for iCal
|
// TODO: Remove start/end parameters in v3, they don't work well for iCal
|
||||||
@@ -46,7 +46,7 @@ namespace NzbDrone.Api.Calendar
|
|||||||
var queryPastDays = Request.Query.PastDays;
|
var queryPastDays = Request.Query.PastDays;
|
||||||
var queryFutureDays = Request.Query.FutureDays;
|
var queryFutureDays = Request.Query.FutureDays;
|
||||||
var queryUnmonitored = Request.Query.Unmonitored;
|
var queryUnmonitored = Request.Query.Unmonitored;
|
||||||
var queryPremiersOnly = Request.Query.PremiersOnly;
|
// var queryPremiersOnly = Request.Query.PremiersOnly;
|
||||||
var queryTags = Request.Query.Tags;
|
var queryTags = Request.Query.Tags;
|
||||||
|
|
||||||
if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value);
|
if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value);
|
||||||
@@ -69,10 +69,10 @@ namespace NzbDrone.Api.Calendar
|
|||||||
unmonitored = bool.Parse(queryUnmonitored.Value);
|
unmonitored = bool.Parse(queryUnmonitored.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queryPremiersOnly.HasValue)
|
//if (queryPremiersOnly.HasValue)
|
||||||
{
|
//{
|
||||||
premiersOnly = bool.Parse(queryPremiersOnly.Value);
|
// premiersOnly = bool.Parse(queryPremiersOnly.Value);
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (queryTags.HasValue)
|
if (queryTags.HasValue)
|
||||||
{
|
{
|
||||||
@@ -80,43 +80,56 @@ namespace NzbDrone.Api.Calendar
|
|||||||
tags.AddRange(tagInput.Split(',').Select(_tagService.GetTag).Select(t => t.Id));
|
tags.AddRange(tagInput.Split(',').Select(_tagService.GetTag).Select(t => t.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
var episodes = _episodeService.EpisodesBetweenDates(start, end, unmonitored);
|
var movies = _movieService.GetMoviesBetweenDates(start, end, unmonitored);
|
||||||
var calendar = new Ical.Net.Calendar
|
var calendar = new Ical.Net.Calendar
|
||||||
{
|
{
|
||||||
ProductId = "-//sonarr.tv//Sonarr//EN"
|
ProductId = "-//radarr.video//Radarr//EN"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
foreach (var movie in movies.OrderBy(v => v.Added))
|
||||||
|
|
||||||
foreach (var episode in episodes.OrderBy(v => v.AirDateUtc.Value))
|
|
||||||
{
|
{
|
||||||
if (premiersOnly && (episode.SeasonNumber == 0 || episode.EpisodeNumber != 1))
|
if (tags.Any() && tags.None(movie.Tags.Contains))
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tags.Any() && tags.None(episode.Series.Tags.Contains))
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var occurrence = calendar.Create<Event>();
|
var occurrence = calendar.Create<Event>();
|
||||||
occurrence.Uid = "NzbDrone_episode_" + episode.Id;
|
occurrence.Uid = "NzbDrone_movie_" + movie.Id;
|
||||||
occurrence.Status = episode.HasFile ? EventStatus.Confirmed : EventStatus.Tentative;
|
occurrence.Status = movie.HasFile ? EventStatus.Confirmed : EventStatus.Tentative;
|
||||||
occurrence.Start = new CalDateTime(episode.AirDateUtc.Value) { HasTime = true };
|
|
||||||
occurrence.End = new CalDateTime(episode.AirDateUtc.Value.AddMinutes(episode.Series.Runtime)) { HasTime = true };
|
|
||||||
occurrence.Description = episode.Overview;
|
|
||||||
occurrence.Categories = new List<string>() { episode.Series.Network };
|
|
||||||
|
|
||||||
switch (episode.Series.SeriesType)
|
switch (movie.Status)
|
||||||
{
|
{
|
||||||
case SeriesTypes.Daily:
|
case MovieStatusType.PreDB:
|
||||||
occurrence.Summary = $"{episode.Series.Title} - {episode.Title}";
|
if (movie.PhysicalRelease != null)
|
||||||
|
{
|
||||||
|
occurrence.Start = new CalDateTime(movie.PhysicalRelease.Value) { HasTime = true };
|
||||||
|
occurrence.End = new CalDateTime(movie.PhysicalRelease.Value.AddMinutes(movie.Runtime)) { HasTime = true };
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MovieStatusType.InCinemas:
|
||||||
|
if (movie.InCinemas != null)
|
||||||
|
{
|
||||||
|
occurrence.Start = new CalDateTime(movie.InCinemas.Value) { HasTime = true };
|
||||||
|
occurrence.End = new CalDateTime(movie.InCinemas.Value.AddMinutes(movie.Runtime)) { HasTime = true };
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MovieStatusType.Announced:
|
||||||
|
continue; // no date
|
||||||
default:
|
default:
|
||||||
occurrence.Summary =$"{episode.Series.Title} - {episode.SeasonNumber}x{episode.EpisodeNumber:00} - {episode.Title}";
|
if (movie.PhysicalRelease != null)
|
||||||
|
{
|
||||||
|
occurrence.Start = new CalDateTime(movie.PhysicalRelease.Value) { HasTime = true };
|
||||||
|
occurrence.End = new CalDateTime(movie.PhysicalRelease.Value.AddMinutes(movie.Runtime)) { HasTime = true };
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
occurrence.Description = movie.Overview;
|
||||||
|
occurrence.Categories = new List<string>() { movie.Studio };
|
||||||
|
|
||||||
|
occurrence.Summary = $"{movie.Title}";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var serializer = (IStringSerializer) new SerializerFactory().Build(calendar.GetType(), new SerializationContext());
|
var serializer = (IStringSerializer) new SerializerFactory().Build(calendar.GetType(), new SerializationContext());
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Nancy;
|
||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Episodes;
|
||||||
using NzbDrone.Api.Movie;
|
using NzbDrone.Api.Movie;
|
||||||
|
using NzbDrone.Api.Series;
|
||||||
using NzbDrone.Core.Datastore.Events;
|
using NzbDrone.Core.Datastore.Events;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace NzbDrone.Api.Config
|
|||||||
public int MinimumAge { get; set; }
|
public int MinimumAge { get; set; }
|
||||||
public int Retention { get; set; }
|
public int Retention { get; set; }
|
||||||
public int RssSyncInterval { get; set; }
|
public int RssSyncInterval { get; set; }
|
||||||
|
public int AvailabilityDelay { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IndexerConfigResourceMapper
|
public static class IndexerConfigResourceMapper
|
||||||
@@ -19,6 +20,7 @@ namespace NzbDrone.Api.Config
|
|||||||
MinimumAge = model.MinimumAge,
|
MinimumAge = model.MinimumAge,
|
||||||
Retention = model.Retention,
|
Retention = model.Retention,
|
||||||
RssSyncInterval = model.RssSyncInterval,
|
RssSyncInterval = model.RssSyncInterval,
|
||||||
|
AvailabilityDelay = model.AvailabilityDelay,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,11 @@ namespace NzbDrone.Api.Config
|
|||||||
public class NetImportConfigResource : RestResource
|
public class NetImportConfigResource : RestResource
|
||||||
{
|
{
|
||||||
public int NetImportSyncInterval { get; set; }
|
public int NetImportSyncInterval { get; set; }
|
||||||
|
public string ListSyncLevel { get; set; }
|
||||||
|
public string ImportExclusions { get; set; }
|
||||||
|
public string TraktAuthToken { get; set; }
|
||||||
|
public string TraktRefreshToken { get; set; }
|
||||||
|
public int TraktTokenExpiry { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class NetImportConfigResourceMapper
|
public static class NetImportConfigResourceMapper
|
||||||
@@ -14,7 +19,12 @@ namespace NzbDrone.Api.Config
|
|||||||
{
|
{
|
||||||
return new NetImportConfigResource
|
return new NetImportConfigResource
|
||||||
{
|
{
|
||||||
NetImportSyncInterval = model.NetImportSyncInterval
|
NetImportSyncInterval = model.NetImportSyncInterval,
|
||||||
|
ListSyncLevel = model.ListSyncLevel,
|
||||||
|
ImportExclusions = model.ImportExclusions,
|
||||||
|
TraktAuthToken = model.TraktAuthToken,
|
||||||
|
TraktRefreshToken = model.TraktRefreshToken,
|
||||||
|
TraktTokenExpiry = model.TraktTokenExpiry,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace NzbDrone.Api.EpisodeFiles
|
|||||||
|
|
||||||
private void DeleteEpisodeFile(int id)
|
private void DeleteEpisodeFile(int id)
|
||||||
{
|
{
|
||||||
var episodeFile = _mediaFileService.Get(id);
|
var episodeFile = _mediaFileService.Get(id);
|
||||||
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||||
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||||
|
|
||||||
|
|||||||
@@ -66,13 +66,9 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
private Response LogError(NancyContext context, Exception exception)
|
private Response LogError(NancyContext context, Exception exception)
|
||||||
{
|
{
|
||||||
var response = _errorPipeline.HandleException(context, exception);
|
var response = _errorPipeline.HandleException(context, exception);
|
||||||
|
|
||||||
context.Response = response;
|
context.Response = response;
|
||||||
|
|
||||||
LogEnd(context);
|
LogEnd(context);
|
||||||
|
|
||||||
context.Response = null;
|
context.Response = null;
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,12 +76,9 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
|||||||
{
|
{
|
||||||
if (request.Url.Query.IsNotNullOrWhiteSpace())
|
if (request.Url.Query.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
return string.Concat(request.Url.Path, "?", request.Url.Query);
|
return string.Concat(request.Url.Path, request.Url.Query);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return request.Url.Path;
|
|
||||||
}
|
}
|
||||||
|
return request.Url.Path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Nancy;
|
||||||
|
using NzbDrone.Api.Extensions;
|
||||||
|
using NzbDrone.Core.MediaCover;
|
||||||
|
using NzbDrone.Core.MetadataSource;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
using Marr.Data;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||||
|
using NzbDrone.Core.RootFolders;
|
||||||
|
using NzbDrone.Common.Cache;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Movie
|
||||||
|
{
|
||||||
|
|
||||||
|
public class UnmappedComparer : IComparer<UnmappedFolder>
|
||||||
|
{
|
||||||
|
public int Compare(UnmappedFolder a, UnmappedFolder b)
|
||||||
|
{
|
||||||
|
return a.Name.CompareTo(b.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MovieBulkImportModule : NzbDroneRestModule<MovieResource>
|
||||||
|
{
|
||||||
|
private readonly ISearchForNewMovie _searchProxy;
|
||||||
|
private readonly IRootFolderService _rootFolderService;
|
||||||
|
private readonly IMakeImportDecision _importDecisionMaker;
|
||||||
|
private readonly IDiskScanService _diskScanService;
|
||||||
|
private readonly ICached<Core.Tv.Movie> _mappedMovies;
|
||||||
|
private readonly IMovieService _movieService;
|
||||||
|
|
||||||
|
public MovieBulkImportModule(ISearchForNewMovie searchProxy, IRootFolderService rootFolderService, IMakeImportDecision importDecisionMaker,
|
||||||
|
IDiskScanService diskScanService, ICacheManager cacheManager, IMovieService movieService)
|
||||||
|
: base("/movies/bulkimport")
|
||||||
|
{
|
||||||
|
_searchProxy = searchProxy;
|
||||||
|
_rootFolderService = rootFolderService;
|
||||||
|
_importDecisionMaker = importDecisionMaker;
|
||||||
|
_diskScanService = diskScanService;
|
||||||
|
_mappedMovies = cacheManager.GetCache<Core.Tv.Movie>(GetType(), "mappedMoviesCache");
|
||||||
|
_movieService = movieService;
|
||||||
|
Get["/"] = x => Search();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Response Search()
|
||||||
|
{
|
||||||
|
if (Request.Query.Id == 0)
|
||||||
|
{
|
||||||
|
//Todo error handling
|
||||||
|
}
|
||||||
|
|
||||||
|
RootFolder rootFolder = _rootFolderService.Get(Request.Query.Id);
|
||||||
|
|
||||||
|
int page = Request.Query.page;
|
||||||
|
int per_page = Request.Query.per_page;
|
||||||
|
|
||||||
|
int min = (page - 1) * per_page;
|
||||||
|
|
||||||
|
int max = page * per_page;
|
||||||
|
|
||||||
|
var unmapped = rootFolder.UnmappedFolders.OrderBy(f => f.Name).ToList();
|
||||||
|
|
||||||
|
int total_count = unmapped.Count;
|
||||||
|
|
||||||
|
if (Request.Query.total_entries.HasValue)
|
||||||
|
{
|
||||||
|
total_count = Request.Query.total_entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
max = total_count >= max ? max : total_count;
|
||||||
|
|
||||||
|
var paged = unmapped.GetRange(min, max-min);
|
||||||
|
|
||||||
|
var mapped = paged.Select(f =>
|
||||||
|
{
|
||||||
|
Core.Tv.Movie m = null;
|
||||||
|
|
||||||
|
var mappedMovie = _mappedMovies.Find(f.Name);
|
||||||
|
|
||||||
|
if (mappedMovie != null)
|
||||||
|
{
|
||||||
|
return mappedMovie;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsedTitle = Parser.ParseMoviePath(f.Name);
|
||||||
|
if (parsedTitle == null)
|
||||||
|
{
|
||||||
|
m = new Core.Tv.Movie
|
||||||
|
{
|
||||||
|
Title = f.Name.Replace(".", " ").Replace("-", " "),
|
||||||
|
Path = f.Path,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m = new Core.Tv.Movie
|
||||||
|
{
|
||||||
|
Title = parsedTitle.MovieTitle,
|
||||||
|
Year = parsedTitle.Year,
|
||||||
|
ImdbId = parsedTitle.ImdbId,
|
||||||
|
Path = f.Path
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var files = _diskScanService.GetVideoFiles(f.Path);
|
||||||
|
|
||||||
|
var decisions = _importDecisionMaker.GetImportDecisions(files.ToList(), m, true);
|
||||||
|
|
||||||
|
var decision = decisions.Where(d => d.Approved && !d.Rejections.Any()).FirstOrDefault();
|
||||||
|
|
||||||
|
if (decision != null)
|
||||||
|
{
|
||||||
|
var local = decision.LocalMovie;
|
||||||
|
|
||||||
|
m.MovieFile = new LazyLoaded<MovieFile>(new MovieFile
|
||||||
|
{
|
||||||
|
Path = local.Path,
|
||||||
|
Edition = local.ParsedMovieInfo.Edition,
|
||||||
|
Quality = local.Quality,
|
||||||
|
MediaInfo = local.MediaInfo,
|
||||||
|
ReleaseGroup = local.ParsedMovieInfo.ReleaseGroup,
|
||||||
|
RelativePath = f.Path.GetRelativePath(local.Path)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
mappedMovie = _searchProxy.MapMovieToTmdbMovie(m);
|
||||||
|
|
||||||
|
if (mappedMovie != null)
|
||||||
|
{
|
||||||
|
mappedMovie.Monitored = true;
|
||||||
|
|
||||||
|
_mappedMovies.Set(f.Name, mappedMovie, TimeSpan.FromDays(2));
|
||||||
|
|
||||||
|
return mappedMovie;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return new PagingResource<MovieResource>
|
||||||
|
{
|
||||||
|
Page = page,
|
||||||
|
PageSize = per_page,
|
||||||
|
SortDirection = SortDirection.Ascending,
|
||||||
|
SortKey = Request.Query.sort_by,
|
||||||
|
TotalRecords = total_count - mapped.Where(m => m == null).Count(),
|
||||||
|
Records = MapToResource(mapped.Where(m => m != null)).ToList()
|
||||||
|
}.AsResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static IEnumerable<MovieResource> MapToResource(IEnumerable<Core.Tv.Movie> movies)
|
||||||
|
{
|
||||||
|
foreach (var currentMovie in movies)
|
||||||
|
{
|
||||||
|
var resource = currentMovie.ToResource();
|
||||||
|
var poster = currentMovie.Images.FirstOrDefault(c => c.CoverType == MediaCoverTypes.Poster);
|
||||||
|
if (poster != null)
|
||||||
|
{
|
||||||
|
resource.RemotePoster = poster.Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return resource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,77 +13,60 @@ using NzbDrone.SignalR;
|
|||||||
|
|
||||||
namespace NzbDrone.Api.EpisodeFiles
|
namespace NzbDrone.Api.EpisodeFiles
|
||||||
{
|
{
|
||||||
public class MovieFileModule : NzbDroneRestModuleWithSignalR<MovieFileResource, MovieFile>
|
public class MovieFileModule : NzbDroneRestModuleWithSignalR<MovieFileResource, MovieFile>, IHandle<MovieFileAddedEvent>
|
||||||
//IHandle<EpisodeFileAddedEvent>
|
|
||||||
{
|
{
|
||||||
private readonly IMediaFileService _mediaFileService;
|
private readonly IMediaFileService _mediaFileService;
|
||||||
private readonly IRecycleBinProvider _recycleBinProvider;
|
private readonly IRecycleBinProvider _recycleBinProvider;
|
||||||
private readonly IMovieService _seriesService;
|
private readonly IMovieService _movieService;
|
||||||
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public MovieFileModule(IBroadcastSignalRMessage signalRBroadcaster,
|
public MovieFileModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
IMediaFileService mediaFileService,
|
IMediaFileService mediaFileService,
|
||||||
IRecycleBinProvider recycleBinProvider,
|
IRecycleBinProvider recycleBinProvider,
|
||||||
IMovieService seriesService,
|
IMovieService movieService,
|
||||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(signalRBroadcaster)
|
: base(signalRBroadcaster)
|
||||||
{
|
{
|
||||||
_mediaFileService = mediaFileService;
|
_mediaFileService = mediaFileService;
|
||||||
_recycleBinProvider = recycleBinProvider;
|
_recycleBinProvider = recycleBinProvider;
|
||||||
_seriesService = seriesService;
|
_movieService = movieService;
|
||||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
GetResourceById = GetMovieFile;
|
GetResourceById = GetMovieFile;
|
||||||
/*GetResourceAll = GetEpisodeFiles;
|
|
||||||
UpdateResource = SetQuality;*/
|
|
||||||
UpdateResource = SetQuality;
|
UpdateResource = SetQuality;
|
||||||
DeleteResource = DeleteEpisodeFile;
|
DeleteResource = DeleteMovieFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MovieFileResource GetMovieFile(int id)
|
private MovieFileResource GetMovieFile(int id)
|
||||||
{
|
{
|
||||||
var episodeFile = _mediaFileService.GetMovie(id);
|
var movie = _mediaFileService.GetMovie(id);
|
||||||
|
|
||||||
return episodeFile.ToResource();
|
return movie.ToResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private List<EpisodeFileResource> GetEpisodeFiles()
|
private void SetQuality(MovieFileResource movieFileResource)
|
||||||
{
|
{
|
||||||
if (!Request.Query.SeriesId.HasValue)
|
var movieFile = _mediaFileService.GetMovie(movieFileResource.Id);
|
||||||
{
|
movieFile.Quality = movieFileResource.Quality;
|
||||||
throw new BadRequestException("seriesId is missing");
|
_mediaFileService.Update(movieFile);
|
||||||
}
|
|
||||||
|
|
||||||
var seriesId = (int)Request.Query.SeriesId;
|
|
||||||
|
|
||||||
var series = _seriesService.GetSeries(seriesId);
|
|
||||||
|
|
||||||
return _mediaFileService.GetFilesBySeries(seriesId).ConvertAll(f => f.ToResource(series, _qualityUpgradableSpecification));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
private void SetQuality(MovieFileResource episodeFileResource)
|
|
||||||
{
|
|
||||||
var episodeFile = _mediaFileService.GetMovie(episodeFileResource.Id);
|
|
||||||
episodeFile.Quality = episodeFileResource.Quality;
|
|
||||||
_mediaFileService.Update(episodeFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteEpisodeFile(int id)
|
private void DeleteMovieFile(int id)
|
||||||
{
|
{
|
||||||
var episodeFile = _mediaFileService.GetMovie(id);
|
var movieFile = _mediaFileService.GetMovie(id);
|
||||||
var series = _seriesService.GetMovie(episodeFile.MovieId);
|
var movie = _movieService.GetMovie(movieFile.MovieId);
|
||||||
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
var fullPath = Path.Combine(movie.Path, movieFile.RelativePath);
|
||||||
|
|
||||||
_logger.Info("Deleting episode file: {0}", fullPath);
|
_logger.Info("Deleting movie file: {0}", fullPath);
|
||||||
_recycleBinProvider.DeleteFile(fullPath);
|
_recycleBinProvider.DeleteFile(fullPath);
|
||||||
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
|
_mediaFileService.Delete(movieFile, DeleteMediaFileReason.Manual);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeFileAddedEvent message)
|
public void Handle(MovieFileAddedEvent message)
|
||||||
{
|
{
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.EpisodeFile.Id);
|
BroadcastResourceChange(ModelAction.Updated, message.MovieFile.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
using NzbDrone.Api.Movie;
|
||||||
|
using NzbDrone.Core.Datastore.Events;
|
||||||
|
using NzbDrone.Core.DecisionEngine;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Movies
|
||||||
|
{
|
||||||
|
public abstract class MovieModuleWithSignalR : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
|
||||||
|
IHandle<MovieGrabbedEvent>,
|
||||||
|
IHandle<MovieDownloadedEvent>
|
||||||
|
{
|
||||||
|
protected readonly IMovieService _movieService;
|
||||||
|
protected readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||||
|
|
||||||
|
protected MovieModuleWithSignalR(IMovieService movieService,
|
||||||
|
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||||
|
IBroadcastSignalRMessage signalRBroadcaster)
|
||||||
|
: base(signalRBroadcaster)
|
||||||
|
{
|
||||||
|
_movieService = movieService;
|
||||||
|
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||||
|
|
||||||
|
GetResourceById = GetMovie;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MovieModuleWithSignalR(IMovieService movieService,
|
||||||
|
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||||
|
IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
|
string resource)
|
||||||
|
: base(signalRBroadcaster, resource)
|
||||||
|
{
|
||||||
|
_movieService = movieService;
|
||||||
|
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||||
|
|
||||||
|
GetResourceById = GetMovie;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MovieResource GetMovie(int id)
|
||||||
|
{
|
||||||
|
var movie = _movieService.GetMovie(id);
|
||||||
|
var resource = MapToResource(movie, true);
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MovieResource MapToResource(Core.Tv.Movie episode, bool includeSeries)
|
||||||
|
{
|
||||||
|
var resource = episode.ToResource();
|
||||||
|
|
||||||
|
if (includeSeries)
|
||||||
|
{
|
||||||
|
var series = episode ?? _movieService.GetMovie(episode.Id);
|
||||||
|
resource = series.ToResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieGrabbedEvent message)
|
||||||
|
{
|
||||||
|
var resource = message.Movie.Movie.ToResource();
|
||||||
|
|
||||||
|
//add a grabbed field in MovieResource?
|
||||||
|
//resource.Grabbed = true;
|
||||||
|
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(MovieDownloadedEvent message)
|
||||||
|
{
|
||||||
|
var resource = message.Movie.Movie.ToResource();
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
using NzbDrone.Api.ClientSchema;
|
using FluentValidation;
|
||||||
|
using NzbDrone.Api.ClientSchema;
|
||||||
using NzbDrone.Core.NetImport;
|
using NzbDrone.Core.NetImport;
|
||||||
using NzbDrone.Core.Profiles;
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
namespace NzbDrone.Api.NetImport
|
namespace NzbDrone.Api.NetImport
|
||||||
{
|
{
|
||||||
public class NetImportModule : ProviderModuleBase<NetImportResource, INetImport, NetImportDefinition>
|
public class NetImportModule : ProviderModuleBase<NetImportResource, INetImport, NetImportDefinition>
|
||||||
{
|
{
|
||||||
private readonly IProfileService _profileService;
|
public NetImportModule(NetImportFactory netImportFactory) : base(netImportFactory, "netimport")
|
||||||
public NetImportModule(NetImportFactory indexerFactory, IProfileService profileService)
|
|
||||||
: base(indexerFactory, "netimport")
|
|
||||||
{
|
{
|
||||||
_profileService = profileService;
|
PostValidator.RuleFor(c => c.RootFolderPath).NotNull();
|
||||||
|
PostValidator.RuleFor(c => c.MinimumAvailability).NotNull();
|
||||||
|
PostValidator.RuleFor(c => c.ProfileId).NotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void MapToResource(NetImportResource resource, NetImportDefinition definition)
|
protected override void MapToResource(NetImportResource resource, NetImportDefinition definition)
|
||||||
@@ -22,6 +23,7 @@ namespace NzbDrone.Api.NetImport
|
|||||||
resource.ProfileId = definition.ProfileId;
|
resource.ProfileId = definition.ProfileId;
|
||||||
resource.RootFolderPath = definition.RootFolderPath;
|
resource.RootFolderPath = definition.RootFolderPath;
|
||||||
resource.ShouldMonitor = definition.ShouldMonitor;
|
resource.ShouldMonitor = definition.ShouldMonitor;
|
||||||
|
resource.MinimumAvailability = definition.MinimumAvailability;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void MapToModel(NetImportDefinition definition, NetImportResource resource)
|
protected override void MapToModel(NetImportDefinition definition, NetImportResource resource)
|
||||||
@@ -33,6 +35,7 @@ namespace NzbDrone.Api.NetImport
|
|||||||
definition.ProfileId = resource.ProfileId;
|
definition.ProfileId = resource.ProfileId;
|
||||||
definition.RootFolderPath = resource.RootFolderPath;
|
definition.RootFolderPath = resource.RootFolderPath;
|
||||||
definition.ShouldMonitor = resource.ShouldMonitor;
|
definition.ShouldMonitor = resource.ShouldMonitor;
|
||||||
|
definition.MinimumAvailability = resource.MinimumAvailability;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Validate(NetImportDefinition definition, bool includeWarnings)
|
protected override void Validate(NetImportDefinition definition, bool includeWarnings)
|
||||||
@@ -41,4 +44,4 @@ namespace NzbDrone.Api.NetImport
|
|||||||
base.Validate(definition, includeWarnings);
|
base.Validate(definition, includeWarnings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using NzbDrone.Core.NetImport;
|
using NzbDrone.Core.NetImport;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Api.NetImport
|
namespace NzbDrone.Api.NetImport
|
||||||
{
|
{
|
||||||
@@ -9,5 +10,6 @@ namespace NzbDrone.Api.NetImport
|
|||||||
public bool ShouldMonitor { get; set; }
|
public bool ShouldMonitor { get; set; }
|
||||||
public string RootFolderPath { get; set; }
|
public string RootFolderPath { get; set; }
|
||||||
public int ProfileId { get; set; }
|
public int ProfileId { get; set; }
|
||||||
|
public MovieStatusType MinimumAvailability { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,8 +118,10 @@
|
|||||||
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
||||||
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
<Compile Include="Indexers\ReleaseModuleBase.cs" />
|
||||||
<Compile Include="Indexers\ReleasePushModule.cs" />
|
<Compile Include="Indexers\ReleasePushModule.cs" />
|
||||||
|
<Compile Include="Movies\MovieModuleWithSignalR.cs" />
|
||||||
|
<Compile Include="Movies\MovieBulkImportModule.cs" />
|
||||||
<Compile Include="Movies\MovieFileModule.cs" />
|
<Compile Include="Movies\MovieFileModule.cs" />
|
||||||
<Compile Include="Movies\MovieModule.cs" />
|
<Compile Include="Series\MovieModule.cs" />
|
||||||
<Compile Include="Movies\RenameMovieModule.cs" />
|
<Compile Include="Movies\RenameMovieModule.cs" />
|
||||||
<Compile Include="Movies\RenameMovieResource.cs" />
|
<Compile Include="Movies\RenameMovieResource.cs" />
|
||||||
<Compile Include="Movies\MovieEditorModule.cs" />
|
<Compile Include="Movies\MovieEditorModule.cs" />
|
||||||
@@ -245,7 +247,6 @@
|
|||||||
<Compile Include="Series\SeriesEditorModule.cs" />
|
<Compile Include="Series\SeriesEditorModule.cs" />
|
||||||
<Compile Include="Series\MovieLookupModule.cs" />
|
<Compile Include="Series\MovieLookupModule.cs" />
|
||||||
<Compile Include="Series\SeriesLookupModule.cs" />
|
<Compile Include="Series\SeriesLookupModule.cs" />
|
||||||
<Compile Include="Series\MovieModule.cs" />
|
|
||||||
<Compile Include="Series\SeriesModule.cs" />
|
<Compile Include="Series\SeriesModule.cs" />
|
||||||
<Compile Include="Series\MovieResource.cs" />
|
<Compile Include="Series\MovieResource.cs" />
|
||||||
<Compile Include="Series\SeriesResource.cs" />
|
<Compile Include="Series\SeriesResource.cs" />
|
||||||
@@ -267,6 +268,7 @@
|
|||||||
<Compile Include="Wanted\CutoffModule.cs" />
|
<Compile Include="Wanted\CutoffModule.cs" />
|
||||||
<Compile Include="Wanted\LegacyMissingModule.cs" />
|
<Compile Include="Wanted\LegacyMissingModule.cs" />
|
||||||
<Compile Include="Wanted\MissingModule.cs" />
|
<Compile Include="Wanted\MissingModule.cs" />
|
||||||
|
<Compile Include="Wanted\MovieCutoffModule.cs" />
|
||||||
<Compile Include="Wanted\MovieMissingModule.cs" />
|
<Compile Include="Wanted\MovieMissingModule.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -295,11 +297,11 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
namespace NzbDrone.Api
|
namespace NzbDrone.Api
|
||||||
@@ -11,6 +13,7 @@ namespace NzbDrone.Api
|
|||||||
public SortDirection SortDirection { get; set; }
|
public SortDirection SortDirection { get; set; }
|
||||||
public string FilterKey { get; set; }
|
public string FilterKey { get; set; }
|
||||||
public string FilterValue { get; set; }
|
public string FilterValue { get; set; }
|
||||||
|
public string FilterType { get; set; }
|
||||||
public int TotalRecords { get; set; }
|
public int TotalRecords { get; set; }
|
||||||
public List<TResource> Records { get; set; }
|
public List<TResource> Records { get; set; }
|
||||||
}
|
}
|
||||||
@@ -38,5 +41,14 @@ namespace NzbDrone.Api
|
|||||||
|
|
||||||
return pagingSpec;
|
return pagingSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*public static Expression<Func<TModel, object>> CreateFilterExpression<TModel>(string filterKey, string filterValue)
|
||||||
|
{
|
||||||
|
Type type = typeof(TModel);
|
||||||
|
ParameterExpression parameterExpression = Expression.Parameter(type, "x");
|
||||||
|
Expression expressionBody = parameterExpression;
|
||||||
|
|
||||||
|
return expressionBody;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ namespace NzbDrone.Api
|
|||||||
|
|
||||||
resource.Fields = SchemaBuilder.ToSchema(definition.Settings);
|
resource.Fields = SchemaBuilder.ToSchema(definition.Settings);
|
||||||
|
|
||||||
resource.InfoLink = string.Format("https://github.com/Sonarr/Sonarr/wiki/Supported-{0}#{1}",
|
resource.InfoLink = string.Format("https://github.com/Radarr/Radarr/wiki/Supported-{0}#{1}",
|
||||||
typeof(TProviderResource).Name.Replace("Resource", "s"),
|
typeof(TProviderResource).Name.Replace("Resource", "s"),
|
||||||
definition.Implementation.ToLower());
|
definition.Implementation.ToLower());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,7 +214,10 @@ namespace NzbDrone.Api.REST
|
|||||||
private PagingResource<TResource> ReadPagingResourceFromRequest()
|
private PagingResource<TResource> ReadPagingResourceFromRequest()
|
||||||
{
|
{
|
||||||
int pageSize;
|
int pageSize;
|
||||||
int.TryParse(Request.Query.PageSize.ToString(), out pageSize);
|
if (!int.TryParse(Request.Query.PageSize.ToString(), out pageSize))
|
||||||
|
{
|
||||||
|
pageSize = 100000;
|
||||||
|
}
|
||||||
if (pageSize == 0) pageSize = 10;
|
if (pageSize == 0) pageSize = 10;
|
||||||
|
|
||||||
int page;
|
int page;
|
||||||
@@ -249,8 +252,15 @@ namespace NzbDrone.Api.REST
|
|||||||
{
|
{
|
||||||
pagingResource.FilterValue = Request.Query.FilterValue.ToString();
|
pagingResource.FilterValue = Request.Query.FilterValue.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Request.Query.FilterType != null)
|
||||||
|
{
|
||||||
|
pagingResource.FilterType = Request.Query.FilterType.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return pagingResource;
|
return pagingResource;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,20 +4,44 @@ using NzbDrone.Api.Extensions;
|
|||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.MetadataSource;
|
using NzbDrone.Core.MetadataSource;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
using NzbDrone.Api.REST;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movie
|
||||||
{
|
{
|
||||||
public class MovieLookupModule : NzbDroneRestModule<MovieResource>
|
public class MovieLookupModule : NzbDroneRestModule<MovieResource>
|
||||||
{
|
{
|
||||||
private readonly ISearchForNewMovie _searchProxy;
|
private readonly ISearchForNewMovie _searchProxy;
|
||||||
|
private readonly IProvideMovieInfo _movieInfo;
|
||||||
|
|
||||||
public MovieLookupModule(ISearchForNewMovie searchProxy)
|
public MovieLookupModule(ISearchForNewMovie searchProxy, IProvideMovieInfo movieInfo)
|
||||||
: base("/movies/lookup")
|
: base("/movies/lookup")
|
||||||
{
|
{
|
||||||
|
_movieInfo = movieInfo;
|
||||||
_searchProxy = searchProxy;
|
_searchProxy = searchProxy;
|
||||||
Get["/"] = x => Search();
|
Get["/"] = x => Search();
|
||||||
|
Get["/tmdb"] = x => SearchByTmdbId();
|
||||||
|
Get["/imdb"] = x => SearchByImdbId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Response SearchByTmdbId()
|
||||||
|
{
|
||||||
|
int tmdbId = -1;
|
||||||
|
if(Int32.TryParse(Request.Query.tmdbId, out tmdbId))
|
||||||
|
{
|
||||||
|
var result = _movieInfo.GetMovieInfo(tmdbId, null);
|
||||||
|
return result.ToResource().AsResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new BadRequestException("Tmdb Id was not valid");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response SearchByImdbId()
|
||||||
|
{
|
||||||
|
string imdbId = Request.Query.imdbId;
|
||||||
|
var result = _movieInfo.GetMovieInfo(imdbId);
|
||||||
|
return result.ToResource().AsResponse();
|
||||||
|
}
|
||||||
|
|
||||||
private Response Search()
|
private Response Search()
|
||||||
{
|
{
|
||||||
@@ -25,7 +49,6 @@ namespace NzbDrone.Api.Movie
|
|||||||
return MapToResource(imdbResults).AsResponse();
|
return MapToResource(imdbResults).AsResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static IEnumerable<MovieResource> MapToResource(IEnumerable<Core.Tv.Movie> movies)
|
private static IEnumerable<MovieResource> MapToResource(IEnumerable<Core.Tv.Movie> movies)
|
||||||
{
|
{
|
||||||
foreach (var currentSeries in movies)
|
foreach (var currentSeries in movies)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ using NzbDrone.Core.Validation.Paths;
|
|||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
using NzbDrone.Core.DataAugmentation.Scene;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
using NzbDrone.SignalR;
|
using NzbDrone.SignalR;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
|
||||||
namespace NzbDrone.Api.Movie
|
namespace NzbDrone.Api.Movie
|
||||||
{
|
{
|
||||||
@@ -52,6 +53,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
_coverMapper = coverMapper;
|
_coverMapper = coverMapper;
|
||||||
|
|
||||||
GetResourceAll = AllMovie;
|
GetResourceAll = AllMovie;
|
||||||
|
GetResourcePaged = GetMoviePaged;
|
||||||
GetResourceById = GetMovie;
|
GetResourceById = GetMovie;
|
||||||
CreateResource = AddMovie;
|
CreateResource = AddMovie;
|
||||||
UpdateResource = UpdateMovie;
|
UpdateResource = UpdateMovie;
|
||||||
@@ -104,6 +106,62 @@ namespace NzbDrone.Api.Movie
|
|||||||
return MapToResource(movies);
|
return MapToResource(movies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PagingResource<MovieResource> GetMoviePaged(PagingResource<MovieResource> pagingResource)
|
||||||
|
{
|
||||||
|
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>();
|
||||||
|
|
||||||
|
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
|
||||||
|
{
|
||||||
|
pagingSpec.FilterExpression = v => v.Monitored == false;
|
||||||
|
}
|
||||||
|
else if (pagingResource.FilterKey == "monitored")
|
||||||
|
{
|
||||||
|
pagingSpec.FilterExpression = v => v.Monitored == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pagingResource.FilterKey == "status")
|
||||||
|
{
|
||||||
|
switch (pagingResource.FilterValue)
|
||||||
|
{
|
||||||
|
case "released":
|
||||||
|
pagingSpec.FilterExpression = v => v.Status == MovieStatusType.Released;
|
||||||
|
break;
|
||||||
|
case "inCinemas":
|
||||||
|
pagingSpec.FilterExpression = v => v.Status == MovieStatusType.InCinemas;
|
||||||
|
break;
|
||||||
|
case "announced":
|
||||||
|
pagingSpec.FilterExpression = v => v.Status == MovieStatusType.Announced;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pagingResource.FilterKey == "downloaded")
|
||||||
|
{
|
||||||
|
pagingSpec.FilterExpression = v => v.MovieFileId == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pagingResource.FilterKey == "title")
|
||||||
|
{
|
||||||
|
if (pagingResource.FilterValue == string.Empty || pagingResource.FilterValue == null)
|
||||||
|
{
|
||||||
|
pagingSpec.FilterExpression = v => true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pagingResource.FilterType == "contains")
|
||||||
|
{
|
||||||
|
pagingSpec.FilterExpression = v => v.CleanTitle.Contains(pagingResource.FilterValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pagingSpec.FilterExpression = v => v.CleanTitle == pagingResource.FilterValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApplyToPage(_moviesService.Paged, pagingSpec, MovieResourceMapper.ToResource);
|
||||||
|
}
|
||||||
|
|
||||||
protected MovieResource MapToResource(Core.Tv.Movie movies)
|
protected MovieResource MapToResource(Core.Tv.Movie movies)
|
||||||
{
|
{
|
||||||
if (movies == null) return null;
|
if (movies == null) return null;
|
||||||
@@ -147,14 +205,20 @@ namespace NzbDrone.Api.Movie
|
|||||||
private void DeleteMovie(int id)
|
private void DeleteMovie(int id)
|
||||||
{
|
{
|
||||||
var deleteFiles = false;
|
var deleteFiles = false;
|
||||||
|
var addExclusion = false;
|
||||||
var deleteFilesQuery = Request.Query.deleteFiles;
|
var deleteFilesQuery = Request.Query.deleteFiles;
|
||||||
|
var addExclusionQuery = Request.Query.addExclusion;
|
||||||
|
|
||||||
if (deleteFilesQuery.HasValue)
|
if (deleteFilesQuery.HasValue)
|
||||||
{
|
{
|
||||||
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
|
deleteFiles = Convert.ToBoolean(deleteFilesQuery.Value);
|
||||||
}
|
}
|
||||||
|
if (addExclusionQuery.HasValue)
|
||||||
|
{
|
||||||
|
addExclusion = Convert.ToBoolean(addExclusionQuery.Value);
|
||||||
|
}
|
||||||
|
|
||||||
_moviesService.DeleteMovie(id, deleteFiles);
|
_moviesService.DeleteMovie(id, deleteFiles, addExclusion);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MapCoversToLocal(params MovieResource[] movies)
|
private void MapCoversToLocal(params MovieResource[] movies)
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ namespace NzbDrone.Api.Movie
|
|||||||
|
|
||||||
//Editing Only
|
//Editing Only
|
||||||
public bool Monitored { get; set; }
|
public bool Monitored { get; set; }
|
||||||
|
public MovieStatusType MinimumAvailability { get; set; }
|
||||||
|
public bool IsAvailable { get; set; }
|
||||||
|
|
||||||
public int Runtime { get; set; }
|
public int Runtime { get; set; }
|
||||||
public DateTime? LastInfoSync { get; set; }
|
public DateTime? LastInfoSync { get; set; }
|
||||||
public string CleanTitle { get; set; }
|
public string CleanTitle { get; set; }
|
||||||
@@ -129,6 +132,9 @@ namespace NzbDrone.Api.Movie
|
|||||||
ProfileId = model.ProfileId,
|
ProfileId = model.ProfileId,
|
||||||
|
|
||||||
Monitored = model.Monitored,
|
Monitored = model.Monitored,
|
||||||
|
MinimumAvailability = model.MinimumAvailability,
|
||||||
|
|
||||||
|
IsAvailable = model.IsAvailable(),
|
||||||
|
|
||||||
SizeOnDisk = size,
|
SizeOnDisk = size,
|
||||||
|
|
||||||
@@ -181,7 +187,8 @@ namespace NzbDrone.Api.Movie
|
|||||||
ProfileId = resource.ProfileId,
|
ProfileId = resource.ProfileId,
|
||||||
|
|
||||||
Monitored = resource.Monitored,
|
Monitored = resource.Monitored,
|
||||||
|
MinimumAvailability = resource.MinimumAvailability,
|
||||||
|
|
||||||
Runtime = resource.Runtime,
|
Runtime = resource.Runtime,
|
||||||
LastInfoSync = resource.LastInfoSync,
|
LastInfoSync = resource.LastInfoSync,
|
||||||
CleanTitle = resource.CleanTitle,
|
CleanTitle = resource.CleanTitle,
|
||||||
@@ -210,7 +217,8 @@ namespace NzbDrone.Api.Movie
|
|||||||
movie.ProfileId = resource.ProfileId;
|
movie.ProfileId = resource.ProfileId;
|
||||||
|
|
||||||
movie.Monitored = resource.Monitored;
|
movie.Monitored = resource.Monitored;
|
||||||
|
movie.MinimumAvailability = resource.MinimumAvailability;
|
||||||
|
|
||||||
movie.RootFolderPath = resource.RootFolderPath;
|
movie.RootFolderPath = resource.RootFolderPath;
|
||||||
movie.Tags = resource.Tags;
|
movie.Tags = resource.Tags;
|
||||||
movie.AddOptions = resource.AddOptions;
|
movie.AddOptions = resource.AddOptions;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace NzbDrone.Api.Wanted
|
|||||||
ISeriesService seriesService,
|
ISeriesService seriesService,
|
||||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||||
IBroadcastSignalRMessage signalRBroadcaster)
|
IBroadcastSignalRMessage signalRBroadcaster)
|
||||||
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/cutoff")
|
: base(episodeService, seriesService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/cutoff-old")
|
||||||
{
|
{
|
||||||
_episodeCutoffService = episodeCutoffService;
|
_episodeCutoffService = episodeCutoffService;
|
||||||
GetResourcePaged = GetCutoffUnmetEpisodes;
|
GetResourcePaged = GetCutoffUnmetEpisodes;
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using NzbDrone.Api.Movie;
|
||||||
|
using NzbDrone.Api.Movies;
|
||||||
|
using NzbDrone.Core.DecisionEngine;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
|
namespace NzbDrone.Api.Wanted
|
||||||
|
{
|
||||||
|
public class MovieCutoffModule : MovieModuleWithSignalR
|
||||||
|
{
|
||||||
|
private readonly IMovieCutoffService _movieCutoffService;
|
||||||
|
|
||||||
|
public MovieCutoffModule(IMovieCutoffService movieCutoffService,
|
||||||
|
IMovieService movieService,
|
||||||
|
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||||
|
IBroadcastSignalRMessage signalRBroadcaster)
|
||||||
|
: base(movieService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/cutoff")
|
||||||
|
{
|
||||||
|
_movieCutoffService = movieCutoffService;
|
||||||
|
GetResourcePaged = GetCutoffUnmetMovies;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PagingResource<MovieResource> GetCutoffUnmetMovies(PagingResource<MovieResource> pagingResource)
|
||||||
|
{
|
||||||
|
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>("title", SortDirection.Ascending);
|
||||||
|
|
||||||
|
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
|
||||||
|
{
|
||||||
|
pagingSpec.FilterExpression = v => v.Monitored == false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pagingSpec.FilterExpression = v => v.Monitored == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var resource = ApplyToPage(_movieCutoffService.MoviesWhereCutoffUnmet, pagingSpec, v => MapToResource(v, true));
|
||||||
|
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,16 +12,14 @@ using NzbDrone.Core.Datastore.Events;
|
|||||||
|
|
||||||
namespace NzbDrone.Api.Wanted
|
namespace NzbDrone.Api.Wanted
|
||||||
{
|
{
|
||||||
class MovieMissingModule : NzbDroneRestModuleWithSignalR<MovieResource, Core.Tv.Movie>,
|
class MovieMissingModule : MovieModuleWithSignalR
|
||||||
IHandle<MovieGrabbedEvent>,
|
|
||||||
IHandle<MovieDownloadedEvent>
|
|
||||||
{
|
{
|
||||||
protected readonly IMovieService _movieService;
|
protected readonly IMovieService _movieService;
|
||||||
|
|
||||||
public MovieMissingModule(IMovieService movieService,
|
public MovieMissingModule(IMovieService movieService,
|
||||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||||
IBroadcastSignalRMessage signalRBroadcaster)
|
IBroadcastSignalRMessage signalRBroadcaster)
|
||||||
: base(signalRBroadcaster, "wanted/missing")
|
: base(movieService, qualityUpgradableSpecification, signalRBroadcaster, "wanted/missing")
|
||||||
{
|
{
|
||||||
|
|
||||||
_movieService = movieService;
|
_movieService = movieService;
|
||||||
@@ -30,48 +28,13 @@ namespace NzbDrone.Api.Wanted
|
|||||||
|
|
||||||
private PagingResource<MovieResource> GetMissingMovies(PagingResource<MovieResource> pagingResource)
|
private PagingResource<MovieResource> GetMissingMovies(PagingResource<MovieResource> pagingResource)
|
||||||
{
|
{
|
||||||
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>("physicalRelease", SortDirection.Descending);
|
var pagingSpec = pagingResource.MapToPagingSpec<MovieResource, Core.Tv.Movie>("title", SortDirection.Descending);
|
||||||
|
|
||||||
if (pagingResource.FilterKey == "monitored" && pagingResource.FilterValue == "false")
|
pagingSpec.FilterExpression = _movieService.ConstructFilterExpression(pagingResource.FilterKey, pagingResource.FilterValue);
|
||||||
{
|
|
||||||
pagingSpec.FilterExpression = v => v.Monitored == false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pagingSpec.FilterExpression = v => v.Monitored == true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var resource = ApplyToPage(_movieService.MoviesWithoutFiles, pagingSpec, v => MapToResource(v, false));
|
var resource = ApplyToPage(_movieService.MoviesWithoutFiles, pagingSpec, v => MapToResource(v, true));
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MovieResource GetMovie(int id)
|
|
||||||
{
|
|
||||||
var movie = _movieService.GetMovie(id);
|
|
||||||
var resource = MapToResource(movie, true);
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MovieResource MapToResource(Core.Tv.Movie movie, bool includeMovieFile)
|
|
||||||
{
|
|
||||||
var resource = movie.ToResource();
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(MovieGrabbedEvent message)
|
|
||||||
{
|
|
||||||
var resource = message.Movie.Movie.ToResource();
|
|
||||||
|
|
||||||
//add a grabbed field in MovieResource?
|
|
||||||
//resource.Grabbed = true;
|
|
||||||
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(MovieDownloadedEvent message)
|
|
||||||
{
|
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Movie.Movie.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ using System;
|
|||||||
|
|
||||||
namespace NzbDrone.Common.Extensions
|
namespace NzbDrone.Common.Extensions
|
||||||
{
|
{
|
||||||
public static class Base64Extentions
|
public static class Base64Extensions
|
||||||
{
|
{
|
||||||
public static string ToBase64(this byte[] bytes)
|
public static string ToBase64(this byte[] bytes)
|
||||||
{
|
{
|
||||||
@@ -14,4 +14,4 @@ namespace NzbDrone.Common.Extensions
|
|||||||
return BitConverter.GetBytes(input).ToBase64();
|
return BitConverter.GetBytes(input).ToBase64();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -5,11 +5,11 @@ using System.Xml.Linq;
|
|||||||
|
|
||||||
namespace NzbDrone.Common.Extensions
|
namespace NzbDrone.Common.Extensions
|
||||||
{
|
{
|
||||||
public static class XmlExtentions
|
public static class XmlExtensions
|
||||||
{
|
{
|
||||||
public static IEnumerable<XElement> FindDecendants(this XContainer container, string localName)
|
public static IEnumerable<XElement> FindDecendants(this XContainer container, string localName)
|
||||||
{
|
{
|
||||||
return container.Descendants().Where(c => c.Name.LocalName.Equals(localName, StringComparison.InvariantCultureIgnoreCase));
|
return container.Descendants().Where(c => c.Name.LocalName.Equals(localName, StringComparison.InvariantCultureIgnoreCase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,14 +145,14 @@
|
|||||||
<Compile Include="Expansive\Tree.cs" />
|
<Compile Include="Expansive\Tree.cs" />
|
||||||
<Compile Include="Expansive\TreeNode.cs" />
|
<Compile Include="Expansive\TreeNode.cs" />
|
||||||
<Compile Include="Expansive\TreeNodeList.cs" />
|
<Compile Include="Expansive\TreeNodeList.cs" />
|
||||||
<Compile Include="Extensions\Base64Extentions.cs" />
|
<Compile Include="Extensions\Base64Extensions.cs" />
|
||||||
<Compile Include="Extensions\DateTimeExtensions.cs" />
|
<Compile Include="Extensions\DateTimeExtensions.cs" />
|
||||||
<Compile Include="Crypto\HashConverter.cs" />
|
<Compile Include="Crypto\HashConverter.cs" />
|
||||||
<Compile Include="Extensions\Int64Extensions.cs" />
|
<Compile Include="Extensions\Int64Extensions.cs" />
|
||||||
<Compile Include="Extensions\ObjectExtensions.cs" />
|
<Compile Include="Extensions\ObjectExtensions.cs" />
|
||||||
<Compile Include="Extensions\StreamExtensions.cs" />
|
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||||
<Compile Include="Extensions\UrlExtensions.cs" />
|
<Compile Include="Extensions\UrlExtensions.cs" />
|
||||||
<Compile Include="Extensions\XmlExtentions.cs" />
|
<Compile Include="Extensions\XmlExtensions.cs" />
|
||||||
<Compile Include="HashUtil.cs" />
|
<Compile Include="HashUtil.cs" />
|
||||||
<Compile Include="Http\Dispatchers\CurlHttpDispatcher.cs" />
|
<Compile Include="Http\Dispatchers\CurlHttpDispatcher.cs" />
|
||||||
<Compile Include="Http\Dispatchers\FallbackHttpDispatcher.cs" />
|
<Compile Include="Http\Dispatchers\FallbackHttpDispatcher.cs" />
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Moq;
|
||||||
|
using NzbDrone.Core.Organizer;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.BulkImport
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class AddMultiMoviesFixture : CoreTest<MovieService>
|
||||||
|
{
|
||||||
|
private List<Movie> fakeMovies;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
fakeMovies = Builder<Movie>.CreateListOfSize(3).BuildList();
|
||||||
|
fakeMovies.ForEach(m =>
|
||||||
|
{
|
||||||
|
m.Path = null;
|
||||||
|
m.RootFolderPath = @"C:\Test\TV";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void movies_added_event_should_have_proper_path()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IBuildFileNames>()
|
||||||
|
.Setup(s => s.GetMovieFolder(It.IsAny<Movie>(), null))
|
||||||
|
.Returns((Movie m, NamingConfig n) => m.Title);
|
||||||
|
|
||||||
|
var movies = Subject.AddMovies(fakeMovies);
|
||||||
|
|
||||||
|
foreach (Movie movie in movies)
|
||||||
|
{
|
||||||
|
movie.Path.Should().NotBeNullOrEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Subject.GetAllMovies().Should().HaveCount(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void movies_added_should_ignore_already_added()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IBuildFileNames>()
|
||||||
|
.Setup(s => s.GetMovieFolder(It.IsAny<Movie>(), null))
|
||||||
|
.Returns((Movie m, NamingConfig n) => m.Title);
|
||||||
|
|
||||||
|
Mocker.GetMock<IMovieRepository>().Setup(s => s.All()).Returns(new List<Movie> { fakeMovies[0] });
|
||||||
|
|
||||||
|
var movies = Subject.AddMovies(fakeMovies);
|
||||||
|
|
||||||
|
Mocker.GetMock<IMovieRepository>().Verify(v => v.InsertMany(It.Is<List<Movie>>(l => l.Count == 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void movies_added_should_ignore_duplicates()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IBuildFileNames>()
|
||||||
|
.Setup(s => s.GetMovieFolder(It.IsAny<Movie>(), null))
|
||||||
|
.Returns((Movie m, NamingConfig n) => m.Title);
|
||||||
|
|
||||||
|
fakeMovies[2].TmdbId = fakeMovies[0].TmdbId;
|
||||||
|
|
||||||
|
var movies = Subject.AddMovies(fakeMovies);
|
||||||
|
|
||||||
|
Mocker.GetMock<IMovieRepository>().Verify(v => v.InsertMany(It.Is<List<Movie>>(l => l.Count == 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,312 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using FizzWare.NBuilder;
|
|
||||||
using FluentAssertions;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.DataAugmentation.Xem;
|
|
||||||
using NzbDrone.Core.DataAugmentation.Xem.Model;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Core.Tv.Events;
|
|
||||||
using NzbDrone.Test.Common;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.DataAugmentation.SceneNumbering
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class XemServiceFixture : CoreTest<XemService>
|
|
||||||
{
|
|
||||||
private Series _series;
|
|
||||||
private List<int> _theXemSeriesIds;
|
|
||||||
private List<XemSceneTvdbMapping> _theXemTvdbMappings;
|
|
||||||
private List<Episode> _episodes;
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public void SetUp()
|
|
||||||
{
|
|
||||||
_series = Builder<Series>.CreateNew()
|
|
||||||
.With(v => v.TvdbId = 10)
|
|
||||||
.With(v => v.UseSceneNumbering = false)
|
|
||||||
.BuildNew();
|
|
||||||
|
|
||||||
_theXemSeriesIds = new List<int> { 120 };
|
|
||||||
Mocker.GetMock<IXemProxy>()
|
|
||||||
.Setup(v => v.GetXemSeriesIds())
|
|
||||||
.Returns(_theXemSeriesIds);
|
|
||||||
|
|
||||||
_theXemTvdbMappings = new List<XemSceneTvdbMapping>();
|
|
||||||
Mocker.GetMock<IXemProxy>()
|
|
||||||
.Setup(v => v.GetSceneTvdbMappings(10))
|
|
||||||
.Returns(_theXemTvdbMappings);
|
|
||||||
|
|
||||||
_episodes = new List<Episode>();
|
|
||||||
_episodes.Add(new Episode { SeasonNumber = 1, EpisodeNumber = 1 });
|
|
||||||
_episodes.Add(new Episode { SeasonNumber = 1, EpisodeNumber = 2 });
|
|
||||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 1 });
|
|
||||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 2 });
|
|
||||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 3 });
|
|
||||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 4 });
|
|
||||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 5 });
|
|
||||||
_episodes.Add(new Episode { SeasonNumber = 3, EpisodeNumber = 1 });
|
|
||||||
_episodes.Add(new Episode { SeasonNumber = 3, EpisodeNumber = 2 });
|
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
|
||||||
.Setup(v => v.GetEpisodeBySeries(It.IsAny<int>()))
|
|
||||||
.Returns(_episodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTvdbMappings()
|
|
||||||
{
|
|
||||||
_theXemSeriesIds.Add(10);
|
|
||||||
|
|
||||||
AddTvdbMapping(1, 1, 1, 1, 1, 1); // 1x01 -> 1x01
|
|
||||||
AddTvdbMapping(2, 1, 2, 2, 1, 2); // 1x02 -> 1x02
|
|
||||||
AddTvdbMapping(3, 2, 1, 3, 2, 1); // 2x01 -> 2x01
|
|
||||||
AddTvdbMapping(4, 2, 2, 4, 2, 2); // 2x02 -> 2x02
|
|
||||||
AddTvdbMapping(5, 2, 3, 5, 2, 3); // 2x03 -> 2x03
|
|
||||||
AddTvdbMapping(6, 3, 1, 6, 2, 4); // 3x01 -> 2x04
|
|
||||||
AddTvdbMapping(7, 3, 2, 7, 2, 5); // 3x02 -> 2x05
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenExistingMapping()
|
|
||||||
{
|
|
||||||
_series.UseSceneNumbering = true;
|
|
||||||
|
|
||||||
_episodes[0].SceneSeasonNumber = 1;
|
|
||||||
_episodes[0].SceneEpisodeNumber = 1;
|
|
||||||
_episodes[1].SceneSeasonNumber = 1;
|
|
||||||
_episodes[1].SceneEpisodeNumber = 2;
|
|
||||||
_episodes[2].SceneSeasonNumber = 2;
|
|
||||||
_episodes[2].SceneEpisodeNumber = 1;
|
|
||||||
_episodes[3].SceneSeasonNumber = 2;
|
|
||||||
_episodes[3].SceneEpisodeNumber = 2;
|
|
||||||
_episodes[4].SceneSeasonNumber = 2;
|
|
||||||
_episodes[4].SceneEpisodeNumber = 3;
|
|
||||||
_episodes[5].SceneSeasonNumber = 3;
|
|
||||||
_episodes[5].SceneEpisodeNumber = 1;
|
|
||||||
_episodes[6].SceneSeasonNumber = 3;
|
|
||||||
_episodes[6].SceneEpisodeNumber = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddTvdbMapping(int sceneAbsolute, int sceneSeason, int sceneEpisode, int tvdbAbsolute, int tvdbSeason, int tvdbEpisode)
|
|
||||||
{
|
|
||||||
_theXemTvdbMappings.Add(new XemSceneTvdbMapping
|
|
||||||
{
|
|
||||||
Scene = new XemValues { Absolute = sceneAbsolute, Season = sceneSeason, Episode = sceneEpisode },
|
|
||||||
Tvdb = new XemValues { Absolute = tvdbAbsolute, Season = tvdbSeason, Episode = tvdbEpisode },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_fetch_scenenumbering_if_not_listed()
|
|
||||||
{
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
Mocker.GetMock<IXemProxy>()
|
|
||||||
.Verify(v => v.GetSceneTvdbMappings(10), Times.Never());
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_fetch_scenenumbering()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.UseSceneNumbering == true)), Times.Once());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_clear_scenenumbering_if_removed_from_thexem()
|
|
||||||
{
|
|
||||||
GivenExistingMapping();
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Once());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_clear_scenenumbering_if_no_results_at_all_from_thexem()
|
|
||||||
{
|
|
||||||
GivenExistingMapping();
|
|
||||||
|
|
||||||
_theXemSeriesIds.Clear();
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
|
||||||
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_clear_scenenumbering_if_thexem_throws()
|
|
||||||
{
|
|
||||||
GivenExistingMapping();
|
|
||||||
|
|
||||||
Mocker.GetMock<IXemProxy>()
|
|
||||||
.Setup(v => v.GetXemSeriesIds())
|
|
||||||
.Throws(new InvalidOperationException());
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
|
||||||
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_flag_unknown_future_episodes_if_existing_season_is_mapped()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
_theXemTvdbMappings.RemoveAll(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 5);
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 5);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_flag_unknown_future_season_if_future_season_is_shifted()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 3 && v.EpisodeNumber == 1);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_flag_unknown_future_season_if_future_season_is_not_shifted()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
_theXemTvdbMappings.RemoveAll(v => v.Scene.Season == 3);
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 3 && v.EpisodeNumber == 1);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_flag_past_episodes_if_not_causing_overlaps()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
_theXemTvdbMappings.RemoveAll(v => v.Scene.Season == 2);
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 1);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_flag_past_episodes_if_causing_overlap()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
_theXemTvdbMappings.RemoveAll(v => v.Scene.Season == 2 && v.Tvdb.Episode <= 1);
|
|
||||||
_theXemTvdbMappings.First(v => v.Scene.Season == 2 && v.Scene.Episode == 2).Scene.Episode = 1;
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 1);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_extrapolate_season_with_specials()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
var specialMapping = _theXemTvdbMappings.First(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 5);
|
|
||||||
specialMapping.Tvdb.Season = 0;
|
|
||||||
specialMapping.Tvdb.Episode = 1;
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 5);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
|
||||||
episode.SceneSeasonNumber.Should().NotHaveValue();
|
|
||||||
episode.SceneEpisodeNumber.Should().NotHaveValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_extrapolate_season_with_future_episodes()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
_theXemTvdbMappings.RemoveAll(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 5);
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 5);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
|
||||||
episode.SceneSeasonNumber.Should().Be(3);
|
|
||||||
episode.SceneEpisodeNumber.Should().Be(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_extrapolate_season_with_shifted_episodes()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
_theXemTvdbMappings.RemoveAll(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 5);
|
|
||||||
var dualMapping = _theXemTvdbMappings.First(v => v.Tvdb.Season == 2 && v.Tvdb.Episode == 4);
|
|
||||||
dualMapping.Scene.Season = 2;
|
|
||||||
dualMapping.Scene.Episode = 3;
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 2 && v.EpisodeNumber == 5);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
|
||||||
episode.SceneSeasonNumber.Should().Be(2);
|
|
||||||
episode.SceneEpisodeNumber.Should().Be(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_extrapolate_shifted_future_seasons()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 3 && v.EpisodeNumber == 2);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeTrue();
|
|
||||||
episode.SceneSeasonNumber.Should().Be(4);
|
|
||||||
episode.SceneEpisodeNumber.Should().Be(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_extrapolate_matching_future_seasons()
|
|
||||||
{
|
|
||||||
GivenTvdbMappings();
|
|
||||||
_theXemTvdbMappings.RemoveAll(v => v.Scene.Season != 1);
|
|
||||||
|
|
||||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
|
||||||
|
|
||||||
var episode = _episodes.First(v => v.SeasonNumber == 3 && v.EpisodeNumber == 2);
|
|
||||||
|
|
||||||
episode.UnverifiedSceneNumbering.Should().BeFalse();
|
|
||||||
episode.SceneSeasonNumber.Should().NotHaveValue();
|
|
||||||
episode.SceneEpisodeNumber.Should().NotHaveValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
|||||||
{
|
{
|
||||||
private Profile _profile;
|
private Profile _profile;
|
||||||
private DelayProfile _delayProfile;
|
private DelayProfile _delayProfile;
|
||||||
private RemoteEpisode _remoteEpisode;
|
private RemoteMovie _remoteEpisode;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
@@ -38,12 +38,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
|||||||
.With(d => d.PreferredProtocol = DownloadProtocol.Usenet)
|
.With(d => d.PreferredProtocol = DownloadProtocol.Usenet)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var series = Builder<Series>.CreateNew()
|
var series = Builder<Movie>.CreateNew()
|
||||||
.With(s => s.Profile = _profile)
|
.With(s => s.Profile = _profile)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_remoteEpisode = Builder<RemoteEpisode>.CreateNew()
|
_remoteEpisode = Builder<RemoteMovie>.CreateNew()
|
||||||
.With(r => r.Series = series)
|
.With(r => r.Movie = series)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_profile.Items = new List<ProfileQualityItem>();
|
_profile.Items = new List<ProfileQualityItem>();
|
||||||
@@ -53,30 +53,30 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
|
|||||||
|
|
||||||
_profile.Cutoff = Quality.WEBDL720p;
|
_profile.Cutoff = Quality.WEBDL720p;
|
||||||
|
|
||||||
_remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
|
_remoteEpisode.ParsedMovieInfo = new ParsedMovieInfo();
|
||||||
_remoteEpisode.Release = new ReleaseInfo();
|
_remoteEpisode.Release = new ReleaseInfo();
|
||||||
_remoteEpisode.Release.DownloadProtocol = DownloadProtocol.Usenet;
|
_remoteEpisode.Release.DownloadProtocol = DownloadProtocol.Usenet;
|
||||||
|
|
||||||
_remoteEpisode.Episodes = Builder<Episode>.CreateListOfSize(1).Build().ToList();
|
//_remoteEpisode.Episodes = Builder<Episode>.CreateListOfSize(1).Build().ToList();
|
||||||
_remoteEpisode.Episodes.First().EpisodeFileId = 0;
|
//_remoteEpisode.Episodes.First().EpisodeFileId = 0;
|
||||||
|
|
||||||
Mocker.GetMock<IDelayProfileService>()
|
//Mocker.GetMock<IDelayProfileService>()
|
||||||
.Setup(s => s.BestForTags(It.IsAny<HashSet<int>>()))
|
// .Setup(s => s.BestForTags(It.IsAny<HashSet<int>>()))
|
||||||
.Returns(_delayProfile);
|
// .Returns(_delayProfile);
|
||||||
|
|
||||||
Mocker.GetMock<IPendingReleaseService>()
|
//Mocker.GetMock<IPendingReleaseService>()
|
||||||
.Setup(s => s.GetPendingRemoteEpisodes(It.IsAny<int>()))
|
// .Setup(s => s.GetPendingRemoteEpisodes(It.IsAny<int>()))
|
||||||
.Returns(new List<RemoteEpisode>());
|
// .Returns(new List<RemoteEpisode>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenExistingFile(QualityModel quality)
|
private void GivenExistingFile(QualityModel quality)
|
||||||
{
|
{
|
||||||
_remoteEpisode.Episodes.First().EpisodeFileId = 1;
|
//_remoteEpisode.Episodes.First().EpisodeFileId = 1;
|
||||||
|
|
||||||
_remoteEpisode.Episodes.First().EpisodeFile = new LazyLoaded<EpisodeFile>(new EpisodeFile
|
//_remoteEpisode.Episodes.First().EpisodeFile = new LazyLoaded<EpisodeFile>(new EpisodeFile
|
||||||
{
|
// {
|
||||||
Quality = quality
|
// Quality = quality
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenUpgradeForExistingFile()
|
private void GivenUpgradeForExistingFile()
|
||||||
|
|||||||
+9
-9
@@ -74,9 +74,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
.Returns(1000000);
|
.Returns(1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override RemoteEpisode CreateRemoteEpisode()
|
protected override RemoteMovie CreateRemoteMovie()
|
||||||
{
|
{
|
||||||
var remoteEpisode = base.CreateRemoteEpisode();
|
var remoteEpisode = base.CreateRemoteMovie();
|
||||||
var torrentInfo = new TorrentInfo();
|
var torrentInfo = new TorrentInfo();
|
||||||
|
|
||||||
torrentInfo.Title = remoteEpisode.Release.Title;
|
torrentInfo.Title = remoteEpisode.Release.Title;
|
||||||
@@ -125,7 +125,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_should_download_file_if_it_doesnt_exist()
|
public void Download_should_download_file_if_it_doesnt_exist()
|
||||||
{
|
{
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
Subject.Download(remoteEpisode);
|
Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
{
|
{
|
||||||
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.DownloadUrl = null;
|
remoteEpisode.Release.DownloadUrl = null;
|
||||||
|
|
||||||
Subject.Download(remoteEpisode);
|
Subject.Download(remoteEpisode);
|
||||||
@@ -153,7 +153,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_should_not_save_magnet_if_disabled()
|
public void Download_should_not_save_magnet_if_disabled()
|
||||||
{
|
{
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.DownloadUrl = null;
|
remoteEpisode.Release.DownloadUrl = null;
|
||||||
|
|
||||||
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteEpisode));
|
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteEpisode));
|
||||||
@@ -169,7 +169,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
{
|
{
|
||||||
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
Subject.Definition.Settings.As<TorrentBlackholeSettings>().SaveMagnetFiles = true;
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
Subject.Download(remoteEpisode);
|
Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
||||||
var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath));
|
var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath));
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.Title = illegalTitle;
|
remoteEpisode.Release.Title = illegalTitle;
|
||||||
|
|
||||||
Subject.Download(remoteEpisode);
|
Subject.Download(remoteEpisode);
|
||||||
@@ -198,7 +198,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_should_throw_if_magnet_and_torrent_url_does_not_exist()
|
public void Download_should_throw_if_magnet_and_torrent_url_does_not_exist()
|
||||||
{
|
{
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.DownloadUrl = null;
|
remoteEpisode.Release.DownloadUrl = null;
|
||||||
|
|
||||||
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteEpisode));
|
Assert.Throws<ReleaseDownloadException>(() => Subject.Download(remoteEpisode));
|
||||||
@@ -273,7 +273,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_return_null_hash()
|
public void should_return_null_hash()
|
||||||
{
|
{
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
Subject.Download(remoteEpisode).Should().BeNull();
|
Subject.Download(remoteEpisode).Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -104,7 +104,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_should_download_file_if_it_doesnt_exist()
|
public void Download_should_download_file_if_it_doesnt_exist()
|
||||||
{
|
{
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
Subject.Download(remoteEpisode);
|
Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
|||||||
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
var illegalTitle = "Saturday Night Live - S38E08 - Jeremy Renner/Maroon 5 [SDTV]";
|
||||||
var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath));
|
var expectedFilename = Path.Combine(_blackholeFolder, "Saturday Night Live - S38E08 - Jeremy Renner+Maroon 5 [SDTV]" + Path.GetExtension(_filePath));
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.Title = illegalTitle;
|
remoteEpisode.Release.Title = illegalTitle;
|
||||||
|
|
||||||
Subject.Download(remoteEpisode);
|
Subject.Download(remoteEpisode);
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
|||||||
.Returns(30);
|
.Returns(30);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), (SearchCriteriaBase)null))
|
.Setup(s => s.Map(It.IsAny<ParsedMovieInfo>(), It.IsAny<string>(), (SearchCriteriaBase)null))
|
||||||
.Returns(() => CreateRemoteEpisode());
|
.Returns(() => CreateRemoteMovie());
|
||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
Mocker.GetMock<IHttpClient>()
|
||||||
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||||
@@ -42,20 +42,20 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests
|
|||||||
.Returns<string, OsPath>((h, r) => r);
|
.Returns<string, OsPath>((h, r) => r);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual RemoteEpisode CreateRemoteEpisode()
|
protected virtual RemoteMovie CreateRemoteMovie()
|
||||||
{
|
{
|
||||||
var remoteEpisode = new RemoteEpisode();
|
var remoteEpisode = new RemoteMovie();
|
||||||
remoteEpisode.Release = new ReleaseInfo();
|
remoteEpisode.Release = new ReleaseInfo();
|
||||||
remoteEpisode.Release.Title = _title;
|
remoteEpisode.Release.Title = _title;
|
||||||
remoteEpisode.Release.DownloadUrl = _downloadUrl;
|
remoteEpisode.Release.DownloadUrl = _downloadUrl;
|
||||||
remoteEpisode.Release.DownloadProtocol = Subject.Protocol;
|
remoteEpisode.Release.DownloadProtocol = Subject.Protocol;
|
||||||
|
|
||||||
remoteEpisode.ParsedEpisodeInfo = new ParsedEpisodeInfo();
|
remoteEpisode.ParsedMovieInfo = new ParsedMovieInfo();
|
||||||
remoteEpisode.ParsedEpisodeInfo.FullSeason = false;
|
//remoteEpisode.ParsedEpisodeInfo.FullSeason = false;
|
||||||
|
|
||||||
remoteEpisode.Episodes = new List<Episode>();
|
//remoteEpisode.Episodes = new List<Episode>();
|
||||||
|
|
||||||
remoteEpisode.Series = new Series();
|
remoteEpisode.Movie = new Movie();
|
||||||
|
|
||||||
return remoteEpisode;
|
return remoteEpisode;
|
||||||
}
|
}
|
||||||
|
|||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Download.Clients;
|
||||||
|
using NzbDrone.Core.Download.Clients.DownloadStation;
|
||||||
|
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class SerialNumberProviderFixture : CoreTest<SerialNumberProvider>
|
||||||
|
{
|
||||||
|
protected DownloadStationSettings _settings;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
protected void Setup()
|
||||||
|
{
|
||||||
|
_settings = new DownloadStationSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenValidResponse()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IDSMInfoProxy>()
|
||||||
|
.Setup(d => d.GetSerialNumber(It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Returns("serial");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenInvalidResponse()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IDSMInfoProxy>()
|
||||||
|
.Setup(d => d.GetSerialNumber(It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Throws(new DownloadClientException("Serial response invalid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_hashedserialnumber()
|
||||||
|
{
|
||||||
|
GivenValidResponse();
|
||||||
|
|
||||||
|
var serial = Subject.GetSerialNumber(_settings);
|
||||||
|
|
||||||
|
// This hash should remain the same for 'serial', so don't update the test if you change HashConverter, fix the code instead.
|
||||||
|
serial.Should().Be("50DE66B735D30738618568294742FCF1DFA52A47");
|
||||||
|
|
||||||
|
Mocker.GetMock<IDSMInfoProxy>()
|
||||||
|
.Verify(d => d.GetSerialNumber(It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_cache_serialnumber()
|
||||||
|
{
|
||||||
|
GivenValidResponse();
|
||||||
|
|
||||||
|
var serial1 = Subject.GetSerialNumber(_settings);
|
||||||
|
var serial2 = Subject.GetSerialNumber(_settings);
|
||||||
|
|
||||||
|
serial2.Should().Be(serial1);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDSMInfoProxy>()
|
||||||
|
.Verify(d => d.GetSerialNumber(It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_throw_if_serial_number_unavailable()
|
||||||
|
{
|
||||||
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.GetSerialNumber(_settings));
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
using System;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.Download.Clients;
|
||||||
|
using NzbDrone.Core.Download.Clients.DownloadStation;
|
||||||
|
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class SharedFolderResolverFixture : CoreTest<SharedFolderResolver>
|
||||||
|
{
|
||||||
|
protected string _serialNumber = "SERIALNUMBER";
|
||||||
|
protected OsPath _sharedFolder;
|
||||||
|
protected OsPath _physicalPath;
|
||||||
|
protected DownloadStationSettings _settings;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
protected void Setup()
|
||||||
|
{
|
||||||
|
_sharedFolder = new OsPath("/myFolder");
|
||||||
|
_physicalPath = new OsPath("/mnt/sda1/folder");
|
||||||
|
_settings = new DownloadStationSettings();
|
||||||
|
|
||||||
|
Mocker.GetMock<IFileStationProxy>()
|
||||||
|
.Setup(f => f.GetSharedFolderMapping(It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Throws(new DownloadClientException("There is no shared folder"));
|
||||||
|
|
||||||
|
Mocker.GetMock<IFileStationProxy>()
|
||||||
|
.Setup(f => f.GetSharedFolderMapping(_sharedFolder.FullPath, It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Returns(new SharedFolderMapping(_sharedFolder.FullPath, _physicalPath.FullPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_throw_when_cannot_resolve_shared_folder()
|
||||||
|
{
|
||||||
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.RemapToFullPath(new OsPath("/unknownFolder"), _settings, _serialNumber));
|
||||||
|
|
||||||
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_valid_sharedfolder()
|
||||||
|
{
|
||||||
|
var mapping = Subject.RemapToFullPath(_sharedFolder, _settings, "abc");
|
||||||
|
|
||||||
|
mapping.Should().Be(_physicalPath);
|
||||||
|
|
||||||
|
Mocker.GetMock<IFileStationProxy>()
|
||||||
|
.Verify(f => f.GetSharedFolderMapping(It.IsAny<string>(), It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_cache_mapping()
|
||||||
|
{
|
||||||
|
Subject.RemapToFullPath(_sharedFolder, _settings, "abc");
|
||||||
|
Subject.RemapToFullPath(_sharedFolder, _settings, "abc");
|
||||||
|
|
||||||
|
Mocker.GetMock<IFileStationProxy>()
|
||||||
|
.Verify(f => f.GetSharedFolderMapping(It.IsAny<string>(), It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_remap_subfolder()
|
||||||
|
{
|
||||||
|
var mapping = Subject.RemapToFullPath(_sharedFolder + "sub", _settings, "abc");
|
||||||
|
|
||||||
|
mapping.Should().Be(_physicalPath + "sub");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+622
@@ -0,0 +1,622 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.Download.Clients.DownloadStation;
|
||||||
|
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
||||||
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TorrentDownloadStationFixture : DownloadClientFixtureBase<TorrentDownloadStation>
|
||||||
|
{
|
||||||
|
protected DownloadStationSettings _settings;
|
||||||
|
|
||||||
|
protected DownloadStationTask _queued;
|
||||||
|
protected DownloadStationTask _downloading;
|
||||||
|
protected DownloadStationTask _failed;
|
||||||
|
protected DownloadStationTask _completed;
|
||||||
|
protected DownloadStationTask _seeding;
|
||||||
|
protected DownloadStationTask _magnet;
|
||||||
|
protected DownloadStationTask _singleFile;
|
||||||
|
protected DownloadStationTask _multipleFiles;
|
||||||
|
protected DownloadStationTask _singleFileCompleted;
|
||||||
|
protected DownloadStationTask _multipleFilesCompleted;
|
||||||
|
|
||||||
|
protected string _serialNumber = "SERIALNUMBER";
|
||||||
|
protected string _category = "sonarr";
|
||||||
|
protected string _tvDirectory = @"video/Series";
|
||||||
|
protected string _defaultDestination = "somepath";
|
||||||
|
protected OsPath _physicalPath = new OsPath("/mnt/sdb1/mydata");
|
||||||
|
|
||||||
|
protected Dictionary<string, object> _downloadStationConfigItems;
|
||||||
|
|
||||||
|
protected string DownloadURL => "magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcad53426&dn=download";
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_settings = new DownloadStationSettings()
|
||||||
|
{
|
||||||
|
Host = "127.0.0.1",
|
||||||
|
Port = 5000,
|
||||||
|
Username = "admin",
|
||||||
|
Password = "pass"
|
||||||
|
};
|
||||||
|
|
||||||
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
|
Subject.Definition.Settings = _settings;
|
||||||
|
|
||||||
|
_queued = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id1",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Waiting,
|
||||||
|
Type = DownloadStationTaskType.BT.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", DownloadURL }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "0"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_completed = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id2",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Finished,
|
||||||
|
Type = DownloadStationTaskType.BT.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", DownloadURL }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "1000"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_seeding = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id2",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Seeding,
|
||||||
|
Type = DownloadStationTaskType.BT.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", DownloadURL }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "1000"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_downloading = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id3",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Downloading,
|
||||||
|
Type = DownloadStationTaskType.BT.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", DownloadURL }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "100"},
|
||||||
|
{ "speed_download", "50" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_failed = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id4",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Error,
|
||||||
|
Type = DownloadStationTaskType.BT.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", DownloadURL }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "10"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_singleFile = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id5",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Seeding,
|
||||||
|
Type = DownloadStationTaskType.BT.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "a.mkv",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", DownloadURL }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "1000"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_multipleFiles = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id6",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Seeding,
|
||||||
|
Type = DownloadStationTaskType.BT.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", DownloadURL }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "1000"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_singleFileCompleted = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id6",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Finished,
|
||||||
|
Type = DownloadStationTaskType.BT.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "a.mkv",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", DownloadURL }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "1000"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_multipleFilesCompleted = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id6",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Finished,
|
||||||
|
Type = DownloadStationTaskType.BT.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", DownloadURL }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "1000"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocker.GetMock<ITorrentFileInfoReader>()
|
||||||
|
.Setup(s => s.GetHashFromTorrentFile(It.IsAny<byte[]>()))
|
||||||
|
.Returns("CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951");
|
||||||
|
|
||||||
|
Mocker.GetMock<IHttpClient>()
|
||||||
|
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||||
|
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[0]));
|
||||||
|
|
||||||
|
_downloadStationConfigItems = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "default_destination", _defaultDestination },
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Setup(v => v.GetConfig(It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Returns(_downloadStationConfigItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenSharedFolder()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ISharedFolderResolver>()
|
||||||
|
.Setup(s => s.RemapToFullPath(It.IsAny<OsPath>(), It.IsAny<DownloadStationSettings>(), It.IsAny<string>()))
|
||||||
|
.Returns<OsPath, DownloadStationSettings, string>((path, setttings, serial) => _physicalPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenSerialNumber()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ISerialNumberProvider>()
|
||||||
|
.Setup(s => s.GetSerialNumber(It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Returns(_serialNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenTvCategory()
|
||||||
|
{
|
||||||
|
_settings.TvCategory = _category;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenTvDirectory()
|
||||||
|
{
|
||||||
|
_settings.TvDirectory = _tvDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void GivenTasks(List<DownloadStationTask> torrents)
|
||||||
|
{
|
||||||
|
if (torrents == null)
|
||||||
|
{
|
||||||
|
torrents = new List<DownloadStationTask>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Setup(s => s.GetTasks(It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Returns(torrents);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void PrepareClientToReturnQueuedItem()
|
||||||
|
{
|
||||||
|
GivenTasks(new List<DownloadStationTask>
|
||||||
|
{
|
||||||
|
_queued
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenSuccessfulDownload()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IHttpClient>()
|
||||||
|
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||||
|
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[1000]));
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Setup(s => s.AddTaskFromUrl(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Callback(PrepareClientToReturnQueuedItem);
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Setup(s => s.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Callback(PrepareClientToReturnQueuedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override RemoteMovie CreateRemoteMovie()
|
||||||
|
{
|
||||||
|
var episode = base.CreateRemoteMovie();
|
||||||
|
|
||||||
|
episode.Release.DownloadUrl = DownloadURL;
|
||||||
|
|
||||||
|
return episode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int GivenAllKindOfTasks()
|
||||||
|
{
|
||||||
|
var tasks = new List<DownloadStationTask>() { _queued, _completed, _failed, _downloading, _seeding };
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Setup(d => d.GetTasks(_settings))
|
||||||
|
.Returns(tasks);
|
||||||
|
|
||||||
|
return tasks.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_with_TvDirectory_should_force_directory()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenTvDirectory();
|
||||||
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), _tvDirectory, It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_with_category_should_force_directory()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenTvCategory();
|
||||||
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), $"{_defaultDestination}/{_category}", It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_without_TvDirectory_and_Category_should_use_default()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_return_empty_list_if_no_tasks_available()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
GivenTasks(new List<DownloadStationTask>());
|
||||||
|
|
||||||
|
Subject.GetItems().Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_return_ignore_tasks_of_unknown_type()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
GivenTasks(new List<DownloadStationTask> { _completed });
|
||||||
|
|
||||||
|
_completed.Type = "ipfs";
|
||||||
|
|
||||||
|
Subject.GetItems().Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_ignore_downloads_in_wrong_folder()
|
||||||
|
{
|
||||||
|
_settings.TvDirectory = @"/shared/folder/sub";
|
||||||
|
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
GivenTasks(new List<DownloadStationTask> { _completed });
|
||||||
|
|
||||||
|
Subject.GetItems().Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_throw_if_shared_folder_resolve_fails()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ISharedFolderResolver>()
|
||||||
|
.Setup(s => s.RemapToFullPath(It.IsAny<OsPath>(), It.IsAny<DownloadStationSettings>(), It.IsAny<string>()))
|
||||||
|
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
|
||||||
|
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenAllKindOfTasks();
|
||||||
|
|
||||||
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.GetItems());
|
||||||
|
ExceptionVerification.ExpectedErrors(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_throw_if_serial_number_unavailable()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ISerialNumberProvider>()
|
||||||
|
.Setup(s => s.GetSerialNumber(_settings))
|
||||||
|
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
|
||||||
|
|
||||||
|
GivenSharedFolder();
|
||||||
|
GivenAllKindOfTasks();
|
||||||
|
|
||||||
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.GetItems());
|
||||||
|
ExceptionVerification.ExpectedErrors(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_should_throw_and_not_add_task_if_cannot_get_serial_number()
|
||||||
|
{
|
||||||
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
|
Mocker.GetMock<ISerialNumberProvider>()
|
||||||
|
.Setup(s => s.GetSerialNumber(_settings))
|
||||||
|
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
|
||||||
|
|
||||||
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.Download(remoteEpisode));
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, _settings), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_set_outputPath_to_base_folder_when_single_file_non_finished_tasks()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>() { _singleFile });
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
items.First().OutputPath.Should().Be(_physicalPath + _singleFile.Title);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_set_outputPath_to_torrent_folder_when_multiple_files_non_finished_tasks()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>() { _multipleFiles });
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
items.First().OutputPath.Should().Be(_physicalPath + _multipleFiles.Title);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_set_outputPath_to_base_folder_when_single_file_finished_tasks()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>() { _singleFileCompleted });
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
items.First().OutputPath.Should().Be(_physicalPath + _singleFileCompleted.Title);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_set_outputPath_to_torrent_folder_when_multiple_files_finished_tasks()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>() { _multipleFilesCompleted });
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
items.First().OutputPath.Should().Be($"{_physicalPath}/{_multipleFiles.Title}");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_not_map_outputpath_for_queued_or_downloading_tasks()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>
|
||||||
|
{
|
||||||
|
_queued, _downloading
|
||||||
|
});
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(2);
|
||||||
|
items.Should().OnlyContain(v => v.OutputPath.IsEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_map_outputpath_for_completed_or_failed_tasks()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>
|
||||||
|
{
|
||||||
|
_completed, _failed, _seeding
|
||||||
|
});
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(3);
|
||||||
|
items.Should().OnlyContain(v => !v.OutputPath.IsEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(DownloadStationTaskStatus.Downloading, DownloadItemStatus.Downloading, true)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Finished, DownloadItemStatus.Completed, false)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Seeding, DownloadItemStatus.Completed, true)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Waiting, DownloadItemStatus.Queued, true)]
|
||||||
|
public void GetItems_should_return_readonly_expected(DownloadStationTaskStatus apiStatus, DownloadItemStatus expectedItemStatus, bool readOnlyExpected)
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
_queued.Status = apiStatus;
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>() { _queued });
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
items.First().IsReadOnly.Should().Be(readOnlyExpected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(DownloadStationTaskStatus.Downloading, DownloadItemStatus.Downloading)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Error, DownloadItemStatus.Failed)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Extracting, DownloadItemStatus.Downloading)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Finished, DownloadItemStatus.Completed)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Finishing, DownloadItemStatus.Downloading)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.HashChecking, DownloadItemStatus.Downloading)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Paused, DownloadItemStatus.Paused)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Seeding, DownloadItemStatus.Completed)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Waiting, DownloadItemStatus.Queued)]
|
||||||
|
public void GetItems_should_return_item_as_downloadItemStatus(DownloadStationTaskStatus apiStatus, DownloadItemStatus expectedItemStatus)
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
_queued.Status = apiStatus;
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>() { _queued });
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
|
||||||
|
items.First().Status.Should().Be(expectedItemStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+452
@@ -0,0 +1,452 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.Download.Clients.DownloadStation;
|
||||||
|
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
||||||
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
using NzbDrone.Core.Organizer;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class UsenetDownloadStationFixture : DownloadClientFixtureBase<UsenetDownloadStation>
|
||||||
|
{
|
||||||
|
protected DownloadStationSettings _settings;
|
||||||
|
|
||||||
|
protected DownloadStationTask _queued;
|
||||||
|
protected DownloadStationTask _downloading;
|
||||||
|
protected DownloadStationTask _failed;
|
||||||
|
protected DownloadStationTask _completed;
|
||||||
|
protected DownloadStationTask _seeding;
|
||||||
|
|
||||||
|
protected string _serialNumber = "SERIALNUMBER";
|
||||||
|
protected string _category = "sonarr";
|
||||||
|
protected string _tvDirectory = @"video/Series";
|
||||||
|
protected string _defaultDestination = "somepath";
|
||||||
|
protected OsPath _physicalPath = new OsPath("/mnt/sdb1/mydata");
|
||||||
|
|
||||||
|
protected RemoteMovie _remoteEpisode;
|
||||||
|
|
||||||
|
protected Dictionary<string, object> _downloadStationConfigItems;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
|
_settings = new DownloadStationSettings()
|
||||||
|
{
|
||||||
|
Host = "127.0.0.1",
|
||||||
|
Port = 5000,
|
||||||
|
Username = "admin",
|
||||||
|
Password = "pass"
|
||||||
|
};
|
||||||
|
|
||||||
|
Subject.Definition = new DownloadClientDefinition();
|
||||||
|
Subject.Definition.Settings = _settings;
|
||||||
|
|
||||||
|
_queued = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id1",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Waiting,
|
||||||
|
Type = DownloadStationTaskType.NZB.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", FileNameBuilder.CleanFileName(_remoteEpisode.Release.Title) + ".nzb" }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "0"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_completed = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id2",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Finished,
|
||||||
|
Type = DownloadStationTaskType.NZB.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", FileNameBuilder.CleanFileName(_remoteEpisode.Release.Title) + ".nzb" }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "1000"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_seeding = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id2",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Seeding,
|
||||||
|
Type = DownloadStationTaskType.NZB.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", FileNameBuilder.CleanFileName(_remoteEpisode.Release.Title) + ".nzb" }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "1000"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_downloading = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id3",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Downloading,
|
||||||
|
Type = DownloadStationTaskType.NZB.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", FileNameBuilder.CleanFileName(_remoteEpisode.Release.Title) + ".nzb" }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "100"},
|
||||||
|
{ "speed_download", "50" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_failed = new DownloadStationTask()
|
||||||
|
{
|
||||||
|
Id = "id4",
|
||||||
|
Size = 1000,
|
||||||
|
Status = DownloadStationTaskStatus.Error,
|
||||||
|
Type = DownloadStationTaskType.NZB.ToString(),
|
||||||
|
Username = "admin",
|
||||||
|
Title = "title",
|
||||||
|
Additional = new DownloadStationTaskAdditional
|
||||||
|
{
|
||||||
|
Detail = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "destination","shared/folder" },
|
||||||
|
{ "uri", FileNameBuilder.CleanFileName(_remoteEpisode.Release.Title) + ".nzb" }
|
||||||
|
},
|
||||||
|
Transfer = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "size_downloaded", "10"},
|
||||||
|
{ "speed_download", "0" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocker.GetMock<IHttpClient>()
|
||||||
|
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||||
|
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[0]));
|
||||||
|
|
||||||
|
_downloadStationConfigItems = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "default_destination", _defaultDestination },
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Setup(v => v.GetConfig(It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Returns(_downloadStationConfigItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenSharedFolder()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ISharedFolderResolver>()
|
||||||
|
.Setup(s => s.RemapToFullPath(It.IsAny<OsPath>(), It.IsAny<DownloadStationSettings>(), It.IsAny<string>()))
|
||||||
|
.Returns<OsPath, DownloadStationSettings, string>((path, setttings, serial) => _physicalPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenSerialNumber()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ISerialNumberProvider>()
|
||||||
|
.Setup(s => s.GetSerialNumber(It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Returns(_serialNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenTvCategory()
|
||||||
|
{
|
||||||
|
_settings.TvCategory = _category;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenTvDirectory()
|
||||||
|
{
|
||||||
|
_settings.TvDirectory = _tvDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void GivenTasks(List<DownloadStationTask> nzbs)
|
||||||
|
{
|
||||||
|
if (nzbs == null)
|
||||||
|
{
|
||||||
|
nzbs = new List<DownloadStationTask>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Setup(s => s.GetTasks(It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Returns(nzbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void PrepareClientToReturnQueuedItem()
|
||||||
|
{
|
||||||
|
GivenTasks(new List<DownloadStationTask>
|
||||||
|
{
|
||||||
|
_queued
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenSuccessfulDownload()
|
||||||
|
{/*
|
||||||
|
Mocker.GetMock<IHttpClient>()
|
||||||
|
.Setup(s => s.Get(It.IsAny<HttpRequest>()))
|
||||||
|
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[1000]));
|
||||||
|
*/
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Setup(s => s.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
||||||
|
.Callback(PrepareClientToReturnQueuedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void GivenAllKindOfTasks()
|
||||||
|
{
|
||||||
|
var tasks = new List<DownloadStationTask>() { _queued, _completed, _failed, _downloading, _seeding };
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Setup(d => d.GetTasks(_settings))
|
||||||
|
.Returns(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_with_TvDirectory_should_force_directory()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenTvDirectory();
|
||||||
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Verify(v => v.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), _tvDirectory, It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_with_category_should_force_directory()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenTvCategory();
|
||||||
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Verify(v => v.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), $"{_defaultDestination}/{_category}", It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_without_TvDirectory_and_Category_should_use_default()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
id.Should().NotBeNullOrEmpty();
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Verify(v => v.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), null, It.IsAny<DownloadStationSettings>()), Times.Once());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_return_empty_list_if_no_tasks_available()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
GivenTasks(new List<DownloadStationTask>());
|
||||||
|
|
||||||
|
Subject.GetItems().Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_return_ignore_tasks_of_unknown_type()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
GivenTasks(new List<DownloadStationTask> { _completed });
|
||||||
|
|
||||||
|
_completed.Type = "ipfs";
|
||||||
|
|
||||||
|
Subject.GetItems().Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_ignore_downloads_in_wrong_folder()
|
||||||
|
{
|
||||||
|
_settings.TvDirectory = @"/shared/folder/sub";
|
||||||
|
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
GivenTasks(new List<DownloadStationTask> { _completed });
|
||||||
|
|
||||||
|
Subject.GetItems().Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_throw_if_shared_folder_resolve_fails()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ISharedFolderResolver>()
|
||||||
|
.Setup(s => s.RemapToFullPath(It.IsAny<OsPath>(), It.IsAny<DownloadStationSettings>(), It.IsAny<string>()))
|
||||||
|
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
|
||||||
|
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenAllKindOfTasks();
|
||||||
|
|
||||||
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.GetItems());
|
||||||
|
ExceptionVerification.ExpectedErrors(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_throw_if_serial_number_unavailable()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<ISerialNumberProvider>()
|
||||||
|
.Setup(s => s.GetSerialNumber(_settings))
|
||||||
|
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
|
||||||
|
|
||||||
|
GivenSharedFolder();
|
||||||
|
GivenAllKindOfTasks();
|
||||||
|
|
||||||
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.GetItems());
|
||||||
|
ExceptionVerification.ExpectedErrors(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Download_should_throw_and_not_add_task_if_cannot_get_serial_number()
|
||||||
|
{
|
||||||
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
|
Mocker.GetMock<ISerialNumberProvider>()
|
||||||
|
.Setup(s => s.GetSerialNumber(_settings))
|
||||||
|
.Throws(new ApplicationException("Some unknown exception, HttpException or DownloadClientException"));
|
||||||
|
|
||||||
|
Assert.Throws(Is.InstanceOf<Exception>(), () => Subject.Download(remoteEpisode));
|
||||||
|
|
||||||
|
Mocker.GetMock<IDownloadStationProxy>()
|
||||||
|
.Verify(v => v.AddTaskFromUrl(It.IsAny<string>(), null, _settings), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_not_map_outputpath_for_queued_or_downloading_tasks()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>
|
||||||
|
{
|
||||||
|
_queued, _downloading
|
||||||
|
});
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(2);
|
||||||
|
items.Should().OnlyContain(v => v.OutputPath.IsEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void GetItems_should_map_outputpath_for_completed_or_failed_tasks()
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>
|
||||||
|
{
|
||||||
|
_completed, _failed, _seeding
|
||||||
|
});
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(3);
|
||||||
|
items.Should().OnlyContain(v => !v.OutputPath.IsEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(DownloadStationTaskStatus.Downloading, DownloadItemStatus.Downloading, true)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Finished, DownloadItemStatus.Completed, false)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Waiting, DownloadItemStatus.Queued, true)]
|
||||||
|
public void GetItems_should_return_readonly_expected(DownloadStationTaskStatus apiStatus, DownloadItemStatus expectedItemStatus, bool readOnlyExpected)
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
_queued.Status = apiStatus;
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>() { _queued });
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
items.First().IsReadOnly.Should().Be(readOnlyExpected);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(DownloadStationTaskStatus.Downloading, DownloadItemStatus.Downloading)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Error, DownloadItemStatus.Failed)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Extracting, DownloadItemStatus.Downloading)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Finished, DownloadItemStatus.Completed)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Finishing, DownloadItemStatus.Downloading)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.HashChecking, DownloadItemStatus.Downloading)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Paused, DownloadItemStatus.Paused)]
|
||||||
|
[TestCase(DownloadStationTaskStatus.Waiting, DownloadItemStatus.Queued)]
|
||||||
|
public void GetItems_should_return_item_as_downloadItemStatus(DownloadStationTaskStatus apiStatus, DownloadItemStatus expectedItemStatus)
|
||||||
|
{
|
||||||
|
GivenSerialNumber();
|
||||||
|
GivenSharedFolder();
|
||||||
|
|
||||||
|
_queued.Status = apiStatus;
|
||||||
|
|
||||||
|
GivenTasks(new List<DownloadStationTask>() { _queued });
|
||||||
|
|
||||||
|
var items = Subject.GetItems();
|
||||||
|
items.Should().HaveCount(1);
|
||||||
|
|
||||||
|
items.First().Status.Should().Be(expectedItemStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -197,7 +197,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_from_magnet_link_should_return_hash_uppercase()
|
public void Download_from_magnet_link_should_return_hash_uppercase()
|
||||||
{
|
{
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
remoteEpisode.Release.DownloadUrl = "magnet:?xt=urn:btih:a45129e59d8750f9da982f53552b1e4f0457ee9f";
|
remoteEpisode.Release.DownloadUrl = "magnet:?xt=urn:btih:a45129e59d8750f9da982f53552b1e4f0457ee9f";
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
|||||||
[Test]
|
[Test]
|
||||||
public void Download_from_torrent_file_should_return_hash_uppercase()
|
public void Download_from_torrent_file_should_return_hash_uppercase()
|
||||||
{
|
{
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
Mocker.GetMock<IHadoukenProxy>()
|
Mocker.GetMock<IHadoukenProxy>()
|
||||||
.Setup(v => v.AddTorrentFile(It.IsAny<HadoukenSettings>(), It.IsAny<byte[]>()))
|
.Setup(v => v.AddTorrentFile(It.IsAny<HadoukenSettings>(), It.IsAny<byte[]>()))
|
||||||
|
|||||||
+2
-2
@@ -189,7 +189,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbVortexTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbVortexTests
|
|||||||
{
|
{
|
||||||
GivenFailedDownload();
|
GivenFailedDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
Assert.Throws<DownloadClientException>(() => Subject.Download(remoteEpisode));
|
Assert.Throws<DownloadClientException>(() => Subject.Download(remoteEpisode));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -315,7 +315,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
|||||||
{
|
{
|
||||||
GivenFailedDownload();
|
GivenFailedDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
Assert.Throws<DownloadClientException>(() => Subject.Download(remoteEpisode));
|
Assert.Throws<DownloadClientException>(() => Subject.Download(remoteEpisode));
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -245,7 +245,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
@@ -290,7 +290,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
|||||||
GivenRedirectToMagnet();
|
GivenRedirectToMagnet();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -303,7 +303,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
|||||||
GivenRedirectToTorrent();
|
GivenRedirectToTorrent();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -116,7 +116,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.Title = title;
|
remoteEpisode.Release.Title = title;
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
@@ -274,7 +274,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -315,12 +315,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
|||||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), (int)SabnzbdPriority.High, It.IsAny<SabnzbdSettings>()))
|
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), (int)SabnzbdPriority.High, It.IsAny<SabnzbdSettings>()))
|
||||||
.Returns(new SabnzbdAddResponse());
|
.Returns(new SabnzbdAddResponse());
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
|
//remoteEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
|
||||||
.All()
|
// .All()
|
||||||
.With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
|
// .With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
|
||||||
.Build()
|
// .Build()
|
||||||
.ToList();
|
// .ToList();
|
||||||
|
|
||||||
Subject.Download(remoteEpisode);
|
Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
|||||||
GivenTvDirectory();
|
GivenTvDirectory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
|||||||
GivenTvCategory();
|
GivenTvCategory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
|||||||
|
|
||||||
_transmissionConfigItems["download-dir"] += "/";
|
_transmissionConfigItems["download-dir"] += "/";
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|||||||
+4
-4
@@ -229,7 +229,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -253,7 +253,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
@@ -351,7 +351,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
|||||||
GivenRedirectToMagnet();
|
GivenRedirectToMagnet();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -364,7 +364,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
|||||||
GivenRedirectToTorrent();
|
GivenRedirectToTorrent();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
|||||||
GivenTvDirectory();
|
GivenTvDirectory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
|||||||
GivenTvCategory();
|
GivenTvCategory();
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
|||||||
|
|
||||||
_transmissionConfigItems["download-dir"] += "/";
|
_transmissionConfigItems["download-dir"] += "/";
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
|||||||
{
|
{
|
||||||
GivenSuccessfulDownload();
|
GivenSuccessfulDownload();
|
||||||
|
|
||||||
var remoteEpisode = CreateRemoteEpisode();
|
var remoteEpisode = CreateRemoteMovie();
|
||||||
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
remoteEpisode.Release.DownloadUrl = magnetUrl;
|
||||||
|
|
||||||
var id = Subject.Download(remoteEpisode);
|
var id = Subject.Download(remoteEpisode);
|
||||||
|
|||||||
+18
-21
@@ -20,22 +20,19 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||||||
public class RemoveGrabbedFixture : CoreTest<PendingReleaseService>
|
public class RemoveGrabbedFixture : CoreTest<PendingReleaseService>
|
||||||
{
|
{
|
||||||
private DownloadDecision _temporarilyRejected;
|
private DownloadDecision _temporarilyRejected;
|
||||||
private Series _series;
|
private Movie _series;
|
||||||
private Episode _episode;
|
private Episode _episode;
|
||||||
private Profile _profile;
|
private Profile _profile;
|
||||||
private ReleaseInfo _release;
|
private ReleaseInfo _release;
|
||||||
private ParsedEpisodeInfo _parsedEpisodeInfo;
|
private ParsedMovieInfo _parsedEpisodeInfo;
|
||||||
private RemoteEpisode _remoteEpisode;
|
private RemoteMovie _remoteEpisode;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_series = Builder<Series>.CreateNew()
|
_series = Builder<Movie>.CreateNew()
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_episode = Builder<Episode>.CreateNew()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_profile = new Profile
|
_profile = new Profile
|
||||||
{
|
{
|
||||||
Name = "Test",
|
Name = "Test",
|
||||||
@@ -52,13 +49,13 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||||||
|
|
||||||
_release = Builder<ReleaseInfo>.CreateNew().Build();
|
_release = Builder<ReleaseInfo>.CreateNew().Build();
|
||||||
|
|
||||||
_parsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew().Build();
|
_parsedEpisodeInfo = Builder<ParsedMovieInfo>.CreateNew().Build();
|
||||||
_parsedEpisodeInfo.Quality = new QualityModel(Quality.HDTV720p);
|
_parsedEpisodeInfo.Quality = new QualityModel(Quality.HDTV720p);
|
||||||
|
|
||||||
_remoteEpisode = new RemoteEpisode();
|
_remoteEpisode = new RemoteMovie();
|
||||||
_remoteEpisode.Episodes = new List<Episode>{ _episode };
|
//_remoteEpisode.Episodes = new List<Episode>{ _episode };
|
||||||
_remoteEpisode.Series = _series;
|
_remoteEpisode.Movie = _series;
|
||||||
_remoteEpisode.ParsedEpisodeInfo = _parsedEpisodeInfo;
|
_remoteEpisode.ParsedMovieInfo = _parsedEpisodeInfo;
|
||||||
_remoteEpisode.Release = _release;
|
_remoteEpisode.Release = _release;
|
||||||
|
|
||||||
_temporarilyRejected = new DownloadDecision(_remoteEpisode, new Rejection("Temp Rejected", RejectionType.Temporary));
|
_temporarilyRejected = new DownloadDecision(_remoteEpisode, new Rejection("Temp Rejected", RejectionType.Temporary));
|
||||||
@@ -67,13 +64,13 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||||||
.Setup(s => s.All())
|
.Setup(s => s.All())
|
||||||
.Returns(new List<PendingRelease>());
|
.Returns(new List<PendingRelease>());
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
Mocker.GetMock<IMovieService>()
|
||||||
.Setup(s => s.GetSeries(It.IsAny<int>()))
|
.Setup(s => s.GetMovie(It.IsAny<int>()))
|
||||||
.Returns(_series);
|
.Returns(_series);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
//Mocker.GetMock<IParsingService>()
|
||||||
.Setup(s => s.GetEpisodes(It.IsAny<ParsedEpisodeInfo>(), _series, true, null))
|
// .Setup(s => s.GetMovie(It.IsAny<ParsedMovieInfo>(), _series.Title))
|
||||||
.Returns(new List<Episode> {_episode});
|
// .Returns(_episode);
|
||||||
|
|
||||||
Mocker.GetMock<IPrioritizeDownloadDecision>()
|
Mocker.GetMock<IPrioritizeDownloadDecision>()
|
||||||
.Setup(s => s.PrioritizeDecisions(It.IsAny<List<DownloadDecision>>()))
|
.Setup(s => s.PrioritizeDecisions(It.IsAny<List<DownloadDecision>>()))
|
||||||
@@ -89,7 +86,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||||||
.All()
|
.All()
|
||||||
.With(h => h.SeriesId = _series.Id)
|
.With(h => h.SeriesId = _series.Id)
|
||||||
.With(h => h.Release = _release.JsonClone())
|
.With(h => h.Release = _release.JsonClone())
|
||||||
.With(h => h.ParsedEpisodeInfo = parsedEpisodeInfo)
|
.With(h => h.ParsedMovieInfo = _parsedEpisodeInfo)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
Mocker.GetMock<IPendingReleaseRepository>()
|
Mocker.GetMock<IPendingReleaseRepository>()
|
||||||
@@ -102,7 +99,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||||||
{
|
{
|
||||||
GivenHeldRelease(_parsedEpisodeInfo.Quality);
|
GivenHeldRelease(_parsedEpisodeInfo.Quality);
|
||||||
|
|
||||||
Subject.Handle(new EpisodeGrabbedEvent(_remoteEpisode));
|
Subject.Handle(new MovieGrabbedEvent(_remoteEpisode));
|
||||||
|
|
||||||
VerifyDelete();
|
VerifyDelete();
|
||||||
}
|
}
|
||||||
@@ -112,7 +109,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||||||
{
|
{
|
||||||
GivenHeldRelease(new QualityModel(Quality.SDTV));
|
GivenHeldRelease(new QualityModel(Quality.SDTV));
|
||||||
|
|
||||||
Subject.Handle(new EpisodeGrabbedEvent(_remoteEpisode));
|
Subject.Handle(new MovieGrabbedEvent(_remoteEpisode));
|
||||||
|
|
||||||
VerifyDelete();
|
VerifyDelete();
|
||||||
}
|
}
|
||||||
@@ -122,7 +119,7 @@ namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
|||||||
{
|
{
|
||||||
GivenHeldRelease(new QualityModel(Quality.Bluray720p));
|
GivenHeldRelease(new QualityModel(Quality.Bluray720p));
|
||||||
|
|
||||||
Subject.Handle(new EpisodeGrabbedEvent(_remoteEpisode));
|
Subject.Handle(new MovieGrabbedEvent(_remoteEpisode));
|
||||||
|
|
||||||
VerifyNoDelete();
|
VerifyNoDelete();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,281 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<channel>
|
||||||
|
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
|
||||||
|
<meta xmlns="http://pipes.yahoo.com" name="pipes" content="noprocess" />
|
||||||
|
<title>TV :: AlphaRatio</title>
|
||||||
|
<link>https://alpharatio.cc/</link>
|
||||||
|
<description>Personal RSS feed: TV</description>
|
||||||
|
<language>en-us</language>
|
||||||
|
<lastBuildDate>Tue, 29 Nov 2016 11:01:28 +0000</lastBuildDate>
|
||||||
|
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
|
||||||
|
<generator>Gazelle Feed Class</generator>
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<title><![CDATA[TvHD 465989 465960 Good.Behavior.S01E03.PROPER.720p.HDTV.x264-KILLERS]]></title>
|
||||||
|
<description>
|
||||||
|
<![CDATA[MB <br />
|
||||||
|
@@@@: : <br />
|
||||||
|
:7 :::.7:@.:u7:.X5LF <br />
|
||||||
|
.LFq2 .B@B@B@B@B@B@B@ <br />
|
||||||
|
.. i@r rB@B@B@B@B@B@B@@@: <br />
|
||||||
|
: :B@B@B@B@: X@@@@@B@B@B@B@B@B@B@J .u@B. <br />
|
||||||
|
:.YkuB@B@B@BM. @B@B@B@B@B@@@B@B@B@r 2B@B@B@B@i <br />
|
||||||
|
@@@B@r@@@B@B: B@B@B@B@B@@@B@B@B@B@ i@B@B@B@BrO@@@@@ <br />
|
||||||
|
@@@@B@B@BB, r:@B@B@@@B@@@B@q@@@BM @L:B.B, @@B@B@B@BO@@@@B@B@B <br />
|
||||||
|
jB@B@B@B@N. 7 B@@@@@B@B@O 8B@. @F B@B@B@@@O@B@B@B@@@@@B. <br />
|
||||||
|
i@B@B@B@: 7 @B@B@B@B@ B: B: i@B@B@B@BNB8B7 .B@@ <br />
|
||||||
|
@B@B@. 1G @B@B@B@ @ , @B@:i @u @: 0EB@ <br />
|
||||||
|
;ir , U@B@B .@ B@B L B@B <br />
|
||||||
|
7 B@B@ q@Bv:@BP @B@ <br />
|
||||||
|
i@Bu @ ,S@ @@ B@@@B@B@. BkU@B@ 5Ui @Y@B <br />
|
||||||
|
@@B@v B :@iB B@@@B@B@M@ @B@@@B@BB @@7i iU 5i2vB@k B@ <br />
|
||||||
|
@B@B@B7 i @ @B@B@B@B@B@B5 i@B@@@B@ r @ <br />
|
||||||
|
@B@B@B@. @ B@B@B@B@B@B@B@. MB @Bu . U @Bi <br />
|
||||||
|
k@P @@@OBi .@ @B@B@B@B@B@B@B. @MBB@@ @F @ 7B@B <br />
|
||||||
|
@B @B@@@B@ 0B@B@B@B@B@B@B@B@ B@B@B@B@F B@B@B. B@B <br />
|
||||||
|
B @B@B@B B: B@B@B@B@@@B@@@BM B@B@B@B@B@: @B@;:B@@@: F@B <br />
|
||||||
|
@. B@@@B@ @Bu i. MX J B@B@B@ @B. @B@B@B@@ B@B@F Si k@@ B@BN <br />
|
||||||
|
@@ @B@B@B@B@B B @B@BOr: .i0F7@B: B@B@ E@ @B@B@r@ B@B@B. @B@B@B5 <br />
|
||||||
|
B@B@B@@@B@B@B: @B@B@B@Z: B@B@B@B@B@B@@@B, L@ @B@ B@B@B@B@B@B@B, <br />
|
||||||
|
:@B@B@B@B@B@B@: Y@B@@@@@B@B@B@: 7B@@@0 :@ L@ ,@B@B@B@B@B@B@B@. <br />
|
||||||
|
JB@B@B@B@B@B@B@ U@B@@J, @U.@@B@B@B B@F i@ PB @B@B@B@B@BG.@B@B@B, <br />
|
||||||
|
r@B@B@B@B@B@B@B ; @B@B@ :. @ @J r@ G@ @@: .Z@@7 B@@@@@B@B@B@F <br />
|
||||||
|
,B@B@B@B@B@B@B@B5 @B@@@ j@B5E@BXB@BvO rB OB B@ B@@@r B@B@B@B@B@B@B@B. <br />
|
||||||
|
@B@B@B@B@B@@@B@i @@ .uO0 :v. @ @B@B @@@ L: ,@ .@ Z@ iB B@B @B@B@@@BNB@ :2@B@B@B@@@B@B <br />
|
||||||
|
:@@B@B@B@B@@@B@B..@@@B@B@@. :YY B@@@: B, B .: u@ .@B@B r@ OB i@B@B@@@B@B <br />
|
||||||
|
UB@B@B@B@B@@@B@B@B@B@B LJ, @B@B. @. @ Y @BP .rUB@B@B@B@Z7, B@B@B@B@B@ <br />
|
||||||
|
,@B@@@B@B@B@B@B@@@ i17. @B@B@v O, B 1B@B@B@B@@@B@@@B@B@B@B@B@B@B@BiB@Bv<br />
|
||||||
|
:B@B@B@B@B@B@B@2@B B@B@B@ k. .@ M@@BOB@B@B@B@B@B@B@B@B@B@B@B@B@P @@B<br />
|
||||||
|
i@B@B@@@B@B@B@B M@B .7 @B@B@r B. 7B @ YB@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@@@<br />
|
||||||
|
u@@B@B@B@@@B@B@ B@B@ 2U8. 5B@@E @, r@ M B@B@B@B@B@B@B@B@B@@@B@B@B@B@@@B@@@@@B<br />
|
||||||
|
q@B@B@B@@@B@B@B. @@@i2 @JX :@B@ BY rB @ G@@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@<br />
|
||||||
|
BB@B@B@B@B@B@Bi . B@@: @B @ @B@B@B@B@B@B@B@B@B@B@B@@@@@B@B@B@j<br />
|
||||||
|
O@B@B@B@B@B@B@@@ u@B@@ Bu B @@B@B@B@BB8 0B@B@B <br />
|
||||||
|
SB@B@B@B@B@B@B@B@B @@B@@@B @ .BS r @@@B@ <br />
|
||||||
|
.@B@B@B@B@B@B@B@B@ B@B@@@B@Br XB@Br 7B u .vB B: B@B@B@B <br />
|
||||||
|
@@@@B@B@B@B@B@B@B@B@B .@B@B@B@B@@M i..@. i i i P @,jB @@B <br />
|
||||||
|
@B@B@B@B@B@B@B@B@B@B@B@i @N@@@B@@@B@B@B @ B@E <br />
|
||||||
|
@B@B@B@@@B@B@B@B@B@B@B@B @ : @@B@B@@@Mi B . @@ <br />
|
||||||
|
F@B@@@B@B@B@B@B@@@B@B@B@,@ M @.:v X i B :BM <br />
|
||||||
|
i@B@B@B@B@@@B@B@B@@@@@B@B L ,r , ; B@. @B@, <br />
|
||||||
|
,M@B@B @B@B@B@B@@@B@B@B@ rL B j :jr@B@@r @B@B@B <br />
|
||||||
|
@B@B@B@B@B@B@B@B .: . .@ : , @@@@B@@ <br />
|
||||||
|
,@B@B@B@B@B@B@B .@X r5BMB: r ,, 7 B B@B @B@B@B@@ <br />
|
||||||
|
L@@B@B@B@ 8B@B@ BM:@B@B@B@B@B@@8X80Mu: FB@B@B@B@B@@@B@B@@@B@B q uO@GMFLv@B@B@B@B@ B@Bu <br />
|
||||||
|
@B@B@B@B k@ MYM@@@B@B@F ,. :5@B@B7 Y@B@@@@@B@@@B@@@@@B@@@@@B@ B : B@B@B@ @@B@BL <br />
|
||||||
|
B@@@@@@@ @@7 @EvB@BF B@B@B@@@@@B@BMB@B@B@B@@@B@B@B@ 7 . .@u, i@ B@B@77B@ <br />
|
||||||
|
B@B@B@@@O@ : 7., :@B@@@B@B@B@, .LB@@@B@B@B@B@B@B@ @ r@: @::M @@B@B@M@B@ <br />
|
||||||
|
:i @B@B@@@Bi5 :: v@B@@@B@B@B B@@@B@@@B@@@B@@ B@@@B@B@B@B@B@B@i<br />
|
||||||
|
: B@B@B@B@B@ @B@B@B@@@B LB@B@@@B@B@B@B@B@@5 @B@B@B@B@B@@@B@ <br />
|
||||||
|
.k@B@B@B@B@B@u. B@B@B@B@B2 @B@B@B@B@B@@@B@B@@@B@@@B@B@B@B@B@B@ <br />
|
||||||
|
:Lur:F@@@B@B@B@B@@@B B@B@B@B@B@ @@@B@B@B@B@B@@@B@B@B@B@B@B@B@B@B@J <br />
|
||||||
|
.vBMi :,,rB@B@B@B@BO @@@B@B@@@5 :i@@@B@B@B@@@B@B@B@B@@@B@@@B@B@B@@: <br />
|
||||||
|
1r @B@B@B@B@B@ LB@B@B@B@Bq N@Bi rB@B@B@B@B@B@B@@@B@B@B@B@B@B@@@B@ <br />
|
||||||
|
,L. @@B@B@B@G Li .@B@B@B@B@B@@@B@. B@B@viv@B@B@B@B@B@B@B@B@B@B@B@@@B@B@B@ <br />
|
||||||
|
r, @@@@@B@@@B@: : B@B@B@B@B@B@@@B@ :B@ @S@B@B@B@B@B@B@@@B@B@B@@@B@B@B@ <br />
|
||||||
|
.j iB@B@B@B@B@B@Bi:; G @@BrLk . i M@B@B@@@B@@@ GB@B@B@B@B@B@B@B@B@@@B@B@B@: <br />
|
||||||
|
,: : BUB@B@B@B@@@@@N0r@B@B B@B@ : :@B@B@B@@@B @B@B@B@B@B@B@B@B@B@B@B@. B <br />
|
||||||
|
@i ui M .. @B@: B.@@B@BB:O @. B @ i B@@@@@B@ @@@B@B@B@@@B @@B@B@B@@@B @ @ <br />
|
||||||
|
E@ @7 ; .U i N@B@ B .@ @ @B@B@B@B@ v .GB @B@B@B@B@@@M: @B@B@B@B@BZ @ Y <br />
|
||||||
|
Bu .@ M 7v7 @ :B@B@@@B@BU @B@B@B@B@ BB@B@B@B@B@Bi B@@@B@B@B@v <br />
|
||||||
|
5@ @7 L S .q .N@B@@@B@BBB@B@B@B@B@B@kqqSB@B@B@B@B@ @B@B@B@B@@r <br />
|
||||||
|
q : B Z .: 2@B@B@B@..L. . M@B@B@:@BiP @B B@@@B@B@B@ <br />
|
||||||
|
; B@@@B@B. @@@B@: 2@B@B@ i @B@@@B@B@B <br />
|
||||||
|
7@B@k@B@B@B@B@B@B@B@ B@B@@@@@Bi <br />
|
||||||
|
jB@B@B@@@B@@O @B@B@B@B@ <br />
|
||||||
|
B@B@B@B@k B@@@B@@@B <br />
|
||||||
|
rPS: @B@ @B@B@ <br />
|
||||||
|
. :: ,ui:,: vL:,:: B@B B@B@B <br />
|
||||||
|
.B@B@B@B@i @B@@@B@5 @B@B :@@@@@ OB@@@ @B@ @B@@@ <br />
|
||||||
|
@B@B@ FB@B@ 7@B@B@ .@@@B @B@B iMB@B@S .GB@B@.,B@@L vG0Sqv;:@ L@@ ..E@B <br />
|
||||||
|
B@@@B@@@B@B@B .@B@@ :B@B@ B@B@ @B@B@..B@B@ @B@@@2.B@B@ @B@BBM S@1 S@. <br />
|
||||||
|
@B@B@B. ,@B@B8 B@B@ .@B@@ @B@@ B@B@8:iii;Mv i@B@M .rr B@B@B@B k@r EJ <br />
|
||||||
|
S@B@B@B@ EB@B@B@B. B@B@B@, r@B@B@1 @B@B@B: YB@@@r. 7@B@B@2 @@@@@@MB@B@ ,Bi <br />
|
||||||
|
:r, .i ,: .i: :i ,:.i. i,:: :: :J@B@X7 i. i: r :,:. ,@ a <br />
|
||||||
|
.B n <br />
|
||||||
|
[ P R E S E N T S ] @ t <br />
|
||||||
|
@ i <br />
|
||||||
|
0 / <br />
|
||||||
|
B 4 <br />
|
||||||
|
@ 0 <br />
|
||||||
|
. 4 <br />
|
||||||
|
<br />
|
||||||
|
Good.Behavior.S01E03.PROPER.720p.HDTV.x264-KILLERS<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Day: 2016-11-29<br />
|
||||||
|
Resolution: 1280x720<br />
|
||||||
|
Size: 1.02 GiB<br />
|
||||||
|
FrameRate: 23.976<br />
|
||||||
|
Length: 00:49:02.144<br />
|
||||||
|
Bitrate: 2 535 Kbps<br />
|
||||||
|
Note: FLEET is missing the last seg<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
n***** We all miss you. Come back soon.]]>
|
||||||
|
</description>
|
||||||
|
<pubDate>Tue, 29 Nov 2016 10:55:58 +0000</pubDate>
|
||||||
|
<link>https://alpharatio.cc/torrents.php?action=download&authkey=private_auth_key&torrent_pass=private_torrent_pass&id=465960</link>
|
||||||
|
<guid>https://alpharatio.cc/torrents.php?action=download&authkey=private_auth_key&torrent_pass=private_torrent_pass&id=465960</guid>
|
||||||
|
<comments>https://alpharatio.cc/torrents.php?id=465989</comments>
|
||||||
|
<dc:creator>Anonymous</dc:creator>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<title><![CDATA[TvHD 465860 465831 WWE.RAW.2016.11.28.720p.HDTV.x264-KYR]]></title>
|
||||||
|
<description>
|
||||||
|
<![CDATA[ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ<br />
|
||||||
|
ÛÛÛÛÛÛÛÛÛÛÛß°° ÜÜÜÜÜÜ Ü° ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ<br />
|
||||||
|
ÛÛÛÛÛÛÛßß°°Ü°ÛÛ²ßÜÛÛÜܲ Üß² ÞÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ<br />
|
||||||
|
ÛÛÛÛÛß Üß°²°²ÛÛÝÛÛÛ±²² ÜÝ Þ ÞÞÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ<br />
|
||||||
|
ÛÛÛÛ° ÛÛݲ޲ÛÛÛÞÛÛ±²ÝÝÞÛ ß ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ<br />
|
||||||
|
²ÛÛ°ÛÝÛÛÛݱÛÛÛ²ÛÛ°ÛÛÞ²Þ Ý ÞÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛßß ßßßÛÛÛÛÛÛÛÛÛÛ<br />
|
||||||
|
ÛÛ°ÛÛÞÛÛÛÛ²ÛÛÛÛÛ°Û²ÛÞ² ݲ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛß ßÛÛÛÛÛÛÛ<br />
|
||||||
|
Û°°ÛÛÛÛÛÛÛÛÛÛÛÛÝÝÛÛßݲ°ÞÞ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ² ²ÛÛÛÛÛ<br />
|
||||||
|
°ÛÝÛÛÞÛÛÛ²ÛÛÛÞÛÞÞÞÜÛÛ°²ÝÞ ÞÛÛÛÛÛÛÛÛÛÛÛÛÛÛ² ²ÛÛÛÛ<br />
|
||||||
|
Û²ÝÛÛÝÛÛÛÛÛÛÛÞ°Û²ÞÛÛÛ Þ ² ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ²ÛÛÛ<br />
|
||||||
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÝÝÛÛÝÛÝÛ ² Ý ÛÛÛÛÛÛÛÛÛÛÛÛÛÝ ÛÛÛ<br />
|
||||||
|
Û²ÛÛÛÝÛÛÛÛÛÝÛÝÛÞÛÛÞ²Þ ÝÝ ÜÜÜÜ ÛÛÛÛÛÛÛÛÛÛÛÛ ÜÜ Ü ÞÛÛ<br />
|
||||||
|
ÛÛÛÛÛÝÛÛÛÛÛÛÞÛÞÛÛ²Þ°Þ ²Ý ßßßÛÛÛ² ÞÛÛÛÛÛÛÛÛÛÛ² ÛÛ²²ÛÛ² ÞÛÛ<br />
|
||||||
|
ÛÛÛÛÛÛÞÛÛÛÝÛÞÛÝÛÛ±Þ ² ÝÞ ßÛÛÛÛÛÛ²Þ ÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ²± ÜÜ ß²ÛÛ<br />
|
||||||
|
²ÛÛÛÛÛÛÛÛÛ²ÞÝÛÝÛÛ°Û ² Þ ² ÜßÛÛÛß ÞÞÛÛÛÛÛÛÛÛÛÝÝ ÛÛß ÜÜÜß² ÛÛ<br />
|
||||||
|
ÛÛÛÛÝÛÛÛÛÛÛÛÝÛÞÞÛܲ Þ Ý Ý ßßß ßÛÛÛÛÛÛÛÛÛÝß ²ß ²ÞÝ ÞÛ<br />
|
||||||
|
²ÛÛÛÝÛÛÛÛÛÞÝÛ²ÞÛÝÛÝ Ý Ý Þ ßÛÛÛÛÛÛÛß Þ ÞÝ ÞÛ<br />
|
||||||
|
±ÛÛÛÛÞÛÛÛÛÞÞÛÝÛÛÝÞÛ ÝÞ ßÛÛÛÛÛ Ý ²ÛÜ ÛÛ<br />
|
||||||
|
²ÛÛÛÛ°ÛÛÛÛÝÛÛÛÞÛÛ°Û ß Þ Ý Ý ÛÛÛÛÛ ÜÛÛÜ Ý Üß ßÛÛ<br />
|
||||||
|
Û²ÛÛÝÝÝÛÛÛÞÛÛÛÛÛÞ²Þ Ý ²Ü²ÛÛ ÜÛÛÛÛÛÛßÛßßß ÜÜÜ²ß ÛÛ<br />
|
||||||
|
ÛÝÛÛÞݰÛÛÛÝÛÛÝÛÛÝÛ²Ý Ý ßßÜÛÛÛÛÛÛÛÛÛ ° ß²ß ² ÞÛ<br />
|
||||||
|
ÛÛ°ÛÞÛÞÞÛÛÛÞÛÛ°ÛÛ²ÞÛ Ý Ý ÜÜ ÞÞÛÛÛÛÛÛÛÛÜÛÜÜ ±°° ß Û<br />
|
||||||
|
ÛÛÛÞÝÛÞÝÛÛÛÝÛÛÛÞÛÛ ²Ý Þ Þ°²ÛÛÛÛ ÞÛÛÛÛÛÛÛÛß ±²±± Þ<br />
|
||||||
|
ÛÛÛÞÛÛÝÛÞÛÛݲÞÛÝÛÛÝÞÝ Ý ²ß ÜßݲÛÛÛÛÛÛÛÝÜ ÜܲÛÛÛ²² Þ<br />
|
||||||
|
ÛÛÝÞÛÛÛÛÛÛÛÝÛ°Û²ÞÝÛ°ÛÞ ÝÝ ÜܲÞÛÛÛÛÛÛÛÛÝÛ²Ü ÜÛÛÛÛÛÛÛÛ±<br />
|
||||||
|
ÛßÜÛÛÛÛÛÝÛÛÞÛÛÞÛ²ÞÝÝÛ ÝÝÝ ° ÝßÛ²ÝÞÛÛÛÛÛÛÛÛÛß ²ÛÛÛÛÛÛÛÛÛ<br />
|
||||||
|
Ûßßß ßܲÞÛÛÛÛÛÞÛÞÛÛ°ÛÛÛ ²²±±Þ ßÜÛÛÛÛÛÛÛÛÛÛ ²ÛÛÛÛÛÛÛÛÛÛ<br />
|
||||||
|
ÛÛÞÛÛÛÝÛÛÝÛÛÜßÛÞÛÛÛ²Ý²Ü ÛÛÛÛÛÛÛÛÛÝÞÜ ÜÜÛÛÛÛÛÛÛÛÛÛÛÛÝ Ü Þ<br />
|
||||||
|
ß²ÛÞ²ÛÛÛ ÛÛÞÛÛÛÞÞÛÛ²Û²Þ²Ý ÞÛÛÛÛÛÛÛÛÝÞÛÛ²ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛß ÞÛ<br />
|
||||||
|
ܲßÜÛÛÛÛÛÛÛÛÛÝÛÛÛÛÛÛÞ²ÛÜÛÛÛÛÛÛÛÛÛÛÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ² ÝÛ<br />
|
||||||
|
ß ÜÜßßÜÛÛÛÛÛÛÞÛÛÛÛÛÛÞÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÛßßÛÛÛÛÛÛÛÛÛÛÛÛÛ² Þ Û<br />
|
||||||
|
ß ßÛÛÜÜÝÛÛÛ²ÛÛÛÛÛÛÝÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜßÛÛÛÛÛÛÛ²ÜÜß ÝÞ²<br />
|
||||||
|
ßÝÛÛÞÛÛÛÞÛÝÛÛÛÞÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ²Ü ² Û²<br />
|
||||||
|
ÛÛÞÛÛÛÝÛÛÞÛÝÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÞÛÛÛÛÛß ² Þ²°<br />
|
||||||
|
ß ²ÞÛÛÛÞÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÝÛÛÛ² ² ÜÛ²<br />
|
||||||
|
ÞÛÛÝÛÛÛÛÛÛÞÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÝÛÛ ² ÜÛ²°<br />
|
||||||
|
Üß ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛßÝß Üß ÜÛ²°<br />
|
||||||
|
²ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛßܲ Üß ÜÛÛ²°<br />
|
||||||
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ Û² Ü²ß ÜÛÛ²±°<br />
|
||||||
|
²ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ Û² ÜÜßß ÜÛÛ²±°<br />
|
||||||
|
ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ Û² ÜÜßß ÜÜÛÛÛ²±°<br />
|
||||||
|
²ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ Û² ÜÜßß ÜÜÛÛÛÛ²²±°<br />
|
||||||
|
ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÝÛ²ÜÜßß ÜÜÛÛÛÛ²²²±°<br />
|
||||||
|
²ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ²ßßßÜÜÜÜÛÛÛÛ²²²±±°<br />
|
||||||
|
²ÛÛÛÛÛÛÛÛÛÛÛÛß²ÛÛÛÛÛÛÛÛ²²²±±°<br />
|
||||||
|
ßÛÛÛÛÛÛÛÛÛÛ °²ß²²²²±±°<br />
|
||||||
|
ßÛÛÛÛÛÛÛÛ °²<br />
|
||||||
|
²ÛÛÛÛÛÛÝ °±Ý<br />
|
||||||
|
ßÛÛÛÛÛܰ°±²<br />
|
||||||
|
²ÛÛ۲߲²ß<br />
|
||||||
|
Û²Û<br />
|
||||||
|
Þ²Ý<br />
|
||||||
|
±<br />
|
||||||
|
°<br />
|
||||||
|
<br />
|
||||||
|
ÜÜÜÜÜÜ ÜÜÜÜÜÜ ÜÜÜÜÜÜ<br />
|
||||||
|
ÜßßÛÛß ßÛ² ÜßßÛÛß ßÛ² ÜÜÛÛÛÛÛß ßÛ²<br />
|
||||||
|
ÛÛÛ°±ÛÝ ²ÛÜ ÛÛÛ°±ÛÝ ÜÛÛÛÛßßÛÛÛÛÛ°±ÛÝ<br />
|
||||||
|
ÞÛÛÛ²ÛÛ ÛÛÝ ÞÛÛÛ²ÛÝÛÛÛß ÞÛÛÛÛ²ÛÛ<br />
|
||||||
|
ÜÜ ÛÛÛÛÛÛ² ÞÛÛÝ ÞÛÛÛÛÛ ²ÛÝ ÛÛÛÛÛÛ²<br />
|
||||||
|
ÞÛÛ ²ÛÛÛÛÛÛ ÛÛÛ ÞÛÛÛÛ² ÞÛÛ ²ÛÛÛÛÛÛ<br />
|
||||||
|
ÛÛÝ ²ÛÛÛÛÛ² ÛÛÛ ÛÛÛÛÛÝ ÛÛÝ ²ÛÛÛÛÛ²<br />
|
||||||
|
ÞÛ² ÜÜÛÛÛÛÛÛÜÜÜ ÞÛÛÝ ²ÛÛÛÛÛ ÞÛ² ÜÜÛÛÛÛÛÛÜÜÜ ß<br />
|
||||||
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛßßÛÜ ²ÛÛÜÜÜÛÛÛÛÛÛÝ ÛÛÛÛÛÛÛÛÛÛÛÛÛßßÛÜ<br />
|
||||||
|
ÞÛÛÛßß ßÛÛÛ°ÞÛ ßÛÛÛÛÛÛÛÛÛ² ÞÛÛÛßß ßÛÛÛ°ÞÛ<br />
|
||||||
|
²Û² ÛÛÛÜÛÝ ÛÛÛÛÛÝ ²ÛÛ ÛÛÛÜÛÝ<br />
|
||||||
|
ÞÛÛÝ ÛÛÛÛÛ² ÞÛÛÛÛÛ ÞÛÛÝ ÛÛÛÛÛ²<br />
|
||||||
|
ÛÛÛ ÛßÛÛÛÛ ÛßÛÛÛÝ ÛÛÛ ÛßÛÛÛÛ<br />
|
||||||
|
ß Û°ÞÛÛÛÝ Û°ÞÛÛÛ ß Û°ÞÛÛÛÝ<br />
|
||||||
|
Û±°ÛÛÛ² Û±°ÛÛÛ² Û±°ÛÛÛ²<br />
|
||||||
|
Þ±±±°ÛÛ Þ±±±°ÛÛ Þ±±±°ÛÛ presents..<br />
|
||||||
|
Þ²±±±±Ý Þ²±±±±Ý Þ²±±±±Ý<br />
|
||||||
|
Û²²²ÛÜ Ü² Û²²²ÛÜ Ü² Û²²²ÛÜ Ü²<br />
|
||||||
|
ßßßßßßßßßßß ßßßßßßßßßßßßßßßßßß ßßßßßßßßßß<br />
|
||||||
|
k n o w y o u r r o l e<br />
|
||||||
|
<br />
|
||||||
|
ú úú--Ä-Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä-Ä--úú ú<br />
|
||||||
|
WWE.RAW.2016.11.28.720p.HDTV.h264-KYR<br />
|
||||||
|
ú úú--Ä-Ä-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä-Ä--úú ú<br />
|
||||||
|
ÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜ<br />
|
||||||
|
ÛßܰÛßÜ°Û Û²Ûßܰ۰ÜßÛ ÜÜÛßÜ°Û ÛÜÛßܰÛßÜÜÛ°ÜßÛ<br />
|
||||||
|
ÚÄÄÛ ßÜÛ ÜÛÛ Û²Û ÜÛÛ Ü ÛÜÜ°Û ÜÛßÄÄÛ Û Û Û ÜÛÛ Û ÛÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄúú ú<br />
|
||||||
|
³ Û Û ÛÜßßÛÜßßÛÜßßÛÜÛ ÛÜß ÛÜßßÛ Û ÛÜÛ Û°Û²Û ß Û<br />
|
||||||
|
³ ßßßßßßßßßßßßßßßßß ßßßßßßßßßßß ßßß ßßßßß ßßßßß<br />
|
||||||
|
³<br />
|
||||||
|
³ titleú[ WWE RAW ]ú<br />
|
||||||
|
³ genreú[ Wrestling ]ú crfú[ 23 ]ú<br />
|
||||||
|
³ rel. dateú[ 11.28.16 ]ú formatú[ x264 ]ú<br />
|
||||||
|
³ air dateú[ 11.28.16 ]ú sourceú[ HDTV ]ú<br />
|
||||||
|
³ runtimeú[ 2h 13m 48s ]ú bitrateú[ 4111kbps ]ú<br />
|
||||||
|
³ filesizeú[ 4.28 GB ]ú resolu.ú[ 1280x720 ]ú<br />
|
||||||
|
³ rar countú[ 93x50mb ]ú framesú[ 59.940 ]ú<br />
|
||||||
|
³ ú[ audioú[ 384 kbps AC3 5.1 ]ú<br />
|
||||||
|
³ ú[ locationú[ USA ]ú<br />
|
||||||
|
³ ú[ ]ú<br />
|
||||||
|
³ url ú[ http://www.wwe.com ]ú <br />
|
||||||
|
³<br />
|
||||||
|
³<br />
|
||||||
|
³ ÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ<br />
|
||||||
|
³ ÛßܰÛßÜ°Û Û²Ûßܰ۰ÜßÛ ÜÜÛßÜ°Û Ûßܰ۰ÜßÛÜ ÜÛßÜ°Û ÜÜÛ<br />
|
||||||
|
³ ú úúÄÄÄÄÄ-Û ßÜÛ ÜÛÛ Û²Û ÜÛÛ Ü ÛÜÜ°Û ÜÛßÄÄÛ Û Û Û ÛÛ ÛÛ ÜÛÛÜܰÛÄÄ´<br />
|
||||||
|
³ Û Û ÛÜßßÛÜßßÛÜßßÛÜÛ ÛÜß ÛÜßßÛ Û Û Û ß ÛÛ°ÛÛÜßßÛÜß Û ³<br />
|
||||||
|
³ ßßßßßßßßßßßßßßßßß ßßßßßßßßßßß ßßßßßßßßßßßß ßßßßßßßß ³<br />
|
||||||
|
³ ³<br />
|
||||||
|
³ ³<br />
|
||||||
|
³ Enjoy! ³<br />
|
||||||
|
³ ³<br />
|
||||||
|
³ ³<br />
|
||||||
|
³ ÜÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ³<br />
|
||||||
|
³ ÛßܰÛßܰ۰ÜßÛßÛ°ÛßÜ°Û ÛÜÛßܰÛßÜÜÛ°ÜßÛ ³<br />
|
||||||
|
ÃÄÄÛ ÝßÛ ßÜÛ Û Û Û Û ß ÛÄÄÛ°Û Û Û ÜÛÛ Û ÛÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-ÄÄÄÄÄúú ú ³<br />
|
||||||
|
Û ß Û Û Û ß Û ß Û Ûßß Û Û Û Û°Û²Û ß Û ³<br />
|
||||||
|
ßßßßßßßßßßßßßßßßßßß ßßßßßßßßß ßßßßß ³<br />
|
||||||
|
³<br />
|
||||||
|
group info ³<br />
|
||||||
|
³<br />
|
||||||
|
Know Your Role and Shut Your Mouth! ³<br />
|
||||||
|
³<br />
|
||||||
|
we are now looking for... ³<br />
|
||||||
|
³<br />
|
||||||
|
(a) capper(s) of cable, PPV, good upspeed advantageous ³<br />
|
||||||
|
.. contact in the usual way. ³<br />
|
||||||
|
³<br />
|
||||||
|
KYR respects... ³<br />
|
||||||
|
³<br />
|
||||||
|
everyone keeping it real and oldschool. we love ya! ³<br />
|
||||||
|
³<br />
|
||||||
|
Ü ÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ³<br />
|
||||||
|
ÜÜÜܲ ÜÜÜ Ûܲ ÜÜÜ ÜÜÜÜÜÜÜ ²Ý ³<br />
|
||||||
|
ú úúÄÄÄÄÄ--ÄÄÄÄÄÄÄÄÄÄÄÄÛ ÜÜ ÝÞÛÛÝÜÜ ÝÞÛÛÝßß ÞÛÛÝÞÛ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´<br />
|
||||||
|
Û ÛÛ ÜÛÛß ÛÛ ÜÛÛ² ÛÛ ÜÛÛß ÛÝ K N O W ³<br />
|
||||||
|
ascii crafted by Û ÛÛÛÛ²Ü ÞÛÛ²ß Ü ÛÛÛÛ²Ü ßÛ ³<br />
|
||||||
|
Û ÛÛ ßÛÛ² ÛÛ Ü²Û ÛÛ ßÛÛ² ²Ý Y O U R ³<br />
|
||||||
|
h8`!HiGHONASCii Û ÛÛ ÝÞÛÛÝ ÛÛ Û Û ÛÛ ÝÞÛÛÝÞÛ ³<br />
|
||||||
|
Û Û² Û ÛÛ² Û² Û Û Û² Û ÛÛ² Û R O L E ³<br />
|
||||||
|
ú úúÄ-Ä----ÄÄÄÄÄÄÄÄÄÄÄÄÛÜÜÜܲÜÜÜÜÜÜÜܲ ÛÜÜÜܲÜÜÜÜܲ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ<br />
|
||||||
|
ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ÜÜÜ ÜÜÜÜÜÜÜ<br />
|
||||||
|
°±²Û ÜßÛ ÜßÛ ÜßÛ ÜßÛ²²ÛßܰÛßÜ°Û Û²Ûßܰ۰ÜßÛ ÜÜÛßÜ°Û ÜÜÛ²²Û°ÜßÛßܰ۰ÜßÛ²±°<br />
|
||||||
|
° °±Û Û Û Û Û Û Û Û Û+±Û ßÜÛ ÜÛÛ Û±Û ÜÛÛ Ü ÛÜÜ°Û ÜÛÛÜܰ۱±Û Ü Û Û Û Û Û±° °<br />
|
||||||
|
°±²ÛÜß°ÛÜß°ÛÜß°ÛÜß°Û²²Û Û ÛÜßßÛÜßßÛÜßßÛÜÛ ÛÜß ÛÜßßÛÜß Û²²ÛÜÛ ÛÜÛ Û ßÜÛ²±°<br />
|
||||||
|
ßßßßßßßßßßßßßßßßß ßßßßßßßßßßßßßßßßß ßßßßßßßßßßßßßßß ßßß ßßßßßß<br />
|
||||||
|
ÜÜÜÜÜÜÜ ÜÜ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ<br />
|
||||||
|
°±²²ÛßÜ Û°ÜßÛßÛ°ÛßܰÛÜ ÜÛÜÛßܰÛßܰ۰۰۰۲²±°<br />
|
||||||
|
° °±±Û ÛÛÛ Û Û Û Û Û ÛÛ ÛÛ°Û Û Û ÝßÛ Û Û Û±±° °<br />
|
||||||
|
°±²²ÛÜß°Û ß Û ß ÛÜÛ ÛÛ°ÛÛ Û Û Û°ß ÛßÛßÛßÛ²²±°<br />
|
||||||
|
ßßßßßßßßßßßß ßßßßßßßßßßßßßßßßßßßßßß]]>
|
||||||
|
</description>
|
||||||
|
<pubDate>Tue, 29 Nov 2016 05:08:18 +0000</pubDate>
|
||||||
|
<link>https://alpharatio.cc/torrents.php?action=download&authkey=private_auth_key&torrent_pass=private_torrent_pass&id=465831</link>
|
||||||
|
<guid>https://alpharatio.cc/torrents.php?action=download&authkey=private_auth_key&torrent_pass=private_torrent_pass&id=465831</guid>
|
||||||
|
<comments>https://alpharatio.cc/torrents.php?id=465860</comments>
|
||||||
|
<dc:creator>Anonymous</dc:creator>
|
||||||
|
</item>
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
|
|
||||||
"result": "failure",
|
|
||||||
"data": [ ],
|
|
||||||
"message": "no show with the tvdb_id 79488 found"
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
|
|
||||||
"result": "success",
|
|
||||||
"data": [
|
|
||||||
"73141",
|
|
||||||
"79886",
|
|
||||||
],
|
|
||||||
"message": ""
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
|
|
||||||
"result": "success",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"scene": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"absolute": 1
|
|
||||||
},
|
|
||||||
"tvdb": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 1,
|
|
||||||
"absolute": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"scene": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 2,
|
|
||||||
"absolute": 2
|
|
||||||
},
|
|
||||||
"tvdb": {
|
|
||||||
"season": 1,
|
|
||||||
"episode": 2,
|
|
||||||
"absolute": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"message": "full mapping for 73388 on tvdb. this was a cached version"
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
|
|
||||||
"result": "success",
|
|
||||||
"data": {
|
|
||||||
"220571": [
|
|
||||||
"Is This a Zombie? Of the Dead",
|
|
||||||
"Kore wa Zombie Desuka?",
|
|
||||||
"Kore wa Zombie Desuka? Of the Dead",
|
|
||||||
"Kore wa Zombie Desuka Of the Dead",
|
|
||||||
"Kore wa Zombie Desu ka - Of the Dead",
|
|
||||||
"Kore wa Zombie Desu ka of the Dead"
|
|
||||||
],
|
|
||||||
"79151": [
|
|
||||||
"Fate Stay Night",
|
|
||||||
"Fate/Zero",
|
|
||||||
"Fate Zero",
|
|
||||||
"Fate/Zero (2012)",
|
|
||||||
"Fate Zero S2",
|
|
||||||
"Fate Zero"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"message": ""
|
|
||||||
|
|
||||||
}
|
|
||||||
+13
-2
@@ -1,4 +1,5 @@
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.HealthCheck;
|
using NzbDrone.Core.HealthCheck;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.HealthCheck.Checks
|
namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||||
@@ -10,14 +11,24 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
result.Type.Should().Be(HealthCheckResult.Ok);
|
result.Type.Should().Be(HealthCheckResult.Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShouldBeWarning(this Core.HealthCheck.HealthCheck result)
|
public static void ShouldBeWarning(this Core.HealthCheck.HealthCheck result, string message = null)
|
||||||
{
|
{
|
||||||
result.Type.Should().Be(HealthCheckResult.Warning);
|
result.Type.Should().Be(HealthCheckResult.Warning);
|
||||||
|
|
||||||
|
if (message.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
result.Message.Should().Contain(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShouldBeError(this Core.HealthCheck.HealthCheck result)
|
public static void ShouldBeError(this Core.HealthCheck.HealthCheck result, string message = null)
|
||||||
{
|
{
|
||||||
result.Type.Should().Be(HealthCheckResult.Error);
|
result.Type.Should().Be(HealthCheckResult.Error);
|
||||||
|
|
||||||
|
if (message.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
result.Message.Should().Contain(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.HealthCheck.Checks;
|
||||||
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class IndexerRssCheckFixture : CoreTest<IndexerRssCheck>
|
||||||
|
{
|
||||||
|
private Mock<IIndexer> _indexerMock;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.GetAvailableProviders())
|
||||||
|
.Returns(new List<IIndexer>());
|
||||||
|
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.RssEnabled(It.IsAny<bool>()))
|
||||||
|
.Returns(new List<IIndexer>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenIndexer(bool supportsRss, bool supportsSearch)
|
||||||
|
{
|
||||||
|
_indexerMock = Mocker.GetMock<IIndexer>();
|
||||||
|
_indexerMock.SetupGet(s => s.SupportsRss).Returns(supportsRss);
|
||||||
|
_indexerMock.SetupGet(s => s.SupportsSearch).Returns(supportsSearch);
|
||||||
|
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.GetAvailableProviders())
|
||||||
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenRssEnabled()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.RssEnabled(It.IsAny<bool>()))
|
||||||
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenRssFiltered()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.RssEnabled(false))
|
||||||
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_error_when_no_indexer_present()
|
||||||
|
{
|
||||||
|
Subject.Check().ShouldBeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_error_when_no_rss_supported_indexer_present()
|
||||||
|
{
|
||||||
|
GivenIndexer(false, true);
|
||||||
|
|
||||||
|
Subject.Check().ShouldBeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_ok_when_rss_is_enabled()
|
||||||
|
{
|
||||||
|
GivenIndexer(true, false);
|
||||||
|
GivenRssEnabled();
|
||||||
|
|
||||||
|
Subject.Check().ShouldBeOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_error_if_rss_is_supported_but_disabled()
|
||||||
|
{
|
||||||
|
GivenIndexer(true, false);
|
||||||
|
|
||||||
|
Subject.Check().ShouldBeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_filter_warning_if_rss_is_enabled_but_filtered()
|
||||||
|
{
|
||||||
|
GivenIndexer(true, false);
|
||||||
|
GivenRssFiltered();
|
||||||
|
|
||||||
|
Subject.Check().ShouldBeWarning("recent indexer errors");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
-69
@@ -8,10 +8,22 @@ using NzbDrone.Core.Test.Framework;
|
|||||||
namespace NzbDrone.Core.Test.HealthCheck.Checks
|
namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class IndexerCheckFixture : CoreTest<IndexerCheck>
|
public class IndexerSearchCheckFixture : CoreTest<IndexerSearchCheck>
|
||||||
{
|
{
|
||||||
private Mock<IIndexer> _indexerMock;
|
private Mock<IIndexer> _indexerMock;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.GetAvailableProviders())
|
||||||
|
.Returns(new List<IIndexer>());
|
||||||
|
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.SearchEnabled(It.IsAny<bool>()))
|
||||||
|
.Returns(new List<IIndexer>());
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenIndexer(bool supportsRss, bool supportsSearch)
|
private void GivenIndexer(bool supportsRss, bool supportsSearch)
|
||||||
{
|
{
|
||||||
_indexerMock = Mocker.GetMock<IIndexer>();
|
_indexerMock = Mocker.GetMock<IIndexer>();
|
||||||
@@ -21,42 +33,30 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
Mocker.GetMock<IIndexerFactory>()
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
.Setup(s => s.GetAvailableProviders())
|
.Setup(s => s.GetAvailableProviders())
|
||||||
.Returns(new List<IIndexer> { _indexerMock.Object });
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
|
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
|
||||||
.Setup(s => s.RssEnabled())
|
|
||||||
.Returns(new List<IIndexer>());
|
|
||||||
|
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
|
||||||
.Setup(s => s.SearchEnabled())
|
|
||||||
.Returns(new List<IIndexer>());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenRssEnabled()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
|
||||||
.Setup(s => s.RssEnabled())
|
|
||||||
.Returns(new List<IIndexer> { _indexerMock.Object });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenSearchEnabled()
|
private void GivenSearchEnabled()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
.Setup(s => s.SearchEnabled())
|
.Setup(s => s.SearchEnabled(It.IsAny<bool>()))
|
||||||
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenSearchFiltered()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
|
.Setup(s => s.SearchEnabled(false))
|
||||||
.Returns(new List<IIndexer> { _indexerMock.Object });
|
.Returns(new List<IIndexer> { _indexerMock.Object });
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_error_when_not_indexers_are_enabled()
|
public void should_return_warning_when_no_indexer_present()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
Subject.Check().ShouldBeWarning();
|
||||||
.Setup(s => s.GetAvailableProviders())
|
|
||||||
.Returns(new List<IIndexer>());
|
|
||||||
|
|
||||||
Subject.Check().ShouldBeError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_warning_when_only_enabled_indexer_doesnt_support_search()
|
public void should_return_warning_when_no_search_supported_indexer_present()
|
||||||
{
|
{
|
||||||
GivenIndexer(true, false);
|
GivenIndexer(true, false);
|
||||||
|
|
||||||
@@ -64,7 +64,16 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_warning_when_only_enabled_indexer_doesnt_support_rss()
|
public void should_return_ok_when_search_is_enabled()
|
||||||
|
{
|
||||||
|
GivenIndexer(false, true);
|
||||||
|
GivenSearchEnabled();
|
||||||
|
|
||||||
|
Subject.Check().ShouldBeOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_warning_if_search_is_supported_but_disabled()
|
||||||
{
|
{
|
||||||
GivenIndexer(false, true);
|
GivenIndexer(false, true);
|
||||||
|
|
||||||
@@ -72,52 +81,12 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_ok_when_multiple_indexers_are_enabled()
|
public void should_return_filter_warning_if_search_is_enabled_but_filtered()
|
||||||
{
|
{
|
||||||
GivenRssEnabled();
|
GivenIndexer(false, true);
|
||||||
GivenSearchEnabled();
|
GivenSearchFiltered();
|
||||||
|
|
||||||
var indexer1 = Mocker.GetMock<IIndexer>();
|
Subject.Check().ShouldBeWarning("recent indexer errors");
|
||||||
indexer1.SetupGet(s => s.SupportsRss).Returns(true);
|
|
||||||
indexer1.SetupGet(s => s.SupportsSearch).Returns(true);
|
|
||||||
|
|
||||||
var indexer2 = new Moq.Mock<IIndexer>();
|
|
||||||
indexer2.SetupGet(s => s.SupportsRss).Returns(true);
|
|
||||||
indexer2.SetupGet(s => s.SupportsSearch).Returns(false);
|
|
||||||
|
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
|
||||||
.Setup(s => s.GetAvailableProviders())
|
|
||||||
.Returns(new List<IIndexer> { indexer1.Object, indexer2.Object });
|
|
||||||
|
|
||||||
Subject.Check().ShouldBeOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_ok_when_indexer_supports_rss_and_search()
|
|
||||||
{
|
|
||||||
GivenIndexer(true, true);
|
|
||||||
GivenRssEnabled();
|
|
||||||
GivenSearchEnabled();
|
|
||||||
|
|
||||||
Subject.Check().ShouldBeOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_warning_if_rss_is_supported_but_disabled()
|
|
||||||
{
|
|
||||||
GivenIndexer(true, true);
|
|
||||||
GivenSearchEnabled();
|
|
||||||
|
|
||||||
Subject.Check().ShouldBeWarning();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_warning_if_search_is_supported_but_disabled()
|
|
||||||
{
|
|
||||||
GivenIndexer(true, true);
|
|
||||||
GivenRssEnabled();
|
|
||||||
|
|
||||||
Subject.Check().ShouldBeWarning();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
|||||||
_mockIndexer.SetupGet(s => s.SupportsSearch).Returns(true);
|
_mockIndexer.SetupGet(s => s.SupportsSearch).Returns(true);
|
||||||
|
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
.Setup(s => s.SearchEnabled())
|
.Setup(s => s.SearchEnabled(true))
|
||||||
.Returns(new List<IIndexer> { _mockIndexer.Object });
|
.Returns(new List<IIndexer> { _mockIndexer.Object });
|
||||||
|
|
||||||
Mocker.GetMock<IMakeDownloadDecision>()
|
Mocker.GetMock<IMakeDownloadDecision>()
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using NUnit.Framework;
|
|||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Indexers.Newznab;
|
using NzbDrone.Core.Indexers.Newznab;
|
||||||
using NzbDrone.Core.Indexers.Omgwtfnzbs;
|
using NzbDrone.Core.Indexers.Omgwtfnzbs;
|
||||||
using NzbDrone.Core.Indexers.Wombles;
|
|
||||||
using NzbDrone.Core.Lifecycle;
|
using NzbDrone.Core.Lifecycle;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
@@ -22,7 +21,6 @@ namespace NzbDrone.Core.Test.IndexerTests
|
|||||||
|
|
||||||
_indexers.Add(Mocker.Resolve<Newznab>());
|
_indexers.Add(Mocker.Resolve<Newznab>());
|
||||||
_indexers.Add(Mocker.Resolve<Omgwtfnzbs>());
|
_indexers.Add(Mocker.Resolve<Omgwtfnzbs>());
|
||||||
_indexers.Add(Mocker.Resolve<Wombles>());
|
|
||||||
|
|
||||||
Mocker.SetConstant<IEnumerable<IIndexer>>(_indexers);
|
Mocker.SetConstant<IEnumerable<IIndexer>>(_indexers);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ using FluentAssertions;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Indexers.KickassTorrents;
|
|
||||||
using NzbDrone.Core.Indexers.Nyaa;
|
using NzbDrone.Core.Indexers.Nyaa;
|
||||||
using NzbDrone.Core.Indexers.Wombles;
|
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
@@ -40,58 +38,6 @@ namespace NzbDrone.Core.Test.IndexerTests.IntegrationTests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void wombles_fetch_recent()
|
|
||||||
{
|
|
||||||
var indexer = Mocker.Resolve<Wombles>();
|
|
||||||
|
|
||||||
indexer.Definition = new IndexerDefinition
|
|
||||||
{
|
|
||||||
Name = "MyIndexer",
|
|
||||||
Settings = NullConfig.Instance
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = indexer.FetchRecent();
|
|
||||||
|
|
||||||
ValidateResult(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
[ManualTest]
|
|
||||||
[Explicit]
|
|
||||||
public void kickass_fetch_recent()
|
|
||||||
{
|
|
||||||
var indexer = Mocker.Resolve<KickassTorrents>();
|
|
||||||
|
|
||||||
indexer.Definition = new IndexerDefinition
|
|
||||||
{
|
|
||||||
Name = "MyIndexer",
|
|
||||||
Settings = new KickassTorrentsSettings()
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = indexer.FetchRecent();
|
|
||||||
|
|
||||||
ValidateTorrentResult(result, hasSize: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
[ManualTest]
|
|
||||||
[Explicit]
|
|
||||||
public void kickass_search_single()
|
|
||||||
{
|
|
||||||
var indexer = Mocker.Resolve<KickassTorrents>();
|
|
||||||
|
|
||||||
indexer.Definition = new IndexerDefinition
|
|
||||||
{
|
|
||||||
Name = "MyIndexer",
|
|
||||||
Settings = new KickassTorrentsSettings()
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = indexer.Fetch(_singleSearchCriteria);
|
|
||||||
|
|
||||||
ValidateTorrentResult(result, hasSize: true, hasMagnet: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void nyaa_fetch_recent()
|
public void nyaa_fetch_recent()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,173 +0,0 @@
|
|||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
using NzbDrone.Core.Indexers.KickassTorrents;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Test.Common;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using FluentAssertions;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.IndexerTests.KickassTorrentsTests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class KickassTorrentsFixture : CoreTest<KickassTorrents>
|
|
||||||
{
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
Subject.Definition = new IndexerDefinition()
|
|
||||||
{
|
|
||||||
Name = "Kickass Torrents",
|
|
||||||
Settings = new KickassTorrentsSettings() { VerifiedOnly = false }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_parse_recent_feed_from_KickassTorrents()
|
|
||||||
{
|
|
||||||
var recentFeed = ReadAllText(@"Files/Indexers/KickassTorrents/KickassTorrents.xml");
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
|
||||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
|
||||||
|
|
||||||
releases.Should().HaveCount(5);
|
|
||||||
releases.First().Should().BeOfType<TorrentInfo>();
|
|
||||||
|
|
||||||
var torrentInfo = (TorrentInfo) releases.First();
|
|
||||||
|
|
||||||
torrentInfo.Title.Should().Be("Doctor Stranger.E03.140512.HDTV.H264.720p-iPOP.avi [CTRG]");
|
|
||||||
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
|
||||||
torrentInfo.DownloadUrl.Should().Be("http://torcache.net/torrent/208C4F7866612CC88BFEBC7C496FA72C2368D1C0.torrent?title=%5Bkickass.to%5Ddoctor.stranger.e03.140512.hdtv.h264.720p.ipop.avi.ctrg");
|
|
||||||
torrentInfo.InfoUrl.Should().Be("http://kickass.to/doctor-stranger-e03-140512-hdtv-h264-720p-ipop-avi-ctrg-t9100648.html");
|
|
||||||
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
|
|
||||||
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
|
|
||||||
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2014/05/12 16:16:49"));
|
|
||||||
torrentInfo.Size.Should().Be(1205364736);
|
|
||||||
torrentInfo.InfoHash.Should().Be("208C4F7866612CC88BFEBC7C496FA72C2368D1C0");
|
|
||||||
torrentInfo.MagnetUrl.Should().Be("magnet:?xt=urn:btih:208C4F7866612CC88BFEBC7C496FA72C2368D1C0&dn=doctor+stranger+e03+140512+hdtv+h264+720p+ipop+avi+ctrg&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_empty_list_on_404()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
|
||||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), new byte[0], System.Net.HttpStatusCode.NotFound));
|
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
|
||||||
|
|
||||||
releases.Should().HaveCount(0);
|
|
||||||
|
|
||||||
ExceptionVerification.IgnoreWarns();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_return_unverified_releases_if_not_configured()
|
|
||||||
{
|
|
||||||
((KickassTorrentsSettings) Subject.Definition.Settings).VerifiedOnly = true;
|
|
||||||
|
|
||||||
var recentFeed = ReadAllText(@"Files/Indexers/KickassTorrents/KickassTorrents.xml");
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
|
||||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
|
||||||
|
|
||||||
releases.Should().HaveCount(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_set_seeders_to_null()
|
|
||||||
{
|
|
||||||
// Atm, Kickass supplies 0 as seeders and leechers on the rss feed (but not the site), so set it to null if there aren't any peers.
|
|
||||||
var recentFeed = ReadAllText(@"Files/Indexers/KickassTorrents/KickassTorrents.xml");
|
|
||||||
|
|
||||||
recentFeed = recentFeed.Replace("<pubDate>Mon, 12 May 2014 16:16:49 +0000</pubDate>", string.Format("<pubDate>{0:R}</pubDate>", DateTime.UtcNow));
|
|
||||||
recentFeed = Regex.Replace(recentFeed, @"(seeds|peers)\>\d*", "$1>0");
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
|
||||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
|
||||||
|
|
||||||
releases.Should().HaveCount(5);
|
|
||||||
releases.First().Should().BeOfType<TorrentInfo>();
|
|
||||||
|
|
||||||
var torrentInfo = (TorrentInfo)releases.First();
|
|
||||||
|
|
||||||
torrentInfo.Peers.Should().NotHaveValue();
|
|
||||||
torrentInfo.Seeders.Should().NotHaveValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_set_seeders_to_null_if_has_peers()
|
|
||||||
{
|
|
||||||
// Atm, Kickass supplies 0 as seeders and leechers on the rss feed (but not the site), so set it to null if there aren't any peers.
|
|
||||||
var recentFeed = ReadAllText(@"Files/Indexers/KickassTorrents/KickassTorrents.xml");
|
|
||||||
|
|
||||||
recentFeed = recentFeed.Replace("<pubDate>Mon, 12 May 2014 16:16:49 +0000</pubDate>", string.Format("<pubDate>{0:R}</pubDate>", DateTime.UtcNow));
|
|
||||||
recentFeed = Regex.Replace(recentFeed, @"(seeds)\>\d*", "$1>0");
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
|
||||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
|
||||||
|
|
||||||
releases.Should().HaveCount(5);
|
|
||||||
releases.First().Should().BeOfType<TorrentInfo>();
|
|
||||||
|
|
||||||
var torrentInfo = (TorrentInfo)releases.First();
|
|
||||||
|
|
||||||
torrentInfo.Peers.Should().Be(311);
|
|
||||||
torrentInfo.Seeders.Should().Be(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_set_seeders_to_null_if_older_than_12_hours()
|
|
||||||
{
|
|
||||||
// Atm, Kickass supplies 0 as seeders and leechers on the rss feed (but not the site), so set it to null if there aren't any peers.
|
|
||||||
var recentFeed = ReadAllText(@"Files/Indexers/KickassTorrents/KickassTorrents.xml");
|
|
||||||
|
|
||||||
recentFeed = Regex.Replace(recentFeed, @"(seeds|peers)\>\d*", "$1>0");
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
|
||||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
|
||||||
|
|
||||||
releases.Should().HaveCount(5);
|
|
||||||
releases.First().Should().BeOfType<TorrentInfo>();
|
|
||||||
|
|
||||||
var torrentInfo = (TorrentInfo)releases.First();
|
|
||||||
|
|
||||||
torrentInfo.Peers.Should().Be(0);
|
|
||||||
torrentInfo.Seeders.Should().Be(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_handle_xml_with_html_accents()
|
|
||||||
{
|
|
||||||
var recentFeed = ReadAllText(@"Files/Indexers/KickassTorrents/KickassTorrents_accents.xml");
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
|
||||||
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
|
||||||
|
|
||||||
releases.Should().HaveCount(5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+17
@@ -215,5 +215,22 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
|||||||
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||||
torrentInfo.DownloadUrl.Should().Be("http://storage.animetosho.org/torrents/4b58360143d59a55cbd922397a3eaa378165f3ff/DAYS%20-%2005%20%281280x720%20HEVC2%20AAC%29.torrent");
|
torrentInfo.DownloadUrl.Should().Be("http://storage.animetosho.org/torrents/4b58360143d59a55cbd922397a3eaa378165f3ff/DAYS%20-%2005%20%281280x720%20HEVC2%20AAC%29.torrent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_parse_recent_feed_from_AlphaRatio()
|
||||||
|
{
|
||||||
|
GivenRecentFeedResponse("TorrentRss/AlphaRatio.xml");
|
||||||
|
|
||||||
|
var releases = Subject.FetchRecent();
|
||||||
|
|
||||||
|
releases.Should().HaveCount(2);
|
||||||
|
releases.Last().Should().BeOfType<TorrentInfo>();
|
||||||
|
|
||||||
|
var torrentInfo = releases.Last() as TorrentInfo;
|
||||||
|
|
||||||
|
torrentInfo.Title.Should().Be("TvHD 465860 465831 WWE.RAW.2016.11.28.720p.HDTV.x264-KYR");
|
||||||
|
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||||
|
torrentInfo.DownloadUrl.Should().Be("https://alpharatio.cc/torrents.php?action=download&authkey=private_auth_key&torrent_pass=private_torrent_pass&id=465831");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
@@ -180,6 +180,26 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_detect_rss_settings_for_AlphaRatio()
|
||||||
|
{
|
||||||
|
_indexerSettings.AllowZeroSize = true;
|
||||||
|
|
||||||
|
GivenRecentFeedResponse("TorrentRss/AlphaRatio.xml");
|
||||||
|
|
||||||
|
var settings = Subject.Detect(_indexerSettings);
|
||||||
|
|
||||||
|
settings.ShouldBeEquivalentTo(new TorrentRssIndexerParserSettings
|
||||||
|
{
|
||||||
|
UseEZTVFormat = false,
|
||||||
|
UseEnclosureUrl = false,
|
||||||
|
UseEnclosureLength = false,
|
||||||
|
ParseSizeInDescription = true,
|
||||||
|
ParseSeedersInDescription = false,
|
||||||
|
SizeElementName = null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
[Ignore("Cannot reliably reject unparseable titles")]
|
[Ignore("Cannot reliably reject unparseable titles")]
|
||||||
public void should_reject_rss_settings_for_AwesomeHD()
|
public void should_reject_rss_settings_for_AwesomeHD()
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using FluentAssertions;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Core.Indexers;
|
|
||||||
using NzbDrone.Core.Indexers.Wombles;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Core.ThingiProvider;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.IndexerTests.WomblesTests
|
|
||||||
{
|
|
||||||
|
|
||||||
[TestFixture]
|
|
||||||
public class TorrentRssIndexerFixture : CoreTest<Wombles>
|
|
||||||
{
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
|
|
||||||
Subject.Definition = new IndexerDefinition()
|
|
||||||
{
|
|
||||||
Name = "Wombles",
|
|
||||||
Settings = new NullConfig(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenRecentFeedResponse(string rssXmlFile)
|
|
||||||
{
|
|
||||||
var recentFeed = ReadAllText(@"Files/Indexers/" + rssXmlFile);
|
|
||||||
|
|
||||||
Mocker.GetMock<IHttpClient>()
|
|
||||||
.Setup(o => o.Execute(It.IsAny<HttpRequest>()))
|
|
||||||
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(), recentFeed));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_parse_recent_feed_from_wombles()
|
|
||||||
{
|
|
||||||
GivenRecentFeedResponse("Wombles/wombles.xml");
|
|
||||||
|
|
||||||
var releases = Subject.FetchRecent();
|
|
||||||
|
|
||||||
releases.Should().HaveCount(5);
|
|
||||||
|
|
||||||
var releaseInfo = releases.First();
|
|
||||||
|
|
||||||
releaseInfo.Title.Should().Be("One.Child.S01E01.720p.HDTV.x264-TLA");
|
|
||||||
releaseInfo.DownloadProtocol.Should().Be(DownloadProtocol.Usenet);
|
|
||||||
releaseInfo.DownloadUrl.Should().Be("http://indexer.local/nzb/bb4/One.Child.S01E01.720p.HDTV.x264-TLA.nzb");
|
|
||||||
releaseInfo.InfoUrl.Should().BeNullOrEmpty();
|
|
||||||
releaseInfo.CommentUrl.Should().BeNullOrEmpty();
|
|
||||||
releaseInfo.Indexer.Should().Be(Subject.Definition.Name);
|
|
||||||
releaseInfo.PublishDate.Should().Be(DateTime.Parse("2016-02-17 23:03:52 +0000").ToUniversalTime());
|
|
||||||
releaseInfo.Size.Should().Be(956*1024*1024);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,12 +16,12 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class UpdateMediaInfoServiceFixture : CoreTest<UpdateMediaInfoService>
|
public class UpdateMediaInfoServiceFixture : CoreTest<UpdateMediaInfoService>
|
||||||
{
|
{
|
||||||
private Series _series;
|
private Movie _series;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_series = new Series
|
_series = new Movie
|
||||||
{
|
{
|
||||||
Id = 1,
|
Id = 1,
|
||||||
Path = @"C:\series".AsOsAgnostic()
|
Path = @"C:\series".AsOsAgnostic()
|
||||||
@@ -56,7 +56,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
|||||||
[Test]
|
[Test]
|
||||||
public void should_skip_up_to_date_media_info()
|
public void should_skip_up_to_date_media_info()
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(3)
|
var episodeFiles = Builder<MovieFile>.CreateListOfSize(3)
|
||||||
.All()
|
.All()
|
||||||
.With(v => v.RelativePath = "media.mkv")
|
.With(v => v.RelativePath = "media.mkv")
|
||||||
.TheFirst(1)
|
.TheFirst(1)
|
||||||
@@ -64,25 +64,25 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
|||||||
.BuildList();
|
.BuildList();
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Setup(v => v.GetFilesBySeries(1))
|
.Setup(v => v.GetFilesByMovie(1))
|
||||||
.Returns(episodeFiles);
|
.Returns(episodeFiles);
|
||||||
|
|
||||||
GivenFileExists();
|
GivenFileExists();
|
||||||
GivenSuccessfulScan();
|
GivenSuccessfulScan();
|
||||||
|
|
||||||
Subject.Handle(new SeriesScannedEvent(_series));
|
Subject.Handle(new MovieScannedEvent(_series));
|
||||||
|
|
||||||
Mocker.GetMock<IVideoFileInfoReader>()
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
.Verify(v => v.GetMediaInfo(Path.Combine(_series.Path, "media.mkv")), Times.Exactly(2));
|
.Verify(v => v.GetMediaInfo(Path.Combine(_series.Path, "media.mkv")), Times.Exactly(2));
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(2));
|
.Verify(v => v.Update(It.IsAny<MovieFile>()), Times.Exactly(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_update_outdated_media_info()
|
public void should_update_outdated_media_info()
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(3)
|
var episodeFiles = Builder<MovieFile>.CreateListOfSize(3)
|
||||||
.All()
|
.All()
|
||||||
.With(v => v.RelativePath = "media.mkv")
|
.With(v => v.RelativePath = "media.mkv")
|
||||||
.TheFirst(1)
|
.TheFirst(1)
|
||||||
@@ -90,48 +90,48 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
|||||||
.BuildList();
|
.BuildList();
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Setup(v => v.GetFilesBySeries(1))
|
.Setup(v => v.GetFilesByMovie(1))
|
||||||
.Returns(episodeFiles);
|
.Returns(episodeFiles);
|
||||||
|
|
||||||
GivenFileExists();
|
GivenFileExists();
|
||||||
GivenSuccessfulScan();
|
GivenSuccessfulScan();
|
||||||
|
|
||||||
Subject.Handle(new SeriesScannedEvent(_series));
|
Subject.Handle(new MovieScannedEvent(_series));
|
||||||
|
|
||||||
Mocker.GetMock<IVideoFileInfoReader>()
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
.Verify(v => v.GetMediaInfo(Path.Combine(_series.Path, "media.mkv")), Times.Exactly(3));
|
.Verify(v => v.GetMediaInfo(Path.Combine(_series.Path, "media.mkv")), Times.Exactly(3));
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(3));
|
.Verify(v => v.Update(It.IsAny<MovieFile>()), Times.Exactly(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_ignore_missing_files()
|
public void should_ignore_missing_files()
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
var episodeFiles = Builder<MovieFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(v => v.RelativePath = "media.mkv")
|
.With(v => v.RelativePath = "media.mkv")
|
||||||
.BuildList();
|
.BuildList();
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Setup(v => v.GetFilesBySeries(1))
|
.Setup(v => v.GetFilesByMovie(1))
|
||||||
.Returns(episodeFiles);
|
.Returns(episodeFiles);
|
||||||
|
|
||||||
GivenSuccessfulScan();
|
GivenSuccessfulScan();
|
||||||
|
|
||||||
Subject.Handle(new SeriesScannedEvent(_series));
|
Subject.Handle(new MovieScannedEvent(_series));
|
||||||
|
|
||||||
Mocker.GetMock<IVideoFileInfoReader>()
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
.Verify(v => v.GetMediaInfo("media.mkv"), Times.Never());
|
.Verify(v => v.GetMediaInfo("media.mkv"), Times.Never());
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Never());
|
.Verify(v => v.Update(It.IsAny<MovieFile>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_continue_after_failure()
|
public void should_continue_after_failure()
|
||||||
{
|
{
|
||||||
var episodeFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
var episodeFiles = Builder<MovieFile>.CreateListOfSize(2)
|
||||||
.All()
|
.All()
|
||||||
.With(v => v.RelativePath = "media.mkv")
|
.With(v => v.RelativePath = "media.mkv")
|
||||||
.TheFirst(1)
|
.TheFirst(1)
|
||||||
@@ -139,20 +139,20 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
|
|||||||
.BuildList();
|
.BuildList();
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Setup(v => v.GetFilesBySeries(1))
|
.Setup(v => v.GetFilesByMovie(1))
|
||||||
.Returns(episodeFiles);
|
.Returns(episodeFiles);
|
||||||
|
|
||||||
GivenFileExists();
|
GivenFileExists();
|
||||||
GivenSuccessfulScan();
|
GivenSuccessfulScan();
|
||||||
GivenFailedScan(Path.Combine(_series.Path, "media2.mkv"));
|
GivenFailedScan(Path.Combine(_series.Path, "media2.mkv"));
|
||||||
|
|
||||||
Subject.Handle(new SeriesScannedEvent(_series));
|
Subject.Handle(new MovieScannedEvent(_series));
|
||||||
|
|
||||||
Mocker.GetMock<IVideoFileInfoReader>()
|
Mocker.GetMock<IVideoFileInfoReader>()
|
||||||
.Verify(v => v.GetMediaInfo(Path.Combine(_series.Path, "media.mkv")), Times.Exactly(1));
|
.Verify(v => v.GetMediaInfo(Path.Combine(_series.Path, "media.mkv")), Times.Exactly(1));
|
||||||
|
|
||||||
Mocker.GetMock<IMediaFileService>()
|
Mocker.GetMock<IMediaFileService>()
|
||||||
.Verify(v => v.Update(It.IsAny<EpisodeFile>()), Times.Exactly(1));
|
.Verify(v => v.Update(It.IsAny<MovieFile>()), Times.Exactly(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,6 @@
|
|||||||
<Compile Include="Blacklisting\BlacklistServiceFixture.cs" />
|
<Compile Include="Blacklisting\BlacklistServiceFixture.cs" />
|
||||||
<Compile Include="Configuration\ConfigCachingFixture.cs" />
|
<Compile Include="Configuration\ConfigCachingFixture.cs" />
|
||||||
<Compile Include="Configuration\ConfigServiceFixture.cs" />
|
<Compile Include="Configuration\ConfigServiceFixture.cs" />
|
||||||
<Compile Include="DataAugmentation\SceneNumbering\XemServiceFixture.cs" />
|
|
||||||
<Compile Include="DataAugmentation\Scene\SceneMappingProxyFixture.cs" />
|
<Compile Include="DataAugmentation\Scene\SceneMappingProxyFixture.cs" />
|
||||||
<Compile Include="DataAugmentation\Scene\SceneMappingServiceFixture.cs" />
|
<Compile Include="DataAugmentation\Scene\SceneMappingServiceFixture.cs" />
|
||||||
<Compile Include="DataAugmentation\DailySeries\DailySeriesDataProxyFixture.cs" />
|
<Compile Include="DataAugmentation\DailySeries\DailySeriesDataProxyFixture.cs" />
|
||||||
@@ -183,6 +182,10 @@
|
|||||||
<Compile Include="Download\DownloadClientTests\TransmissionTests\TransmissionFixtureBase.cs" />
|
<Compile Include="Download\DownloadClientTests\TransmissionTests\TransmissionFixtureBase.cs" />
|
||||||
<Compile Include="Download\DownloadClientTests\UTorrentTests\UTorrentFixture.cs" />
|
<Compile Include="Download\DownloadClientTests\UTorrentTests\UTorrentFixture.cs" />
|
||||||
<Compile Include="Download\DownloadClientTests\VuzeTests\VuzeFixture.cs" />
|
<Compile Include="Download\DownloadClientTests\VuzeTests\VuzeFixture.cs" />
|
||||||
|
<Compile Include="Download\DownloadClientTests\DownloadStationTests\TorrentDownloadStationFixture.cs" />
|
||||||
|
<Compile Include="Download\DownloadClientTests\DownloadStationTests\SerialNumberProviderFixture.cs" />
|
||||||
|
<Compile Include="Download\DownloadClientTests\DownloadStationTests\SharedFolderResolverFixture.cs" />
|
||||||
|
<Compile Include="Download\DownloadClientTests\DownloadStationTests\UsenetDownloadStationFixture.cs" />
|
||||||
<Compile Include="Download\DownloadServiceFixture.cs" />
|
<Compile Include="Download\DownloadServiceFixture.cs" />
|
||||||
<Compile Include="Download\FailedDownloadServiceFixture.cs" />
|
<Compile Include="Download\FailedDownloadServiceFixture.cs" />
|
||||||
<Compile Include="Download\Pending\PendingReleaseServiceTests\PendingReleaseServiceFixture.cs" />
|
<Compile Include="Download\Pending\PendingReleaseServiceTests\PendingReleaseServiceFixture.cs" />
|
||||||
@@ -211,9 +214,10 @@
|
|||||||
<Compile Include="HealthCheck\Checks\AppDataLocationFixture.cs" />
|
<Compile Include="HealthCheck\Checks\AppDataLocationFixture.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\DownloadClientCheckFixture.cs" />
|
<Compile Include="HealthCheck\Checks\DownloadClientCheckFixture.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\DroneFactoryCheckFixture.cs" />
|
<Compile Include="HealthCheck\Checks\DroneFactoryCheckFixture.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\HealthCheckFixtureExtentions.cs" />
|
<Compile Include="HealthCheck\Checks\HealthCheckFixtureExtensions.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\ImportMechanismCheckFixture.cs" />
|
<Compile Include="HealthCheck\Checks\ImportMechanismCheckFixture.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\IndexerCheckFixture.cs" />
|
<Compile Include="HealthCheck\Checks\IndexerSearchCheckFixture.cs" />
|
||||||
|
<Compile Include="HealthCheck\Checks\IndexerRssCheckFixture.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\MonoVersionCheckFixture.cs" />
|
<Compile Include="HealthCheck\Checks\MonoVersionCheckFixture.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\IndexerStatusCheckFixture.cs" />
|
<Compile Include="HealthCheck\Checks\IndexerStatusCheckFixture.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\RootFolderCheckFixture.cs" />
|
<Compile Include="HealthCheck\Checks\RootFolderCheckFixture.cs" />
|
||||||
@@ -257,11 +261,9 @@
|
|||||||
<Compile Include="IndexerTests\TestIndexer.cs" />
|
<Compile Include="IndexerTests\TestIndexer.cs" />
|
||||||
<Compile Include="IndexerTests\TestIndexerSettings.cs" />
|
<Compile Include="IndexerTests\TestIndexerSettings.cs" />
|
||||||
<Compile Include="IndexerTests\IPTorrentsTests\IPTorrentsFixture.cs" />
|
<Compile Include="IndexerTests\IPTorrentsTests\IPTorrentsFixture.cs" />
|
||||||
<Compile Include="IndexerTests\KickassTorrentsTests\KickassTorrentsFixture.cs" />
|
|
||||||
<Compile Include="IndexerTests\NyaaTests\NyaaFixture.cs" />
|
<Compile Include="IndexerTests\NyaaTests\NyaaFixture.cs" />
|
||||||
<Compile Include="IndexerTests\TorrentRssIndexerTests\TorrentRssIndexerFixture.cs" />
|
<Compile Include="IndexerTests\TorrentRssIndexerTests\TorrentRssIndexerFixture.cs" />
|
||||||
<Compile Include="IndexerTests\TorrentRssIndexerTests\TestTorrentRssIndexer.cs" />
|
<Compile Include="IndexerTests\TorrentRssIndexerTests\TestTorrentRssIndexer.cs" />
|
||||||
<Compile Include="IndexerTests\WomblesTests\WomblesFixture.cs" />
|
|
||||||
<Compile Include="IndexerTests\XElementExtensionsFixture.cs" />
|
<Compile Include="IndexerTests\XElementExtensionsFixture.cs" />
|
||||||
<Compile Include="InstrumentationTests\DatabaseTargetFixture.cs" />
|
<Compile Include="InstrumentationTests\DatabaseTargetFixture.cs" />
|
||||||
<Compile Include="JobTests\JobRepositoryFixture.cs" />
|
<Compile Include="JobTests\JobRepositoryFixture.cs" />
|
||||||
@@ -347,7 +349,6 @@
|
|||||||
<Compile Include="Profiles\ProfileRepositoryFixture.cs" />
|
<Compile Include="Profiles\ProfileRepositoryFixture.cs" />
|
||||||
<Compile Include="Profiles\ProfileServiceFixture.cs" />
|
<Compile Include="Profiles\ProfileServiceFixture.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Providers\XemProxyFixture.cs" />
|
|
||||||
<Compile Include="ProviderTests\DiskProviderTests\ArchiveProviderFixture.cs" />
|
<Compile Include="ProviderTests\DiskProviderTests\ArchiveProviderFixture.cs" />
|
||||||
<Compile Include="ProviderTests\DiskScanProviderTests\GetVideoFilesFixture.cs" />
|
<Compile Include="ProviderTests\DiskScanProviderTests\GetVideoFilesFixture.cs" />
|
||||||
<Compile Include="ProviderTests\RecycleBinProviderTests\CleanupFixture.cs" />
|
<Compile Include="ProviderTests\RecycleBinProviderTests\CleanupFixture.cs" />
|
||||||
@@ -383,6 +384,7 @@
|
|||||||
<Compile Include="UpdateTests\UpdatePackageProviderFixture.cs" />
|
<Compile Include="UpdateTests\UpdatePackageProviderFixture.cs" />
|
||||||
<Compile Include="UpdateTests\UpdateServiceFixture.cs" />
|
<Compile Include="UpdateTests\UpdateServiceFixture.cs" />
|
||||||
<Compile Include="XbmcVersionTests.cs" />
|
<Compile Include="XbmcVersionTests.cs" />
|
||||||
|
<Compile Include="BulkImport\AddMultiMoviesFixture.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Marr.Data\Marr.Data.csproj">
|
<ProjectReference Include="..\Marr.Data\Marr.Data.csproj">
|
||||||
@@ -418,6 +420,10 @@
|
|||||||
<Content Include="Files\imdb_watchlist.xml">
|
<Content Include="Files\imdb_watchlist.xml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="Files\Indexers\TorrentRss\AlphaRatio.xml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Content>
|
||||||
<Content Include="License.txt" />
|
<Content Include="License.txt" />
|
||||||
<None Include="Files\Indexers\BroadcastheNet\RecentFeed.json">
|
<None Include="Files\Indexers\BroadcastheNet\RecentFeed.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
@@ -558,21 +564,11 @@
|
|||||||
<None Include="Files\TestArchive.zip">
|
<None Include="Files\TestArchive.zip">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<Content Include="Files\Xem\Failure.txt">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Files\Xem\Ids.txt">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Files\Xem\Mappings.txt">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Files\Xem\Names.txt">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Folder Include="DataAugmentation\SceneNumbering\" />
|
||||||
|
<Folder Include="Providers\" />
|
||||||
<Folder Include="ProviderTests\UpdateProviderTests\" />
|
<Folder Include="ProviderTests\UpdateProviderTests\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -587,11 +583,11 @@
|
|||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Series")]
|
||||||
public class AbsoluteEpisodeNumberParserFixture : CoreTest
|
public class AbsoluteEpisodeNumberParserFixture : CoreTest
|
||||||
{
|
{
|
||||||
[TestCase("[SubDESU]_High_School_DxD_07_(1280x720_x264-AAC)_[6B7FD717]", "High School DxD", 7, 0, 0)]
|
[TestCase("[SubDESU]_High_School_DxD_07_(1280x720_x264-AAC)_[6B7FD717]", "High School DxD", 7, 0, 0)]
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Series")]
|
||||||
public class DailyEpisodeParserFixture : CoreTest
|
public class DailyEpisodeParserFixture : CoreTest
|
||||||
{
|
{
|
||||||
[TestCase("Conan 2011 04 18 Emma Roberts HDTV XviD BFF", "Conan", 2011, 04, 18)]
|
[TestCase("Conan 2011 04 18 Emma Roberts HDTV XviD BFF", "Conan", 2011, 04, 18)]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
@@ -11,6 +11,9 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", Language.English)]
|
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", Language.English)]
|
||||||
[TestCase("Castle.2009.S01E14.French.HDTV.XviD-LOL", Language.French)]
|
[TestCase("Castle.2009.S01E14.French.HDTV.XviD-LOL", Language.French)]
|
||||||
|
[TestCase("Ouija.Origin.of.Evil.2016.MULTi.TRUEFRENCH.1080p.BluRay.x264-MELBA", Language.French)]
|
||||||
|
[TestCase("Everest.2015.FRENCH.VFQ.BDRiP.x264-CNF30", Language.French)]
|
||||||
|
[TestCase("Showdown.In.Little.Tokyo.1991.MULTI.VFQ.VFF.DTSHD-MASTER.1080p.BluRay.x264-ZombiE", Language.French)]
|
||||||
[TestCase("Castle.2009.S01E14.Spanish.HDTV.XviD-LOL", Language.Spanish)]
|
[TestCase("Castle.2009.S01E14.Spanish.HDTV.XviD-LOL", Language.Spanish)]
|
||||||
[TestCase("Castle.2009.S01E14.German.HDTV.XviD-LOL", Language.German)]
|
[TestCase("Castle.2009.S01E14.German.HDTV.XviD-LOL", Language.German)]
|
||||||
[TestCase("Castle.2009.S01E14.Germany.HDTV.XviD-LOL", Language.English)]
|
[TestCase("Castle.2009.S01E14.Germany.HDTV.XviD-LOL", Language.English)]
|
||||||
@@ -46,10 +49,17 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
[TestCase("Castle.2009.S01E14.HDTV.XviD.HUNDUB-LOL", Language.Hungarian)]
|
[TestCase("Castle.2009.S01E14.HDTV.XviD.HUNDUB-LOL", Language.Hungarian)]
|
||||||
[TestCase("Castle.2009.S01E14.HDTV.XviD.ENG.HUN-LOL", Language.Hungarian)]
|
[TestCase("Castle.2009.S01E14.HDTV.XviD.ENG.HUN-LOL", Language.Hungarian)]
|
||||||
[TestCase("Castle.2009.S01E14.HDTV.XviD.HUN-LOL", Language.Hungarian)]
|
[TestCase("Castle.2009.S01E14.HDTV.XviD.HUN-LOL", Language.Hungarian)]
|
||||||
|
[TestCase("The Danish Girl 2015", Language.English)]
|
||||||
|
[TestCase("Passengers.2016.German.DL.AC3.Dubbed.1080p.WebHD.h264.iNTERNAL-PsO", Language.German)]
|
||||||
public void should_parse_language(string postTitle, Language language)
|
public void should_parse_language(string postTitle, Language language)
|
||||||
{
|
{
|
||||||
var result = LanguageParser.ParseLanguage(postTitle);
|
var result = Parser.Parser.ParseMovieTitle(postTitle);
|
||||||
result.Should().Be(language);
|
if (result == null)
|
||||||
|
{
|
||||||
|
Parser.Parser.ParseTitle(postTitle).Language.Should().Be(language);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
result.Language.Should().Be(language);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("2 Broke Girls - S01E01 - Pilot.en.sub", Language.English)]
|
[TestCase("2 Broke Girls - S01E01 - Pilot.en.sub", Language.English)]
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Series")]
|
||||||
public class MiniSeriesEpisodeParserFixture : CoreTest
|
public class MiniSeriesEpisodeParserFixture : CoreTest
|
||||||
{
|
{
|
||||||
[TestCase("The.Kennedys.Part.2.DSR.XviD-SYS", "The Kennedys", 2)]
|
[TestCase("The.Kennedys.Part.2.DSR.XviD-SYS", "The Kennedys", 2)]
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Series")]
|
||||||
public class MultiEpisodeParserFixture : CoreTest
|
public class MultiEpisodeParserFixture : CoreTest
|
||||||
{
|
{
|
||||||
[TestCase("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", "WEEDS", 3, new[] { 1, 2, 3, 4, 5, 6 })]
|
[TestCase("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", "WEEDS", 3, new[] { 1, 2, 3, 4, 5, 6 })]
|
||||||
|
|||||||
@@ -62,5 +62,30 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
Parser.Parser.ParseTitle(postTitle).SeriesTitle.Should().Be(title);
|
Parser.Parser.ParseTitle(postTitle).SeriesTitle.Should().Be(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("The.Man.from.U.N.C.L.E.2015.1080p.BluRay.x264-SPARKS", "The Man from U.N.C.L.E.")]
|
||||||
|
[TestCase("1941.1979.EXTENDED.720p.BluRay.X264-AMIABLE", "1941")]
|
||||||
|
[TestCase("MY MOVIE (2016) [R][Action, Horror][720p.WEB-DL.AVC.8Bit.6ch.AC3].mkv", "MY MOVIE")]
|
||||||
|
[TestCase("R.I.P.D.2013.720p.BluRay.x264-SPARKS", "R.I.P.D.")]
|
||||||
|
[TestCase("V.H.S.2.2013.LIMITED.720p.BluRay.x264-GECKOS", "V.H.S. 2")]
|
||||||
|
[TestCase("This Is A Movie (1999) [IMDB #] <Genre, Genre, Genre> {ACTORS} !DIRECTOR +MORE_SILLY_STUFF_NO_ONE_NEEDS ?", "This Is A Movie")]
|
||||||
|
[TestCase("We Are the Best!.2013.720p.H264.mkv", "We Are the Best!")]
|
||||||
|
[TestCase("(500).Days.Of.Summer.(2009).DTS.1080p.BluRay.x264.NLsubs", "(500) Days Of Summer")]
|
||||||
|
public void should_parse_movie_title(string postTitle, string title)
|
||||||
|
{
|
||||||
|
Parser.Parser.ParseMovieTitle(postTitle).MovieTitle.Should().Be(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("1941.1979.EXTENDED.720p.BluRay.X264-AMIABLE", 1979)]
|
||||||
|
public void should_parse_movie_year(string postTitle, int year)
|
||||||
|
{
|
||||||
|
Parser.Parser.ParseMovieTitle(postTitle).Year.Should().Be(year);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("The Danish Girl 2015")]
|
||||||
|
public void should_not_parse_language_in_movie_title(string postTitle)
|
||||||
|
{
|
||||||
|
Parser.Parser.ParseMovieTitle(postTitle).Language.Should().Be(Language.English);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using NzbDrone.Test.Common;
|
|||||||
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Series")]
|
||||||
public class GetEpisodesFixture : TestBase<ParsingService>
|
public class GetEpisodesFixture : TestBase<ParsingService>
|
||||||
{
|
{
|
||||||
private Series _series;
|
private Series _series;
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||||||
public class MapFixture : TestBase<ParsingService>
|
public class MapFixture : TestBase<ParsingService>
|
||||||
{
|
{
|
||||||
private Series _series;
|
private Series _series;
|
||||||
|
private Movie _movie;
|
||||||
|
private ParsedMovieInfo _parsedMovieInfo;
|
||||||
|
private ParsedMovieInfo _wrongYearInfo;
|
||||||
|
private ParsedMovieInfo _romanTitleInfo;
|
||||||
|
private ParsedMovieInfo _alternativeTitleInfo;
|
||||||
|
private MovieSearchCriteria _movieSearchCriteria;
|
||||||
private List<Episode> _episodes;
|
private List<Episode> _episodes;
|
||||||
private ParsedEpisodeInfo _parsedEpisodeInfo;
|
private ParsedEpisodeInfo _parsedEpisodeInfo;
|
||||||
private SingleEpisodeSearchCriteria _singleEpisodeSearchCriteria;
|
private SingleEpisodeSearchCriteria _singleEpisodeSearchCriteria;
|
||||||
@@ -30,6 +36,13 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||||||
.With(s => s.CleanTitle = "rock")
|
.With(s => s.CleanTitle = "rock")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
_movie = Builder<Movie>.CreateNew()
|
||||||
|
.With(m => m.Title = "Mission Impossible 3")
|
||||||
|
.With(m => m.CleanTitle = "missionimpossible3")
|
||||||
|
.With(m => m.Year = 2006)
|
||||||
|
.With(m => m.AlternativeTitles = new List<string> { "Mission Impossible 3: Same same" })
|
||||||
|
.Build();
|
||||||
|
|
||||||
_episodes = Builder<Episode>.CreateListOfSize(1)
|
_episodes = Builder<Episode>.CreateListOfSize(1)
|
||||||
.All()
|
.All()
|
||||||
.With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
|
.With(e => e.AirDate = DateTime.Today.ToString(Episode.AIR_DATE_FORMAT))
|
||||||
@@ -43,6 +56,31 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||||||
EpisodeNumbers = new[] { 1 }
|
EpisodeNumbers = new[] { 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_parsedMovieInfo = new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
MovieTitle = _movie.Title,
|
||||||
|
Year = _movie.Year,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
_wrongYearInfo = new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
MovieTitle = _movie.Title,
|
||||||
|
Year = 1900,
|
||||||
|
};
|
||||||
|
|
||||||
|
_alternativeTitleInfo = new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
MovieTitle = _movie.AlternativeTitles.First(),
|
||||||
|
Year = _movie.Year,
|
||||||
|
};
|
||||||
|
|
||||||
|
_romanTitleInfo = new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
MovieTitle = "Mission Impossible III",
|
||||||
|
Year = _movie.Year,
|
||||||
|
};
|
||||||
|
|
||||||
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
||||||
{
|
{
|
||||||
Series = _series,
|
Series = _series,
|
||||||
@@ -50,27 +88,18 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||||||
SeasonNumber = _episodes.First().SeasonNumber,
|
SeasonNumber = _episodes.First().SeasonNumber,
|
||||||
Episodes = _episodes
|
Episodes = _episodes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_movieSearchCriteria = new MovieSearchCriteria
|
||||||
|
{
|
||||||
|
Movie = _movie
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenMatchBySeriesTitle()
|
private void GivenMatchByMovieTitle()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<ISeriesService>()
|
Mocker.GetMock<IMovieService>()
|
||||||
.Setup(s => s.FindByTitle(It.IsAny<string>()))
|
.Setup(s => s.FindByTitle(It.IsAny<string>()))
|
||||||
.Returns(_series);
|
.Returns(_movie);
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenMatchByTvdbId()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Setup(s => s.FindByTvdbId(It.IsAny<Int32>()))
|
|
||||||
.Returns(_series);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenMatchByTvRageId()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Setup(s => s.FindByTvRageId(It.IsAny<int>()))
|
|
||||||
.Returns(_series);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenParseResultSeriesDoesntMatchSearchCriteria()
|
private void GivenParseResultSeriesDoesntMatchSearchCriteria()
|
||||||
@@ -79,121 +108,45 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_lookup_series_by_name()
|
public void should_lookup_Movie_by_name()
|
||||||
{
|
{
|
||||||
GivenMatchBySeriesTitle();
|
GivenMatchByMovieTitle();
|
||||||
|
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
|
Subject.Map(_parsedMovieInfo, "", null);
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
Mocker.GetMock<IMovieService>()
|
||||||
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Once());
|
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_use_tvdbid_when_series_title_lookup_fails()
|
public void should_use_search_criteria_movie_title()
|
||||||
{
|
{
|
||||||
GivenMatchByTvdbId();
|
GivenMatchByMovieTitle();
|
||||||
|
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
|
Subject.Map(_parsedMovieInfo, "", _movieSearchCriteria);
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.FindByTvdbId(It.IsAny<Int32>()), Times.Once());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_use_tvrageid_when_series_title_lookup_fails()
|
|
||||||
{
|
|
||||||
GivenMatchByTvRageId();
|
|
||||||
|
|
||||||
Subject.Map(_parsedEpisodeInfo, 0, _series.TvRageId);
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.FindByTvRageId(It.IsAny<int>()), Times.Once());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_not_use_tvrageid_when_scene_naming_exception_exists()
|
|
||||||
{
|
|
||||||
GivenMatchByTvRageId();
|
|
||||||
|
|
||||||
Mocker.GetMock<ISceneMappingService>()
|
|
||||||
.Setup(v => v.FindTvdbId(It.IsAny<string>()))
|
|
||||||
.Returns(10);
|
|
||||||
|
|
||||||
var result = Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId);
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.FindByTvRageId(It.IsAny<int>()), Times.Never());
|
|
||||||
|
|
||||||
result.Series.Should().BeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_use_search_criteria_series_title()
|
|
||||||
{
|
|
||||||
GivenMatchBySeriesTitle();
|
|
||||||
|
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
Mocker.GetMock<ISeriesService>()
|
||||||
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Never());
|
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_FindByTitle_when_search_criteria_matching_fails()
|
public void should_not_match_with_wrong_year()
|
||||||
{
|
{
|
||||||
GivenParseResultSeriesDoesntMatchSearchCriteria();
|
GivenMatchByMovieTitle();
|
||||||
|
Subject.Map(_wrongYearInfo, "", _movieSearchCriteria).Movie.Should().BeNull();
|
||||||
Subject.Map(_parsedEpisodeInfo, 10, 10, _singleEpisodeSearchCriteria);
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Once());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_FindByTvdbId_when_search_criteria_and_FindByTitle_matching_fails()
|
public void should_match_alternative_title()
|
||||||
{
|
{
|
||||||
GivenParseResultSeriesDoesntMatchSearchCriteria();
|
Subject.Map(_alternativeTitleInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
|
||||||
|
}
|
||||||
|
|
||||||
Subject.Map(_parsedEpisodeInfo, 10, 10, _singleEpisodeSearchCriteria);
|
[Test]
|
||||||
|
public void should_match_roman_title()
|
||||||
|
{
|
||||||
|
Subject.Map(_romanTitleInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
|
||||||
|
}
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.FindByTvdbId(It.IsAny<Int32>()), Times.Once());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_FindByTvRageId_when_search_criteria_and_FindByTitle_matching_fails()
|
|
||||||
{
|
|
||||||
GivenParseResultSeriesDoesntMatchSearchCriteria();
|
|
||||||
|
|
||||||
Subject.Map(_parsedEpisodeInfo, 10, 10, _singleEpisodeSearchCriteria);
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.FindByTvRageId(It.IsAny<int>()), Times.Once());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_use_tvdbid_matching_when_alias_is_found()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<ISceneMappingService>()
|
|
||||||
.Setup(s => s.FindTvdbId(It.IsAny<string>()))
|
|
||||||
.Returns(_series.TvdbId);
|
|
||||||
|
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Never());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_use_tvrageid_match_from_search_criteria_when_title_match_fails()
|
|
||||||
{
|
|
||||||
GivenParseResultSeriesDoesntMatchSearchCriteria();
|
|
||||||
|
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
|
|
||||||
|
|
||||||
Mocker.GetMock<ISeriesService>()
|
|
||||||
.Verify(v => v.FindByTitle(It.IsAny<string>()), Times.Never());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Series")]//Is this really necessary with movies? I dont think so
|
||||||
public class PathParserFixture : CoreTest
|
public class PathParserFixture : CoreTest
|
||||||
{
|
{
|
||||||
[TestCase(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)]
|
[TestCase(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)]
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
new object[] { Quality.Bluray720p },
|
new object[] { Quality.Bluray720p },
|
||||||
new object[] { Quality.Bluray1080p },
|
new object[] { Quality.Bluray1080p },
|
||||||
new object[] { Quality.Bluray2160p },
|
new object[] { Quality.Bluray2160p },
|
||||||
|
new object[] { Quality.Remux1080p },
|
||||||
|
new object[] { Quality.Remux2160p },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static object[] OtherSourceQualityParserCases =
|
public static object[] OtherSourceQualityParserCases =
|
||||||
@@ -40,6 +42,8 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
new object[] { "720p BluRay", Quality.Bluray720p },
|
new object[] { "720p BluRay", Quality.Bluray720p },
|
||||||
new object[] { "1080p BluRay", Quality.Bluray1080p },
|
new object[] { "1080p BluRay", Quality.Bluray1080p },
|
||||||
new object[] { "2160p BluRay", Quality.Bluray2160p },
|
new object[] { "2160p BluRay", Quality.Bluray2160p },
|
||||||
|
new object[] { "1080p Remux", Quality.Remux1080p },
|
||||||
|
new object[] { "2160p Remux", Quality.Remux2160p },
|
||||||
};
|
};
|
||||||
|
|
||||||
[TestCase("S07E23 .avi ", false)]
|
[TestCase("S07E23 .avi ", false)]
|
||||||
@@ -79,7 +83,6 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
[TestCase("the.shield.1x13.circles.ws.xvidvd-tns", false)]
|
[TestCase("the.shield.1x13.circles.ws.xvidvd-tns", false)]
|
||||||
[TestCase("the_x-files.9x18.sunshine_days.ac3.ws_dvdrip_xvid-fov.avi", false)]
|
[TestCase("the_x-files.9x18.sunshine_days.ac3.ws_dvdrip_xvid-fov.avi", false)]
|
||||||
[TestCase("[FroZen] Miyuki - 23 [DVD][7F6170E6]", false)]
|
[TestCase("[FroZen] Miyuki - 23 [DVD][7F6170E6]", false)]
|
||||||
[TestCase("Hannibal.S01E05.576p.BluRay.DD5.1.x264-HiSD", false)]
|
|
||||||
[TestCase("Hannibal.S01E05.480p.BluRay.DD5.1.x264-HiSD", false)]
|
[TestCase("Hannibal.S01E05.480p.BluRay.DD5.1.x264-HiSD", false)]
|
||||||
[TestCase("Heidi Girl of the Alps (BD)(640x480(RAW) (BATCH 1) (1-13)", false)]
|
[TestCase("Heidi Girl of the Alps (BD)(640x480(RAW) (BATCH 1) (1-13)", false)]
|
||||||
[TestCase("[Doki] Clannad - 02 (848x480 XviD BD MP3) [95360783]", false)]
|
[TestCase("[Doki] Clannad - 02 (848x480 XviD BD MP3) [95360783]", false)]
|
||||||
@@ -215,6 +218,27 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
ParseAndVerifyQuality(title, Quality.Bluray1080p, proper);
|
ParseAndVerifyQuality(title, Quality.Bluray1080p, proper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("Movie.Name.2004.576p.BDRip.x264-HANDJOB")]
|
||||||
|
[TestCase("Hannibal.S01E05.576p.BluRay.DD5.1.x264-HiSD")]
|
||||||
|
public void should_parse_bluray576p_quality(string title)
|
||||||
|
{
|
||||||
|
ParseAndVerifyQuality(title, Quality.Bluray576p, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("Contract.to.Kill.2016.REMUX.1080p.BluRay.AVC.DTS-HD.MA.5.1-iFT")]
|
||||||
|
[TestCase("27.Dresses.2008.REMUX.1080p.Bluray.AVC.DTS-HR.MA.5.1-LEGi0N")]
|
||||||
|
public void should_parse_remux1080p_quality(string title)
|
||||||
|
{
|
||||||
|
ParseAndVerifyQuality(title, Quality.Remux1080p, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("Contract.to.Kill.2016.REMUX.2160p.BluRay.AVC.DTS-HD.MA.5.1-iFT")]
|
||||||
|
[TestCase("27.Dresses.2008.REMUX.2160p.Bluray.AVC.DTS-HR.MA.5.1-LEGi0N")]
|
||||||
|
public void should_parse_remux2160p_quality(string title)
|
||||||
|
{
|
||||||
|
ParseAndVerifyQuality(title, Quality.Remux2160p, false);
|
||||||
|
}
|
||||||
|
|
||||||
//[TestCase("POI S02E11 1080i HDTV DD5.1 MPEG2-TrollHD", false)]
|
//[TestCase("POI S02E11 1080i HDTV DD5.1 MPEG2-TrollHD", false)]
|
||||||
//[TestCase("How I Met Your Mother S01E18 Nothing Good Happens After 2 A.M. 720p HDTV DD5.1 MPEG2-TrollHD", false)]
|
//[TestCase("How I Met Your Mother S01E18 Nothing Good Happens After 2 A.M. 720p HDTV DD5.1 MPEG2-TrollHD", false)]
|
||||||
//[TestCase("The Voice S01E11 The Finals 1080i HDTV DD5.1 MPEG2-TrollHD", false)]
|
//[TestCase("The Voice S01E11 The Finals 1080i HDTV DD5.1 MPEG2-TrollHD", false)]
|
||||||
@@ -275,6 +299,13 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
QualityParser.ParseQuality(title).QualitySource.Should().Be(QualitySource.Extension);
|
QualityParser.ParseQuality(title).QualitySource.Should().Be(QualitySource.Extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("Movie.Title.2016.1080p.KORSUB.WEBRip.x264.AAC2.0-RADARR", "korsub")]
|
||||||
|
[TestCase("Movie.Title.2016.1080p.KORSUBS.WEBRip.x264.AAC2.0-RADARR", "korsubs")]
|
||||||
|
public void should_parse_hardcoded_subs(string postTitle, string sub)
|
||||||
|
{
|
||||||
|
QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub);
|
||||||
|
}
|
||||||
|
|
||||||
private void ParseAndVerifyQuality(string title, Quality quality, bool proper)
|
private void ParseAndVerifyQuality(string title, Quality quality, bool proper)
|
||||||
{
|
{
|
||||||
var result = QualityParser.ParseQuality(title);
|
var result = QualityParser.ParseQuality(title);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Series")]
|
||||||
public class SeasonParserFixture : CoreTest
|
public class SeasonParserFixture : CoreTest
|
||||||
{
|
{
|
||||||
[TestCase("30.Rock.Season.04.HDTV.XviD-DIMENSION", "30 Rock", 4)]
|
[TestCase("30.Rock.Season.04.HDTV.XviD-DIMENSION", "30 Rock", 4)]
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using NzbDrone.Core.Test.Framework;
|
|||||||
namespace NzbDrone.Core.Test.ParserTests
|
namespace NzbDrone.Core.Test.ParserTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Series")]
|
||||||
public class SeriesTitleInfoFixture : CoreTest
|
public class SeriesTitleInfoFixture : CoreTest
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Series")]
|
||||||
public class SingleEpisodeParserFixture : CoreTest
|
public class SingleEpisodeParserFixture : CoreTest
|
||||||
{
|
{
|
||||||
[TestCase("Sonny.With.a.Chance.S02E15", "Sonny With a Chance", 2, 15)]
|
[TestCase("Sonny.With.a.Chance.S02E15", "Sonny With a Chance", 2, 15)]
|
||||||
|
|||||||
+46
-15
@@ -1,39 +1,47 @@
|
|||||||
using System.IO;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
{
|
{
|
||||||
|
|
||||||
public class GetVideoFilesFixture : CoreTest<DiskScanService>
|
public class GetVideoFilesFixture : CoreTest<DiskScanService>
|
||||||
{
|
{
|
||||||
private string[] _files;
|
private string[] _fileNames;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_files = new[]
|
_fileNames = new[]
|
||||||
{
|
{
|
||||||
@"C:\Test\30 Rock1.mkv",
|
@"30 Rock1.mkv",
|
||||||
@"C:\Test\30 Rock2.avi",
|
@"30 Rock2.avi",
|
||||||
@"C:\Test\30 Rock3.MP4",
|
@"30 Rock3.MP4",
|
||||||
@"C:\Test\30 Rock4.wMv",
|
@"30 Rock4.wMv",
|
||||||
@"C:\Test\movie.exe",
|
@"movie.exe",
|
||||||
@"C:\Test\movie"
|
@"movie"
|
||||||
};
|
};
|
||||||
|
|
||||||
GivenFiles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenFiles()
|
private IEnumerable<string> GetFiles(string folder, string subFolder = "")
|
||||||
{
|
{
|
||||||
|
return _fileNames.Select(f => Path.Combine(folder, subFolder, f));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenFiles(IEnumerable<string> files)
|
||||||
|
{
|
||||||
|
var filesToReturn = files.ToArray();
|
||||||
Mocker.GetMock<IDiskProvider>()
|
Mocker.GetMock<IDiskProvider>()
|
||||||
.Setup(s => s.GetFiles(It.IsAny<string>(), SearchOption.AllDirectories))
|
.Setup(s => s.GetFiles(It.IsAny<string>(), SearchOption.AllDirectories))
|
||||||
.Returns(_files);
|
.Returns(filesToReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -73,8 +81,31 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
|||||||
public void should_return_video_files_only()
|
public void should_return_video_files_only()
|
||||||
{
|
{
|
||||||
var path = @"C:\Test\";
|
var path = @"C:\Test\";
|
||||||
|
GivenFiles(GetFiles(path));
|
||||||
|
|
||||||
Subject.GetVideoFiles(path).Should().HaveCount(4);
|
Subject.GetVideoFiles(path).Should().HaveCount(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("Extras")]
|
||||||
|
[TestCase("@eadir")]
|
||||||
|
[TestCase("extrafanart")]
|
||||||
|
[TestCase("Plex Versions")]
|
||||||
|
[TestCase(".secret")]
|
||||||
|
[TestCase(".hidden")]
|
||||||
|
public void should_filter_certain_sub_folders(string subFolder)
|
||||||
|
{
|
||||||
|
var path = @"C:\Test\";
|
||||||
|
var files = GetFiles(path).ToList();
|
||||||
|
var specialFiles = GetFiles(path, subFolder).ToList();
|
||||||
|
var allFiles = files.Concat(specialFiles);
|
||||||
|
|
||||||
|
var series = Builder<Series>.CreateNew()
|
||||||
|
.With(s => s.Path = path)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var filteredFiles = Subject.FilterFiles(series, allFiles);
|
||||||
|
filteredFiles.Should().NotContain(specialFiles);
|
||||||
|
filteredFiles.Count.Should().BeGreaterThan(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
using FluentAssertions;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.DataAugmentation.Xem;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Test.Common.Categories;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.Providers
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
[IntegrationTest]
|
|
||||||
public class XemProxyFixture : CoreTest<XemProxy>
|
|
||||||
{
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
UseRealHttp();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void get_series_ids()
|
|
||||||
{
|
|
||||||
var ids = Subject.GetXemSeriesIds();
|
|
||||||
|
|
||||||
ids.Should().NotBeEmpty();
|
|
||||||
ids.Should().Contain(i => i == 73141);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(12345, Description = "invalid id")]
|
|
||||||
[TestCase(279042, Description = "no single connection")]
|
|
||||||
public void should_return_empty_when_known_error(int id)
|
|
||||||
{
|
|
||||||
Subject.GetSceneTvdbMappings(id).Should().BeEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(82807)]
|
|
||||||
[TestCase(73141, Description = "American Dad!")]
|
|
||||||
public void should_get_mapping(int seriesId)
|
|
||||||
{
|
|
||||||
var result = Subject.GetSceneTvdbMappings(seriesId);
|
|
||||||
|
|
||||||
result.Should().NotBeEmpty();
|
|
||||||
result.Should().OnlyContain(c => c.Scene != null);
|
|
||||||
result.Should().OnlyContain(c => c.Tvdb != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(78916)]
|
|
||||||
public void should_filter_out_episodes_without_scene_mapping(int seriesId)
|
|
||||||
{
|
|
||||||
var result = Subject.GetSceneTvdbMappings(seriesId);
|
|
||||||
|
|
||||||
result.Should().NotContain(c => c.Tvdb == null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.RootFolders;
|
using NzbDrone.Core.RootFolders;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Test.Common;
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.RootFolderTests
|
namespace NzbDrone.Core.Test.RootFolderTests
|
||||||
@@ -103,5 +107,48 @@ namespace NzbDrone.Core.Test.RootFolderTests
|
|||||||
|
|
||||||
Assert.Throws<InvalidOperationException>(() => Subject.Add(new RootFolder { Path = path }));
|
Assert.Throws<InvalidOperationException>(() => Subject.Add(new RootFolder { Path = path }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("$recycle.bin")]
|
||||||
|
[TestCase("system volume information")]
|
||||||
|
[TestCase("recycler")]
|
||||||
|
[TestCase("lost+found")]
|
||||||
|
[TestCase(".appledb")]
|
||||||
|
[TestCase(".appledesktop")]
|
||||||
|
[TestCase(".appledouble")]
|
||||||
|
[TestCase("@eadir")]
|
||||||
|
[TestCase(".grab")]
|
||||||
|
public void should_get_root_folder_with_subfolders_excluding_special_sub_folders(string subFolder)
|
||||||
|
{
|
||||||
|
var rootFolder = Builder<RootFolder>.CreateNew()
|
||||||
|
.With(r => r.Path = @"C:\Test\TV")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var subFolders = new[]
|
||||||
|
{
|
||||||
|
"Series1",
|
||||||
|
"Series2",
|
||||||
|
"Series3",
|
||||||
|
subFolder
|
||||||
|
};
|
||||||
|
|
||||||
|
var folders = subFolders.Select(f => Path.Combine(@"C:\Test\TV", f)).ToArray();
|
||||||
|
|
||||||
|
Mocker.GetMock<IRootFolderRepository>()
|
||||||
|
.Setup(s => s.Get(It.IsAny<int>()))
|
||||||
|
.Returns(rootFolder);
|
||||||
|
|
||||||
|
Mocker.GetMock<ISeriesService>()
|
||||||
|
.Setup(s => s.GetAllSeries())
|
||||||
|
.Returns(new List<Series>());
|
||||||
|
|
||||||
|
Mocker.GetMock<IDiskProvider>()
|
||||||
|
.Setup(s => s.GetDirectories(rootFolder.Path))
|
||||||
|
.Returns(folders);
|
||||||
|
|
||||||
|
var unmappedFolders = Subject.Get(rootFolder.Id).UnmappedFolders;
|
||||||
|
|
||||||
|
unmappedFolders.Count.Should().BeGreaterThan(0);
|
||||||
|
unmappedFolders.Should().NotContain(u => u.Name == subFolder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,40 +1,39 @@
|
|||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
using NzbDrone.Core.Tv.Events;
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.TvTests.SeriesServiceTests
|
namespace NzbDrone.Core.Test.TvTests.SeriesServiceTests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class AddSeriesFixture : CoreTest<SeriesService>
|
public class AddSeriesFixture : CoreTest<SeriesService>
|
||||||
{
|
{
|
||||||
private Series fakeSeries;
|
private Series fakeSeries;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
fakeSeries = Builder<Series>.CreateNew().Build();
|
fakeSeries = Builder<Series>.CreateNew().Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void series_added_event_should_have_proper_path()
|
public void series_added_event_should_have_proper_path()
|
||||||
{
|
{
|
||||||
fakeSeries.Path = null;
|
fakeSeries.Path = null;
|
||||||
fakeSeries.RootFolderPath = @"C:\Test\TV";
|
fakeSeries.RootFolderPath = @"C:\Test\TV";
|
||||||
|
|
||||||
Mocker.GetMock<IBuildFileNames>()
|
Mocker.GetMock<IBuildFileNames>()
|
||||||
.Setup(s => s.GetSeriesFolder(fakeSeries, null))
|
.Setup(s => s.GetSeriesFolder(fakeSeries, null))
|
||||||
.Returns(fakeSeries.Title);
|
.Returns(fakeSeries.Title);
|
||||||
|
|
||||||
var series = Subject.AddSeries(fakeSeries);
|
var series = Subject.AddSeries(fakeSeries);
|
||||||
|
|
||||||
series.Path.Should().NotBeNull();
|
series.Path.Should().NotBeNull();
|
||||||
|
|
||||||
VerifyEventPublished<SeriesAddedEvent>();
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -105,12 +105,69 @@ namespace NzbDrone.Core.Configuration
|
|||||||
set { SetValue("RssSyncInterval", value); }
|
set { SetValue("RssSyncInterval", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int AvailabilityDelay
|
||||||
|
{
|
||||||
|
get { return GetValueInt("AvailabilityDelay",0); }
|
||||||
|
set { SetValue("AvailabilityDelay", value); }
|
||||||
|
}
|
||||||
|
|
||||||
public int NetImportSyncInterval
|
public int NetImportSyncInterval
|
||||||
{
|
{
|
||||||
get { return GetValueInt("NetImportSyncInterval", 60); }
|
get { return GetValueInt("NetImportSyncInterval", 60); }
|
||||||
|
|
||||||
set { SetValue("NetImportSyncInterval", value); }
|
set { SetValue("NetImportSyncInterval", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string TraktAuthToken
|
||||||
|
{
|
||||||
|
get { return GetValue("TraktAuthToken", string.Empty); }
|
||||||
|
|
||||||
|
set { SetValue("TraktAuthToken", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string TraktRefreshToken
|
||||||
|
{
|
||||||
|
get { return GetValue("TraktRefreshToken", string.Empty); }
|
||||||
|
|
||||||
|
set {SetValue("TraktRefreshToken", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TraktTokenExpiry
|
||||||
|
{
|
||||||
|
get { return GetValueInt("TraktTokenExpiry", 0); }
|
||||||
|
|
||||||
|
set { SetValue("TraktTokenExpiry", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NewTraktAuthToken
|
||||||
|
{
|
||||||
|
get {return GetValue("NewTraktAuthToken", string.Empty); }
|
||||||
|
set { SetValue("NewTraktAuthToken", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string NewTraktRefreshToken
|
||||||
|
{
|
||||||
|
get {return GetValue("NewTraktRefreshToken", string.Empty); }
|
||||||
|
set { SetValue("NewTraktRefreshToken", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NewTraktTokenExpiry
|
||||||
|
{
|
||||||
|
get {return GetValueInt("NewTraktTokenExpiry", 0); }
|
||||||
|
set { SetValue("NewTraktTokenExpiry", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ListSyncLevel
|
||||||
|
{
|
||||||
|
get { return GetValue("ListSyncLevel", "disabled"); }
|
||||||
|
set { SetValue("ListSyncLevel", value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ImportExclusions
|
||||||
|
{
|
||||||
|
get { return GetValue("ImportExclusions", string.Empty); }
|
||||||
|
set { SetValue("ImportExclusions", value); }
|
||||||
|
}
|
||||||
|
|
||||||
public int MinimumAge
|
public int MinimumAge
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,7 +46,17 @@ namespace NzbDrone.Core.Configuration
|
|||||||
int RssSyncInterval { get; set; }
|
int RssSyncInterval { get; set; }
|
||||||
int MinimumAge { get; set; }
|
int MinimumAge { get; set; }
|
||||||
|
|
||||||
|
int AvailabilityDelay { get; set; }
|
||||||
|
|
||||||
int NetImportSyncInterval { get; set; }
|
int NetImportSyncInterval { get; set; }
|
||||||
|
string ListSyncLevel { get; set; }
|
||||||
|
string ImportExclusions { get; set; }
|
||||||
|
string TraktAuthToken { get; set; }
|
||||||
|
string TraktRefreshToken { get; set; }
|
||||||
|
int TraktTokenExpiry { get; set; }
|
||||||
|
string NewTraktAuthToken { get; set; }
|
||||||
|
string NewTraktRefreshToken {get; set; }
|
||||||
|
int NewTraktTokenExpiry { get; set; }
|
||||||
|
|
||||||
//UI
|
//UI
|
||||||
int FirstDayOfWeek { get; set; }
|
int FirstDayOfWeek { get; set; }
|
||||||
@@ -56,6 +66,7 @@ namespace NzbDrone.Core.Configuration
|
|||||||
string LongDateFormat { get; set; }
|
string LongDateFormat { get; set; }
|
||||||
string TimeFormat { get; set; }
|
string TimeFormat { get; set; }
|
||||||
bool ShowRelativeDates { get; set; }
|
bool ShowRelativeDates { get; set; }
|
||||||
|
|
||||||
bool EnableColorImpairedMode { get; set; }
|
bool EnableColorImpairedMode { get; set; }
|
||||||
|
|
||||||
//Internal
|
//Internal
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace NzbDrone.Core.DataAugmentation.Xem.Model
|
|
||||||
{
|
|
||||||
public class XemResult<T>
|
|
||||||
{
|
|
||||||
public string Result { get; set; }
|
|
||||||
public T Data { get; set; }
|
|
||||||
public string Message { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace NzbDrone.Core.DataAugmentation.Xem.Model
|
|
||||||
{
|
|
||||||
public class XemSceneTvdbMapping
|
|
||||||
{
|
|
||||||
public XemValues Scene { get; set; }
|
|
||||||
public XemValues Tvdb { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace NzbDrone.Core.DataAugmentation.Xem.Model
|
|
||||||
{
|
|
||||||
public class XemValues
|
|
||||||
{
|
|
||||||
public int Season { get; set; }
|
|
||||||
public int Episode { get; set; }
|
|
||||||
public int Absolute { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
|
||||||
using NzbDrone.Core.DataAugmentation.Xem.Model;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.DataAugmentation.Xem
|
|
||||||
{
|
|
||||||
public interface IXemProxy
|
|
||||||
{
|
|
||||||
List<int> GetXemSeriesIds();
|
|
||||||
List<XemSceneTvdbMapping> GetSceneTvdbMappings(int id);
|
|
||||||
List<SceneMapping> GetSceneTvdbNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class XemProxy : IXemProxy
|
|
||||||
{
|
|
||||||
private const string ROOT_URL = "http://thexem.de/map/";
|
|
||||||
|
|
||||||
private readonly Logger _logger;
|
|
||||||
private readonly IHttpClient _httpClient;
|
|
||||||
private readonly IHttpRequestBuilderFactory _xemRequestBuilder;
|
|
||||||
|
|
||||||
private static readonly string[] IgnoredErrors = { "no single connection", "no show with the tvdb_id" };
|
|
||||||
|
|
||||||
public XemProxy(IHttpClient httpClient, Logger logger)
|
|
||||||
{
|
|
||||||
_httpClient = httpClient;
|
|
||||||
_logger = logger;
|
|
||||||
|
|
||||||
_xemRequestBuilder = new HttpRequestBuilder(ROOT_URL)
|
|
||||||
.AddSuffixQueryParam("origin", "tvdb")
|
|
||||||
.CreateFactory();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<int> GetXemSeriesIds()
|
|
||||||
{
|
|
||||||
_logger.Debug("Fetching Series IDs from");
|
|
||||||
|
|
||||||
var request = _xemRequestBuilder.Create()
|
|
||||||
.Resource("/havemap")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var response = _httpClient.Get<XemResult<List<string>>>(request).Resource;
|
|
||||||
CheckForFailureResult(response);
|
|
||||||
|
|
||||||
return response.Data.Select(d =>
|
|
||||||
{
|
|
||||||
int tvdbId = 0;
|
|
||||||
int.TryParse(d, out tvdbId);
|
|
||||||
|
|
||||||
return tvdbId;
|
|
||||||
}).Where(t => t > 0).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<XemSceneTvdbMapping> GetSceneTvdbMappings(int id)
|
|
||||||
{
|
|
||||||
_logger.Debug("Fetching Mappings for: {0}", id);
|
|
||||||
|
|
||||||
var request = _xemRequestBuilder.Create()
|
|
||||||
.Resource("/all")
|
|
||||||
.AddQueryParam("id", id)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var response = _httpClient.Get<XemResult<List<XemSceneTvdbMapping>>>(request).Resource;
|
|
||||||
|
|
||||||
return response.Data.Where(c => c.Scene != null).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SceneMapping> GetSceneTvdbNames()
|
|
||||||
{
|
|
||||||
_logger.Debug("Fetching alternate names");
|
|
||||||
|
|
||||||
var request = _xemRequestBuilder.Create()
|
|
||||||
.Resource("/allNames")
|
|
||||||
.AddQueryParam("seasonNumbers", true)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var response = _httpClient.Get<XemResult<Dictionary<int, List<JObject>>>>(request).Resource;
|
|
||||||
|
|
||||||
var result = new List<SceneMapping>();
|
|
||||||
|
|
||||||
foreach (var series in response.Data)
|
|
||||||
{
|
|
||||||
foreach (var name in series.Value)
|
|
||||||
{
|
|
||||||
foreach (var n in name)
|
|
||||||
{
|
|
||||||
int seasonNumber;
|
|
||||||
if (!int.TryParse(n.Value.ToString(), out seasonNumber))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//hack to deal with Fate/Zero
|
|
||||||
if (series.Key == 79151 && seasonNumber > 1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Add(new SceneMapping
|
|
||||||
{
|
|
||||||
Title = n.Key,
|
|
||||||
SearchTerm = n.Key,
|
|
||||||
SceneSeasonNumber = seasonNumber,
|
|
||||||
TvdbId = series.Key
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CheckForFailureResult<T>(XemResult<T> response)
|
|
||||||
{
|
|
||||||
if (response.Result.Equals("failure", StringComparison.InvariantCultureIgnoreCase) &&
|
|
||||||
!IgnoredErrors.Any(knowError => response.Message.Contains(knowError)))
|
|
||||||
{
|
|
||||||
throw new Exception("Error response received from Xem: " + response.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,243 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Common.Cache;
|
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
|
||||||
using NzbDrone.Core.Messaging.Events;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
using NzbDrone.Core.Tv.Events;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.DataAugmentation.Xem
|
|
||||||
{
|
|
||||||
public class XemService : ISceneMappingProvider, IHandle<SeriesUpdatedEvent>, IHandle<SeriesRefreshStartingEvent>
|
|
||||||
{
|
|
||||||
private readonly IEpisodeService _episodeService;
|
|
||||||
private readonly IXemProxy _xemProxy;
|
|
||||||
private readonly ISeriesService _seriesService;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
private readonly ICachedDictionary<bool> _cache;
|
|
||||||
|
|
||||||
public XemService(IEpisodeService episodeService,
|
|
||||||
IXemProxy xemProxy,
|
|
||||||
ISeriesService seriesService, ICacheManager cacheManager, Logger logger)
|
|
||||||
{
|
|
||||||
_episodeService = episodeService;
|
|
||||||
_xemProxy = xemProxy;
|
|
||||||
_seriesService = seriesService;
|
|
||||||
_logger = logger;
|
|
||||||
_cache = cacheManager.GetCacheDictionary<bool>(GetType(), "mappedTvdbid");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PerformUpdate(Series series)
|
|
||||||
{
|
|
||||||
_logger.Debug("Updating scene numbering mapping for: {0}", series);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var mappings = _xemProxy.GetSceneTvdbMappings(series.TvdbId);
|
|
||||||
|
|
||||||
if (!mappings.Any() && !series.UseSceneNumbering)
|
|
||||||
{
|
|
||||||
_logger.Debug("Mappings for: {0} are empty, skipping", series);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var episodes = _episodeService.GetEpisodeBySeries(series.Id);
|
|
||||||
|
|
||||||
foreach (var episode in episodes)
|
|
||||||
{
|
|
||||||
episode.SceneAbsoluteEpisodeNumber = null;
|
|
||||||
episode.SceneSeasonNumber = null;
|
|
||||||
episode.SceneEpisodeNumber = null;
|
|
||||||
episode.UnverifiedSceneNumbering = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var mapping in mappings)
|
|
||||||
{
|
|
||||||
_logger.Debug("Setting scene numbering mappings for {0} S{1:00}E{2:00}", series, mapping.Tvdb.Season, mapping.Tvdb.Episode);
|
|
||||||
|
|
||||||
var episode = episodes.SingleOrDefault(e => e.SeasonNumber == mapping.Tvdb.Season && e.EpisodeNumber == mapping.Tvdb.Episode);
|
|
||||||
|
|
||||||
if (episode == null)
|
|
||||||
{
|
|
||||||
_logger.Debug("Information hasn't been added to TheTVDB yet, skipping.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
episode.SceneAbsoluteEpisodeNumber = mapping.Scene.Absolute;
|
|
||||||
episode.SceneSeasonNumber = mapping.Scene.Season;
|
|
||||||
episode.SceneEpisodeNumber = mapping.Scene.Episode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (episodes.Any(v => v.SceneEpisodeNumber.HasValue && v.SceneSeasonNumber != 0))
|
|
||||||
{
|
|
||||||
ExtrapolateMappings(series, episodes, mappings);
|
|
||||||
}
|
|
||||||
|
|
||||||
_episodeService.UpdateEpisodes(episodes);
|
|
||||||
series.UseSceneNumbering = mappings.Any();
|
|
||||||
_seriesService.UpdateSeries(series);
|
|
||||||
|
|
||||||
_logger.Debug("XEM mapping updated for {0}", series);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.Error(ex, "Error updating scene numbering mappings for: " + series);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExtrapolateMappings(Series series, List<Episode> episodes, List<Model.XemSceneTvdbMapping> mappings)
|
|
||||||
{
|
|
||||||
var mappedEpisodes = episodes.Where(v => v.SeasonNumber != 0 && v.SceneEpisodeNumber.HasValue).ToList();
|
|
||||||
var mappedSeasons = new HashSet<int>(mappedEpisodes.Select(v => v.SeasonNumber).Distinct());
|
|
||||||
|
|
||||||
var sceneEpisodeMappings = mappings.ToLookup(v => v.Scene.Season)
|
|
||||||
.ToDictionary(v => v.Key, e => new HashSet<int>(e.Select(v => v.Scene.Episode)));
|
|
||||||
|
|
||||||
var firstTvdbEpisodeBySeason = mappings.ToLookup(v => v.Tvdb.Season)
|
|
||||||
.ToDictionary(v => v.Key, e => e.Min(v => v.Tvdb.Episode));
|
|
||||||
|
|
||||||
var lastSceneSeason = mappings.Select(v => v.Scene.Season).Max();
|
|
||||||
var lastTvdbSeason = mappings.Select(v => v.Tvdb.Season).Max();
|
|
||||||
|
|
||||||
// Mark all episodes not on the xem as unverified.
|
|
||||||
foreach (var episode in episodes)
|
|
||||||
{
|
|
||||||
if (episode.SeasonNumber == 0) continue;
|
|
||||||
if (episode.SceneEpisodeNumber.HasValue) continue;
|
|
||||||
|
|
||||||
if (mappedSeasons.Contains(episode.SeasonNumber))
|
|
||||||
{
|
|
||||||
// Mark if a mapping exists for an earlier episode in this season.
|
|
||||||
if (firstTvdbEpisodeBySeason[episode.SeasonNumber] <= episode.EpisodeNumber)
|
|
||||||
{
|
|
||||||
episode.UnverifiedSceneNumbering = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark if a mapping exists with a scene number to this episode.
|
|
||||||
if (sceneEpisodeMappings.ContainsKey(episode.SeasonNumber) &&
|
|
||||||
sceneEpisodeMappings[episode.SeasonNumber].Contains(episode.EpisodeNumber))
|
|
||||||
{
|
|
||||||
episode.UnverifiedSceneNumbering = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (lastSceneSeason != lastTvdbSeason && episode.SeasonNumber > lastTvdbSeason)
|
|
||||||
{
|
|
||||||
episode.UnverifiedSceneNumbering = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var episode in episodes)
|
|
||||||
{
|
|
||||||
if (episode.SeasonNumber == 0) continue;
|
|
||||||
if (episode.SceneEpisodeNumber.HasValue) continue;
|
|
||||||
if (episode.SeasonNumber < lastTvdbSeason) continue;
|
|
||||||
if (!episode.UnverifiedSceneNumbering) continue;
|
|
||||||
|
|
||||||
var seasonMappings = mappings.Where(v => v.Tvdb.Season == episode.SeasonNumber).ToList();
|
|
||||||
if (seasonMappings.Any(v => v.Tvdb.Episode >= episode.EpisodeNumber))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seasonMappings.Any())
|
|
||||||
{
|
|
||||||
var lastEpisodeMapping = seasonMappings.OrderBy(v => v.Tvdb.Episode).Last();
|
|
||||||
var lastSceneSeasonMapping = mappings.Where(v => v.Scene.Season == lastEpisodeMapping.Scene.Season).OrderBy(v => v.Scene.Episode).Last();
|
|
||||||
|
|
||||||
if (lastSceneSeasonMapping.Tvdb.Season == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var offset = episode.EpisodeNumber - lastEpisodeMapping.Tvdb.Episode;
|
|
||||||
|
|
||||||
episode.SceneSeasonNumber = lastEpisodeMapping.Scene.Season;
|
|
||||||
episode.SceneEpisodeNumber = lastEpisodeMapping.Scene.Episode + offset;
|
|
||||||
episode.SceneAbsoluteEpisodeNumber = lastEpisodeMapping.Scene.Absolute + offset;
|
|
||||||
}
|
|
||||||
else if (lastTvdbSeason != lastSceneSeason)
|
|
||||||
{
|
|
||||||
var offset = episode.SeasonNumber - lastTvdbSeason;
|
|
||||||
|
|
||||||
episode.SceneSeasonNumber = lastSceneSeason + offset;
|
|
||||||
episode.SceneEpisodeNumber = episode.EpisodeNumber;
|
|
||||||
// TODO: SceneAbsoluteEpisodeNumber.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateXemSeriesIds()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var ids = _xemProxy.GetXemSeriesIds();
|
|
||||||
|
|
||||||
if (ids.Any())
|
|
||||||
{
|
|
||||||
_cache.Update(ids.ToDictionary(v => v.ToString(), v => true));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cache.ExtendTTL();
|
|
||||||
_logger.Warn("Failed to update Xem series list.");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_cache.ExtendTTL();
|
|
||||||
_logger.Warn(ex, "Failed to update Xem series list.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SceneMapping> GetSceneMappings()
|
|
||||||
{
|
|
||||||
var mappings = _xemProxy.GetSceneTvdbNames();
|
|
||||||
|
|
||||||
return mappings.Where(m =>
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
|
|
||||||
if (int.TryParse(m.Title, out id))
|
|
||||||
{
|
|
||||||
_logger.Debug("Skipping all numeric name: {0} for {1}", m.Title, m.TvdbId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(SeriesUpdatedEvent message)
|
|
||||||
{
|
|
||||||
if (_cache.IsExpired(TimeSpan.FromHours(3)))
|
|
||||||
{
|
|
||||||
UpdateXemSeriesIds();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_cache.Count == 0)
|
|
||||||
{
|
|
||||||
_logger.Debug("Scene numbering is not available");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_cache.Find(message.Series.TvdbId.ToString()) && !message.Series.UseSceneNumbering)
|
|
||||||
{
|
|
||||||
_logger.Debug("Scene numbering is not available for {0} [{1}]", message.Series.Title, message.Series.TvdbId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PerformUpdate(message.Series);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(SeriesRefreshStartingEvent message)
|
|
||||||
{
|
|
||||||
if (message.ManualTrigger && _cache.IsExpired(TimeSpan.FromMinutes(1)))
|
|
||||||
{
|
|
||||||
UpdateXemSeriesIds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(127)]
|
||||||
|
public class remove_wombles : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Delete.FromTable("Indexers").Row(new { Implementation = "Wombles" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(128)]
|
||||||
|
public class remove_kickass : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Delete.FromTable("Indexers").Row(new { Implementation = "Kickass Torrents" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(129)]
|
||||||
|
public class add_parsed_movie_info_to_pending_release : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("PendingReleases").AddColumn("ParsedMovieInfo").AsString().Nullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(129)]
|
||||||
|
public class remove_kickass_again : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Delete.FromTable("Indexers").Row(new { Implementation = "KickassTorrents" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(127)]
|
||||||
|
public class remove_wombles_kickass : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Delete.FromTable("Indexers").Row(new { Implementation = "Wombles" });
|
||||||
|
Delete.FromTable("Indexers").Row(new { Implementation = "KickassTorrents" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(131)]
|
||||||
|
public class make_parsed_episode_info_nullable : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("PendingReleases").AlterColumn("ParsedEpisodeInfo").AsString().Nullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(132)]
|
||||||
|
public class rename_torrent_downloadstation : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Execute.Sql("UPDATE DownloadClients SET Implementation = 'TorrentDownloadStation' WHERE Implementation = 'DownloadStation';");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using FluentMigrator;
|
||||||
|
//using FluentMigrator.Expressions;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(133)]
|
||||||
|
public class add_minimumavailability : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
if (!this.Schema.Schema("dbo").Table("NetImport").Column("MinimumAvailability").Exists())
|
||||||
|
{
|
||||||
|
Alter.Table("NetImport").AddColumn("MinimumAvailability").AsInt32().WithDefaultValue(MovieStatusType.PreDB);
|
||||||
|
}
|
||||||
|
if (!this.Schema.Schema("dbo").Table("Movies").Column("MinimumAvailability").Exists())
|
||||||
|
{
|
||||||
|
Alter.Table("Movies").AddColumn("MinimumAvailability").AsInt32().WithDefaultValue(MovieStatusType.PreDB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user