1
0
Fork 0
mirror of https://github.com/Jackett/Jackett synced 2025-03-06 03:38:31 +00:00

core: generate magnet link from infohash and vice versa. resolves #8590 (#10087)

* global list of public trackers
* infohash => magnet link (only in public trackers)
* magnet link => infohash
This commit is contained in:
Diego Heras 2020-11-02 17:43:13 +01:00 committed by GitHub
parent 9bd8f4d014
commit 14fdea164c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 141 additions and 1 deletions

View file

@ -296,6 +296,14 @@ namespace Jackett.Common.Indexers
if (r.PublishDate > DateTime.Now)
r.PublishDate = DateTime.Now;
// generate magnet link from info hash (not allowed for private sites)
if (r.MagnetUri == null && !string.IsNullOrWhiteSpace(r.InfoHash) && Type != "private")
r.MagnetUri = MagnetUtil.InfoHashToPublicMagnet(r.InfoHash, r.Title);
// generate info hash from magnet link
if (r.MagnetUri != null && string.IsNullOrWhiteSpace(r.InfoHash))
r.InfoHash = MagnetUtil.MagnetToInfoHash(r.MagnetUri);
return r;
});
return fixedResults;

View file

@ -0,0 +1,48 @@
using System;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using Jackett.Common.Helpers;
namespace Jackett.Common.Utils
{
public static class MagnetUtil
{
// Update best trackers from https://github.com/ngosang/trackerslist
private static readonly NameValueCollection _Trackers = new NameValueCollection
{
{"tr", "udp://tracker.opentrackr.org:1337/announce"},
{"tr", "udp://tracker.coppersurfer.tk:6969/announce"},
{"tr", "udp://9.rarbg.to:2710/announce"},
{"tr", "udp://tracker.internetwarriors.net:1337/announce"},
{"tr", "udp://tracker.cyberia.is:6969/announce"},
{"tr", "udp://exodus.desync.com:6969/announce"},
{"tr", "udp://explodie.org:6969/announce"},
{"tr", "http://tracker1.itzmx.com:8080/announce"},
{"tr", "udp://tracker.tiny-vps.com:6969/announce"},
{"tr", "udp://open.stealth.si:80/announce"}
};
private static readonly string _TrackersEncoded = _Trackers.GetQueryString();
public static Uri InfoHashToPublicMagnet(string infoHash, string title)
{
if (string.IsNullOrWhiteSpace(infoHash) || string.IsNullOrWhiteSpace(title))
return null;
return new Uri($"magnet:?xt=urn:btih:{infoHash}&dn={WebUtilityHelpers.UrlEncode(title, Encoding.UTF8)}&{_TrackersEncoded}");
}
public static string MagnetToInfoHash(Uri magnet)
{
try
{
var xt = ParseUtil.GetArgumentFromQueryString(magnet.ToString(), "xt");
return xt.Split(':').Last(); // remove prefix urn:btih:
}
catch (Exception)
{
return null;
}
}
}
}

View file

@ -124,7 +124,7 @@ namespace Jackett.Test.Common.Indexers
}
[Test]
public void TestFixResults()
public void TestFixResultsOriginPublishDate()
{
var indexer = new TestWebIndexer();
var query = new TorznabQuery();
@ -144,6 +144,44 @@ namespace Jackett.Test.Common.Indexers
Assert.AreEqual(DateTime.Now.Year, fixedResults.First().PublishDate.Year);
}
[Test]
public void TestFixResultsMagnet()
{
var indexer = new TestWebIndexer();
var query = new TorznabQuery();
// get info_hash from magnet
var results = new List<ReleaseInfo>
{
new ReleaseInfo
{
MagnetUri = new Uri("magnet:?xt=urn:btih:3333333333333333333333333333333333333333&dn=Title&tr=udp%3A%2F%2Ftracker.com%3A6969")
}
};
Assert.AreEqual(null, results.First().InfoHash);
var fixedResults = indexer._FixResults(query, results).ToList();
Assert.AreEqual("3333333333333333333333333333333333333333", fixedResults.First().InfoHash);
// build magnet from info_hash (private site), not allowed
results = new List<ReleaseInfo>
{
new ReleaseInfo
{
Title = "Tracker Title",
InfoHash = "3333333333333333333333333333333333333333"
}
};
Assert.AreEqual(null, results.First().MagnetUri);
fixedResults = indexer._FixResults(query, results).ToList();
Assert.AreEqual(null, fixedResults.First().MagnetUri);
// build magnet from info_hash (public, semi-private sites)
indexer.SetType("public");
Assert.AreEqual(null, results.First().MagnetUri);
fixedResults = indexer._FixResults(query, results).ToList();
Assert.True(fixedResults.First().MagnetUri.ToString().Contains("3333333333333333333333333333333333333333"));
}
[Test]
public void TestAddCategoryMapping()
{

View file

@ -0,0 +1,45 @@
using System;
using Jackett.Common.Utils;
using NUnit.Framework;
using Assert = NUnit.Framework.Assert;
namespace Jackett.Test.Common.Utils
{
[TestFixture]
public class MagnetUtilTests
{
[Test]
public void TestInfoHashToPublicMagnet()
{
const string infoHash = "3333333333333333333333333333333333333333";
const string title = "Torrent Title 😀"; // with unicode characters
// TODO: I'm not sure if unicode characters must be encoded
// good magnet
var magnet = MagnetUtil.InfoHashToPublicMagnet(infoHash, title);
Assert.True(magnet.ToString().StartsWith("magnet:?xt=urn:btih:3333333333333333333333333333333333333333&dn=Torrent+Title+😀&tr="));
// bad magnet (no info hash)
magnet = MagnetUtil.InfoHashToPublicMagnet("", title);
Assert.AreEqual(null, magnet);
// bad magnet (no title)
magnet = MagnetUtil.InfoHashToPublicMagnet(infoHash, "");
Assert.AreEqual(null, magnet);
}
[Test]
public void TestMagnetToInfoHash()
{
// good magnet
var magnet = new Uri("magnet:?xt=urn:btih:3333333333333333333333333333333333333333&dn=Torrent+Title+😀&tr=udp%3A%2F%2Ftracker.com%3A6969%2Fannounce");
var infoHash = MagnetUtil.MagnetToInfoHash(magnet);
Assert.AreEqual("3333333333333333333333333333333333333333", infoHash);
// bad magnet
magnet = new Uri("magnet:?tr=udp%3A%2F%2Ftracker.com%3A6969%2Fannounce");
infoHash = MagnetUtil.MagnetToInfoHash(magnet);
Assert.AreEqual(null, infoHash);
}
}
}

View file

@ -44,6 +44,7 @@ namespace Jackett.Test.TestHelpers
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// public methods to test private methods
public void SetType(string type) => Type = type;
public IEnumerable<ReleaseInfo> _FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> results) =>
FilterResults(query, results);