mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-18 21:35:51 -04:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ca66fb61a | |||
| 064844ac0c | |||
| 5540594ecf | |||
| 433ae019de | |||
| 10091b9454 | |||
| 475851775f | |||
| 0fff862fd2 | |||
| 23754c49dc | |||
| fbf790e9fd | |||
| 6d00bd0f7a | |||
| 5bf95e0d9e | |||
| 8bb4b02be7 | |||
| b26a036eed | |||
| ef57882291 | |||
| 32a2407ad1 | |||
| 33b48eec95 | |||
| 3790dc9109 | |||
| 343d849536 | |||
| c36b259fa9 | |||
| 6463913f22 | |||
| e39deb4bdc | |||
| 9ca2c21547 | |||
| f376360611 | |||
| 3e966d4d58 | |||
| e036267c33 | |||
| 7d4378ca7a | |||
| ee1ebfd893 | |||
| 403fd0f0c0 | |||
| fc5ac8219f | |||
| 600a433faa | |||
| 5609facd9d | |||
| 36ea6c6b99 | |||
| 56ac87c760 | |||
| 47753c47a5 | |||
| 712c0eb84a | |||
| 8765155223 | |||
| 63d7596e98 |
@@ -37,6 +37,11 @@ cache:
|
|||||||
pull_requests:
|
pull_requests:
|
||||||
do_not_increment_build_number: true
|
do_not_increment_build_number: true
|
||||||
|
|
||||||
|
on_failure:
|
||||||
|
- ps: Get-ChildItem .\_artifacts\*.zip | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||||
|
- ps: Get-ChildItem .\_artifacts\*.exe | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||||
|
- ps: Get-ChildItem .\_artifacts\*.tar.gz | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||||
|
|
||||||
only_commits:
|
only_commits:
|
||||||
files:
|
files:
|
||||||
- src/
|
- src/
|
||||||
|
|||||||
@@ -208,9 +208,9 @@ PackageTests()
|
|||||||
find $sourceFolder -path $testSearchPattern -exec cp -r -u -T "{}" $testPackageFolder \;
|
find $sourceFolder -path $testSearchPattern -exec cp -r -u -T "{}" $testPackageFolder \;
|
||||||
|
|
||||||
if [ $runtime = "dotnet" ] ; then
|
if [ $runtime = "dotnet" ] ; then
|
||||||
$nuget install NUnit.ConsoleRunner -Version 3.2.0 -Output $testPackageFolder
|
$nuget install NUnit.Runners -Version 3.2.1 -Output $testPackageFolder
|
||||||
else
|
else
|
||||||
mono $nuget install NUnit.ConsoleRunner -Version 3.2.0 -Output $testPackageFolder
|
mono $nuget install NUnit.Runners -Version 3.2.1 -Output $testPackageFolder
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cp $outputFolder/*.dll $testPackageFolder
|
cp $outputFolder/*.dll $testPackageFolder
|
||||||
|
|||||||
+34
-25
@@ -23,6 +23,9 @@ if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then
|
|||||||
DAY="`date +%d`"
|
DAY="`date +%d`"
|
||||||
else
|
else
|
||||||
VERSION=$1
|
VERSION=$1
|
||||||
|
BRANCH=$2
|
||||||
|
BRANCH=${BRANCH#refs\/heads\/}
|
||||||
|
BRANCH=${BRANCH//\//-}
|
||||||
fi
|
fi
|
||||||
outputFolder='./_output'
|
outputFolder='./_output'
|
||||||
outputFolderMono='./_output_mono'
|
outputFolderMono='./_output_mono'
|
||||||
@@ -34,35 +37,41 @@ rm $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr
|
|||||||
chmod +x $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr2
|
chmod +x $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr2
|
||||||
mv $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr2 $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr >& error.log
|
mv $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr2 $outputFolderOsxApp/Radarr.app/Contents/MacOS/Sonarr >& error.log
|
||||||
|
|
||||||
cp -r $outputFolder/ Radarr_Windows_$VERSION
|
|
||||||
cp -r $outputFolderMono/ Radarr_Mono_$VERSION
|
|
||||||
cp -r $outputFolderOsxApp/ Radarr_OSX_$VERSION
|
|
||||||
|
|
||||||
if [ $runtime = "dotnet" ] ; then
|
if [ $runtime = "dotnet" ] ; then
|
||||||
./7za.exe a Radarr_Windows_$VERSION.zip ./Radarr_Windows_$VERSION/*
|
./7za.exe a Radarr_Windows_$VERSION.zip ./Radarr_Windows_$VERSION/*
|
||||||
./7za.exe a -ttar -so Radarr_Mono_$VERSION.tar ./Radarr_Mono_$VERSION/* | ./7za.exe a -si Radarr_Mono_$VERSION.tar.gz
|
./7za.exe a -ttar -so Radarr_Mono_$VERSION.tar ./Radarr_Mono_$VERSION/* | ./7za.exe a -si Radarr_Mono_$VERSION.tar.gz
|
||||||
./7za.exe a -ttar -so Radarr_OSX_$VERSION.tar ./_output_osx/* | ./7za.exe a -si Radarr_OSX_$VERSION.tar.gz
|
./7za.exe a -ttar -so Radarr_OSX_$VERSION.tar ./_output_osx/* | ./7za.exe a -si Radarr_OSX_$VERSION.tar.gz
|
||||||
./7za.exe a -ttar -so Radarr_OSX_App_$VERSION.tar ./_output_osx_app/* | ./7za.exe a -si Radarr_OSX_App_$VERSION.tar.gz
|
./7za.exe a -ttar -so Radarr_OSX_App_$VERSION.tar ./_output_osx_app/* | ./7za.exe a -si Radarr_OSX_App_$VERSION.tar.gz
|
||||||
else
|
else
|
||||||
zip -r Radarr_Windows_$VERSION.zip Radarr_Windows_$VERSION/* >& /dev/null
|
cp -r $outputFolder/ Radarr
|
||||||
zip -r Radarr_Mono_$VERSION.zip Radarr_Mono_$VERSION/* >& /dev/null #TODO update for tar.gz
|
zip -r Radarr.$BRANCH.$VERSION.windows.zip Radarr
|
||||||
zip -r Radarr_OSX_$VERSION_App.zip Radarr_OSX_$VERSION/* >& /dev/null
|
rm -rf Radarr
|
||||||
|
cp -r $outputFolderMono/ Radarr
|
||||||
|
tar -zcvf Radarr.$BRANCH.$VERSION.linux.tar.gz Radarr
|
||||||
|
rm -rf Radarr
|
||||||
|
cp -r $outputFolderOsx/ Radarr
|
||||||
|
tar -zcvf Radarr.$BRANCH.$VERSION.osx.tar.gz Radarr
|
||||||
|
rm -rf Radarr
|
||||||
|
#TODO update for tar.gz
|
||||||
|
|
||||||
|
cd _output_osx_app/
|
||||||
|
zip -r ../Radarr.$BRANCH.$VERSION.osx-app.zip *
|
||||||
fi
|
fi
|
||||||
ftp -n ftp.leonardogalli.ch << END_SCRIPT
|
# ftp -n ftp.leonardogalli.ch << END_SCRIPT
|
||||||
passive
|
# passive
|
||||||
quote USER $FTP_USER
|
# quote USER $FTP_USER
|
||||||
quote PASS $FTP_PASS
|
# quote PASS $FTP_PASS
|
||||||
mkdir builds
|
# mkdir builds
|
||||||
cd builds
|
# cd builds
|
||||||
mkdir $YEAR
|
# mkdir $YEAR
|
||||||
cd $YEAR
|
# cd $YEAR
|
||||||
mkdir $MONTH
|
# mkdir $MONTH
|
||||||
cd $MONTH
|
# cd $MONTH
|
||||||
mkdir $DAY
|
# mkdir $DAY
|
||||||
cd $DAY
|
# cd $DAY
|
||||||
binary
|
# binary
|
||||||
put Radarr_Windows_$VERSION.zip
|
# put Radarr_Windows_$VERSION.zip
|
||||||
put Radarr_Mono_$VERSION.zip
|
# put Radarr_Mono_$VERSION.zip
|
||||||
put Radarr_OSX_$VERSION.zip
|
# put Radarr_OSX_$VERSION.zip
|
||||||
quit
|
# quit
|
||||||
END_SCRIPT
|
# END_SCRIPT
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ namespace NzbDrone.Api.Config
|
|||||||
public int MinimumAge { get; set; }
|
public int MinimumAge { get; set; }
|
||||||
public int Retention { get; set; }
|
public int Retention { get; set; }
|
||||||
public int RssSyncInterval { get; set; }
|
public int RssSyncInterval { get; set; }
|
||||||
public int AvailabilityDelay { get; set; }
|
public bool PreferIndexerFlags { get; set; }
|
||||||
public bool AllowHardcodedSubs { get; set; }
|
public int AvailabilityDelay { get; set; }
|
||||||
public string WhitelistedHardcodedSubs { get; set; }
|
public bool AllowHardcodedSubs { get; set; }
|
||||||
|
public string WhitelistedHardcodedSubs { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IndexerConfigResourceMapper
|
public static class IndexerConfigResourceMapper
|
||||||
@@ -22,9 +23,10 @@ namespace NzbDrone.Api.Config
|
|||||||
MinimumAge = model.MinimumAge,
|
MinimumAge = model.MinimumAge,
|
||||||
Retention = model.Retention,
|
Retention = model.Retention,
|
||||||
RssSyncInterval = model.RssSyncInterval,
|
RssSyncInterval = model.RssSyncInterval,
|
||||||
AvailabilityDelay = model.AvailabilityDelay,
|
PreferIndexerFlags = model.PreferIndexerFlags,
|
||||||
AllowHardcodedSubs = model.AllowHardcodedSubs,
|
AvailabilityDelay = model.AvailabilityDelay,
|
||||||
WhitelistedHardcodedSubs = model.WhitelistedHardcodedSubs,
|
AllowHardcodedSubs = model.AllowHardcodedSubs,
|
||||||
|
WhitelistedHardcodedSubs = model.WhitelistedHardcodedSubs,
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ namespace NzbDrone.Api.Indexers
|
|||||||
public bool DownloadAllowed { get; set; }
|
public bool DownloadAllowed { get; set; }
|
||||||
public int ReleaseWeight { get; set; }
|
public int ReleaseWeight { get; set; }
|
||||||
|
|
||||||
|
public IEnumerable<string> IndexerFlags { get; set; }
|
||||||
|
|
||||||
public string MagnetUrl { get; set; }
|
public string MagnetUrl { get; set; }
|
||||||
public string InfoHash { get; set; }
|
public string InfoHash { get; set; }
|
||||||
@@ -132,7 +133,7 @@ namespace NzbDrone.Api.Indexers
|
|||||||
Seeders = torrentInfo.Seeders,
|
Seeders = torrentInfo.Seeders,
|
||||||
Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
|
Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
|
||||||
Protocol = releaseInfo.DownloadProtocol,
|
Protocol = releaseInfo.DownloadProtocol,
|
||||||
|
IndexerFlags = torrentInfo.IndexerFlags.ToString().Split(new string[] { ", " }, StringSplitOptions.None),
|
||||||
Edition = parsedMovieInfo.Edition,
|
Edition = parsedMovieInfo.Edition,
|
||||||
|
|
||||||
IsDaily = false,
|
IsDaily = false,
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
|
|
||||||
private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics)
|
private void LinkMovieStatistics(MovieResource resource, MovieStatistics moviesStatistics)
|
||||||
{
|
{
|
||||||
resource.SizeOnDisk = moviesStatistics.SizeOnDisk;
|
//resource.SizeOnDisk = 0;//TODO: incorporate movie statistics moviesStatistics.SizeOnDisk;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateAlternateTitles(List<MovieResource> resources)
|
private void PopulateAlternateTitles(List<MovieResource> resources)
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
//TotalEpisodeCount
|
//TotalEpisodeCount
|
||||||
//EpisodeCount
|
//EpisodeCount
|
||||||
//EpisodeFileCount
|
//EpisodeFileCount
|
||||||
//SizeOnDisk
|
SizeOnDisk = size,
|
||||||
Status = model.Status,
|
Status = model.Status,
|
||||||
Overview = model.Overview,
|
Overview = model.Overview,
|
||||||
//NextAiring
|
//NextAiring
|
||||||
@@ -138,7 +138,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
IsAvailable = model.IsAvailable(),
|
IsAvailable = model.IsAvailable(),
|
||||||
FolderName = model.FolderName(),
|
FolderName = model.FolderName(),
|
||||||
|
|
||||||
SizeOnDisk = size,
|
//SizeOnDisk = size,
|
||||||
|
|
||||||
Runtime = model.Runtime,
|
Runtime = model.Runtime,
|
||||||
LastInfoSync = model.LastInfoSync,
|
LastInfoSync = model.LastInfoSync,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace NzbDrone.Common.Test.DiskTests
|
|||||||
public void should_be_able_to_check_space_on_ramdrive()
|
public void should_be_able_to_check_space_on_ramdrive()
|
||||||
{
|
{
|
||||||
MonoOnly();
|
MonoOnly();
|
||||||
Subject.GetAvailableSpace("/run/").Should().NotBe(0);
|
Subject.GetAvailableSpace("/").Should().NotBe(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ namespace NzbDrone.Common.Test
|
|||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("")]
|
[TestCase("")]
|
||||||
[TestCase("http://")]
|
|
||||||
public void DownloadString_should_throw_on_error(string url)
|
public void DownloadString_should_throw_on_error(string url)
|
||||||
{
|
{
|
||||||
Assert.Throws<ArgumentException>(() => Subject.DownloadString(url));
|
Assert.Throws<ArgumentException>(() => Subject.DownloadString(url));
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
private RemoteEpisode parseResultMulti;
|
private RemoteEpisode parseResultMulti;
|
||||||
private RemoteEpisode parseResultSingle;
|
private RemoteEpisode parseResultSingle;
|
||||||
private Series series;
|
private Series series;
|
||||||
|
private Movie movie;
|
||||||
|
private RemoteMovie remoteMovie;
|
||||||
private QualityDefinition qualityType;
|
private QualityDefinition qualityType;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
@@ -28,6 +30,16 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
series = Builder<Series>.CreateNew()
|
series = Builder<Series>.CreateNew()
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
movie = Builder<Movie>.CreateNew().Build();
|
||||||
|
|
||||||
|
remoteMovie = new RemoteMovie
|
||||||
|
{
|
||||||
|
Movie = movie,
|
||||||
|
Release = new ReleaseInfo(),
|
||||||
|
ParsedMovieInfo = new ParsedMovieInfo { Quality = new QualityModel(Quality.SDTV, new Revision(version: 2)) },
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
parseResultMultiSet = new RemoteEpisode
|
parseResultMultiSet = new RemoteEpisode
|
||||||
{
|
{
|
||||||
Series = series,
|
Series = series,
|
||||||
@@ -216,5 +228,17 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||||||
|
|
||||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_use_110_minutes_if_runtime_is_0()
|
||||||
|
{
|
||||||
|
movie.Runtime = 0;
|
||||||
|
remoteMovie.Movie = movie;
|
||||||
|
remoteMovie.Release.Size = 1095.Megabytes();
|
||||||
|
|
||||||
|
Subject.IsSatisfiedBy(remoteMovie, null).Accepted.Should().Be(true);
|
||||||
|
remoteMovie.Release.Size = 1105.Megabytes();
|
||||||
|
Subject.IsSatisfiedBy(remoteMovie, null).Accepted.Should().Be(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Indexers.PassThePopcorn;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Test.Common;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.IndexerTests.PTPTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class PTPFixture : CoreTest<PassThePopcorn>
|
||||||
|
{
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
Subject.Definition = new IndexerDefinition()
|
||||||
|
{
|
||||||
|
Name = "PTP",
|
||||||
|
Settings = new PassThePopcornSettings() { Passkey = "fakekey", Username = "asdf", Password = "sad" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("Files/Indexers/PTP/imdbsearch.json")]
|
||||||
|
public void should_parse_feed_from_PTP(string fileName)
|
||||||
|
{
|
||||||
|
var authResponse = new PassThePopcornAuthResponse { Result = "Ok" };
|
||||||
|
|
||||||
|
System.IO.StringWriter authStream = new System.IO.StringWriter();
|
||||||
|
Json.Serialize(authResponse, authStream);
|
||||||
|
var responseJson = ReadAllText(fileName);
|
||||||
|
|
||||||
|
Mocker.GetMock<IHttpClient>()
|
||||||
|
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.POST)))
|
||||||
|
.Returns<HttpRequest>(r => new HttpResponse(r,new HttpHeader(), authStream.ToString()));
|
||||||
|
|
||||||
|
Mocker.GetMock<IHttpClient>()
|
||||||
|
.Setup(o => o.Execute(It.Is<HttpRequest>(v => v.Method == HttpMethod.GET)))
|
||||||
|
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader {ContentType = HttpAccept.Json.Value}, responseJson));
|
||||||
|
|
||||||
|
var torrents = Subject.FetchRecent();
|
||||||
|
|
||||||
|
torrents.Should().HaveCount(293);
|
||||||
|
torrents.First().Should().BeOfType<PassThePopcornInfo>();
|
||||||
|
|
||||||
|
var first = torrents.First() as TorrentInfo;
|
||||||
|
|
||||||
|
first.Guid.Should().Be("PassThePopcorn-483521");
|
||||||
|
first.Title.Should().Be("The.Night.Of.S01.720p.HDTV.x264-BTN");
|
||||||
|
first.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
|
||||||
|
first.DownloadUrl.Should().Be("https://passthepopcorn.me/torrents.php?action=download&id=483521&authkey=00000000000000000000000000000000&torrent_pass=00000000000000000000000000000000");
|
||||||
|
first.InfoUrl.Should().Be("https://passthepopcorn.me/torrents.php?id=148131&torrentid=483521");
|
||||||
|
//first.PublishDate.Should().Be(DateTime.Parse("2017-04-17T12:13:42+0000").ToUniversalTime()); stupid timezones
|
||||||
|
first.Size.Should().Be(9370933376);
|
||||||
|
first.InfoHash.Should().BeNullOrEmpty();
|
||||||
|
first.MagnetUrl.Should().BeNullOrEmpty();
|
||||||
|
first.Peers.Should().Be(3);
|
||||||
|
first.Seeders.Should().Be(1);
|
||||||
|
|
||||||
|
torrents.Any(t => t.IndexerFlags.HasFlag(IndexerFlags.G_Freeleech)).Should().Be(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -389,6 +389,10 @@
|
|||||||
<Content Include="Files\ArabicRomanNumeralDictionary.JSON">
|
<Content Include="Files\ArabicRomanNumeralDictionary.JSON">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Compile Include="IndexerTests\PTPTests\PTPFixture.cs" />
|
||||||
|
<None Include="Files\Indexers\PTP\imdbsearch.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Marr.Data\Marr.Data.csproj">
|
<ProjectReference Include="..\Marr.Data\Marr.Data.csproj">
|
||||||
@@ -574,6 +578,8 @@
|
|||||||
<Folder Include="DataAugmentation\SceneNumbering\" />
|
<Folder Include="DataAugmentation\SceneNumbering\" />
|
||||||
<Folder Include="Providers\" />
|
<Folder Include="Providers\" />
|
||||||
<Folder Include="ProviderTests\UpdateProviderTests\" />
|
<Folder Include="ProviderTests\UpdateProviderTests\" />
|
||||||
|
<Folder Include="IndexerTests\PTPTests\" />
|
||||||
|
<Folder Include="Files\Indexers\PTP\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
@@ -74,6 +74,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
[TestCase("To.Live.and.Die.in.L.A.1985.1080p.BluRay", "To Live and Die in L.A.")]
|
[TestCase("To.Live.and.Die.in.L.A.1985.1080p.BluRay", "To Live and Die in L.A.")]
|
||||||
[TestCase("A.I.Artificial.Intelligence.(2001)", "A.I. Artificial Intelligence")]
|
[TestCase("A.I.Artificial.Intelligence.(2001)", "A.I. Artificial Intelligence")]
|
||||||
[TestCase("A.Movie.Name.(1998)", "A Movie Name")]
|
[TestCase("A.Movie.Name.(1998)", "A Movie Name")]
|
||||||
|
[TestCase("Thor: The Dark World 2013", "Thor The Dark World")]
|
||||||
public void should_parse_movie_title(string postTitle, string title)
|
public void should_parse_movie_title(string postTitle, string title)
|
||||||
{
|
{
|
||||||
Parser.Parser.ParseMovieTitle(postTitle).MovieTitle.Should().Be(title);
|
Parser.Parser.ParseMovieTitle(postTitle).MovieTitle.Should().Be(title);
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||||||
private ParsedMovieInfo _wrongYearInfo;
|
private ParsedMovieInfo _wrongYearInfo;
|
||||||
private ParsedMovieInfo _romanTitleInfo;
|
private ParsedMovieInfo _romanTitleInfo;
|
||||||
private ParsedMovieInfo _alternativeTitleInfo;
|
private ParsedMovieInfo _alternativeTitleInfo;
|
||||||
|
private ParsedMovieInfo _umlautInfo;
|
||||||
|
private ParsedMovieInfo _umlautAltInfo;
|
||||||
private MovieSearchCriteria _movieSearchCriteria;
|
private MovieSearchCriteria _movieSearchCriteria;
|
||||||
private List<Episode> _episodes;
|
private List<Episode> _episodes;
|
||||||
private ParsedEpisodeInfo _parsedEpisodeInfo;
|
private ParsedEpisodeInfo _parsedEpisodeInfo;
|
||||||
@@ -37,10 +39,10 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_movie = Builder<Movie>.CreateNew()
|
_movie = Builder<Movie>.CreateNew()
|
||||||
.With(m => m.Title = "Mission Impossible 3")
|
.With(m => m.Title = "Fack Ju Göthe 2")
|
||||||
.With(m => m.CleanTitle = "missionimpossible3")
|
.With(m => m.CleanTitle = "fackjugoethe2")
|
||||||
.With(m => m.Year = 2006)
|
.With(m => m.Year = 2015)
|
||||||
.With(m => m.AlternativeTitles = new List<string> { "Mission Impossible 3: Same same" })
|
.With(m => m.AlternativeTitles = new List<string> { "Fack Ju Göthe 2: Same same" })
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
_episodes = Builder<Episode>.CreateListOfSize(1)
|
_episodes = Builder<Episode>.CreateListOfSize(1)
|
||||||
@@ -77,10 +79,22 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||||||
|
|
||||||
_romanTitleInfo = new ParsedMovieInfo
|
_romanTitleInfo = new ParsedMovieInfo
|
||||||
{
|
{
|
||||||
MovieTitle = "Mission Impossible III",
|
MovieTitle = "Fack Ju Göthe II",
|
||||||
Year = _movie.Year,
|
Year = _movie.Year,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_umlautInfo = new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
MovieTitle = "Fack Ju Goethe 2",
|
||||||
|
Year = _movie.Year
|
||||||
|
};
|
||||||
|
|
||||||
|
_umlautAltInfo = new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
MovieTitle = "Fack Ju Goethe 2: Same same",
|
||||||
|
Year = _movie.Year
|
||||||
|
};
|
||||||
|
|
||||||
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
||||||
{
|
{
|
||||||
Series = _series,
|
Series = _series,
|
||||||
@@ -148,5 +162,12 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||||||
Subject.Map(_romanTitleInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
|
Subject.Map(_romanTitleInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_match_umlauts()
|
||||||
|
{
|
||||||
|
Subject.Map(_umlautInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
|
||||||
|
Subject.Map(_umlautAltInfo, "", _movieSearchCriteria).Movie.Should().Be(_movieSearchCriteria.Movie);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,11 +105,11 @@ namespace NzbDrone.Core.Configuration
|
|||||||
set { SetValue("RssSyncInterval", value); }
|
set { SetValue("RssSyncInterval", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public int AvailabilityDelay
|
public int AvailabilityDelay
|
||||||
{
|
{
|
||||||
get { return GetValueInt("AvailabilityDelay",0); }
|
get { return GetValueInt("AvailabilityDelay",0); }
|
||||||
set { SetValue("AvailabilityDelay", value); }
|
set { SetValue("AvailabilityDelay", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public int NetImportSyncInterval
|
public int NetImportSyncInterval
|
||||||
{
|
{
|
||||||
@@ -190,19 +190,26 @@ namespace NzbDrone.Core.Configuration
|
|||||||
set { SetValue("EnableCompletedDownloadHandling", value); }
|
set { SetValue("EnableCompletedDownloadHandling", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AllowHardcodedSubs
|
public bool PreferIndexerFlags
|
||||||
{
|
{
|
||||||
get { return GetValueBoolean("AllowHardcodedSubs", false); }
|
get { return GetValueBoolean("PreferIndexerFlags", false); }
|
||||||
|
|
||||||
set { SetValue("AllowHardcodedSubs", value); }
|
set {SetValue("PreferIndexerFlags", value);}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string WhitelistedHardcodedSubs
|
public bool AllowHardcodedSubs
|
||||||
{
|
{
|
||||||
get { return GetValue("WhitelistedHardcodedSubs", ""); }
|
get { return GetValueBoolean("AllowHardcodedSubs", false); }
|
||||||
|
|
||||||
set { SetValue("WhitelistedHardcodedSubs", value); }
|
set { SetValue("AllowHardcodedSubs", value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string WhitelistedHardcodedSubs
|
||||||
|
{
|
||||||
|
get { return GetValue("WhitelistedHardcodedSubs", ""); }
|
||||||
|
|
||||||
|
set { SetValue("WhitelistedHardcodedSubs", value); }
|
||||||
|
}
|
||||||
|
|
||||||
public bool RemoveCompletedDownloads
|
public bool RemoveCompletedDownloads
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,20 +46,22 @@ namespace NzbDrone.Core.Configuration
|
|||||||
int RssSyncInterval { get; set; }
|
int RssSyncInterval { get; set; }
|
||||||
int MinimumAge { get; set; }
|
int MinimumAge { get; set; }
|
||||||
|
|
||||||
int AvailabilityDelay { get; set; }
|
bool PreferIndexerFlags { get; set; }
|
||||||
|
|
||||||
bool AllowHardcodedSubs { get; set; }
|
int AvailabilityDelay { get; set; }
|
||||||
string WhitelistedHardcodedSubs { get; set; }
|
|
||||||
|
bool AllowHardcodedSubs { get; set; }
|
||||||
|
string WhitelistedHardcodedSubs { get; set; }
|
||||||
|
|
||||||
int NetImportSyncInterval { get; set; }
|
int NetImportSyncInterval { get; set; }
|
||||||
string ListSyncLevel { get; set; }
|
string ListSyncLevel { get; set; }
|
||||||
string ImportExclusions { get; set; }
|
string ImportExclusions { get; set; }
|
||||||
string TraktAuthToken { get; set; }
|
string TraktAuthToken { get; set; }
|
||||||
string TraktRefreshToken { get; set; }
|
string TraktRefreshToken { get; set; }
|
||||||
int TraktTokenExpiry { get; set; }
|
int TraktTokenExpiry { get; set; }
|
||||||
string NewTraktAuthToken { get; set; }
|
string NewTraktAuthToken { get; set; }
|
||||||
string NewTraktRefreshToken {get; set; }
|
string NewTraktRefreshToken {get; set; }
|
||||||
int NewTraktTokenExpiry { get; set; }
|
int NewTraktTokenExpiry { get; set; }
|
||||||
|
|
||||||
//UI
|
//UI
|
||||||
int FirstDayOfWeek { get; set; }
|
int FirstDayOfWeek { get; set; }
|
||||||
|
|||||||
@@ -4,18 +4,21 @@ using System.Linq;
|
|||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Profiles.Delay;
|
using NzbDrone.Core.Profiles.Delay;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
|
||||||
namespace NzbDrone.Core.DecisionEngine
|
namespace NzbDrone.Core.DecisionEngine
|
||||||
{
|
{
|
||||||
public class DownloadDecisionComparer : IComparer<DownloadDecision>
|
public class DownloadDecisionComparer : IComparer<DownloadDecision>
|
||||||
{
|
{
|
||||||
private readonly IDelayProfileService _delayProfileService;
|
private readonly IDelayProfileService _delayProfileService;
|
||||||
|
private readonly IConfigService _configService;
|
||||||
public delegate int CompareDelegate(DownloadDecision x, DownloadDecision y);
|
public delegate int CompareDelegate(DownloadDecision x, DownloadDecision y);
|
||||||
public delegate int CompareDelegate<TSubject, TValue>(DownloadDecision x, DownloadDecision y);
|
public delegate int CompareDelegate<TSubject, TValue>(DownloadDecision x, DownloadDecision y);
|
||||||
|
|
||||||
public DownloadDecisionComparer(IDelayProfileService delayProfileService)
|
public DownloadDecisionComparer(IDelayProfileService delayProfileService, IConfigService configService)
|
||||||
{
|
{
|
||||||
_delayProfileService = delayProfileService;
|
_delayProfileService = delayProfileService;
|
||||||
|
_configService = configService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Compare(DownloadDecision x, DownloadDecision y)
|
public int Compare(DownloadDecision x, DownloadDecision y)
|
||||||
@@ -24,6 +27,7 @@ namespace NzbDrone.Core.DecisionEngine
|
|||||||
{
|
{
|
||||||
CompareQuality,
|
CompareQuality,
|
||||||
ComparePreferredWords,
|
ComparePreferredWords,
|
||||||
|
CompareIndexerFlags,
|
||||||
CompareProtocol,
|
CompareProtocol,
|
||||||
ComparePeersIfTorrent,
|
ComparePeersIfTorrent,
|
||||||
CompareAgeIfUsenet,
|
CompareAgeIfUsenet,
|
||||||
@@ -84,7 +88,22 @@ namespace NzbDrone.Core.DecisionEngine
|
|||||||
return num;
|
return num;
|
||||||
|
|
||||||
});
|
});
|
||||||
; }
|
}
|
||||||
|
|
||||||
|
private int CompareIndexerFlags(DownloadDecision x, DownloadDecision y)
|
||||||
|
{
|
||||||
|
var releaseX = x.RemoteMovie.Release;
|
||||||
|
var releaseY = y.RemoteMovie.Release;
|
||||||
|
|
||||||
|
if (_configService.PreferIndexerFlags)
|
||||||
|
{
|
||||||
|
return CompareBy(x.RemoteMovie.Release, y.RemoteMovie.Release, release => ScoreFlags(release.IndexerFlags));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int CompareProtocol(DownloadDecision x, DownloadDecision y)
|
private int CompareProtocol(DownloadDecision x, DownloadDecision y)
|
||||||
{
|
{
|
||||||
@@ -185,5 +204,34 @@ namespace NzbDrone.Core.DecisionEngine
|
|||||||
|
|
||||||
return CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode => remoteEpisode.Release.Size.Round(200.Megabytes()));
|
return CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode => remoteEpisode.Release.Size.Round(200.Megabytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int ScoreFlags(IndexerFlags flags)
|
||||||
|
{
|
||||||
|
var flagValues = Enum.GetValues(typeof(IndexerFlags));
|
||||||
|
|
||||||
|
var score = 0;
|
||||||
|
|
||||||
|
foreach (IndexerFlags value in flagValues)
|
||||||
|
{
|
||||||
|
if ((flags & value) == value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case IndexerFlags.G_DoubleUpload:
|
||||||
|
case IndexerFlags.G_Freeleech:
|
||||||
|
case IndexerFlags.PTP_Approved:
|
||||||
|
case IndexerFlags.PTP_Golden:
|
||||||
|
case IndexerFlags.HDB_Internal:
|
||||||
|
score += 2;
|
||||||
|
break;
|
||||||
|
case IndexerFlags.G_Halfleech:
|
||||||
|
score += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return score;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Core.Profiles.Delay;
|
using NzbDrone.Core.Profiles.Delay;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
|
||||||
namespace NzbDrone.Core.DecisionEngine
|
namespace NzbDrone.Core.DecisionEngine
|
||||||
{
|
{
|
||||||
@@ -13,10 +14,12 @@ namespace NzbDrone.Core.DecisionEngine
|
|||||||
public class DownloadDecisionPriorizationService : IPrioritizeDownloadDecision
|
public class DownloadDecisionPriorizationService : IPrioritizeDownloadDecision
|
||||||
{
|
{
|
||||||
private readonly IDelayProfileService _delayProfileService;
|
private readonly IDelayProfileService _delayProfileService;
|
||||||
|
private readonly IConfigService _configService;
|
||||||
|
|
||||||
public DownloadDecisionPriorizationService(IDelayProfileService delayProfileService)
|
public DownloadDecisionPriorizationService(IDelayProfileService delayProfileService, IConfigService configService)
|
||||||
{
|
{
|
||||||
_delayProfileService = delayProfileService;
|
_delayProfileService = delayProfileService;
|
||||||
|
_configService = configService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DownloadDecision> PrioritizeDecisions(List<DownloadDecision> decisions)
|
public List<DownloadDecision> PrioritizeDecisions(List<DownloadDecision> decisions)
|
||||||
@@ -24,7 +27,7 @@ namespace NzbDrone.Core.DecisionEngine
|
|||||||
return decisions.Where(c => c.RemoteEpisode.Series != null)
|
return decisions.Where(c => c.RemoteEpisode.Series != null)
|
||||||
.GroupBy(c => c.RemoteEpisode.Series.Id, (seriesId, downloadDecisions) =>
|
.GroupBy(c => c.RemoteEpisode.Series.Id, (seriesId, downloadDecisions) =>
|
||||||
{
|
{
|
||||||
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService));
|
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService, _configService));
|
||||||
})
|
})
|
||||||
.SelectMany(c => c)
|
.SelectMany(c => c)
|
||||||
.Union(decisions.Where(c => c.RemoteEpisode.Series == null))
|
.Union(decisions.Where(c => c.RemoteEpisode.Series == null))
|
||||||
@@ -36,7 +39,7 @@ namespace NzbDrone.Core.DecisionEngine
|
|||||||
return decisions.Where(c => c.RemoteMovie.Movie != null)
|
return decisions.Where(c => c.RemoteMovie.Movie != null)
|
||||||
.GroupBy(c => c.RemoteMovie.Movie.Id, (movieId, downloadDecisions) =>
|
.GroupBy(c => c.RemoteMovie.Movie.Id, (movieId, downloadDecisions) =>
|
||||||
{
|
{
|
||||||
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService));
|
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService, _configService));
|
||||||
})
|
})
|
||||||
.SelectMany(c => c)
|
.SelectMany(c => c)
|
||||||
.Union(decisions.Where(c => c.RemoteMovie.Movie == null))
|
.Union(decisions.Where(c => c.RemoteMovie.Movie == null))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
@@ -121,6 +121,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
|||||||
}
|
}
|
||||||
|
|
||||||
var qualityDefinition = _qualityDefinitionService.Get(quality);
|
var qualityDefinition = _qualityDefinitionService.Get(quality);
|
||||||
|
if (subject.Movie.Runtime == 0)
|
||||||
|
{
|
||||||
|
_logger.Info("{0} has no runtime information using median movie runtime of 110 minutes.", subject.Movie);
|
||||||
|
subject.Movie.Runtime = 110;
|
||||||
|
}
|
||||||
if (qualityDefinition.MinSize.HasValue)
|
if (qualityDefinition.MinSize.HasValue)
|
||||||
{
|
{
|
||||||
var minSize = qualityDefinition.MinSize.Value.Megabytes();
|
var minSize = qualityDefinition.MinSize.Value.Megabytes();
|
||||||
|
|||||||
@@ -129,7 +129,14 @@ namespace NzbDrone.Core.Download
|
|||||||
{
|
{
|
||||||
var statusMessages = importResults
|
var statusMessages = importResults
|
||||||
.Where(v => v.Result != ImportResultType.Imported)
|
.Where(v => v.Result != ImportResultType.Imported)
|
||||||
.Select(v => new TrackedDownloadStatusMessage(Path.GetFileName(v.ImportDecision.LocalMovie.Path), v.Errors))
|
.Select(v =>
|
||||||
|
{
|
||||||
|
if (v.ImportDecision.LocalMovie == null)
|
||||||
|
{
|
||||||
|
return new TrackedDownloadStatusMessage("", v.Errors);
|
||||||
|
}
|
||||||
|
return new TrackedDownloadStatusMessage(Path.GetFileName(v.ImportDecision.LocalMovie.Path), v.Errors);
|
||||||
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
trackedDownload.Warn(statusMessages);
|
trackedDownload.Warn(statusMessages);
|
||||||
|
|||||||
@@ -226,7 +226,12 @@ namespace NzbDrone.Core.Download.Pending
|
|||||||
Title = decision.RemoteMovie.Release.Title,
|
Title = decision.RemoteMovie.Release.Title,
|
||||||
Added = DateTime.UtcNow
|
Added = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
_repository.Insert(release);
|
if (release.ParsedMovieInfo == null)
|
||||||
|
{
|
||||||
|
_logger.Warn("Pending release {0} does not have ParsedMovieInfo, will cause issues.", release.Title);
|
||||||
|
}
|
||||||
|
|
||||||
|
_repository.Insert(release);
|
||||||
|
|
||||||
_eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent());
|
_eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,12 @@ namespace NzbDrone.Core.Indexers.AwesomeHD
|
|||||||
{
|
{
|
||||||
var id = torrent.Id;
|
var id = torrent.Id;
|
||||||
var title = $"{torrent.Name}.{torrent.Year}.{torrent.Resolution}.{torrent.Media}.{torrent.Encoding}.{torrent.AudioFormat}-{torrent.ReleaseGroup}";
|
var title = $"{torrent.Name}.{torrent.Year}.{torrent.Resolution}.{torrent.Media}.{torrent.Encoding}.{torrent.AudioFormat}-{torrent.ReleaseGroup}";
|
||||||
|
IndexerFlags flags = 0;
|
||||||
|
|
||||||
|
if (torrent.Freeleech == "1.00")
|
||||||
|
{
|
||||||
|
flags |= IndexerFlags.G_Freeleech;
|
||||||
|
}
|
||||||
|
|
||||||
torrentInfos.Add(new TorrentInfo()
|
torrentInfos.Add(new TorrentInfo()
|
||||||
{
|
{
|
||||||
@@ -80,7 +86,8 @@ namespace NzbDrone.Core.Indexers.AwesomeHD
|
|||||||
Seeders = int.Parse(torrent.Seeders),
|
Seeders = int.Parse(torrent.Seeders),
|
||||||
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
|
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
|
||||||
PublishDate = torrent.Time.ToUniversalTime(),
|
PublishDate = torrent.Time.ToUniversalTime(),
|
||||||
ImdbId = int.Parse(torrent.ImdbId.Substring(2))
|
ImdbId = int.Parse(torrent.ImdbId.Substring(2)),
|
||||||
|
IndexerFlags = flags,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,18 @@ namespace NzbDrone.Core.Indexers.HDBits
|
|||||||
var id = result.Id;
|
var id = result.Id;
|
||||||
var internalRelease = (result.TypeOrigin == 1 ? true : false);
|
var internalRelease = (result.TypeOrigin == 1 ? true : false);
|
||||||
|
|
||||||
|
IndexerFlags flags = 0;
|
||||||
|
|
||||||
|
if (result.FreeLeech == "yes")
|
||||||
|
{
|
||||||
|
flags |= IndexerFlags.G_Freeleech;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (internalRelease)
|
||||||
|
{
|
||||||
|
flags |= IndexerFlags.HDB_Internal;
|
||||||
|
}
|
||||||
|
|
||||||
torrentInfos.Add(new HDBitsInfo()
|
torrentInfos.Add(new HDBitsInfo()
|
||||||
{
|
{
|
||||||
Guid = string.Format("HDBits-{0}", id),
|
Guid = string.Format("HDBits-{0}", id),
|
||||||
@@ -65,7 +77,8 @@ namespace NzbDrone.Core.Indexers.HDBits
|
|||||||
Peers = result.Leechers + result.Seeders,
|
Peers = result.Leechers + result.Seeders,
|
||||||
PublishDate = result.Added.ToUniversalTime(),
|
PublishDate = result.Added.ToUniversalTime(),
|
||||||
Internal = internalRelease,
|
Internal = internalRelease,
|
||||||
ImdbId = result.ImdbInfo?.Id ?? 0
|
ImdbId = result.ImdbInfo?.Id ?? 0,
|
||||||
|
IndexerFlags = flags
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||||||
public string ReleaseName { get; set; }
|
public string ReleaseName { get; set; }
|
||||||
public bool Checked { get; set; }
|
public bool Checked { get; set; }
|
||||||
public bool GoldenPopcorn { get; set; }
|
public bool GoldenPopcorn { get; set; }
|
||||||
|
public string FreeleechType { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Movie
|
public class Movie
|
||||||
|
|||||||
@@ -55,60 +55,69 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
|
|||||||
{
|
{
|
||||||
var id = torrent.Id;
|
var id = torrent.Id;
|
||||||
var title = torrent.ReleaseName;
|
var title = torrent.ReleaseName;
|
||||||
|
IndexerFlags flags = 0;
|
||||||
|
|
||||||
if (torrent.GoldenPopcorn)
|
if (torrent.GoldenPopcorn)
|
||||||
{
|
{
|
||||||
title = $"{title} 🍿";
|
flags |= IndexerFlags.PTP_Golden;//title = $"{title} 🍿";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (torrent.Checked)
|
if (torrent.Checked)
|
||||||
{
|
{
|
||||||
title = $"{title} ✔";
|
flags |= IndexerFlags.PTP_Approved;//title = $"{title} ✔";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (torrent.FreeleechType == "Freeleech")
|
||||||
|
{
|
||||||
|
flags |= IndexerFlags.G_Freeleech;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only add approved torrents
|
// Only add approved torrents
|
||||||
if (_settings.RequireApproved && torrent.Checked)
|
if (_settings.RequireApproved && torrent.Checked)
|
||||||
{
|
|
||||||
torrentInfos.Add(new PassThePopcornInfo()
|
|
||||||
{
|
{
|
||||||
Guid = string.Format("PassThePopcorn-{0}", id),
|
torrentInfos.Add(new PassThePopcornInfo()
|
||||||
Title = title,
|
{
|
||||||
Size = long.Parse(torrent.Size),
|
Guid = string.Format("PassThePopcorn-{0}", id),
|
||||||
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
|
Title = title,
|
||||||
InfoUrl = GetInfoUrl(result.GroupId, id),
|
Size = long.Parse(torrent.Size),
|
||||||
Seeders = int.Parse(torrent.Seeders),
|
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
|
||||||
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
|
InfoUrl = GetInfoUrl(result.GroupId, id),
|
||||||
PublishDate = torrent.UploadTime.ToUniversalTime(),
|
Seeders = int.Parse(torrent.Seeders),
|
||||||
Golden = torrent.GoldenPopcorn,
|
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
|
||||||
Scene = torrent.Scene,
|
PublishDate = torrent.UploadTime.ToUniversalTime(),
|
||||||
Approved = torrent.Checked,
|
Golden = torrent.GoldenPopcorn,
|
||||||
ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0)
|
Scene = torrent.Scene,
|
||||||
});
|
Approved = torrent.Checked,
|
||||||
}
|
ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0),
|
||||||
// Add all torrents
|
IndexerFlags = flags
|
||||||
else if (!_settings.RequireApproved)
|
});
|
||||||
{
|
}
|
||||||
torrentInfos.Add(new PassThePopcornInfo()
|
|
||||||
|
// Add all torrents
|
||||||
|
else if (!_settings.RequireApproved)
|
||||||
{
|
{
|
||||||
Guid = string.Format("PassThePopcorn-{0}", id),
|
torrentInfos.Add(new PassThePopcornInfo()
|
||||||
Title = title,
|
{
|
||||||
Size = long.Parse(torrent.Size),
|
Guid = string.Format("PassThePopcorn-{0}", id),
|
||||||
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
|
Title = title,
|
||||||
InfoUrl = GetInfoUrl(result.GroupId, id),
|
Size = long.Parse(torrent.Size),
|
||||||
Seeders = int.Parse(torrent.Seeders),
|
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
|
||||||
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
|
InfoUrl = GetInfoUrl(result.GroupId, id),
|
||||||
PublishDate = torrent.UploadTime.ToUniversalTime(),
|
Seeders = int.Parse(torrent.Seeders),
|
||||||
Golden = torrent.GoldenPopcorn,
|
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
|
||||||
Scene = torrent.Scene,
|
PublishDate = torrent.UploadTime.ToUniversalTime(),
|
||||||
Approved = torrent.Checked,
|
Golden = torrent.GoldenPopcorn,
|
||||||
ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0)
|
Scene = torrent.Scene,
|
||||||
});
|
Approved = torrent.Checked,
|
||||||
}
|
ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0),
|
||||||
// Don't add any torrents
|
IndexerFlags = flags
|
||||||
else if (_settings.RequireApproved && !torrent.Checked)
|
});
|
||||||
{
|
}
|
||||||
continue;
|
// Don't add any torrents
|
||||||
}
|
else if (_settings.RequireApproved && !torrent.Checked)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ namespace NzbDrone.Core.Indexers.Torznab
|
|||||||
torrentInfo.ImdbId = int.Parse(GetImdbId(item).Substring(2));
|
torrentInfo.ImdbId = int.Parse(GetImdbId(item).Substring(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
torrentInfo.IndexerFlags = GetFlags(item);
|
||||||
|
|
||||||
return torrentInfo;
|
return torrentInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +154,32 @@ namespace NzbDrone.Core.Indexers.Torznab
|
|||||||
return base.GetPeers(item);
|
return base.GetPeers(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected IndexerFlags GetFlags(XElement item)
|
||||||
|
{
|
||||||
|
IndexerFlags flags = 0;
|
||||||
|
|
||||||
|
var downloadFactor = TryGetFloatTorznabAttribute(item, "downloadvolumefactor", 1);
|
||||||
|
|
||||||
|
var uploadFactor = TryGetFloatTorznabAttribute(item, "uploadvolumefactor", 1);
|
||||||
|
|
||||||
|
if (uploadFactor == 2)
|
||||||
|
{
|
||||||
|
flags |= IndexerFlags.G_DoubleUpload;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloadFactor == 0.5)
|
||||||
|
{
|
||||||
|
flags |= IndexerFlags.G_Halfleech;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloadFactor == 0.0)
|
||||||
|
{
|
||||||
|
flags |= IndexerFlags.G_Freeleech;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
protected string TryGetTorznabAttribute(XElement item, string key, string defaultValue = "")
|
protected string TryGetTorznabAttribute(XElement item, string key, string defaultValue = "")
|
||||||
{
|
{
|
||||||
var attr = item.Elements(ns + "attr").FirstOrDefault(e => e.Attribute("name").Value.Equals(key, StringComparison.CurrentCultureIgnoreCase));
|
var attr = item.Elements(ns + "attr").FirstOrDefault(e => e.Attribute("name").Value.Equals(key, StringComparison.CurrentCultureIgnoreCase));
|
||||||
@@ -160,6 +189,20 @@ namespace NzbDrone.Core.Indexers.Torznab
|
|||||||
return attr.Attribute("value").Value;
|
return attr.Attribute("value").Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float TryGetFloatTorznabAttribute(XElement item, string key, float defaultValue = 0)
|
||||||
|
{
|
||||||
|
var attr = TryGetTorznabAttribute(item, key, defaultValue.ToString());
|
||||||
|
|
||||||
|
float result = 0;
|
||||||
|
|
||||||
|
if (float.TryParse(attr, out result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ namespace NzbDrone.Core.MetadataSource.PreDB
|
|||||||
|
|
||||||
private List<PreDBResult> GetResults(string category = "", string search = "")
|
private List<PreDBResult> GetResults(string category = "", string search = "")
|
||||||
{
|
{
|
||||||
|
return new List<PreDBResult>();
|
||||||
var builder = new HttpRequestBuilder("http://predb.me").AddQueryParam("rss", "1");
|
var builder = new HttpRequestBuilder("http://predb.me").AddQueryParam("rss", "1");
|
||||||
if (category.IsNotNullOrWhiteSpace())
|
if (category.IsNotNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
@@ -171,10 +172,12 @@ namespace NzbDrone.Core.MetadataSource.PreDB
|
|||||||
|
|
||||||
public bool HasReleases(Movie movie)
|
public bool HasReleases(Movie movie)
|
||||||
{
|
{
|
||||||
var results = GetResults("movies", movie.Title);
|
try
|
||||||
|
{
|
||||||
|
var results = GetResults("movies", movie.Title);
|
||||||
|
|
||||||
foreach (PreDBResult result in results)
|
foreach (PreDBResult result in results)
|
||||||
{
|
{
|
||||||
var parsed = Parser.Parser.ParseMovieTitle(result.Title);
|
var parsed = Parser.Parser.ParseMovieTitle(result.Title);
|
||||||
if (parsed == null)
|
if (parsed == null)
|
||||||
{
|
{
|
||||||
@@ -182,13 +185,20 @@ namespace NzbDrone.Core.MetadataSource.PreDB
|
|||||||
}
|
}
|
||||||
var match = _parsingService.Map(parsed, "", new MovieSearchCriteria { Movie = movie });
|
var match = _parsingService.Map(parsed, "", new MovieSearchCriteria { Movie = movie });
|
||||||
|
|
||||||
if (match != null && match.Movie != null && match.Movie.Id == movie.Id)
|
if (match != null && match.Movie != null && match.Movie.Id == movie.Id)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, "Error while looking on predb.me.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace NzbDrone.Core.Notifications.Email
|
|||||||
|
|
||||||
public EmailSettings()
|
public EmailSettings()
|
||||||
{
|
{
|
||||||
Server = "smtp.google.com";
|
Server = "smtp.gmail.com";
|
||||||
Port = 587;
|
Port = 587;
|
||||||
Ssl = true;
|
Ssl = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1275,6 +1275,7 @@
|
|||||||
<Compile Include="Datastore\Migration\131_make_parsed_episode_info_nullable.cs" />
|
<Compile Include="Datastore\Migration\131_make_parsed_episode_info_nullable.cs" />
|
||||||
<Compile Include="Housekeeping\Housekeepers\FixWronglyMatchedMovieFiles.cs" />
|
<Compile Include="Housekeeping\Housekeepers\FixWronglyMatchedMovieFiles.cs" />
|
||||||
<Compile Include="Datastore\Migration\135_add_haspredbentry_to_movies.cs" />
|
<Compile Include="Datastore\Migration\135_add_haspredbentry_to_movies.cs" />
|
||||||
|
<Compile Include="Tv\QueryExtensions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
|
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
|
||||||
@@ -26,6 +26,8 @@ namespace NzbDrone.Core.Parser.Model
|
|||||||
public string Codec { get; set; }
|
public string Codec { get; set; }
|
||||||
public string Resolution { get; set; }
|
public string Resolution { get; set; }
|
||||||
|
|
||||||
|
public IndexerFlags IndexerFlags { get; set; }
|
||||||
|
|
||||||
public int Age
|
public int Age
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -91,4 +93,15 @@ namespace NzbDrone.Core.Parser.Model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum IndexerFlags
|
||||||
|
{
|
||||||
|
G_Freeleech = 1, //General
|
||||||
|
G_Halfleech = 2, //General, only 1/2 of download counted
|
||||||
|
G_DoubleUpload = 4, //General
|
||||||
|
PTP_Golden = 8, //PTP
|
||||||
|
PTP_Approved = 16, //PTP
|
||||||
|
HDB_Internal = 32 //HDBits
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -273,7 +273,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
|
|
||||||
private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{7})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{7})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|576[ip]|720[ip]|1080[ip]|2160[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*",
|
private static readonly Regex SimpleTitleRegex = new Regex(@"\s*(?:480[ip]|576[ip]|720[ip]|1080[ip]|2160[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*",
|
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*",
|
||||||
@@ -310,6 +310,12 @@ namespace NzbDrone.Core.Parser
|
|||||||
private static readonly Regex RequestInfoRegex = new Regex(@"\[.+?\]", RegexOptions.Compiled);
|
private static readonly Regex RequestInfoRegex = new Regex(@"\[.+?\]", RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly string[] Numbers = new[] { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
|
private static readonly string[] Numbers = new[] { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
|
||||||
|
private static Dictionary<String, String> _umlautMappings = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"ö", "oe"},
|
||||||
|
{"ä", "ae"},
|
||||||
|
{"ü", "ue"},
|
||||||
|
};
|
||||||
|
|
||||||
public static ParsedEpisodeInfo ParsePath(string path)
|
public static ParsedEpisodeInfo ParsePath(string path)
|
||||||
{
|
{
|
||||||
@@ -405,8 +411,13 @@ namespace NzbDrone.Core.Parser
|
|||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
|
var languageTitle = simpleTitle;
|
||||||
|
if (result.MovieTitle.IsNotNullOrWhiteSpace() )
|
||||||
|
{
|
||||||
|
languageTitle = simpleTitle.Replace(result.MovieTitle, "A Movie");
|
||||||
|
}
|
||||||
|
|
||||||
result.Language = LanguageParser.ParseLanguage(simpleTitle.Replace(result.MovieTitle, "A Movie"));
|
result.Language = LanguageParser.ParseLanguage(languageTitle);
|
||||||
Logger.Debug("Language parsed: {0}", result.Language);
|
Logger.Debug("Language parsed: {0}", result.Language);
|
||||||
|
|
||||||
result.Quality = QualityParser.ParseQuality(title);
|
result.Quality = QualityParser.ParseQuality(title);
|
||||||
@@ -655,7 +666,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
if (long.TryParse(title, out number))
|
if (long.TryParse(title, out number))
|
||||||
return title;
|
return title;
|
||||||
|
|
||||||
return NormalizeRegex.Replace(title, string.Empty).ToLower().RemoveAccent();
|
return ReplaceGermanUmlauts(NormalizeRegex.Replace(title, string.Empty).ToLower()).RemoveAccent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string NormalizeEpisodeTitle(string title)
|
public static string NormalizeEpisodeTitle(string title)
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
private readonly IMovieService _movieService;
|
private readonly IMovieService _movieService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
private static HashSet<ArabicRomanNumeral> _arabicRomanNumeralMappings;
|
private static HashSet<ArabicRomanNumeral> _arabicRomanNumeralMappings;
|
||||||
|
|
||||||
|
|
||||||
public ParsingService(IEpisodeService episodeService,
|
public ParsingService(IEpisodeService episodeService,
|
||||||
ISeriesService seriesService,
|
ISeriesService seriesService,
|
||||||
@@ -178,7 +179,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
return _movieService.FindByTitle(title);
|
return _movieService.FindByTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
var movies = _movieService.FindByTitle(parsedMovieInfo.MovieTitle);
|
var movies = _movieService.FindByTitle(parsedMovieInfo.MovieTitle, parsedMovieInfo.Year);
|
||||||
|
|
||||||
if (movies == null)
|
if (movies == null)
|
||||||
{
|
{
|
||||||
@@ -412,7 +413,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool TryGetMovieBySearchCriteria(ParsedMovieInfo parsedMovieInfo, SearchCriteriaBase searchCriteria, out Movie possibleMovie)
|
private bool TryGetMovieBySearchCriteria(ParsedMovieInfo parsedMovieInfo, SearchCriteriaBase searchCriteria, out Movie possibleMovie)
|
||||||
{
|
{
|
||||||
possibleMovie = null;
|
possibleMovie = null;
|
||||||
List<string> possibleTitles = new List<string>();
|
List<string> possibleTitles = new List<string>();
|
||||||
@@ -424,6 +425,8 @@ namespace NzbDrone.Core.Parser
|
|||||||
possibleTitles.Add(altTitle.CleanSeriesTitle());
|
possibleTitles.Add(altTitle.CleanSeriesTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string cleanTitle = parsedMovieInfo.MovieTitle.CleanSeriesTitle();
|
||||||
|
|
||||||
foreach (string title in possibleTitles)
|
foreach (string title in possibleTitles)
|
||||||
{
|
{
|
||||||
if (title == parsedMovieInfo.MovieTitle.CleanSeriesTitle())
|
if (title == parsedMovieInfo.MovieTitle.CleanSeriesTitle())
|
||||||
@@ -436,12 +439,14 @@ namespace NzbDrone.Core.Parser
|
|||||||
string arabicNumeral = numeralMapping.ArabicNumeralAsString;
|
string arabicNumeral = numeralMapping.ArabicNumeralAsString;
|
||||||
string romanNumeral = numeralMapping.RomanNumeralLowerCase;
|
string romanNumeral = numeralMapping.RomanNumeralLowerCase;
|
||||||
|
|
||||||
|
_logger.Debug(cleanTitle);
|
||||||
|
|
||||||
if (title.Replace(arabicNumeral, romanNumeral) == parsedMovieInfo.MovieTitle.CleanSeriesTitle())
|
if (title.Replace(arabicNumeral, romanNumeral) == parsedMovieInfo.MovieTitle.CleanSeriesTitle())
|
||||||
{
|
{
|
||||||
possibleMovie = searchCriteria.Movie;
|
possibleMovie = searchCriteria.Movie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title.Replace(romanNumeral, arabicNumeral) == parsedMovieInfo.MovieTitle.CleanSeriesTitle())
|
if (title == parsedMovieInfo.MovieTitle.CleanSeriesTitle().Replace(arabicNumeral, romanNumeral))
|
||||||
{
|
{
|
||||||
possibleMovie = searchCriteria.Movie;
|
possibleMovie = searchCriteria.Movie;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,12 +98,18 @@ namespace NzbDrone.Core.Tv
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DateTime.Now >= MinimumAvailabilityDate.AddDays((double)delay);
|
if (MinimumAvailabilityDate == DateTime.MinValue || MinimumAvailabilityDate == DateTime.MaxValue)
|
||||||
|
{
|
||||||
|
return DateTime.Now >= MinimumAvailabilityDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return DateTime.Now >= MinimumAvailabilityDate.AddDays((double)delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Format("[{0}][{1}]", ImdbId, Title.NullSafe());
|
return string.Format("[{0}][{1} ({2})]", ImdbId, Title.NullSafe(), Year.NullSafe());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -238,29 +238,31 @@ namespace NzbDrone.Core.Tv
|
|||||||
cleanTitleWithArabicNumbers = cleanTitleWithArabicNumbers.Replace(romanNumber, arabicNumber);
|
cleanTitleWithArabicNumbers = cleanTitleWithArabicNumbers.Replace(romanNumber, arabicNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<Movie> results = Query.Where(s => s.CleanTitle == cleanTitle);
|
Movie result = Query.Where(s => s.CleanTitle == cleanTitle).FirstWithYear(year);
|
||||||
|
|
||||||
if (results == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
results = Query.Where(movie => movie.CleanTitle == cleanTitleWithArabicNumbers) ??
|
result = Query.Where(movie => movie.CleanTitle == cleanTitleWithArabicNumbers).FirstWithYear(year) ??
|
||||||
Query.Where(movie => movie.CleanTitle == cleanTitleWithRomanNumbers);
|
Query.Where(movie => movie.CleanTitle == cleanTitleWithRomanNumbers).FirstWithYear(year);
|
||||||
|
|
||||||
if (results == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
IEnumerable<Movie> movies = All();
|
IEnumerable<Movie> movies = All();
|
||||||
Func<string, string> titleCleaner = title => CoreParser.CleanSeriesTitle(title.ToLower());
|
Func<string, string> titleCleaner = title => CoreParser.CleanSeriesTitle(title.ToLower());
|
||||||
Func<IEnumerable<string>, string, bool> altTitleComparer =
|
Func<IEnumerable<string>, string, bool> altTitleComparer =
|
||||||
(alternativeTitles, atitle) =>
|
(alternativeTitles, atitle) =>
|
||||||
alternativeTitles.Any(altTitle => altTitle == titleCleaner(atitle));
|
alternativeTitles.Any(altTitle => titleCleaner(altTitle) == atitle);
|
||||||
|
|
||||||
results = movies.Where(m => altTitleComparer(m.AlternativeTitles, cleanTitle) ||
|
result = movies.Where(m => altTitleComparer(m.AlternativeTitles, cleanTitle) ||
|
||||||
altTitleComparer(m.AlternativeTitles, cleanTitleWithRomanNumbers) ||
|
altTitleComparer(m.AlternativeTitles, cleanTitleWithRomanNumbers) ||
|
||||||
altTitleComparer(m.AlternativeTitles, cleanTitleWithArabicNumbers));
|
altTitleComparer(m.AlternativeTitles, cleanTitleWithArabicNumbers)).FirstWithYear(year);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return year.HasValue
|
return result;
|
||||||
|
/*return year.HasValue
|
||||||
? results?.FirstOrDefault(movie => movie.Year == year.Value)
|
? results?.FirstOrDefault(movie => movie.Year == year.Value)
|
||||||
: results?.FirstOrDefault();
|
: results?.FirstOrDefault();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public Movie FindByTmdbId(int tmdbid)
|
public Movie FindByTmdbId(int tmdbid)
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ namespace NzbDrone.Core.Tv
|
|||||||
private readonly IBuildFileNames _fileNameBuilder;
|
private readonly IBuildFileNames _fileNameBuilder;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
|
||||||
public MovieService(IMovieRepository movieRepository,
|
public MovieService(IMovieRepository movieRepository,
|
||||||
IEventAggregator eventAggregator,
|
IEventAggregator eventAggregator,
|
||||||
ISceneMappingService sceneMappingService,
|
ISceneMappingService sceneMappingService,
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Datastore.Extensions;
|
||||||
|
using Marr.Data.QGen;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
using NzbDrone.Core.Parser.RomanNumerals;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using CoreParser = NzbDrone.Core.Parser.Parser;
|
||||||
|
namespace NzbDrone.Core
|
||||||
|
{
|
||||||
|
public static class QueryExtensions
|
||||||
|
{
|
||||||
|
public static Movie FirstWithYear(this SortBuilder<Movie> query, int? year)
|
||||||
|
{
|
||||||
|
return year.HasValue ? query.FirstOrDefault(movie => movie.Year == year) : query.FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EnumerableExtensions
|
||||||
|
{
|
||||||
|
public static Movie FirstWithYear(this IEnumerable<Movie> query, int? year)
|
||||||
|
{
|
||||||
|
return year.HasValue ? query.FirstOrDefault(movie => movie.Year == year) : query.FirstOrDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using Mono.Unix;
|
using Mono.Unix;
|
||||||
using Mono.Unix.Native;
|
using Mono.Unix.Native;
|
||||||
using NLog;
|
using NLog;
|
||||||
@@ -17,21 +18,50 @@ namespace NzbDrone.Mono.Disk
|
|||||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(DiskProvider));
|
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(DiskProvider));
|
||||||
|
|
||||||
private readonly IProcMountProvider _procMountProvider;
|
private readonly IProcMountProvider _procMountProvider;
|
||||||
private readonly NzbDrone.Mono.Disk.ISymbolicLinkResolver _symLinkResolver;
|
private readonly ISymbLinkResolver _symLinkResolver;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
// Mono supports sending -1 for a uint to indicate that the owner or group should not be set
|
// Mono supports sending -1 for a uint to indicate that the owner or group should not be set
|
||||||
// `unchecked((uint)-1)` and `uint.MaxValue` are the same thing.
|
// `unchecked((uint)-1)` and `uint.MaxValue` are the same thing.
|
||||||
private const uint UNCHANGED_ID = uint.MaxValue;
|
private const uint UNCHANGED_ID = uint.MaxValue;
|
||||||
|
|
||||||
public DiskProvider(IProcMountProvider procMountProvider, NzbDrone.Mono.Disk.ISymbolicLinkResolver symLinkResolver)
|
public DiskProvider(IProcMountProvider procMountProvider, ISymbLinkResolver symLinkResolver, Logger logger)
|
||||||
{
|
{
|
||||||
_procMountProvider = procMountProvider;
|
_procMountProvider = procMountProvider;
|
||||||
_symLinkResolver = symLinkResolver;
|
_symLinkResolver = symLinkResolver;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IMount GetMount(string path)
|
public override IMount GetMount(string path)
|
||||||
{
|
{
|
||||||
path = _symLinkResolver.GetCompleteRealPath(path);
|
if (path == null) return null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] dirs;
|
||||||
|
int lastIndex;
|
||||||
|
GetPathComponents(path, out dirs, out lastIndex);
|
||||||
|
|
||||||
|
var realPath = new StringBuilder();
|
||||||
|
if (dirs.Length > 0)
|
||||||
|
{
|
||||||
|
var dir = UnixPath.IsPathRooted(path) ? "/" : "";
|
||||||
|
dir += dirs[0];
|
||||||
|
realPath.Append(GetRealPath(dir));
|
||||||
|
}
|
||||||
|
for (var i = 1; i < lastIndex; ++i)
|
||||||
|
{
|
||||||
|
realPath.Append("/").Append(dirs[i]);
|
||||||
|
var realSubPath = GetRealPath(realPath.ToString());
|
||||||
|
realPath.Remove(0, realPath.Length);
|
||||||
|
realPath.Append(realSubPath);
|
||||||
|
}
|
||||||
|
path = realPath.ToString();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Debug(ex, string.Format("Failed to check for symlinks in the path {0}", path));
|
||||||
|
}
|
||||||
|
|
||||||
return base.GetMount(path);
|
return base.GetMount(path);
|
||||||
}
|
}
|
||||||
@@ -219,5 +249,65 @@ namespace NzbDrone.Mono.Disk
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void GetPathComponents(string path, out string[] components, out int lastIndex)
|
||||||
|
{
|
||||||
|
var dirs = path.Split(UnixPath.DirectorySeparatorChar);
|
||||||
|
var target = 0;
|
||||||
|
for (var i = 0; i < dirs.Length; ++i)
|
||||||
|
{
|
||||||
|
if (dirs[i] == "." || dirs[i] == string.Empty)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirs[i] == "..")
|
||||||
|
{
|
||||||
|
if (target != 0)
|
||||||
|
{
|
||||||
|
target--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
target++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dirs[target++] = dirs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
components = dirs;
|
||||||
|
lastIndex = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetRealPath(string path)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
var link = UnixPath.TryReadLink(path);
|
||||||
|
|
||||||
|
if (link == null)
|
||||||
|
{
|
||||||
|
var errno = Stdlib.GetLastError();
|
||||||
|
if (errno != Errno.EINVAL)
|
||||||
|
{
|
||||||
|
_logger.Trace("Checking path {0} for symlink returned error {1}, assuming it's not a symlink.", path, errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UnixPath.IsPathRooted(link))
|
||||||
|
{
|
||||||
|
path = link;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = UnixPath.GetDirectoryName(path) + UnixPath.DirectorySeparatorChar + link;
|
||||||
|
path = UnixPath.GetCanonicalPath(path);
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,23 +6,23 @@ using NLog;
|
|||||||
|
|
||||||
namespace NzbDrone.Mono.Disk
|
namespace NzbDrone.Mono.Disk
|
||||||
{
|
{
|
||||||
public interface ISymbolicLinkResolver
|
public interface ISymbLinkResolver
|
||||||
{
|
{
|
||||||
string GetCompleteRealPath(string path);
|
string GetCompletePath(string path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mono's own implementation doesn't handle exceptions very well.
|
// Mono's own implementation doesn't handle exceptions very well.
|
||||||
// All of this code was copied from mono with minor changes.
|
// All of this code was copied from mono with minor changes.
|
||||||
public class SymbolicLinkResolver : ISymbolicLinkResolver
|
public class SymbLinkResolver : ISymbLinkResolver
|
||||||
{
|
{
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public SymbolicLinkResolver(Logger logger)
|
public SymbLinkResolver(Logger logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetCompleteRealPath(string path)
|
public string GetCompletePath(string path)
|
||||||
{
|
{
|
||||||
if (path == null) return null;
|
if (path == null) return null;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
var Backgrid = require('backgrid');
|
||||||
|
var Marionette = require('marionette');
|
||||||
|
require('bootstrap');
|
||||||
|
|
||||||
|
module.exports = Backgrid.Cell.extend({
|
||||||
|
className : 'edition-cell',
|
||||||
|
//template : 'Cells/EditionCellTemplate',
|
||||||
|
|
||||||
|
render : function() {
|
||||||
|
|
||||||
|
var flags = this.model.get("indexerFlags");
|
||||||
|
if (!flags) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
var html = "";
|
||||||
|
|
||||||
|
if (flags) {
|
||||||
|
_.each(flags, function(flag){
|
||||||
|
var addon = "";
|
||||||
|
var title = "";
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case "G_Freeleech":
|
||||||
|
addon = "⬇";
|
||||||
|
title = "Freeleech";
|
||||||
|
break;
|
||||||
|
case "G_Halfleech":
|
||||||
|
addon = "⇩";
|
||||||
|
title = "50% Freeleech";
|
||||||
|
break;
|
||||||
|
case "G_DoubleUpload":
|
||||||
|
addon = "⬆";
|
||||||
|
title = "Double upload";
|
||||||
|
break;
|
||||||
|
case "PTP_Golden":
|
||||||
|
addon = "🍿";
|
||||||
|
title = "Golden";
|
||||||
|
break;
|
||||||
|
case "PTP_Approved":
|
||||||
|
addon = "✔";
|
||||||
|
title = "Approved by PTP"
|
||||||
|
break;
|
||||||
|
case "HDB_Internal":
|
||||||
|
addon = "⭐️";
|
||||||
|
title = "HDBits Internal";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (addon != "") {
|
||||||
|
html += "<span title='{0}'>{1}</span> ".format(title, addon);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$el.html(html);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -9,6 +9,9 @@ module.exports = NzbDroneCell.extend({
|
|||||||
var title = this.model.get('title');
|
var title = this.model.get('title');
|
||||||
var infoUrl = this.model.get('infoUrl');
|
var infoUrl = this.model.get('infoUrl');
|
||||||
|
|
||||||
|
var flags = this.model.get("indexerFlags");
|
||||||
|
|
||||||
|
|
||||||
if (infoUrl) {
|
if (infoUrl) {
|
||||||
this.$el.html('<a href="{0}">{1}</a>'.format(infoUrl, title));
|
this.$el.html('<a href="{0}">{1}</a>'.format(infoUrl, title));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ var AgeCell = require('../../Release/AgeCell');
|
|||||||
var ProtocolCell = require('../../Release/ProtocolCell');
|
var ProtocolCell = require('../../Release/ProtocolCell');
|
||||||
var PeersCell = require('../../Release/PeersCell');
|
var PeersCell = require('../../Release/PeersCell');
|
||||||
var EditionCell = require('../../Cells/EditionCell');
|
var EditionCell = require('../../Cells/EditionCell');
|
||||||
|
var IndexerFlagsCell = require('../../Cells/IndexerFlagsCell');
|
||||||
|
|
||||||
module.exports = Marionette.Layout.extend({
|
module.exports = Marionette.Layout.extend({
|
||||||
template : 'Movies/Search/ManualLayoutTemplate',
|
template : 'Movies/Search/ManualLayoutTemplate',
|
||||||
@@ -39,6 +40,11 @@ module.exports = Marionette.Layout.extend({
|
|||||||
cell : EditionCell,
|
cell : EditionCell,
|
||||||
title : "Edition",
|
title : "Edition",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name : 'flags',
|
||||||
|
label : 'Flags',
|
||||||
|
cell : IndexerFlagsCell,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name : 'indexer',
|
name : 'indexer',
|
||||||
label : 'Indexer',
|
label : 'Indexer',
|
||||||
|
|||||||
@@ -33,6 +33,33 @@ var Collection = PagableCollection.extend({
|
|||||||
"edition" : {
|
"edition" : {
|
||||||
sortKey : "edition"
|
sortKey : "edition"
|
||||||
},
|
},
|
||||||
|
"flags" : {
|
||||||
|
sortValue : function(model) {
|
||||||
|
var flags = model.get("indexerFlags");
|
||||||
|
var weight = 0;
|
||||||
|
if (flags) {
|
||||||
|
_.each(flags, function(flag){
|
||||||
|
var addon = "";
|
||||||
|
var title = "";
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case "G_Halfleech":
|
||||||
|
weight += 1;
|
||||||
|
break;
|
||||||
|
case "G_Freeleech":
|
||||||
|
case "G_DoubleUpload":
|
||||||
|
case "PTP_Approved":
|
||||||
|
case "PTP_Golden":
|
||||||
|
case "HDB_Internal":
|
||||||
|
weight += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
},
|
||||||
'download' : {
|
'download' : {
|
||||||
sortKey : 'releaseWeight'
|
sortKey : 'releaseWeight'
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ var QualityCell = require('../Cells/QualityCell');
|
|||||||
var ApprovalStatusCell = require('../Cells/ApprovalStatusCell');
|
var ApprovalStatusCell = require('../Cells/ApprovalStatusCell');
|
||||||
var LoadingView = require('../Shared/LoadingView');
|
var LoadingView = require('../Shared/LoadingView');
|
||||||
var EditionCell = require('../Cells/EditionCell');
|
var EditionCell = require('../Cells/EditionCell');
|
||||||
|
var ReleaseTitleCell = require("../Cells/ReleaseTitleCell");
|
||||||
|
|
||||||
module.exports = Marionette.Layout.extend({
|
module.exports = Marionette.Layout.extend({
|
||||||
template : 'Release/ReleaseLayoutTemplate',
|
template : 'Release/ReleaseLayoutTemplate',
|
||||||
@@ -34,7 +35,7 @@ module.exports = Marionette.Layout.extend({
|
|||||||
name : 'title',
|
name : 'title',
|
||||||
label : 'Title',
|
label : 'Title',
|
||||||
sortable : true,
|
sortable : true,
|
||||||
cell : Backgrid.StringCell
|
cell : ReleaseTitleCell
|
||||||
},
|
},
|
||||||
/*{
|
/*{
|
||||||
name : 'episodeNumbers',
|
name : 'episodeNumbers',
|
||||||
|
|||||||
@@ -25,6 +25,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="col-sm-3 control-label">Prefer Special Indexer Flags</label>
|
||||||
|
<div class="col-sm-1 col-sm-push-2 help-inline">
|
||||||
|
<i class="icon-sonarr-form-info" title="If set to yes, the more indexer flags (such as Golden, Approved, Internal, Freeleech, Double upload, etc.) a release has the more priorized it will be. Quality and Preferred words would still come first."/>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 col-sm-pull-1">
|
||||||
|
<div class="input-group">
|
||||||
|
<label class="checkbox toggle well">
|
||||||
|
<input type="checkbox" name="preferIndexerFlags" class="x-completed-download-handling"/>
|
||||||
|
<p>
|
||||||
|
<span>Yes</span>
|
||||||
|
<span>No</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="btn btn-primary slide-button"/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group advanced-setting">
|
<div class="form-group advanced-setting">
|
||||||
<label class="col-sm-3 control-label">RSS Sync Interval</label>
|
<label class="col-sm-3 control-label">RSS Sync Interval</label>
|
||||||
|
|
||||||
@@ -39,7 +60,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group advanced-setting">
|
<div class="form-group advanced-setting">
|
||||||
<label class="col-sm-3 control-label">Whitelisted Subtitle Tags Tags</label>
|
<label class="col-sm-3 control-label">Whitelisted Subtitle Tags</label>
|
||||||
<div class="col-sm-1 col-sm-push-2 help-inline">
|
<div class="col-sm-1 col-sm-push-2 help-inline">
|
||||||
<i class="icon-sonarr-form-info" title="All subtitle tags set here will not be considered hardcoded (e.g. dksub). This field is caseinsensitive. Tags must be put in singular (dksub instead of dksubs)."/>
|
<i class="icon-sonarr-form-info" title="All subtitle tags set here will not be considered hardcoded (e.g. dksub). This field is caseinsensitive. Tags must be put in singular (dksub instead of dksubs)."/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-sm-3 control-label">Filter Series Tags</label>
|
<label class="col-sm-3 control-label">Filter Movies Tags</label>
|
||||||
|
|
||||||
<div class="col-sm-5">
|
<div class="col-sm-5">
|
||||||
<input type="text" class="form-control x-tags">
|
<input type="text" class="form-control x-tags">
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ module.exports = Marionette.AppRouter.extend({
|
|||||||
|
|
||||||
if (window.NzbDrone.Analytics && window.Piwik) {
|
if (window.NzbDrone.Analytics && window.Piwik) {
|
||||||
try {
|
try {
|
||||||
var piwik = window.Piwik.getTracker(window.location.protocol + '//piwik.nzbdrone.com/piwik.php', 1);
|
var piwik = window.Piwik.getTracker(window.location.protocol + '//radarr.video/piwik/piwik.php', 1);
|
||||||
piwik.setReferrerUrl('');
|
piwik.setReferrerUrl('');
|
||||||
piwik.setCustomUrl('http://local' + window.location.pathname);
|
piwik.setCustomUrl('http://local' + window.location.pathname);
|
||||||
piwik.setCustomVariable(1, 'version', window.NzbDrone.Version, 'page');
|
piwik.setCustomVariable(1, 'version', window.NzbDrone.Version, 'page');
|
||||||
@@ -60,7 +60,7 @@ module.exports = Marionette.AppRouter.extend({
|
|||||||
window.localStorage.clear();
|
window.localStorage.clear();
|
||||||
Config.setValue("pageSize", pageSize);
|
Config.setValue("pageSize", pageSize);
|
||||||
// Remove above when out of pre-release :)
|
// Remove above when out of pre-release :)
|
||||||
|
|
||||||
this.pendingUpdate = true;
|
this.pendingUpdate = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
if(window.NzbDrone.Analytics) {
|
if(window.NzbDrone.Analytics) {
|
||||||
var d = document;
|
var d = document;
|
||||||
var g = d.createElement('script');
|
var g = d.createElement('script');
|
||||||
@@ -7,6 +6,6 @@ if(window.NzbDrone.Analytics) {
|
|||||||
g.type = 'text/javascript';
|
g.type = 'text/javascript';
|
||||||
g.async = true;
|
g.async = true;
|
||||||
g.defer = true;
|
g.defer = true;
|
||||||
g.src = '//piwik.sonarr.tv/piwik.js';
|
g.src = 'https://radarr.video/piwik/piwik.js';
|
||||||
s.parentNode.insertBefore(g, s);
|
s.parentNode.insertBefore(g, s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
|
|
||||||
<!-- Windows Phone -->
|
<!-- Windows Phone -->
|
||||||
<meta name="msapplication-navbutton-color" content="#272727"/>
|
<meta name="msapplication-navbutton-color" content="#272727"/>
|
||||||
|
<!-- Piwik -->
|
||||||
|
|
||||||
|
<!-- End Piwik Code -->
|
||||||
|
|
||||||
<!-- Generated by http://realfavicongenerator.net/ -->
|
<!-- Generated by http://realfavicongenerator.net/ -->
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/Content/Images/favicon/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/Content/Images/favicon/apple-touch-icon.png">
|
||||||
|
|||||||
Reference in New Issue
Block a user