AHD, PTP and HDB support the new indexer flags too now! Indexer flags can be preferred over other releases.

pull/1410/head
Leonardo Galli 8 years ago committed by GitHub
parent 10091b9454
commit 433ae019de

@ -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,
}; };
} }

File diff suppressed because one or more lines are too long

@ -0,0 +1,86 @@
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());
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);
}
[Test]
public void should_warn_on_wrong_passkey()
{
var responseJson = new { status = 5, message = "Invalid authentication credentials" }.ToJson();
Mocker.GetMock<IHttpClient>()
.Setup(v => v.Execute(It.IsAny<HttpRequest>()))
.Returns<HttpRequest>(r => new HttpResponse(r, new HttpHeader(),
Encoding.UTF8.GetBytes(responseJson)));
var torrents = Subject.FetchRecent();
torrents.Should().BeEmpty();
ExceptionVerification.ExpectedWarns(1);
}
}
}

@ -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}" />

@ -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))

@ -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,11 +55,11 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
{ {
var id = torrent.Id; var id = torrent.Id;
var title = torrent.ReleaseName; var title = torrent.ReleaseName;
IndexerFlags flags = 0; IndexerFlags flags = 0;
if (torrent.GoldenPopcorn) if (torrent.GoldenPopcorn)
{ {
flags |= IndexerFlags.PTP_Golden;//title = $"{title} 🍿"; flags |= IndexerFlags.PTP_Golden;//title = $"{title} 🍿";
} }
if (torrent.Checked) if (torrent.Checked)
@ -67,52 +67,57 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
flags |= IndexerFlags.PTP_Approved;//title = $"{title} ✔"; flags |= IndexerFlags.PTP_Approved;//title = $"{title} ✔";
} }
// Only add approved torrents if (torrent.FreeleechType == "Freeleech")
if (_settings.RequireApproved && torrent.Checked)
{ {
torrentInfos.Add(new PassThePopcornInfo() flags |= IndexerFlags.G_Freeleech;
{
Guid = string.Format("PassThePopcorn-{0}", id),
Title = title,
Size = long.Parse(torrent.Size),
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
InfoUrl = GetInfoUrl(result.GroupId, id),
Seeders = int.Parse(torrent.Seeders),
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
PublishDate = torrent.UploadTime.ToUniversalTime(),
Golden = torrent.GoldenPopcorn,
Scene = torrent.Scene,
Approved = torrent.Checked,
ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0),
IndexerFlags = flags
});
} }
// Add all torrents // Only add approved torrents
else if (!_settings.RequireApproved) 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,
IndexerFlags = flags Approved = torrent.Checked,
}); ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0),
} IndexerFlags = flags
// Don't add any torrents });
else if (_settings.RequireApproved && !torrent.Checked) }
{
continue; // Add all torrents
} else if (!_settings.RequireApproved)
{
torrentInfos.Add(new PassThePopcornInfo()
{
Guid = string.Format("PassThePopcorn-{0}", id),
Title = title,
Size = long.Parse(torrent.Size),
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
InfoUrl = GetInfoUrl(result.GroupId, id),
Seeders = int.Parse(torrent.Seeders),
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
PublishDate = torrent.UploadTime.ToUniversalTime(),
Golden = torrent.GoldenPopcorn,
Scene = torrent.Scene,
Approved = torrent.Checked,
ImdbId = (result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0),
IndexerFlags = flags
});
}
// 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;
} }
} }

@ -97,7 +97,11 @@ namespace NzbDrone.Core.Parser.Model
[Flags] [Flags]
public enum IndexerFlags public enum IndexerFlags
{ {
PTP_Golden = 1, //PTP G_Freeleech = 1, //General
PTP_Approved = 2, //PTP 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
} }
} }

@ -0,0 +1,58 @@
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"
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;
}
});

@ -10,22 +10,7 @@ module.exports = NzbDroneCell.extend({
var infoUrl = this.model.get('infoUrl'); var infoUrl = this.model.get('infoUrl');
var flags = this.model.get("indexerFlags"); var flags = this.model.get("indexerFlags");
if (flags) {
_.each(flags, function(flag){
var addon = "";
switch (flag) {
case "PTP_Golden":
addon = "🍿";
break;
case "PTP_Approved":
addon = "✔";
break;
}
title += addon;
});
}
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));

@ -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,7 +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("./ReleaseTitleCell"); var ReleaseTitleCell = require("../Cells/ReleaseTitleCell");
module.exports = Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
template : 'Release/ReleaseLayoutTemplate', template : 'Release/ReleaseLayoutTemplate',

@ -1,33 +0,0 @@
var _ = require('underscore');
var Backgrid = require('backgrid');
var FormatHelpers = require('../Shared/FormatHelpers');
module.exports = Backgrid.Cell.extend({
className : 'title-cell',
render : function() {
debugger;
var title = this.model.get('title');
var flags = this.model.get("indexerFlags");
if (flags) {
_.each(flags, function(flag){
var addon = "";
debugger;
switch (flag) {
case "PTP_Golden":
addon = "🍿";
break;
case "PTP_Approved":
addon = "✔";
break;
}
title += addon;
});
}
this.$el.html(title);
return this;
}
});

@ -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>

Loading…
Cancel
Save