2014-05-13 20:57:46 +03:00
|
|
|
using System;
|
2015-07-13 20:26:00 +02:00
|
|
|
using System.Collections.Generic;
|
2014-05-13 20:57:46 +03:00
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
using System.Xml.Linq;
|
2015-02-12 08:42:31 +02:00
|
|
|
using NzbDrone.Common.Extensions;
|
2014-05-13 20:57:46 +03:00
|
|
|
using NzbDrone.Core.Parser.Model;
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.Indexers
|
|
|
|
{
|
|
|
|
public class TorrentRssParser : RssParser
|
|
|
|
{
|
|
|
|
// Parse various seeder/leecher/peers formats in the description element to determine number of seeders.
|
|
|
|
public Boolean ParseSeedersInDescription { get; set; }
|
|
|
|
|
2015-02-12 08:42:31 +02:00
|
|
|
// Use the specified element name to determine the size
|
|
|
|
public String SizeElementName { get; set; }
|
|
|
|
|
2014-05-13 20:57:46 +03:00
|
|
|
public TorrentRssParser()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-07-13 20:26:00 +02:00
|
|
|
public IEnumerable<XElement> GetItems(IndexerResponse indexerResponse)
|
|
|
|
{
|
|
|
|
var document = LoadXmlDocument(indexerResponse);
|
|
|
|
var items = GetItems(document);
|
|
|
|
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
2014-05-13 20:57:46 +03:00
|
|
|
protected override ReleaseInfo CreateNewReleaseInfo()
|
|
|
|
{
|
|
|
|
return new TorrentInfo();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override ReleaseInfo ProcessItem(XElement item, ReleaseInfo releaseInfo)
|
|
|
|
{
|
|
|
|
var result = base.ProcessItem(item, releaseInfo) as TorrentInfo;
|
|
|
|
|
|
|
|
result.InfoHash = GetInfoHash(item);
|
|
|
|
result.MagnetUrl = GetMagnetUrl(item);
|
2014-12-20 03:21:03 +02:00
|
|
|
result.Seeders = GetSeeders(item);
|
2014-05-13 20:57:46 +03:00
|
|
|
result.Peers = GetPeers(item);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual String GetInfoHash(XElement item)
|
|
|
|
{
|
2015-05-14 22:57:45 +02:00
|
|
|
var magnetUrl = GetMagnetUrl(item);
|
|
|
|
if (magnetUrl.IsNotNullOrWhiteSpace())
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var magnetLink = new MonoTorrent.MagnetLink(magnetUrl);
|
|
|
|
return magnetLink.InfoHash.ToHex();
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-13 20:57:46 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual String GetMagnetUrl(XElement item)
|
|
|
|
{
|
2015-05-14 22:57:45 +02:00
|
|
|
var downloadUrl = GetDownloadUrl(item);
|
|
|
|
if (downloadUrl.StartsWith("magnet:"))
|
|
|
|
{
|
|
|
|
return downloadUrl;
|
|
|
|
}
|
|
|
|
|
2014-05-13 20:57:46 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual Int32? GetSeeders(XElement item)
|
|
|
|
{
|
2015-07-03 21:21:49 +02:00
|
|
|
if (ParseSeedersInDescription && item.Element("description") != null)
|
2014-05-13 20:57:46 +03:00
|
|
|
{
|
2014-12-21 21:02:02 +02:00
|
|
|
var matchSeeders = ParseSeedersRegex.Match(item.Element("description").Value);
|
2014-05-13 20:57:46 +03:00
|
|
|
|
2014-12-21 21:02:02 +02:00
|
|
|
if (matchSeeders.Success)
|
2014-05-13 20:57:46 +03:00
|
|
|
{
|
2014-12-21 21:02:02 +02:00
|
|
|
return Int32.Parse(matchSeeders.Groups["value"].Value);
|
|
|
|
}
|
|
|
|
|
|
|
|
var matchPeers = ParsePeersRegex.Match(item.Element("description").Value);
|
|
|
|
var matchLeechers = ParseLeechersRegex.Match(item.Element("description").Value);
|
|
|
|
|
|
|
|
if (matchPeers.Success && matchLeechers.Success)
|
|
|
|
{
|
|
|
|
return Int32.Parse(matchPeers.Groups["value"].Value) - Int32.Parse(matchLeechers.Groups["value"].Value);
|
2014-05-13 20:57:46 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual Int32? GetPeers(XElement item)
|
|
|
|
{
|
2015-07-03 21:21:49 +02:00
|
|
|
if (ParseSeedersInDescription && item.Element("description") != null)
|
2014-05-13 20:57:46 +03:00
|
|
|
{
|
2014-12-21 21:02:02 +02:00
|
|
|
var matchPeers = ParsePeersRegex.Match(item.Element("description").Value);
|
|
|
|
|
|
|
|
if (matchPeers.Success)
|
|
|
|
{
|
|
|
|
return Int32.Parse(matchPeers.Groups["value"].Value);
|
|
|
|
}
|
|
|
|
|
|
|
|
var matchSeeders = ParseSeedersRegex.Match(item.Element("description").Value);
|
|
|
|
var matchLeechers = ParseLeechersRegex.Match(item.Element("description").Value);
|
2014-05-13 20:57:46 +03:00
|
|
|
|
2014-12-21 21:02:02 +02:00
|
|
|
if (matchSeeders.Success && matchLeechers.Success)
|
2014-05-13 20:57:46 +03:00
|
|
|
{
|
2014-12-21 21:02:02 +02:00
|
|
|
return Int32.Parse(matchSeeders.Groups["value"].Value) + Int32.Parse(matchLeechers.Groups["value"].Value);
|
2014-05-13 20:57:46 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-02-12 08:42:31 +02:00
|
|
|
protected override long GetSize(XElement item)
|
|
|
|
{
|
|
|
|
var size = base.GetSize(item);
|
|
|
|
if (size == 0 && SizeElementName.IsNotNullOrWhiteSpace())
|
|
|
|
{
|
|
|
|
if (item.Element(SizeElementName) != null)
|
|
|
|
{
|
|
|
|
size = ParseSize(item.Element(SizeElementName).Value, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2014-05-13 20:57:46 +03:00
|
|
|
private static readonly Regex ParseSeedersRegex = new Regex(@"(Seeder)s?:\s+(?<value>\d+)|(?<value>\d+)\s+(seeder)s?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
2014-12-21 21:02:02 +02:00
|
|
|
private static readonly Regex ParseLeechersRegex = new Regex(@"(Leecher)s?:\s+(?<value>\d+)|(?<value>\d+)\s+(leecher)s?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
|
|
private static readonly Regex ParsePeersRegex = new Regex(@"(Peer)s?:\s+(?<value>\d+)|(?<value>\d+)\s+(peer)s?", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
2014-05-13 20:57:46 +03:00
|
|
|
}
|
|
|
|
}
|