mirror of
https://github.com/Radarr/Radarr.git
synced 2026-03-24 17:25:22 -04:00
Compare commits
158 Commits
v2.0.0.324
...
v2.0.0.335
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
492b114510 | ||
|
|
55412968e0 | ||
|
|
dba359cafe | ||
|
|
6682266cc9 | ||
|
|
05dc68d689 | ||
|
|
8fede1efc9 | ||
|
|
8d85fb15c4 | ||
|
|
32d7da91b7 | ||
|
|
08ebc8d292 | ||
|
|
ada5919136 | ||
|
|
bfa629f431 | ||
|
|
2a42ad8970 | ||
|
|
08714f79da | ||
|
|
6983f36f4d | ||
|
|
03cf9a44cf | ||
|
|
c4fe645c31 | ||
|
|
ea19020015 | ||
|
|
346d7f3cf4 | ||
|
|
1b65ead75d | ||
|
|
889d3d1207 | ||
|
|
3c88f6c452 | ||
|
|
cc6ab0ade1 | ||
|
|
3ad7673d69 | ||
|
|
51155ba909 | ||
|
|
786e0b825a | ||
|
|
7bc4249ede | ||
|
|
fd3dda2b16 | ||
|
|
fa0401fa89 | ||
|
|
15b215f9c2 | ||
|
|
61de750e05 | ||
|
|
84ae81efe3 | ||
|
|
5c6ac2ae8b | ||
|
|
265821c9de | ||
|
|
1eb6629088 | ||
|
|
103de770c3 | ||
|
|
bf3d0ed2d1 | ||
|
|
3a84e0fafc | ||
|
|
4b9ec94fcc | ||
|
|
067f450486 | ||
|
|
dbb3eb0e54 | ||
|
|
30ab5bc17f | ||
|
|
8917ea9cc9 | ||
|
|
c5684439f4 | ||
|
|
d46c170b70 | ||
|
|
de8deffbd2 | ||
|
|
0578e68a51 | ||
|
|
1ac27002e5 | ||
|
|
2f3e444394 | ||
|
|
c02d6c426c | ||
|
|
102f2e39be | ||
|
|
a78381db7d | ||
|
|
a143c0b75e | ||
|
|
36f97329ff | ||
|
|
b5b15b623a | ||
|
|
724a3eee45 | ||
|
|
80403a4021 | ||
|
|
14b9a031bb | ||
|
|
873fadbcaa | ||
|
|
370406c3de | ||
|
|
461be2b388 | ||
|
|
dc75c44a50 | ||
|
|
c9d0bc7148 | ||
|
|
77e9493ccf | ||
|
|
120be567d3 | ||
|
|
cce82d38c0 | ||
|
|
527122452c | ||
|
|
c4430ab4de | ||
|
|
c9f720885e | ||
|
|
bd222dbd95 | ||
|
|
c9ef0951bc | ||
|
|
6f8cbc22be | ||
|
|
2b6bac8104 | ||
|
|
a9ada8fcf1 | ||
|
|
c7f56c1091 | ||
|
|
7d0ba9dd2b | ||
|
|
f3d31c3ea1 | ||
|
|
2c472d6e3e | ||
|
|
54a6f7c05b | ||
|
|
754237c57b | ||
|
|
0c56fddecf | ||
|
|
a7523ed462 | ||
|
|
51f705d89a | ||
|
|
569ef09f39 | ||
|
|
71f3435026 | ||
|
|
7e89bcca38 | ||
|
|
92cff8c4cc | ||
|
|
4c1e211675 | ||
|
|
3df5d9444b | ||
|
|
c42e322949 | ||
|
|
963f1a168e | ||
|
|
36629242d1 | ||
|
|
408ff983cf | ||
|
|
92b87b9d21 | ||
|
|
c9f1039ab4 | ||
|
|
3c52a9066c | ||
|
|
4c3c705517 | ||
|
|
5a2fa41af7 | ||
|
|
27980b2cd6 | ||
|
|
fc572500e4 | ||
|
|
155c82c199 | ||
|
|
28e2cf97da | ||
|
|
acaa07c69d | ||
|
|
6fd7a64330 | ||
|
|
546f4ab577 | ||
|
|
5effca92b8 | ||
|
|
aa4fca7177 | ||
|
|
860d7ed079 | ||
|
|
eb8af60029 | ||
|
|
225489738d | ||
|
|
ccff4fe142 | ||
|
|
cd5b00afa8 | ||
|
|
866f971d41 | ||
|
|
6d18b37a94 | ||
|
|
de3ba041f2 | ||
|
|
a2d8413b2a | ||
|
|
1fbbfb3317 | ||
|
|
724981db57 | ||
|
|
aae3970865 | ||
|
|
49718fbfbe | ||
|
|
587ad5beb5 | ||
|
|
4de20b09a8 | ||
|
|
f7adb19474 | ||
|
|
a1ff7cbef0 | ||
|
|
1cc6ad0d5f | ||
|
|
aa78807ee2 | ||
|
|
5fda64de66 | ||
|
|
75a50b83fb | ||
|
|
78ade3250c | ||
|
|
fac6b05bb4 | ||
|
|
39aef8bed5 | ||
|
|
99e9e4f5fd | ||
|
|
70544738ed | ||
|
|
90469630d1 | ||
|
|
7a74327761 | ||
|
|
ba2da07c2f | ||
|
|
5363a9e8d7 | ||
|
|
4010a5336c | ||
|
|
9d7522cc15 | ||
|
|
a090ed8b5e | ||
|
|
6b9c686390 | ||
|
|
6744e0d506 | ||
|
|
bbcabf0632 | ||
|
|
b540307dbd | ||
|
|
4a6778c609 | ||
|
|
3ae2883eb5 | ||
|
|
dc91fa0206 | ||
|
|
fb02499823 | ||
|
|
f4b9d0336d | ||
|
|
49acae0fbb | ||
|
|
f547cfd0c9 | ||
|
|
1bdc1acddd | ||
|
|
267b54fd8b | ||
|
|
527663e27e | ||
|
|
310b788352 | ||
|
|
7d23f24854 | ||
|
|
ab1e82414b | ||
|
|
00ba19d683 | ||
|
|
4b9664d82a |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -119,7 +119,15 @@ wix/*.wixpdb
|
||||
setup/Output/
|
||||
*.~is
|
||||
|
||||
UI.Phantom/
|
||||
|
||||
#VS outout folders
|
||||
bin
|
||||
obj
|
||||
output/*
|
||||
|
||||
|
||||
#OS X metadata files
|
||||
._*
|
||||
|
||||
_start
|
||||
|
||||
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[submodule "src/ExternalModules/CurlSharp"]
|
||||
path = src/ExternalModules/CurlSharp
|
||||
url = https://github.com/Sonarr/CurlSharp.git
|
||||
branch = master
|
||||
@@ -22,7 +22,7 @@ Setup guides, FAQ, the more information we have on the wiki the better.
|
||||
5. Compile in Visual Studio
|
||||
|
||||
### Contributing Code ###
|
||||
- If you're adding a new, already requested feature, please comment on [Trello](https://trello.sonarr.tv "Trello") so work is not duplicated (If you want to add something not already on there, please talk to us first)
|
||||
- If you're adding a new, already requested feature, please comment on [Github Issues](https://github.com/Sonarr/Sonarr/issues "Github Issues") so work is not duplicated (If you want to add something not already on there, please talk to us first)
|
||||
- Rebase from NzbDrone's develop branch, don't merge
|
||||
- Make meaningful commits, or squash them
|
||||
- Feel free to make a pull request before work is complete, this will let us see where its at and make comments/suggest improvements
|
||||
|
||||
@@ -116,6 +116,9 @@ Function PackageMono()
|
||||
|
||||
Write-Host "Adding NzbDrone.Core.dll.config (for dllmap)"
|
||||
Copy-Item "$sourceFolder\NzbDrone.Core\NzbDrone.Core.dll.config" $outputFolderMono
|
||||
|
||||
Write-Host "Adding CurlSharp.dll.config (for dllmap)"
|
||||
Copy-Item "$sourceFolder\NzbDrone.Common\CurlSharp.dll.config" $outputFolderMono
|
||||
|
||||
Write-Host Renaming NzbDrone.Console.exe to NzbDrone.exe
|
||||
Get-ChildItem $outputFolderMono -File -Filter "NzbDrone.exe*" -Recurse | foreach ($_) {remove-item $_.fullname}
|
||||
|
||||
@@ -8,5 +8,4 @@ require('./less.js');
|
||||
require('./stripBom.js');
|
||||
require('./imageMin.js');
|
||||
require('./webpack.js');
|
||||
|
||||
|
||||
require('./start.js');
|
||||
|
||||
@@ -1,19 +1,45 @@
|
||||
module.exports = {
|
||||
var phantom = require('./phantom');
|
||||
|
||||
var paths = {
|
||||
src: {
|
||||
root: './src/UI/',
|
||||
templates: './src/UI/**/*.hbs',
|
||||
html: './src/UI/*.html',
|
||||
partials: './src/UI/**/*Partial.hbs',
|
||||
scripts: './src/UI/**/*.js',
|
||||
less: ['./src/UI/**/*.less'],
|
||||
content: './src/UI/Content/',
|
||||
images: './src/UI/Content/Images/**/*',
|
||||
exclude: {
|
||||
libs: '!./src/UI/JsLibraries/**'
|
||||
}
|
||||
},
|
||||
dest: {
|
||||
root: './_output/UI/',
|
||||
content: './_output/UI/Content/'
|
||||
}
|
||||
};
|
||||
|
||||
if (phantom) {
|
||||
paths = {
|
||||
src: {
|
||||
root: './src/UI/',
|
||||
templates: './src/UI/**/*.hbs',
|
||||
html: './src/UI/*.html',
|
||||
partials: './src/UI/**/*Partial.hbs',
|
||||
scripts: './src/UI/**/*.js',
|
||||
less: ['./src/UI/**/*.less'],
|
||||
content: './src/UI/Content/',
|
||||
images: './src/UI/Content/Images/**/*',
|
||||
exclude :{
|
||||
libs:'!./src/UI/JsLibraries/**'
|
||||
}
|
||||
root: './src/UI.Phantom/',
|
||||
templates: './src/UI.Phantom/**/*.hbs',
|
||||
html: './src/UI.Phantom/*.html',
|
||||
partials: './src/UI.Phantom/**/*Partial.hbs',
|
||||
scripts: './src/UI.Phantom/**/*.js',
|
||||
less: ['./src/UI.Phantom/**/*.less'],
|
||||
content: './src/UI.Phantom/Content/',
|
||||
images: './src/UI.Phantom/Content/Images/**/*',
|
||||
exclude: {
|
||||
libs: '!./src/UI.Phantom/JsLibraries/**'
|
||||
}
|
||||
},
|
||||
dest: {
|
||||
root: './_output/UI/',
|
||||
content: './_output/UI/Content/'
|
||||
root: './_output/UI.Phantom/',
|
||||
content: './_output/UI.Phantom/Content/'
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = paths;
|
||||
|
||||
12
gulp/phantom.js
Normal file
12
gulp/phantom.js
Normal file
@@ -0,0 +1,12 @@
|
||||
// Switch to phantom.
|
||||
// Example:
|
||||
// gulp --phantom
|
||||
|
||||
var phantom = false;
|
||||
process.argv.forEach(function (val, index, array) {
|
||||
if(val=== '--phantom'){
|
||||
phantom = true;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = phantom;
|
||||
112
gulp/start.js
Normal file
112
gulp/start.js
Normal file
@@ -0,0 +1,112 @@
|
||||
// will download and run sonarr (server) in a non-windows enviroment
|
||||
// you can use this if you don't care about the server code and just want to work
|
||||
// with the web code.
|
||||
|
||||
var http = require('http');
|
||||
var gulp = require('gulp');
|
||||
var fs = require('fs');
|
||||
var targz = require('tar.gz');
|
||||
var del = require('del');
|
||||
var print = require('gulp-print');
|
||||
var spawn = require('child_process').spawn;
|
||||
|
||||
function download(url, dest, cb) {
|
||||
console.log('Downloading ' + url + ' to ' + dest);
|
||||
var file = fs.createWriteStream(dest);
|
||||
var request = http.get(url, function (response) {
|
||||
response.pipe(file);
|
||||
file.on('finish', function () {
|
||||
console.log('Download completed');
|
||||
file.close(cb);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getLatest(cb) {
|
||||
var branch = 'develop';
|
||||
process.argv.forEach(function (val) {
|
||||
var branchMatch = /branch=([\S]*)/.exec(val);
|
||||
if (branchMatch && branchMatch.length > 1) {
|
||||
branch = branchMatch[1];
|
||||
}
|
||||
});
|
||||
|
||||
var url = 'http://services.sonarr.tv/v1/update/' + branch + '?os=osx';
|
||||
|
||||
console.log('Checking for latest version:', url);
|
||||
|
||||
http.get(url, function (res) {
|
||||
var data = '';
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
data += chunk;
|
||||
});
|
||||
|
||||
res.on('end', function () {
|
||||
var updatePackage = JSON.parse(data).updatePackage;
|
||||
console.log('Latest version available: ' + updatePackage.version + ' Release Date: ' + updatePackage.releaseDate);
|
||||
cb(updatePackage);
|
||||
});
|
||||
}).on('error', function (e) {
|
||||
console.log('problem with request: ' + e.message);
|
||||
});
|
||||
}
|
||||
|
||||
function extract(source, dest, cb) {
|
||||
console.log('extracting download page to ' + dest);
|
||||
new targz().extract(source, dest, function (err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
console.log('Update package extracted.');
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
gulp.task('getSonarr', function () {
|
||||
|
||||
//gulp.src('/Users/kayone/git/Sonarr/_start/2.0.0.3288/NzbDrone/*.*')
|
||||
// .pipe(print())
|
||||
// .pipe(gulp.dest('./_output
|
||||
|
||||
//return;
|
||||
try {
|
||||
fs.mkdirSync('./_start/');
|
||||
} catch (e) {
|
||||
if (e.code != 'EEXIST') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
getLatest(function (package) {
|
||||
var packagePath = "./_start/" + package.filename;
|
||||
var dirName = "./_start/" + package.version;
|
||||
download(package.url, packagePath, function () {
|
||||
extract(packagePath, dirName, function () {
|
||||
// clean old binaries
|
||||
console.log('Cleaning old binaries')
|
||||
del.sync(['./_output/*', '!./_output/UI/']);
|
||||
console.log('copying binaries to target');
|
||||
gulp.src(dirName + '/NzbDrone/*.*')
|
||||
.pipe(gulp.dest('./_output/'));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('startSonarr', function () {
|
||||
|
||||
var ls = spawn('mono', ['--debug', './_output/NzbDrone.exe']);
|
||||
|
||||
ls.stdout.on('data', function (data) {
|
||||
process.stdout.write('' + data);
|
||||
});
|
||||
|
||||
ls.stderr.on('data', function (data) {
|
||||
process.stdout.write('' + data);
|
||||
});
|
||||
|
||||
ls.on('close', function (code) {
|
||||
console.log('child process exited with code ' + code);
|
||||
});
|
||||
});
|
||||
33
package.json
33
package.json
@@ -15,25 +15,26 @@
|
||||
"gitHead": "9ff7aa1bf7fe38c4c5bdb92f56c8ad556916ed67",
|
||||
"readmeFilename": "readme.md",
|
||||
"dependencies": {
|
||||
"del": "1.1.1",
|
||||
"gulp": "3.8.10",
|
||||
"gulp-cached": "1.0.2",
|
||||
"gulp-concat": "2.4.3",
|
||||
"del": "1.2.0",
|
||||
"gulp": "3.9.0",
|
||||
"gulp-cached": "1.1.0",
|
||||
"gulp-concat": "2.6.0",
|
||||
"gulp-declare": "0.3.0",
|
||||
"gulp-handlebars": "3.0.1",
|
||||
"gulp-jshint": "1.9.2",
|
||||
"gulp-less": "2.0.1",
|
||||
"gulp-jshint": "1.11.2",
|
||||
"gulp-less": "3.0.3",
|
||||
"gulp-print": "1.1.0",
|
||||
"gulp-replace": "0.5.2",
|
||||
"gulp-replace": "0.5.3",
|
||||
"gulp-run": "1.6.8",
|
||||
"gulp-stripbom": "1.0.4",
|
||||
"gulp-run": "1.6.6",
|
||||
"gulp-webpack": "1.2.0",
|
||||
"gulp-wrap": "0.10.1",
|
||||
"handlebars": "2.0.0",
|
||||
"jshint-loader": "0.8.1",
|
||||
"jshint-stylish": "1.0.0",
|
||||
"run-sequence": "1.0.2",
|
||||
"streamqueue": "0.1.1",
|
||||
"webpack": "1.5.3"
|
||||
"gulp-webpack": "1.5.0",
|
||||
"gulp-wrap": "0.11.0",
|
||||
"handlebars": "3.0.3",
|
||||
"jshint-loader": "0.8.3",
|
||||
"jshint-stylish": "2.0.1",
|
||||
"run-sequence": "1.1.1",
|
||||
"streamqueue": "1.1.0",
|
||||
"tar.gz": "^0.1.1",
|
||||
"webpack": "1.10.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS fee
|
||||
## Configuring Development Environment: ##
|
||||
|
||||
### Requirements ###
|
||||
- Visual Studio 2013 ([Express Edition](http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-for-web "Express Edition") might work but not tested.)
|
||||
- Visual Studio 2013 [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/)
|
||||
- [Gulp](http://gulpjs.com)
|
||||
@@ -30,6 +30,7 @@ Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS fee
|
||||
|
||||
- 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`
|
||||
- install gulp `npm install gulp -g`
|
||||
- start gulp to monitor your dev environment for any changes that need post processing using `gulp watch` command.
|
||||
@@ -44,7 +45,7 @@ Sonarr is a PVR for Usenet and BitTorrent users. It can monitor multiple RSS fee
|
||||
|
||||
### License ###
|
||||
* [GNU GPL v3](http://www.gnu.org/licenses/gpl.html)
|
||||
Copyright 2010-2014
|
||||
Copyright 2010-2015
|
||||
|
||||
|
||||
### Sponsors ###
|
||||
|
||||
1
src/ExternalModules/CurlSharp
Submodule
1
src/ExternalModules/CurlSharp
Submodule
Submodule src/ExternalModules/CurlSharp added at cfdbbbd9c6
Binary file not shown.
Binary file not shown.
@@ -56,7 +56,7 @@ namespace Microsoft.AspNet.SignalR.Infrastructure
|
||||
}
|
||||
catch(NotImplementedException)
|
||||
{
|
||||
// This happens on mono
|
||||
// This happens on mono
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentAssertions, Version=3.2.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Reference Include="FluentAssertions, Version=3.4.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.3.4.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions.Core, Version=3.2.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Reference Include="FluentAssertions.Core, Version=3.4.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.3.4.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@@ -112,4 +112,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentAssertions" version="3.2.1" targetFramework="net40" />
|
||||
<package id="FluentAssertions" version="3.4.0" targetFramework="net40" />
|
||||
<package id="Moq" version="4.0.10827" />
|
||||
<package id="NBuilder" version="3.0.1.1" targetFramework="net40" />
|
||||
<package id="NUnit" version="2.6.3" targetFramework="net40" />
|
||||
|
||||
@@ -28,15 +28,15 @@ namespace NzbDrone.Api.ClientSchema
|
||||
{
|
||||
|
||||
var field = new Field
|
||||
{
|
||||
Name = propertyInfo.Name,
|
||||
Label = fieldAttribute.Label,
|
||||
HelpText = fieldAttribute.HelpText,
|
||||
HelpLink = fieldAttribute.HelpLink,
|
||||
Order = fieldAttribute.Order,
|
||||
Advanced = fieldAttribute.Advanced,
|
||||
Type = fieldAttribute.Type.ToString().ToLowerInvariant()
|
||||
};
|
||||
{
|
||||
Name = propertyInfo.Name,
|
||||
Label = fieldAttribute.Label,
|
||||
HelpText = fieldAttribute.HelpText,
|
||||
HelpLink = fieldAttribute.HelpLink,
|
||||
Order = fieldAttribute.Order,
|
||||
Advanced = fieldAttribute.Advanced,
|
||||
Type = fieldAttribute.Type.ToString().ToLowerInvariant()
|
||||
};
|
||||
|
||||
var value = propertyInfo.GetValue(model, null);
|
||||
if (value != null)
|
||||
@@ -101,20 +101,37 @@ namespace NzbDrone.Api.ClientSchema
|
||||
propertyInfo.SetValue(target, value, null);
|
||||
}
|
||||
|
||||
else if (propertyInfo.PropertyType == typeof (IEnumerable<Int32>))
|
||||
else if (propertyInfo.PropertyType == typeof(IEnumerable<Int32>))
|
||||
{
|
||||
IEnumerable<Int32> value;
|
||||
|
||||
if (field.Value.GetType() == typeof (JArray))
|
||||
if (field.Value.GetType() == typeof(JArray))
|
||||
{
|
||||
value = ((JArray) field.Value).Select(s => s.Value<Int32>());
|
||||
value = ((JArray)field.Value).Select(s => s.Value<Int32>());
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
value = field.Value.ToString().Split(new []{','}, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToInt32(s));
|
||||
value = field.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToInt32(s));
|
||||
}
|
||||
|
||||
|
||||
propertyInfo.SetValue(target, value, null);
|
||||
}
|
||||
|
||||
else if (propertyInfo.PropertyType == typeof(IEnumerable<string>))
|
||||
{
|
||||
IEnumerable<string> value;
|
||||
|
||||
if (field.Value.GetType() == typeof(JArray))
|
||||
{
|
||||
value = ((JArray)field.Value).Select(s => s.Value<string>());
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
value = field.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
propertyInfo.SetValue(target, value, null);
|
||||
}
|
||||
|
||||
@@ -142,4 +159,4 @@ namespace NzbDrone.Api.ClientSchema
|
||||
return options.OrderBy(o => o.Value).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,21 +27,23 @@ namespace NzbDrone.Api.Config
|
||||
GetResourceById = GetHostConfig;
|
||||
UpdateResource = SaveHostConfig;
|
||||
|
||||
SharedValidator.RuleFor(c => c.Branch).NotEmpty().WithMessage("Branch name is required, 'master' is the default");
|
||||
SharedValidator.RuleFor(c => c.BindAddress)
|
||||
.ValidIp4Address()
|
||||
.NotListenAllIp4Address()
|
||||
.When(c => c.BindAddress != "*");
|
||||
|
||||
SharedValidator.RuleFor(c => c.Port).ValidPort();
|
||||
|
||||
SharedValidator.RuleFor(c => c.UrlBase).ValidUrlBase();
|
||||
|
||||
SharedValidator.RuleFor(c => c.Username).NotEmpty().When(c => c.AuthenticationMethod != AuthenticationType.None);
|
||||
SharedValidator.RuleFor(c => c.Password).NotEmpty().When(c => c.AuthenticationMethod != AuthenticationType.None);
|
||||
|
||||
SharedValidator.RuleFor(c => c.SslPort).ValidPort().When(c => c.EnableSsl);
|
||||
SharedValidator.RuleFor(c => c.SslCertHash).NotEmpty().When(c => c.EnableSsl && OsInfo.IsWindows);
|
||||
|
||||
SharedValidator.RuleFor(c => c.Branch).NotEmpty().WithMessage("Branch name is required, 'master' is the default");
|
||||
SharedValidator.RuleFor(c => c.UpdateScriptPath).IsValidPath().When(c => c.UpdateMechanism == UpdateMechanism.Script);
|
||||
|
||||
SharedValidator.RuleFor(c => c.BindAddress)
|
||||
.ValidIp4Address()
|
||||
.NotListenAllIp4Address()
|
||||
.When(c => c.BindAddress != "*");
|
||||
}
|
||||
|
||||
private HostConfigResource GetHostConfig()
|
||||
|
||||
31
src/NzbDrone.Api/Frontend/Mappers/RobotsTxtMapper.cs
Normal file
31
src/NzbDrone.Api/Frontend/Mappers/RobotsTxtMapper.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
|
||||
namespace NzbDrone.Api.Frontend.Mappers
|
||||
{
|
||||
public class RobotsTxtMapper : StaticResourceMapperBase
|
||||
{
|
||||
private readonly IAppFolderInfo _appFolderInfo;
|
||||
|
||||
public RobotsTxtMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, Logger logger)
|
||||
: base(diskProvider, logger)
|
||||
{
|
||||
_appFolderInfo = appFolderInfo;
|
||||
}
|
||||
|
||||
public override string Map(string resourceUrl)
|
||||
{
|
||||
var path = Path.Combine("Content", "robots.txt");
|
||||
|
||||
return Path.Combine(_appFolderInfo.StartUpFolder, "UI", path);
|
||||
}
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
{
|
||||
return resourceUrl.Equals("/robots.txt");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@ namespace NzbDrone.Api.Mapping
|
||||
{
|
||||
public static TTarget InjectTo<TTarget>(this object source) where TTarget : new()
|
||||
{
|
||||
if (source == null) return default(TTarget);
|
||||
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
if (targetType.IsGenericType &&
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
<Compile Include="Extensions\AccessControlHeaders.cs" />
|
||||
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
|
||||
<Compile Include="Frontend\Mappers\LoginHtmlMapper.cs" />
|
||||
<Compile Include="Frontend\Mappers\RobotsTxtMapper.cs" />
|
||||
<Compile Include="Parse\ParseModule.cs" />
|
||||
<Compile Include="Parse\ParseResource.cs" />
|
||||
<Compile Include="ManualImport\ManualImportModule.cs" />
|
||||
@@ -216,12 +217,15 @@
|
||||
<Compile Include="REST\RestResource.cs" />
|
||||
<Compile Include="RootFolders\RootFolderModule.cs" />
|
||||
<Compile Include="RootFolders\RootFolderResource.cs" />
|
||||
<Compile Include="SeasonPass\SeasonPassResource.cs" />
|
||||
<Compile Include="Series\AlternateTitleResource.cs" />
|
||||
<Compile Include="Series\SeasonResource.cs" />
|
||||
<Compile Include="SeasonPass\SeasonPassModule.cs" />
|
||||
<Compile Include="Series\SeriesEditorModule.cs" />
|
||||
<Compile Include="Series\SeriesLookupModule.cs" />
|
||||
<Compile Include="Series\SeriesModule.cs" />
|
||||
<Compile Include="Series\SeriesResource.cs" />
|
||||
<Compile Include="Series\SeasonStatisticsResource.cs" />
|
||||
<Compile Include="System\Backup\BackupModule.cs" />
|
||||
<Compile Include="System\Backup\BackupResource.cs" />
|
||||
<Compile Include="System\Tasks\TaskModule.cs" />
|
||||
@@ -272,4 +276,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -22,7 +22,7 @@ namespace NzbDrone.Api.Profiles.Delay
|
||||
DeleteResource = DeleteProfile;
|
||||
|
||||
SharedValidator.RuleFor(d => d.Tags).NotEmpty().When(d => d.Id != 1);
|
||||
SharedValidator.RuleFor(d => d.Tags).EmptyCollection().When(d => d.Id == 1);
|
||||
SharedValidator.RuleFor(d => d.Tags).EmptyCollection<DelayProfileResource, int>().When(d => d.Id == 1);
|
||||
SharedValidator.RuleFor(d => d.Tags).SetValidator(tagInUseValidator);
|
||||
SharedValidator.RuleFor(d => d.UsenetDelay).GreaterThanOrEqualTo(0);
|
||||
SharedValidator.RuleFor(d => d.TorrentDelay).GreaterThanOrEqualTo(0);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Api.ClientSchema;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
|
||||
namespace NzbDrone.Api
|
||||
{
|
||||
@@ -12,6 +13,7 @@ namespace NzbDrone.Api
|
||||
public string Implementation { get; set; }
|
||||
public string ConfigContract { get; set; }
|
||||
public string InfoLink { get; set; }
|
||||
public ProviderMessage Message { get; set; }
|
||||
|
||||
public List<ProviderResource> Presets { get; set; }
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@ namespace NzbDrone.Api.Qualities
|
||||
{
|
||||
public Quality Quality { get; set; }
|
||||
|
||||
public String Title { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
public Int32 Weight { get; set; }
|
||||
public int Weight { get; set; }
|
||||
|
||||
public Int32 MinSize { get; set; }
|
||||
public Int32 MaxSize { get; set; }
|
||||
public double? MinSize { get; set; }
|
||||
public double? MaxSize { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ namespace NzbDrone.Api.Queue
|
||||
|
||||
if (pendingRelease != null)
|
||||
{
|
||||
_pendingReleaseService.RemovePendingQueueItem(id);
|
||||
_pendingReleaseService.RemovePendingQueueItems(pendingRelease.Id);
|
||||
|
||||
return new object().AsResponse();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Restrictions;
|
||||
|
||||
namespace NzbDrone.Api.Restrictions
|
||||
@@ -19,6 +21,16 @@ namespace NzbDrone.Api.Restrictions
|
||||
CreateResource = Create;
|
||||
UpdateResource = Update;
|
||||
DeleteResource = Delete;
|
||||
|
||||
SharedValidator.Custom(restriction =>
|
||||
{
|
||||
if (restriction.Ignored.IsNullOrWhiteSpace() && restriction.Required.IsNullOrWhiteSpace())
|
||||
{
|
||||
return new ValidationFailure("", "Either 'Must contain' or 'Must not contain' is required");
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private RestrictionResource Get(Int32 id)
|
||||
|
||||
33
src/NzbDrone.Api/SeasonPass/SeasonPassModule.cs
Normal file
33
src/NzbDrone.Api/SeasonPass/SeasonPassModule.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.SeasonPass
|
||||
{
|
||||
public class SeasonPassModule : NzbDroneApiModule
|
||||
{
|
||||
private readonly IEpisodeMonitoredService _episodeMonitoredService;
|
||||
|
||||
public SeasonPassModule(IEpisodeMonitoredService episodeMonitoredService)
|
||||
: base("/seasonpass")
|
||||
{
|
||||
_episodeMonitoredService = episodeMonitoredService;
|
||||
Post["/"] = series => UpdateAll();
|
||||
}
|
||||
|
||||
private Response UpdateAll()
|
||||
{
|
||||
//Read from request
|
||||
var request = Request.Body.FromJson<SeasonPassResource>();
|
||||
|
||||
foreach (var s in request.Series)
|
||||
{
|
||||
_episodeMonitoredService.SetEpisodeMonitoredStatus(s, request.MonitoringOptions);
|
||||
}
|
||||
|
||||
return "ok".AsResponse(HttpStatusCode.Accepted);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/NzbDrone.Api/SeasonPass/SeasonPassResource.cs
Normal file
11
src/NzbDrone.Api/SeasonPass/SeasonPassResource.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.SeasonPass
|
||||
{
|
||||
public class SeasonPassResource
|
||||
{
|
||||
public List<Core.Tv.Series> Series { get; set; }
|
||||
public MonitoringOptions MonitoringOptions { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Api.Series
|
||||
namespace NzbDrone.Api.Series
|
||||
{
|
||||
public class SeasonResource
|
||||
{
|
||||
public int SeasonNumber { get; set; }
|
||||
public Boolean Monitored { get; set; }
|
||||
public bool Monitored { get; set; }
|
||||
public SeasonStatisticsResource Statistics { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
25
src/NzbDrone.Api/Series/SeasonStatisticsResource.cs
Normal file
25
src/NzbDrone.Api/Series/SeasonStatisticsResource.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace NzbDrone.Api.Series
|
||||
{
|
||||
public class SeasonStatisticsResource
|
||||
{
|
||||
public DateTime? NextAiring { get; set; }
|
||||
public DateTime? PreviousAiring { get; set; }
|
||||
public int EpisodeFileCount { get; set; }
|
||||
public int EpisodeCount { get; set; }
|
||||
public int TotalEpisodeCount { get; set; }
|
||||
public long SizeOnDisk { get; set; }
|
||||
|
||||
public decimal PercentOfEpisodes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (EpisodeCount == 0) return 0;
|
||||
|
||||
return (decimal)EpisodeFileCount / (decimal)EpisodeCount * 100;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,8 @@ namespace NzbDrone.Api.Series
|
||||
IHandle<SeriesUpdatedEvent>,
|
||||
IHandle<SeriesEditedEvent>,
|
||||
IHandle<SeriesDeletedEvent>,
|
||||
IHandle<SeriesRenamedEvent>
|
||||
IHandle<SeriesRenamedEvent>,
|
||||
IHandle<MediaCoversUpdatedEvent>
|
||||
|
||||
{
|
||||
private readonly ISeriesService _seriesService;
|
||||
@@ -160,11 +161,20 @@ namespace NzbDrone.Api.Series
|
||||
|
||||
private void LinkSeriesStatistics(SeriesResource resource, SeriesStatistics seriesStatistics)
|
||||
{
|
||||
resource.TotalEpisodeCount = seriesStatistics.TotalEpisodeCount;
|
||||
resource.EpisodeCount = seriesStatistics.EpisodeCount;
|
||||
resource.EpisodeFileCount = seriesStatistics.EpisodeFileCount;
|
||||
resource.NextAiring = seriesStatistics.NextAiring;
|
||||
resource.PreviousAiring = seriesStatistics.PreviousAiring;
|
||||
resource.SizeOnDisk = seriesStatistics.SizeOnDisk;
|
||||
|
||||
if (seriesStatistics.SeasonStatistics != null)
|
||||
{
|
||||
foreach (var season in resource.Seasons)
|
||||
{
|
||||
season.Statistics = seriesStatistics.SeasonStatistics.SingleOrDefault(s => s.SeasonNumber == season.SeasonNumber).InjectTo<SeasonStatisticsResource>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateAlternateTitles(List<SeriesResource> resources)
|
||||
@@ -215,5 +225,10 @@ namespace NzbDrone.Api.Series
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
||||
}
|
||||
|
||||
public void Handle(MediaCoversUpdatedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace NzbDrone.Api.Series
|
||||
}
|
||||
}
|
||||
|
||||
public Int32? TotalEpisodeCount { get; set; }
|
||||
public Int32? EpisodeCount { get; set; }
|
||||
public Int32? EpisodeFileCount { get; set; }
|
||||
public Int64? SizeOnDisk { get; set; }
|
||||
@@ -68,6 +69,9 @@ namespace NzbDrone.Api.Series
|
||||
public HashSet<Int32> Tags { get; set; }
|
||||
public DateTime Added { get; set; }
|
||||
public AddSeriesOptions AddOptions { get; set; }
|
||||
public Ratings Ratings { get; set; }
|
||||
|
||||
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
||||
|
||||
//Used to support legacy consumers
|
||||
public Int32 QualityProfileId
|
||||
|
||||
@@ -37,13 +37,13 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentAssertions, Version=3.2.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Reference Include="FluentAssertions, Version=3.4.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.3.4.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions.Core, Version=3.2.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Reference Include="FluentAssertions.Core, Version=3.4.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.3.4.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@@ -122,4 +122,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentAssertions" version="3.2.1" targetFramework="net40" />
|
||||
<package id="FluentAssertions" version="3.4.0" targetFramework="net40" />
|
||||
<package id="Moq" version="4.0.10827" />
|
||||
<package id="NBuilder" version="3.0.1.1" />
|
||||
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentAssertions, Version=3.2.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Reference Include="FluentAssertions, Version=3.4.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.3.4.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions.Core, Version=3.2.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Reference Include="FluentAssertions.Core, Version=3.4.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.3.4.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentAssertions" version="3.2.1" targetFramework="net40" />
|
||||
<package id="FluentAssertions" version="3.4.0" targetFramework="net40" />
|
||||
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||
<package id="NUnit" version="2.6.3" targetFramework="net40" />
|
||||
<package id="Selenium.Support" version="2.44.0" targetFramework="net40" />
|
||||
|
||||
@@ -10,22 +10,6 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
{
|
||||
public abstract class DiskProviderFixtureBase<TSubject> : TestBase<TSubject> where TSubject : class, IDiskProvider
|
||||
{
|
||||
public DirectoryInfo GetFilledTempFolder()
|
||||
{
|
||||
var tempFolder = GetTempFilePath();
|
||||
Directory.CreateDirectory(tempFolder);
|
||||
|
||||
File.WriteAllText(Path.Combine(tempFolder, Path.GetRandomFileName()), "RootFile");
|
||||
|
||||
var subDir = Path.Combine(tempFolder, Path.GetRandomFileName());
|
||||
Directory.CreateDirectory(subDir);
|
||||
|
||||
File.WriteAllText(Path.Combine(subDir, Path.GetRandomFileName()), "SubFile1");
|
||||
File.WriteAllText(Path.Combine(subDir, Path.GetRandomFileName()), "SubFile2");
|
||||
|
||||
return new DirectoryInfo(tempFolder);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void directory_exist_should_be_able_to_find_existing_folder()
|
||||
{
|
||||
@@ -101,65 +85,9 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
|
||||
File.WriteAllText(source, "SourceFile1");
|
||||
|
||||
Subject.MoveFile(source, source, true);
|
||||
Assert.Throws<IOException>(() => Subject.MoveFile(source, source, true));
|
||||
|
||||
File.Exists(source).Should().BeTrue();
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFolder_should_copy_folder()
|
||||
{
|
||||
var source = GetFilledTempFolder();
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.CopyFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyCopy(source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFolder_should_overwrite_existing_folder()
|
||||
{
|
||||
var source = GetFilledTempFolder();
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
Subject.CopyFolder(source.FullName, destination.FullName);
|
||||
|
||||
//Delete Random File
|
||||
destination.GetFiles("*.*", SearchOption.AllDirectories).First().Delete();
|
||||
|
||||
Subject.CopyFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyCopy(source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MoveFolder_should_move_folder()
|
||||
{
|
||||
var original = GetFilledTempFolder();
|
||||
var source = new DirectoryInfo(GetTempFilePath());
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.CopyFolder(original.FullName, source.FullName);
|
||||
|
||||
Subject.MoveFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyMove(original.FullName, source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MoveFolder_should_overwrite_existing_folder()
|
||||
{
|
||||
var original = GetFilledTempFolder();
|
||||
var source = new DirectoryInfo(GetTempFilePath());
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.CopyFolder(original.FullName, source.FullName);
|
||||
Subject.CopyFolder(original.FullName, destination.FullName);
|
||||
|
||||
Subject.MoveFolder(source.FullName, destination.FullName);
|
||||
|
||||
VerifyMove(original.FullName, source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -194,72 +122,6 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
Directory.Exists(sourceDir).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_able_to_hardlink_file()
|
||||
{
|
||||
var sourceDir = GetTempFilePath();
|
||||
var source = Path.Combine(sourceDir, "test.txt");
|
||||
var destination = Path.Combine(sourceDir, "destination.txt");
|
||||
|
||||
Directory.CreateDirectory(sourceDir);
|
||||
|
||||
Subject.WriteAllText(source, "SourceFile");
|
||||
|
||||
var result = Subject.TransferFile(source, destination, TransferMode.HardLink);
|
||||
|
||||
result.Should().Be(TransferMode.HardLink);
|
||||
|
||||
File.AppendAllText(source, "Test");
|
||||
File.ReadAllText(destination).Should().Be("SourceFileTest");
|
||||
}
|
||||
|
||||
private void DoHardLinkRename(FileShare fileShare)
|
||||
{
|
||||
var sourceDir = GetTempFilePath();
|
||||
var source = Path.Combine(sourceDir, "test.txt");
|
||||
var destination = Path.Combine(sourceDir, "destination.txt");
|
||||
var rename = Path.Combine(sourceDir, "rename.txt");
|
||||
|
||||
Directory.CreateDirectory(sourceDir);
|
||||
|
||||
Subject.WriteAllText(source, "SourceFile");
|
||||
|
||||
Subject.TransferFile(source, destination, TransferMode.HardLink);
|
||||
|
||||
using (var stream = new FileStream(source, FileMode.Open, FileAccess.Read, fileShare))
|
||||
{
|
||||
stream.ReadByte();
|
||||
|
||||
Subject.MoveFile(destination, rename);
|
||||
|
||||
stream.ReadByte();
|
||||
}
|
||||
|
||||
File.Exists(rename).Should().BeTrue();
|
||||
File.Exists(destination).Should().BeFalse();
|
||||
|
||||
File.AppendAllText(source, "Test");
|
||||
File.ReadAllText(rename).Should().Be("SourceFileTest");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_able_to_rename_open_hardlinks_with_fileshare_delete()
|
||||
{
|
||||
DoHardLinkRename(FileShare.Delete);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_be_able_to_rename_open_hardlinks_with_fileshare_none()
|
||||
{
|
||||
Assert.Throws<IOException>(() => DoHardLinkRename(FileShare.None));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_be_able_to_rename_open_hardlinks_with_fileshare_write()
|
||||
{
|
||||
Assert.Throws<IOException>(() => DoHardLinkRename(FileShare.Read));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void empty_folder_should_return_folder_modified_date()
|
||||
{
|
||||
@@ -338,14 +200,6 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
Subject.FileGetLastWrite(testFile).Should().Be(lastWriteTime);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Explicit]
|
||||
public void check_last_write()
|
||||
{
|
||||
Console.WriteLine(Subject.FolderGetLastWrite(GetFilledTempFolder().FullName));
|
||||
Console.WriteLine(GetFilledTempFolder().LastWriteTimeUtc);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetParentFolder_should_remove_trailing_slash_before_getting_parent_folder()
|
||||
{
|
||||
@@ -355,22 +209,51 @@ namespace NzbDrone.Common.Test.DiskTests
|
||||
Subject.GetParentFolder(path).Should().Be(parent);
|
||||
}
|
||||
|
||||
private void VerifyCopy(string source, string destination)
|
||||
private void DoHardLinkRename(FileShare fileShare)
|
||||
{
|
||||
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
||||
var destFiles = Directory.GetFileSystemEntries(destination, "*", SearchOption.AllDirectories).Select(v => v.Substring(destination.Length + 1)).ToArray();
|
||||
var sourceDir = GetTempFilePath();
|
||||
var source = Path.Combine(sourceDir, "test.txt");
|
||||
var destination = Path.Combine(sourceDir, "destination.txt");
|
||||
var rename = Path.Combine(sourceDir, "rename.txt");
|
||||
|
||||
CollectionAssert.AreEquivalent(sourceFiles, destFiles);
|
||||
Directory.CreateDirectory(sourceDir);
|
||||
|
||||
File.WriteAllText(source, "SourceFile");
|
||||
|
||||
Subject.TryCreateHardLink(source, destination).Should().BeTrue();
|
||||
|
||||
using (var stream = new FileStream(source, FileMode.Open, FileAccess.Read, fileShare))
|
||||
{
|
||||
stream.ReadByte();
|
||||
|
||||
Subject.MoveFile(destination, rename);
|
||||
|
||||
stream.ReadByte();
|
||||
}
|
||||
|
||||
File.Exists(rename).Should().BeTrue();
|
||||
File.Exists(destination).Should().BeFalse();
|
||||
|
||||
File.AppendAllText(source, "Test");
|
||||
File.ReadAllText(rename).Should().Be("SourceFileTest");
|
||||
}
|
||||
|
||||
private void VerifyMove(string source, string from, string destination)
|
||||
[Test]
|
||||
public void should_be_able_to_rename_open_hardlinks_with_fileshare_delete()
|
||||
{
|
||||
Directory.Exists(from).Should().BeFalse();
|
||||
DoHardLinkRename(FileShare.Delete);
|
||||
}
|
||||
|
||||
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
||||
var destFiles = Directory.GetFileSystemEntries(destination, "*", SearchOption.AllDirectories).Select(v => v.Substring(destination.Length + 1)).ToArray();
|
||||
[Test]
|
||||
public void should_not_be_able_to_rename_open_hardlinks_with_fileshare_none()
|
||||
{
|
||||
Assert.Throws<IOException>(() => DoHardLinkRename(FileShare.None));
|
||||
}
|
||||
|
||||
CollectionAssert.AreEquivalent(sourceFiles, destFiles);
|
||||
[Test]
|
||||
public void should_not_be_able_to_rename_open_hardlinks_with_fileshare_write()
|
||||
{
|
||||
Assert.Throws<IOException>(() => DoHardLinkRename(FileShare.Read));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
798
src/NzbDrone.Common.Test/DiskTests/DiskTransferServiceFixture.cs
Normal file
798
src/NzbDrone.Common.Test/DiskTests/DiskTransferServiceFixture.cs
Normal file
@@ -0,0 +1,798 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Test.Common;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace NzbDrone.Common.Test.DiskTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class DiskTransferServiceFixture : TestBase<DiskTransferService>
|
||||
{
|
||||
private readonly String _sourcePath = @"C:\source\my.video.mkv".AsOsAgnostic();
|
||||
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();
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>(MockBehavior.Strict);
|
||||
|
||||
WithEmulatedDiskProvider();
|
||||
|
||||
WithExistingFile(_sourcePath);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_use_verified_transfer()
|
||||
{
|
||||
Subject.VerificationMode.Should().Be(DiskTransferVerificationMode.VerifyOnly);
|
||||
|
||||
var result = Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.TryCreateHardLink(_sourcePath, _backupPath), Times.Never());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Disabled verified transfer temporarily.")]
|
||||
public void should_use_verified_transfer_on_mono()
|
||||
{
|
||||
MonoOnly();
|
||||
|
||||
Subject.VerificationMode.Should().Be(DiskTransferVerificationMode.Transactional);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Disabled verified transfer temporarily.")]
|
||||
public void should_not_use_verified_transfer_on_windows()
|
||||
{
|
||||
WindowsOnly();
|
||||
|
||||
Subject.VerificationMode.Should().Be(DiskTransferVerificationMode.VerifyOnly);
|
||||
|
||||
var result = Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.TryCreateHardLink(_sourcePath, _backupPath), Times.Never());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_path_is_the_same()
|
||||
{
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _sourcePath, TransferMode.HardLink));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.TryCreateHardLink(_sourcePath, _sourcePath), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_different_casing_unless_moving()
|
||||
{
|
||||
var targetPath = Path.Combine(Path.GetDirectoryName(_sourcePath), Path.GetFileName(_sourcePath).ToUpper());
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, targetPath, TransferMode.HardLink));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_rename_via_temp_if_different_casing()
|
||||
{
|
||||
var targetPath = Path.Combine(Path.GetDirectoryName(_sourcePath), Path.GetFileName(_sourcePath).ToUpper());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_sourcePath, _backupPath, true))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_backupPath, true);
|
||||
WithExistingFile(_sourcePath, false);
|
||||
});
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_backupPath, targetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(targetPath, true);
|
||||
WithExistingFile(_backupPath, false);
|
||||
});
|
||||
|
||||
var result = Subject.TransferFile(_sourcePath, targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.MoveFile(_backupPath, targetPath, false), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_rollback_rename_via_temp_on_exception()
|
||||
{
|
||||
var targetPath = Path.Combine(Path.GetDirectoryName(_sourcePath), Path.GetFileName(_sourcePath).ToUpper());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_sourcePath, _backupPath, true))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_backupPath, true);
|
||||
WithExistingFile(_sourcePath, false);
|
||||
});
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_backupPath, targetPath, false))
|
||||
.Throws(new IOException("Access Violation"));
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, targetPath, TransferMode.Move));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.MoveFile(_backupPath, _sourcePath, false), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_log_error_if_rollback_move_fails()
|
||||
{
|
||||
var targetPath = Path.Combine(Path.GetDirectoryName(_sourcePath), Path.GetFileName(_sourcePath).ToUpper());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_sourcePath, _backupPath, true))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_backupPath, true);
|
||||
WithExistingFile(_sourcePath, false);
|
||||
});
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_backupPath, targetPath, false))
|
||||
.Throws(new IOException("Access Violation"));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_backupPath, _sourcePath, false))
|
||||
.Throws(new IOException("Access Violation"));
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, targetPath, TransferMode.Move));
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_destination_is_child_of_source()
|
||||
{
|
||||
var childPath = Path.Combine(_sourcePath, "child");
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, childPath, TransferMode.Move));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_hardlink_only()
|
||||
{
|
||||
WithSuccessfulHardlink(_sourcePath, _targetPath);
|
||||
|
||||
var result = Subject.TransferFile(_sourcePath, _targetPath, TransferMode.HardLink);
|
||||
|
||||
result.Should().Be(TransferMode.HardLink);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_hardlink_only_failed()
|
||||
{
|
||||
WithFailedHardlink();
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.HardLink));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_fallback_to_copy_if_hardlink_failed()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
WithFailedHardlink();
|
||||
|
||||
var result = Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.CopyFile(_sourcePath, _tempTargetPath, false), Times.Once());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.MoveFile(_tempTargetPath, _targetPath, false), Times.Once());
|
||||
|
||||
VerifyDeletedFile(_sourcePath);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_none_should_not_verify_copy()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.None;
|
||||
|
||||
Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Copy);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.CopyFile(_sourcePath, _targetPath, false), Times.Once());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetFileSize(It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_none_should_not_verify_move()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.None;
|
||||
|
||||
Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Once());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetFileSize(It.IsAny<string>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_none_should_delete_existing_target_when_overwriting()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.None;
|
||||
|
||||
WithExistingFile(_targetPath);
|
||||
|
||||
Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move, true);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.DeleteFile(_targetPath), Times.Once());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_none_should_throw_if_existing_target_when_not_overwriting()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.None;
|
||||
|
||||
WithExistingFile(_targetPath);
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move, false));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.DeleteFile(_targetPath), Times.Never());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.MoveFile(_sourcePath, _targetPath, false), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_verifyonly_should_verify_copy()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
|
||||
Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Copy);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetFileSize(_sourcePath), Times.Once());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetFileSize(_targetPath), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_verifyonly_should_rollback_copy_on_partial_and_throw()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.CopyFile(_sourcePath, _targetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_targetPath, true, 900);
|
||||
});
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Copy));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.DeleteFile(_targetPath), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_log_error_if_rollback_copy_fails()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.CopyFile(_sourcePath, _targetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_targetPath, true, 900);
|
||||
});
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.DeleteFile(_targetPath))
|
||||
.Throws(new IOException("Access Violation"));
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Copy));
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_verifyonly_should_verify_move()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
|
||||
Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetFileSize(_sourcePath), Times.Once());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.GetFileSize(_targetPath), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_verifyonly_should_not_rollback_move_on_partial_and_throw()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_sourcePath, _targetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_sourcePath, false);
|
||||
WithExistingFile(_targetPath, true, 900);
|
||||
});
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.DeleteFile(_targetPath), Times.Never());
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_verifyonly_should_rollback_move_on_partial_if_source_remains()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_sourcePath, _targetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_targetPath, true, 900);
|
||||
});
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.DeleteFile(_targetPath), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_log_error_if_rollback_partialmove_fails()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_sourcePath, _targetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_targetPath, true, 900);
|
||||
});
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.DeleteFile(_targetPath))
|
||||
.Throws(new IOException("Access Violation"));
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move));
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_delete_old_backup()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
WithExistingFile(_backupPath);
|
||||
|
||||
WithSuccessfulHardlink(_sourcePath, _backupPath);
|
||||
|
||||
Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.DeleteFile(_backupPath), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_delete_old_partial()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
WithExistingFile(_tempTargetPath);
|
||||
|
||||
WithSuccessfulHardlink(_sourcePath, _backupPath);
|
||||
|
||||
Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.DeleteFile(_tempTargetPath), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_hardlink_before_move()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
WithSuccessfulHardlink(_sourcePath, _backupPath);
|
||||
|
||||
var result = Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.TryCreateHardLink(_sourcePath, _backupPath), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_retry_if_partial_copy()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
var retry = 0;
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.CopyFile(_sourcePath, _tempTargetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_tempTargetPath, true, 900);
|
||||
if (retry++ == 1) WithExistingFile(_tempTargetPath, true, 1000);
|
||||
});
|
||||
|
||||
var result = Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Copy);
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_retry_twice_if_partial_copy()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
var retry = 0;
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.CopyFile(_sourcePath, _tempTargetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_tempTargetPath, true, 900);
|
||||
if (retry++ == 3) throw new Exception("Test Failed, retried too many times.");
|
||||
});
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Copy));
|
||||
|
||||
ExceptionVerification.ExpectedWarns(2);
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_remove_source_after_move()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
WithSuccessfulHardlink(_sourcePath, _backupPath);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_backupPath, _tempTargetPath, false))
|
||||
.Callback(() => WithExistingFile(_tempTargetPath, true));
|
||||
|
||||
var result = Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
VerifyDeletedFile(_sourcePath);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_not_remove_source_if_partial_still_exists()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
var targetPath = Path.Combine(Path.GetDirectoryName(_targetPath), Path.GetFileName(_targetPath).ToUpper());
|
||||
var tempTargetPath = targetPath + ".partial~";
|
||||
|
||||
WithSuccessfulHardlink(_sourcePath, _backupPath);
|
||||
|
||||
WithExistingFile(_targetPath);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_backupPath, tempTargetPath, false))
|
||||
.Callback(() => WithExistingFile(tempTargetPath, true));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(tempTargetPath, targetPath, false))
|
||||
.Callback(() => { });
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, targetPath, TransferMode.Move));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.DeleteFile(_sourcePath), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_remove_partial_if_copy_fails()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
WithSuccessfulHardlink(_sourcePath, _backupPath);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.CopyFile(_sourcePath, _tempTargetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_tempTargetPath, true, 900);
|
||||
})
|
||||
.Throws(new IOException("Blackbox IO error"));
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Copy));
|
||||
|
||||
VerifyDeletedFile(_tempTargetPath);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_remove_backup_if_move_throws()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
WithSuccessfulHardlink(_sourcePath, _backupPath);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_backupPath, _tempTargetPath, false))
|
||||
.Throws(new IOException("Blackbox IO error"));
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move));
|
||||
|
||||
VerifyDeletedFile(_backupPath);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void mode_transactional_should_remove_partial_if_move_fails()
|
||||
{
|
||||
Subject.VerificationMode = DiskTransferVerificationMode.Transactional;
|
||||
|
||||
WithSuccessfulHardlink(_sourcePath, _backupPath);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(_backupPath, _tempTargetPath, false))
|
||||
.Callback(() =>
|
||||
{
|
||||
WithExistingFile(_backupPath, false);
|
||||
WithExistingFile(_tempTargetPath, true, 900);
|
||||
});
|
||||
|
||||
Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Move);
|
||||
|
||||
VerifyDeletedFile(_tempTargetPath);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFolder_should_copy_folder()
|
||||
{
|
||||
WithRealDiskProvider();
|
||||
|
||||
var source = GetFilledTempFolder();
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.TransferFolder(source.FullName, destination.FullName, TransferMode.Copy);
|
||||
|
||||
VerifyCopyFolder(source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CopyFolder_should_overwrite_existing_folder()
|
||||
{
|
||||
WithRealDiskProvider();
|
||||
|
||||
var source = GetFilledTempFolder();
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
Subject.TransferFolder(source.FullName, destination.FullName, TransferMode.Copy);
|
||||
|
||||
//Delete Random File
|
||||
destination.GetFiles("*.*", SearchOption.AllDirectories).First().Delete();
|
||||
|
||||
Subject.TransferFolder(source.FullName, destination.FullName, TransferMode.Copy);
|
||||
|
||||
VerifyCopyFolder(source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void MoveFolder_should_move_folder()
|
||||
{
|
||||
WithRealDiskProvider();
|
||||
|
||||
var original = GetFilledTempFolder();
|
||||
var source = new DirectoryInfo(GetTempFilePath());
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.TransferFolder(original.FullName, source.FullName, TransferMode.Copy);
|
||||
|
||||
Subject.TransferFolder(source.FullName, destination.FullName, TransferMode.Move);
|
||||
|
||||
VerifyMoveFolder(original.FullName, source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MoveFolder_should_overwrite_existing_folder()
|
||||
{
|
||||
WithRealDiskProvider();
|
||||
|
||||
var original = GetFilledTempFolder();
|
||||
var source = new DirectoryInfo(GetTempFilePath());
|
||||
var destination = new DirectoryInfo(GetTempFilePath());
|
||||
|
||||
Subject.TransferFolder(original.FullName, source.FullName, TransferMode.Copy);
|
||||
Subject.TransferFolder(original.FullName, destination.FullName, TransferMode.Copy);
|
||||
|
||||
Subject.TransferFolder(source.FullName, destination.FullName, TransferMode.Move);
|
||||
|
||||
VerifyMoveFolder(original.FullName, source.FullName, destination.FullName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_destination_is_readonly()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.CopyFile(It.IsAny<string>(), It.IsAny<string>(), false))
|
||||
.Throws(new IOException("Access denied"));
|
||||
|
||||
Assert.Throws<IOException>(() => Subject.TransferFile(_sourcePath, _targetPath, TransferMode.Copy));
|
||||
}
|
||||
|
||||
public DirectoryInfo GetFilledTempFolder()
|
||||
{
|
||||
var tempFolder = GetTempFilePath();
|
||||
Directory.CreateDirectory(tempFolder);
|
||||
|
||||
File.WriteAllText(Path.Combine(tempFolder, Path.GetRandomFileName()), "RootFile");
|
||||
|
||||
var subDir = Path.Combine(tempFolder, Path.GetRandomFileName());
|
||||
Directory.CreateDirectory(subDir);
|
||||
|
||||
File.WriteAllText(Path.Combine(subDir, Path.GetRandomFileName()), "SubFile1");
|
||||
File.WriteAllText(Path.Combine(subDir, Path.GetRandomFileName()), "SubFile2");
|
||||
|
||||
return new DirectoryInfo(tempFolder);
|
||||
}
|
||||
|
||||
private void WithExistingFile(string path, bool exists = true, int size = 1000)
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.FileExists(path))
|
||||
.Returns(exists);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetFileSize(path))
|
||||
.Returns(size);
|
||||
}
|
||||
|
||||
private void WithSuccessfulHardlink(string source, string target)
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.TryCreateHardLink(source, target))
|
||||
.Callback(() => WithExistingFile(target))
|
||||
.Returns(true);
|
||||
}
|
||||
|
||||
private void WithFailedHardlink()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.TryCreateHardLink(It.IsAny<String>(), It.IsAny<String>()))
|
||||
.Returns(false);
|
||||
}
|
||||
|
||||
private void WithEmulatedDiskProvider()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.FileExists(It.IsAny<string>()))
|
||||
.Returns(false);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.CopyFile(It.IsAny<string>(), It.IsAny<string>(), false))
|
||||
.Callback<string, string, bool>((s, d, o) =>
|
||||
{
|
||||
WithExistingFile(d);
|
||||
});
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(It.IsAny<string>(), It.IsAny<string>(), false))
|
||||
.Callback<string, string, bool>((s, d, o) =>
|
||||
{
|
||||
WithExistingFile(s, false);
|
||||
WithExistingFile(d);
|
||||
});
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.DeleteFile(It.IsAny<string>()))
|
||||
.Callback<string>(v =>
|
||||
{
|
||||
WithExistingFile(v, false);
|
||||
});
|
||||
}
|
||||
|
||||
private void WithRealDiskProvider()
|
||||
{
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.FolderExists(It.IsAny<string>()))
|
||||
.Returns<string>(v => Directory.Exists(v));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.FileExists(It.IsAny<string>()))
|
||||
.Returns<string>(v => File.Exists(v));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.CreateFolder(It.IsAny<string>()))
|
||||
.Callback<string>(v => Directory.CreateDirectory(v));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.DeleteFolder(It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Callback<string, bool>((v,r) => Directory.Delete(v, r));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.DeleteFile(It.IsAny<string>()))
|
||||
.Callback<string>(v => File.Delete(v));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetDirectoryInfos(It.IsAny<string>()))
|
||||
.Returns<string>(v => new DirectoryInfo(v).GetDirectories().ToList());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetFileInfos(It.IsAny<string>()))
|
||||
.Returns<string>(v => new DirectoryInfo(v).GetFiles().ToList());
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.GetFileSize(It.IsAny<string>()))
|
||||
.Returns<string>(v => new FileInfo(v).Length);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.TryCreateHardLink(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns(false);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.CopyFile(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Callback<string, string, bool>((s, d, o) => File.Copy(s, d, o));
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(v => v.MoveFile(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Callback<string, string, bool>((s,d,o) => {
|
||||
if (File.Exists(d) && o) File.Delete(d);
|
||||
File.Move(s, d);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void VerifyCopyFolder(string source, string destination)
|
||||
{
|
||||
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
||||
var destFiles = Directory.GetFileSystemEntries(destination, "*", SearchOption.AllDirectories).Select(v => v.Substring(destination.Length + 1)).ToArray();
|
||||
|
||||
CollectionAssert.AreEquivalent(sourceFiles, destFiles);
|
||||
}
|
||||
|
||||
private void VerifyMoveFolder(string source, string from, string destination)
|
||||
{
|
||||
Directory.Exists(from).Should().BeFalse();
|
||||
|
||||
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();
|
||||
var destFiles = Directory.GetFileSystemEntries(destination, "*", SearchOption.AllDirectories).Select(v => v.Substring(destination.Length + 1)).ToArray();
|
||||
|
||||
CollectionAssert.AreEquivalent(sourceFiles, destFiles);
|
||||
}
|
||||
|
||||
private void VerifyDeletedFile(String filePath)
|
||||
{
|
||||
var path = filePath;
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
.Verify(v => v.DeleteFile(path), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,17 @@ namespace NzbDrone.Common.Test.Http
|
||||
response.Resource.Url.Should().Be(request.Url.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_execute_simple_post()
|
||||
{
|
||||
var request = new HttpRequest("http://eu.httpbin.org/post");
|
||||
request.Body = "{ my: 1 }";
|
||||
|
||||
var response = Subject.Post<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Data.Should().Be(request.Body);
|
||||
}
|
||||
|
||||
[TestCase("gzip")]
|
||||
public void should_execute_get_using_gzip(string compression)
|
||||
{
|
||||
@@ -73,8 +84,6 @@ namespace NzbDrone.Common.Test.Http
|
||||
ExceptionVerification.IgnoreWarns();
|
||||
}
|
||||
|
||||
|
||||
[TestCase(HttpStatusCode.Moved)]
|
||||
[TestCase(HttpStatusCode.MovedPermanently)]
|
||||
public void should_not_follow_redirects_when_not_in_production(HttpStatusCode statusCode)
|
||||
{
|
||||
@@ -217,6 +226,29 @@ namespace NzbDrone.Common.Test.Http
|
||||
|
||||
ExceptionVerification.IgnoreErrors();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_overwrite_response_cookie()
|
||||
{
|
||||
var requestSet = new HttpRequest("http://eu.httpbin.org/cookies/set?my=cookie");
|
||||
requestSet.AllowAutoRedirect = false;
|
||||
requestSet.StoreResponseCookie = true;
|
||||
requestSet.AddCookie("my", "oldcookie");
|
||||
|
||||
var responseSet = Subject.Get(requestSet);
|
||||
|
||||
var request = new HttpRequest("http://eu.httpbin.org/get");
|
||||
|
||||
var response = Subject.Get<HttpBinResource>(request);
|
||||
|
||||
response.Resource.Headers.Should().ContainKey("Cookie");
|
||||
|
||||
var cookie = response.Resource.Headers["Cookie"].ToString();
|
||||
|
||||
cookie.Should().Contain("my=cookie");
|
||||
|
||||
ExceptionVerification.IgnoreErrors();
|
||||
}
|
||||
}
|
||||
|
||||
public class HttpBinResource
|
||||
@@ -224,5 +256,6 @@ namespace NzbDrone.Common.Test.Http
|
||||
public Dictionary<string, object> Headers { get; set; }
|
||||
public string Origin { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Data { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -37,13 +37,13 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentAssertions, Version=3.2.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Reference Include="FluentAssertions, Version=3.4.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.3.4.0\lib\net40\FluentAssertions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="FluentAssertions.Core, Version=3.2.1.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\FluentAssertions.3.2.1\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Reference Include="FluentAssertions.Core, Version=3.4.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.3.4.0\lib\net40\FluentAssertions.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
@@ -72,6 +72,7 @@
|
||||
<Compile Include="DiskTests\DiskProviderFixtureBase.cs" />
|
||||
<Compile Include="DiskTests\FreeSpaceFixtureBase.cs" />
|
||||
<Compile Include="DiskTests\IsParentFixtureBase.cs" />
|
||||
<Compile Include="DiskTests\DiskTransferServiceFixture.cs" />
|
||||
<Compile Include="EnsureTest\PathExtensionFixture.cs" />
|
||||
<Compile Include="EnvironmentProviderTest.cs" />
|
||||
<Compile Include="EnvironmentTests\EnvironmentProviderTest.cs" />
|
||||
|
||||
@@ -151,7 +151,6 @@ namespace NzbDrone.Common.Test
|
||||
[TestCase(@"C:\Test", @"C:\Test2\sub", @"C:\Test2\sub")]
|
||||
[TestCase(@"/Test", @"sub", @"/Test/sub")]
|
||||
[TestCase(@"/Test", @"sub/", @"/Test/sub/")]
|
||||
[TestCase(@"/Test", @"sub/", @"/Test/sub/")]
|
||||
[TestCase(@"/Test/", @"sub/test/", @"/Test/sub/test/")]
|
||||
[TestCase(@"/Test/", @"/Test2/", @"/Test2/")]
|
||||
[TestCase(@"C:\Test", "", @"C:\Test")]
|
||||
|
||||
@@ -62,7 +62,6 @@ namespace NzbDrone.Common.Test
|
||||
[TestCase(@"C:\Test", @"C:\Test\\")]
|
||||
[TestCase(@"C:\\\\\Test", @"C:\Test\\")]
|
||||
[TestCase(@"C:\Test\\\\", @"C:\Test\\")]
|
||||
[TestCase(@"C:\Test", @"C:\Test\\")]
|
||||
[TestCase(@"\\Server\pool", @"\\Server\pool")]
|
||||
[TestCase(@"\\Server\pool\", @"\\Server\pool")]
|
||||
[TestCase(@"\\Server\pool", @"\\Server\pool\")]
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace NzbDrone.Common.Test
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Explicit]
|
||||
public void Should_be_able_to_start_and_stop_service()
|
||||
{
|
||||
Subject.GetService(ALWAYS_INSTALLED_SERVICE).Status
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentAssertions" version="3.2.1" targetFramework="net40" />
|
||||
<package id="FluentAssertions" version="3.4.0" targetFramework="net40" />
|
||||
<package id="Moq" version="4.0.10827" />
|
||||
<package id="NLog" version="2.1.0" targetFramework="net40" />
|
||||
<package id="NUnit" version="2.6.3" targetFramework="net40" />
|
||||
|
||||
7
src/NzbDrone.Common/CurlSharp.dll.config
Normal file
7
src/NzbDrone.Common/CurlSharp.dll.config
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<!-- <dllmap os="osx" dll="libcurl.dll" target="libcurl.3.dylib"/> -->
|
||||
<dllmap os="linux" dll="libcurl.dll" target="libcurl.so.3" />
|
||||
<dllmap os="freebsd" dll="libcurl.dll" target="libcurl.so.3" />
|
||||
<dllmap os="solaris" dll="libcurl.dll" target="libcurl.so.3" />
|
||||
</configuration>
|
||||
@@ -168,62 +168,6 @@ namespace NzbDrone.Common.Disk
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
public void CopyFolder(string source, string destination)
|
||||
{
|
||||
Ensure.That(source, () => source).IsValidPath();
|
||||
Ensure.That(destination, () => destination).IsValidPath();
|
||||
|
||||
TransferFolder(source, destination, TransferMode.Copy);
|
||||
}
|
||||
|
||||
public void MoveFolder(string source, string destination)
|
||||
{
|
||||
Ensure.That(source, () => source).IsValidPath();
|
||||
Ensure.That(destination, () => destination).IsValidPath();
|
||||
|
||||
try
|
||||
{
|
||||
TransferFolder(source, destination, TransferMode.Move);
|
||||
DeleteFolder(source, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.Data.Add("Source", source);
|
||||
e.Data.Add("Destination", destination);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void TransferFolder(string source, string destination, TransferMode mode)
|
||||
{
|
||||
Ensure.That(source, () => source).IsValidPath();
|
||||
Ensure.That(destination, () => destination).IsValidPath();
|
||||
|
||||
Logger.ProgressDebug("{0} {1} -> {2}", mode, source, destination);
|
||||
|
||||
var sourceFolder = new DirectoryInfo(source);
|
||||
var targetFolder = new DirectoryInfo(destination);
|
||||
|
||||
if (!targetFolder.Exists)
|
||||
{
|
||||
targetFolder.Create();
|
||||
}
|
||||
|
||||
foreach (var subDir in sourceFolder.GetDirectories())
|
||||
{
|
||||
TransferFolder(subDir.FullName, Path.Combine(destination, subDir.Name), mode);
|
||||
}
|
||||
|
||||
foreach (var sourceFile in sourceFolder.GetFiles("*.*", SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
var destFile = Path.Combine(destination, sourceFile.Name);
|
||||
|
||||
Logger.ProgressDebug("{0} {1} -> {2}", mode, sourceFile, destFile);
|
||||
|
||||
TransferFile(sourceFile.FullName, destFile, mode, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteFile(string path)
|
||||
{
|
||||
Ensure.That(path, () => path).IsValidPath();
|
||||
@@ -236,23 +180,25 @@ namespace NzbDrone.Common.Disk
|
||||
|
||||
public void CopyFile(string source, string destination, bool overwrite = false)
|
||||
{
|
||||
TransferFile(source, destination, TransferMode.Copy, overwrite);
|
||||
Ensure.That(source, () => source).IsValidPath();
|
||||
Ensure.That(destination, () => destination).IsValidPath();
|
||||
|
||||
if (source.PathEquals(destination))
|
||||
{
|
||||
throw new IOException(string.Format("Source and destination can't be the same {0}", source));
|
||||
}
|
||||
|
||||
File.Copy(source, destination, overwrite);
|
||||
}
|
||||
|
||||
public void MoveFile(string source, string destination, bool overwrite = false)
|
||||
{
|
||||
TransferFile(source, destination, TransferMode.Move, overwrite);
|
||||
}
|
||||
|
||||
public TransferMode TransferFile(string source, string destination, TransferMode mode, bool overwrite)
|
||||
{
|
||||
Ensure.That(source, () => source).IsValidPath();
|
||||
Ensure.That(destination, () => destination).IsValidPath();
|
||||
|
||||
if (source.PathEquals(destination))
|
||||
{
|
||||
Logger.Warn("Source and destination can't be the same {0}", source);
|
||||
return TransferMode.None;
|
||||
throw new IOException(string.Format("Source and destination can't be the same {0}", source));
|
||||
}
|
||||
|
||||
if (FileExists(destination) && overwrite)
|
||||
@@ -260,33 +206,8 @@ namespace NzbDrone.Common.Disk
|
||||
DeleteFile(destination);
|
||||
}
|
||||
|
||||
if (mode.HasFlag(TransferMode.HardLink))
|
||||
{
|
||||
bool createdHardlink = TryCreateHardLink(source, destination);
|
||||
if (createdHardlink)
|
||||
{
|
||||
return TransferMode.HardLink;
|
||||
}
|
||||
if (!mode.HasFlag(TransferMode.Copy))
|
||||
{
|
||||
throw new IOException("Hardlinking from '" + source + "' to '" + destination + "' failed.");
|
||||
}
|
||||
}
|
||||
|
||||
if (mode.HasFlag(TransferMode.Copy))
|
||||
{
|
||||
File.Copy(source, destination, overwrite);
|
||||
return TransferMode.Copy;
|
||||
}
|
||||
|
||||
if (mode.HasFlag(TransferMode.Move))
|
||||
{
|
||||
RemoveReadOnly(source);
|
||||
File.Move(source, destination);
|
||||
return TransferMode.Move;
|
||||
}
|
||||
|
||||
return TransferMode.None;
|
||||
RemoveReadOnly(source);
|
||||
File.Move(source, destination);
|
||||
}
|
||||
|
||||
public abstract bool TryCreateHardLink(string source, string destination);
|
||||
@@ -459,6 +380,7 @@ namespace NzbDrone.Common.Disk
|
||||
{
|
||||
return DriveInfo.GetDrives()
|
||||
.Where(d => d.DriveType == DriveType.Fixed || d.DriveType == DriveType.Network)
|
||||
.Where(d => d.IsReady)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
435
src/NzbDrone.Common/Disk/DiskTransferService.cs
Normal file
435
src/NzbDrone.Common/Disk/DiskTransferService.cs
Normal file
@@ -0,0 +1,435 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
using NzbDrone.Common.EnsureThat;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
||||
namespace NzbDrone.Common.Disk
|
||||
{
|
||||
public interface IDiskTransferService
|
||||
{
|
||||
TransferMode TransferFolder(String sourcePath, String targetPath, TransferMode mode, bool verified = true);
|
||||
TransferMode TransferFile(String sourcePath, String targetPath, TransferMode mode, bool overwrite = false, bool verified = true);
|
||||
}
|
||||
|
||||
public enum DiskTransferVerificationMode
|
||||
{
|
||||
None,
|
||||
VerifyOnly,
|
||||
Transactional
|
||||
}
|
||||
|
||||
public class DiskTransferService : IDiskTransferService
|
||||
{
|
||||
private const Int32 RetryCount = 2;
|
||||
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public DiskTransferVerificationMode VerificationMode { get; set; }
|
||||
|
||||
public DiskTransferService(IDiskProvider diskProvider, Logger logger)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_logger = logger;
|
||||
|
||||
// TODO: Atm we haven't seen partial transfers on windows so we disable verified transfer.
|
||||
// (If enabled in the future, be sure to check specifically for ReFS, which doesn't support hardlinks.)
|
||||
VerificationMode = OsInfo.IsWindows ? DiskTransferVerificationMode.VerifyOnly : DiskTransferVerificationMode.Transactional;
|
||||
|
||||
// TODO: Disabled the transactional logic entirely coz we have a couple of potential issues which we don't want in master.
|
||||
VerificationMode = DiskTransferVerificationMode.VerifyOnly;
|
||||
}
|
||||
|
||||
public TransferMode TransferFolder(String sourcePath, String targetPath, TransferMode mode, bool verified = true)
|
||||
{
|
||||
Ensure.That(sourcePath, () => sourcePath).IsValidPath();
|
||||
Ensure.That(targetPath, () => targetPath).IsValidPath();
|
||||
|
||||
if (VerificationMode != DiskTransferVerificationMode.Transactional)
|
||||
{
|
||||
verified = false;
|
||||
}
|
||||
|
||||
if (!_diskProvider.FolderExists(targetPath))
|
||||
{
|
||||
_diskProvider.CreateFolder(targetPath);
|
||||
}
|
||||
|
||||
var result = mode;
|
||||
|
||||
foreach (var subDir in _diskProvider.GetDirectoryInfos(sourcePath))
|
||||
{
|
||||
result &= TransferFolder(subDir.FullName, Path.Combine(targetPath, subDir.Name), mode, verified);
|
||||
}
|
||||
|
||||
foreach (var sourceFile in _diskProvider.GetFileInfos(sourcePath))
|
||||
{
|
||||
var destFile = Path.Combine(targetPath, sourceFile.Name);
|
||||
|
||||
result &= TransferFile(sourceFile.FullName, destFile, mode, true, verified);
|
||||
}
|
||||
|
||||
if (mode.HasFlag(TransferMode.Move))
|
||||
{
|
||||
_diskProvider.DeleteFolder(sourcePath, true);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public TransferMode TransferFile(String sourcePath, String targetPath, TransferMode mode, bool overwrite = false, bool verified = true)
|
||||
{
|
||||
Ensure.That(sourcePath, () => sourcePath).IsValidPath();
|
||||
Ensure.That(targetPath, () => targetPath).IsValidPath();
|
||||
|
||||
if (VerificationMode != DiskTransferVerificationMode.Transactional)
|
||||
{
|
||||
verified = false;
|
||||
}
|
||||
|
||||
_logger.Debug("{0} [{1}] > [{2}]", mode, sourcePath, targetPath);
|
||||
|
||||
if (sourcePath == targetPath)
|
||||
{
|
||||
throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath));
|
||||
}
|
||||
|
||||
if (sourcePath.PathEquals(targetPath, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
if (mode.HasFlag(TransferMode.HardLink) || mode.HasFlag(TransferMode.Copy))
|
||||
{
|
||||
throw new IOException(string.Format("Source and destination can't be the same {0}", sourcePath));
|
||||
}
|
||||
|
||||
if (mode.HasFlag(TransferMode.Move))
|
||||
{
|
||||
var tempPath = sourcePath + ".backup~";
|
||||
|
||||
_diskProvider.MoveFile(sourcePath, tempPath, true);
|
||||
try
|
||||
{
|
||||
ClearTargetPath(targetPath, overwrite);
|
||||
|
||||
_diskProvider.MoveFile(tempPath, targetPath);
|
||||
|
||||
return TransferMode.Move;
|
||||
}
|
||||
catch
|
||||
{
|
||||
RollbackMove(sourcePath, tempPath);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return TransferMode.None;
|
||||
}
|
||||
|
||||
if (sourcePath.IsParentPath(targetPath))
|
||||
{
|
||||
throw new IOException(string.Format("Destination cannot be a child of the source [{0}] => [{1}]", sourcePath, targetPath));
|
||||
}
|
||||
|
||||
ClearTargetPath(targetPath, overwrite);
|
||||
|
||||
if (mode.HasFlag(TransferMode.HardLink))
|
||||
{
|
||||
var createdHardlink = _diskProvider.TryCreateHardLink(sourcePath, targetPath);
|
||||
if (createdHardlink)
|
||||
{
|
||||
return TransferMode.HardLink;
|
||||
}
|
||||
if (!mode.HasFlag(TransferMode.Copy))
|
||||
{
|
||||
throw new IOException("Hardlinking from '" + sourcePath + "' to '" + targetPath + "' failed.");
|
||||
}
|
||||
}
|
||||
|
||||
if (verified)
|
||||
{
|
||||
if (mode.HasFlag(TransferMode.Copy))
|
||||
{
|
||||
if (TryCopyFile(sourcePath, targetPath))
|
||||
{
|
||||
return TransferMode.Copy;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode.HasFlag(TransferMode.Move))
|
||||
{
|
||||
if (TryMoveFile(sourcePath, targetPath))
|
||||
{
|
||||
return TransferMode.Move;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IOException(String.Format("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath));
|
||||
}
|
||||
else if (VerificationMode == DiskTransferVerificationMode.VerifyOnly)
|
||||
{
|
||||
var originalSize = _diskProvider.GetFileSize(sourcePath);
|
||||
|
||||
if (mode.HasFlag(TransferMode.Copy))
|
||||
{
|
||||
try
|
||||
{
|
||||
_diskProvider.CopyFile(sourcePath, targetPath);
|
||||
|
||||
var targetSize = _diskProvider.GetFileSize(targetPath);
|
||||
if (targetSize != originalSize)
|
||||
{
|
||||
throw new IOException(string.Format("File copy incomplete. [{0}] was {1} bytes long instead of {2} bytes.", targetPath, targetSize, originalSize));
|
||||
}
|
||||
|
||||
return TransferMode.Copy;
|
||||
}
|
||||
catch
|
||||
{
|
||||
RollbackCopy(sourcePath, targetPath);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode.HasFlag(TransferMode.Move))
|
||||
{
|
||||
try
|
||||
{
|
||||
_diskProvider.MoveFile(sourcePath, targetPath);
|
||||
|
||||
var targetSize = _diskProvider.GetFileSize(targetPath);
|
||||
if (targetSize != originalSize)
|
||||
{
|
||||
throw new IOException(string.Format("File copy incomplete, data loss may have occured. [{0}] was {1} bytes long instead of the expected {2}.", targetPath, targetSize, originalSize));
|
||||
}
|
||||
|
||||
return TransferMode.Move;
|
||||
}
|
||||
catch
|
||||
{
|
||||
RollbackPartialMove(sourcePath, targetPath);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mode.HasFlag(TransferMode.Copy))
|
||||
{
|
||||
_diskProvider.CopyFile(sourcePath, targetPath);
|
||||
return TransferMode.Copy;
|
||||
}
|
||||
|
||||
if (mode.HasFlag(TransferMode.Move))
|
||||
{
|
||||
_diskProvider.MoveFile(sourcePath, targetPath);
|
||||
return TransferMode.Move;
|
||||
}
|
||||
}
|
||||
|
||||
return TransferMode.None;
|
||||
}
|
||||
|
||||
private void ClearTargetPath(String targetPath, bool overwrite)
|
||||
{
|
||||
if (_diskProvider.FileExists(targetPath))
|
||||
{
|
||||
if (overwrite)
|
||||
{
|
||||
_diskProvider.DeleteFile(targetPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException(string.Format("Destination already exists [{0}]", targetPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RollbackPartialMove(string sourcePath, string targetPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Debug("Rolling back incomplete file move [{0}] to [{1}].", sourcePath, targetPath);
|
||||
|
||||
WaitForIO();
|
||||
|
||||
if (_diskProvider.FileExists(sourcePath))
|
||||
{
|
||||
_diskProvider.DeleteFile(targetPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Error("Failed to properly rollback the file move [{0}] to [{1}], incomplete file may be left in target path.", sourcePath, targetPath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException(string.Format("Failed to properly rollback the file move [{0}] to [{1}], incomplete file may be left in target path.", sourcePath, targetPath), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void RollbackMove(string sourcePath, string targetPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Debug("Rolling back file move [{0}] to [{1}].", sourcePath, targetPath);
|
||||
|
||||
WaitForIO();
|
||||
|
||||
_diskProvider.MoveFile(targetPath, sourcePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException(string.Format("Failed to properly rollback the file move [{0}] to [{1}], file may be left in target path.", sourcePath, targetPath), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void RollbackCopy(string sourcePath, string targetPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.Debug("Rolling back file copy [{0}] to [{1}].", sourcePath, targetPath);
|
||||
|
||||
WaitForIO();
|
||||
|
||||
if (_diskProvider.FileExists(targetPath))
|
||||
{
|
||||
_diskProvider.DeleteFile(targetPath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException(string.Format("Failed to properly rollback the file copy [{0}] to [{1}], file may be left in target path.", sourcePath, targetPath), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void WaitForIO()
|
||||
{
|
||||
// This delay is intended to give the IO stack a bit of time to recover, this is especially required if remote NAS devices are involved.
|
||||
Thread.Sleep(3000);
|
||||
}
|
||||
|
||||
private Boolean TryCopyFile(String sourcePath, String targetPath)
|
||||
{
|
||||
var originalSize = _diskProvider.GetFileSize(sourcePath);
|
||||
|
||||
var tempTargetPath = targetPath + ".partial~";
|
||||
|
||||
try
|
||||
{
|
||||
for (var i = 0; i <= RetryCount; i++)
|
||||
{
|
||||
_diskProvider.CopyFile(sourcePath, tempTargetPath);
|
||||
|
||||
if (_diskProvider.FileExists(tempTargetPath))
|
||||
{
|
||||
var targetSize = _diskProvider.GetFileSize(tempTargetPath);
|
||||
if (targetSize == originalSize)
|
||||
{
|
||||
_diskProvider.MoveFile(tempTargetPath, targetPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
WaitForIO();
|
||||
|
||||
_diskProvider.DeleteFile(tempTargetPath);
|
||||
|
||||
if (i == RetryCount)
|
||||
{
|
||||
_logger.Error("Failed to completely transfer [{0}] to [{1}], aborting.", sourcePath, targetPath, i + 1, RetryCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warn("Failed to completely transfer [{0}] to [{1}], retrying [{2}/{3}].", sourcePath, targetPath, i + 1, RetryCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
WaitForIO();
|
||||
|
||||
if (_diskProvider.FileExists(tempTargetPath))
|
||||
{
|
||||
_diskProvider.DeleteFile(tempTargetPath);
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Boolean TryMoveFile(String sourcePath, String targetPath)
|
||||
{
|
||||
var originalSize = _diskProvider.GetFileSize(sourcePath);
|
||||
|
||||
var backupPath = sourcePath + ".backup~";
|
||||
var tempTargetPath = targetPath + ".partial~";
|
||||
|
||||
if (_diskProvider.FileExists(backupPath))
|
||||
{
|
||||
_logger.Trace("Removing old backup.");
|
||||
_diskProvider.DeleteFile(backupPath);
|
||||
}
|
||||
|
||||
if (_diskProvider.FileExists(tempTargetPath))
|
||||
{
|
||||
_logger.Trace("Removing old partial.");
|
||||
_diskProvider.DeleteFile(tempTargetPath);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Trace("Attempting to move hardlinked backup.");
|
||||
if (_diskProvider.TryCreateHardLink(sourcePath, backupPath))
|
||||
{
|
||||
_diskProvider.MoveFile(backupPath, tempTargetPath);
|
||||
|
||||
if (_diskProvider.FileExists(tempTargetPath))
|
||||
{
|
||||
var targetSize = _diskProvider.GetFileSize(tempTargetPath);
|
||||
|
||||
if (targetSize == originalSize)
|
||||
{
|
||||
_diskProvider.MoveFile(tempTargetPath, targetPath);
|
||||
if (_diskProvider.FileExists(tempTargetPath))
|
||||
{
|
||||
throw new IOException(String.Format("Temporary file '{0}' still exists, aborting.", tempTargetPath));
|
||||
}
|
||||
_logger.Trace("Hardlink move succeeded, deleting source.");
|
||||
_diskProvider.DeleteFile(sourcePath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep(5000);
|
||||
|
||||
_diskProvider.DeleteFile(tempTargetPath);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_diskProvider.FileExists(backupPath))
|
||||
{
|
||||
_diskProvider.DeleteFile(backupPath);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Trace("Hardlink move failed, reverting to copy.");
|
||||
if (TryCopyFile(sourcePath, targetPath))
|
||||
{
|
||||
_logger.Trace("Copy succeeded, deleting source.");
|
||||
_diskProvider.DeleteFile(sourcePath);
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.Trace("Copy failed.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,9 @@ namespace NzbDrone.Common.Disk
|
||||
long GetFolderSize(string path);
|
||||
long GetFileSize(string path);
|
||||
void CreateFolder(string path);
|
||||
void CopyFolder(string source, string destination);
|
||||
void MoveFolder(string source, string destination);
|
||||
void TransferFolder(string source, string destination, TransferMode transferMode);
|
||||
void DeleteFile(string path);
|
||||
void CopyFile(string source, string destination, bool overwrite = false);
|
||||
void MoveFile(string source, string destination, bool overwrite = false);
|
||||
TransferMode TransferFile(string source, string destination, TransferMode transferMode, bool overwrite = false);
|
||||
bool TryCreateHardLink(string source, string destination);
|
||||
void DeleteFolder(string path, bool recursive);
|
||||
string ReadAllText(string filePath);
|
||||
|
||||
@@ -37,10 +37,15 @@ namespace NzbDrone.Common.Extensions
|
||||
return info.FullName.TrimEnd('/').Trim('\\', ' ');
|
||||
}
|
||||
|
||||
public static bool PathEquals(this string firstPath, string secondPath)
|
||||
public static bool PathEquals(this string firstPath, string secondPath, StringComparison? comparison = null)
|
||||
{
|
||||
if (firstPath.Equals(secondPath, OsInfo.PathStringComparison)) return true;
|
||||
return String.Equals(firstPath.CleanFilePath(), secondPath.CleanFilePath(), OsInfo.PathStringComparison);
|
||||
if (!comparison.HasValue)
|
||||
{
|
||||
comparison = OsInfo.PathStringComparison;
|
||||
}
|
||||
|
||||
if (firstPath.Equals(secondPath, comparison.Value)) return true;
|
||||
return String.Equals(firstPath.CleanFilePath(), secondPath.CleanFilePath(), comparison.Value);
|
||||
}
|
||||
|
||||
public static string GetRelativePath(this string parentPath, string childPath)
|
||||
|
||||
245
src/NzbDrone.Common/Http/CurlHttpClient.cs
Normal file
245
src/NzbDrone.Common/Http/CurlHttpClient.cs
Normal file
@@ -0,0 +1,245 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using CurlSharp;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class CurlHttpClient
|
||||
{
|
||||
private static Logger Logger = NzbDroneLogger.GetLogger(typeof(CurlHttpClient));
|
||||
|
||||
public CurlHttpClient()
|
||||
{
|
||||
if (!CheckAvailability())
|
||||
{
|
||||
throw new ApplicationException("Curl failed to initialize.");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckAvailability()
|
||||
{
|
||||
try
|
||||
{
|
||||
return CurlGlobalHandle.Instance.Initialize();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.TraceException("Initializing curl failed", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public HttpResponse GetResponse(HttpRequest httpRequest, HttpWebRequest webRequest)
|
||||
{
|
||||
lock (CurlGlobalHandle.Instance)
|
||||
{
|
||||
Stream responseStream = new MemoryStream();
|
||||
Stream headerStream = new MemoryStream();
|
||||
|
||||
using (var curlEasy = new CurlEasy())
|
||||
{
|
||||
curlEasy.AutoReferer = false;
|
||||
curlEasy.WriteFunction = (b, s, n, o) =>
|
||||
{
|
||||
responseStream.Write(b, 0, s * n);
|
||||
return s * n;
|
||||
};
|
||||
curlEasy.HeaderFunction = (b, s, n, o) =>
|
||||
{
|
||||
headerStream.Write(b, 0, s * n);
|
||||
return s * n;
|
||||
};
|
||||
|
||||
curlEasy.UserAgent = webRequest.UserAgent;
|
||||
curlEasy.FollowLocation = webRequest.AllowAutoRedirect;
|
||||
curlEasy.HttpGet = webRequest.Method == "GET";
|
||||
curlEasy.Post = webRequest.Method == "POST";
|
||||
curlEasy.Put = webRequest.Method == "PUT";
|
||||
curlEasy.Url = webRequest.RequestUri.ToString();
|
||||
|
||||
if (webRequest.CookieContainer != null)
|
||||
{
|
||||
curlEasy.Cookie = webRequest.CookieContainer.GetCookieHeader(webRequest.RequestUri);
|
||||
}
|
||||
|
||||
if (!httpRequest.Body.IsNullOrWhiteSpace())
|
||||
{
|
||||
// TODO: This might not go well with encoding.
|
||||
curlEasy.PostFieldSize = httpRequest.Body.Length;
|
||||
curlEasy.SetOpt(CurlOption.CopyPostFields, httpRequest.Body);
|
||||
}
|
||||
|
||||
// Yes, we have to keep a ref to the object to prevent corrupting the unmanaged state
|
||||
using (var httpRequestHeaders = SerializeHeaders(webRequest))
|
||||
{
|
||||
curlEasy.HttpHeader = httpRequestHeaders;
|
||||
|
||||
var result = curlEasy.Perform();
|
||||
|
||||
if (result != CurlCode.Ok)
|
||||
{
|
||||
throw new WebException(string.Format("Curl Error {0} for Url {1}", result, curlEasy.Url));
|
||||
}
|
||||
}
|
||||
|
||||
var webHeaderCollection = ProcessHeaderStream(webRequest, headerStream);
|
||||
var responseData = ProcessResponseStream(webRequest, responseStream, webHeaderCollection);
|
||||
|
||||
var httpHeader = new HttpHeader(webHeaderCollection);
|
||||
|
||||
return new HttpResponse(httpRequest, httpHeader, responseData, (HttpStatusCode)curlEasy.ResponseCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CurlSlist SerializeHeaders(HttpWebRequest webRequest)
|
||||
{
|
||||
if (webRequest.SendChunked)
|
||||
{
|
||||
throw new NotSupportedException("Chunked transfer is not supported");
|
||||
}
|
||||
|
||||
if (webRequest.ContentLength > 0)
|
||||
{
|
||||
webRequest.Headers.Add("Content-Length", webRequest.ContentLength.ToString());
|
||||
}
|
||||
|
||||
if (webRequest.AutomaticDecompression.HasFlag(DecompressionMethods.GZip))
|
||||
{
|
||||
if (webRequest.AutomaticDecompression.HasFlag(DecompressionMethods.Deflate))
|
||||
{
|
||||
webRequest.Headers.Add("Accept-Encoding", "gzip, deflate");
|
||||
}
|
||||
else
|
||||
{
|
||||
webRequest.Headers.Add("Accept-Encoding", "gzip");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (webRequest.AutomaticDecompression.HasFlag(DecompressionMethods.Deflate))
|
||||
{
|
||||
webRequest.Headers.Add("Accept-Encoding", "deflate");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var curlHeaders = new CurlSlist();
|
||||
for (int i = 0; i < webRequest.Headers.Count; i++)
|
||||
{
|
||||
curlHeaders.Append(webRequest.Headers.GetKey(i) + ": " + webRequest.Headers.Get(i));
|
||||
}
|
||||
|
||||
curlHeaders.Append("Content-Type: " + webRequest.ContentType ?? string.Empty);
|
||||
|
||||
return curlHeaders;
|
||||
}
|
||||
|
||||
private WebHeaderCollection ProcessHeaderStream(HttpWebRequest webRequest, Stream headerStream)
|
||||
{
|
||||
headerStream.Position = 0;
|
||||
var headerData = headerStream.ToBytes();
|
||||
var headerString = Encoding.ASCII.GetString(headerData);
|
||||
|
||||
var webHeaderCollection = new WebHeaderCollection();
|
||||
|
||||
foreach (var header in headerString.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(1))
|
||||
{
|
||||
webHeaderCollection.Add(header);
|
||||
}
|
||||
|
||||
var setCookie = webHeaderCollection.Get("Set-Cookie");
|
||||
if (setCookie != null && setCookie.Length > 0 && webRequest.CookieContainer != null)
|
||||
{
|
||||
webRequest.CookieContainer.SetCookies(webRequest.RequestUri, setCookie);
|
||||
}
|
||||
|
||||
return webHeaderCollection;
|
||||
}
|
||||
|
||||
private byte[] ProcessResponseStream(HttpWebRequest webRequest, Stream responseStream, WebHeaderCollection webHeaderCollection)
|
||||
{
|
||||
responseStream.Position = 0;
|
||||
|
||||
if (responseStream.Length != 0 && webRequest.AutomaticDecompression != DecompressionMethods.None)
|
||||
{
|
||||
var encoding = webHeaderCollection["Content-Encoding"];
|
||||
if (encoding != null)
|
||||
{
|
||||
if (webRequest.AutomaticDecompression.HasFlag(DecompressionMethods.GZip) && encoding.IndexOf("gzip") != -1)
|
||||
{
|
||||
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
|
||||
|
||||
webHeaderCollection.Remove("Content-Encoding");
|
||||
}
|
||||
else if (webRequest.AutomaticDecompression.HasFlag(DecompressionMethods.Deflate) && encoding.IndexOf("deflate") != -1)
|
||||
{
|
||||
responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
|
||||
|
||||
webHeaderCollection.Remove("Content-Encoding");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return responseStream.ToBytes();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class CurlGlobalHandle : SafeHandle
|
||||
{
|
||||
public static readonly CurlGlobalHandle Instance = new CurlGlobalHandle();
|
||||
|
||||
private bool _initialized;
|
||||
private bool _available;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
private CurlGlobalHandle()
|
||||
: base(IntPtr.Zero, true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool Initialize()
|
||||
{
|
||||
lock (CurlGlobalHandle.Instance)
|
||||
{
|
||||
if (_initialized)
|
||||
return _available;
|
||||
|
||||
_initialized = true;
|
||||
_available = Curl.GlobalInit(CurlInitFlag.All) == CurlCode.Ok;
|
||||
|
||||
return _available;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
if (_initialized && _available)
|
||||
{
|
||||
Curl.GlobalCleanup();
|
||||
_available = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsInvalid
|
||||
{
|
||||
get { return !_initialized || !_available; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ namespace NzbDrone.Common.Http
|
||||
private readonly Logger _logger;
|
||||
private readonly IRateLimitService _rateLimitService;
|
||||
private readonly ICached<CookieContainer> _cookieContainerCache;
|
||||
private readonly ICached<bool> _curlTLSFallbackCache;
|
||||
|
||||
public HttpClient(ICacheManager cacheManager, IRateLimitService rateLimitService, Logger logger)
|
||||
{
|
||||
@@ -34,6 +35,7 @@ namespace NzbDrone.Common.Http
|
||||
ServicePointManager.DefaultConnectionLimit = 12;
|
||||
|
||||
_cookieContainerCache = cacheManager.GetCache<CookieContainer>(typeof(HttpClient));
|
||||
_curlTLSFallbackCache = cacheManager.GetCache<bool>(typeof(HttpClient), "curlTLSFallback");
|
||||
}
|
||||
|
||||
public HttpResponse Execute(HttpRequest request)
|
||||
@@ -71,29 +73,128 @@ namespace NzbDrone.Common.Http
|
||||
AddRequestHeaders(webRequest, request.Headers);
|
||||
}
|
||||
|
||||
var cookieContainer = _cookieContainerCache.Get("container", () => new CookieContainer());
|
||||
PrepareRequestCookies(request, webRequest);
|
||||
|
||||
if (request.Cookies.Count != 0)
|
||||
var response = ExecuteRequest(request, webRequest);
|
||||
|
||||
HandleResponseCookies(request, webRequest);
|
||||
|
||||
stopWatch.Stop();
|
||||
|
||||
_logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds);
|
||||
|
||||
if (request.AllowAutoRedirect && !RuntimeInfoBase.IsProduction &&
|
||||
(response.StatusCode == HttpStatusCode.Moved ||
|
||||
response.StatusCode == HttpStatusCode.MovedPermanently ||
|
||||
response.StatusCode == HttpStatusCode.Found))
|
||||
{
|
||||
foreach (var pair in request.Cookies)
|
||||
_logger.Error("Server requested a redirect to [" + response.Headers["Location"] + "]. Update the request URL to avoid this redirect.");
|
||||
}
|
||||
|
||||
if (!request.SuppressHttpError && response.HasHttpError)
|
||||
{
|
||||
_logger.Warn("HTTP Error - {0}", response);
|
||||
throw new HttpException(request, response);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private void PrepareRequestCookies(HttpRequest request, HttpWebRequest webRequest)
|
||||
{
|
||||
lock (_cookieContainerCache)
|
||||
{
|
||||
var persistentCookieContainer = _cookieContainerCache.Get("container", () => new CookieContainer());
|
||||
|
||||
if (request.Cookies.Count != 0)
|
||||
{
|
||||
cookieContainer.Add(new Cookie(pair.Key, pair.Value, "/", request.Url.Host)
|
||||
foreach (var pair in request.Cookies)
|
||||
{
|
||||
Expires = DateTime.UtcNow.AddHours(1)
|
||||
});
|
||||
persistentCookieContainer.Add(new Cookie(pair.Key, pair.Value, "/", request.Url.Host)
|
||||
{
|
||||
Expires = DateTime.UtcNow.AddHours(1)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var requestCookies = persistentCookieContainer.GetCookies(request.Url);
|
||||
|
||||
if (requestCookies.Count == 0 && !request.StoreResponseCookie)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (webRequest.CookieContainer == null)
|
||||
{
|
||||
webRequest.CookieContainer = new CookieContainer();
|
||||
}
|
||||
|
||||
webRequest.CookieContainer.Add(requestCookies);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleResponseCookies(HttpRequest request, HttpWebRequest webRequest)
|
||||
{
|
||||
if (!request.StoreResponseCookie)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.StoreResponseCookie)
|
||||
lock (_cookieContainerCache)
|
||||
{
|
||||
webRequest.CookieContainer = cookieContainer;
|
||||
}
|
||||
else
|
||||
{
|
||||
webRequest.CookieContainer = new CookieContainer();
|
||||
webRequest.CookieContainer.Add(cookieContainer.GetCookies(request.Url));
|
||||
}
|
||||
var persistentCookieContainer = _cookieContainerCache.Get("container", () => new CookieContainer());
|
||||
|
||||
var cookies = webRequest.CookieContainer.GetCookies(request.Url);
|
||||
|
||||
persistentCookieContainer.Add(cookies);
|
||||
}
|
||||
}
|
||||
|
||||
private HttpResponse ExecuteRequest(HttpRequest request, HttpWebRequest webRequest)
|
||||
{
|
||||
if (OsInfo.IsMonoRuntime && webRequest.RequestUri.Scheme == "https")
|
||||
{
|
||||
if (!_curlTLSFallbackCache.Find(webRequest.RequestUri.Host))
|
||||
{
|
||||
try
|
||||
{
|
||||
return ExecuteWebRequest(request, webRequest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.ToString().Contains("The authentication or decryption has failed."))
|
||||
{
|
||||
_logger.Debug("https request failed in tls error for {0}, trying curl fallback.", webRequest.RequestUri.Host);
|
||||
|
||||
_curlTLSFallbackCache.Set(webRequest.RequestUri.Host, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CurlHttpClient.CheckAvailability())
|
||||
{
|
||||
return ExecuteCurlRequest(request, webRequest);
|
||||
}
|
||||
|
||||
_logger.Trace("Curl not available, using default WebClient.");
|
||||
}
|
||||
|
||||
return ExecuteWebRequest(request, webRequest);
|
||||
}
|
||||
|
||||
private HttpResponse ExecuteCurlRequest(HttpRequest request, HttpWebRequest webRequest)
|
||||
{
|
||||
var curlClient = new CurlHttpClient();
|
||||
|
||||
return curlClient.GetResponse(request, webRequest);
|
||||
}
|
||||
|
||||
private HttpResponse ExecuteWebRequest(HttpRequest request, HttpWebRequest webRequest)
|
||||
{
|
||||
if (!request.Body.IsNullOrWhiteSpace())
|
||||
{
|
||||
var bytes = request.Headers.GetEncodingFromContentType().GetBytes(request.Body.ToCharArray());
|
||||
@@ -131,26 +232,7 @@ namespace NzbDrone.Common.Http
|
||||
}
|
||||
}
|
||||
|
||||
stopWatch.Stop();
|
||||
|
||||
var response = new HttpResponse(request, new HttpHeader(httpWebResponse.Headers), data, httpWebResponse.StatusCode);
|
||||
_logger.Trace("{0} ({1:n0} ms)", response, stopWatch.ElapsedMilliseconds);
|
||||
|
||||
if (request.AllowAutoRedirect && !RuntimeInfoBase.IsProduction &&
|
||||
(response.StatusCode == HttpStatusCode.Moved ||
|
||||
response.StatusCode == HttpStatusCode.MovedPermanently ||
|
||||
response.StatusCode == HttpStatusCode.Found))
|
||||
{
|
||||
_logger.Error("Server requested a redirect to [" + response.Headers["Location"] + "]. Update the request URL to avoid this redirect.");
|
||||
}
|
||||
|
||||
if (!request.SuppressHttpError && response.HasHttpError)
|
||||
{
|
||||
_logger.Warn("HTTP Error - {0}", response);
|
||||
throw new HttpException(request, response);
|
||||
}
|
||||
|
||||
return response;
|
||||
return new HttpResponse(request, new HttpHeader(httpWebResponse.Headers), data, httpWebResponse.StatusCode);
|
||||
}
|
||||
|
||||
public void DownloadFile(string url, string fileName)
|
||||
|
||||
@@ -71,6 +71,11 @@ namespace NzbDrone.Common.Http
|
||||
_segments.Add(key, value);
|
||||
}
|
||||
|
||||
public void AddQueryParam(string segment, string value)
|
||||
{
|
||||
UriBuilder.SetQueryParam(segment, value);
|
||||
}
|
||||
|
||||
public void AddCookie(string key, string value)
|
||||
{
|
||||
Cookies[key] = value;
|
||||
|
||||
@@ -14,9 +14,7 @@ namespace NzbDrone.Common.Http
|
||||
query += "&";
|
||||
}
|
||||
|
||||
uriBuilder.Query = query.Trim('?') + (key + "=" + value);
|
||||
uriBuilder.Query = query.Trim('?') + key + "=" + Uri.EscapeDataString(value.ToString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@
|
||||
<Compile Include="Disk\OsPath.cs" />
|
||||
<Compile Include="Disk\DiskProviderBase.cs" />
|
||||
<Compile Include="Disk\IDiskProvider.cs" />
|
||||
<Compile Include="Disk\DiskTransferService.cs" />
|
||||
<Compile Include="Disk\TransferMode.cs" />
|
||||
<Compile Include="EnsureThat\Ensure.cs" />
|
||||
<Compile Include="EnsureThat\EnsureBoolExtensions.cs" />
|
||||
@@ -139,6 +140,7 @@
|
||||
<Compile Include="Extensions\StreamExtensions.cs" />
|
||||
<Compile Include="Extensions\XmlExtentions.cs" />
|
||||
<Compile Include="HashUtil.cs" />
|
||||
<Compile Include="Http\CurlHttpClient.cs" />
|
||||
<Compile Include="Http\GZipWebClient.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
@@ -195,6 +197,9 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="CurlSharp.dll.config">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="packages.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
@@ -207,6 +212,10 @@
|
||||
<Content Include="Expansive\license.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ExternalModules\CurlSharp\CurlSharp\CurlSharp.csproj">
|
||||
<Project>{74420a79-cc16-442c-8b1e-7c1b913844f0}</Project>
|
||||
<Name>CurlSharp</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\LogentriesNLog\LogentriesNLog.csproj">
|
||||
<Project>{9DC31DE3-79FF-47A8-96B4-6BA18F6BB1CB}</Project>
|
||||
<Name>LogentriesNLog</Name>
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace NzbDrone.Common.Processes
|
||||
var filename = Path.Combine(_appFolderInfo.AppDataFolder, "nzbdrone.pid");
|
||||
try
|
||||
{
|
||||
File.WriteAllText(filename, _processProvider.GetCurrentProcess().Id.ToString());
|
||||
File.WriteAllText(filename, _processProvider.GetCurrentProcessId().ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace NzbDrone.Common.Processes
|
||||
{
|
||||
public interface IProcessProvider
|
||||
{
|
||||
int GetCurrentProcessId();
|
||||
ProcessInfo GetCurrentProcess();
|
||||
ProcessInfo GetProcessById(int id);
|
||||
List<ProcessInfo> FindProcessByName(string name);
|
||||
@@ -40,6 +41,11 @@ namespace NzbDrone.Common.Processes
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public int GetCurrentProcessId()
|
||||
{
|
||||
return Process.GetCurrentProcess().Id;
|
||||
}
|
||||
|
||||
public ProcessInfo GetCurrentProcess()
|
||||
{
|
||||
return ConvertToProcessInfo(Process.GetCurrentProcess());
|
||||
@@ -238,6 +244,12 @@ namespace NzbDrone.Common.Processes
|
||||
|
||||
foreach (var processInfo in processes)
|
||||
{
|
||||
if (processInfo.Id == Process.GetCurrentProcess().Id)
|
||||
{
|
||||
_logger.Debug("Tried killing own process, skipping: {0} [{1}]", processInfo.Id, processInfo.ProcessName);
|
||||
continue;
|
||||
}
|
||||
|
||||
_logger.Debug("Killing process: {0} [{1}]", processInfo.Id, processInfo.ProcessName);
|
||||
Kill(processInfo.Id);
|
||||
}
|
||||
@@ -300,6 +312,18 @@ namespace NzbDrone.Common.Processes
|
||||
|
||||
_logger.Debug("Found {0} processes with the name: {1}", processes.Count, name);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (var process in processes)
|
||||
{
|
||||
_logger.Debug(" - [{0}] {1}", process.Id, process.ProcessName);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Don't crash on gettings some log data.
|
||||
}
|
||||
|
||||
return processes;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common.Categories;
|
||||
|
||||
namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
|
||||
namespace NzbDrone.Core.Test.DataAugmentation.Scene
|
||||
{
|
||||
[TestFixture]
|
||||
[IntegrationTest]
|
||||
@@ -12,7 +12,7 @@ using NzbDrone.Test.Common;
|
||||
using FluentAssertions;
|
||||
using NzbDrone.Common.Extensions;
|
||||
|
||||
namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
|
||||
namespace NzbDrone.Core.Test.DataAugmentation.Scene
|
||||
{
|
||||
[TestFixture]
|
||||
|
||||
@@ -177,6 +177,31 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
|
||||
[TestCase("Working!!", "Working!!", 1)]
|
||||
[TestCase("Working`!!", "Working`!!", 2)]
|
||||
[TestCase("Working!!!", "Working!!!", 3)]
|
||||
[TestCase("Working!!!!", "Working!!!", 3)]
|
||||
[TestCase("Working !!", "Working!!", 1)]
|
||||
public void should_return_single_match(string parseTitle, string title, int expectedSeasonNumber)
|
||||
{
|
||||
var mappings = new List<SceneMapping>
|
||||
{
|
||||
new SceneMapping { Title = "Working!!", ParseTerm = "working", SearchTerm = "Working!!", TvdbId = 100, SeasonNumber = -1 },
|
||||
new SceneMapping { Title = "Working!!", ParseTerm = "working", SearchTerm = "Working!!", TvdbId = 100, SeasonNumber = 1 },
|
||||
new SceneMapping { Title = "Working`!!", ParseTerm = "working", SearchTerm = "Working`!!", TvdbId = 100, SeasonNumber = 2 },
|
||||
new SceneMapping { Title = "Working!!!", ParseTerm = "working", SearchTerm = "Working!!!", TvdbId = 100, SeasonNumber = 3 },
|
||||
};
|
||||
|
||||
Mocker.GetMock<ISceneMappingRepository>().Setup(c => c.All()).Returns(mappings);
|
||||
|
||||
var tvdbId = Subject.FindTvDbId(parseTitle);
|
||||
var seasonNumber = Subject.GetSeasonNumber(parseTitle);
|
||||
|
||||
tvdbId.Should().Be(100);
|
||||
seasonNumber.Should().Be(expectedSeasonNumber);
|
||||
}
|
||||
|
||||
private void AssertNoUpdate()
|
||||
{
|
||||
_provider1.Verify(c => c.GetSceneMappings(), Times.Once());
|
||||
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DataAugmentation.Xem;
|
||||
using NzbDrone.Core.DataAugmentation.Xem.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
|
||||
namespace NzbDrone.Core.Test.DataAugmentation.SceneNumbering
|
||||
{
|
||||
[TestFixture]
|
||||
public class XemServiceFixture : CoreTest<XemService>
|
||||
{
|
||||
private Series _series;
|
||||
private List<int> _theXemSeriesIds;
|
||||
private List<XemSceneTvdbMapping> _theXemTvdbMappings;
|
||||
private List<Episode> _episodes;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.With(v => v.TvdbId = 10)
|
||||
.With(v => v.UseSceneNumbering = false)
|
||||
.BuildNew();
|
||||
|
||||
_theXemSeriesIds = new List<int> { 120 };
|
||||
Mocker.GetMock<IXemProxy>()
|
||||
.Setup(v => v.GetXemSeriesIds())
|
||||
.Returns(_theXemSeriesIds);
|
||||
|
||||
_theXemTvdbMappings = new List<XemSceneTvdbMapping>();
|
||||
Mocker.GetMock<IXemProxy>()
|
||||
.Setup(v => v.GetSceneTvdbMappings(10))
|
||||
.Returns(_theXemTvdbMappings);
|
||||
|
||||
_episodes = new List<Episode>();
|
||||
_episodes.Add(new Episode { SeasonNumber = 1, EpisodeNumber = 1 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 1, EpisodeNumber = 2 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 1 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 2 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 3 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 4 });
|
||||
_episodes.Add(new Episode { SeasonNumber = 2, EpisodeNumber = 5 });
|
||||
|
||||
Mocker.GetMock<IEpisodeService>()
|
||||
.Setup(v => v.GetEpisodeBySeries(It.IsAny<int>()))
|
||||
.Returns(_episodes);
|
||||
}
|
||||
|
||||
private void GivenTvdbMappings()
|
||||
{
|
||||
_theXemSeriesIds.Add(10);
|
||||
|
||||
AddTvdbMapping(1, 1, 1, 1, 1, 1);
|
||||
AddTvdbMapping(2, 1, 2, 2, 1, 2);
|
||||
AddTvdbMapping(3, 2, 1, 3, 2, 1);
|
||||
AddTvdbMapping(4, 2, 2, 4, 2, 2);
|
||||
AddTvdbMapping(5, 2, 3, 5, 2, 3);
|
||||
AddTvdbMapping(6, 3, 1, 6, 2, 4);
|
||||
AddTvdbMapping(7, 3, 2, 7, 2, 5);
|
||||
}
|
||||
|
||||
private void GivenExistingMapping()
|
||||
{
|
||||
_series.UseSceneNumbering = true;
|
||||
|
||||
_episodes[0].SceneSeasonNumber = 1;
|
||||
_episodes[0].SceneEpisodeNumber = 1;
|
||||
_episodes[1].SceneSeasonNumber = 1;
|
||||
_episodes[1].SceneEpisodeNumber = 2;
|
||||
_episodes[2].SceneSeasonNumber = 2;
|
||||
_episodes[2].SceneEpisodeNumber = 1;
|
||||
_episodes[3].SceneSeasonNumber = 2;
|
||||
_episodes[3].SceneEpisodeNumber = 2;
|
||||
_episodes[4].SceneSeasonNumber = 2;
|
||||
_episodes[4].SceneEpisodeNumber = 3;
|
||||
_episodes[5].SceneSeasonNumber = 3;
|
||||
_episodes[5].SceneEpisodeNumber = 1;
|
||||
_episodes[6].SceneSeasonNumber = 3;
|
||||
_episodes[6].SceneEpisodeNumber = 1;
|
||||
}
|
||||
|
||||
private void AddTvdbMapping(int sceneAbsolute, int sceneSeason, int sceneEpisode, int tvdbAbsolute, int tvdbSeason, int tvdbEpisode)
|
||||
{
|
||||
_theXemTvdbMappings.Add(new XemSceneTvdbMapping
|
||||
{
|
||||
Scene = new XemValues { Absolute = sceneAbsolute, Season = sceneSeason, Episode = sceneEpisode },
|
||||
Tvdb = new XemValues { Absolute = tvdbAbsolute, Season = tvdbSeason, Episode = tvdbEpisode },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_not_fetch_scenenumbering_if_not_listed()
|
||||
{
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
Mocker.GetMock<IXemProxy>()
|
||||
.Verify(v => v.GetSceneTvdbMappings(10), Times.Never());
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_fetch_scenenumbering()
|
||||
{
|
||||
GivenTvdbMappings();
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.UseSceneNumbering == true)), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_clear_scenenumbering_if_removed_from_thexem()
|
||||
{
|
||||
GivenExistingMapping();
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_clear_scenenumbering_if_no_results_at_all_from_thexem()
|
||||
{
|
||||
GivenExistingMapping();
|
||||
|
||||
_theXemSeriesIds.Clear();
|
||||
|
||||
Subject.Handle(new SeriesUpdatedEvent(_series));
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), Times.Never());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using FluentMigrator;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class disable_eztv : MigrationTest<Core.Datastore.Migration.disable_eztv>
|
||||
{
|
||||
[Test]
|
||||
public void should_disable_rss_for_eztv()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
InsertIndexer(c, "https://www.ezrss.it/");
|
||||
});
|
||||
|
||||
var indexers = Mocker.Resolve<IndexerRepository>().All().ToList();
|
||||
indexers.First().EnableRss.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_disable_search_for_eztv()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
InsertIndexer(c, "https://www.ezrss.it/");
|
||||
});
|
||||
|
||||
var indexers = Mocker.Resolve<IndexerRepository>().All().ToList();
|
||||
indexers.First().EnableSearch.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_disable_if_using_custom_url()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
InsertIndexer(c, "https://ezrss.sonarr.tv/");
|
||||
});
|
||||
|
||||
var indexers = Mocker.Resolve<IndexerRepository>().All().ToList();
|
||||
indexers.First().EnableRss.Should().BeTrue();
|
||||
indexers.First().EnableSearch.Should().BeTrue();
|
||||
}
|
||||
|
||||
private void InsertIndexer(MigrationBase migrationBase, string url)
|
||||
{
|
||||
migrationBase.Insert.IntoTable("Indexers").Row(new
|
||||
{
|
||||
Name = "eztv",
|
||||
Implementation = "Eztv",
|
||||
Settings = String.Format(@"{{
|
||||
""baseUrl"": ""{0}""
|
||||
}}", url),
|
||||
ConfigContract = "EztvSettings",
|
||||
EnableRss = 1,
|
||||
EnableSearch = 1
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ using NzbDrone.Core.Tv;
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class dedupe_tags : MigrationTest<Core.Datastore.Migration.dedupe_tags>
|
||||
public class dedupe_tagsFixture : MigrationTest<Core.Datastore.Migration.dedupe_tags>
|
||||
{
|
||||
[Test]
|
||||
public void should_not_fail_if_series_tags_are_null()
|
||||
|
||||
@@ -11,7 +11,7 @@ using NzbDrone.Core.Test.Framework;
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class move_dot_prefix_to_transmission_category : MigrationTest<Core.Datastore.Migration.move_dot_prefix_to_transmission_category>
|
||||
public class move_dot_prefix_to_transmission_categoryFixture : MigrationTest<Core.Datastore.Migration.move_dot_prefix_to_transmission_category>
|
||||
{
|
||||
[Test]
|
||||
public void should_not_fail_if_no_transmission()
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class update_quality_minmax_sizeFixture : MigrationTest<Core.Datastore.Migration.update_quality_minmax_size>
|
||||
{
|
||||
[Test]
|
||||
public void should_not_fail_if_empty()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<QualityDefinitionRepository>().All();
|
||||
|
||||
items.Should().HaveCount(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_rawhd_to_null()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("QualityDefinitions").Row(new
|
||||
{
|
||||
Quality = 1,
|
||||
Title = "SDTV",
|
||||
MinSize = 0,
|
||||
MaxSize = 100
|
||||
})
|
||||
.Row(new
|
||||
{
|
||||
Quality = 10,
|
||||
Title = "RawHD",
|
||||
MinSize = 0,
|
||||
MaxSize = 100
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<QualityDefinitionRepository>().All();
|
||||
|
||||
items.Should().HaveCount(2);
|
||||
|
||||
items.First(v => v.Quality.Id == 10).MaxSize.Should().NotHaveValue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_zero_maxsize_to_null()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("QualityDefinitions").Row(new
|
||||
{
|
||||
Quality = 1,
|
||||
Title = "SDTV",
|
||||
MinSize = 0,
|
||||
MaxSize = 0
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<QualityDefinitionRepository>().All();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First(v => v.Quality.Id == 1).MaxSize.Should().NotHaveValue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_preserve_values()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("QualityDefinitions").Row(new
|
||||
{
|
||||
Quality = 1,
|
||||
Title = "SDTV",
|
||||
MinSize = 0,
|
||||
MaxSize = 100
|
||||
})
|
||||
.Row(new
|
||||
{
|
||||
Quality = 10,
|
||||
Title = "RawHD",
|
||||
MinSize = 0,
|
||||
MaxSize = 100
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<QualityDefinitionRepository>().All();
|
||||
|
||||
items.Should().HaveCount(2);
|
||||
|
||||
items.First(v => v.Quality.Id == 1).MaxSize.Should().Be(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients.Deluge;
|
||||
using NzbDrone.Core.Download.Clients.Sabnzbd;
|
||||
using NzbDrone.Core.Download.Clients.Transmission;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using System.Drawing;
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class expand_transmission_urlbaseFixture : MigrationTest<Core.Datastore.Migration.expand_transmission_urlbase>
|
||||
{
|
||||
[Test]
|
||||
public void should_not_fail_if_no_transmission()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("DownloadClients").Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Name = "Deluge",
|
||||
Implementation = "Deluge",
|
||||
Settings = new DelugeSettings
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
TvCategory = "abc",
|
||||
UrlBase = "/my/"
|
||||
}.ToJson(),
|
||||
ConfigContract = "DelugeSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<DownloadClientRepository>().All();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First().Settings.As<DelugeSettings>().UrlBase.Should().Be("/my/");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_updated_for_transmission()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("DownloadClients").Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Name = "Trans",
|
||||
Implementation = "Transmission",
|
||||
Settings = new TransmissionSettings
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
TvCategory = "abc",
|
||||
UrlBase = null
|
||||
}.ToJson(),
|
||||
ConfigContract = "TransmissionSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<DownloadClientRepository>().All();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First().Settings.As<TransmissionSettings>().UrlBase.Should().Be("/transmission/");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_append_to_existing_urlbase()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("DownloadClients").Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Name = "Trans",
|
||||
Implementation = "Transmission",
|
||||
Settings = new TransmissionSettings
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
TvCategory = "abc",
|
||||
UrlBase = "/my/url/"
|
||||
}.ToJson(),
|
||||
ConfigContract = "TransmissionSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<DownloadClientRepository>().All();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First().Settings.As<TransmissionSettings>().UrlBase.Should().Be("/my/url/transmission/");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Notifications;
|
||||
using NzbDrone.Core.Notifications.PushBullet;
|
||||
using NzbDrone.Core.Notifications.Pushover;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class pushbullet_device_idsFixture : MigrationTest<Core.Datastore.Migration.pushbullet_device_ids>
|
||||
{
|
||||
[Test]
|
||||
public void should_not_fail_if_no_pushbullet()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Notifications").Row(new
|
||||
{
|
||||
OnGrab = false,
|
||||
OnDownload = false,
|
||||
OnUpgrade = false,
|
||||
Name = "Pushover",
|
||||
Implementation = "Pushover",
|
||||
Settings = new PushoverSettings().ToJson(),
|
||||
ConfigContract = "PushoverSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<NotificationRepository>().All();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_fail_if_deviceId_is_not_set()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Notifications").Row(new
|
||||
{
|
||||
OnGrab = false,
|
||||
OnDownload = false,
|
||||
OnUpgrade = false,
|
||||
Name = "PushBullet",
|
||||
Implementation = "PushBullet",
|
||||
Settings = new
|
||||
{
|
||||
ApiKey = "my_api_key",
|
||||
}.ToJson(),
|
||||
ConfigContract = "PushBulletSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<NotificationRepository>().All();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_add_deviceIds_setting_matching_deviceId()
|
||||
{
|
||||
var deviceId = "device_id";
|
||||
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Notifications").Row(new
|
||||
{
|
||||
OnGrab = false,
|
||||
OnDownload = false,
|
||||
OnUpgrade = false,
|
||||
Name = "PushBullet",
|
||||
Implementation = "PushBullet",
|
||||
Settings = new
|
||||
{
|
||||
ApiKey = "my_api_key",
|
||||
DeviceId = deviceId
|
||||
}.ToJson(),
|
||||
ConfigContract = "PushBulletSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<NotificationRepository>().All();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Settings.As<PushBulletSettings>().DeviceIds.First().Should().Be(deviceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Notifications;
|
||||
using NzbDrone.Core.Notifications.PushBullet;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class pushbullet_devices_channels : MigrationTest<Core.Datastore.Migration.pushbullet_devices_channels_list>
|
||||
{
|
||||
[Test]
|
||||
public void should_convert_comma_separted_string_to_list()
|
||||
{
|
||||
var deviceId = "device_id";
|
||||
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Notifications").Row(new
|
||||
{
|
||||
OnGrab = false,
|
||||
OnDownload = false,
|
||||
OnUpgrade = false,
|
||||
Name = "PushBullet",
|
||||
Implementation = "PushBullet",
|
||||
Settings = new
|
||||
{
|
||||
ApiKey = "my_api_key",
|
||||
ChannelTags = "channel1,channel2"
|
||||
}.ToJson(),
|
||||
ConfigContract = "PushBulletSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<NotificationRepository>().All();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
var settings = items.First().Settings.As<PushBulletSettings>();
|
||||
settings.ChannelTags.Should().HaveCount(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Indexers.KickassTorrents;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class update_kickass_url_migration_fixture : MigrationTest<update_kickass_url>
|
||||
{
|
||||
[TestCase("http://kickass.so")]
|
||||
[TestCase("https://kickass.so")]
|
||||
[TestCase("http://kickass.to")]
|
||||
[TestCase("https://kickass.to")]
|
||||
[TestCase("http://kat.cr")]
|
||||
// [TestCase("HTTP://KICKASS.SO")] Not sure if there is an easy way to do this, not sure if worth it.
|
||||
public void should_replace_old_url(string oldUrl)
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Indexers").Row(new
|
||||
{
|
||||
Name = "Kickass_wrong_url",
|
||||
Implementation = "KickassTorrents",
|
||||
Settings = new KickassTorrentsSettings
|
||||
{
|
||||
BaseUrl = oldUrl
|
||||
}.ToJson(),
|
||||
ConfigContract = "KickassTorrentsSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<IndexerRepository>().All().ToList();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Settings.As<KickassTorrentsSettings>().BaseUrl.Should().Be("https://kat.cr");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_replace_other_indexers()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Indexers").Row(new
|
||||
{
|
||||
Name = "not_kickass",
|
||||
Implementation = "NotKickassTorrents",
|
||||
Settings = new KickassTorrentsSettings
|
||||
{
|
||||
BaseUrl = "kickass.so",
|
||||
}.ToJson(),
|
||||
ConfigContract = "KickassTorrentsSettings"
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<IndexerRepository>().All().ToList();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Settings.As<KickassTorrentsSettings>().BaseUrl.Should().Be("kickass.so");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@@ -6,8 +7,8 @@ using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
@@ -52,6 +53,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
|
||||
};
|
||||
|
||||
Mocker.GetMock<IQualityDefinitionService>()
|
||||
.Setup(v => v.Get(It.IsAny<Quality>()))
|
||||
.Returns<Quality>(v => Quality.DefaultQualityDefinitions.First(c => c.Quality == v));
|
||||
|
||||
qualityType = Builder<QualityDefinition>.CreateNew()
|
||||
.With(q => q.MinSize = 2)
|
||||
.With(q => q.MaxSize = 10)
|
||||
@@ -136,6 +141,20 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
Subject.IsSatisfiedBy(parseResultMultiSet, null).Accepted.Should().Be(expectedResult);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_if_size_is_zero()
|
||||
{
|
||||
GivenLastEpisode();
|
||||
|
||||
series.Runtime = 30;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Release.Size = 0;
|
||||
qualityType.MinSize = 10;
|
||||
qualityType.MaxSize = 20;
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_if_unlimited_30_minute()
|
||||
{
|
||||
@@ -144,7 +163,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
series.Runtime = 30;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Release.Size = 18457280000;
|
||||
qualityType.MaxSize = 0;
|
||||
qualityType.MaxSize = null;
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
@@ -157,9 +176,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
series.Runtime = 60;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Release.Size = 36857280000;
|
||||
qualityType.MaxSize = 0;
|
||||
qualityType.MaxSize = null;
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue(); ;
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -180,12 +199,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
[Test]
|
||||
public void should_return_true_if_RAWHD()
|
||||
{
|
||||
var parseResult = new RemoteEpisode
|
||||
{
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.RAWHD) },
|
||||
};
|
||||
parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.RAWHD);
|
||||
|
||||
series.Runtime = 45;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Series.SeriesType = SeriesTypes.Daily;
|
||||
parseResultSingle.Release.Size = 8000.Megabytes();
|
||||
|
||||
Subject.IsSatisfiedBy(parseResult, null).Accepted.Should().BeTrue();
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -34,11 +34,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
.With(h => h.Title = "Drone.S01E01.HDTV")
|
||||
.Build();
|
||||
|
||||
var remoteEpisode = new RemoteEpisode
|
||||
{
|
||||
Series = new Series(),
|
||||
Episodes = new List<Episode> { new Episode { Id = 1 } }
|
||||
};
|
||||
var remoteEpisode = BuildRemoteEpisode();
|
||||
|
||||
_trackedDownload = Builder<TrackedDownload>.CreateNew()
|
||||
.With(c => c.State = TrackedDownloadStage.Downloading)
|
||||
@@ -65,6 +61,16 @@ namespace NzbDrone.Core.Test.Download
|
||||
|
||||
}
|
||||
|
||||
private RemoteEpisode BuildRemoteEpisode()
|
||||
{
|
||||
return new RemoteEpisode
|
||||
{
|
||||
Series = new Series(),
|
||||
Episodes = new List<Episode> { new Episode { Id = 1 } }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private void GivenNoGrabbedHistory()
|
||||
{
|
||||
Mocker.GetMock<IHistoryService>()
|
||||
@@ -82,6 +88,24 @@ namespace NzbDrone.Core.Test.Download
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void GivenABadlyNamedDownload()
|
||||
{
|
||||
_trackedDownload.DownloadItem.DownloadId = "1234";
|
||||
_trackedDownload.DownloadItem.Title = "Droned Pilot"; // Set a badly named download
|
||||
Mocker.GetMock<IHistoryService>()
|
||||
.Setup(s => s.MostRecentForDownloadId(It.Is<string>(i => i == "1234")))
|
||||
.Returns(new History.History() { SourceTitle = "Droned S01E01" });
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.GetSeries(It.IsAny<string>()))
|
||||
.Returns((Series)null);
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.GetSeries("Droned S01E01"))
|
||||
.Returns(BuildRemoteEpisode().Series);
|
||||
}
|
||||
|
||||
private void GivenSeriesMatch()
|
||||
{
|
||||
Mocker.GetMock<IParsingService>()
|
||||
@@ -284,6 +308,47 @@ namespace NzbDrone.Core.Test.Download
|
||||
AssertNoCompletedDownload();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_mark_as_imported_if_the_download_can_be_tracked_using_the_source_seriesid()
|
||||
{
|
||||
GivenABadlyNamedDownload();
|
||||
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
||||
});
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Setup(v => v.GetSeries(It.IsAny<int>()))
|
||||
.Returns(BuildRemoteEpisode().Series);
|
||||
|
||||
Subject.Process(_trackedDownload);
|
||||
|
||||
AssertCompletedDownload();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_mark_as_imported_if_the_download_cannot_be_tracked_using_the_source_title_as_it_was_initiated_externally()
|
||||
{
|
||||
GivenABadlyNamedDownload();
|
||||
|
||||
Mocker.GetMock<IDownloadedEpisodesImportService>()
|
||||
.Setup(v => v.ProcessPath(It.IsAny<string>(), It.IsAny<Series>(), It.IsAny<DownloadClientItem>()))
|
||||
.Returns(new List<ImportResult>
|
||||
{
|
||||
new ImportResult(new ImportDecision(new LocalEpisode {Path = @"C:\TestPath\Droned.S01E01.mkv"}))
|
||||
});
|
||||
|
||||
Mocker.GetMock<IHistoryService>()
|
||||
.Setup(s => s.MostRecentForDownloadId(It.Is<string>(i => i == "1234")));
|
||||
|
||||
Subject.Process(_trackedDownload);
|
||||
|
||||
AssertNoCompletedDownload();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_import_when_there_is_a_title_mismatch()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.Clients.RTorrent;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.Download.DownloadClientTests.RTorrentTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class RTorrentFixture : DownloadClientFixtureBase<RTorrent>
|
||||
{
|
||||
protected RTorrentTorrent _downloading;
|
||||
protected RTorrentTorrent _completed;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Subject.Definition = new DownloadClientDefinition();
|
||||
Subject.Definition.Settings = new RTorrentSettings()
|
||||
{
|
||||
TvCategory = null
|
||||
};
|
||||
|
||||
_downloading = new RTorrentTorrent
|
||||
{
|
||||
Hash = "HASH",
|
||||
IsFinished = false,
|
||||
IsOpen = true,
|
||||
IsActive = true,
|
||||
Name = _title,
|
||||
TotalSize = 1000,
|
||||
RemainingSize = 500,
|
||||
Path = "somepath"
|
||||
};
|
||||
|
||||
_completed = new RTorrentTorrent
|
||||
{
|
||||
Hash = "HASH",
|
||||
IsFinished = true,
|
||||
Name = _title,
|
||||
TotalSize = 1000,
|
||||
RemainingSize = 0,
|
||||
Path = "somepath"
|
||||
};
|
||||
|
||||
Mocker.GetMock<ITorrentFileInfoReader>()
|
||||
.Setup(s => s.GetHashFromTorrentFile(It.IsAny<Byte[]>()))
|
||||
.Returns("CBC2F069FE8BB2F544EAE707D75BCD3DE9DCF951");
|
||||
}
|
||||
|
||||
protected void GivenSuccessfulDownload()
|
||||
{
|
||||
Mocker.GetMock<IRTorrentProxy>()
|
||||
.Setup(s => s.AddTorrentFromUrl(It.IsAny<String>(), It.IsAny<RTorrentSettings>()))
|
||||
.Callback(PrepareClientToReturnCompletedItem);
|
||||
|
||||
Mocker.GetMock<IRTorrentProxy>()
|
||||
.Setup(s => s.AddTorrentFromFile(It.IsAny<String>(), It.IsAny<Byte[]>(), It.IsAny<RTorrentSettings>()))
|
||||
.Callback(PrepareClientToReturnCompletedItem);
|
||||
}
|
||||
|
||||
protected virtual void GivenTorrents(List<RTorrentTorrent> torrents)
|
||||
{
|
||||
if (torrents == null)
|
||||
{
|
||||
torrents = new List<RTorrentTorrent>();
|
||||
}
|
||||
|
||||
Mocker.GetMock<IRTorrentProxy>()
|
||||
.Setup(s => s.GetTorrents(It.IsAny<RTorrentSettings>()))
|
||||
.Returns(torrents);
|
||||
}
|
||||
|
||||
protected void PrepareClientToReturnDownloadingItem()
|
||||
{
|
||||
GivenTorrents(new List<RTorrentTorrent>
|
||||
{
|
||||
_downloading
|
||||
});
|
||||
}
|
||||
|
||||
protected void PrepareClientToReturnCompletedItem()
|
||||
{
|
||||
GivenTorrents(new List<RTorrentTorrent>
|
||||
{
|
||||
_completed
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void downloading_item_should_have_required_properties()
|
||||
{
|
||||
PrepareClientToReturnDownloadingItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
VerifyDownloading(item);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void completed_download_should_have_required_properties()
|
||||
{
|
||||
PrepareClientToReturnCompletedItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
VerifyCompleted(item);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Download_should_return_unique_id()
|
||||
{
|
||||
GivenSuccessfulDownload();
|
||||
|
||||
var remoteEpisode = CreateRemoteEpisode();
|
||||
|
||||
var id = Subject.Download(remoteEpisode);
|
||||
|
||||
id.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,5 +371,16 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests
|
||||
|
||||
Subject.Test();
|
||||
}
|
||||
|
||||
[TestCase(-1)] // Infinite/Unknown
|
||||
[TestCase(-2)] // Magnet Downloading
|
||||
public void should_ignore_negative_eta(int eta)
|
||||
{
|
||||
_completed.Eta = eta;
|
||||
|
||||
PrepareClientToReturnCompletedItem();
|
||||
var item = Subject.GetItems().Single();
|
||||
item.RemainingTime.Should().NotHaveValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Indexers;
|
||||
|
||||
namespace NzbDrone.Core.Test.Download
|
||||
{
|
||||
@@ -27,8 +28,8 @@ namespace NzbDrone.Core.Test.Download
|
||||
.Returns(_downloadClients);
|
||||
|
||||
Mocker.GetMock<IProvideDownloadClient>()
|
||||
.Setup(v => v.GetDownloadClient(It.IsAny<Indexers.DownloadProtocol>()))
|
||||
.Returns<Indexers.DownloadProtocol>(v => _downloadClients.FirstOrDefault(d => d.Protocol == v));
|
||||
.Setup(v => v.GetDownloadClient(It.IsAny<DownloadProtocol>()))
|
||||
.Returns<DownloadProtocol>(v => _downloadClients.FirstOrDefault(d => d.Protocol == v));
|
||||
|
||||
var episodes = Builder<Episode>.CreateListOfSize(2)
|
||||
.TheFirst(1).With(s => s.Id = 12)
|
||||
@@ -37,7 +38,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
.Build().ToList();
|
||||
|
||||
var releaseInfo = Builder<ReleaseInfo>.CreateNew()
|
||||
.With(v => v.DownloadProtocol = Indexers.DownloadProtocol.Usenet)
|
||||
.With(v => v.DownloadProtocol = DownloadProtocol.Usenet)
|
||||
.With(v => v.DownloadUrl = "http://test.site/download1.ext")
|
||||
.Build();
|
||||
|
||||
@@ -50,20 +51,24 @@ namespace NzbDrone.Core.Test.Download
|
||||
|
||||
private Mock<IDownloadClient> WithUsenetClient()
|
||||
{
|
||||
var mock = new Mock<IDownloadClient>(Moq.MockBehavior.Default);
|
||||
var mock = new Mock<IDownloadClient>(MockBehavior.Default);
|
||||
mock.SetupGet(s => s.Definition).Returns(Builder<IndexerDefinition>.CreateNew().Build());
|
||||
|
||||
_downloadClients.Add(mock.Object);
|
||||
|
||||
mock.SetupGet(v => v.Protocol).Returns(Indexers.DownloadProtocol.Usenet);
|
||||
mock.SetupGet(v => v.Protocol).Returns(DownloadProtocol.Usenet);
|
||||
|
||||
return mock;
|
||||
}
|
||||
|
||||
private Mock<IDownloadClient> WithTorrentClient()
|
||||
{
|
||||
var mock = new Mock<IDownloadClient>(Moq.MockBehavior.Default);
|
||||
var mock = new Mock<IDownloadClient>(MockBehavior.Default);
|
||||
mock.SetupGet(s => s.Definition).Returns(Builder<IndexerDefinition>.CreateNew().Build());
|
||||
|
||||
_downloadClients.Add(mock.Object);
|
||||
|
||||
mock.SetupGet(v => v.Protocol).Returns(Indexers.DownloadProtocol.Torrent);
|
||||
mock.SetupGet(v => v.Protocol).Returns(DownloadProtocol.Torrent);
|
||||
|
||||
return mock;
|
||||
}
|
||||
@@ -131,7 +136,7 @@ namespace NzbDrone.Core.Test.Download
|
||||
var mockTorrent = WithTorrentClient();
|
||||
var mockUsenet = WithUsenetClient();
|
||||
|
||||
_parseResult.Release.DownloadProtocol = Indexers.DownloadProtocol.Torrent;
|
||||
_parseResult.Release.DownloadProtocol = DownloadProtocol.Torrent;
|
||||
|
||||
Subject.DownloadReport(_parseResult);
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Crypto;
|
||||
using NzbDrone.Core.Download.Pending;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class RemovePendingFixture : CoreTest<PendingReleaseService>
|
||||
{
|
||||
private List<PendingRelease> _pending;
|
||||
private Episode _episode;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_pending = new List<PendingRelease>();
|
||||
|
||||
_episode = Builder<Episode>.CreateNew()
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<IPendingReleaseRepository>()
|
||||
.Setup(s => s.AllBySeriesId(It.IsAny<int>()))
|
||||
.Returns(_pending);
|
||||
|
||||
Mocker.GetMock<IPendingReleaseRepository>()
|
||||
.Setup(s => s.All())
|
||||
.Returns( _pending);
|
||||
|
||||
Mocker.GetMock<ISeriesService>()
|
||||
.Setup(s => s.GetSeries(It.IsAny<int>()))
|
||||
.Returns(new Series());
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.GetEpisodes(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<Series>(), It.IsAny<bool>(), null))
|
||||
.Returns(new List<Episode>{ _episode });
|
||||
}
|
||||
|
||||
private void AddPending(int id, int seasonNumber, int[] episodes)
|
||||
{
|
||||
_pending.Add(new PendingRelease
|
||||
{
|
||||
Id = id,
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { SeasonNumber = seasonNumber, EpisodeNumbers = episodes }
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_remove_same_release()
|
||||
{
|
||||
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 3 });
|
||||
|
||||
var queueId = HashConverter.GetHashInt31(String.Format("pending-{0}-ep{1}", 1, _episode.Id));
|
||||
|
||||
Subject.RemovePendingQueueItems(queueId);
|
||||
|
||||
AssertRemoved(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_remove_multiple_releases_release()
|
||||
{
|
||||
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 2 });
|
||||
AddPending(id: 3, seasonNumber: 2, episodes: new[] { 3 });
|
||||
AddPending(id: 4, seasonNumber: 2, episodes: new[] { 3 });
|
||||
|
||||
var queueId = HashConverter.GetHashInt31(String.Format("pending-{0}-ep{1}", 3, _episode.Id));
|
||||
|
||||
Subject.RemovePendingQueueItems(queueId);
|
||||
|
||||
AssertRemoved(3, 4);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_remove_diffrent_season()
|
||||
{
|
||||
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1 });
|
||||
AddPending(id: 3, seasonNumber: 3, episodes: new[] { 1 });
|
||||
AddPending(id: 4, seasonNumber: 3, episodes: new[] { 1 });
|
||||
|
||||
var queueId = HashConverter.GetHashInt31(String.Format("pending-{0}-ep{1}", 1, _episode.Id));
|
||||
|
||||
Subject.RemovePendingQueueItems(queueId);
|
||||
|
||||
AssertRemoved(1, 2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_remove_diffrent_episodes()
|
||||
{
|
||||
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1 });
|
||||
AddPending(id: 3, seasonNumber: 2, episodes: new[] { 2 });
|
||||
AddPending(id: 4, seasonNumber: 2, episodes: new[] { 3 });
|
||||
|
||||
var queueId = HashConverter.GetHashInt31(String.Format("pending-{0}-ep{1}", 1, _episode.Id));
|
||||
|
||||
Subject.RemovePendingQueueItems(queueId);
|
||||
|
||||
AssertRemoved(1, 2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_remove_multiepisodes()
|
||||
{
|
||||
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1, 2 });
|
||||
|
||||
var queueId = HashConverter.GetHashInt31(String.Format("pending-{0}-ep{1}", 1, _episode.Id));
|
||||
|
||||
Subject.RemovePendingQueueItems(queueId);
|
||||
|
||||
AssertRemoved(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_remove_singleepisodes()
|
||||
{
|
||||
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1, 2 });
|
||||
|
||||
var queueId = HashConverter.GetHashInt31(String.Format("pending-{0}-ep{1}", 2, _episode.Id));
|
||||
|
||||
Subject.RemovePendingQueueItems(queueId);
|
||||
|
||||
AssertRemoved(2);
|
||||
}
|
||||
|
||||
private void AssertRemoved(params int[] ids)
|
||||
{
|
||||
Mocker.GetMock<IPendingReleaseRepository>().Verify(c => c.DeleteMany(It.Is<IEnumerable<int>>(s => s.SequenceEqual(ids))));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Download.TrackedDownloads;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Core.Test.Download.TrackedDownloads
|
||||
{
|
||||
[TestFixture]
|
||||
public class TrackedDownloadServiceFixture : CoreTest<TrackedDownloadService>
|
||||
{
|
||||
private void GivenDownloadHistory()
|
||||
{
|
||||
Mocker.GetMock<IHistoryService>()
|
||||
.Setup(s => s.FindByDownloadId(It.Is<string>(sr => sr == "35238")))
|
||||
.Returns(new List<History.History>(){
|
||||
new History.History(){
|
||||
DownloadId = "35238",
|
||||
SourceTitle = "TV Series S01",
|
||||
SeriesId = 5,
|
||||
EpisodeId = 4
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_track_downloads_using_the_source_title_if_it_cannot_be_found_using_the_download_title()
|
||||
{
|
||||
GivenDownloadHistory();
|
||||
|
||||
var remoteEpisode = new RemoteEpisode
|
||||
{
|
||||
Series = new Series() { Id = 5 },
|
||||
Episodes = new List<Episode> { new Episode { Id = 4 } },
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo()
|
||||
{
|
||||
SeriesTitle = "TV Series",
|
||||
SeasonNumber = 1
|
||||
}
|
||||
};
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Setup(s => s.Map(It.Is<ParsedEpisodeInfo>(i => i.SeasonNumber == 1 && i.SeriesTitle == "TV Series"), It.IsAny<int>(), It.IsAny<IEnumerable<int>>()))
|
||||
.Returns(remoteEpisode);
|
||||
|
||||
var client = new DownloadClientDefinition()
|
||||
{
|
||||
Id = 1,
|
||||
Protocol = DownloadProtocol.Torrent
|
||||
};
|
||||
|
||||
var item = new DownloadClientItem()
|
||||
{
|
||||
Title = "The torrent release folder",
|
||||
DownloadId = "35238",
|
||||
};
|
||||
|
||||
var trackedDownload = Subject.TrackDownload(client, item);
|
||||
|
||||
trackedDownload.Should().NotBeNull();
|
||||
trackedDownload.RemoteEpisode.Should().NotBeNull();
|
||||
trackedDownload.RemoteEpisode.Series.Should().NotBeNull();
|
||||
trackedDownload.RemoteEpisode.Series.Id.Should().Be(5);
|
||||
trackedDownload.RemoteEpisode.Episodes.First().Id.Should().Be(4);
|
||||
trackedDownload.RemoteEpisode.ParsedEpisodeInfo.SeasonNumber.Should().Be(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/NzbDrone.Core.Test/Files/Indexers/HdBits/RecentFeed.json
Normal file
57
src/NzbDrone.Core.Test/Files/Indexers/HdBits/RecentFeed.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"status": 0,
|
||||
"data": [
|
||||
{
|
||||
"id": 257142,
|
||||
"hash": "EABC50AEF9F53CEDED84ADF14144D3368E586F3A",
|
||||
"leechers": 1,
|
||||
"seeders": 46,
|
||||
"name": "Supernatural S10E17 1080p WEB-DL DD5.1 H.264-ECI",
|
||||
"times_completed": 49,
|
||||
"size": 1718009717,
|
||||
"utadded": 1428179446,
|
||||
"added": "2015-04-04T20:30:46+0000",
|
||||
"comments": 0,
|
||||
"numfiles": 1,
|
||||
"filename": "Supernatural.S10E17.1080p.WEB-DL.DD5.1.H.264-ECI.torrent",
|
||||
"freeleech": "no",
|
||||
"type_category": 2,
|
||||
"type_codec": 1,
|
||||
"type_medium": 6,
|
||||
"type_origin": 0,
|
||||
"username": "abc",
|
||||
"owner": 1107944,
|
||||
"tvdb": {
|
||||
"id": 78901,
|
||||
"season": 10,
|
||||
"episode": 17
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 257140,
|
||||
"hash": "BE3BA5396B9A30544353B55FDD89EDE46C8FB72A",
|
||||
"leechers": 0,
|
||||
"seeders": 18,
|
||||
"name": "Scandal S04E18 1080p WEB-DL DD5.1 H.264-ECI",
|
||||
"times_completed": 19,
|
||||
"size": 1789106197,
|
||||
"utadded": 1428179128,
|
||||
"added": "2015-04-04T20:25:28+0000",
|
||||
"comments": 0,
|
||||
"numfiles": 1,
|
||||
"filename": "Scandal.2012.S04E18.1080p.WEB-DL.DD5.1.H.264-ECI.torrent",
|
||||
"freeleech": "no",
|
||||
"type_category": 2,
|
||||
"type_codec": 1,
|
||||
"type_medium": 6,
|
||||
"type_origin": 0,
|
||||
"username": "abc",
|
||||
"owner": 1107944,
|
||||
"tvdb": {
|
||||
"id": 248841,
|
||||
"season": 4,
|
||||
"episode": 18
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
[
|
||||
{
|
||||
"f": "Thunderbirds.Are.Go.S01E09.Slingshot.1080p.WEB-DL.AAC2.0.H.264-Coo7[rartv]",
|
||||
"c": "TV HD Episodes",
|
||||
"d": "magnet:?xt=urn:btih:ff4737b5230307836ec8abce6ab73727f1358bf3&dn=Thunderbirds.Are.Go.S01E09.Slingshot.1080p.WEB-DL.AAC2.0.H.264-Coo7%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce",
|
||||
"s": "44",
|
||||
"l": "19",
|
||||
"t": "896238116",
|
||||
"u": "2015-05-24 19:36:09"
|
||||
},
|
||||
{
|
||||
"f": "Thunderbirds.Are.Go.S01E10.Tunnels.Of.Time.720p.HDTV.x264-RDVAS[rartv]",
|
||||
"c": "TV HD Episodes",
|
||||
"d": "magnet:?xt=urn:btih:47bf1d7bfb72a83300bbe68d0b6aa09591e7a0a1&dn=Thunderbirds.Are.Go.S01E10.Tunnels.Of.Time.720p.HDTV.x264-RDVAS%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce",
|
||||
"s": "179",
|
||||
"l": "125",
|
||||
"t": "556055350",
|
||||
"u": "2015-05-24 19:07:59"
|
||||
},
|
||||
{
|
||||
"f": "Tatau.S01E06.1080p.WEB-DL.AAC2.0.H.264-BS[rartv]",
|
||||
"c": "TV HD Episodes",
|
||||
"d": "magnet:?xt=urn:btih:8857e9b011c7a0483351371721fa9f3ba356dd73&dn=Tatau.S01E06.1080p.WEB-DL.AAC2.0.H.264-BS%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce",
|
||||
"s": "27",
|
||||
"l": "22",
|
||||
"t": "1652442143",
|
||||
"u": "2015-05-24 18:54:49"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"torrent_results": [
|
||||
{
|
||||
"title": "Sense8.S01E01.WEBRip.x264-FGT",
|
||||
"category": "TV Episodes",
|
||||
"download": "magnet:?xt=urn:btih:d8bde635f573acb390c7d7e7efc1556965fdc802&dn=Sense8.S01E01.WEBRip.x264-FGT&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce",
|
||||
"seeders": 304,
|
||||
"leechers": 200,
|
||||
"size": 564198371,
|
||||
"pubdate": "2015-06-05 16:58:11 +0000",
|
||||
"episode_info": {
|
||||
"imdb": "tt2431438",
|
||||
"tvrage": "35197",
|
||||
"tvdb": "268156",
|
||||
"airdate": "2015-06-05",
|
||||
"epnum": "01",
|
||||
"seasonnum": "1",
|
||||
"title": "Limbic Resonance"
|
||||
},
|
||||
"ranked": 1,
|
||||
"info_page": "https:\/\/torrentapi.org\/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_5_6__d8bde635f5"
|
||||
},
|
||||
{
|
||||
"title": "Sense8.S01E02.WEBRip.x264-FGT",
|
||||
"category": "TV Episodes",
|
||||
"download": "magnet:?xt=urn:btih:e5ab5f398d929c791ac4f1d5bb2fba0997372a91&dn=Sense8.S01E02.WEBRip.x264-FGT&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce",
|
||||
"seeders": 299,
|
||||
"leechers": 209,
|
||||
"size": 486918696,
|
||||
"pubdate": "2015-06-05 16:58:23 +0000",
|
||||
"episode_info": {
|
||||
"imdb": "tt2431438",
|
||||
"tvrage": "35197",
|
||||
"tvdb": "268156",
|
||||
"airdate": "2015-06-05",
|
||||
"epnum": "02",
|
||||
"seasonnum": "1",
|
||||
"title": "I Am Also A We"
|
||||
},
|
||||
"ranked": 1,
|
||||
"info_page": "https:\/\/torrentapi.org\/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_5_7__e5ab5f398d"
|
||||
},
|
||||
{
|
||||
"title": "Comedy.Bang.Bang.S04E20.HDTV.x264-YesTV[rartv]",
|
||||
"category": "TV Episodes",
|
||||
"download": "magnet:?xt=urn:btih:0ed8bd14206e211eef9d3d36a48b038f280ef20c&dn=Comedy.Bang.Bang.S04E20.HDTV.x264-YesTV%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce",
|
||||
"seeders": 45,
|
||||
"leechers": 15,
|
||||
"size": 154208067,
|
||||
"pubdate": "2015-06-05 17:33:37 +0000",
|
||||
"episode_info": {
|
||||
"imdb": "tt2176287",
|
||||
"tvrage": "31483",
|
||||
"tvdb": "258310",
|
||||
"airdate": "2015-06-05",
|
||||
"epnum": "20",
|
||||
"seasonnum": "4",
|
||||
"title": "Judd Apatow Wears a Polo and Blue Suede Shoes"
|
||||
},
|
||||
"ranked": 1,
|
||||
"info_page": "https:\/\/torrentapi.org\/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_6_7__0ed8bd1420"
|
||||
},
|
||||
{
|
||||
"title": "Comedy.Bang.Bang.S04E20.720p.HDTV.x264-YesTV[rartv]",
|
||||
"category": "TV HD Episodes",
|
||||
"download": "magnet:?xt=urn:btih:10257dee06327ba66cc2674e08d71b3bb2089b06&dn=Comedy.Bang.Bang.S04E20.720p.HDTV.x264-YesTV%5Brartv%5D&tr=http%3A%2F%2Ftracker.trackerfix.com%3A80%2Fannounce&tr=udp%3A%2F%2F9.rarbg.me%3A2710&tr=udp%3A%2F%2F9.rarbg.to%3A2710&tr=udp%3A%2F%2Fopen.demonii.com%3A1337%2Fannounce",
|
||||
"seeders": 22,
|
||||
"leechers": 6,
|
||||
"size": 514574549,
|
||||
"pubdate": "2015-06-05 17:33:49 +0000",
|
||||
"episode_info": {
|
||||
"imdb": "tt2176287",
|
||||
"tvrage": "31483",
|
||||
"tvdb": "258310",
|
||||
"airdate": "2015-06-05",
|
||||
"epnum": "20",
|
||||
"seasonnum": "4",
|
||||
"title": "Judd Apatow Wears a Polo and Blue Suede Shoes"
|
||||
},
|
||||
"ranked": 1,
|
||||
"info_page": "https:\/\/torrentapi.org\/redirect_to_info.php?token=i5cx7b9agd&p=8_6_4_4_6_8__10257dee06"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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 Show Torrents :: Awesome-HD</title>
|
||||
<link>https://awesome-hd.net/</link>
|
||||
<description>RSS feed for all new tv show uploads.</description>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate>Wed, 20 May 2015 07:06:12 +0000</lastBuildDate>
|
||||
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
|
||||
<generator>Gazelle Feed Class</generator>
|
||||
|
||||
<item>
|
||||
<title><![CDATA[TV-SHOW: Utopia [2013] - HiFi / Blu-Ray / 1080p / mkv / x264 / FLAC / AHD Gold / DXVA / 75% Freeleech]]></title>
|
||||
<description>
|
||||
<![CDATA[Runtime: 50<br />
|
||||
Tagline: <br />
|
||||
Plot:<br />
|
||||
After a group of people, who meet online, discover a bizarre graphic novel which seems to hold mysterious answers, they find themselves being tracked down by a merciless organization known merely as 'The Network'.<br />
|
||||
]]>
|
||||
</description>
|
||||
<pubDate>Tue, 19 May 2015 22:03:37 +0000</pubDate>
|
||||
<link>https://awesome-hd.net/torrents.php?action=download&authkey=redacted&torrent_pass=redacted&id=30689</link>
|
||||
<guid>https://awesome-hd.net/torrents.php?action=download&authkey=redacted&torrent_pass=redacted&id=30689</guid>
|
||||
<comments>https://awesome-hd.net/torrents.php?id=15436</comments>
|
||||
<dc:creator>tehlarsie</dc:creator>
|
||||
</item>
|
||||
<item>
|
||||
<title><![CDATA[TV-SHOW: The Following [2013] - NTb / Blu-Ray / 720p / mkv / x264 / AC-3 / AHD Gold / DXVA]]></title>
|
||||
<description>
|
||||
<![CDATA[Runtime: 43<br />
|
||||
Tagline: Joe Caroll Was Just The Beggining.<br />
|
||||
Plot:<br />
|
||||
A brilliant and charismatic, yet psychotic serial killer communicates with other active serial killers and activates a cult of believers following his every command.<br />
|
||||
]]>
|
||||
</description>
|
||||
<pubDate>Sun, 17 May 2015 18:21:15 +0000</pubDate>
|
||||
<link>https://awesome-hd.net/torrents.php?action=download&authkey=redacted&torrent_pass=redacted&id=30655</link>
|
||||
<guid>https://awesome-hd.net/torrents.php?action=download&authkey=redacted&torrent_pass=redacted&id=30655</guid>
|
||||
<comments>https://awesome-hd.net/torrents.php?id=15428</comments>
|
||||
<dc:creator>Charlesvain</dc:creator>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
834
src/NzbDrone.Core.Test/Files/Indexers/TorrentRss/BitHdtv.xml
Normal file
834
src/NzbDrone.Core.Test/Files/Indexers/TorrentRss/BitHdtv.xml
Normal file
@@ -0,0 +1,834 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<rss version="0.91">
|
||||
<channel>
|
||||
<title>BIT-HDTV - Home of High Definition </title>
|
||||
<link>https://www.bit-hdtv.com</link>
|
||||
<description>This is a private tracker, and you have to register before you can get full access to the site. Before you do anything here at BIT-HDTV we suggest you read the rules! There are only a few rules to abide by, and we do enforce them!</description>
|
||||
<language>en-usde</language>
|
||||
<copyright>Copyright ? 2004 BIT-HDTV - Home of High Definition </copyright>
|
||||
<webMaster>noreply@bit-hdtv.com</webMaster>
|
||||
<image>
|
||||
<title>BIT-HDTV - Home of High Definition </title>
|
||||
<url>https://www.bit-hdtv.com/favicon.ico</url>
|
||||
<link>https://www.bit-hdtv.com</link>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
<description>This is a private tracker, and you have to register before you can get full access to the site. Before you do anything here at BIT-HDTV we suggest you read the rules! There are only a few rules to abide by, and we do enforce them!</description>
|
||||
</image>
|
||||
<item>
|
||||
<title>Egypt's Lost Queens.720p.2014.WEB.H.264</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Documentaries
|
||||
</category>
|
||||
<size> Size: 0.99 GB</size>
|
||||
<status> Status: 2 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 03:19:49</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://img62.imageshack.us/img62/6364/fckuf.png[/img][/center]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 59mn 5s
|
||||
Overall bit rate: 2 399 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate:
|
||||
Resolution: 1280x720
|
||||
Display aspect ratio: 16:9
|
||||
Language:
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: AAC
|
||||
Bitrate:
|
||||
Channel(s): 2
|
||||
Language: English
|
||||
|
||||
[b]Subtitle [/b]
|
||||
Format: UTF-8
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 0.99 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Pretty.Little.Liars.S06E01.720p.HDTV.X264-DIMENSION</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: TV
|
||||
</category>
|
||||
<size> Size: 685.67 MB</size>
|
||||
<status> Status: 3 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 02:57:51</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://img6.imageshack.us/img6/6272/460vy.jpg[/img]
|
||||
[/center]
|
||||
|
||||
[center][img]http://images.tvrage.com/shows/26/25591.jpg[/img][/center]
|
||||
[quote]
|
||||
[b]Description:[/b] [b]Pretty Little Liars[/b] follows four estranged best friends who are reunited one year after their best friend and queen bee of the group, Alison, goes missing only to discover they are receiving messages from an anonymous [b]'A'[/b] who knows all their secrets. The drama stars Lucy Hale ([i]Privileged[/i]) as Aria, Troian Bellisario ([i]Navy NCIS[/i]) as Spencer, Ashley Benson ([i]Bring It On: In It to Win It[/i]) as Hanna and Shay Mitchell as Emily. ([b]Source: [/b]ABC Family)[/quote]
|
||||
|
||||
[quote]
|
||||
[b]Show:[/b] Pretty Little Liars
|
||||
[b]Network:[/b] ABC Family
|
||||
[b]Country:[/b] US
|
||||
[b]Classification:[/b] Scripted
|
||||
[b]Genres:[/b] Drama, Mystery, Teens
|
||||
|
||||
[b]Show Overview:[/b] [url=http://www.tvrage.com/Pretty_Little_Liars]http://www.tvrage.com/Pretty_Little_Liars[/url]
|
||||
|
||||
[b]Episode Info:[/b]
|
||||
[b]Title:[/b] Game On, Charles
|
||||
[b]Description:[/b]
|
||||
[b]Airdate:[/b] 2015-06-02
|
||||
[b]Season:[/b] 6
|
||||
[b]Episode:[/b] 1
|
||||
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 42mn 17s
|
||||
Overall bit rate: 2 267 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 1 838 Kbps
|
||||
Resolution: 1280x720
|
||||
Display aspect ratio: 16:9
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: AC-3
|
||||
Bitrate: 384 Kbps
|
||||
Channel(s): 6
|
||||
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 685.67 MB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Highway.2002.720p.WEB-DL.DD5.1.H264-FGT</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 3.02 GB</size>
|
||||
<status> Status: 3 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 02:42:46</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://ia.media-imdb.com/images/M/MV5BMTg2ODEzNTU4N15BMl5BanBnXkFtZTcwOTQ4OTYxMQ@@._V1_SX300.jpg[/img][/center]
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] Highway
|
||||
[b]Year:[/b] 2002
|
||||
[b]Released:[/b] 26 Mar 2002
|
||||
[b]Runtime:[/b] 97 min
|
||||
[b]Genre:[/b] Crime, Drama
|
||||
[b]Director:[/b] James Cox
|
||||
[b]Writer:[/b] Scott Rosenberg
|
||||
[b]Actors:[/b] Jared Leto, Jake Gyllenhaal, Selma Blair, John C. McGinley
|
||||
[b]Plot:[/b] Jack is caught with the wife of his employer, a Vegas thug. The thug sends goons after Jack, who convinces his best friend, Pilot, to flee with him. Pilot insists that they head for Seattle...
|
||||
[b]Language:[/b] English
|
||||
[b]Country:[/b] USA
|
||||
[b]Awards:[/b] 4 nominations.
|
||||
[b]Metascore:[/b] N/A
|
||||
[b]Raiting:[/b] 6.3
|
||||
[b]Votes:[/b] 4706
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt0165361
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 36mn
|
||||
Overall bit rate: 4 461 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 3 988 Kbps
|
||||
Resolution: 1280x544
|
||||
Display aspect ratio: 2.35:1
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: AC-3
|
||||
Bitrate: 384 Kbps
|
||||
Channel(s): 6
|
||||
Language: English
|
||||
|
||||
[b]Subtitle [/b]
|
||||
Format: UTF-8
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 3.02 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Kajaki.2014.LIMITED.1080p.BluRay.x264-GECKOS</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 7.65 GB</size>
|
||||
<status> Status: 6 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 02:06:42</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://ia.media-imdb.com/images/M/MV5BMTQ5MjYxMDM4MV5BMl5BanBnXkFtZTgwNDU2NzA0MzE@._V1_SX300.jpg[/img][/center]
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] Kajaki
|
||||
[b]Year:[/b] 2014
|
||||
[b]Released:[/b] 28 Nov 2014
|
||||
[b]Runtime:[/b] 108 min
|
||||
[b]Genre:[/b] Adventure, Drama, Thriller
|
||||
[b]Director:[/b] Paul Katis
|
||||
[b]Writer:[/b] Tom Williams (screenplay), Tom Williams
|
||||
[b]Actors:[/b] Mark Stanley, David Elliot, Malachi Kirby, Paul Luebke
|
||||
[b]Plot:[/b] Kajaki Dam 2006. A company of young British soldiers encounter an unexpected, terrifying enemy. A dried-out river bed, and under every step the possibility of an anti-personnel mine. A mine that could cost you your leg - or your life.
|
||||
[b]Language:[/b] English
|
||||
[b]Country:[/b] UK, Jordan
|
||||
[b]Awards:[/b] N/A
|
||||
[b]Metascore:[/b] N/A
|
||||
[b]Raiting:[/b] 8.1
|
||||
[b]Votes:[/b] 294
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt3622120
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 48mn
|
||||
Overall bit rate: 10.1 Mbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 9 346 Kbps
|
||||
Resolution: 1920x808
|
||||
Display aspect ratio: 2.40:1
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: DTS
|
||||
Bitrate: 768 Kbps
|
||||
Channel(s): 6
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 7.65 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Demon Baby.2014.720p.WEB-DL.x264 ETRG.mkv</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 2.05 GB</size>
|
||||
<status> Status: 3 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 02:02:35</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
NO INFO
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 9mn
|
||||
Overall bit rate: 4 199 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate:
|
||||
Resolution: 1280x532
|
||||
Display aspect ratio: 2.40:1
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: AAC
|
||||
Bitrate:
|
||||
Channel(s): 2
|
||||
Language: English
|
||||
|
||||
[b]Subtitle [/b]
|
||||
Format: UTF-8
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 2.05 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>The Badger Game 2014 720p WEB-DL x264 ETRG</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 3.11 GB</size>
|
||||
<status> Status: 3 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 01:59:47</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://ia.media-imdb.com/images/M/MV5BMjM3NDY3Njg2Ml5BMl5BanBnXkFtZTgwNzc1NzYzMDE@._V1_SX300.jpg[/img][/center]
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] The Badger Game
|
||||
[b]Year:[/b] 2014
|
||||
[b]Released:[/b] 26 Sep 2014
|
||||
[b]Runtime:[/b] 99 min
|
||||
[b]Genre:[/b] Crime, Drama, Thriller
|
||||
[b]Director:[/b] Joshua Wagner, Thomas Zambeck
|
||||
[b]Writer:[/b] Joshua Wagner, Thomas Zambeck, Thomas Zambeck (story)
|
||||
[b]Actors:[/b] Augie Duke, Patrick Cronen, Jillian Leigh, Sam Boxleitner
|
||||
[b]Plot:[/b] A chronic philanderer falls victim to an extortion scheme when he is abducted by four masked strangers demanding retribution for his sins.
|
||||
[b]Language:[/b] English
|
||||
[b]Country:[/b] USA
|
||||
[b]Awards:[/b] N/A
|
||||
[b]Metascore:[/b] N/A
|
||||
[b]Raiting:[/b] N/A
|
||||
[b]Votes:[/b] N/A
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt2836434
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 39mn
|
||||
Overall bit rate: 4 499 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 4 025 Kbps
|
||||
Resolution: 1280x640
|
||||
Display aspect ratio: 2.000
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: AC-3
|
||||
Bitrate: 384 Kbps
|
||||
Channel(s): 6
|
||||
Language: English
|
||||
|
||||
[b]Subtitle [/b]
|
||||
Format: UTF-8
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 3.11 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>It.Lives.Again.1978.HDTV.720p.x264.Ac3.mkv</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 4.37 GB</size>
|
||||
<status> Status: 3 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 01:47:08</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://ia.media-imdb.com/images/M/MV5BMTQxOTEwMTQ1M15BMl5BanBnXkFtZTcwMzk2MTgxMQ@@._V1_SX300.jpg[/img][/center]
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] It Lives Again
|
||||
[b]Year:[/b] 1978
|
||||
[b]Released:[/b] 10 May 1978
|
||||
[b]Runtime:[/b] 91 min
|
||||
[b]Genre:[/b] Horror
|
||||
[b]Director:[/b] Larry Cohen
|
||||
[b]Writer:[/b] Larry Cohen (based on characters created for the screen by), Larry Cohen
|
||||
[b]Actors:[/b] Frederic Forrest, Kathleen Lloyd, John P. Ryan, John Marley
|
||||
[b]Plot:[/b] An epidemic of mutant monster babies sweeps America.
|
||||
[b]Language:[/b] English
|
||||
[b]Country:[/b] USA
|
||||
[b]Awards:[/b] N/A
|
||||
[b]Metascore:[/b] N/A
|
||||
[b]Raiting:[/b] 5.0
|
||||
[b]Votes:[/b] 1269
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt0077756
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 30mn
|
||||
Overall bit rate: 6 900 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 6 571 Kbps
|
||||
Resolution: 1280x720
|
||||
Display aspect ratio: 16:9
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: AC-3
|
||||
Bitrate: 192 Kbps
|
||||
Channel(s): 1
|
||||
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 4.37 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Scienceless.Fiction.2014.1080p.BluRay.x264-SADPANDA</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 6.56 GB</size>
|
||||
<status> Status: 5 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 01:39:37</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] Scienceless Fiction
|
||||
[b]Year:[/b] 2014
|
||||
[b]Released:[/b] 5 Mar 2014
|
||||
[b]Runtime:[/b] N/A
|
||||
[b]Genre:[/b] Action, Comedy, Fantasy
|
||||
[b]Director:[/b] Bill Zebub
|
||||
[b]Writer:[/b] Bill Zebub
|
||||
[b]Actors:[/b] Nadine Theresa Stevens, Andrea Hall, Scarlett Storm, Lydia Lael
|
||||
[b]Plot:[/b] N/A
|
||||
[b]Language:[/b] English
|
||||
[b]Country:[/b] USA
|
||||
[b]Awards:[/b] N/A
|
||||
[b]Metascore:[/b] N/A
|
||||
[b]Raiting:[/b] 2.4
|
||||
[b]Votes:[/b] 7
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt3447592
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 49mn
|
||||
Overall bit rate: 8 604 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 8 411 Kbps
|
||||
Resolution: 1920x1080
|
||||
Display aspect ratio: 16:9
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: AC-3
|
||||
Bitrate: 192 Kbps
|
||||
Channel(s): 2
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 6.56 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Don't.Say.a.Word.2001.720p.BluRay.DTS.x264-CRiSC.mkv</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 5.62 GB</size>
|
||||
<status> Status: 4 seeders and no leecher</status>
|
||||
<speed> Speed: 0.00 KB/s</speed>
|
||||
<pubDate>2015-06-03 01:37:02</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://ia.media-imdb.com/images/M/MV5BMTI0NDMxMzgyOF5BMl5BanBnXkFtZTcwNDYzODAzMQ@@._V1_SX300.jpg[/img][/center]
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] Don't Say a Word
|
||||
[b]Year:[/b] 2001
|
||||
[b]Released:[/b] 28 Sep 2001
|
||||
[b]Runtime:[/b] 113 min
|
||||
[b]Genre:[/b] Crime, Thriller
|
||||
[b]Director:[/b] Gary Fleder
|
||||
[b]Writer:[/b] Andrew Klavan (novel), Anthony Peckham (screenplay), Patrick Smith Kelly (screenplay)
|
||||
[b]Actors:[/b] Michael Douglas, Sean Bean, Brittany Murphy, Skye McCole Bartusiak
|
||||
[b]Plot:[/b] When the daughter of a psychiatrist is kidnapped, he's horrified to discover that the abductors' demand is that he break through to a post traumatic stress disorder suffering young woman who knows a secret...
|
||||
[b]Language:[/b] English, Italian, Chinese
|
||||
[b]Country:[/b] USA, Australia, Switzerland, Canada
|
||||
[b]Awards:[/b] 1 nomination.
|
||||
[b]Metascore:[/b] 38
|
||||
[b]Raiting:[/b] 6.3
|
||||
[b]Votes:[/b] 37331
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt0260866
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 53mn
|
||||
Overall bit rate: 7 084 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 5 434 Kbps
|
||||
Resolution: 1280x544
|
||||
Display aspect ratio: 2.35:1
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: DTS
|
||||
Bitrate: 1 509 Kbps
|
||||
Channel(s): 6
|
||||
Language: English
|
||||
|
||||
[b]Subtitle [/b]
|
||||
Format: UTF-8
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 5.62 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Onion.Field.1979.720p.BluRay.x264-SiNNERS</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 6.56 GB</size>
|
||||
<status> Status: 4 seeders and no leecher</status>
|
||||
<speed> Speed: 0.00 KB/s</speed>
|
||||
<pubDate>2015-06-03 01:28:52</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://ia.media-imdb.com/images/M/MV5BMTU0MDI0MDMyMF5BMl5BanBnXkFtZTgwMjgyMjEyMDE@._V1_SX300.jpg[/img][/center]
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] The Onion Field
|
||||
[b]Year:[/b] 1979
|
||||
[b]Released:[/b] 24 Apr 1980
|
||||
[b]Runtime:[/b] 122 min
|
||||
[b]Genre:[/b] Crime, Drama
|
||||
[b]Director:[/b] Harold Becker
|
||||
[b]Writer:[/b] Joseph Wambaugh (book), Joseph Wambaugh (screenplay)
|
||||
[b]Actors:[/b] John Savage, James Woods, Franklyn Seales, Ted Danson
|
||||
[b]Plot:[/b] Greg Powell is a disturbed ex-con who recruits Jimmy Smith (aka Jimmy Youngblood), a petty thief, as his partner in crime. Powell panics one night when the two of them are pulled over by a ...
|
||||
[b]Language:[/b] English
|
||||
[b]Country:[/b] USA
|
||||
[b]Awards:[/b] Nominated for 1 Golden Globe. Another 2 wins & 1 nomination.
|
||||
[b]Metascore:[/b] N/A
|
||||
[b]Raiting:[/b] 7.0
|
||||
[b]Votes:[/b] 3115
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt0079668
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 2h 6mn
|
||||
Overall bit rate: 7 432 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 5 923 Kbps
|
||||
Resolution: 1280x688
|
||||
Display aspect ratio: 1.85:1
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: DTS
|
||||
Bitrate: 1 509 Kbps
|
||||
Channel(s): 2
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 6.56 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Boys.In.The.Band.1970.720p.BluRay.x264-SiNNERS</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 5.47 GB</size>
|
||||
<status> Status: 2 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 01:28:46</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
NO INFO
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 2h 0mn
|
||||
Overall bit rate: 6 522 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 5 012 Kbps
|
||||
Resolution: 1280x720
|
||||
Display aspect ratio: 16:9
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: DTS
|
||||
Bitrate: 1 509 Kbps
|
||||
Channel(s): 2
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 5.47 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Unfinished.Business.2015.720p.BluRay.DD5.1.x264-BiTHD</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 4.79 GB</size>
|
||||
<status> Status: 20 seeders and 6 leechers</status>
|
||||
<speed> Speed: 0.00 KB/s</speed>
|
||||
<pubDate>2015-06-03 01:24:49</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center]
|
||||
[img]http://www.impawards.com/2015/posters/unfinished_business_ver7.jpg[/img]
|
||||
[img]http://www.impawards.com/2015/posters/unfinished_business_ver8.jpg[/img]
|
||||
[img]http://www.fatmovieguy.com/wp-content/uploads/2014/11/Unfinished-Business-Movie-Poster.jpg[/img][/center]
|
||||
|
||||
[center] [size=5][b]General Information:[/b][/size][/center]
|
||||
RUNTIME........: 1:30:56
|
||||
CHAPTERS.......: Yes
|
||||
SIZE...........: 4,78 GB
|
||||
VIDEO CODEC....: x264 core, 2 pass HighL4.1
|
||||
RESOLUTION.....: 1280x532
|
||||
BITRATE........: 6900 Kbps
|
||||
FRAMERATE......: 23.976 fps
|
||||
AUDIO..........: English, DTS 5.1, 1509 kbps
|
||||
SUBTITLES......: English, Spanish (SRT)
|
||||
SOURCE.........: Unfinished Business 2015 1080p BluRay AVC DTS-HD MA 5.1-HDAccess
|
||||
|
||||
ENCODER........: BiTHD
|
||||
RELEASE DATE...: 03.06.2015
|
||||
|
||||
[center][size=5][b]Screenshots:[/b][/size]
|
||||
|
||||
[size=5][b]Source vs Encode[/b][/size]
|
||||
|
||||
[URL=http://imgbox.com/bQ5XEVX3][IMG]http://3.t.imgbox.com/bQ5XEVX3.jpg[/IMG][/URL] [URL=http://imgbox.com/odAsd44y][IMG]http://4.t.imgbox.com/odAsd44y.jpg[/IMG][/URL] [URL=http://imgbox.com/ZEl141ko][IMG]http://5.t.imgbox.com/ZEl141ko.jpg[/IMG][/URL] [URL=http://imgbox.com/c9nKPnln][IMG]http://8.t.imgbox.com/c9nKPnln.jpg[/IMG][/URL] [URL=http://imgbox.com/C1LOEEx9][IMG]http://9.t.imgbox.com/C1LOEEx9.jpg[/IMG][/URL] [URL=http://imgbox.com/Feig0iuM][IMG]http://0.t.imgbox.com/Feig0iuM.jpg[/IMG][/URL][/center]
|
||||
Size: 4.79 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Merchant.of.Four.Seasons.1971.720p.BluRay.x264-USURY</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 3.28 GB</size>
|
||||
<status> Status: 2 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 01:15:58</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://ia.media-imdb.com/images/M/MV5BMTI4NjcyMTc4Ml5BMl5BanBnXkFtZTcwNTIxMDQyMQ@@._V1_SX300.jpg[/img][/center]
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] The Merchant of Four Seasons
|
||||
[b]Year:[/b] 1971
|
||||
[b]Released:[/b] 4 Nov 1971
|
||||
[b]Runtime:[/b] 88 min
|
||||
[b]Genre:[/b] Drama
|
||||
[b]Director:[/b] Rainer Werner Fassbinder
|
||||
[b]Writer:[/b] Rainer Werner Fassbinder
|
||||
[b]Actors:[/b] Hans Hirschmüller, Irm Hermann, Hanna Schygulla, Andrea Schober
|
||||
[b]Plot:[/b] Hans is a street fruit peddler and born-loser. His choice of career upsets his bourgeois family, causing him to turn to drinking and violence. After recovering from a debilitating heart ...
|
||||
[b]Language:[/b] German, Arabic
|
||||
[b]Country:[/b] West Germany
|
||||
[b]Awards:[/b] 3 wins & 5 nominations.
|
||||
[b]Metascore:[/b] N/A
|
||||
[b]Raiting:[/b] 7.5
|
||||
[b]Votes:[/b] 2255
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt0067227
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 28mn
|
||||
Overall bit rate: 5 287 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 4 645 Kbps
|
||||
Resolution: 992x720
|
||||
Display aspect ratio: 1.378
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: AC-3
|
||||
Bitrate: 640 Kbps
|
||||
Channel(s): 1
|
||||
Language: German
|
||||
|
||||
[b]Subtitle [/b]
|
||||
Format: UTF-8
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
Size: 3.28 GB
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Wolfen.1981.720p.BluRay.X264-AMIABLE</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 5.46 GB</size>
|
||||
<status> Status: 3 seeders and 0 leechers</status>
|
||||
<speed> Speed: no traffic</speed>
|
||||
<pubDate>2015-06-03 01:15:53</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://ia.media-imdb.com/images/M/MV5BMTkwNDc4NDQ3Nl5BMl5BanBnXkFtZTYwNTM0MjI5._V1_SX300.jpg[/img][/center]
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] Wolfen
|
||||
[b]Year:[/b] 1981
|
||||
[b]Released:[/b] 24 Jul 1981
|
||||
[b]Runtime:[/b] 115 min
|
||||
[b]Genre:[/b] Horror, Thriller
|
||||
[b]Director:[/b] Michael Wadleigh
|
||||
[b]Writer:[/b] Whitley Strieber (based on the novel by), David Eyre (screen story), Michael Wadleigh (screen story), David Eyre (screenplay), Michael Wadleigh (screenplay)
|
||||
[b]Actors:[/b] Albert Finney, Diane Venora, Edward James Olmos, Gregory Hines
|
||||
[b]Plot:[/b] A New York cop investigates a series of brutal deaths that resemble animal attacks.
|
||||
[b]Language:[/b] English
|
||||
[b]Country:[/b] USA
|
||||
[b]Awards:[/b] 2 wins & 4 nominations.
|
||||
[b]Metascore:[/b] N/A
|
||||
[b]Raiting:[/b] 6.3
|
||||
[b]Votes:[/b] 5773
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt0083336
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 54mn
|
||||
Overall bit rate: 6 857 Kbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 5 346 Kbps
|
||||
Resolution: 1280x536
|
||||
Display aspect ratio: 2.40:1
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: DTS
|
||||
Bitrate: 1 509 Kbps
|
||||
Channel(s): 6
|
||||
Language: English
|
||||
|
||||
[b]Subtitle [/b]
|
||||
Format: UTF-8
|
||||
Type: SDH
|
||||
Language: English
|
||||
|
||||
[b]Subtitle [/b]
|
||||
Format: UTF-8
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Run.All.Night.2015.1080p.BluRay.x264-SPARKS</title>
|
||||
<link>https://www.bit-hdtv.com/rssdownload.php?id=123</link>
|
||||
<category>
|
||||
Category: Movies
|
||||
</category>
|
||||
<size> Size: 8.74 GB</size>
|
||||
<status> Status: 18 seeders and 2 leechers</status>
|
||||
<speed> Speed: 0.00 KB/s</speed>
|
||||
<pubDate>2015-06-03 00:28:55</pubDate>
|
||||
<description>
|
||||
Description:
|
||||
[center][img]http://ia.media-imdb.com/images/M/MV5BMTU2ODI3ODEyOV5BMl5BanBnXkFtZTgwMTM3NTQzNDE@._V1_SX300.jpg[/img][/center]
|
||||
|
||||
[quote]
|
||||
[b]Title:[/b] Run All Night
|
||||
[b]Year:[/b] 2015
|
||||
[b]Released:[/b] 13 Mar 2015
|
||||
[b]Runtime:[/b] 114 min
|
||||
[b]Genre:[/b] Action, Crime, Drama
|
||||
[b]Director:[/b] Jaume Collet-Serra
|
||||
[b]Writer:[/b] Brad Ingelsby
|
||||
[b]Actors:[/b] Liam Neeson, Ed Harris, Joel Kinnaman, Boyd Holbrook
|
||||
[b]Plot:[/b] Mobster and hit man Jimmy Conlon has one night to figure out where his loyalties lie: with his estranged son, Mike, whose life is in danger, or his longtime best friend, mob boss Shawn Maguire, who wants Mike to pay for the death of his own son.
|
||||
[b]Language:[/b] English
|
||||
[b]Country:[/b] USA
|
||||
[b]Awards:[/b] N/A
|
||||
[b]Metascore:[/b] 59
|
||||
[b]Raiting:[/b] 7.0
|
||||
[b]Votes:[/b] 10707
|
||||
[b]IMDB:[/b] http://www.imdb.com/title/tt2199571
|
||||
[/quote]
|
||||
[quote]
|
||||
[b]General[/b]
|
||||
Format: Matroska
|
||||
Duration: 1h 54mn
|
||||
Overall bit rate: 10.9 Mbps
|
||||
|
||||
[b]Video[/b]
|
||||
Format: AVC
|
||||
Format profile:
|
||||
Bitrate: 9 434 Kbps
|
||||
Resolution: 1920x800
|
||||
Display aspect ratio: 2.40:1
|
||||
Language: English
|
||||
|
||||
[b]Audio[/b]
|
||||
Format: DTS
|
||||
Bitrate: 1 509 Kbps
|
||||
Channel(s): 6
|
||||
Language: English
|
||||
|
||||
[/quote]
|
||||
[color=Red][size=4]Please leave feedback by giving comments or by pressing thanks. Enjoy![/color][/size]
|
||||
</description>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
53
src/NzbDrone.Core.Test/Files/Indexers/TorrentRss/Doki.xml
Normal file
53
src/NzbDrone.Core.Test/Files/Indexers/TorrentRss/Doki.xml
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>Doki Fansubs Torrents (latest)</title>
|
||||
<link>http://tracker.anime-index.org/index.php?page=torrents&search=doki&category=0&active=0</link>
|
||||
<description>[Doki] Torrents RSS (generated by Yukinrss)</description>
|
||||
<ttl>15</ttl>
|
||||
<pubDate>Thu, 02 Jul 2015 08:18:28 GMT</pubDate>
|
||||
<generator>Yukinrss 1.03.58 (http://yukinrss.net/)</generator>
|
||||
<image>
|
||||
<url>http://yukinrss.net/img/rss-doki.png</url>
|
||||
<title>Doki Fansubs Torrents (latest)</title>
|
||||
<link>http://tracker.anime-index.org/index.php?page=torrents&search=doki&category=0&active=0</link>
|
||||
<width>144</width>
|
||||
<height>52</height>
|
||||
</image>
|
||||
<item>
|
||||
<title>[Doki] PriPara 50 (848x480 h264 AAC) [6F0B49FD] mkv</title>
|
||||
<pubDate>Thu, 02 Jul 2015 08:18:29 GMT</pubDate>
|
||||
<link>http://tracker.anime-index.org/index.php?page=torrents&search=doki&category=0&active=0</link>
|
||||
<guid isPermaLink="true">http://tracker.anime-index.org/download.php?id=82d8ad84403e01a7786130905ca169a3429e657f&f=%5BDoki%5D+PriPara+-+50+%28848x480+h264+AAC%29+%5B6F0B49FD%5D.mkv.torrent</guid>
|
||||
<enclosure url="http://tracker.anime-index.org/download.php?id=82d8ad84403e01a7786130905ca169a3429e657f&f=%5BDoki%5D+PriPara+-+50+%28848x480+h264+AAC%29+%5B6F0B49FD%5D.mkv.torrent" type="application/x-bittorrent" length="15360"/>
|
||||
</item>
|
||||
<item>
|
||||
<title>[Doki] PriPara 50 (1280x720 Hi10P AAC) [441163C4] mkv</title>
|
||||
<pubDate>Thu, 02 Jul 2015 08:18:29 GMT</pubDate>
|
||||
<link>http://tracker.anime-index.org/index.php?page=torrents&search=doki&category=0&active=0</link>
|
||||
<guid isPermaLink="true">http://tracker.anime-index.org/download.php?id=8f7d8bf3d68bb03c88f3fb9b17fd07ca96265085&f=%5BDoki%5D+PriPara+-+50+%281280x720+Hi10P+AAC%29+%5B441163C4%5D.mkv.torrent</guid>
|
||||
<enclosure url="http://tracker.anime-index.org/download.php?id=8f7d8bf3d68bb03c88f3fb9b17fd07ca96265085&f=%5BDoki%5D+PriPara+-+50+%281280x720+Hi10P+AAC%29+%5B441163C4%5D.mkv.torrent" type="application/x-bittorrent" length="15360"/>
|
||||
</item>
|
||||
<item>
|
||||
<title>[Doki] Hitoribocchi no OO Seikatsu Chapter 10 [52706FCC] zip</title>
|
||||
<pubDate>Sat, 27 Jun 2015 10:01:02 GMT</pubDate>
|
||||
<link>http://tracker.anime-index.org/index.php?page=torrents&search=doki&category=0&active=0</link>
|
||||
<guid isPermaLink="true">http://tracker.anime-index.org/download.php?id=52b245c90ba00b9755c1b49eaad15da8c39ae742&f=%5BDoki%5D+Hitoribocchi+no+OO+Seikatsu+-+Chapter+10+%5B52706FCC%5D.zip.torrent</guid>
|
||||
<enclosure url="http://tracker.anime-index.org/download.php?id=52b245c90ba00b9755c1b49eaad15da8c39ae742&f=%5BDoki%5D+Hitoribocchi+no+OO+Seikatsu+-+Chapter+10+%5B52706FCC%5D.zip.torrent" type="application/x-bittorrent" length="15360"/>
|
||||
</item>
|
||||
<item>
|
||||
<title>[Doki] PriPara 49 (1280x720 Hi10P AAC) [328C34F3] mkv</title>
|
||||
<pubDate>Fri, 26 Jun 2015 00:54:59 GMT</pubDate>
|
||||
<link>http://tracker.anime-index.org/index.php?page=torrents&search=doki&category=0&active=0</link>
|
||||
<guid isPermaLink="true">http://tracker.anime-index.org/download.php?id=a376fbcd79a40f7ad11eb5af2951a33fb11b8394&f=%5BDoki%5D+PriPara+-+49+%281280x720+Hi10P+AAC%29+%5B328C34F3%5D.mkv.torrent</guid>
|
||||
<enclosure url="http://tracker.anime-index.org/download.php?id=a376fbcd79a40f7ad11eb5af2951a33fb11b8394&f=%5BDoki%5D+PriPara+-+49+%281280x720+Hi10P+AAC%29+%5B328C34F3%5D.mkv.torrent" type="application/x-bittorrent" length="15360"/>
|
||||
</item>
|
||||
<item>
|
||||
<title>[Doki] PriPara 44 (848x480 h264 AAC) [43DB504A] mkv</title>
|
||||
<pubDate>Thu, 14 May 2015 01:21:19 GMT</pubDate>
|
||||
<link>http://tracker.anime-index.org/index.php?page=torrents&search=doki&category=0&active=0</link>
|
||||
<guid isPermaLink="true">http://tracker.anime-index.org/download.php?id=239196fdeb6427e9c11d69d2853642873481d855&f=%5BDoki%5D+PriPara+-+44+%28848x480+h264+AAC%29+%5B43DB504A%5D.mkv.torrent</guid>
|
||||
<enclosure url="http://tracker.anime-index.org/download.php?id=239196fdeb6427e9c11d69d2853642873481d855&f=%5BDoki%5D+PriPara+-+44+%28848x480+h264+AAC%29+%5B43DB504A%5D.mkv.torrent" type="application/x-bittorrent" length="15360"/>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,666 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>immortalseed.me RSS Syndicator</title>
|
||||
<link>http://immortalseed.me</link>
|
||||
<description>Latest Torrents on immortalseed.me</description>
|
||||
<language>en-US</language>
|
||||
<image>
|
||||
<title>immortalseed.me RSS Syndicator</title>
|
||||
<url>http://immortalseed.me</url>
|
||||
<link>http://immortalseed.me</link>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
<description>immortalseed.me RSS Syndicator</description>
|
||||
</image>
|
||||
<copyright>Copyright &copy; 2015 immortalseed.me</copyright>
|
||||
<webMaster>contact@immortalseed.me</webMaster>
|
||||
<lastBuildDate>Fri, 06 Feb 2015 13:40:57 -12</lastBuildDate>
|
||||
<ttl>20</ttl>
|
||||
<generator>immortalseed.me RSS Syndicator</generator>
|
||||
<item>
|
||||
<title>Conan.2015.02.05.Jeff.Bridges.720p.HDTV.X264-CROOKS</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 2 / Size: 938.49 MB / Snatched: 5 x times<br /><br />Describing itself as a traditional late-night talk show, Conan draws its comedy from recent news stories, political figures and prominent celebrities, as well as aspects of the show itself. The show typically opens with a monologue from Conan OBrien relating to recent headlines and frequently features exchanges with his sidekick, Andy Richter, and members of the audience. The next segment is devoted to a celebrity interview, with guests ranging from actors and musicians to media personalities and political figures. The show then closes with either a musical or comedy performance.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/195.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/195.jpg" border="0" alt="" onload="TSResizeImage(this, '350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374534</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 13:32:26</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Hollywood.Sessions.Part.5.720p.HDTV.X264-BATV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 4 / Leechers: 1 / Size: 1.44 GB / Snatched: 3 x times<br /><br />The Los Angeles Times and EPIX have joined forces to co-produce a new series featuring 2014s biggest film stars and potential award contenders in unguarded conversation with Times writers. <br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1864121706_5f6e7e789e1b7713a46d1493919c6489">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57507.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57507.jpg" border="0" alt="" onload="TSResizeImage(this, '1864121706_5f6e7e789e1b7713a46d1493919c6489');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374526</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 12:09:18</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Jump.S02E05.720p.HDTV.X264-C4TV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 4 / Leechers: 0 / Size: 1.38 GB / Snatched: 3 x times<br /><br />The Jump is a reality series which follows twelve celebrities as they take on some of the most challenging and dangerous winter sports in an effort to become crowned the series champion.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1428502695_5f6e7e789e1b7713a46d1493919c6489">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57507.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57507.jpg" border="0" alt="" onload="TSResizeImage(this, '1428502695_5f6e7e789e1b7713a46d1493919c6489');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374524</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 12:00:55</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Eye.Candy.S01E04.720p.WEBRip.H264-TURBO</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 0 / Size: 915.73 MB / Snatched: 8 x times<br /><br />Eye Candy centers on tech genius Lindy who, convinced by her roommate to begin online dating, begins to suspect that one of her mysterious suitors may be a deadly cyber stalker. When her friends at the elusive cyber-police uncover a potential serial killer in Manhattan, all signs point to one of Lindys dates. Teaming up with this band of hackers Lindy works to solve the murders while unleashing her own style of justice on the streets of New York City.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1147507273_3cb6176bf6c1a5a396901d9250431cf3">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/57061.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/57061.jpg" border="0" alt="" onload="TSResizeImage(this, '1147507273_3cb6176bf6c1a5a396901d9250431cf3');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374521</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 11:10:43</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Nightwatch.S01E03.720p.HDTV.X264-TOPKEK</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 8 / Leechers: 0 / Size: 1.02 GB / Snatched: 10 x times<br /><br />Nightwatch follows the dangerous and hectic stretch between 9PM and 3AM when emergency responders come across the most unnerving cases. New Orleans is the backdrop for this nonfiction drama series where cameras have unlimited access to the citys Fire Department and EMS Unit. Those who cover the night shift battle time and circumstance to save lives while they try to keep their own personal lives and relationships in order.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1943113810_3cb6176bf6c1a5a396901d9250431cf3">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/57061.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/57061.jpg" border="0" alt="" onload="TSResizeImage(this, '1943113810_3cb6176bf6c1a5a396901d9250431cf3');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374516</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 09:41:35</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Portlandia.S05E05.720p.HDTV.X264-TOPKEK</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 15 / Leechers: 0 / Size: 619.27 MB / Snatched: 16 x times<br /><br />Portlandia features Fred Armisen, Carrie Brownstein and guest stars satirizing such alternative-culture types as the owners of a feminist book store, a bike messenger, a punk-rock couple, and an arty duo obsessed with putting little cut-outs of birds on anything they lay their hands on. Each half-hour episode will consist of interwoven short films, with some characters recurring from week-to-week.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="261112036_3cb6176bf6c1a5a396901d9250431cf3">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/57061.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/57061.jpg" border="0" alt="" onload="TSResizeImage(this, '261112036_3cb6176bf6c1a5a396901d9250431cf3');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374515</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 09:39:06</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>American.Idol.S14E10.720p.HDTV.X264-2HD</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 12 / Leechers: 0 / Size: 1.29 GB / Snatched: 13 x times<br /><br />The American Idol TV show is a 60 minute singing talent competition reality series on the FOX Network where singers compete to become the newest &quot;American Idol&quot;. After each contestant performs, the judges give their opinions which are sometimes very complimentary and sometimes extremely critical. After each episode ends, the viewing audience votes on whose performance they most liked. The one with the fewest votes is eliminated and the performances and voting continues weekly until the ultimate winner is chosen. That individual wins a million dollars and a recording contract. The losers also often do quite well in their careers due to the exposure they got on the show.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1177906378_3cb6176bf6c1a5a396901d9250431cf3">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/57061.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/57061.jpg" border="0" alt="" onload="TSResizeImage(this, '1177906378_3cb6176bf6c1a5a396901d9250431cf3');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374502</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 09:12:21</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Alaska-Battle.On.The.Bay.S01E05.Peak.Season.720p.HDTV.X264-DHD</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 8 / Leechers: 0 / Size: 1.39 GB / Snatched: 8 x times<br /><br />A reality series following five fishing boats on Bristol Bay over a four-week sockeye salmon season.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1130568413_5f6e7e789e1b7713a46d1493919c6489">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57507.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57507.jpg" border="0" alt="" onload="TSResizeImage(this, '1130568413_5f6e7e789e1b7713a46d1493919c6489');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374492</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 08:23:27</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Shortland.Street.S23E241.720p.HDTV.X264-FiHTV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 4 / Leechers: 0 / Size: 587.77 MB / Snatched: 3 x times<br /><br />Shortland Street is a daily soap opera which originated in New Zealand. It follows the lives of the staff who work at a medical clinic. The series has also been shown on the ITV network in the United Kingdom.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1770260589_5f6e7e789e1b7713a46d1493919c6489">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57507.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57507.jpg" border="0" alt="" onload="TSResizeImage(this, '1770260589_5f6e7e789e1b7713a46d1493919c6489');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374484</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 07:27:33</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Wizard.Wars.S01E08.Silly.Rabbits.720p.HDTV.X264-DHD</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 9 / Leechers: 0 / Size: 1.19 GB / Snatched: 9 x times<br /><br />Penn & Teller headline this competition series, which takes viewers behind the scenes of magic by challenging a new team of magicians each week to create the most jaw-dropping illusions using an array of random objects and transforming them into eye-popping miracles. The winning team of challengers in the first round then take on the expert &quot;home team&quot; of world-renowned wizards: Two-time World Championship of Magic winner Gregory Wilson; Wynn Resort resident magician Shimshi; YouTube sensation Justin Flom, and internationally renowned mentalist Angela Funovits. Judges on the show include the aforementioned Penn & Teller, Jason Latimer and Christen Gerhart.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1222177821_5f6e7e789e1b7713a46d1493919c6489">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57507.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57507.jpg" border="0" alt="" onload="TSResizeImage(this, '1222177821_5f6e7e789e1b7713a46d1493919c6489');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374482</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 07:22:53</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Daily.Show.2015.02.05.Bob.Odenkirk.720p.HDTV.X264-BATV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 57 / Leechers: 4 / Size: 591.41 MB / Snatched: 67 x times<br /><br />Providing comedy/news in the tradition of TV Nation and SNL&apos;s Weekend Update, Comedy Central&apos;s Daily Show reports on the foibles and of the real world with a satirical edge. In addition to news stories, the Daily Show also has celebrities (and semi-celebrities) on for interviews with the host, Jon Stewart.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="654516103_5f6e7e789e1b7713a46d1493919c6489">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57507.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57507.jpg" border="0" alt="" onload="TSResizeImage(this, '654516103_5f6e7e789e1b7713a46d1493919c6489');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374476</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 06:44:51</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>WWII.Air.Crash.Detectives.S01E01.Sharp.Top.Mountain.B25.Crash.720p.HDTV.X264-W4F</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 9 / Leechers: 0 / Size: 1.02 GB / Snatched: 10 x times<br /><br />World War II Air Crash Detectives&apos; follows Garth Barnard&apos;s unshakeable resolve to investigate how thousands of young Airmen from the Second World War ended up dead whilst in air accidents or training.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="524383421_5f6e7e789e1b7713a46d1493919c6489">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57507.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57507.jpg" border="0" alt="" onload="TSResizeImage(this, '524383421_5f6e7e789e1b7713a46d1493919c6489');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374472</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 06:07:56</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Wild.West.Alaska.S03E05.Smooth.Criminal.720p.HDTV.X264-DHD</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 7 / Leechers: 0 / Size: 1.11 GB / Snatched: 7 x times<br /><br />The staff of Wild West Guns provides firearms to Alaska&apos;s hunters and assorted quirky characters. <br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="697549617_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '697549617_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374468</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 05:46:47</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Ellen.DeGeneres.Show.2015.02.05.Scott.Foley.720p.HDTV.X264-W4F</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 0 / Size: 1.04 GB / Snatched: 7 x times<br /><br />The Ellen Degeneres Show features celebrity interviews and musical guests with segments that spotlight real people and fans of the show. Each day after her monologue, Ellen dances her way to center stage in an unbridled show of enthusiasm, with the help of the show&apos;s resident DJ, Tony Okungbowa. In addition, Ellen features audience participation, from bringing studio guests into the &quot;luxury box&quot; to inviting the audience to dance along with her.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="644251749_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '644251749_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374464</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 05:21:09</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Shark.Tank.S06E17.720p.HDTV.X264-BATV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 17 / Leechers: 0 / Size: 1.11 GB / Snatched: 19 x times<br /><br />Shark Tank follows aspiring entrepreneurs as they present various business ideas to moguls (known as the sharks ) in hopes of landing an investment in their ideas. Each week, ambitious entrepreneurs present their breakthrough business concepts to ruthless investors to convince them to invest in the concept.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1249649498_43cb692c0e92ffe1e77d50b199a48958">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '1249649498_43cb692c0e92ffe1e77d50b199a48958');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374462</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 05:12:39</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Impractical.Jokers.S04E02.Below.The.Belt.720p.HDTV.X264-DHD</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 17 / Leechers: 0 / Size: 523.83 MB / Snatched: 23 x times<br /><br />Impractical Jokers is an American hidden camera-practical joke reality television series that premiered. It follows the four members of the comedy troupe The Tenderloins as they coerce one another into doing public pranks while being filmed by hidden cameras. The show differs from other prank television programs in that the stars of Impractical Jokers do not know the details of the prank until the moment they are performing it on strangers. While one cast-member performs the prank, the other three comedians in the troupe are behind the scenes feeding lines to their friend via microphone (with an earpiece). The lines fed to the prankster are meant to create a humorous and awkward exchange between the prankster and the stranger being pranked.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1178425252_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '1178425252_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374461</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 05:08:03</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Portlandia.S05E05.720p.HDTV.X264-2HD</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 45 / Leechers: 0 / Size: 549.50 MB / Snatched: 59 x times<br /><br />Portlandia features Fred Armisen, Carrie Brownstein and guest stars satirizing such alternative-culture types as the owners of a feminist book store, a bike messenger, a punk-rock couple, and an arty duo obsessed with putting little cut-outs of birds on anything they lay their hands on. Each half-hour episode will consist of interwoven short films, with some characters recurring from week-to-week.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1868035685_874ec97fe0c0b02fa8d0727397a907ae">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/381.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/381.jpg" border="0" alt="" onload="TSResizeImage(this, '1868035685_874ec97fe0c0b02fa8d0727397a907ae');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374458</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 04:46:48</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Expedition.Unknown.S01E05.City.Of.Gold.720p.HDTV.X264-DHD</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 1 / Size: 1.62 GB / Snatched: 6 x times<br /><br />Expedition Unknown&apos; follows Josh Gates on a worldwide trip around the globe. In each episode he heads off on a journey and attempts to solve some of the world&apos;s most puzzling problems.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="172049851_43cb692c0e92ffe1e77d50b199a48958">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '172049851_43cb692c0e92ffe1e77d50b199a48958');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374451</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 04:22:37</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Allegiance.S01E01.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 73 / Leechers: 8 / Size: 896.21 MB / Snatched: 95 x times<br /><br />Alex O'Connor, a young idealistic CIA analyst specializing in Russian affairs, learns a shocking secret and his close-knit, affluent family is about to be split apart when it's revealed that his parents, Mark and Katya, are covert Russian spies deactivated decades ago. But today the Kremlin has re-enlisted them into service as they plan a terrorist operation inside the U.S. border that will bring America to its knees.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="490676434_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '490676434_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374448</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 04:04:28</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>How.To.Get.Away.With.Murder.S01E11.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 57 / Leechers: 7 / Size: 1.00 GB / Snatched: 80 x times<br /><br />A sexy, suspense-driven legal thriller about a group of ambitious law students and their brilliant, mysterious criminal defense professor (Viola Davis) who become entangled in a murder plot that will rock their entire university and change the course of their lives.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1104868105_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '1104868105_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374447</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 04:03:50</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Elementary.S03E13.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 118 / Leechers: 11 / Size: 900.23 MB / Snatched: 165 x times<br /><br />Elementary stars Jonny Lee Miller as detective Sherlock Holmes and Lucy Liu as Dr. Joan Watson in a modern-day drama about a crime-solving duo that cracks the NYPD&apos;s most impossible cases. Following his fall from grace in London and a stint in rehab, eccentric Sherlock escapes to Manhattan where his wealthy father forces him to live with his worst nightmare - a sober companion, Dr. Watson. A successful surgeon until she lost a patient and her license three years ago, Watson views her current job as another opportunity to help people, as well as paying a penance.<br />
|
||||
<br />
|
||||
However, the restless Sherlock is nothing like her previous clients. He informs her that none of her expertise as an addiction specialist applies to him and he&apos;s devised his own post-rehab regimen - resuming his work as a police consultant in New York City. Watson has no choice but to accompany her irascible new charge on his jobs.<br />
|
||||
<br />
|
||||
But Sherlock finds her medical background helpful, and Watson realizes she has a knack for playing investigator. Sherlock&apos;s police contact, Capt. Tobias &quot;Toby&quot; Gregson (Aidan Quinn), knows from previous experience working with Scotland Yard that Sherlock is brilliant at closing cases, and welcomes him as part of the team. With the mischievous Sherlock Holmes now running free in New York solving crimes, it&apos;s simple deduction that he&apos;s going to need someone to keep him grounded, and it&apos;s elementary that it&apos;s a job for Watson.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="383874736_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '383874736_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374443</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 03:59:38</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Big.Bang.Theory.S08E14.1080p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 26 / Leechers: 0 / Size: 1.40 GB / Snatched: 38 x times<br /><br />The Big Bang Theory is a comedy series about four young scientists who know all about the world of physics, and one girl, who gives the physics world a real spin.<br />
|
||||
<br />
|
||||
Leonard Hofstadter is a smart guy who tries his best to complete his research and become famous for his work while also attempting to be the most socially-interacting guy in their friend group.<br />
|
||||
<br />
|
||||
Sheldon Cooper is one of the worlds smartest men with an intellectual capacity through the roof and a language with scientific words normal people only have one comment to (What?). Though its never been said by himself, all signs throughout the show point to him having the Asperger Syndrome, making him the smartest, but also least social, group member.<br />
|
||||
<br />
|
||||
Howard Wolowitz is an engineer with his mind partially on science, but mostly on women. He always tries his best to impress a girl and get his share of sexual intercourses, but he always manages to screw up somehow, probably with his bad knowledge of treating women in a bad matter.<br />
|
||||
<br />
|
||||
Rajesh Koothrappali is an Indian scientist performing experiments on black holes, outer space, life on other planets and not to mention string theory. Raj is mostly known for his Selective Mutism, in other words, his fear of speaking to women, making social interaction difficult for him.<br />
|
||||
<br />
|
||||
Finally, theres Penny. Penny is the gorgeous girl next-door to Leonard and Sheldons apartment, and though she does not have any knowledge in physics or science, she makes success by being a funny character frequently having hilarious comments and on- and off-going relationships.<br />
|
||||
<br />
|
||||
All together, this unit of comedians make the shows half-hour episodes pure enjoyment and whether you like physics, women or neither, this show is surely going to get you laughing!<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1776335379_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '1776335379_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374437</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 03:44:49</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Archer.2009.S06E05.720p.HDTV.X264-KILLERS</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 109 / Leechers: 1 / Size: 459.63 MB / Snatched: 152 x times<br /><br />Archer aka &quot;The Duchess&quot; works for the International Secret Intelligence Service (ISIS), a spy agency where espionage and global crises are merely opportunities for its highly trained employees to confuse, undermine, betray and royally screw each other.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="2016815095_43cb692c0e92ffe1e77d50b199a48958">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '2016815095_43cb692c0e92ffe1e77d50b199a48958');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374436</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 03:40:02</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Inside.Man.S03E03.Morgan.See.Morgan.Do.720p.HDTV.X264-DHD</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 1 / Size: 0.99 GB / Snatched: 6 x times<br /><br />Oscar-nominated documentary filmmaker Morgan Spurlock is the inside man on this hourlong weekend series, which CNN says provides ``an intimate look into diverse sectors of American life and offers a deep-dive into pressing issues facing the U.S.&apos;&apos; Episodes include stories about migrant farm workers, the elder care industry, union workers, gun owners, education, bankruptcy, medical marijuana and drought conditions.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1339825556_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '1339825556_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374432</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 03:25:50</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Backstrom.S01E03.720p.HDTV.X264-KILLERS</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 68 / Leechers: 6 / Size: 1.38 GB / Snatched: 82 x times<br /><br />Backstrom centers on Everett Backstrom (Wilson), an overweight, offensive, irascible detective, as he tries, and fails, to change his self-destructive behavior. Mamie Gummer will play the female lead Nicole Graveley, a watchful, competent police detective who is a lesbian saddened over her breakup with her longtime partner.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1485930295_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '1485930295_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374429</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 03:19:18</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Scandal.US.S04E11.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 58 / Leechers: 4 / Size: 856.63 MB / Snatched: 75 x times<br /><br />When you get into trouble there&apos;s only one person to call, Olivia Pope. Olivia is a professional &apos;fixer&apos; who makes problems go away before anyone even knows they exist. For the moneyed, the powerful and even the President, Olivia is a legend in her field. Her spectacular success is mostly due to her unbreakable rule of always trust your gut. No matter how careful you are, when you do damage control for a living, you&apos;re bound to cause some damage to your own life. She and her crew eat, sleep, live and breathe crisis. Each week, as the team races against the clock to defuse intriguing new problems before they become full-blown disasters, they also have to deal with their own personal issues. They may call themselves &apos;gladiators in suits&apos;, but little by little, Olivia and her crew begin to reveal the chinks in their armor.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1817445719_43cb692c0e92ffe1e77d50b199a48958">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '1817445719_43cb692c0e92ffe1e77d50b199a48958');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374428</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 03:13:33</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Blacklist.S02E10.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 157 / Leechers: 7 / Size: 699.11 MB / Snatched: 213 x times<br /><br />&apos;The Blacklist&apos; follows Raymond &quot;Red&quot; Reddington (James Spader), one of the FBI&apos;s most wanted fugitives, as he joins with the FBI, claiming that they can work with one another. When he agrees to cooperate in bringing down dangerous criminals and terrorists, he tells them that he will only speak with Elizabeth Keen (Megan Boone), a rookie FBI profiler.<br />
|
||||
<br />
|
||||
As they work together, Keen questions Reddington&apos;s motives and Reddington simply feels she is very special. When one terrorist is taken down, Reddington informs them that it is only the beginning. Reddington gives the FBI access to &quot;The Blacklist&quot;, a list with known terrorists and criminals the world doesn&apos;t know about. With Reddington&apos;s help, they work together to eradicate the list.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="74051766_620778c1a5d72709be3fc47a2262cdb9">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/41872.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/41872.jpg" border="0" alt="" onload="TSResizeImage(this, '74051766_620778c1a5d72709be3fc47a2262cdb9');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374424</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 03:02:59</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Big.Bang.Theory.S08E14.1080i.HDTV.DD5.1.MPEG2-TOPKEK</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 15 / Leechers: 0 / Size: 2.21 GB / Snatched: 20 x times<br /><br />The Big Bang Theory is a comedy series about four young scientists who know all about the world of physics, and one girl, who gives the physics world a real spin.<br />
|
||||
<br />
|
||||
Leonard Hofstadter is a smart guy who tries his best to complete his research and become famous for his work while also attempting to be the most socially-interacting guy in their friend group.<br />
|
||||
<br />
|
||||
Sheldon Cooper is one of the worlds smartest men with an intellectual capacity through the roof and a language with scientific words normal people only have one comment to (What?). Though its never been said by himself, all signs throughout the show point to him having the Asperger Syndrome, making him the smartest, but also least social, group member.<br />
|
||||
<br />
|
||||
Howard Wolowitz is an engineer with his mind partially on science, but mostly on women. He always tries his best to impress a girl and get his share of sexual intercourses, but he always manages to screw up somehow, probably with his bad knowledge of treating women in a bad matter.<br />
|
||||
<br />
|
||||
Rajesh Koothrappali is an Indian scientist performing experiments on black holes, outer space, life on other planets and not to mention string theory. Raj is mostly known for his Selective Mutism, in other words, his fear of speaking to women, making social interaction difficult for him.<br />
|
||||
<br />
|
||||
Finally, theres Penny. Penny is the gorgeous girl next-door to Leonard and Sheldons apartment, and though she does not have any knowledge in physics or science, she makes success by being a funny character frequently having hilarious comments and on- and off-going relationships.<br />
|
||||
<br />
|
||||
All together, this unit of comedians make the shows half-hour episodes pure enjoyment and whether you like physics, women or neither, this show is surely going to get you laughing!<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1099410497_49fffcedd2eef0506d6b92e66fc4f3d4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57412.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57412.jpg" border="0" alt="" onload="TSResizeImage(this, '1099410497_49fffcedd2eef0506d6b92e66fc4f3d4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374418</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 02:45:45</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Two.And.A.Half.Men.S12E13.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 66 / Leechers: 6 / Size: 516.28 MB / Snatched: 91 x times<br /><br />Two and a Half Men is a comedy about men, women, sex, dating, divorce, mothers, single parenthood, sibling relations, surrogate families, money and, most importantly, love. More specifically, it&apos;s about a single father Alan Harper living in a beachfront house with his underachieving son, Jake, and divorced Internet billionaire Walden Schmidt.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="2049658409_a0a1e3decf031001556c1348071d1cb6">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/57412.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/57412.jpg" border="0" alt="" onload="TSResizeImage(this, '2049658409_a0a1e3decf031001556c1348071d1cb6');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374416</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 02:33:28</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Sunnyside.S01E05.720p.HDTV.X264-KILLERS</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 7 / Leechers: 0 / Size: 751.86 MB / Snatched: 7 x times<br /><br />Sunnyside is a sketch comedy show set in the fictional neighbourhood of Sunnyside, a community in transition, featuring people from all walks of life.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1981468187_49fffcedd2eef0506d6b92e66fc4f3d4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57412.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57412.jpg" border="0" alt="" onload="TSResizeImage(this, '1981468187_49fffcedd2eef0506d6b92e66fc4f3d4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374407</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 02:05:58</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Mom.S02E13.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 30 / Leechers: 3 / Size: 384.45 MB / Snatched: 51 x times<br /><br />Mom is a comedy from executive producer Chuck Lorre starring Anna Faris as a newly sober single mom raising two children in a world full of temptations and pitfalls, and multiple Emmy Award winner Allison Janney as her critical, estranged mother. Christy is a waitress at a posh Napa Valley establishment who is four months clean and doing her best to be a good mom and overcome a history of questionable choices. Her sobriety is tested when Bonnie, her recovering alcoholic mom, reappears chock-full of passive-aggressive insights into Christy&apos;s many mistakes. Bonnie joins Christy&apos;s already complicated circle of relationships: her handsome, married boss - and lover - Gabriel; the restaurant&apos;s hot-tempered chef, Rudy; her pretty, 16-going-on-25-year-old daughter, Violet; her sweet but overly honest son, Roscoe; her irresponsible ex-husband and Roscoe&apos;s father, Baxter; and Violet&apos;s clueless boyfriend, Luke. Christy tries to remain positive as she pursues her new path in life, but she faces an uphill battle, surrounded by a dubious support system - and a copious amount of dysfunction.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1419914574_a0a1e3decf031001556c1348071d1cb6">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/57412.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/57412.jpg" border="0" alt="" onload="TSResizeImage(this, '1419914574_a0a1e3decf031001556c1348071d1cb6');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374405</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 02:02:35</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Vampire.Diaries.S06E13.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 69 / Leechers: 3 / Size: 847.92 MB / Snatched: 90 x times<br /><br />Based on novels of the same name, Vampire Diaries follows Elena, a young heroine, who is the object of passion for two vampire brothers. Four months after the tragic car accident that killed their parents, 17-year-old Elena Gilbert (Nina Dobrev, DeGrassi: The Next Generation) and her 15-year-old brother, Jeremy (Steven R. McQueen, Everwood) are still trying to cope with their grief and move on with their lives. Elena has always been the star student; beautiful, popular and involved with school and friends, but now she finds herself struggling to hide her sadness from the world. As the school year begins, Elena and her friends are fascinated by a handsome and mysterious new student, Stefan Salvatore (Paul Wesley, Army Wives). Stefan and Elena are immediately drawn to one another, and Elena has no way of knowing that Stefan is a centuries-old vampire, struggling to live peacefully among humans, while his brother Damon (Ian Somerhalder, Lost) is the embodiment of vampire violence and brutality. Now these two vampire brothers - one good, one evil - are at war for Elena&apos;s soul and for the souls of her friends, family and all the residents of the small town of Mystic Falls, Virginia.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1148331454_a0a1e3decf031001556c1348071d1cb6">&nbsp;</span> <a href="https://immortalseed.me/pic/modpics/57412.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/pic/modpics/57412.jpg" border="0" alt="" onload="TSResizeImage(this, '1148331454_a0a1e3decf031001556c1348071d1cb6');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374404</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 02:01:19</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Top.Chef.S12E14.720p.WEBRip.H264-TARS</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 22 / Leechers: 2 / Size: 1.31 GB / Snatched: 37 x times<br /><br />Top Chef is a reality show unlike any other while it searches for the world&apos;s next top chef. Each week this talented group of chefs, professionally trained and self-taught, will be challenged and judged by some of the best known chefs in the industry. Over the course of the season and endless challenges one chef a week is asked to &quot;pack thier knives and go&quot; until there is only one left standing as the ultimate Top Chef. Bravo has once again capitalized on it&apos;s knack for finding and fostering top creative talent, while still delivering on the personalities and conflict that make for deliciously fun entertainment.<br />
|
||||
<br />
|
||||
Each episode of &quot;Top Chef&quot; holds two challenges for the chefs. The first is a &quot;quickfire&quot; test of their ability to think out of the box and create something new interesting and tasty, all while under the pressure of very little time. The second is a more involved elimination challenge designed to test the versatility and invention of the chefs as they take on unique culinary trials such as working with unusual and exotic foods or catering for a range of demanding clients. The food will be tasted and evaluated by the host and judges, but will also be served to the customers for whom the challenge is aimed, whether it be patrons at a five star restaurant or a room full of hungry kids. Food has to appeal to the diner as well as the critics if the chef is to survive.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="687893489_49fffcedd2eef0506d6b92e66fc4f3d4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/57412.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/57412.jpg" border="0" alt="" onload="TSResizeImage(this, '687893489_49fffcedd2eef0506d6b92e66fc4f3d4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374402</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 02:00:25</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>High.School.USA.S01E06.720p.HDTV.X264-W4F</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 0 / Size: 118.83 MB / Snatched: 6 x times<br /><br />Join the super-positive, millennial students of HIGH SCHOOL USA!, as they confront all the unique challenges of growing up in a modern world. Led by the painfully nave and always upbeat MARSH MERRIWETHER, there is nothing these kids cant put a positive spin on, from cyber-bullying to Adderall-addiction to embarrassing sexting incidents. <br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1339811646_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1339811646_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374394</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 01:31:45</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Big.Bang.Theory.S08E14.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 205 / Leechers: 8 / Size: 480.77 MB / Snatched: 286 x times<br /><br />The Big Bang Theory is a comedy series about four young scientists who know all about the world of physics, and one girl, who gives the physics world a real spin.<br />
|
||||
<br />
|
||||
Leonard Hofstadter is a smart guy who tries his best to complete his research and become famous for his work while also attempting to be the most socially-interacting guy in their friend group.<br />
|
||||
<br />
|
||||
Sheldon Cooper is one of the worlds smartest men with an intellectual capacity through the roof and a language with scientific words normal people only have one comment to (What?). Though its never been said by himself, all signs throughout the show point to him having the Asperger Syndrome, making him the smartest, but also least social, group member.<br />
|
||||
<br />
|
||||
Howard Wolowitz is an engineer with his mind partially on science, but mostly on women. He always tries his best to impress a girl and get his share of sexual intercourses, but he always manages to screw up somehow, probably with his bad knowledge of treating women in a bad matter.<br />
|
||||
<br />
|
||||
Rajesh Koothrappali is an Indian scientist performing experiments on black holes, outer space, life on other planets and not to mention string theory. Raj is mostly known for his Selective Mutism, in other words, his fear of speaking to women, making social interaction difficult for him.<br />
|
||||
<br />
|
||||
Finally, theres Penny. Penny is the gorgeous girl next-door to Leonard and Sheldons apartment, and though she does not have any knowledge in physics or science, she makes success by being a funny character frequently having hilarious comments and on- and off-going relationships.<br />
|
||||
<br />
|
||||
All together, this unit of comedians make the shows half-hour episodes pure enjoyment and whether you like physics, women or neither, this show is surely going to get you laughing!<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1183173375_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1183173375_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374391</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 01:30:51</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Bangkok.Airport.S01E03.720p.HDTV.X264-C4TV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 7 / Leechers: 2 / Size: 1.19 GB / Snatched: 7 x times<br /><br />Following British tourists checking in and out of the south-east Asian airport. The show follows employees and passengers at the airport as they come across issues that they face daily and other more bizarre cases.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1561915789_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1561915789_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374389</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 01:27:32</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Lucas.Bros.Moving.Company.S02E04.720p.HDTV.X264-W4F</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 5 / Leechers: 0 / Size: 120.48 MB / Snatched: 6 x times<br /><br />The stand-up comedy of New York-based identical twins Kenny and Keith Lucas (The Lucas Brothers) gets animated. After their uncle dies and leaves them his old van, the twins start a moving company called Vaation Boy$. Their customers are often apprehensive to hire such a scrawny duo, but the brothers like to remind them that that&apos;s why God made two of them. A day that begins simply by moving a bed down the street may lead to the threat of city-wide catastrophe, resolved only with the help of a once-famous &apos;90s wrestler.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="704076537_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '704076537_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374388</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 01:24:14</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Eat.Well.For.Less.S01E02.720p.HDTV.X264-C4TV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 7 / Leechers: 1 / Size: 1.13 GB / Snatched: 6 x times<br /><br />Gregg Wallace, award-winning greengrocer Chris Bavin and dietitian Lucy Jones help families across the UK save money, sort food facts from food fiction and eat well for less. <br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1204824465_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1204824465_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374385</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 01:17:10</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Regular.Show.S06E16.I.See.Turtles.720p.HDTV.X264-W4F</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 4 / Leechers: 0 / Size: 271.45 MB / Snatched: 6 x times<br /><br />The daily surreal adventures of a blue jay and raccoon duo that attempt to deal with their mundane jobs as groundskeepers at the local park. <br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="913288059_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '913288059_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374384</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 01:13:29</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Kyle.Files.S01E05.720p.HDTV.X264-C4TV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 4 / Leechers: 0 / Size: 446.16 MB / Snatched: 3 x times<br /><br />The show sees Jeremy Kyle investigating high-profile issues that impact on peoples lives across the country, from legal highs to knife crime, and from underage drinking to plastic surgery.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1484525890_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1484525890_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374382</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 01:11:56</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Greys.Anatomy.S11E10.720p.HDTV.X264-DIMENSION</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 80 / Leechers: 1 / Size: 779.32 MB / Snatched: 113 x times<br /><br />The series follows the lives of interns, residents and their mentors in the fictional Seattle Grace Mercy West Hospital in Seattle, as they struggle to complete their medical training and maintain personal lives.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="661358230_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '661358230_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374377</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 01:01:00</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>American.Idol.S14E09.720p.HDTV.X264-FBS</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 13 / Leechers: 2 / Size: 1.20 GB / Snatched: 26 x times<br /><br />The American Idol TV show is a 60 minute singing talent competition reality series on the FOX Network where singers compete to become the newest &quot;American Idol&quot;. After each contestant performs, the judges give their opinions which are sometimes very complimentary and sometimes extremely critical. After each episode ends, the viewing audience votes on whose performance they most liked. The one with the fewest votes is eliminated and the performances and voting continues weekly until the ultimate winner is chosen. That individual wins a million dollars and a recording contract. The losers also often do quite well in their careers due to the exposure they got on the show.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1474887622_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1474887622_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374367</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 00:09:45</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Car.Crash.Britain.S01E01.720p.HDTV.X264-FTP</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 9 / Leechers: 0 / Size: 1.13 GB / Snatched: 12 x times<br /><br />In this programme well see the most shocking road accidents, the worst crashes and the great escapes astonishing moments, all filmed by the people actually involved in them. <br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="741132585_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '741132585_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374359</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-05 23:36:52</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Exes.S04E11.720p.WEBRip.X264-SRS</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 9 / Leechers: 0 / Size: 512.82 MB / Snatched: 12 x times<br /><br />&quot;The Exes&quot; revolves around three divorced men, ladies man Phil (Donald Faison), homebody Haskell (Wayne Knight) and newly-single and needy Stuart (David Alan Basche). The men live together in an apartment across the hall from their divorce attorney, Holly (Kristen Johnston), who also happens to be their landlord. Holly avoids her own relationship and commitment issues by becoming immersed in the men&apos;s affairs as they put their lives back together and return to the dating scene.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1039906801_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1039906801_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374349</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-05 23:09:53</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Late.Late.Show.2015.02.04.Andy.Cohen.720p.HDTV.X264-W4F</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 5 / Leechers: 0 / Size: 901.39 MB / Snatched: 6 x times<br /><br />The Late Late Show with Craig Ferguson is a Peabody Award-winning American late-night talk show hosted by Scottish American comedian Craig Ferguson. Ferguson is the third regular host of the CBS Late Late Show franchise. The show follows Late Show with David Letterman in the CBS late-night lineup.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="985135033_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '985135033_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374346</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-05 22:59:21</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Mob.Wives.S05E08.720p.HDTV.X264-YesTV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 10 / Leechers: 0 / Size: 999.78 MB / Snatched: 10 x times<br /><br />&quot;Mob Wives&quot; is a docu-soap series that follows the lives of four women at a crossroads, having to pick up the pieces and carry on while their husbands or fathers do time for Mob-related activities. They are struggling with their identities, their own families and their futures.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="2087511031_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '2087511031_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374342</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-05 22:53:58</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Snooki.And.JWOWW.S04E12.The.Final.Aftershow.720p.HDTV.X264-YesTV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 1 / Size: 459.39 MB / Snatched: 6 x times<br /><br />Snooki & JWoww is an American reality television series on MTV starring Nicole &quot;Snooki&quot; Polizzi and Jennifer &quot;JWoww&quot; Farley, the first of two spinoffs of Jersey Shore, on which both Polizzi and Farley previously gained fame as cast members.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="55708515_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '55708515_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374340</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-05 22:52:22</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Snooki.And.JWOWW.S04E12.720p.HDTV.X264-YesTV</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 1 / Size: 1.49 GB / Snatched: 8 x times<br /><br />Snooki & JWoww is an American reality television series on MTV starring Nicole &quot;Snooki&quot; Polizzi and Jennifer &quot;JWoww&quot; Farley, the first of two spinoffs of Jersey Shore, on which both Polizzi and Farley previously gained fame as cast members.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1644410724_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1644410724_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374339</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-05 22:51:55</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>The.Nightly.Show.2015.02.04.720p.HDTV.X264-W4F</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 17 / Leechers: 0 / Size: 594.03 MB / Snatched: 22 x times<br /><br />The Nightly Show will provide viewers with Larry Wilmore&apos;s distinct point of view and comedic take on current events and pop culture. Hosted by Wilmore, the series will feature a diverse panel of voices, providing a perspective largely missing in the late-night television landscape.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1157923301_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1157923301_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374335</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-05 22:44:57</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<title>Crims.S01E05.720p.HDTV.X264-TLA</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 9 / Leechers: 0 / Size: 562.08 MB / Snatched: 9 x times<br /><br />Crims follows straight-laced Luke and Jason. Luke inadvertently finds himself sentenced to two years in Young Offender Institution Sunnybank View after becoming a bank robber&apos;s getaway driver, along with the bank robber in question, his girlfriend&apos;s brother and so-called friend - Jason. To make matters worse he has to share a cell with Jason. Luke will have to rely on Jason&apos;s street smarts to get him through. Unfortunately, Jason is a massive idiot. On hand to keep a watchful eye on the boys as prison officer Dawn, alongside her unsettling colleague Creg.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="1245743322_229d6c19d62f235698f60e876f0f5ab4">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/55069.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/55069.jpg" border="0" alt="" onload="TSResizeImage(this, '1245743322_229d6c19d62f235698f60e876f0f5ab4');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374333</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-05 22:38:43</pubDate>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:showrss="http://showrss.info/">
|
||||
<channel>
|
||||
<title>showRSS global feed</title>
|
||||
<link>http://showrss.info/</link>
|
||||
<ttl>30</ttl>
|
||||
<description>showRSS global feed</description>
|
||||
<item>
|
||||
<title>The Voice 8x25</title>
|
||||
<link>magnet:?xt=urn:btih:96CD620BEDA3EFD7C4D7746EF94549D03A2EB13B&dn=The+Voice+S08E25+WEBRip+x264+WNN&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</link>
|
||||
<guid isPermaLink="false">9bf12f5ecc9d61aec05b28e605784ee7</guid>
|
||||
<pubDate>Fri, 15 May 2015 08:30:01 +0000</pubDate>
|
||||
<description>New standard torrent: The Voice 8x25. Link: <a href="magnet:?xt=urn:btih:96CD620BEDA3EFD7C4D7746EF94549D03A2EB13B&dn=The+Voice+S08E25+WEBRip+x264+WNN&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337">magnet:?xt=urn:btih:96CD620BEDA3EFD7C4D7746EF94549D03A2EB13B&dn=The+Voice+S08E25+WEBRip+x264+WNN&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</a></description>
|
||||
<showrss:showid>1073</showrss:showid>
|
||||
<showrss:showname>The Voice</showrss:showname>
|
||||
<showrss:episode>51937</showrss:episode>
|
||||
<showrss:info_hash>96CD620BEDA3EFD7C4D7746EF94549D03A2EB13B</showrss:info_hash>
|
||||
<showrss:rawtitle>The Voice S08E25 WEBRip x264 WNN</showrss:rawtitle>
|
||||
<enclosure url="magnet:?xt=urn:btih:96CD620BEDA3EFD7C4D7746EF94549D03A2EB13B&dn=The+Voice+S08E25+WEBRip+x264+WNN&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337" length="0" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>The Voice 8x26</title>
|
||||
<link>magnet:?xt=urn:btih:9171902E28B8307F336AFFA8B7460A24B6D262F4&dn=The+Voice+S08E26+WEBRip+x264+WNN&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</link>
|
||||
<guid isPermaLink="false">d06427695cee7b602083a1ba71c09e4c</guid>
|
||||
<pubDate>Fri, 15 May 2015 08:30:01 +0000</pubDate>
|
||||
<description>New standard torrent: The Voice 8x26. Link: <a href="magnet:?xt=urn:btih:9171902E28B8307F336AFFA8B7460A24B6D262F4&dn=The+Voice+S08E26+WEBRip+x264+WNN&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337">magnet:?xt=urn:btih:9171902E28B8307F336AFFA8B7460A24B6D262F4&dn=The+Voice+S08E26+WEBRip+x264+WNN&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</a></description>
|
||||
<showrss:showid>1073</showrss:showid>
|
||||
<showrss:showname>The Voice</showrss:showname>
|
||||
<showrss:episode>51936</showrss:episode>
|
||||
<showrss:info_hash>9171902E28B8307F336AFFA8B7460A24B6D262F4</showrss:info_hash>
|
||||
<showrss:rawtitle>The Voice S08E26 WEBRip x264 WNN</showrss:rawtitle>
|
||||
<enclosure url="magnet:?xt=urn:btih:9171902E28B8307F336AFFA8B7460A24B6D262F4&dn=The+Voice+S08E26+WEBRip+x264+WNN&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337" length="0" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>How It's Made 25x07 720p</title>
|
||||
<link>magnet:?xt=urn:btih:CC48D14C6B0DB35A2286BCFD2029311343721208&dn=How+Its+Made+S25E07+720p+HDTV+x264+DHD&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</link>
|
||||
<guid isPermaLink="false">400a3c4d98f657b0c223d3709eb456c8</guid>
|
||||
<pubDate>Fri, 15 May 2015 07:20:01 +0000</pubDate>
|
||||
<description>New HD 720p torrent: How It's Made 25x07 720p. Link: <a href="magnet:?xt=urn:btih:CC48D14C6B0DB35A2286BCFD2029311343721208&dn=How+Its+Made+S25E07+720p+HDTV+x264+DHD&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337">magnet:?xt=urn:btih:CC48D14C6B0DB35A2286BCFD2029311343721208&dn=How+Its+Made+S25E07+720p+HDTV+x264+DHD&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</a></description>
|
||||
<showrss:showid>883</showrss:showid>
|
||||
<showrss:showname>How It's Made</showrss:showname>
|
||||
<showrss:episode>51935</showrss:episode>
|
||||
<showrss:info_hash>CC48D14C6B0DB35A2286BCFD2029311343721208</showrss:info_hash>
|
||||
<showrss:rawtitle>How Its Made S25E07 720p HDTV x264 DHD</showrss:rawtitle>
|
||||
<enclosure url="magnet:?xt=urn:btih:CC48D14C6B0DB35A2286BCFD2029311343721208&dn=How+Its+Made+S25E07+720p+HDTV+x264+DHD&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337" length="0" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Major Lazer 1x05 720p</title>
|
||||
<link>magnet:?xt=urn:btih:501CFEA851601815A8EED051924DDF80A952D6FA&dn=Major+Lazer+S01E05+720p+HDTV+X264+DIMENSION&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</link>
|
||||
<guid isPermaLink="false">3872c93c3853ccc94443d224716a7a58</guid>
|
||||
<pubDate>Fri, 15 May 2015 06:00:01 +0000</pubDate>
|
||||
<description>New HD 720p torrent: Major Lazer 1x05 720p. Link: <a href="magnet:?xt=urn:btih:501CFEA851601815A8EED051924DDF80A952D6FA&dn=Major+Lazer+S01E05+720p+HDTV+X264+DIMENSION&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337">magnet:?xt=urn:btih:501CFEA851601815A8EED051924DDF80A952D6FA&dn=Major+Lazer+S01E05+720p+HDTV+X264+DIMENSION&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</a></description>
|
||||
<showrss:showid>1077</showrss:showid>
|
||||
<showrss:showname>Major Lazer</showrss:showname>
|
||||
<showrss:episode>51934</showrss:episode>
|
||||
<showrss:info_hash>501CFEA851601815A8EED051924DDF80A952D6FA</showrss:info_hash>
|
||||
<showrss:rawtitle>Major Lazer S01E05 720p HDTV X264 DIMENSION</showrss:rawtitle>
|
||||
<enclosure url="magnet:?xt=urn:btih:501CFEA851601815A8EED051924DDF80A952D6FA&dn=Major+Lazer+S01E05+720p+HDTV+X264+DIMENSION&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337" length="0" type="application/x-bittorrent" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Lip Sync Battle 1x08 720p</title>
|
||||
<link>magnet:?xt=urn:btih:83AD17789674A470FDF71F9D7E590FE4478E95FB&dn=Lip+Sync+Battle+S01E08+720p+HDTV+x264+FiHTV&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</link>
|
||||
<guid isPermaLink="false">34250ff7fd704989736d0772b8c9db18</guid>
|
||||
<pubDate>Fri, 15 May 2015 05:20:01 +0000</pubDate>
|
||||
<description>New HD 720p torrent: Lip Sync Battle 1x08 720p. Link: <a href="magnet:?xt=urn:btih:83AD17789674A470FDF71F9D7E590FE4478E95FB&dn=Lip+Sync+Battle+S01E08+720p+HDTV+x264+FiHTV&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337">magnet:?xt=urn:btih:83AD17789674A470FDF71F9D7E590FE4478E95FB&dn=Lip+Sync+Battle+S01E08+720p+HDTV+x264+FiHTV&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337</a></description>
|
||||
<showrss:showid>1061</showrss:showid>
|
||||
<showrss:showname>Lip Sync Battle</showrss:showname>
|
||||
<showrss:episode>51933</showrss:episode>
|
||||
<showrss:info_hash>83AD17789674A470FDF71F9D7E590FE4478E95FB</showrss:info_hash>
|
||||
<showrss:rawtitle>Lip Sync Battle S01E08 720p HDTV x264 FiHTV</showrss:rawtitle>
|
||||
<enclosure url="magnet:?xt=urn:btih:83AD17789674A470FDF71F9D7E590FE4478E95FB&dn=Lip+Sync+Battle+S01E08+720p+HDTV+x264+FiHTV&tr=udp://tracker.coppersurfer.tk:6969/announce&tr=udp://tracker.leechers-paradise.org:6969&tr=udp://open.demonii.com:1337" length="0" type="application/x-bittorrent" />
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>TtN</title>
|
||||
<description>Advanced RSS Feed</description>
|
||||
<link>https://transmithe.net</link>
|
||||
<lastBuildDate>Tue, 19 May 2015 16:35:24 -0400</lastBuildDate>
|
||||
<copyright>(c) 2015 TtN</copyright>
|
||||
<atom:link href="https://transmithe.net/advanced_rss.php?cats=all&tpc=5&auth=abc" rel="self" type="application/rss+xml" />
|
||||
|
||||
<item>
|
||||
<title><![CDATA[[SD-Episode] Tonight.S17E10.The.Air.We.Breathe.HDTV.x264-C4TV [SEEDERS (0)/LEECHERS (0)]]]></title>
|
||||
<description><![CDATA[<b>tonight.s17e10.the.air.we.breathe.hdtv.x264-c4tv.mp4</b><br />Size: 185918870 bytes (177.31 MiB), duration: 00:24:25, avg.bitrate: 1015 kb/s<br />Audio: aac, 48000 Hz, stereo (eng)<br />Video: h264, yuv420p, 720x404, 25.00 fps® (und)<br /><br /><b>Screens:</b><div align="left"><a href="http://peerlist.org/host/images/37207662496553736014.jpg" target="_blank"><div id="img1" style="font-size:'1'; display:inline;"><img name="img1" src='http://peerlist.org/host/images/37207662496553736014_thumb.jpg' border='0' alt='' /></div></a> <a href="http://peerlist.org/host/images/31909474116455351384.jpg" target="_blank"><div id="img2" style="font-size:'1'; display:inline;"><img name="img2" src='http://peerlist.org/host/images/31909474116455351384_thumb.jpg' border='0' alt='' /></div></a> <a href="http://peerlist.org/host/images/25779638126904333220.jpg" target="_blank"><div id="img3" style="font-size:'1'; display:inline;"><img name="img3" src='http://peerlist.org/host/images/25779638126904333220_thumb.jpg' border='0' alt='' /></div></a> <br /><a href="http://peerlist.org/host/images/61103593704239674920.jpg" target="_blank"><div id="img4" style="font-size:'1'; display:inline;"><img name="img4" src='http://peerlist.org/host/images/61103593704239674920_thumb.jpg' border='0' alt='' /></div></a> <a href="http://peerlist.org/host/images/70305137193128274342.jpg" target="_blank"><div id="img5" style="font-size:'1'; display:inline;"><img name="img5" src='http://peerlist.org/host/images/70305137193128274342_thumb.jpg' border='0' alt='' /></div></a> <a href="http://peerlist.org/host/images/23010180768907914115.jpg" target="_blank"><div id="img6" style="font-size:'1'; display:inline;"><img name="img6" src='http://peerlist.org/host/images/23010180768907914115_thumb.jpg' border='0' alt='' /></div></a> <br /></div><br />]]></description>
|
||||
<link>https://transmithe.net/index.php?page=torrent-details&id=abc</link>
|
||||
<guid>https://transmithe.net/index.php?page=torrent-details&id=abc</guid>
|
||||
<enclosure url="https://transmithe.net/download.php?id=abc&f=Tonight.S17E10.The.Air.We.Breathe.HDTV.x264-C4TV.torrent&auth=abc" length="14701" type="application/x-bittorrent" />
|
||||
<pubDate>Tue, 19 May 2015 16:11:53 -0400</pubDate>
|
||||
</item>
|
||||
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE torrent PUBLIC "-//bitTorrent//DTD torrent 0.1//EN" "http://xmlns.ezrss.it/0.1/dtd/">
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>ezRSS - Latest torrent releases</title>
|
||||
<ttl>15</ttl>
|
||||
<link>http://ezrss.it/feed/</link>
|
||||
<image>
|
||||
<title>ezRSS - Latest torrent releases</title>
|
||||
<url>http://ezrss.it/images/ezrssit.png</url>
|
||||
<link>http://ezrss.it/feed/</link>
|
||||
</image>
|
||||
<description>The latest 30 torrent releases.</description>
|
||||
<item>
|
||||
<title><![CDATA[Andy McNabs Tour Of Duty Series 1 - Courage Under Fire 1x6 [DVDRIP - MVGROUP]]]></title>
|
||||
<link>invalid.url</link>
|
||||
<category domain="http://eztv.it/shows/187/mv-group-documentaries/"><![CDATA[TV Show / MV Group Documentaries]]></category>
|
||||
<pubDate>Mon, 15 Sep 2014 13:04:21 -0500</pubDate>
|
||||
<description><![CDATA[Show Name: Andy McNabs Tour Of Duty Series 1; Episode Title: Courage Under Fire; Season: 1; Episode: 6]]></description>
|
||||
<enclosure url="invalid.url" length="698999946" type="application/x-bittorrent" />
|
||||
<comments>http://eztv.it/forum/discuss/58438/</comments>
|
||||
<guid>http://eztv.it/ep/58438/andy-mcnabs-tour-of-duty-series-1-6of6-courage-under-fire-dvdrip-x264-mvgroup/</guid>
|
||||
<torrent xmlns="http://xmlns.ezrss.it/0.1/">
|
||||
<fileName><![CDATA[Andy.McNabs.Tour.Of.Duty.Series.1.6of6.Courage.Under.Fire.DVDRip.x264-MVGroup.[MVGroup.org].torrent]]></fileName>
|
||||
<contentLength>698999946</contentLength>
|
||||
<infoHash>AAA2038BED9EBCA2C312D1C9C3E8E024D0EB414E</infoHash>
|
||||
<magnetURI><![CDATA[magnet:?xt=urn:btih:VKRAHC7NT26KFQYS2HE4H2HAETIOWQKO&dn=Andy.McNabs.Tour.Of.Duty.Series.1.6of6.Courage.Under.Fire.DVDRip.x264-MVGroup]]></magnetURI>
|
||||
</torrent>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE torrent PUBLIC "-//bitTorrent//DTD torrent 0.1//EN" "http://xmlns.ezrss.it/0.1/dtd/">
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>ezRSS - Latest torrent releases</title>
|
||||
<ttl>15</ttl>
|
||||
<link>http://ezrss.it/feed/</link>
|
||||
<image>
|
||||
<title>ezRSS - Latest torrent releases</title>
|
||||
<url>http://ezrss.it/images/ezrssit.png</url>
|
||||
<link>http://ezrss.it/feed/</link>
|
||||
</image>
|
||||
<description>The latest 30 torrent releases.</description>
|
||||
<item>
|
||||
<title><![CDATA[Andy McNabs Tour Of Duty Series 1 - Courage Under Fire 1x6 [DVDRIP - MVGROUP]]]></title>
|
||||
<link><![CDATA[magnet:?xt=urn:btih:VKRAHC7NT26KFQYS2HE4H2HAETIOWQKO&dn=Andy.McNabs.Tour.Of.Duty.Series.1.6of6.Courage.Under.Fire.DVDRip.x264-MVGroup]]></link>
|
||||
<category domain="http://eztv.it/shows/187/mv-group-documentaries/"><![CDATA[TV Show / MV Group Documentaries]]></category>
|
||||
<pubDate>Mon, 15 Sep 2014 13:04:21 -0500</pubDate>
|
||||
<description><![CDATA[Show Name: Andy McNabs Tour Of Duty Series 1; Episode Title: Courage Under Fire; Season: 1; Episode: 6]]></description>
|
||||
<enclosure url="magnet:?xt=urn:btih:VKRAHC7NT26KFQYS2HE4H2HAETIOWQKO&dn=Andy.McNabs.Tour.Of.Duty.Series.1.6of6.Courage.Under.Fire.DVDRip.x264-MVGroup" length="100000" type="application/x-bittorrent" />
|
||||
<comments>http://eztv.it/forum/discuss/58438/</comments>
|
||||
<guid>http://eztv.it/ep/58438/andy-mcnabs-tour-of-duty-series-1-6of6-courage-under-fire-dvdrip-x264-mvgroup/</guid>
|
||||
<torrent xmlns="http://xmlns.ezrss.it/0.1/">
|
||||
<fileName><![CDATA[Andy.McNabs.Tour.Of.Duty.Series.1.6of6.Courage.Under.Fire.DVDRip.x264-MVGroup.[MVGroup.org].torrent]]></fileName>
|
||||
<infoHash>AAA2038BED9EBCA2C312D1C9C3E8E024D0EB414E</infoHash>
|
||||
<magnetURI><![CDATA[magnet:?xt=urn:btih:VKRAHC7NT26KFQYS2HE4H2HAETIOWQKO&dn=Andy.McNabs.Tour.Of.Duty.Series.1.6of6.Courage.Under.Fire.DVDRip.x264-MVGroup]]></magnetURI>
|
||||
</torrent>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>immortalseed.me RSS Syndicator</title>
|
||||
<link>http://immortalseed.me</link>
|
||||
<description>Latest Torrents on immortalseed.me</description>
|
||||
<language>en-US</language>
|
||||
<image>
|
||||
<title>immortalseed.me RSS Syndicator</title>
|
||||
<url>http://immortalseed.me</url>
|
||||
<link>http://immortalseed.me</link>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
<description>immortalseed.me RSS Syndicator</description>
|
||||
</image>
|
||||
<copyright>Copyright &copy; 2015 immortalseed.me</copyright>
|
||||
<webMaster>contact@immortalseed.me</webMaster>
|
||||
<lastBuildDate>Fri, 06 Feb 2015 13:40:57 -12</lastBuildDate>
|
||||
<ttl>20</ttl>
|
||||
<generator>immortalseed.me RSS Syndicator</generator>
|
||||
<item>
|
||||
<title>Conan.2015.02.05.Jeff.Bridges.720p.HDTV.X264-CROOKS</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 2 / Size: 938.49 MB / Snatched: 5 x times<br /><br />Describing itself as a traditional late-night talk show, Conan draws its comedy from recent news stories, political figures and prominent celebrities, as well as aspects of the show itself. The show typically opens with a monologue from Conan OBrien relating to recent headlines and frequently features exchanges with his sidekick, Andy Richter, and members of the audience. The next segment is devoted to a celebrity interview, with guests ranging from actors and musicians to media personalities and political figures. The show then closes with either a musical or comedy performance.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/195.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/195.jpg" border="0" alt="" onload="TSResizeImage(this, '350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb');" /></a></span></div>
|
||||
</description>
|
||||
<link>invalid.url</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 13:32:26</pubDate>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>immortalseed.me RSS Syndicator</title>
|
||||
<link>http://immortalseed.me</link>
|
||||
<description>Latest Torrents on immortalseed.me</description>
|
||||
<language>en-US</language>
|
||||
<image>
|
||||
<title>immortalseed.me RSS Syndicator</title>
|
||||
<url>http://immortalseed.me</url>
|
||||
<link>http://immortalseed.me</link>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
<description>immortalseed.me RSS Syndicator</description>
|
||||
</image>
|
||||
<copyright>Copyright &copy; 2015 immortalseed.me</copyright>
|
||||
<webMaster>contact@immortalseed.me</webMaster>
|
||||
<lastBuildDate>Fri, 06 Feb 2015 13:40:57 -12</lastBuildDate>
|
||||
<ttl>20</ttl>
|
||||
<generator>immortalseed.me RSS Syndicator</generator>
|
||||
<item>
|
||||
<title>Conan.2015.02.05.Jeff.Bridges.720p.HDTV.X264-CROOKS</title>
|
||||
<description>
|
||||
Uploader: Anonymous / Category: TV - High Definition / Seeders: 6 / Leechers: 2 / Size: 0.49 MB / Snatched: 5 x times<br /><br />Describing itself as a traditional late-night talk show, Conan draws its comedy from recent news stories, political figures and prominent celebrities, as well as aspects of the show itself. The show typically opens with a monologue from Conan OBrien relating to recent headlines and frequently features exchanges with his sidekick, Andy Richter, and members of the audience. The next segment is devoted to a celebrity interview, with guests ranging from actors and musicians to media personalities and political figures. The show then closes with either a musical or comedy performance.<br />
|
||||
<br />
|
||||
<div style="text-align: center;"><span id="lazyload"><span id="350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb">&nbsp;</span> <a href="https://immortalseed.me/images/modpics/195.jpg" id="ts_show_preview" alt=""><img src="https://immortalseed.me/images/modpics/195.jpg" border="0" alt="" onload="TSResizeImage(this, '350237944_80b24e6a90a69f7bb9b39a6b3f99e4bb');" /></a></span></div>
|
||||
</description>
|
||||
<link>https://immortalseed.me/download.php?type=rss&secret_key=12345678910&id=374534</link>
|
||||
<author>Anonymous</author>
|
||||
<category>TV - High Definition</category>
|
||||
<pubDate>2015-02-06 13:32:26</pubDate>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<item>
|
||||
<title>Surviving Marriage S01E09 480p HDTV x264-mSD</title>
|
||||
<link>https://www.torrentday.com/download.php/123/Surviving.Marriage.S01E09.480p.HDTV.x264-mSD.torrent?torrent_pass=abc</link>
|
||||
<description>Category: TV/480p Size: 341 m Uploaded: 20:40 19-05-2015 </description>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
154
src/NzbDrone.Core.Test/Files/Indexers/TorrentRss/speed.cd.xml
Normal file
154
src/NzbDrone.Core.Test/Files/Indexers/TorrentRss/speed.cd.xml
Normal file
@@ -0,0 +1,154 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Speed.cd</title>
|
||||
<link>http://speed.cd/</link>
|
||||
<description>Speed.cd RSS Feed, Please Read The Rules Before Use!</description>
|
||||
<language>en-us</language>
|
||||
<category domain="Speed">TorrentFeed</category>
|
||||
<generator>Speed.cd Site</generator>
|
||||
<docs>http://www.rssboard.org/rss-specification</docs>
|
||||
<atom:link href="http://speed.cd/get_rss.php?feed=dl&user=userxx&cat=2&passkey=SECRETKEY" rel="self" type="application/rss+xml" />
|
||||
<pubDate>Mon, 16 Feb 2015 02:15:49 +0000</pubDate>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599299</guid>
|
||||
<title>Nightwatch S01E04 PROPER HDTV x264-W4F</title>
|
||||
<link>http://speed.cd/download.php?torrent=599299&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 386.41 MB Added: Mon, 16 Feb 2015 02:03:47 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 02:03:47 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599297</guid>
|
||||
<title>Brooklyn Nine-Nine S02E16 HDTV x264-ASAP</title>
|
||||
<link>http://speed.cd/download.php?torrent=599297&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 163.59 MB Added: Mon, 16 Feb 2015 01:59:51 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:59:51 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599296</guid>
|
||||
<title>The Simpsons S26E14 HDTV XviD-AFG</title>
|
||||
<link>http://speed.cd/download.php?torrent=599296&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 173.40 MB Added: Mon, 16 Feb 2015 01:58:17 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:58:17 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599295</guid>
|
||||
<title>Investigation Discovery Killer Truckers HDTV x264-W4F</title>
|
||||
<link>http://speed.cd/download.php?torrent=599295&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 348.39 MB Added: Mon, 16 Feb 2015 01:56:19 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:56:19 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599294</guid>
|
||||
<title>Liv and Maddie S02E11 HDTV x264-W4F</title>
|
||||
<link>http://speed.cd/download.php?torrent=599294&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 242.08 MB Added: Mon, 16 Feb 2015 01:51:37 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:51:37 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599293</guid>
|
||||
<title>Mulaney S01E13 HDTV XviD-AFG</title>
|
||||
<link>http://speed.cd/download.php?torrent=599293&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 177.41 MB Added: Mon, 16 Feb 2015 01:48:16 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:48:16 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599291</guid>
|
||||
<title>Law and Order SVU S16E14 REPACK 480p HDTV x264-mSD</title>
|
||||
<link>http://speed.cd/download.php?torrent=599291&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 206.15 MB Added: Mon, 16 Feb 2015 01:33:36 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:33:36 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599290</guid>
|
||||
<title>The Casual Vacancy 1x01 480p HDTV x264-mSD</title>
|
||||
<link>http://speed.cd/download.php?torrent=599290&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 223.26 MB Added: Mon, 16 Feb 2015 01:33:16 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:33:16 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599289</guid>
|
||||
<title>UFO Conspiracies S01E03 Fireball Attack HDTV x264-W4F</title>
|
||||
<link>http://speed.cd/download.php?torrent=599289&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 246.24 MB Added: Mon, 16 Feb 2015 01:31:12 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:31:12 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599287</guid>
|
||||
<title>The Simpsons S26E14 HDTV x264-LOL</title>
|
||||
<link>http://speed.cd/download.php?torrent=599287&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 117.85 MB Added: Mon, 16 Feb 2015 01:28:55 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:28:55 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599286</guid>
|
||||
<title>UFO Conspiracies S01E01 Presidential Threat HDTV x264-W4F</title>
|
||||
<link>http://speed.cd/download.php?torrent=599286&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 280.65 MB Added: Mon, 16 Feb 2015 01:28:31 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:28:31 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599285</guid>
|
||||
<title>Modern Times S01E03 24 Hour Parcel People HDTV x264-BARGE</title>
|
||||
<link>http://speed.cd/download.php?torrent=599285&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 432.25 MB Added: Mon, 16 Feb 2015 01:28:16 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:28:16 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599284</guid>
|
||||
<title>Impractical Jokers S04E03 Uncool and the Gang HDTV x264-W4F</title>
|
||||
<link>http://speed.cd/download.php?torrent=599284&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 167.32 MB Added: Mon, 16 Feb 2015 01:25:55 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:25:55 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599283</guid>
|
||||
<title>Austin and Ally S04E04 Seniors and Senors HDTV x264-W4F</title>
|
||||
<link>http://speed.cd/download.php?torrent=599283&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 282.91 MB Added: Mon, 16 Feb 2015 01:24:02 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:24:02 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599282</guid>
|
||||
<title>Jimmy Fallon 2015 02 13 Samuel L Jackson-Norman Reedus 480p HDTV x264-mSD</title>
|
||||
<link>http://speed.cd/download.php?torrent=599282&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 207.20 MB Added: Mon, 16 Feb 2015 01:23:15 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:23:15 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599279</guid>
|
||||
<title>Manhattan Love Story US S01E11 HDTV XviD-AFG</title>
|
||||
<link>http://speed.cd/download.php?torrent=599279&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 168.68 MB Added: Mon, 16 Feb 2015 01:18:35 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:18:35 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599278</guid>
|
||||
<title>Modern Times S01E02 Warwick Davis Big Night HDTV x264-BARGE</title>
|
||||
<link>http://speed.cd/download.php?torrent=599278&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 353.35 MB Added: Mon, 16 Feb 2015 01:10:18 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:10:18 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599276</guid>
|
||||
<title>The Auction House S02E01 HDTV XviD-AFG</title>
|
||||
<link>http://speed.cd/download.php?torrent=599276&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 394.73 MB Added: Mon, 16 Feb 2015 01:08:16 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 01:08:16 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599262</guid>
|
||||
<title>Lockdown S02E07 Surviving Stateville 480p HDTV x264-mSD</title>
|
||||
<link>http://speed.cd/download.php?torrent=599262&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 237.82 MB Added: Mon, 16 Feb 2015 00:48:35 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 00:48:35 +0000</pubDate>
|
||||
</item>
|
||||
<item>
|
||||
<guid isPermaLink='false'>100000599261</guid>
|
||||
<title>Modern Times S01E01 The Vikings Are Coming HDTV x264-BARGE</title>
|
||||
<link>http://speed.cd/download.php?torrent=599261&key=SECRETKEY</link>
|
||||
<description>Category: TV/Episodes Size: 359.24 MB Added: Mon, 16 Feb 2015 00:47:12 +0000</description>
|
||||
<pubDate>Mon, 16 Feb 2015 00:47:12 +0000</pubDate>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -6,7 +6,7 @@
|
||||
<description>The latest torrents from TorrentLeech.org</description>
|
||||
<language>en</language>
|
||||
<ttl>5</ttl>
|
||||
<atom:link href="http://rss.torrentleech.org/4fd6a70f990234472f40" rel="self" type="application/rss+xml" />
|
||||
<atom:link href="http://rss.torrentleech.org/1234" rel="self" type="application/rss+xml" />
|
||||
<item>
|
||||
<title><![CDATA[Classic Car Rescue S02E04 720p HDTV x264-C4TV]]></title>
|
||||
<pubDate>Mon, 12 May 2014 19:15:28 +0000</pubDate>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user