Jackett/src/Jackett.Common/Indexers/TorrentMafya.cs

211 lines
8.1 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AngleSharp.Dom;
using AngleSharp.Html.Parser;
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;
using Newtonsoft.Json.Linq;
using NLog;
namespace Jackett.Common.Indexers
{
[ExcludeFromCodeCoverage]
public class TorrentMafya : BaseWebIndexer
{
private class TorrentMafyaRowResult
{
public string col1 { get; set; }
public string col2 { get; set; }
public string col3 { get; set; }
}
private class TorrentMafyaArchiveResponse
{
public IEnumerable<TorrentMafyaRowResult> aaData { get; set; }
}
private void MapCategories()
{
AddCategoryMapping("games", TorznabCatType.PCGames,"Oyun");
AddCategoryMapping("programs", TorznabCatType.PC, "Program");
AddCategoryMapping("movies", TorznabCatType.Movies, "Film");
AddCategoryMapping("tv", TorznabCatType.TV, "Dizi");
AddCategoryMapping("apk", TorznabCatType.PCPhoneAndroid, "APK");
}
public TorrentMafya(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps)
: base(id: "torrentmafya",
name: "TorrentMafya",
description: "TorrentMafya is a Turkish general torrent tracker ",
link: "https://www.torrentmafya.org/",
caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
configService: configService,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationData())
{
Encoding = Encoding.UTF8;
Language = "tr-tr";
Type = "public";
MapCategories();
}
private static DateTime ParseReleasePublishDate(string date)
{
try
{
var splitDate = date.Split(' ');
var firstPart = int.Parse(splitDate[0]) * -1;
var secondPart = splitDate[1].ToLowerInvariant();
switch (secondPart)
{
case "saat":
return DateTime.Now.AddHours(firstPart);
case "gün":
return DateTime.Now.AddDays(firstPart);
case "ay":
return DateTime.Now.AddMonths(firstPart);
case "yıl":
return DateTime.Now.AddYears(firstPart);
default:
return DateTime.MinValue;
}
}
catch
{
return DateTime.MinValue;
}
}
private static List<int> ParseReleaseCategory(ITokenList classes)
{
var result = new List<int>();
if (classes.Contains("fa-gamepad"))
{
result.Add(TorznabCatType.PCGames.ID);
} else if (classes.Contains("fa-film"))
{
result.Add(TorznabCatType.Movies.ID);
} else if (classes.Contains("fa-tv"))
{
result.Add(TorznabCatType.TV.ID);
}
else if (classes.Contains("fa-microchip"))
{
result.Add(TorznabCatType.PC.ID);
} else if (classes.Contains("fa-android"))
{
result.Add(TorznabCatType.PCPhoneAndroid.ID);
}
return result;
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
var releases = await PerformQuery(new TorznabQuery());
await ConfigureIfOK(string.Empty, releases.Any(), () =>
throw new Exception("Could not find release from this URL."));
return IndexerConfigurationStatus.Completed;
}
private static ReleaseInfo ParseReleaseInfo(IHtmlParser parser, TorrentMafyaRowResult row)
{
var firstColumn = parser.ParseDocument(row.col1);
var mainColumn = parser.ParseDocument(row.col3);
var sizeContent = mainColumn.QuerySelector("span.boyut")?.TextContent;
var magnetLink = mainColumn.QuerySelector("a[href^=\"magnet:?xt=\"]")?.GetAttribute("href");
var fileLink = mainColumn.QuerySelector("a[title^=\"İndir\"]")?.GetAttribute("href");
var rowLink = (Uri)null;
if (!string.IsNullOrEmpty(magnetLink))
{
rowLink = new Uri(magnetLink);
} else if (!string.IsNullOrEmpty(fileLink))
{
rowLink = new Uri(fileLink);
}
var detailsLink = new Uri(firstColumn.QuerySelector("a").GetAttribute("href"));
var category = ParseReleaseCategory(firstColumn.QuerySelector("i")?.ClassList);
var seederContent = mainColumn.QuerySelector("span.sayiGonderen")?.TextContent;
var leecherContent = mainColumn.QuerySelector("span.sayiIndiren")?.TextContent;
int.TryParse(seederContent, out var seeders);
int.TryParse(leecherContent, out var leechers);
return new ReleaseInfo
{
Title = firstColumn.QuerySelector("a")?.TextContent,
Comments = detailsLink,
PublishDate = ParseReleasePublishDate(row.col2),
Category = category,
Seeders = seeders,
Peers = seeders + leechers,
DownloadVolumeFactor = 0,
UploadVolumeFactor = 1,
Link = rowLink,
Guid = rowLink,
Size = !string.IsNullOrEmpty(sizeContent) ? ReleaseInfo.GetBytes(sizeContent) : 0
};
}
private static Dictionary<string, string> PrepareSearchQueryCollection(string searchString) => new Dictionary<string, string>
{
{"draw", "8"},
{"columns[0][data]", "col1"},
{"columns[0][name]", ""},
{"columns[0][searchable]", "true"},
{"columns[0][orderable]", "false"},
{"columns[0][search][value]", ""},
{"columns[0][search][regex]", "false"},
{"columns[1][data]", "col2"},
{"columns[1][name]", ""},
{"columns[1][searchable]", "true"},
{"columns[1][orderable]", "false"},
{"columns[1][search][value]", ""},
{"columns[1][search][regex]", "false"},
{"columns[2][data]", "col3"},
{"columns[2][name]", ""},
{"columns[2][searchable]", "true"},
{"columns[2][orderable]", "false"},
{"columns[2][search][value]", ""},
{"columns[2][search][regex]", "false"},
{"start", "0"},
{"length", "20"},
{"search[value]", searchString},
{"search[regex]", "false"},
{"tur", "1"}
};
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
{
var result = new List<ReleaseInfo>();
var searchString = query.GetQueryString().Replace(" ", "%");
var searchUrl = $"{SiteLink}table.php";
var referrer = $"{SiteLink}arsiv/";
var body = PrepareSearchQueryCollection(searchString);
var response = await RequestWithCookiesAsync(searchUrl, null, RequestType.POST, referrer, body);
var content = response.ContentString;
try
{
var json = JsonConvert.DeserializeObject<TorrentMafyaArchiveResponse>(response.ContentString);
var parser = new HtmlParser();
result.AddRange(json.aaData.Select(row => ParseReleaseInfo(parser, row)));
}
catch (Exception ex)
{
OnParseError(content, ex);
}
return result;
}
}
}