Compare commits
118 Commits
curl-upgra
...
v2.0.0.468
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5613ab05e0 | ||
|
|
372442af2c | ||
|
|
28c45f941b | ||
|
|
ea1616586f | ||
|
|
e48600da42 | ||
|
|
5d9d2e684e | ||
|
|
2e392e0f5e | ||
|
|
83370ddbbb | ||
|
|
c20b152c28 | ||
|
|
bf5067466d | ||
|
|
ec7f749541 | ||
|
|
56ecbf4a31 | ||
|
|
1b39911135 | ||
|
|
6aaefae2d5 | ||
|
|
db9d601115 | ||
|
|
e7331539f0 | ||
|
|
58bd57bed6 | ||
|
|
7a58082cd7 | ||
|
|
2e08f195e4 | ||
|
|
a1a5e29c3e | ||
|
|
5033886b90 | ||
|
|
29419d6575 | ||
|
|
3c22f68f5a | ||
|
|
a0d98951aa | ||
|
|
70f7404499 | ||
|
|
abd70f5381 | ||
|
|
878e973081 | ||
|
|
2bf3b9e7dd | ||
|
|
2326db0dea | ||
|
|
3590fedeaf | ||
|
|
f4866cae69 | ||
|
|
149d191f62 | ||
|
|
bb9bd63382 | ||
|
|
34fda24124 | ||
|
|
c8d10829a0 | ||
|
|
ae2bdb757a | ||
|
|
714ad075fc | ||
|
|
87a05df2fd | ||
|
|
f3263efa52 | ||
|
|
1cad11d207 | ||
|
|
781df8b20a | ||
|
|
ebcce05588 | ||
|
|
bbf2134fe1 | ||
|
|
081c5fc332 | ||
|
|
47915d5e05 | ||
|
|
47e221d9a0 | ||
|
|
bf485f6f2c | ||
|
|
b365d8a537 | ||
|
|
fee8da88a6 | ||
|
|
cc0dbf1af4 | ||
|
|
836131ebb1 | ||
|
|
9a870a3709 | ||
|
|
afe05189da | ||
|
|
2abaef16f1 | ||
|
|
37d5a3f2ad | ||
|
|
be4d70e3a9 | ||
|
|
79043f2c64 | ||
|
|
1dab0aee6a | ||
|
|
9b162f2d5e | ||
|
|
5518cf5362 | ||
|
|
f7e3d9b4c2 | ||
|
|
6d9a952bd1 | ||
|
|
3501e33722 | ||
|
|
fa89d33900 | ||
|
|
0af48fb2e8 | ||
|
|
7e9f0d0522 | ||
|
|
1f8bd8e1e9 | ||
|
|
2855090005 | ||
|
|
060b9f6fd1 | ||
|
|
9304547c95 | ||
|
|
c56c83e169 | ||
|
|
c6fa883662 | ||
|
|
4043d07ab1 | ||
|
|
8af3348e7f | ||
|
|
49d0d4c357 | ||
|
|
47b1157b96 | ||
|
|
adc79f0eba | ||
|
|
6b117427f8 | ||
|
|
7884dd9a39 | ||
|
|
45d8b1e2ad | ||
|
|
cf306f4aba | ||
|
|
d7aa23388e | ||
|
|
82a99b7f80 | ||
|
|
2f6d9e191e | ||
|
|
0782a15979 | ||
|
|
ddd119a4eb | ||
|
|
d4788b4cae | ||
|
|
812999423b | ||
|
|
657730f4d2 | ||
|
|
0255eb3aca | ||
|
|
fc15daa37e | ||
|
|
10264a5bfb | ||
|
|
ef044f1ff5 | ||
|
|
ef03e9e9a7 | ||
|
|
3bd7c09acf | ||
|
|
fbd2f8dea4 | ||
|
|
15e07f72d4 | ||
|
|
f25bfe9d28 | ||
|
|
d5e720c404 | ||
|
|
c9a8ebc2e6 | ||
|
|
5e7e816c03 | ||
|
|
f56076a135 | ||
|
|
54dd527f01 | ||
|
|
c6eb19c04d | ||
|
|
38b65ba27d | ||
|
|
a2a49ce934 | ||
|
|
047d5a4388 | ||
|
|
aae69ff49a | ||
|
|
da451cfe03 | ||
|
|
01e2f4e7e5 | ||
|
|
8aacc61c50 | ||
|
|
111e401a2c | ||
|
|
8d91f18823 | ||
|
|
cea6469ab8 | ||
|
|
ced7a7dce2 | ||
|
|
20a2cfe260 | ||
|
|
5b0a285b84 | ||
|
|
68ea8a551c |
BIN
Logo/1024.png
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 55 KiB |
BIN
Logo/128.png
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 3.4 KiB |
BIN
Logo/16.png
|
Before Width: | Height: | Size: 707 B After Width: | Height: | Size: 490 B |
BIN
Logo/256.png
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 7.2 KiB |
BIN
Logo/32.png
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
Logo/400.png
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 15 KiB |
BIN
Logo/48.png
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
Logo/512.png
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 21 KiB |
BIN
Logo/64.png
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
Logo/800.png
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 34 KiB |
BIN
Logo/96-Outline-White.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
52
README.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Sonarr
|
||||
|
||||
Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new episodes of your favorite shows and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.
|
||||
|
||||
## Major Features Include:
|
||||
|
||||
* Support for major platforms: Windows, Linux, macOS, Raspberry Pi, etc.
|
||||
* Automatically detects new episodes
|
||||
* Can scan your existing library and download any missing episodes
|
||||
* Can watch for better quality of the episodes you already have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
|
||||
* Automatic failed download handling will try another release if one fails
|
||||
* Manual search so you can pick any release or to see why a release was not downloaded automatically
|
||||
* Fully configurable episode renaming
|
||||
* Full integration with SABnzbd and NZBGet
|
||||
* Full integration with Kodi, Plex (notification, library update, metadata)
|
||||
* Full support for specials and multi-episode releases
|
||||
* And a beautiful UI
|
||||
|
||||
## Configuring Development Environment:
|
||||
|
||||
### Requirements
|
||||
|
||||
* Visual Studio 2015 (https://www.visualstudio.com/vs/)
|
||||
* [Git](https://git-scm.com/downloads)
|
||||
* [NodeJS](https://nodejs.org/en/download/)
|
||||
|
||||
### Setup
|
||||
|
||||
* Make sure all the required software mentioned above are installed.
|
||||
* Clone the repository into your development machine. [*info*](https://help.github.com/articles/working-with-repositories)
|
||||
* Grab the submodules `git submodule init && git submodule update`
|
||||
* Install the required Node Packages `npm install`
|
||||
* Start gulp to monitor your dev environment for any changes that need post processing using `npm start` command.
|
||||
|
||||
*Please note gulp must be running at all times while you are working with Sonarr client source files.*
|
||||
|
||||
### Development
|
||||
|
||||
* Open `NzbDrone.sln` in Visual Studio
|
||||
* Make sure `NzbDrone.Console` is set as the startup project
|
||||
|
||||
### License
|
||||
|
||||
* [GNU GPL v3](http://www.gnu.org/licenses/gpl.html)
|
||||
* Copyright 2010-2017
|
||||
|
||||
### Sponsors
|
||||
|
||||
* [JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools
|
||||
* [ReSharper](http://www.jetbrains.com/resharper/)
|
||||
* [WebStorm](http://www.jetbrains.com/webstorm/)
|
||||
* [TeamCity](http://www.jetbrains.com/teamcity/)
|
||||
53
readme.md
@@ -1,53 +0,0 @@
|
||||
# Sonarr #
|
||||
|
||||
|
||||
Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS feeds for new episodes of your favorite shows and will grab, sort and rename them. It can also be configured to automatically upgrade the quality of files already downloaded when a better quality format becomes available.
|
||||
|
||||
## Major Features Include: ##
|
||||
|
||||
* Support for major platforms: Windows, Linux, OSX, Raspberry Pi, etc.
|
||||
* Automatically detects new episodes
|
||||
* Can scan your existing library and download any missing episodes
|
||||
* Can watch for better quality of the episodes you already have and do an automatic upgrade. *eg. from DVD to Blu-Ray*
|
||||
* Automatic failed download handling will try another release if one fails
|
||||
* Manual search so you can pick any release or to see why a release was not downloaded automatically
|
||||
* Fully configurable episode renaming
|
||||
* Full integration with SABNzbd and NzbGet
|
||||
* Full integration with XBMC, Plex (notification, library update, metadata)
|
||||
* Full support for specials and multi-episode releases
|
||||
* And a beautiful UI
|
||||
|
||||
|
||||
## Configuring Development Environment: ##
|
||||
|
||||
### Requirements ###
|
||||
- Visual Studio 2015 [Free Community Edition](https://www.visualstudio.com/en-us/products/visual-studio-community-vs.aspx)
|
||||
- [Git](http://git-scm.com/downloads)
|
||||
- [NodeJS](http://nodejs.org/download/)
|
||||
|
||||
### Setup ###
|
||||
|
||||
- Make sure all the required software mentioned above are installed.
|
||||
- Clone the repository into your development machine. [*info*](https://help.github.com/articles/working-with-repositories)
|
||||
- Grab the submodules `git submodule init && git submodule update`
|
||||
- install the required Node Packages `npm install`
|
||||
- start gulp to monitor your dev environment for any changes that need post processing using `npm start` command.
|
||||
|
||||
*Please note gulp must be running at all times while you are working with Sonarr client source files.*
|
||||
|
||||
|
||||
### Development ###
|
||||
- Open `NzbDrone.sln` in Visual Studio
|
||||
- Make sure `NzbDrone.Console` is set as the startup project
|
||||
|
||||
|
||||
### License ###
|
||||
* [GNU GPL v3](http://www.gnu.org/licenses/gpl.html)
|
||||
Copyright 2010-2016
|
||||
|
||||
|
||||
### Sponsors ###
|
||||
- [JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools
|
||||
- [ReSharper](http://www.jetbrains.com/resharper/)
|
||||
- [WebStorm](http://www.jetbrains.com/webstorm/)
|
||||
- [TeamCity](http://www.jetbrains.com/teamcity/)
|
||||
@@ -52,8 +52,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.4.1\lib\net40\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\NLog.4.4.3\lib\net40\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="NLog" version="4.4.1" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.3" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -42,17 +42,17 @@
|
||||
<HintPath>..\packages\NBuilder.4.0.0\lib\net40\FizzWare.NBuilder.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="FluentAssertions, Version=4.19.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.19.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="FluentAssertions.Core, Version=4.19.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.19.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="Moq, Version=4.2.1510.2205, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=3.6.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.6.0\lib\net40\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
||||
<package id="FluentAssertions" version="4.19.0" targetFramework="net40" />
|
||||
<package id="Moq" version="4.0.10827" />
|
||||
<package id="NBuilder" version="4.0.0" targetFramework="net40" />
|
||||
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
||||
<package id="NUnit" version="3.6.0" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -37,6 +37,7 @@ namespace NzbDrone.Api.Calendar
|
||||
var end = DateTime.Today.AddDays(futureDays);
|
||||
var unmonitored = false;
|
||||
var premiersOnly = false;
|
||||
var asAllDay = false;
|
||||
var tags = new List<int>();
|
||||
|
||||
// TODO: Remove start/end parameters in v3, they don't work well for iCal
|
||||
@@ -46,6 +47,7 @@ namespace NzbDrone.Api.Calendar
|
||||
var queryFutureDays = Request.Query.FutureDays;
|
||||
var queryUnmonitored = Request.Query.Unmonitored;
|
||||
var queryPremiersOnly = Request.Query.PremiersOnly;
|
||||
var queryAsAllDay = Request.Query.AsAllDay;
|
||||
var queryTags = Request.Query.Tags;
|
||||
|
||||
if (queryStart.HasValue) start = DateTime.Parse(queryStart.Value);
|
||||
@@ -73,6 +75,11 @@ namespace NzbDrone.Api.Calendar
|
||||
premiersOnly = bool.Parse(queryPremiersOnly.Value);
|
||||
}
|
||||
|
||||
if (queryAsAllDay.HasValue)
|
||||
{
|
||||
asAllDay = bool.Parse(queryAsAllDay.Value);
|
||||
}
|
||||
|
||||
if (queryTags.HasValue)
|
||||
{
|
||||
var tagInput = (string)queryTags.Value.ToString();
|
||||
@@ -102,11 +109,19 @@ namespace NzbDrone.Api.Calendar
|
||||
var occurrence = calendar.Create<Event>();
|
||||
occurrence.Uid = "NzbDrone_episode_" + episode.Id;
|
||||
occurrence.Status = episode.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 };
|
||||
|
||||
if (asAllDay)
|
||||
{
|
||||
occurrence.Start = new CalDateTime(episode.AirDateUtc.Value) { HasTime = false };
|
||||
}
|
||||
else
|
||||
{
|
||||
occurrence.Start = new CalDateTime(episode.AirDateUtc.Value) { HasTime = true };
|
||||
occurrence.End = new CalDateTime(episode.AirDateUtc.Value.AddMinutes(episode.Series.Runtime)) { HasTime = true };
|
||||
}
|
||||
|
||||
switch (episode.Series.SeriesType)
|
||||
{
|
||||
case SeriesTypes.Daily:
|
||||
|
||||
@@ -73,14 +73,14 @@ namespace NzbDrone.Api.ClientSchema
|
||||
|
||||
if (propertyInfo.PropertyType == typeof(int))
|
||||
{
|
||||
var value = Convert.ToInt32(field.Value);
|
||||
propertyInfo.SetValue(target, value, null);
|
||||
var value = field.Value.ToString().ParseInt32();
|
||||
propertyInfo.SetValue(target, value ?? 0, null);
|
||||
}
|
||||
|
||||
else if (propertyInfo.PropertyType == typeof(long))
|
||||
{
|
||||
var value = Convert.ToInt64(field.Value);
|
||||
propertyInfo.SetValue(target, value, null);
|
||||
var value = field.Value.ToString().ParseInt64();
|
||||
propertyInfo.SetValue(target, value ?? 0, null);
|
||||
}
|
||||
|
||||
else if (propertyInfo.PropertyType == typeof(int?))
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace NzbDrone.Api.Config
|
||||
|
||||
public bool SkipFreeSpaceCheckWhenImporting { get; set; }
|
||||
public bool CopyUsingHardlinks { get; set; }
|
||||
public bool ImportExtraFiles { get; set; }
|
||||
public string ExtraFileExtensions { get; set; }
|
||||
public bool EnableMediaInfo { get; set; }
|
||||
}
|
||||
@@ -44,6 +45,7 @@ namespace NzbDrone.Api.Config
|
||||
|
||||
SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting,
|
||||
CopyUsingHardlinks = model.CopyUsingHardlinks,
|
||||
ImportExtraFiles = model.ImportExtraFiles,
|
||||
ExtraFileExtensions = model.ExtraFileExtensions,
|
||||
EnableMediaInfo = model.EnableMediaInfo
|
||||
};
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore.Events;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
@@ -16,6 +18,7 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||
IHandle<EpisodeFileAddedEvent>
|
||||
{
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IRecycleBinProvider _recycleBinProvider;
|
||||
private readonly ISeriesService _seriesService;
|
||||
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
@@ -23,6 +26,7 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||
|
||||
public EpisodeFileModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
IMediaFileService mediaFileService,
|
||||
IDiskProvider diskProvider,
|
||||
IRecycleBinProvider recycleBinProvider,
|
||||
ISeriesService seriesService,
|
||||
IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
@@ -30,6 +34,7 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||
: base(signalRBroadcaster)
|
||||
{
|
||||
_mediaFileService = mediaFileService;
|
||||
_diskProvider = diskProvider;
|
||||
_recycleBinProvider = recycleBinProvider;
|
||||
_seriesService = seriesService;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
@@ -74,9 +79,10 @@ namespace NzbDrone.Api.EpisodeFiles
|
||||
var episodeFile = _mediaFileService.Get(id);
|
||||
var series = _seriesService.GetSeries(episodeFile.SeriesId);
|
||||
var fullPath = Path.Combine(series.Path, episodeFile.RelativePath);
|
||||
var subfolder = _diskProvider.GetParentFolder(series.Path).GetRelativePath(_diskProvider.GetParentFolder(fullPath));
|
||||
|
||||
_logger.Info("Deleting episode file: {0}", fullPath);
|
||||
_recycleBinProvider.DeleteFile(fullPath);
|
||||
_recycleBinProvider.DeleteFile(fullPath, subfolder);
|
||||
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.Manual);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
||||
context.Items["ApiRequestStartTime"] = DateTime.UtcNow;
|
||||
|
||||
var reqPath = GetRequestPathAndQuery(context.Request);
|
||||
|
||||
|
||||
_loggerHttp.Trace("Req: {0} [{1}] {2}", id, context.Request.Method, reqPath);
|
||||
|
||||
return null;
|
||||
@@ -80,7 +80,7 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
||||
{
|
||||
if (request.Url.Query.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
return string.Concat(request.Url.Path, "?", request.Url.Query);
|
||||
return string.Concat(request.Url.Path, request.Url.Query);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -88,4 +88,4 @@ namespace NzbDrone.Api.Extensions.Pipelines
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using Nancy;
|
||||
@@ -38,7 +38,7 @@ namespace NzbDrone.Api.Frontend.Mappers
|
||||
if (_diskProvider.FileExists(filePath, _caseSensitive))
|
||||
{
|
||||
var response = new StreamResponse(() => GetContentStream(filePath), MimeTypes.GetMimeType(filePath));
|
||||
return response;
|
||||
return new MaterialisingResponse(response);
|
||||
}
|
||||
|
||||
_logger.Warn("File {0} not found", filePath);
|
||||
|
||||
@@ -41,20 +41,17 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="antlr.runtime, Version=2.7.6.2, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\antlr.runtime.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Ical.Net.2.2.32\lib\net40\antlr.runtime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentValidation, Version=6.2.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentValidation.6.2.1.0\lib\portable-net40+sl50+wp80+win8+wpa81\FluentValidation.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ical.Net, Version=2.1.0.30332, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\Ical.Net.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="Ical.Net, Version=2.1.0.18776, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ical.Net.2.2.32\lib\net40\Ical.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Ical.Net.Collections, Version=2.1.0.30331, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\Ical.Net.Collections.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="Ical.Net.Collections, Version=2.1.0.18775, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ical.Net.2.2.32\lib\net40\Ical.Net.Collections.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Nancy, Version=1.4.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Nancy.1.4.3\lib\net40\Nancy.dll</HintPath>
|
||||
@@ -73,12 +70,10 @@
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.4.1\lib\net40\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\NLog.4.4.3\lib\net40\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NodaTime, Version=1.3.0.0, Culture=neutral, PublicKeyToken=4226afe0d9b296d1, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ical.Net.2.2.25\lib\net40\NodaTime.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Ical.Net.2.2.32\lib\net40\NodaTime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace NzbDrone.Api.Series
|
||||
|
||||
public static List<Season> ToModel(this IEnumerable<SeasonResource> resources)
|
||||
{
|
||||
return resources.Select(ToModel).ToList();
|
||||
return resources?.Select(ToModel).ToList() ?? new List<Season>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,14 @@ namespace NzbDrone.Api.Series
|
||||
|
||||
{
|
||||
private readonly ISeriesService _seriesService;
|
||||
private readonly IAddSeriesService _addSeriesService;
|
||||
private readonly ISeriesStatisticsService _seriesStatisticsService;
|
||||
private readonly ISceneMappingService _sceneMappingService;
|
||||
private readonly IMapCoversToLocal _coverMapper;
|
||||
|
||||
public SeriesModule(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
ISeriesService seriesService,
|
||||
IAddSeriesService addSeriesService,
|
||||
ISeriesStatisticsService seriesStatisticsService,
|
||||
ISceneMappingService sceneMappingService,
|
||||
IMapCoversToLocal coverMapper,
|
||||
@@ -48,6 +50,7 @@ namespace NzbDrone.Api.Series
|
||||
: base(signalRBroadcaster)
|
||||
{
|
||||
_seriesService = seriesService;
|
||||
_addSeriesService = addSeriesService;
|
||||
_seriesStatisticsService = seriesStatisticsService;
|
||||
_sceneMappingService = sceneMappingService;
|
||||
|
||||
@@ -74,7 +77,6 @@ namespace NzbDrone.Api.Series
|
||||
|
||||
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
|
||||
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
|
||||
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
||||
PostValidator.RuleFor(s => s.TvdbId).GreaterThan(0).SetValidator(seriesExistsValidator);
|
||||
|
||||
PutValidator.RuleFor(s => s.Path).IsValidPath();
|
||||
@@ -114,7 +116,7 @@ namespace NzbDrone.Api.Series
|
||||
{
|
||||
var model = seriesResource.ToModel();
|
||||
|
||||
return _seriesService.AddSeries(model).Id;
|
||||
return _addSeriesService.AddSeries(model).Id;
|
||||
}
|
||||
|
||||
private void UpdateSeries(SeriesResource seriesResource)
|
||||
|
||||
@@ -207,19 +207,9 @@ namespace NzbDrone.Api.Series
|
||||
|
||||
public static Core.Tv.Series ToModel(this SeriesResource resource, Core.Tv.Series series)
|
||||
{
|
||||
series.TvdbId = resource.TvdbId;
|
||||
var updatedSeries = resource.ToModel();
|
||||
|
||||
series.Seasons = resource.Seasons.ToModel();
|
||||
series.Path = resource.Path;
|
||||
series.ProfileId = resource.ProfileId;
|
||||
|
||||
series.SeasonFolder = resource.SeasonFolder;
|
||||
series.Monitored = resource.Monitored;
|
||||
|
||||
series.SeriesType = resource.SeriesType;
|
||||
series.RootFolderPath = resource.RootFolderPath;
|
||||
series.Tags = resource.Tags;
|
||||
series.AddOptions = resource.AddOptions;
|
||||
series.ApplyChanges(updatedSeries);
|
||||
|
||||
return series;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentValidation" version="6.2.1.0" targetFramework="net40" />
|
||||
<package id="Ical.Net" version="2.2.25" targetFramework="net40" />
|
||||
<package id="Ical.Net" version="2.2.32" targetFramework="net40" />
|
||||
<package id="Nancy" version="1.4.3" targetFramework="net40" />
|
||||
<package id="Nancy.Authentication.Basic" version="1.4.1" targetFramework="net40" />
|
||||
<package id="Nancy.Authentication.Forms" version="1.4.1" targetFramework="net40" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.1" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.3" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -41,21 +41,17 @@
|
||||
<HintPath>..\packages\NBuilder.4.0.0\lib\net40\FizzWare.NBuilder.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="FluentAssertions, Version=4.19.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.19.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="FluentAssertions.Core, Version=4.19.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.19.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.4.1\lib\net40\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\NLog.4.4.3\lib\net40\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="nunit.framework, Version=3.6.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.6.0\lib\net40\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
||||
<package id="FluentAssertions" version="4.19.0" targetFramework="net40" />
|
||||
<package id="Moq" version="4.0.10827" />
|
||||
<package id="NBuilder" version="4.0.0" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.1" targetFramework="net40" />
|
||||
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.3" targetFramework="net40" />
|
||||
<package id="NUnit" version="3.6.0" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -38,21 +38,17 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="FluentAssertions, Version=4.19.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.19.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="FluentAssertions.Core, Version=4.19.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.19.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.4.1\lib\net40\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\NLog.4.4.3\lib\net40\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="nunit.framework, Version=3.6.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.6.0\lib\net40\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -62,13 +58,11 @@
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="WebDriver, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Selenium.WebDriver.3.0.1\lib\net40\WebDriver.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="WebDriver, Version=3.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Selenium.WebDriver.3.2.0\lib\net40\WebDriver.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebDriver.Support, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Selenium.Support.3.0.1\lib\net40\WebDriver.Support.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="WebDriver.Support, Version=3.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Selenium.Support.3.2.0\lib\net40\WebDriver.Support.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.1" targetFramework="net40" />
|
||||
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
||||
<package id="Selenium.Support" version="3.0.1" targetFramework="net40" />
|
||||
<package id="Selenium.WebDriver" version="3.0.1" targetFramework="net40" />
|
||||
<package id="FluentAssertions" version="4.19.0" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.3" targetFramework="net40" />
|
||||
<package id="NUnit" version="3.6.0" targetFramework="net40" />
|
||||
<package id="Selenium.Support" version="3.2.0" targetFramework="net40" />
|
||||
<package id="Selenium.WebDriver" version="3.2.0" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -16,6 +16,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
private readonly string _targetPath = @"C:\target\my.video.mkv".AsOsAgnostic();
|
||||
private readonly string _backupPath = @"C:\source\my.video.mkv.backup~".AsOsAgnostic();
|
||||
private readonly string _tempTargetPath = @"C:\target\my.video.mkv.partial~".AsOsAgnostic();
|
||||
private readonly string _nfsFile = ".nfs01231232";
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
@@ -642,6 +643,21 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
VerifyCopyFolder(source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFolder_should_ignore_nfs_temp_file()
|
||||
{
|
||||
WithRealDiskProvider();
|
||||
|
||||
var source = GetFilledTempFolder();
|
||||
|
||||
File.WriteAllText(Path.Combine(source.FullName, _nfsFile), "SubFile1");
|
||||
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.TransferFolder(source.FullName, destination.FullName, TransferMode.Copy);
|
||||
|
||||
File.Exists(Path.Combine(destination.FullName, _nfsFile)).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MoveFolder_should_move_folder()
|
||||
@@ -704,6 +720,26 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
destination.GetFileSystemInfos().Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MirrorFolder_should_not_remove_nfs_files()
|
||||
{
|
||||
WithRealDiskProvider();
|
||||
|
||||
var original = GetFilledTempFolder();
|
||||
var source = new DirectoryInfo(GetTempFilePath());
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
source.Create();
|
||||
Subject.TransferFolder(original.FullName, destination.FullName, TransferMode.Copy);
|
||||
|
||||
File.WriteAllText(Path.Combine(destination.FullName, _nfsFile), "SubFile1");
|
||||
|
||||
var count = Subject.MirrorFolder(source.FullName, destination.FullName);
|
||||
|
||||
count.Should().Equals(0);
|
||||
destination.GetFileSystemInfos().Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MirrorFolder_should_add_new_files()
|
||||
{
|
||||
@@ -721,6 +757,24 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
VerifyCopyFolder(original.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MirrorFolder_should_ignore_nfs_temp_file()
|
||||
{
|
||||
WithRealDiskProvider();
|
||||
|
||||
var source = GetFilledTempFolder();
|
||||
|
||||
File.WriteAllText(Path.Combine(source.FullName, _nfsFile), "SubFile1");
|
||||
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
var count = Subject.MirrorFolder(source.FullName, destination.FullName);
|
||||
|
||||
count.Should().Equals(3);
|
||||
|
||||
File.Exists(Path.Combine(destination.FullName, _nfsFile)).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MirrorFolder_should_not_touch_equivalent_files()
|
||||
{
|
||||
|
||||
21
src/NzbDrone.Common.Test/HashUtilFixture.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace NzbDrone.Common.Test
|
||||
{
|
||||
[TestFixture]
|
||||
public class HashUtilFixture
|
||||
{
|
||||
[Test]
|
||||
public void should_create_anon_id()
|
||||
{
|
||||
HashUtil.AnonymousToken().Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_create_the_same_id()
|
||||
{
|
||||
HashUtil.AnonymousToken().Should().Be(HashUtil.AnonymousToken());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System;
|
||||
using System.Text;
|
||||
using NzbDrone.Common.Http;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Common.Test.Http
|
||||
{
|
||||
@@ -36,5 +37,17 @@ namespace NzbDrone.Common.Test.Http
|
||||
Action action = () => httpheader.GetEncodingFromContentType();
|
||||
action.ShouldThrow<ArgumentException>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_cookie_with_trailing_semi_colon()
|
||||
{
|
||||
var cookies = HttpHeader.ParseCookies("uid=123456; pass=123456b2f3abcde42ac3a123f3f1fc9f;");
|
||||
|
||||
cookies.Count.Should().Be(2);
|
||||
cookies.First().Key.Should().Be("uid");
|
||||
cookies.First().Value.Should().Be("123456");
|
||||
cookies.Last().Key.Should().Be("pass");
|
||||
cookies.Last().Value.Should().Be("123456b2f3abcde42ac3a123f3f1fc9f");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,21 +37,17 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentAssertions, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="FluentAssertions, Version=4.19.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.19.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions.Core, Version=4.18.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.18.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="FluentAssertions.Core, Version=4.19.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.4.19.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.4.1\lib\net40\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\NLog.4.4.3\lib\net40\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.5.0\lib\net40\nunit.framework.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="nunit.framework, Version=3.6.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NUnit.3.6.0\lib\net40\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
@@ -84,6 +80,7 @@
|
||||
<Compile Include="ExtensionTests\IEnumerableExtensionTests\ExceptByFixture.cs" />
|
||||
<Compile Include="ExtensionTests\IEnumerableExtensionTests\IntersectByFixture.cs" />
|
||||
<Compile Include="ExtensionTests\Int64ExtensionFixture.cs" />
|
||||
<Compile Include="HashUtilFixture.cs" />
|
||||
<Compile Include="Http\HttpClientFixture.cs" />
|
||||
<Compile Include="Http\HttpHeaderFixture.cs" />
|
||||
<Compile Include="Http\HttpRequestBuilderFixture.cs" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentAssertions" version="4.18.0" targetFramework="net40" />
|
||||
<package id="FluentAssertions" version="4.19.0" targetFramework="net40" />
|
||||
<package id="Moq" version="4.0.10827" />
|
||||
<package id="NLog" version="4.4.1" targetFramework="net40" />
|
||||
<package id="NUnit" version="3.5.0" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.3" targetFramework="net40" />
|
||||
<package id="NUnit" version="3.6.0" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -64,11 +64,15 @@ namespace NzbDrone.Common.Disk
|
||||
|
||||
foreach (var subDir in _diskProvider.GetDirectoryInfos(sourcePath))
|
||||
{
|
||||
if (ShouldIgnore(subDir)) continue;
|
||||
|
||||
result &= TransferFolder(subDir.FullName, Path.Combine(targetPath, subDir.Name), mode, verificationMode);
|
||||
}
|
||||
|
||||
foreach (var sourceFile in _diskProvider.GetFileInfos(sourcePath))
|
||||
{
|
||||
if (ShouldIgnore(sourceFile)) continue;
|
||||
|
||||
var destFile = Path.Combine(targetPath, sourceFile.Name);
|
||||
|
||||
result &= TransferFile(sourceFile.FullName, destFile, mode, true, verificationMode);
|
||||
@@ -101,11 +105,15 @@ namespace NzbDrone.Common.Disk
|
||||
|
||||
foreach (var subDir in targetFolders.Where(v => !sourceFolders.Any(d => d.Name == v.Name)))
|
||||
{
|
||||
if (ShouldIgnore(subDir)) continue;
|
||||
|
||||
_diskProvider.DeleteFolder(subDir.FullName, true);
|
||||
}
|
||||
|
||||
foreach (var subDir in sourceFolders)
|
||||
{
|
||||
if (ShouldIgnore(subDir)) continue;
|
||||
|
||||
filesCopied += MirrorFolder(subDir.FullName, Path.Combine(targetPath, subDir.Name));
|
||||
}
|
||||
|
||||
@@ -114,11 +122,15 @@ namespace NzbDrone.Common.Disk
|
||||
|
||||
foreach (var targetFile in targetFiles.Where(v => !sourceFiles.Any(d => d.Name == v.Name)))
|
||||
{
|
||||
if (ShouldIgnore(targetFile)) continue;
|
||||
|
||||
_diskProvider.DeleteFile(targetFile.FullName);
|
||||
}
|
||||
|
||||
foreach (var sourceFile in sourceFiles)
|
||||
{
|
||||
if (ShouldIgnore(sourceFile)) continue;
|
||||
|
||||
var targetFile = Path.Combine(targetPath, sourceFile.Name);
|
||||
|
||||
if (CompareFiles(sourceFile.FullName, targetFile))
|
||||
@@ -564,5 +576,27 @@ namespace NzbDrone.Common.Disk
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ShouldIgnore(DirectoryInfo folder)
|
||||
{
|
||||
if (folder.Name.StartsWith(".nfs"))
|
||||
{
|
||||
_logger.Trace("Ignoring folder {0}", folder.FullName);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool ShouldIgnore(FileInfo file)
|
||||
{
|
||||
if (file.Name.StartsWith(".nfs"))
|
||||
{
|
||||
_logger.Trace("Ignoring file {0}", file.FullName);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,19 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||
public static bool IsMono => Platform == PlatformType.Mono;
|
||||
public static bool IsDotNet => Platform == PlatformType.DotNet;
|
||||
|
||||
public static string PlatformName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDotNet)
|
||||
{
|
||||
return ".NET";
|
||||
}
|
||||
|
||||
return "Mono";
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Version Version { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ using System;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class Base64Extentions
|
||||
public static class Base64Extensions
|
||||
{
|
||||
public static string ToBase64(this byte[] bytes)
|
||||
{
|
||||
@@ -14,4 +14,4 @@ namespace NzbDrone.Common.Extensions
|
||||
return BitConverter.GetBytes(input).ToBase64();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,8 @@ namespace NzbDrone.Common.Extensions
|
||||
|
||||
public static Dictionary<T1, T2> Merge<T1, T2>(this Dictionary<T1, T2> first, Dictionary<T1, T2> second)
|
||||
{
|
||||
if (first == null) throw new ArgumentNullException("first");
|
||||
if (second == null) throw new ArgumentNullException("second");
|
||||
if (first == null) throw new ArgumentNullException(nameof(first));
|
||||
if (second == null) throw new ArgumentNullException(nameof(second));
|
||||
|
||||
var merged = new Dictionary<T1, T2>();
|
||||
first.ToList().ForEach(kv => merged[kv.Key] = kv.Value);
|
||||
|
||||
@@ -5,11 +5,11 @@ using System.Xml.Linq;
|
||||
|
||||
namespace NzbDrone.Common.Extensions
|
||||
{
|
||||
public static class XmlExtentions
|
||||
public static class XmlExtensions
|
||||
{
|
||||
public static IEnumerable<XElement> FindDecendants(this XContainer container, string localName)
|
||||
{
|
||||
return container.Descendants().Where(c => c.Name.LocalName.Equals(localName, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,13 @@ namespace NzbDrone.Common
|
||||
}
|
||||
}
|
||||
}
|
||||
return string.Format("{0:x8}", mCrc);
|
||||
return $"{mCrc:x8}";
|
||||
}
|
||||
|
||||
public static string AnonymousToken()
|
||||
{
|
||||
var seed = $"{Environment.ProcessorCount}_{Environment.OSVersion.Platform}_{Environment.MachineName}_{Environment.UserName}";
|
||||
return HashUtil.CalculateCrc(seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
@@ -169,7 +169,7 @@ namespace NzbDrone.Common.Http
|
||||
|
||||
public static List<KeyValuePair<string, string>> ParseCookies(string cookies)
|
||||
{
|
||||
return cookies.Split(';')
|
||||
return cookies.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(v => v.Trim().Split('='))
|
||||
.Select(v => new KeyValuePair<string, string>(v[0], v[1]))
|
||||
.ToList();
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace NzbDrone.Common.Http
|
||||
public class JsonRpcRequestBuilder : HttpRequestBuilder
|
||||
{
|
||||
public static HttpAccept JsonRpcHttpAccept = new HttpAccept("application/json-rpc, application/json");
|
||||
public static string JsonRpcContentType = "application/json-rpc";
|
||||
public static string JsonRpcContentType = "application/json";
|
||||
|
||||
public string JsonMethod { get; private set; }
|
||||
public List<object> JsonParameters { get; private set; }
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using SharpRaven.Data;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation.Sentry
|
||||
@@ -7,7 +6,7 @@ namespace NzbDrone.Common.Instrumentation.Sentry
|
||||
{
|
||||
public SentryUser Create()
|
||||
{
|
||||
return new SentryUser(Environment.MachineName);
|
||||
return new SentryUser(HashUtil.AnonymousToken());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,13 +37,13 @@ namespace NzbDrone.Common.Instrumentation.Sentry
|
||||
{
|
||||
Compression = true,
|
||||
Environment = RuntimeInfo.IsProduction ? "production" : "development",
|
||||
Release = BuildInfo.Release
|
||||
Release = BuildInfo.Release,
|
||||
ErrorOnCapture = OnError
|
||||
};
|
||||
|
||||
_client.ErrorOnCapture = OnError;
|
||||
|
||||
_client.Tags.Add("osfamily", OsInfo.Os.ToString());
|
||||
_client.Tags.Add("runtime", PlatformInfo.Platform.ToString().ToLower());
|
||||
_client.Tags.Add("runtime", PlatformInfo.PlatformName);
|
||||
_client.Tags.Add("culture", Thread.CurrentThread.CurrentCulture.Name);
|
||||
_client.Tags.Add("branch", BuildInfo.Branch);
|
||||
_client.Tags.Add("version", BuildInfo.Version.ToString());
|
||||
@@ -135,10 +135,14 @@ namespace NzbDrone.Common.Instrumentation.Sentry
|
||||
sentryEvent.Fingerprint.Add(logEvent.Exception.GetType().FullName);
|
||||
}
|
||||
|
||||
var osName = Environment.GetEnvironmentVariable("OS_NAME");
|
||||
var osVersion = Environment.GetEnvironmentVariable("OS_VERSION");
|
||||
var runTimeVersion = Environment.GetEnvironmentVariable("RUNTIME_VERSION");
|
||||
|
||||
sentryEvent.Tags.Add("os_name", Environment.GetEnvironmentVariable("OS_NAME"));
|
||||
sentryEvent.Tags.Add("os_version", Environment.GetEnvironmentVariable("OS_VERSION"));
|
||||
sentryEvent.Tags.Add("runtime_version", Environment.GetEnvironmentVariable("RUNTIME_VERSION"));
|
||||
|
||||
sentryEvent.Tags.Add("os_name", osName);
|
||||
sentryEvent.Tags.Add("os_version", $"{osName} {osVersion}");
|
||||
sentryEvent.Tags.Add("runtime_version", $"{PlatformInfo.PlatformName} {runTimeVersion}");
|
||||
|
||||
_client.Capture(sentryEvent);
|
||||
}
|
||||
|
||||
@@ -44,16 +44,14 @@
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.4.1\lib\net40\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\NLog.4.4.3\lib\net40\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Org.Mentalis, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DotNet4.SocksProxy.1.3.2.0\lib\net40\Org.Mentalis.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="SharpRaven, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpRaven.2.1.0\lib\net40\SharpRaven.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<Reference Include="SharpRaven, Version=2.2.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpRaven.2.2.0\lib\net40\SharpRaven.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SocksWebProxy, Version=1.3.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DotNet4.SocksProxy.1.3.2.0\lib\net40\SocksWebProxy.dll</HintPath>
|
||||
@@ -135,14 +133,14 @@
|
||||
<Compile Include="Expansive\Tree.cs" />
|
||||
<Compile Include="Expansive\TreeNode.cs" />
|
||||
<Compile Include="Expansive\TreeNodeList.cs" />
|
||||
<Compile Include="Extensions\Base64Extentions.cs" />
|
||||
<Compile Include="Extensions\Base64Extensions.cs" />
|
||||
<Compile Include="Extensions\DateTimeExtensions.cs" />
|
||||
<Compile Include="Crypto\HashConverter.cs" />
|
||||
<Compile Include="Extensions\Int64Extensions.cs" />
|
||||
<Compile Include="Extensions\ObjectExtensions.cs" />
|
||||
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||
<Compile Include="Extensions\UrlExtensions.cs" />
|
||||
<Compile Include="Extensions\XmlExtentions.cs" />
|
||||
<Compile Include="Extensions\XmlExtensions.cs" />
|
||||
<Compile Include="HashUtil.cs" />
|
||||
<Compile Include="Http\Dispatchers\CurlHttpDispatcher.cs" />
|
||||
<Compile Include="Http\Dispatchers\FallbackHttpDispatcher.cs" />
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace NzbDrone.Common.TPL
|
||||
/// <param name="maxDegreeOfParallelism">The maximum degree of parallelism provided by this scheduler.</param>
|
||||
public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
|
||||
{
|
||||
if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
|
||||
if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException(nameof(maxDegreeOfParallelism));
|
||||
_maxDegreeOfParallelism = maxDegreeOfParallelism;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<package id="DotNet4.SocksProxy" version="1.3.2.0" targetFramework="net40" />
|
||||
<package id="ICSharpCode.SharpZipLib.Patched" version="0.86.5" targetFramework="net40" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.1" targetFramework="net40" />
|
||||
<package id="SharpRaven" version="2.1.0" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.3" targetFramework="net40" />
|
||||
<package id="SharpRaven" version="2.2.0" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -79,8 +79,7 @@
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NLog.4.4.1\lib\net40\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\NLog.4.4.3\lib\net40\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<package id="Microsoft.Owin" version="2.1.0" targetFramework="net40" />
|
||||
<package id="Microsoft.Owin.Hosting" version="2.1.0" targetFramework="net40" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.1" targetFramework="net40" />
|
||||
<package id="NLog" version="4.4.3" targetFramework="net40" />
|
||||
<package id="Owin" version="1.0" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class update_btn_url_migration_fixture : MigrationTest<update_btn_url>
|
||||
{
|
||||
[TestCase("http://api.btnapps.net")]
|
||||
[TestCase("https://api.btnapps.net")]
|
||||
[TestCase("http://api.btnapps.net/")]
|
||||
[TestCase("https://api.btnapps.net/")]
|
||||
public void should_replace_old_url(string oldUrl)
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Indexers").Row(new
|
||||
{
|
||||
Name = "btn_old_url",
|
||||
Implementation = "BroadcastheNet",
|
||||
Settings = new BroadcastheNetSettings106
|
||||
{
|
||||
BaseUrl = oldUrl
|
||||
}.ToJson(),
|
||||
ConfigContract = "BroadcastheNetSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<IndexerDefinition90>("SELECT * FROM Indexers");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Settings.ToObject<BroadcastheNetSettings106>().BaseUrl.Should().Contain("api.broadcasthe.net");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_replace_other_indexers()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Indexers").Row(new
|
||||
{
|
||||
Name = "not_btn",
|
||||
Implementation = "NotBroadcastheNet",
|
||||
Settings = new BroadcastheNetSettings106
|
||||
{
|
||||
BaseUrl = "http://api.btnapps.net",
|
||||
}.ToJson(),
|
||||
ConfigContract = "BroadcastheNetSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<IndexerDefinition90>("SELECT * FROM Indexers");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Settings.ToObject<BroadcastheNetSettings106>().BaseUrl.Should().Be("http://api.btnapps.net");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class fix_extra_file_extensionsFixture : MigrationTest<fix_extra_file_extension>
|
||||
{
|
||||
[Test]
|
||||
public void should_extra_files_that_do_not_have_an_extension()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("ExtraFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
EpisodeFileId = 1,
|
||||
RelativePath = "Series.Title.S01E01",
|
||||
Added = "2016-05-30 20:23:02.3725923",
|
||||
LastUpdated = "2016-05-30 20:23:02.3725923",
|
||||
Extension = ""
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query("Select * from ExtraFiles");
|
||||
|
||||
items.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_fix_double_extension()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("SubtitleFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
EpisodeFileId = 1,
|
||||
RelativePath = "Series.Title.S01E01.en.srt",
|
||||
Added = "2016-05-30 20:23:02.3725923",
|
||||
LastUpdated = "2016-05-30 20:23:02.3725923",
|
||||
Language = Language.English,
|
||||
Extension = "en.srt"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query("Select * from SubtitleFiles");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First()["Extension"].Should().Be(".srt");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_fix_extension_missing_a_leading_period()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("ExtraFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
EpisodeFileId = 1,
|
||||
RelativePath = "Series.Title.S01E01.nfo-orig",
|
||||
Added = "2016-05-30 20:23:02.3725923",
|
||||
LastUpdated = "2016-05-30 20:23:02.3725923",
|
||||
Extension = "nfo-orig"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query("Select * from ExtraFiles");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First()["Extension"].Should().Be(".nfo-orig");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class import_extra_files_configFixture : MigrationTest<import_extra_files>
|
||||
{
|
||||
[Test]
|
||||
public void should_not_insert_if_missing()
|
||||
{
|
||||
var db = WithMigrationTestDb();
|
||||
|
||||
var items = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
|
||||
items.Should().BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_insert_if_empty()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "extrafileextensions",
|
||||
Value = ""
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
|
||||
items.Should().BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_insert_True_if_configured()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "extrafileextensions",
|
||||
Value = "srt"
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
|
||||
items.Should().Be("True");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class fix_extra_files_configFixture : MigrationTest<fix_extra_files_config>
|
||||
{
|
||||
[Test]
|
||||
public void should_not_update_importextrafiles_disabled()
|
||||
{
|
||||
var db = WithMigrationTestDb();
|
||||
|
||||
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
|
||||
itemEnabled.Should().BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_fix_importextrafiles_if_wrong()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "importextrafiles",
|
||||
Value = 1
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
|
||||
itemEnabled.Should().Be("True");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_fill_in_default_extensions()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "importextrafiles",
|
||||
Value = "False"
|
||||
});
|
||||
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "extrafileextensions",
|
||||
Value = ""
|
||||
});
|
||||
});
|
||||
|
||||
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
|
||||
itemEnabled.Should().Be("False");
|
||||
|
||||
var itemExtensions = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'extrafileextensions'");
|
||||
itemExtensions.Should().Be("srt");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_fill_in_default_extensions()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "importextrafiles",
|
||||
Value = "True"
|
||||
});
|
||||
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "extrafileextensions",
|
||||
Value = ""
|
||||
});
|
||||
});
|
||||
|
||||
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
|
||||
itemEnabled.Should().Be("True");
|
||||
|
||||
var itemExtensions = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'extrafileextensions'");
|
||||
itemExtensions.Should().Be("");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_fill_in_default_extensions_if_not_defined()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "importextrafiles",
|
||||
Value = "False"
|
||||
});
|
||||
});
|
||||
|
||||
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
|
||||
itemEnabled.Should().Be("False");
|
||||
|
||||
var itemExtensions = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'extrafileextensions'");
|
||||
itemExtensions.Should().BeNull();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_fill_in_default_extensions_if_already_defined()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "importextrafiles",
|
||||
Value = "False"
|
||||
});
|
||||
|
||||
c.Insert.IntoTable("Config").Row(new
|
||||
{
|
||||
Key = "extrafileextensions",
|
||||
Value = "sub"
|
||||
});
|
||||
});
|
||||
|
||||
var itemEnabled = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'importextrafiles'");
|
||||
itemEnabled.Should().Be("False");
|
||||
|
||||
var itemExtensions = db.QueryScalar<string>("SELECT Value FROM Config WHERE Key = 'extrafileextensions'");
|
||||
itemExtensions.Should().Be("sub");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,6 +217,37 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.FullSeason.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_multiepisode_over_single_episode_for_anime()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
|
||||
remoteEpisode1.Series.SeriesType = SeriesTypes.Anime;
|
||||
remoteEpisode2.Series.SeriesType = SeriesTypes.Anime;
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Episodes.Count.Should().Be(remoteEpisode1.Episodes.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_single_episode_over_multi_episode_for_non_anime()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1), GivenEpisode(2) }, new QualityModel(Quality.HDTV720p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p));
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Episodes.Count.Should().Be(remoteEpisode2.Episodes.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_releases_with_more_seeders()
|
||||
{
|
||||
@@ -348,5 +379,34 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.Release.Should().Be(remoteEpisode1.Release);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_quality_over_the_number_of_peers()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.Bluray1080p));
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.SDTV));
|
||||
|
||||
var torrentInfo1 = new TorrentInfo();
|
||||
torrentInfo1.PublishDate = DateTime.Now;
|
||||
torrentInfo1.DownloadProtocol = DownloadProtocol.Torrent;
|
||||
torrentInfo1.Seeders = 100;
|
||||
torrentInfo1.Peers = 10;
|
||||
torrentInfo1.Size = 200.Megabytes();
|
||||
|
||||
var torrentInfo2 = torrentInfo1.JsonClone();
|
||||
torrentInfo2.Seeders = 1100;
|
||||
torrentInfo2.Peers = 10;
|
||||
torrentInfo1.Size = 250.Megabytes();
|
||||
|
||||
remoteEpisode1.Release = torrentInfo1;
|
||||
remoteEpisode2.Release = torrentInfo2;
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
((TorrentInfo)qualifiedReports.First().RemoteEpisode.Release).Should().Be(torrentInfo1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
};
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("AllowedTestCases")]
|
||||
[Test, TestCaseSource(nameof(AllowedTestCases))]
|
||||
public void should_allow_if_quality_is_defined_in_profile(Quality qualityType)
|
||||
{
|
||||
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
|
||||
@@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
Subject.IsSatisfiedBy(remoteEpisode, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("DeniedTestCases")]
|
||||
[Test, TestCaseSource(nameof(DeniedTestCases))]
|
||||
public void should_not_allow_if_quality_is_not_defined_in_profile(Quality qualityType)
|
||||
{
|
||||
remoteEpisode.ParsedEpisodeInfo.Quality.Quality = qualityType;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
.Returns(autoDownloadPropers);
|
||||
}
|
||||
|
||||
[Test, TestCaseSource("IsUpgradeTestCases")]
|
||||
[Test, TestCaseSource(nameof(IsUpgradeTestCases))]
|
||||
public void IsUpgradeTest(Quality current, int currentVersion, Quality newQuality, int newVersion, Quality cutoff, bool expected)
|
||||
{
|
||||
GivenAutoDownloadPropers(true);
|
||||
|
||||
134
src/NzbDrone.Core.Test/DiskSpace/DiskSpaceServiceFixture.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DiskSpace;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.DiskSpace
|
||||
{
|
||||
[TestFixture]
|
||||
public class DiskSpaceServiceFixture : CoreTest<DiskSpaceService>
|
||||
{
|
||||
private string _seriesFolder;
|
||||
private string _seriesFolder2;
|
||||
private string _droneFactoryFolder;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_seriesFolder = @"G:\fasdlfsdf\series".AsOsAgnostic();
|
||||
_seriesFolder2 = @"G:\fasdlfsdf\series2".AsOsAgnostic();
|
||||
_droneFactoryFolder = @"G:\dronefactory".AsOsAgnostic();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetMounts())
|
||||
.Returns(new List<IMount>());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetPathRoot(It.IsAny<string>()))
|
||||
.Returns(@"G:\".AsOsAgnostic());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetAvailableSpace(It.IsAny<string>()))
|
||||
.Returns(0);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetTotalSize(It.IsAny<string>()))
|
||||
.Returns(0);
|
||||
|
||||
GivenSeries();
|
||||
}
|
||||
|
||||
private void GivenSeries(params Series[] series)
|
||||
{
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Setup(v => v.GetAllSeries())
|
||||
.Returns(series.ToList());
|
||||
}
|
||||
|
||||
private void GivenExistingFolder(string folder)
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.FolderExists(folder))
|
||||
.Returns(true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_check_diskspace_for_series_folders()
|
||||
{
|
||||
GivenSeries(new Series { Path = _seriesFolder });
|
||||
|
||||
GivenExistingFolder(_seriesFolder);
|
||||
|
||||
var freeSpace = Subject.GetFreeSpace();
|
||||
|
||||
freeSpace.Should().NotBeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_check_diskspace_for_same_root_folder_only_once()
|
||||
{
|
||||
GivenSeries(new Series { Path = _seriesFolder }, new Series { Path = _seriesFolder2 });
|
||||
|
||||
GivenExistingFolder(_seriesFolder);
|
||||
GivenExistingFolder(_seriesFolder2);
|
||||
|
||||
var freeSpace = Subject.GetFreeSpace();
|
||||
|
||||
freeSpace.Should().HaveCount(1);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetAvailableSpace(It.IsAny<string>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_check_diskspace_for_missing_series_folders()
|
||||
{
|
||||
GivenSeries(new Series { Path = _seriesFolder });
|
||||
|
||||
var freeSpace = Subject.GetFreeSpace();
|
||||
|
||||
freeSpace.Should().BeEmpty();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetAvailableSpace(It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_check_diskspace_for_dronefactory_folder()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.SetupGet(v => v.DownloadedEpisodesFolder)
|
||||
.Returns(_droneFactoryFolder);
|
||||
|
||||
GivenExistingFolder(_droneFactoryFolder);
|
||||
|
||||
var freeSpace = Subject.GetFreeSpace();
|
||||
|
||||
freeSpace.Should().NotBeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_check_diskspace_for_missing_dronefactory_folder()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.SetupGet(v => v.DownloadedEpisodesFolder)
|
||||
.Returns(_droneFactoryFolder);
|
||||
|
||||
var freeSpace = Subject.GetFreeSpace();
|
||||
|
||||
freeSpace.Should().BeEmpty();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetAvailableSpace(It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,6 +99,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var result = Subject.GetItems().Single();
|
||||
|
||||
VerifyCompleted(result);
|
||||
|
||||
result.CanBeRemoved.Should().BeFalse();
|
||||
result.CanMoveFiles.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -77,6 +77,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.Blackhole
|
||||
var result = Subject.GetItems().Single();
|
||||
|
||||
VerifyCompleted(result);
|
||||
|
||||
result.CanBeRemoved.Should().BeTrue();
|
||||
result.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
protected DelugeTorrent _downloading;
|
||||
protected DelugeTorrent _failed;
|
||||
protected DelugeTorrent _completed;
|
||||
protected DelugeTorrent _seeding;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
@@ -75,7 +76,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
Size = 1000,
|
||||
BytesDownloaded = 1000,
|
||||
Progress = 100.0,
|
||||
DownloadPath = "somepath"
|
||||
DownloadPath = "somepath",
|
||||
IsAutoManaged = true,
|
||||
StopAtRatio = true,
|
||||
StopRatio = 1.0,
|
||||
Ratio = 1.5
|
||||
};
|
||||
|
||||
Mocker.GetMock<ITorrentFileInfoReader>()
|
||||
@@ -114,7 +119,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
.Returns("CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951".ToLower())
|
||||
.Callback(PrepareClientToReturnQueuedItem);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void GivenTorrents(List<DelugeTorrent> torrents)
|
||||
{
|
||||
if (torrents == null)
|
||||
@@ -129,7 +134,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
|
||||
protected void PrepareClientToReturnQueuedItem()
|
||||
{
|
||||
GivenTorrents(new List<DelugeTorrent>
|
||||
GivenTorrents(new List<DelugeTorrent>
|
||||
{
|
||||
_queued
|
||||
});
|
||||
@@ -137,7 +142,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
|
||||
protected void PrepareClientToReturnDownloadingItem()
|
||||
{
|
||||
GivenTorrents(new List<DelugeTorrent>
|
||||
GivenTorrents(new List<DelugeTorrent>
|
||||
{
|
||||
_downloading
|
||||
});
|
||||
@@ -145,7 +150,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
|
||||
protected void PrepareClientToReturnFailedItem()
|
||||
{
|
||||
GivenTorrents(new List<DelugeTorrent>
|
||||
GivenTorrents(new List<DelugeTorrent>
|
||||
{
|
||||
_failed
|
||||
});
|
||||
@@ -189,6 +194,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
PrepareClientToReturnCompletedItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
VerifyCompleted(item);
|
||||
|
||||
item.CanBeRemoved.Should().BeTrue();
|
||||
item.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -248,11 +256,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
item.Status.Should().Be(expectedItemStatus);
|
||||
}
|
||||
|
||||
[TestCase(DelugeTorrentStatus.Paused, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(DelugeTorrentStatus.Checking, DownloadItemStatus.Downloading, true)]
|
||||
[TestCase(DelugeTorrentStatus.Queued, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(DelugeTorrentStatus.Seeding, DownloadItemStatus.Completed, true)]
|
||||
public void GetItems_should_return_completed_item_as_downloadItemStatus(string apiStatus, DownloadItemStatus expectedItemStatus, bool expectedReadOnly)
|
||||
[TestCase(DelugeTorrentStatus.Paused, DownloadItemStatus.Completed)]
|
||||
[TestCase(DelugeTorrentStatus.Checking, DownloadItemStatus.Downloading)]
|
||||
[TestCase(DelugeTorrentStatus.Queued, DownloadItemStatus.Completed)]
|
||||
[TestCase(DelugeTorrentStatus.Seeding, DownloadItemStatus.Completed)]
|
||||
public void GetItems_should_return_completed_item_as_downloadItemStatus(string apiStatus, DownloadItemStatus expectedItemStatus)
|
||||
{
|
||||
_completed.State = apiStatus;
|
||||
|
||||
@@ -261,24 +269,25 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DelugeTests
|
||||
var item = Subject.GetItems().Single();
|
||||
|
||||
item.Status.Should().Be(expectedItemStatus);
|
||||
item.IsReadOnly.Should().Be(expectedReadOnly);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetItems_should_check_share_ratio_for_readonly()
|
||||
[TestCase(0.5, false)]
|
||||
[TestCase(1.01, true)]
|
||||
public void GetItems_should_check_share_ratio_for_moveFiles_and_remove(double ratio, bool canBeRemoved)
|
||||
{
|
||||
_completed.State = DelugeTorrentStatus.Paused;
|
||||
_completed.IsAutoManaged = true;
|
||||
_completed.StopAtRatio = true;
|
||||
_completed.StopRatio = 1.0;
|
||||
_completed.Ratio = 1.01;
|
||||
_completed.Ratio = ratio;
|
||||
|
||||
PrepareClientToReturnCompletedItem();
|
||||
|
||||
var item = Subject.GetItems().Single();
|
||||
|
||||
item.Status.Should().Be(DownloadItemStatus.Completed);
|
||||
item.IsReadOnly.Should().BeFalse();
|
||||
item.CanMoveFiles.Should().Be(canBeRemoved);
|
||||
item.CanBeRemoved.Should().Be(canBeRemoved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,626 @@
|
||||
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<IDownloadStationInfoProxy>()
|
||||
.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<IDownloadStationTaskProxy>()
|
||||
.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<IDownloadStationTaskProxy>()
|
||||
.Setup(s => s.AddTaskFromUrl(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
||||
.Callback(PrepareClientToReturnQueuedItem);
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.Setup(s => s.AddTaskFromData(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DownloadStationSettings>()))
|
||||
.Callback(PrepareClientToReturnQueuedItem);
|
||||
}
|
||||
|
||||
protected override RemoteEpisode CreateRemoteEpisode()
|
||||
{
|
||||
var episode = base.CreateRemoteEpisode();
|
||||
|
||||
episode.Release.DownloadUrl = DownloadURL;
|
||||
|
||||
return episode;
|
||||
}
|
||||
|
||||
protected int GivenAllKindOfTasks()
|
||||
{
|
||||
var tasks = new List<DownloadStationTask>() { _queued, _completed, _failed, _downloading, _seeding };
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.Setup(d => d.GetTasks(_settings))
|
||||
.Returns(tasks);
|
||||
|
||||
return tasks.Count;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_TvDirectory_should_force_directory()
|
||||
{
|
||||
GivenSerialNumber();
|
||||
GivenTvDirectory();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.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 = CreateRemoteEpisode();
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.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 = CreateRemoteEpisode();
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.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 = CreateRemoteEpisode();
|
||||
|
||||
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<IDownloadStationTaskProxy>()
|
||||
.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, false, false)]
|
||||
[TestCase(DownloadStationTaskStatus.Finished, true, true)]
|
||||
[TestCase(DownloadStationTaskStatus.Seeding, true, false)]
|
||||
[TestCase(DownloadStationTaskStatus.Waiting, false, false)]
|
||||
public void GetItems_should_return_canBeMoved_and_canBeDeleted_as_expected(DownloadStationTaskStatus apiStatus, bool canMoveFilesExpected, bool canBeRemovedExpected)
|
||||
{
|
||||
GivenSerialNumber();
|
||||
GivenSharedFolder();
|
||||
|
||||
_queued.Status = apiStatus;
|
||||
|
||||
GivenTasks(new List<DownloadStationTask>() { _queued });
|
||||
|
||||
var items = Subject.GetItems();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
var item = items.First();
|
||||
|
||||
item.CanBeRemoved.Should().Be(canBeRemovedExpected);
|
||||
item.CanMoveFiles.Should().Be(canMoveFilesExpected);
|
||||
}
|
||||
|
||||
[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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
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 RemoteEpisode _remoteEpisode;
|
||||
|
||||
protected Dictionary<string, object> _downloadStationConfigItems;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_remoteEpisode = CreateRemoteEpisode();
|
||||
|
||||
_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<IDownloadStationInfoProxy>()
|
||||
.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<IDownloadStationTaskProxy>()
|
||||
.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<IDownloadStationTaskProxy>()
|
||||
.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<IDownloadStationTaskProxy>()
|
||||
.Setup(d => d.GetTasks(_settings))
|
||||
.Returns(tasks);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_with_TvDirectory_should_force_directory()
|
||||
{
|
||||
GivenSerialNumber();
|
||||
GivenTvDirectory();
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.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 = CreateRemoteEpisode();
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.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 = CreateRemoteEpisode();
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
|
||||
Mocker.GetMock<IDownloadStationTaskProxy>()
|
||||
.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 = CreateRemoteEpisode();
|
||||
|
||||
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<IDownloadStationTaskProxy>()
|
||||
.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)]
|
||||
[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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,6 +190,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
||||
PrepareClientToReturnCompletedItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
VerifyCompleted(item);
|
||||
|
||||
item.CanBeRemoved.Should().BeTrue();
|
||||
item.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -298,7 +301,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.HadoukenTests
|
||||
.Returns("hash");
|
||||
|
||||
var result = Subject.Download(remoteEpisode);
|
||||
|
||||
|
||||
Assert.IsFalse(result.Any(c => char.IsLower(c)));
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbVortexTests
|
||||
public void queued_item_should_have_required_properties()
|
||||
{
|
||||
GivenQueue(_queued);
|
||||
|
||||
|
||||
var result = Subject.GetItems().Single();
|
||||
|
||||
VerifyQueued(result);
|
||||
@@ -139,6 +139,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbVortexTests
|
||||
var result = Subject.GetItems().Single();
|
||||
|
||||
VerifyCompleted(result);
|
||||
|
||||
result.CanBeRemoved.Should().BeTrue();
|
||||
result.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -92,14 +92,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
||||
protected void GivenFailedDownload()
|
||||
{
|
||||
Mocker.GetMock<INzbgetProxy>()
|
||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<NzbgetSettings>()))
|
||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<NzbgetSettings>()))
|
||||
.Returns((string)null);
|
||||
}
|
||||
|
||||
protected void GivenSuccessfulDownload()
|
||||
{
|
||||
Mocker.GetMock<INzbgetProxy>()
|
||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<NzbgetSettings>()))
|
||||
.Setup(s => s.DownloadNzb(It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<bool>(), It.IsAny<NzbgetSettings>()))
|
||||
.Returns(Guid.NewGuid().ToString().Replace("-", ""));
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
||||
|
||||
GivenQueue(_queued);
|
||||
GivenHistory(null);
|
||||
|
||||
|
||||
var result = Subject.GetItems().Single();
|
||||
|
||||
VerifyQueued(result);
|
||||
@@ -204,6 +204,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.NzbgetTests
|
||||
var result = Subject.GetItems().Single();
|
||||
|
||||
VerifyCompleted(result);
|
||||
|
||||
result.CanBeRemoved.Should().BeTrue();
|
||||
result.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -311,7 +311,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_read_only_if_max_ratio_not_reached()
|
||||
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_not_reached()
|
||||
{
|
||||
GivenMaxRatio(1.0f);
|
||||
|
||||
@@ -330,11 +330,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
GivenTorrents(new List<QBittorrentTorrent> { torrent });
|
||||
|
||||
var item = Subject.GetItems().Single();
|
||||
item.IsReadOnly.Should().BeTrue();
|
||||
item.CanBeRemoved.Should().BeFalse();
|
||||
item.CanMoveFiles.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_read_only_if_max_ratio_reached_and_not_paused()
|
||||
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_reached_and_not_paused()
|
||||
{
|
||||
GivenMaxRatio(1.0f);
|
||||
|
||||
@@ -353,11 +354,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
GivenTorrents(new List<QBittorrentTorrent> { torrent });
|
||||
|
||||
var item = Subject.GetItems().Single();
|
||||
item.IsReadOnly.Should().BeTrue();
|
||||
item.CanBeRemoved.Should().BeFalse();
|
||||
item.CanMoveFiles.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_read_only_if_max_ratio_is_not_set()
|
||||
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_is_not_set()
|
||||
{
|
||||
GivenMaxRatio(1.0f, false);
|
||||
|
||||
@@ -376,11 +378,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
GivenTorrents(new List<QBittorrentTorrent> { torrent });
|
||||
|
||||
var item = Subject.GetItems().Single();
|
||||
item.IsReadOnly.Should().BeTrue();
|
||||
item.CanBeRemoved.Should().BeFalse();
|
||||
item.CanMoveFiles.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_be_read_only_if_max_ratio_reached_and_paused()
|
||||
public void should_be_removable_and_should_allow_move_files_if_max_ratio_reached_and_paused()
|
||||
{
|
||||
GivenMaxRatio(1.0f);
|
||||
|
||||
@@ -399,7 +402,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
|
||||
GivenTorrents(new List<QBittorrentTorrent> { torrent });
|
||||
|
||||
var item = Subject.GetItems().Single();
|
||||
item.IsReadOnly.Should().BeFalse();
|
||||
item.CanBeRemoved.Should().BeTrue();
|
||||
item.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -54,11 +54,11 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests
|
||||
protected void GivenSuccessfulDownload()
|
||||
{
|
||||
Mocker.GetMock<IRTorrentProxy>()
|
||||
.Setup(s => s.AddTorrentFromUrl(It.IsAny<string>(), It.IsAny<RTorrentSettings>()))
|
||||
.Setup(s => s.AddTorrentFromUrl(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<RTorrentPriority>(), It.IsAny<string>(), It.IsAny<RTorrentSettings>()))
|
||||
.Callback(PrepareClientToReturnCompletedItem);
|
||||
|
||||
Mocker.GetMock<IRTorrentProxy>()
|
||||
.Setup(s => s.AddTorrentFromFile(It.IsAny<string>(), It.IsAny<byte[]>(), It.IsAny<RTorrentSettings>()))
|
||||
.Setup(s => s.AddTorrentFromFile(It.IsAny<string>(), It.IsAny<byte[]>(), It.IsAny<string>(), It.IsAny<RTorrentPriority>(), It.IsAny<string>(), It.IsAny<RTorrentSettings>()))
|
||||
.Callback(PrepareClientToReturnCompletedItem);
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
private SabnzbdHistory _failed;
|
||||
private SabnzbdHistory _completed;
|
||||
private SabnzbdConfig _config;
|
||||
private SabnzbdFullStatus _fullStatus;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
@@ -65,7 +66,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
{
|
||||
Status = SabnzbdDownloadStatus.Failed,
|
||||
Size = 1000,
|
||||
Category = "tv",
|
||||
Category = "tv",
|
||||
Id = "sabnzbd_nzb12345",
|
||||
Title = "Droned.S01E01.Pilot.1080p.WEB-DL-DRONE"
|
||||
}
|
||||
@@ -80,7 +81,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
{
|
||||
Status = SabnzbdDownloadStatus.Completed,
|
||||
Size = 1000,
|
||||
Category = "tv",
|
||||
Category = "tv",
|
||||
Id = "sabnzbd_nzb12345",
|
||||
Title = "Droned.S01E01.Pilot.1080p.WEB-DL-DRONE",
|
||||
Storage = "/remote/mount/vv/Droned.S01E01.Pilot.1080p.WEB-DL-DRONE"
|
||||
@@ -100,9 +101,29 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
}
|
||||
};
|
||||
|
||||
Mocker.GetMock<ISabnzbdProxy>()
|
||||
.Setup(v => v.GetVersion(It.IsAny<SabnzbdSettings>()))
|
||||
.Returns("1.2.3");
|
||||
|
||||
Mocker.GetMock<ISabnzbdProxy>()
|
||||
.Setup(s => s.GetConfig(It.IsAny<SabnzbdSettings>()))
|
||||
.Returns(_config);
|
||||
|
||||
_fullStatus = new SabnzbdFullStatus
|
||||
{
|
||||
CompleteDir = @"Y:\nzbget\root\complete".AsOsAgnostic()
|
||||
};
|
||||
|
||||
Mocker.GetMock<ISabnzbdProxy>()
|
||||
.Setup(s => s.GetFullStatus(It.IsAny<SabnzbdSettings>()))
|
||||
.Returns(_fullStatus);
|
||||
}
|
||||
|
||||
protected void GivenVersion(string version)
|
||||
{
|
||||
Mocker.GetMock<ISabnzbdProxy>()
|
||||
.Setup(s => s.GetVersion(It.IsAny<SabnzbdSettings>()))
|
||||
.Returns(version);
|
||||
}
|
||||
|
||||
protected void GivenFailedDownload()
|
||||
@@ -166,7 +187,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
|
||||
GivenQueue(_queued);
|
||||
GivenHistory(null);
|
||||
|
||||
|
||||
var result = Subject.GetItems().Single();
|
||||
|
||||
VerifyQueued(result);
|
||||
@@ -218,6 +239,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
var result = Subject.GetItems().Single();
|
||||
|
||||
VerifyCompleted(result);
|
||||
|
||||
result.CanBeRemoved.Should().BeTrue();
|
||||
result.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -386,23 +410,46 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
result.OutputPath.Should().Be(@"C:\sorted\somewhere\asdfasdf\asdfasdf.mkv".AsOsAgnostic());
|
||||
}
|
||||
|
||||
[TestCase(@"Y:\nzbget\root", @"completed\downloads", @"vv", @"Y:\nzbget\root\completed\downloads\vv")]
|
||||
[TestCase(@"Y:\nzbget\root", @"completed", @"vv", @"Y:\nzbget\root\completed\vv")]
|
||||
[TestCase(@"/nzbget/root", @"completed/downloads", @"vv", @"/nzbget/root/completed/downloads/vv")]
|
||||
[TestCase(@"/nzbget/root", @"completed", @"vv", @"/nzbget/root/completed/vv")]
|
||||
public void should_return_status_with_outputdir(string rootFolder, string completeDir, string categoryDir, string expectedDir)
|
||||
[TestCase(@"Y:\nzbget\root", @"completed\downloads", @"vv", @"Y:\nzbget\root\completed\downloads", @"Y:\nzbget\root\completed\downloads\vv")]
|
||||
[TestCase(@"Y:\nzbget\root", @"completed", @"vv", @"Y:\nzbget\root\completed", @"Y:\nzbget\root\completed\vv")]
|
||||
[TestCase(@"/nzbget/root", @"completed/downloads", @"vv", @"/nzbget/root/completed/downloads", @"/nzbget/root/completed/downloads/vv")]
|
||||
[TestCase(@"/nzbget/root", @"completed", @"vv", @"/nzbget/root/completed", @"/nzbget/root/completed/vv")]
|
||||
public void should_return_status_with_outputdir_for_version_lt_2(string rootFolder, string completeDir, string categoryDir, string fullCompleteDir, string fullCategoryDir)
|
||||
{
|
||||
_fullStatus.CompleteDir = null;
|
||||
_queued.DefaultRootFolder = rootFolder;
|
||||
_config.Misc.complete_dir = completeDir;
|
||||
_config.Categories.First().Dir = categoryDir;
|
||||
|
||||
|
||||
GivenVersion("1.2.1");
|
||||
GivenQueue(null);
|
||||
|
||||
var result = Subject.GetStatus();
|
||||
|
||||
result.IsLocalhost.Should().BeTrue();
|
||||
result.OutputRootFolders.Should().NotBeNull();
|
||||
result.OutputRootFolders.First().Should().Be(expectedDir);
|
||||
result.OutputRootFolders.First().Should().Be(fullCategoryDir);
|
||||
}
|
||||
|
||||
[TestCase(@"Y:\nzbget\root", @"completed\downloads", @"vv", @"Y:\nzbget\root\completed\downloads", @"Y:\nzbget\root\completed\downloads\vv")]
|
||||
[TestCase(@"Y:\nzbget\root", @"completed", @"vv", @"Y:\nzbget\root\completed", @"Y:\nzbget\root\completed\vv")]
|
||||
[TestCase(@"/nzbget/root", @"completed/downloads", @"vv", @"/nzbget/root/completed/downloads", @"/nzbget/root/completed/downloads/vv")]
|
||||
[TestCase(@"/nzbget/root", @"completed", @"vv", @"/nzbget/root/completed", @"/nzbget/root/completed/vv")]
|
||||
public void should_return_status_with_outputdir_for_version_gte_2(string rootFolder, string completeDir, string categoryDir, string fullCompleteDir, string fullCategoryDir)
|
||||
{
|
||||
_fullStatus.CompleteDir = fullCompleteDir;
|
||||
_queued.DefaultRootFolder = null;
|
||||
_config.Misc.complete_dir = completeDir;
|
||||
_config.Categories.First().Dir = categoryDir;
|
||||
|
||||
GivenVersion("2.0.0beta1");
|
||||
GivenQueue(null);
|
||||
|
||||
var result = Subject.GetStatus();
|
||||
|
||||
result.IsLocalhost.Should().BeTrue();
|
||||
result.OutputRootFolders.Should().NotBeNull();
|
||||
result.OutputRootFolders.First().Should().Be(fullCategoryDir);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -450,5 +497,73 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.SabnzbdTests
|
||||
result.IsValid.Should().BeTrue();
|
||||
result.HasWarnings.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_test_success_if_tv_sorting_disabled()
|
||||
{
|
||||
_config.Misc.enable_tv_sorting = false;
|
||||
_config.Misc.tv_categories = null;
|
||||
|
||||
var result = new NzbDroneValidationResult(Subject.Test());
|
||||
|
||||
result.IsValid.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_test_failed_if_tv_sorting_null()
|
||||
{
|
||||
_config.Misc.enable_tv_sorting = true;
|
||||
_config.Misc.tv_categories = null;
|
||||
|
||||
var result = new NzbDroneValidationResult(Subject.Test());
|
||||
|
||||
result.IsValid.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_test_failed_if_tv_sorting_empty()
|
||||
{
|
||||
_config.Misc.enable_tv_sorting = true;
|
||||
_config.Misc.tv_categories = new string[0];
|
||||
|
||||
var result = new NzbDroneValidationResult(Subject.Test());
|
||||
|
||||
result.IsValid.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_test_success_if_tv_sorting_contains_different_category()
|
||||
{
|
||||
_config.Misc.enable_tv_sorting = true;
|
||||
_config.Misc.tv_categories = new[] { "tv-custom" };
|
||||
|
||||
var result = new NzbDroneValidationResult(Subject.Test());
|
||||
|
||||
result.IsValid.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_test_failed_if_tv_sorting_contains_category()
|
||||
{
|
||||
_config.Misc.enable_tv_sorting = true;
|
||||
_config.Misc.tv_categories = new[] { "tv" };
|
||||
|
||||
var result = new NzbDroneValidationResult(Subject.Test());
|
||||
|
||||
result.IsValid.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_test_failed_if_tv_sorting_default_category()
|
||||
{
|
||||
Subject.Definition.Settings.As<SabnzbdSettings>().TvCategory = null;
|
||||
|
||||
_config.Misc.enable_tv_sorting = true;
|
||||
_config.Misc.tv_categories = new[] { "Default" };
|
||||
|
||||
var result = new NzbDroneValidationResult(Subject.Test());
|
||||
|
||||
result.IsValid.Should().BeFalse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
PrepareClientToReturnCompletedItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
VerifyCompleted(item);
|
||||
|
||||
item.CanBeRemoved.Should().BeTrue();
|
||||
item.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -172,13 +175,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
item.Status.Should().Be(expectedItemStatus);
|
||||
}
|
||||
|
||||
[TestCase(TransmissionTorrentStatus.Stopped, DownloadItemStatus.Completed, false)]
|
||||
[TestCase(TransmissionTorrentStatus.CheckWait, DownloadItemStatus.Downloading, true)]
|
||||
[TestCase(TransmissionTorrentStatus.Check, DownloadItemStatus.Downloading, true)]
|
||||
[TestCase(TransmissionTorrentStatus.Queued, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(TransmissionTorrentStatus.SeedingWait, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(TransmissionTorrentStatus.Seeding, DownloadItemStatus.Completed, true)]
|
||||
public void GetItems_should_return_completed_item_as_downloadItemStatus(TransmissionTorrentStatus apiStatus, DownloadItemStatus expectedItemStatus, bool expectedReadOnly)
|
||||
[TestCase(TransmissionTorrentStatus.Stopped, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(TransmissionTorrentStatus.CheckWait, DownloadItemStatus.Downloading, false)]
|
||||
[TestCase(TransmissionTorrentStatus.Check, DownloadItemStatus.Downloading, false)]
|
||||
[TestCase(TransmissionTorrentStatus.Queued, DownloadItemStatus.Completed, false)]
|
||||
[TestCase(TransmissionTorrentStatus.SeedingWait, DownloadItemStatus.Completed, false)]
|
||||
[TestCase(TransmissionTorrentStatus.Seeding, DownloadItemStatus.Completed, false)]
|
||||
public void GetItems_should_return_completed_item_as_downloadItemStatus(TransmissionTorrentStatus apiStatus, DownloadItemStatus expectedItemStatus, bool expectedValue)
|
||||
{
|
||||
_completed.Status = apiStatus;
|
||||
|
||||
@@ -187,7 +190,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
var item = Subject.GetItems().Single();
|
||||
|
||||
item.Status.Should().Be(expectedItemStatus);
|
||||
item.IsReadOnly.Should().Be(expectedReadOnly);
|
||||
item.CanBeRemoved.Should().Be(expectedValue);
|
||||
item.CanMoveFiles.Should().Be(expectedValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -222,6 +222,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
||||
PrepareClientToReturnCompletedItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
VerifyCompleted(item);
|
||||
|
||||
item.CanBeRemoved.Should().BeTrue();
|
||||
item.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -292,12 +295,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
||||
item.Status.Should().Be(expectedItemStatus);
|
||||
}
|
||||
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checking, DownloadItemStatus.Queued, false)]
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checked, DownloadItemStatus.Completed, false)]
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checked | UTorrentTorrentStatus.Queued, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checked | UTorrentTorrentStatus.Started, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checked | UTorrentTorrentStatus.Queued | UTorrentTorrentStatus.Paused, DownloadItemStatus.Completed, true)]
|
||||
public void GetItems_should_return_completed_item_as_downloadItemStatus(UTorrentTorrentStatus apiStatus, DownloadItemStatus expectedItemStatus, bool expectedReadOnly)
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checking, DownloadItemStatus.Queued, true)]
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checked, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checked | UTorrentTorrentStatus.Queued, DownloadItemStatus.Completed, false)]
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checked | UTorrentTorrentStatus.Started, DownloadItemStatus.Completed, false)]
|
||||
[TestCase(UTorrentTorrentStatus.Loaded | UTorrentTorrentStatus.Checked | UTorrentTorrentStatus.Queued | UTorrentTorrentStatus.Paused, DownloadItemStatus.Completed, false)]
|
||||
public void GetItems_should_return_completed_item_as_downloadItemStatus(UTorrentTorrentStatus apiStatus, DownloadItemStatus expectedItemStatus, bool expectedValue)
|
||||
{
|
||||
_completed.Status = apiStatus;
|
||||
|
||||
@@ -306,7 +309,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.UTorrentTests
|
||||
var item = Subject.GetItems().Single();
|
||||
|
||||
item.Status.Should().Be(expectedItemStatus);
|
||||
item.IsReadOnly.Should().Be(expectedReadOnly);
|
||||
item.CanBeRemoved.Should().Be(expectedValue);
|
||||
item.CanMoveFiles.Should().Be(expectedValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -43,6 +43,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
PrepareClientToReturnCompletedItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
VerifyCompleted(item);
|
||||
|
||||
item.CanBeRemoved.Should().BeTrue();
|
||||
item.CanMoveFiles.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -174,13 +177,13 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
item.Status.Should().Be(expectedItemStatus);
|
||||
}
|
||||
|
||||
[TestCase(TransmissionTorrentStatus.Stopped, DownloadItemStatus.Completed, false)]
|
||||
[TestCase(TransmissionTorrentStatus.CheckWait, DownloadItemStatus.Downloading, true)]
|
||||
[TestCase(TransmissionTorrentStatus.Check, DownloadItemStatus.Downloading, true)]
|
||||
[TestCase(TransmissionTorrentStatus.Queued, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(TransmissionTorrentStatus.SeedingWait, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(TransmissionTorrentStatus.Seeding, DownloadItemStatus.Completed, true)]
|
||||
public void GetItems_should_return_completed_item_as_downloadItemStatus(TransmissionTorrentStatus apiStatus, DownloadItemStatus expectedItemStatus, bool expectedReadOnly)
|
||||
[TestCase(TransmissionTorrentStatus.Stopped, DownloadItemStatus.Completed, true)]
|
||||
[TestCase(TransmissionTorrentStatus.CheckWait, DownloadItemStatus.Downloading, false)]
|
||||
[TestCase(TransmissionTorrentStatus.Check, DownloadItemStatus.Downloading, false)]
|
||||
[TestCase(TransmissionTorrentStatus.Queued, DownloadItemStatus.Completed, false)]
|
||||
[TestCase(TransmissionTorrentStatus.SeedingWait, DownloadItemStatus.Completed, false)]
|
||||
[TestCase(TransmissionTorrentStatus.Seeding, DownloadItemStatus.Completed, false)]
|
||||
public void GetItems_should_return_completed_item_as_downloadItemStatus(TransmissionTorrentStatus apiStatus, DownloadItemStatus expectedItemStatus, bool expectedValue)
|
||||
{
|
||||
_completed.Status = apiStatus;
|
||||
|
||||
@@ -189,7 +192,8 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
var item = Subject.GetItems().Single();
|
||||
|
||||
item.Status.Should().Be(expectedItemStatus);
|
||||
item.IsReadOnly.Should().Be(expectedReadOnly);
|
||||
item.CanBeRemoved.Should().Be(expectedValue);
|
||||
item.CanMoveFiles.Should().Be(expectedValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -312,4 +316,4 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.VuzeTests
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:torrent="http://xmlns.ezrss.it/0.1/">
|
||||
<channel>
|
||||
<title>tv torrents RSS feed - KickassTorrents</title>
|
||||
<link>http://kickass.to/</link>
|
||||
<description>tv torrents RSS feed</description>
|
||||
<item>
|
||||
<title>Doctor Stranger.E03.140512.HDTV.H264.720p-iPOP.avi [CTRG]</title>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/2NE1/</author>
|
||||
<link>http://kickass.to/doctor-stranger-e03-140512-hdtv-h264-720p-ipop-avi-ctrg-t9100648.html</link>
|
||||
<guid>http://kickass.to/doctor-stranger-e03-140512-hdtv-h264-720p-ipop-avi-ctrg-t9100648.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:16:49 +0000</pubDate>
|
||||
<torrent:contentLength>1205364736</torrent:contentLength>
|
||||
<torrent:infoHash>208C4F7866612CC88BFEBC7C496FA72C2368D1C0</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[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]]></torrent:magnetURI>
|
||||
<torrent:seeds>206</torrent:seeds>
|
||||
<torrent:peers>311</torrent:peers>
|
||||
<torrent:verified>1</torrent:verified>
|
||||
<torrent:fileName>doctor.stranger.e03.140512.hdtv.h264.720p.ipop.avi.ctrg.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/208C4F7866612CC88BFEBC7C496FA72C2368D1C0.torrent?title=%5Bkickass.to%5Ddoctor.stranger.e03.140512.hdtv.h264.720p.ipop.avi.ctrg" length="1205364736" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Triangle.E03.140512.HDTV.XViD-iPOP.avi [CTRG]</title>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/2NE1/</author>
|
||||
<link>http://kickass.to/triangle-e03-140512-hdtv-xvid-ipop-avi-ctrg-t9100647.html</link>
|
||||
<guid>http://kickass.to/triangle-e03-140512-hdtv-xvid-ipop-avi-ctrg-t9100647.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:16:31 +0000</pubDate>
|
||||
<torrent:contentLength>677543936</torrent:contentLength>
|
||||
<torrent:infoHash>BF22A53C9889A7D325F2A3D904E566B7DF4074EB</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[magnet:?xt=urn:btih:BF22A53C9889A7D325F2A3D904E566B7DF4074EB&dn=triangle+e03+140512+hdtv+xvid+ipop+avi+ctrg&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce]]></torrent:magnetURI>
|
||||
<torrent:seeds>242</torrent:seeds>
|
||||
<torrent:peers>374</torrent:peers>
|
||||
<torrent:verified>1</torrent:verified>
|
||||
<torrent:fileName>triangle.e03.140512.hdtv.xvid.ipop.avi.ctrg.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/BF22A53C9889A7D325F2A3D904E566B7DF4074EB.torrent?title=%5Bkickass.to%5Dtriangle.e03.140512.hdtv.xvid.ipop.avi.ctrg" length="677543936" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Triangle.E03.140512.HDTV.H264.720p-iPOP.avi [CTRG]</title>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/2NE1/</author>
|
||||
<link>http://kickass.to/triangle-e03-140512-hdtv-h264-720p-ipop-avi-ctrg-t9100646.html</link>
|
||||
<guid>http://kickass.to/triangle-e03-140512-hdtv-h264-720p-ipop-avi-ctrg-t9100646.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:16:10 +0000</pubDate>
|
||||
<torrent:contentLength>1196869632</torrent:contentLength>
|
||||
<torrent:infoHash>8427BFB8884B8228364EBB9B3EA7D8B77E03A7BC</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[magnet:?xt=urn:btih:8427BFB8884B8228364EBB9B3EA7D8B77E03A7BC&dn=triangle+e03+140512+hdtv+h264+720p+ipop+avi+ctrg&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce]]></torrent:magnetURI>
|
||||
<torrent:seeds>177</torrent:seeds>
|
||||
<torrent:peers>268</torrent:peers>
|
||||
<torrent:verified>1</torrent:verified>
|
||||
<torrent:fileName>triangle.e03.140512.hdtv.h264.720p.ipop.avi.ctrg.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/8427BFB8884B8228364EBB9B3EA7D8B77E03A7BC.torrent?title=%5Bkickass.to%5Dtriangle.e03.140512.hdtv.h264.720p.ipop.avi.ctrg" length="1196869632" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Triangle.E03.140512.HDTV.X264.720p-BarosG_.avi [CTRG]</title>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/2NE1/</author>
|
||||
<link>http://kickass.to/triangle-e03-140512-hdtv-x264-720p-barosg-avi-ctrg-t9100644.html</link>
|
||||
<guid>http://kickass.to/triangle-e03-140512-hdtv-x264-720p-barosg-avi-ctrg-t9100644.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:15:52 +0000</pubDate>
|
||||
<torrent:contentLength>1418906266</torrent:contentLength>
|
||||
<torrent:infoHash>5556B773893DB55287ECEC581E850B853163DB11</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[magnet:?xt=urn:btih:5556B773893DB55287ECEC581E850B853163DB11&dn=triangle+e03+140512+hdtv+x264+720p+barosg+avi+ctrg&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce]]></torrent:magnetURI>
|
||||
<torrent:seeds>522</torrent:seeds>
|
||||
<torrent:peers>785</torrent:peers>
|
||||
<torrent:verified>1</torrent:verified>
|
||||
<torrent:fileName>triangle.e03.140512.hdtv.x264.720p.barosg.avi.ctrg.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/5556B773893DB55287ECEC581E850B853163DB11.torrent?title=%5Bkickass.to%5Dtriangle.e03.140512.hdtv.x264.720p.barosg.avi.ctrg" length="1418906266" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Battlestar Galactica 1978 Dvd3 e09 e10 e11 e12 [NL] [FR] [ENG] Sub</title>
|
||||
<description>
|
||||
<![CDATA[In een afgelegen zonnestelsel leeft een mensenras op twaalf koloniewerelden. Ze zijn al eeuwen in oorlog met de Cylons, gevechtsrobots die ooit werden gemaakt door een allang verdwenen buitenaards reptielachtig ras. Met de hulp van de menselijke verrader Baltar zijn de Cylons erin geslaagd de mensheid vrijwel uit te roeien. Slechts een oorlogsschip kan aan de vernietiging ontkomen: de Battlestar Galactica van commandant Adama.
|
||||
|
||||
Met een vloot burgerschepen vol vluchtelingen vlucht de Galactica voor de Cylons. Adama besluit op zoek te gaan naar de legendarische 13e en laatste kolonie, genaamd Aarde. Tijdens de lange en gevaarlijke reis worden ze voortdurend bedreigd door de achtervolgende Cylons en andere gevaren.]]>
|
||||
</description>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/hendriknl/</author>
|
||||
<link>http://kickass.to/battlestar-galactica-1978-dvd3-e09-e10-e11-e12-nl-fr-eng-sub-t9100642.html</link>
|
||||
<guid>http://kickass.to/battlestar-galactica-1978-dvd3-e09-e10-e11-e12-nl-fr-eng-sub-t9100642.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:15:46 +0000</pubDate>
|
||||
<torrent:contentLength>4680841216</torrent:contentLength>
|
||||
<torrent:infoHash>3D293CAFEDAC595F6E55F9C284DD76862FE254F6</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[magnet:?xt=urn:btih:3D293CAFEDAC595F6E55F9C284DD76862FE254F6&dn=battlestar+galactica+1978+dvd3+e09+e10+e11+e12+nl+fr+eng+sub&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce]]></torrent:magnetURI>
|
||||
<torrent:seeds>2</torrent:seeds>
|
||||
<torrent:peers>5</torrent:peers>
|
||||
<torrent:verified>0</torrent:verified>
|
||||
<torrent:fileName>battlestar.galactica.1978.dvd3.e09.e10.e11.e12.nl.fr.eng.sub.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/3D293CAFEDAC595F6E55F9C284DD76862FE254F6.torrent?title=%5Bkickass.to%5Dbattlestar.galactica.1978.dvd3.e09.e10.e11.e12.nl.fr.eng.sub" length="4680841216" type="application/x-bittorrent" />
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,93 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:torrent="http://xmlns.ezrss.it/0.1/">
|
||||
<channel>
|
||||
<title>tv torrents RSS feed - KickassTorrents</title>
|
||||
<link>http://kickass.to/</link>
|
||||
<description>tv torrents RSS feed</description>
|
||||
<item>
|
||||
<title>Doctor Strangér.E03.140512.HDTV.H264.720p-iPOP.avi [CTRG]</title>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/2NE1/</author>
|
||||
<link>http://kickass.to/doctor-stranger-e03-140512-hdtv-h264-720p-ipop-avi-ctrg-t9100648.html</link>
|
||||
<guid>http://kickass.to/doctor-stranger-e03-140512-hdtv-h264-720p-ipop-avi-ctrg-t9100648.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:16:49 +0000</pubDate>
|
||||
<torrent:contentLength>1205364736</torrent:contentLength>
|
||||
<torrent:infoHash>208C4F7866612CC88BFEBC7C496FA72C2368D1C0</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[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]]></torrent:magnetURI>
|
||||
<torrent:seeds>206</torrent:seeds>
|
||||
<torrent:peers>311</torrent:peers>
|
||||
<torrent:verified>1</torrent:verified>
|
||||
<torrent:fileName>doctor.stranger.e03.140512.hdtv.h264.720p.ipop.avi.ctrg.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/208C4F7866612CC88BFEBC7C496FA72C2368D1C0.torrent?title=%5Bkickass.to%5Ddoctor.stranger.e03.140512.hdtv.h264.720p.ipop.avi.ctrg" length="1205364736" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Triangle.E03.140512.HDTV.XViD-iPOP.avi [CTRG]</title>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/2NE1/</author>
|
||||
<link>http://kickass.to/triangle-e03-140512-hdtv-xvid-ipop-avi-ctrg-t9100647.html</link>
|
||||
<guid>http://kickass.to/triangle-e03-140512-hdtv-xvid-ipop-avi-ctrg-t9100647.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:16:31 +0000</pubDate>
|
||||
<torrent:contentLength>677543936</torrent:contentLength>
|
||||
<torrent:infoHash>BF22A53C9889A7D325F2A3D904E566B7DF4074EB</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[magnet:?xt=urn:btih:BF22A53C9889A7D325F2A3D904E566B7DF4074EB&dn=triangle+e03+140512+hdtv+xvid+ipop+avi+ctrg&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce]]></torrent:magnetURI>
|
||||
<torrent:seeds>242</torrent:seeds>
|
||||
<torrent:peers>374</torrent:peers>
|
||||
<torrent:verified>1</torrent:verified>
|
||||
<torrent:fileName>triangle.e03.140512.hdtv.xvid.ipop.avi.ctrg.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/BF22A53C9889A7D325F2A3D904E566B7DF4074EB.torrent?title=%5Bkickass.to%5Dtriangle.e03.140512.hdtv.xvid.ipop.avi.ctrg" length="677543936" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Triangle.E03.140512.HDTV.H264.720p-iPOP.avi [CTRG]</title>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/2NE1/</author>
|
||||
<link>http://kickass.to/triangle-e03-140512-hdtv-h264-720p-ipop-avi-ctrg-t9100646.html</link>
|
||||
<guid>http://kickass.to/triangle-e03-140512-hdtv-h264-720p-ipop-avi-ctrg-t9100646.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:16:10 +0000</pubDate>
|
||||
<torrent:contentLength>1196869632</torrent:contentLength>
|
||||
<torrent:infoHash>8427BFB8884B8228364EBB9B3EA7D8B77E03A7BC</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[magnet:?xt=urn:btih:8427BFB8884B8228364EBB9B3EA7D8B77E03A7BC&dn=triangle+e03+140512+hdtv+h264+720p+ipop+avi+ctrg&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce]]></torrent:magnetURI>
|
||||
<torrent:seeds>177</torrent:seeds>
|
||||
<torrent:peers>268</torrent:peers>
|
||||
<torrent:verified>1</torrent:verified>
|
||||
<torrent:fileName>triangle.e03.140512.hdtv.h264.720p.ipop.avi.ctrg.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/8427BFB8884B8228364EBB9B3EA7D8B77E03A7BC.torrent?title=%5Bkickass.to%5Dtriangle.e03.140512.hdtv.h264.720p.ipop.avi.ctrg" length="1196869632" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Triangle.E03.140512.HDTV.X264.720p-BarosG_.avi [CTRG]</title>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/2NE1/</author>
|
||||
<link>http://kickass.to/triangle-e03-140512-hdtv-x264-720p-barosg-avi-ctrg-t9100644.html</link>
|
||||
<guid>http://kickass.to/triangle-e03-140512-hdtv-x264-720p-barosg-avi-ctrg-t9100644.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:15:52 +0000</pubDate>
|
||||
<torrent:contentLength>1418906266</torrent:contentLength>
|
||||
<torrent:infoHash>5556B773893DB55287ECEC581E850B853163DB11</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[magnet:?xt=urn:btih:5556B773893DB55287ECEC581E850B853163DB11&dn=triangle+e03+140512+hdtv+x264+720p+barosg+avi+ctrg&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce]]></torrent:magnetURI>
|
||||
<torrent:seeds>522</torrent:seeds>
|
||||
<torrent:peers>785</torrent:peers>
|
||||
<torrent:verified>1</torrent:verified>
|
||||
<torrent:fileName>triangle.e03.140512.hdtv.x264.720p.barosg.avi.ctrg.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/5556B773893DB55287ECEC581E850B853163DB11.torrent?title=%5Bkickass.to%5Dtriangle.e03.140512.hdtv.x264.720p.barosg.avi.ctrg" length="1418906266" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Battlestar Galactica 1978 Dvd3 e09 e10 e11 e12 [NL] [FR] [ENG] Sub</title>
|
||||
<description>
|
||||
<![CDATA[In een afgelegen zonnestelsel leeft een mensenras op twaalf koloniewerelden. Ze zijn al eeuwen in oorlog met de Cylons, gevechtsrobots die ooit werden gemaakt door een allang verdwenen buitenaards reptielachtig ras. Met de hulp van de menselijke verrader Baltar zijn de Cylons erin geslaagd de mensheid vrijwel uit te roeien. Slechts een oorlogsschip kan aan de vernietiging ontkomen: de Battlestar Galactica van commandant Adama.
|
||||
|
||||
Met een vloot burgerschepen vol vluchtelingen vlucht de Galactica voor de Cylons. Adama besluit op zoek te gaan naar de legendarische 13e en laatste kolonie, genaamd Aarde. Tijdens de lange en gevaarlijke reis worden ze voortdurend bedreigd door de achtervolgende Cylons en andere gevaren.]]>
|
||||
</description>
|
||||
<category>TV</category>
|
||||
<author>http://kickass.to/user/hendriknl/</author>
|
||||
<link>http://kickass.to/battlestar-galactica-1978-dvd3-e09-e10-e11-e12-nl-fr-eng-sub-t9100642.html</link>
|
||||
<guid>http://kickass.to/battlestar-galactica-1978-dvd3-e09-e10-e11-e12-nl-fr-eng-sub-t9100642.html</guid>
|
||||
<pubDate>Mon, 12 May 2014 16:15:46 +0000</pubDate>
|
||||
<torrent:contentLength>4680841216</torrent:contentLength>
|
||||
<torrent:infoHash>3D293CAFEDAC595F6E55F9C284DD76862FE254F6</torrent:infoHash>
|
||||
<torrent:magnetURI><![CDATA[magnet:?xt=urn:btih:3D293CAFEDAC595F6E55F9C284DD76862FE254F6&dn=battlestar+galactica+1978+dvd3+e09+e10+e11+e12+nl+fr+eng+sub&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce]]></torrent:magnetURI>
|
||||
<torrent:seeds>2</torrent:seeds>
|
||||
<torrent:peers>5</torrent:peers>
|
||||
<torrent:verified>0</torrent:verified>
|
||||
<torrent:fileName>battlestar.galactica.1978.dvd3.e09.e10.e11.e12.nl.fr.eng.sub.torrent</torrent:fileName>
|
||||
<enclosure url="http://torcache.net/torrent/3D293CAFEDAC595F6E55F9C284DD76862FE254F6.torrent?title=%5Bkickass.to%5Dbattlestar.galactica.1978.dvd3.e09.e10.e11.e12.nl.fr.eng.sub" length="4680841216" type="application/x-bittorrent" />
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
281
src/NzbDrone.Core.Test/Files/Indexers/TorrentRss/AlphaRatio.xml
Normal file
@@ -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>
|
||||
@@ -0,0 +1,98 @@
|
||||
<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<channel>
|
||||
<title>limetorrents.cc - RSS Feed</title>
|
||||
<link>http://www.limetorrents.cc/</link>
|
||||
<description>Latest Torrents RSS.</description>
|
||||
<language>en-us</language>
|
||||
<pubDate>Thu, 16 Feb 2017 05:48:36 +0200</pubDate>
|
||||
<lastBuildDate>Thu, 16 Feb 2017 05:48:36 +0200</lastBuildDate>
|
||||
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
|
||||
<generator>limetorrents.cc RSS Generator 1.1</generator>
|
||||
<item>
|
||||
<title>The Expanse 2x04 (720p-HDTV-x264-SVA)[VTV]</title>
|
||||
<guid isPermaLink='true'>http://www.limetorrents.cc/The-Expanse-2x04-(720p-HDTV-x264-SVA)[VTV]-torrent-8643587.html</guid>
|
||||
<pubDate>16 Feb 2017 05:24:26 +0300</pubDate>
|
||||
<category>TV shows</category>
|
||||
<link>http://www.limetorrents.cc/The-Expanse-2x04-(720p-HDTV-x264-SVA)[VTV]-torrent-8643587.html</link>
|
||||
<size>880496711</size>
|
||||
<description>
|
||||
<![CDATA[
|
||||
Category: <a href="http://www.limetorrents.cc/browse-torrents/TV-shows/">TV shows</a><br />
|
||||
Seeds: 0<br />Leechers: 0<br />Size: 839.71 MB<br /><br /><a href="http://www.limetorrents.cc/The-Expanse-2x04-(720p-HDTV-x264-SVA)[VTV]-torrent-8643587.html">More @ limetorrents.cc</a><br /> ]]>
|
||||
</description>
|
||||
|
||||
<comments>http://www.limetorrents.cc/The-Expanse-2x04-(720p-HDTV-x264-SVA)[VTV]-torrent-8643587.html</comments>
|
||||
<category domain="http://www.limetorrents.cc/browse-torrents/TV shows">TV shows</category>
|
||||
<enclosure url="http://itorrents.org/torrent/51C578C9823DD58F6EEA287C368ED935843D63AB.torrent?title=The-Expanse-2x04-(720p-HDTV-x264-SVA)[VTV]" length="880496711" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Criminal Minds S12E13 720p HDTV x264-FLEET[PRiME]</title>
|
||||
<guid isPermaLink='true'>http://www.limetorrents.cc/Criminal-Minds-S12E13-720p-HDTV-x264-FLEET[PRiME]-torrent-8643586.html</guid>
|
||||
<pubDate>16 Feb 2017 05:20:49 +0300</pubDate>
|
||||
<category>TV shows</category>
|
||||
<link>http://www.limetorrents.cc/Criminal-Minds-S12E13-720p-HDTV-x264-FLEET[PRiME]-torrent-8643586.html</link>
|
||||
<size>940818158</size>
|
||||
<description>
|
||||
<![CDATA[
|
||||
Category: <a href="http://www.limetorrents.cc/browse-torrents/TV-shows/">TV shows</a><br />
|
||||
Seeds: 0<br />Leechers: 0<br />Size: 897.23 MB<br /><br /><a href="http://www.limetorrents.cc/Criminal-Minds-S12E13-720p-HDTV-x264-FLEET[PRiME]-torrent-8643586.html">More @ limetorrents.cc</a><br /> ]]>
|
||||
</description>
|
||||
|
||||
<comments>http://www.limetorrents.cc/Criminal-Minds-S12E13-720p-HDTV-x264-FLEET[PRiME]-torrent-8643586.html</comments>
|
||||
<category domain="http://www.limetorrents.cc/browse-torrents/TV shows">TV shows</category>
|
||||
<enclosure url="http://itorrents.org/torrent/C7EBCBE53A82E7C8F0826417F5174C8709DB9DC0.torrent?title=Criminal-Minds-S12E13-720p-HDTV-x264-FLEET[PRiME]" length="940818158" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Legion S01E02 720p HDTV x264-AVS[PRiME]</title>
|
||||
<guid isPermaLink='true'>http://www.limetorrents.cc/Legion-S01E02-720p-HDTV-x264-AVS[PRiME]-torrent-8643585.html</guid>
|
||||
<pubDate>16 Feb 2017 05:20:48 +0300</pubDate>
|
||||
<category>TV shows</category>
|
||||
<link>http://www.limetorrents.cc/Legion-S01E02-720p-HDTV-x264-AVS[PRiME]-torrent-8643585.html</link>
|
||||
<size>1320654292</size>
|
||||
<description>
|
||||
<![CDATA[
|
||||
Category: <a href="http://www.limetorrents.cc/browse-torrents/TV-shows/">TV shows</a><br />
|
||||
Seeds: 0<br />Leechers: 0<br />Size: 1.23 GB<br /><br /><a href="http://www.limetorrents.cc/Legion-S01E02-720p-HDTV-x264-AVS[PRiME]-torrent-8643585.html">More @ limetorrents.cc</a><br /> ]]>
|
||||
</description>
|
||||
|
||||
<comments>http://www.limetorrents.cc/Legion-S01E02-720p-HDTV-x264-AVS[PRiME]-torrent-8643585.html</comments>
|
||||
<category domain="http://www.limetorrents.cc/browse-torrents/TV shows">TV shows</category>
|
||||
<enclosure url="http://itorrents.org/torrent/ED2903DB3F4B3D728D2E7091C33B6F502A0FB5D4.torrent?title=Legion-S01E02-720p-HDTV-x264-AVS[PRiME]" length="1320654292" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Suits S06E14 HDTV x264-SVA[PRiME]</title>
|
||||
<guid isPermaLink='true'>http://www.limetorrents.cc/Suits-S06E14-HDTV-x264-SVA[PRiME]-torrent-8643579.html</guid>
|
||||
<pubDate>16 Feb 2017 05:11:58 +0300</pubDate>
|
||||
<category>TV shows</category>
|
||||
<link>http://www.limetorrents.cc/Suits-S06E14-HDTV-x264-SVA[PRiME]-torrent-8643579.html</link>
|
||||
<size>212274667</size>
|
||||
<description>
|
||||
<![CDATA[
|
||||
Category: <a href="http://www.limetorrents.cc/browse-torrents/TV-shows/">TV shows</a><br />
|
||||
Seeds: 0<br />Leechers: 0<br />Size: 202.44 MB<br /><br /><a href="http://www.limetorrents.cc/Suits-S06E14-HDTV-x264-SVA[PRiME]-torrent-8643579.html">More @ limetorrents.cc</a><br /> ]]>
|
||||
</description>
|
||||
|
||||
<comments>http://www.limetorrents.cc/Suits-S06E14-HDTV-x264-SVA[PRiME]-torrent-8643579.html</comments>
|
||||
<category domain="http://www.limetorrents.cc/browse-torrents/TV shows">TV shows</category>
|
||||
<enclosure url="http://itorrents.org/torrent/5E412B3200773684AEDBEBF9B053ED58180279DD.torrent?title=Suits-S06E14-HDTV-x264-SVA[PRiME]" length="212274667" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>The Expanse S02E04 HDTV x264-SVA[PRiME]</title>
|
||||
<guid isPermaLink='true'>http://www.limetorrents.cc/The-Expanse-S02E04-HDTV-x264-SVA[PRiME]-torrent-8643578.html</guid>
|
||||
<pubDate>16 Feb 2017 05:11:57 +0300</pubDate>
|
||||
<category>TV shows</category>
|
||||
<link>http://www.limetorrents.cc/The-Expanse-S02E04-HDTV-x264-SVA[PRiME]-torrent-8643578.html</link>
|
||||
<size>269445781</size>
|
||||
<description>
|
||||
<![CDATA[
|
||||
Category: <a href="http://www.limetorrents.cc/browse-torrents/TV-shows/">TV shows</a><br />
|
||||
Seeds: 0<br />Leechers: 0<br />Size: 256.96 MB<br /><br /><a href="http://www.limetorrents.cc/The-Expanse-S02E04-HDTV-x264-SVA[PRiME]-torrent-8643578.html">More @ limetorrents.cc</a><br /> ]]>
|
||||
</description>
|
||||
|
||||
<comments>http://www.limetorrents.cc/The-Expanse-S02E04-HDTV-x264-SVA[PRiME]-torrent-8643578.html</comments>
|
||||
<category domain="http://www.limetorrents.cc/browse-torrents/TV shows">TV shows</category>
|
||||
<enclosure url="http://itorrents.org/torrent/7E552CD2D99E43C34FBB233E3BAF0C1ECD416C76.torrent?title=The-Expanse-S02E04-HDTV-x264-SVA[PRiME]" length="269445781" type="application/x-bittorrent" />
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,78 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0">
|
||||
|
||||
<channel>
|
||||
<title>Womble's NZB Index</title>
|
||||
<link>http://indexer.local/</link>
|
||||
<description>NZB Index</description>
|
||||
<webMaster>my.email@internet.me</webMaster>
|
||||
<ttl>15</ttl>
|
||||
|
||||
|
||||
<item>
|
||||
<title>One.Child.S01E01.720p.HDTV.x264-TLA</title>
|
||||
<link>http://indexer.local/nzb/bb4/One.Child.S01E01.720p.HDTV.x264-TLA.nzb</link>
|
||||
<description>
|
||||
One.Child.S01E01.720p.HDTV.x264-TLA
|
||||
(Size:956 Mb)
|
||||
</description>
|
||||
<category>tv-hd</category>
|
||||
<pubDate>2/17/2016 11:03:52 PM</pubDate>
|
||||
<guid isPermaLink="true">http://indexer.local/nzb/bb4/One.Child.S01E01.720p.HDTV.x264-TLA.nzb</guid>
|
||||
<enclosure url="http://indexer.local/nzb/bb4/One.Child.S01E01.720p.HDTV.x264-TLA.nzb" length="2048" type="text/xml" />
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Midsomer.Murders.S18E06.Harvest.Of.Souls.HDTV.x264-ORGANiC</title>
|
||||
<link>http://indexer.local/nzb/17c/Midsomer.Murders.S18E06.Harvest.Of.Souls.HDTV.x264-ORGANiC.nzb</link>
|
||||
<description>
|
||||
Midsomer.Murders.S18E06.Harvest.Of.Souls.HDTV.x264-ORGANiC
|
||||
(Size:730 Mb)
|
||||
</description>
|
||||
<category>tv-sd</category>
|
||||
<pubDate>2/17/2016 10:55:33 PM</pubDate>
|
||||
<guid isPermaLink="true">http://indexer.local/nzb/17c/Midsomer.Murders.S18E06.Harvest.Of.Souls.HDTV.x264-ORGANiC.nzb</guid>
|
||||
<enclosure url="http://indexer.local/nzb/17c/Midsomer.Murders.S18E06.Harvest.Of.Souls.HDTV.x264-ORGANiC.nzb" length="2048" type="text/xml" />
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Forget.and.Forgive.2014.HDTV.x264-SQUEAK</title>
|
||||
<link>http://indexer.local/nzb/f3f/Forget.and.Forgive.2014.HDTV.x264-SQUEAK.nzb</link>
|
||||
<description>
|
||||
Forget.and.Forgive.2014.HDTV.x264-SQUEAK
|
||||
(Size:719 Mb)
|
||||
</description>
|
||||
<category>tv-sd</category>
|
||||
<pubDate>2/17/2016 10:25:28 PM</pubDate>
|
||||
<guid isPermaLink="true">http://indexer.local/nzb/f3f/Forget.and.Forgive.2014.HDTV.x264-SQUEAK.nzb</guid>
|
||||
<enclosure url="http://indexer.local/nzb/f3f/Forget.and.Forgive.2014.HDTV.x264-SQUEAK.nzb" length="2048" type="text/xml" />
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>National.Geographic.The.Lakeshore.Killers.HDTV.x264-SQUEAK</title>
|
||||
<link>http://indexer.local/nzb/828/National.Geographic.The.Lakeshore.Killers.HDTV.x264-SQUEAK.nzb</link>
|
||||
<description>
|
||||
National.Geographic.The.Lakeshore.Killers.HDTV.x264-SQUEAK
|
||||
(Size:436 Mb)
|
||||
</description>
|
||||
<category>tv-sd</category>
|
||||
<pubDate>2/17/2016 10:20:36 PM</pubDate>
|
||||
<guid isPermaLink="true">http://indexer.local/nzb/828/National.Geographic.The.Lakeshore.Killers.HDTV.x264-SQUEAK.nzb</guid>
|
||||
<enclosure url="http://indexer.local/nzb/828/National.Geographic.The.Lakeshore.Killers.HDTV.x264-SQUEAK.nzb" length="2048" type="text/xml" />
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<title>Desert.Lands.of.The.Middle.East.E01.Turkeys.Harsh.Paradise.HDTV.x264-SQUEAK</title>
|
||||
<link>http://indexer.local/nzb/210/Desert.Lands.of.The.Middle.East.E01.Turkeys.Harsh.Paradise.HDTV.x264-SQUEAK.nzb</link>
|
||||
<description>
|
||||
Desert.Lands.of.The.Middle.East.E01.Turkeys.Harsh.Paradise.HDTV.x264-SQUEAK
|
||||
(Size:460 Mb)
|
||||
</description>
|
||||
<category>tv-sd</category>
|
||||
<pubDate>2/17/2016 10:18:29 PM</pubDate>
|
||||
<guid isPermaLink="true">http://indexer.local/nzb/210/Desert.Lands.of.The.Middle.East.E01.Turkeys.Harsh.Paradise.HDTV.x264-SQUEAK.nzb</guid>
|
||||
<enclosure url="http://indexer.local/nzb/210/Desert.Lands.of.The.Middle.East.E01.Turkeys.Harsh.Paradise.HDTV.x264-SQUEAK.nzb" length="2048" type="text/xml" />
|
||||
</item>
|
||||
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -99,7 +99,6 @@ namespace NzbDrone.Core.Test.Framework
|
||||
{
|
||||
WithTempAsAppPath();
|
||||
|
||||
Mocker.SetConstant<IAnnouncer>(Mocker.Resolve<MigrationLogger>());
|
||||
Mocker.SetConstant<IConnectionStringFactory>(Mocker.Resolve<ConnectionStringFactory>());
|
||||
Mocker.SetConstant<IMigrationController>(Mocker.Resolve<MigrationController>());
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace NzbDrone.Core.Test.Framework
|
||||
{
|
||||
List<Dictionary<string, object>> Query(string sql);
|
||||
List<T> Query<T>(string sql) where T : new();
|
||||
T QueryScalar<T>(string sql);
|
||||
}
|
||||
|
||||
public class DirectDataMapper : IDirectDataMapper
|
||||
@@ -25,7 +26,7 @@ namespace NzbDrone.Core.Test.Framework
|
||||
_providerFactory = dataMapper.ProviderFactory;
|
||||
_connectionString = dataMapper.ConnectionString;
|
||||
}
|
||||
|
||||
|
||||
private DbConnection OpenConnection()
|
||||
{
|
||||
var connection = _providerFactory.CreateConnection();
|
||||
@@ -62,6 +63,13 @@ namespace NzbDrone.Core.Test.Framework
|
||||
return dataTable.Rows.Cast<DataRow>().Select(MapToObject<T>).ToList();
|
||||
}
|
||||
|
||||
public T QueryScalar<T>(string sql)
|
||||
{
|
||||
var dataTable = GetDataTable(sql);
|
||||
|
||||
return dataTable.Rows.Cast<DataRow>().Select(d => MapValue(d, 0, typeof(T))).Cast<T>().FirstOrDefault();
|
||||
}
|
||||
|
||||
protected Dictionary<string, object> MapToDictionary(DataRow dataRow)
|
||||
{
|
||||
var item = new Dictionary<string, object>();
|
||||
@@ -107,24 +115,29 @@ namespace NzbDrone.Core.Test.Framework
|
||||
propertyType = propertyType.GetGenericArguments()[0];
|
||||
}
|
||||
|
||||
object value;
|
||||
if (dataRow.ItemArray[i] == DBNull.Value)
|
||||
{
|
||||
value = null;
|
||||
}
|
||||
else if (dataRow.Table.Columns[i].DataType == typeof(string) && propertyType != typeof(string))
|
||||
{
|
||||
value = Json.Deserialize((string)dataRow.ItemArray[i], propertyType);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = Convert.ChangeType(dataRow.ItemArray[i], propertyType);
|
||||
}
|
||||
object value = MapValue(dataRow, i, propertyType);
|
||||
|
||||
|
||||
propertyInfo.SetValue(item, value, null);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private object MapValue(DataRow dataRow, int i, Type targetType)
|
||||
{
|
||||
if (dataRow.ItemArray[i] == DBNull.Value)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (dataRow.Table.Columns[i].DataType == typeof(string) && targetType != typeof(string))
|
||||
{
|
||||
return Json.Deserialize((string)dataRow.ItemArray[i], targetType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ChangeType(dataRow.ItemArray[i], targetType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using FluentMigrator;
|
||||
using FluentMigrator.Runner;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Test.Common.AutoMoq;
|
||||
|
||||
namespace NzbDrone.Core.Test.Framework
|
||||
{
|
||||
@@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.Framework
|
||||
BeforeMigration = m =>
|
||||
{
|
||||
var migration = m as TMigration;
|
||||
if (beforeMigration != null && migration is TMigration)
|
||||
if (beforeMigration != null && migration != null)
|
||||
{
|
||||
beforeMigration(migration);
|
||||
}
|
||||
@@ -39,10 +39,8 @@ namespace NzbDrone.Core.Test.Framework
|
||||
[SetUp]
|
||||
public override void SetupDb()
|
||||
{
|
||||
Mocker.SetConstant<IAnnouncer>(Mocker.Resolve<MigrationLogger>());
|
||||
SetupContainer();
|
||||
}
|
||||
|
||||
[Obsolete("Don't use Mocker/Repositories in MigrationTests, query the DB.", true)]
|
||||
public new AutoMoqer Mocker => base.Mocker;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using FluentAssertions;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.HealthCheck;
|
||||
|
||||
namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||
@@ -10,14 +11,24 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,22 @@ using NzbDrone.Core.Test.Framework;
|
||||
namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||
{
|
||||
[TestFixture]
|
||||
public class IndexerCheckFixture : CoreTest<IndexerCheck>
|
||||
public class IndexerSearchCheckFixture : CoreTest<IndexerSearchCheck>
|
||||
{
|
||||
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)
|
||||
{
|
||||
_indexerMock = Mocker.GetMock<IIndexer>();
|
||||
@@ -21,42 +33,30 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(s => s.GetAvailableProviders())
|
||||
.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()
|
||||
{
|
||||
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 });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_error_when_not_indexers_are_enabled()
|
||||
public void should_return_warning_when_no_indexer_present()
|
||||
{
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(s => s.GetAvailableProviders())
|
||||
.Returns(new List<IIndexer>());
|
||||
|
||||
Subject.Check().ShouldBeError();
|
||||
Subject.Check().ShouldBeWarning();
|
||||
}
|
||||
|
||||
[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);
|
||||
|
||||
@@ -64,7 +64,16 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||
}
|
||||
|
||||
[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);
|
||||
|
||||
@@ -72,52 +81,12 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_ok_when_multiple_indexers_are_enabled()
|
||||
public void should_return_filter_warning_if_search_is_enabled_but_filtered()
|
||||
{
|
||||
GivenRssEnabled();
|
||||
GivenSearchEnabled();
|
||||
GivenIndexer(false, true);
|
||||
GivenSearchFiltered();
|
||||
|
||||
var indexer1 = Mocker.GetMock<IIndexer>();
|
||||
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();
|
||||
Subject.Check().ShouldBeWarning("recent indexer errors");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,10 +81,10 @@ namespace NzbDrone.Core.Test.HistoryTests
|
||||
Path = @"C:\Test\Unsorted\Series.s01e01.mkv"
|
||||
};
|
||||
|
||||
Subject.Handle(new EpisodeImportedEvent(localEpisode, episodeFile, true, "sab", "abcd", true));
|
||||
Subject.Handle(new EpisodeImportedEvent(localEpisode, episodeFile, true, "sab", "abcd"));
|
||||
|
||||
Mocker.GetMock<IHistoryRepository>()
|
||||
.Verify(v => v.Insert(It.Is<History.History>(h => h.SourceTitle == Path.GetFileNameWithoutExtension(localEpisode.Path))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
_mockIndexer.SetupGet(s => s.SupportsSearch).Returns(true);
|
||||
|
||||
Mocker.GetMock<IIndexerFactory>()
|
||||
.Setup(s => s.SearchEnabled())
|
||||
.Setup(s => s.SearchEnabled(true))
|
||||
.Returns(new List<IIndexer> { _mockIndexer.Object });
|
||||
|
||||
Mocker.GetMock<IMakeDownloadDecision>()
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.IndexerTests.BroadcastheNetTests
|
||||
Subject.Definition = new IndexerDefinition()
|
||||
{
|
||||
Name = "BroadcastheNet",
|
||||
Settings = new BroadcastheNetSettings() { ApiKey = "abc", BaseUrl = "https://api.btnapps.net/" }
|
||||
Settings = new BroadcastheNetSettings() { ApiKey = "abc", BaseUrl = "https://api.broadcasthe.net/" }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace NzbDrone.Core.Test.IndexerTests.BroadcastheNetTests
|
||||
{
|
||||
var recentFeed = ReadAllText(@"Files/Indexers/BroadcastheNet/RecentFeed.json");
|
||||
|
||||
(Subject.Definition.Settings as BroadcastheNetSettings).BaseUrl = "http://api.btnapps.net/";
|
||||
(Subject.Definition.Settings as BroadcastheNetSettings).BaseUrl = "http://api.broadcasthe.net/";
|
||||
|
||||
recentFeed = recentFeed.Replace("http:", "https:");
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ using NUnit.Framework;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.Newznab;
|
||||
using NzbDrone.Core.Indexers.Omgwtfnzbs;
|
||||
using NzbDrone.Core.Indexers.Wombles;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
@@ -22,7 +21,6 @@ namespace NzbDrone.Core.Test.IndexerTests
|
||||
|
||||
_indexers.Add(Mocker.Resolve<Newznab>());
|
||||
_indexers.Add(Mocker.Resolve<Omgwtfnzbs>());
|
||||
_indexers.Add(Mocker.Resolve<Wombles>());
|
||||
|
||||
Mocker.SetConstant<IEnumerable<IIndexer>>(_indexers);
|
||||
}
|
||||
@@ -44,4 +42,4 @@ namespace NzbDrone.Core.Test.IndexerTests
|
||||
AllStoredModels.Should().NotContain(c => c.Id == existingIndexers.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.KickassTorrents;
|
||||
using NzbDrone.Core.Indexers.Nyaa;
|
||||
using NzbDrone.Core.Indexers.Wombles;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
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]
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
using FluentAssertions;
|
||||
using System;
|
||||
using System.Xml;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers.Newznab;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
|
||||
{
|
||||
@@ -64,5 +67,35 @@ namespace NzbDrone.Core.Test.IndexerTests.NewznabTests
|
||||
caps.DefaultPageSize.Should().Be(100);
|
||||
caps.MaxPageSize.Should().Be(100);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_failed_to_get()
|
||||
{
|
||||
Mocker.GetMock<IHttpClient>()
|
||||
.Setup(o => o.Get(It.IsAny<HttpRequest>()))
|
||||
.Throws<Exception>();
|
||||
|
||||
Assert.Throws<Exception>(() => Subject.GetCapabilities(_settings));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_xml_invalid()
|
||||
{
|
||||
GivenCapsResponse(_caps.Replace("<limits", "<>"));
|
||||
|
||||
Assert.Throws<XmlException>(() => Subject.GetCapabilities(_settings));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_throw_on_xml_data_unexpected()
|
||||
{
|
||||
GivenCapsResponse(_caps.Replace("5030", "asdf"));
|
||||
|
||||
var result = Subject.GetCapabilities(_settings);
|
||||
|
||||
result.Should().NotBeNull();
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +173,32 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
torrentInfo.Seeders.Should().NotHaveValue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_LimeTorrents()
|
||||
{
|
||||
GivenRecentFeedResponse("TorrentRss/LimeTorrents.xml");
|
||||
|
||||
var releases = Subject.FetchRecent();
|
||||
|
||||
releases.Should().HaveCount(5);
|
||||
releases.First().Should().BeOfType<TorrentInfo>();
|
||||
|
||||
var torrentInfo = releases.First() as TorrentInfo;
|
||||
|
||||
torrentInfo.Title.Should().Be("The Expanse 2x04 (720p-HDTV-x264-SVA)[VTV]");
|
||||
torrentInfo.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||
torrentInfo.DownloadUrl.Should().Be("http://itorrents.org/torrent/51C578C9823DD58F6EEA287C368ED935843D63AB.torrent?title=The-Expanse-2x04-(720p-HDTV-x264-SVA)[VTV]");
|
||||
torrentInfo.InfoUrl.Should().BeNullOrEmpty();
|
||||
torrentInfo.CommentUrl.Should().Be("http://www.limetorrents.cc/The-Expanse-2x04-(720p-HDTV-x264-SVA)[VTV]-torrent-8643587.html");
|
||||
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
|
||||
torrentInfo.PublishDate.Should().Be(DateTime.Parse("16 Feb 2017 05:24:26 +0300").ToUniversalTime());
|
||||
torrentInfo.Size.Should().Be(880496711);
|
||||
torrentInfo.InfoHash.Should().BeNull();
|
||||
torrentInfo.MagnetUrl.Should().BeNull();
|
||||
torrentInfo.Peers.Should().NotHaveValue();
|
||||
torrentInfo.Seeders.Should().NotHaveValue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_recent_feed_from_AnimeTosho_without_size()
|
||||
{
|
||||
@@ -215,5 +241,22 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
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");
|
||||
}
|
||||
|
||||
[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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +180,46 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_detect_rss_settings_for_LimeTorrents()
|
||||
{
|
||||
_indexerSettings.AllowZeroSize = true;
|
||||
|
||||
GivenRecentFeedResponse("TorrentRss/LimeTorrents.xml");
|
||||
|
||||
var settings = Subject.Detect(_indexerSettings);
|
||||
|
||||
settings.ShouldBeEquivalentTo(new TorrentRssIndexerParserSettings
|
||||
{
|
||||
UseEZTVFormat = false,
|
||||
UseEnclosureUrl = true,
|
||||
UseEnclosureLength = true,
|
||||
ParseSizeInDescription = false,
|
||||
ParseSeedersInDescription = false,
|
||||
SizeElementName = null
|
||||
});
|
||||
}
|
||||
|
||||
[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]
|
||||
[Ignore("Cannot reliably reject unparseable titles")]
|
||||
public void should_reject_rss_settings_for_AwesomeHD()
|
||||
@@ -215,7 +255,6 @@ namespace NzbDrone.Core.Test.IndexerTests.TorrentRssIndexerTests
|
||||
|
||||
[TestCase("BitMeTv/BitMeTv.xml")]
|
||||
[TestCase("Fanzub/fanzub.xml")]
|
||||
[TestCase("KickassTorrents/KickassTorrents.xml")]
|
||||
[TestCase("IPTorrents/IPTorrents.xml")]
|
||||
[TestCase("Newznab/newznab_nzb_su.xml")]
|
||||
[TestCase("Nyaa/Nyaa.xml")]
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
@@ -17,28 +18,50 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
public class ScanFixture : CoreTest<DiskScanService>
|
||||
{
|
||||
private Series _series;
|
||||
private string _rootFolder;
|
||||
private string _otherSeriesFolder;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_rootFolder = @"C:\Test\TV".AsOsAgnostic();
|
||||
_otherSeriesFolder = @"C:\Test\TV\OtherSeries".AsOsAgnostic();
|
||||
var seriesFolder = @"C:\Test\TV\Series".AsOsAgnostic();
|
||||
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.With(s => s.Path = @"C:\Test\TV\Series".AsOsAgnostic())
|
||||
.With(s => s.Path = seriesFolder)
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.FolderExists(It.IsAny<string>()))
|
||||
.Returns(false);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.GetParentFolder(It.IsAny<string>()))
|
||||
.Returns((string path) => Directory.GetParent(path).FullName);
|
||||
}
|
||||
|
||||
private void GivenParentFolderExists()
|
||||
private void GivenRootFolder(params string[] subfolders)
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.FolderExists(It.IsAny<string>()))
|
||||
.Setup(s => s.FolderExists(_rootFolder))
|
||||
.Returns(true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.GetDirectories(It.IsAny<string>()))
|
||||
.Returns(new string[] { @"C:\Test\TV\Series2".AsOsAgnostic() });
|
||||
.Setup(s => s.GetDirectories(_rootFolder))
|
||||
.Returns(subfolders);
|
||||
|
||||
foreach (var folder in subfolders)
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.FolderExists(folder))
|
||||
.Returns(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void GivenSeriesFolder()
|
||||
{
|
||||
GivenRootFolder(_series.Path);
|
||||
}
|
||||
|
||||
private void GivenFiles(IEnumerable<string> files)
|
||||
@@ -49,39 +72,124 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_scan_if_series_root_folder_does_not_exist()
|
||||
{
|
||||
public void should_not_scan_if_root_folder_does_not_exist()
|
||||
{
|
||||
Subject.Scan(_series);
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.FolderExists(_series.Path), Times.Never());
|
||||
|
||||
Mocker.GetMock<IMediaFileTableCleanupService>()
|
||||
.Verify(v => v.Clean(It.IsAny<Series>(), It.IsAny<List<string>>()), Times.Never());
|
||||
.Verify(v => v.Clean(It.IsAny<Series>(), It.IsAny<List<string>>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_scan_if_series_root_folder_is_empty()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.FolderExists(It.IsAny<string>()))
|
||||
.Returns(true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(s => s.GetDirectories(It.IsAny<string>()))
|
||||
.Returns(new string[0]);
|
||||
GivenRootFolder();
|
||||
|
||||
Subject.Scan(_series);
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.FolderExists(_series.Path), Times.Never());
|
||||
|
||||
Mocker.GetMock<IMediaFileTableCleanupService>()
|
||||
.Verify(v => v.Clean(It.IsAny<Series>(), new List<string>()), Times.Never());
|
||||
.Verify(v => v.Clean(It.IsAny<Series>(), It.IsAny<List<string>>()), Times.Never());
|
||||
|
||||
Mocker.GetMock<IMakeImportDecision>()
|
||||
.Verify(v => v.GetImportDecisions(It.IsAny<List<string>>(), _series), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_create_if_series_folder_does_not_exist_but_create_folder_enabled()
|
||||
{
|
||||
GivenRootFolder(_otherSeriesFolder);
|
||||
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.CreateEmptySeriesFolders)
|
||||
.Returns(true);
|
||||
|
||||
Subject.Scan(_series);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.CreateFolder(_series.Path), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_create_if_series_folder_does_not_exist_and_create_folder_disabled()
|
||||
{
|
||||
GivenRootFolder(_otherSeriesFolder);
|
||||
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.CreateEmptySeriesFolders)
|
||||
.Returns(false);
|
||||
|
||||
Subject.Scan(_series);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.CreateFolder(_series.Path), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_clean_but_not_import_if_series_folder_does_not_exist()
|
||||
{
|
||||
GivenRootFolder(_otherSeriesFolder);
|
||||
|
||||
Subject.Scan(_series);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.FolderExists(_series.Path), Times.Once());
|
||||
|
||||
Mocker.GetMock<IMediaFileTableCleanupService>()
|
||||
.Verify(v => v.Clean(It.IsAny<Series>(), It.IsAny<List<string>>()), Times.Once());
|
||||
|
||||
Mocker.GetMock<IMakeImportDecision>()
|
||||
.Verify(v => v.GetImportDecisions(It.IsAny<List<string>>(), _series), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_clean_but_not_import_if_series_folder_does_not_exist_and_create_folder_enabled()
|
||||
{
|
||||
GivenRootFolder(_otherSeriesFolder);
|
||||
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.CreateEmptySeriesFolders)
|
||||
.Returns(true);
|
||||
|
||||
Subject.Scan(_series);
|
||||
|
||||
Mocker.GetMock<IMediaFileTableCleanupService>()
|
||||
.Verify(v => v.Clean(It.IsAny<Series>(), It.IsAny<List<string>>()), Times.Once());
|
||||
|
||||
Mocker.GetMock<IMakeImportDecision>()
|
||||
.Verify(v => v.GetImportDecisions(It.IsAny<List<string>>(), _series), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_find_files_at_root_of_series_folder()
|
||||
{
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
Path.Combine(_series.Path, "file1.mkv").AsOsAgnostic(),
|
||||
Path.Combine(_series.Path, "s01e01.mkv").AsOsAgnostic()
|
||||
});
|
||||
|
||||
Subject.Scan(_series);
|
||||
|
||||
Mocker.GetMock<IMakeImportDecision>()
|
||||
.Verify(v => v.GetImportDecisions(It.Is<List<string>>(l => l.Count == 2), _series), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_scan_extras_subfolder()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
@@ -94,6 +202,9 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
|
||||
Subject.Scan(_series);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetFiles(It.IsAny<string>(), It.IsAny<SearchOption>()), Times.Once());
|
||||
|
||||
Mocker.GetMock<IMakeImportDecision>()
|
||||
.Verify(v => v.GetImportDecisions(It.Is<List<string>>(l => l.Count == 1), _series), Times.Once());
|
||||
}
|
||||
@@ -101,7 +212,7 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
[Test]
|
||||
public void should_not_scan_AppleDouble_subfolder()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
@@ -119,9 +230,10 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
[Test]
|
||||
public void should_scan_extras_series_and_subfolders()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
_series.Path = @"C:\Test\TV\Extras".AsOsAgnostic();
|
||||
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
Path.Combine(_series.Path, "Extras", "file1.mkv").AsOsAgnostic(),
|
||||
@@ -141,7 +253,7 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
[Test]
|
||||
public void should_not_scan_subfolders_that_start_with_period()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
@@ -160,7 +272,7 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
[Test]
|
||||
public void should_not_scan_subfolder_of_season_folder_that_starts_with_a_period()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
@@ -180,7 +292,7 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
[Test]
|
||||
public void should_not_scan_Synology_eaDir()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
@@ -197,7 +309,7 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
[Test]
|
||||
public void should_not_scan_thumb_folder()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
@@ -214,9 +326,10 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
[Test]
|
||||
public void should_scan_dotHack_folder()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
_series.Path = @"C:\Test\TV\.hack".AsOsAgnostic();
|
||||
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
Path.Combine(_series.Path, "Season 1", "file1.mkv").AsOsAgnostic(),
|
||||
@@ -229,27 +342,10 @@ namespace NzbDrone.Core.Test.MediaFiles.DiskScanServiceTests
|
||||
.Verify(v => v.GetImportDecisions(It.Is<List<string>>(l => l.Count == 2), _series), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_find_files_at_root_of_series_folder()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
Path.Combine(_series.Path, "file1.mkv").AsOsAgnostic(),
|
||||
Path.Combine(_series.Path, "s01e01.mkv").AsOsAgnostic()
|
||||
});
|
||||
|
||||
Subject.Scan(_series);
|
||||
|
||||
Mocker.GetMock<IMakeImportDecision>()
|
||||
.Verify(v => v.GetImportDecisions(It.Is<List<string>>(l => l.Count == 2), _series), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_exclude_osx_metadata_files()
|
||||
{
|
||||
GivenParentFolderExists();
|
||||
GivenSeriesFolder();
|
||||
|
||||
GivenFiles(new List<string>
|
||||
{
|
||||
|
||||