2020-02-09 02:35:16 +00:00
|
|
|
using System;
|
2019-02-16 01:19:05 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Collections.Specialized;
|
2020-05-03 23:35:52 +00:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2019-02-16 01:19:05 +00:00
|
|
|
using System.Linq;
|
|
|
|
using System.Text;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using Jackett.Common.Models;
|
|
|
|
using Jackett.Common.Models.IndexerConfig;
|
|
|
|
using Jackett.Common.Services.Interfaces;
|
|
|
|
using Jackett.Common.Utils;
|
|
|
|
using Jackett.Common.Utils.Clients;
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
using NLog;
|
|
|
|
|
2020-02-09 02:35:16 +00:00
|
|
|
namespace Jackett.Common.Indexers
|
|
|
|
{
|
2020-05-03 23:35:52 +00:00
|
|
|
[ExcludeFromCodeCoverage]
|
2020-05-05 07:09:53 +00:00
|
|
|
public class TorrentsCSV : BaseWebIndexer
|
2020-02-09 02:35:16 +00:00
|
|
|
{
|
2020-06-07 00:11:41 +00:00
|
|
|
private string SearchEndpoint => SiteLink + "service/search";
|
2019-02-16 01:19:05 +00:00
|
|
|
|
2020-05-05 07:09:53 +00:00
|
|
|
private new ConfigurationData configData => base.configData;
|
|
|
|
|
2020-12-11 22:14:21 +00:00
|
|
|
public TorrentsCSV(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps,
|
|
|
|
ICacheService cs)
|
2020-05-11 19:59:28 +00:00
|
|
|
: base(id: "torrentscsv",
|
|
|
|
name: "Torrents.csv",
|
2020-05-05 07:09:53 +00:00
|
|
|
description: "Torrents.csv is a self-hostable, open source torrent search engine and database",
|
|
|
|
link: "https://torrents-csv.ml/",
|
2020-10-18 20:47:36 +00:00
|
|
|
caps: new TorznabCapabilities
|
|
|
|
{
|
|
|
|
TvSearchParams = new List<TvSearchParam>
|
|
|
|
{
|
|
|
|
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
|
|
|
|
},
|
|
|
|
MovieSearchParams = new List<MovieSearchParam>
|
|
|
|
{
|
|
|
|
MovieSearchParam.Q
|
|
|
|
}
|
|
|
|
},
|
2020-05-05 07:09:53 +00:00
|
|
|
configService: configService,
|
|
|
|
client: wc,
|
|
|
|
logger: l,
|
|
|
|
p: ps,
|
2020-12-11 22:14:21 +00:00
|
|
|
cacheService: cs,
|
2020-05-05 07:09:53 +00:00
|
|
|
configData: new ConfigurationData())
|
2020-02-09 02:35:16 +00:00
|
|
|
{
|
2019-02-16 01:19:05 +00:00
|
|
|
Encoding = Encoding.UTF8;
|
2021-09-08 01:02:29 +00:00
|
|
|
Language = "en-US";
|
2019-02-16 01:19:05 +00:00
|
|
|
Type = "public";
|
|
|
|
|
2020-05-05 07:09:53 +00:00
|
|
|
// torrents.csv doesn't return categories
|
|
|
|
AddCategoryMapping(1, TorznabCatType.Other);
|
2019-02-16 01:19:05 +00:00
|
|
|
}
|
|
|
|
|
2020-02-09 02:35:16 +00:00
|
|
|
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
|
|
|
{
|
2020-12-11 23:12:40 +00:00
|
|
|
LoadValuesFromJson(configJson);
|
2020-02-09 02:35:16 +00:00
|
|
|
var releases = await PerformQuery(new TorznabQuery());
|
2019-02-16 01:19:05 +00:00
|
|
|
|
2020-05-05 07:09:53 +00:00
|
|
|
await ConfigureIfOK(string.Empty, releases.Any(),
|
|
|
|
() => throw new Exception("Error: 0 results found!"));
|
2019-02-16 01:19:05 +00:00
|
|
|
|
|
|
|
return IndexerConfigurationStatus.Completed;
|
|
|
|
}
|
|
|
|
|
2021-05-16 18:13:54 +00:00
|
|
|
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
|
|
|
{
|
2020-02-09 02:35:16 +00:00
|
|
|
var releases = new List<ReleaseInfo>();
|
|
|
|
var searchString = query.GetQueryString();
|
2020-10-17 10:27:50 +00:00
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(searchString)) // not supported
|
|
|
|
{
|
|
|
|
releases.Add(new ReleaseInfo
|
|
|
|
{
|
|
|
|
Title = "[NOT IMPLEMENTED] Empty search is unsupported in this indexer",
|
|
|
|
Guid = new Uri(SiteLink),
|
2020-11-08 02:11:27 +00:00
|
|
|
Details = new Uri(SiteLink),
|
2020-10-17 10:27:50 +00:00
|
|
|
MagnetUri = new Uri("magnet:?xt=urn:btih:3333333333333333333333333333333333333333"), // unknown torrent
|
|
|
|
Category = new List<int> { TorznabCatType.Other.ID },
|
|
|
|
PublishDate = new DateTime(),
|
2020-10-18 13:14:52 +00:00
|
|
|
Grabs = 0,
|
|
|
|
Seeders = 0,
|
|
|
|
Peers = 0,
|
|
|
|
DownloadVolumeFactor = 0,
|
2020-10-19 21:19:10 +00:00
|
|
|
UploadVolumeFactor = 1
|
2020-10-17 10:27:50 +00:00
|
|
|
});
|
|
|
|
return releases;
|
|
|
|
}
|
|
|
|
|
2020-05-05 07:09:53 +00:00
|
|
|
if (!string.IsNullOrWhiteSpace(searchString) && searchString.Length < 3)
|
|
|
|
return releases; // search needs at least 3 characters
|
2019-02-16 01:19:05 +00:00
|
|
|
|
2020-05-05 07:09:53 +00:00
|
|
|
var qc = new NameValueCollection
|
2020-03-26 22:15:28 +00:00
|
|
|
{
|
2020-10-17 10:27:50 +00:00
|
|
|
{ "size", "100" },
|
|
|
|
{ "q", searchString }
|
2020-03-26 22:15:28 +00:00
|
|
|
};
|
2019-02-16 01:19:05 +00:00
|
|
|
|
2020-10-17 10:27:50 +00:00
|
|
|
var searchUrl = SearchEndpoint + "?" + qc.GetQueryString();
|
2020-06-11 15:09:27 +00:00
|
|
|
var response = await RequestWithCookiesAndRetryAsync(searchUrl);
|
2020-02-09 02:35:16 +00:00
|
|
|
try
|
|
|
|
{
|
2020-06-09 17:36:57 +00:00
|
|
|
var jsonStart = response.ContentString;
|
2020-02-09 02:35:16 +00:00
|
|
|
var jsonContent = JArray.Parse(jsonStart);
|
2019-02-16 01:19:05 +00:00
|
|
|
|
2020-02-09 02:35:16 +00:00
|
|
|
foreach (var torrent in jsonContent)
|
|
|
|
{
|
|
|
|
if (torrent == null)
|
|
|
|
throw new Exception("Error: No data returned!");
|
|
|
|
|
2020-05-05 07:09:53 +00:00
|
|
|
var title = torrent.Value<string>("name");
|
|
|
|
var size = torrent.Value<long>("size_bytes");
|
|
|
|
var seeders = torrent.Value<int>("seeders");
|
|
|
|
var leechers = torrent.Value<int>("leechers");
|
|
|
|
var grabs = ParseUtil.CoerceInt(torrent.Value<string>("completed") ?? "0");
|
2020-11-02 17:01:06 +00:00
|
|
|
var infoHash = torrent.Value<JToken>("infohash").ToString();
|
2020-05-05 07:09:53 +00:00
|
|
|
|
|
|
|
// convert unix timestamp to human readable date
|
|
|
|
var publishDate = new DateTime(1970, 1, 1, 0, 0, 0, 0);
|
|
|
|
publishDate = publishDate.AddSeconds(torrent.Value<long>("created_unix"));
|
|
|
|
|
2020-03-26 22:15:28 +00:00
|
|
|
var release = new ReleaseInfo
|
|
|
|
{
|
2020-05-05 07:09:53 +00:00
|
|
|
Title = title,
|
2020-11-08 02:11:27 +00:00
|
|
|
Details = new Uri(SiteLink), // there is no details link
|
2020-11-02 17:01:06 +00:00
|
|
|
Guid = new Uri($"magnet:?xt=urn:btih:{infoHash}"),
|
|
|
|
InfoHash = infoHash, // magnet link is auto generated from infohash
|
2020-05-05 07:09:53 +00:00
|
|
|
Category = new List<int> { TorznabCatType.Other.ID },
|
|
|
|
PublishDate = publishDate,
|
|
|
|
Size = size,
|
2020-03-26 22:15:28 +00:00
|
|
|
Grabs = grabs,
|
2020-05-05 07:09:53 +00:00
|
|
|
Seeders = seeders,
|
|
|
|
Peers = leechers + seeders,
|
|
|
|
DownloadVolumeFactor = 0,
|
2020-10-19 21:19:10 +00:00
|
|
|
UploadVolumeFactor = 1
|
2020-03-26 22:15:28 +00:00
|
|
|
};
|
|
|
|
|
2020-02-09 02:35:16 +00:00
|
|
|
releases.Add(release);
|
2019-02-16 01:19:05 +00:00
|
|
|
}
|
2020-02-09 02:35:16 +00:00
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
2020-06-09 17:36:57 +00:00
|
|
|
OnParseError(response.ContentString, ex);
|
2019-02-16 01:19:05 +00:00
|
|
|
}
|
|
|
|
return releases;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|