2020-04-07 19:58:36 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2020-05-03 23:35:52 +00:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2020-04-07 19:58:36 +00:00
|
|
|
using System.Linq;
|
|
|
|
using System.Text;
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using AngleSharp.Html.Parser;
|
|
|
|
using Jackett.Common.Helpers;
|
|
|
|
using Jackett.Common.Models;
|
|
|
|
using Jackett.Common.Models.IndexerConfig;
|
|
|
|
using Jackett.Common.Services.Interfaces;
|
|
|
|
using Jackett.Common.Utils.Clients;
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
using NLog;
|
|
|
|
using WebClient = Jackett.Common.Utils.Clients.WebClient;
|
|
|
|
|
|
|
|
namespace Jackett.Common.Indexers
|
|
|
|
{
|
2020-05-03 23:35:52 +00:00
|
|
|
[ExcludeFromCodeCoverage]
|
2020-04-07 19:58:36 +00:00
|
|
|
public class Cinecalidad : BaseWebIndexer
|
|
|
|
{
|
2022-03-08 20:13:47 +00:00
|
|
|
private const int MaxLatestPageLimit = 3; // 12 items per page * 3 pages = 36
|
2022-01-16 10:30:26 +00:00
|
|
|
private const int MaxSearchPageLimit = 6;
|
2020-04-07 19:58:36 +00:00
|
|
|
|
2021-04-28 20:50:03 +00:00
|
|
|
public override string[] LegacySiteLinks { get; protected set; } = {
|
2021-12-08 02:32:48 +00:00
|
|
|
"https://cinecalidad.website/",
|
2021-04-28 20:50:03 +00:00
|
|
|
"https://www.cinecalidad.to/",
|
|
|
|
"https://www.cinecalidad.im/", // working but outdated, maybe copycat
|
2020-04-07 19:58:36 +00:00
|
|
|
"https://www.cinecalidad.is/",
|
2021-03-21 01:41:52 +00:00
|
|
|
"https://www.cinecalidad.li/",
|
2020-12-15 19:16:09 +00:00
|
|
|
"https://www.cinecalidad.eu/",
|
2021-03-21 01:41:52 +00:00
|
|
|
"https://cinecalidad.unbl0ck.xyz/",
|
|
|
|
"https://cinecalidad.u4m.club/",
|
2021-11-13 05:29:34 +00:00
|
|
|
"https://cinecalidad.mrunblock.icu/",
|
2022-03-26 22:26:50 +00:00
|
|
|
"https://www.cinecalidad.lat/",
|
2021-11-13 05:29:34 +00:00
|
|
|
"https://www.cine-calidad.com/"
|
2020-12-15 19:16:09 +00:00
|
|
|
};
|
|
|
|
|
2020-12-11 22:14:21 +00:00
|
|
|
public Cinecalidad(IIndexerConfigurationService configService, WebClient wc, Logger l, IProtectionService ps,
|
|
|
|
ICacheService cs)
|
2020-05-11 19:59:28 +00:00
|
|
|
: base(id: "cinecalidad",
|
|
|
|
name: "Cinecalidad",
|
2022-01-16 10:30:26 +00:00
|
|
|
description: "Películas Full HD en Latino Dual.",
|
2022-03-26 22:26:50 +00:00
|
|
|
link: "https://cinecalidad3.com/",
|
2021-04-28 20:50:03 +00:00
|
|
|
caps: new TorznabCapabilities
|
|
|
|
{
|
2020-10-18 17:26:22 +00:00
|
|
|
MovieSearchParams = new List<MovieSearchParam> { MovieSearchParam.Q }
|
|
|
|
},
|
2020-04-07 19:58:36 +00:00
|
|
|
configService: configService,
|
|
|
|
client: wc,
|
|
|
|
logger: l,
|
|
|
|
p: ps,
|
2020-12-11 22:14:21 +00:00
|
|
|
cacheService: cs,
|
2020-04-07 19:58:36 +00:00
|
|
|
configData: new ConfigurationData())
|
|
|
|
{
|
|
|
|
Encoding = Encoding.UTF8;
|
2022-01-16 10:30:26 +00:00
|
|
|
Language = "es-419";
|
2020-04-07 19:58:36 +00:00
|
|
|
Type = "public";
|
|
|
|
|
|
|
|
AddCategoryMapping(1, TorznabCatType.MoviesHD);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
|
|
|
{
|
|
|
|
var releases = new List<ReleaseInfo>();
|
|
|
|
|
|
|
|
var templateUrl = SiteLink;
|
2021-10-09 18:36:22 +00:00
|
|
|
templateUrl += "{0}?s="; // placeholder for page
|
2020-04-07 19:58:36 +00:00
|
|
|
|
2022-03-08 20:13:47 +00:00
|
|
|
var maxPages = MaxLatestPageLimit; // we scrape only 3 pages for recent torrents
|
|
|
|
var recent = !string.IsNullOrWhiteSpace(query.GetQueryString());
|
|
|
|
if (recent)
|
2020-04-07 19:58:36 +00:00
|
|
|
{
|
2021-10-09 18:36:22 +00:00
|
|
|
templateUrl += WebUtilityHelpers.UrlEncode(query.GetQueryString(), Encoding.UTF8);
|
2020-04-07 19:58:36 +00:00
|
|
|
maxPages = MaxSearchPageLimit;
|
|
|
|
}
|
|
|
|
|
|
|
|
var lastPublishDate = DateTime.Now;
|
|
|
|
for (var page = 1; page <= maxPages; page++)
|
|
|
|
{
|
|
|
|
var pageParam = page > 1 ? $"page/{page}/" : "";
|
|
|
|
var searchUrl = string.Format(templateUrl, pageParam);
|
2020-06-11 15:09:27 +00:00
|
|
|
var response = await RequestWithCookiesAndRetryAsync(searchUrl);
|
2020-04-07 19:58:36 +00:00
|
|
|
var pageReleases = ParseReleases(response, query);
|
|
|
|
|
|
|
|
// publish date is not available in the torrent list, but we add a relative date so we can sort
|
2020-10-02 12:29:14 +00:00
|
|
|
foreach (var release in pageReleases)
|
2020-04-07 19:58:36 +00:00
|
|
|
{
|
|
|
|
release.PublishDate = lastPublishDate;
|
|
|
|
lastPublishDate = lastPublishDate.AddMinutes(-1);
|
|
|
|
}
|
|
|
|
releases.AddRange(pageReleases);
|
|
|
|
|
2022-03-08 20:13:47 +00:00
|
|
|
if (pageReleases.Count < 1 && recent)
|
2020-04-07 19:58:36 +00:00
|
|
|
break; // this is the last page
|
|
|
|
}
|
|
|
|
|
|
|
|
return releases;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override async Task<byte[]> Download(Uri link)
|
|
|
|
{
|
2020-09-21 16:39:47 +00:00
|
|
|
var results = await RequestWithCookiesAsync(link.ToString());
|
2020-04-07 19:58:36 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var parser = new HtmlParser();
|
2020-06-09 17:36:57 +00:00
|
|
|
var dom = parser.ParseDocument(results.ContentString);
|
2022-01-16 10:30:26 +00:00
|
|
|
var protectedLink = dom.QuerySelector("a:contains('Torrent')").GetAttribute("data-url");
|
|
|
|
protectedLink = Base64Decode(protectedLink);
|
2020-12-22 17:21:00 +00:00
|
|
|
protectedLink = GetAbsoluteUrl(protectedLink);
|
2020-04-07 19:58:36 +00:00
|
|
|
|
2020-11-28 20:40:10 +00:00
|
|
|
results = await RequestWithCookiesAsync(protectedLink);
|
2020-06-09 17:36:57 +00:00
|
|
|
dom = parser.ParseDocument(results.ContentString);
|
2020-04-07 19:58:36 +00:00
|
|
|
var magnetUrl = dom.QuerySelector("a[href^=magnet]").GetAttribute("href");
|
|
|
|
return await base.Download(new Uri(magnetUrl));
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
2020-06-09 17:36:57 +00:00
|
|
|
OnParseError(results.ContentString, ex);
|
2020-04-07 19:58:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-06-10 21:22:29 +00:00
|
|
|
private List<ReleaseInfo> ParseReleases(WebResult response, TorznabQuery query)
|
2020-04-07 19:58:36 +00:00
|
|
|
{
|
|
|
|
var releases = new List<ReleaseInfo>();
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var parser = new HtmlParser();
|
2020-06-09 17:36:57 +00:00
|
|
|
var dom = parser.ParseDocument(response.ContentString);
|
2020-04-07 19:58:36 +00:00
|
|
|
|
2022-01-15 18:15:26 +00:00
|
|
|
var rows = dom.QuerySelectorAll("article");
|
2020-04-07 19:58:36 +00:00
|
|
|
foreach (var row in rows)
|
|
|
|
{
|
2022-01-16 10:30:26 +00:00
|
|
|
if (row.QuerySelector("div.selt") != null)
|
|
|
|
continue; // we only support movies
|
|
|
|
|
|
|
|
var qLink = row.QuerySelector("a.absolute");
|
2022-03-08 20:13:47 +00:00
|
|
|
var qImg = row.QuerySelector("img.rounded");
|
2022-01-16 10:30:26 +00:00
|
|
|
if (qLink == null || qImg == null)
|
2020-05-01 16:32:23 +00:00
|
|
|
continue; // skip results without image
|
2022-01-16 10:30:26 +00:00
|
|
|
|
|
|
|
var title = qLink.TextContent.Trim();
|
2020-04-07 19:58:36 +00:00
|
|
|
if (!CheckTitleMatchWords(query.GetQueryString(), title))
|
|
|
|
continue; // skip if it doesn't contain all words
|
2022-01-16 10:30:26 +00:00
|
|
|
title += " MULTi/LATiN SPANiSH 1080p BDRip x264";
|
2022-01-15 18:15:26 +00:00
|
|
|
var poster = new Uri(GetAbsoluteUrl(qImg.GetAttribute("src")));
|
2022-01-16 10:30:26 +00:00
|
|
|
var link = new Uri(qLink.GetAttribute("href"));
|
2020-04-07 19:58:36 +00:00
|
|
|
|
|
|
|
var release = new ReleaseInfo
|
|
|
|
{
|
|
|
|
Title = title,
|
|
|
|
Link = link,
|
2020-11-08 02:11:27 +00:00
|
|
|
Details = link,
|
2020-04-07 19:58:36 +00:00
|
|
|
Guid = link,
|
2020-10-02 12:29:14 +00:00
|
|
|
Category = new List<int> { TorznabCatType.MoviesHD.ID },
|
2020-11-07 23:43:33 +00:00
|
|
|
Poster = poster,
|
2020-04-07 19:58:36 +00:00
|
|
|
Size = 2147483648, // 2 GB
|
|
|
|
Files = 1,
|
|
|
|
Seeders = 1,
|
|
|
|
Peers = 2,
|
|
|
|
DownloadVolumeFactor = 0,
|
|
|
|
UploadVolumeFactor = 1
|
|
|
|
};
|
|
|
|
|
|
|
|
releases.Add(release);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
2020-06-09 17:36:57 +00:00
|
|
|
OnParseError(response.ContentString, ex);
|
2020-04-07 19:58:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return releases;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: merge this method with query.MatchQueryStringAND
|
|
|
|
private static bool CheckTitleMatchWords(string queryStr, string title)
|
|
|
|
{
|
|
|
|
// this code split the words, remove words with 2 letters or less, remove accents and lowercase
|
|
|
|
var queryMatches = Regex.Matches(queryStr, @"\b[\w']*\b");
|
|
|
|
var queryWords = from m in queryMatches.Cast<Match>()
|
|
|
|
where !string.IsNullOrEmpty(m.Value) && m.Value.Length > 2
|
|
|
|
select Encoding.UTF8.GetString(Encoding.GetEncoding("ISO-8859-8").GetBytes(m.Value.ToLower()));
|
|
|
|
|
|
|
|
var titleMatches = Regex.Matches(title, @"\b[\w']*\b");
|
|
|
|
var titleWords = from m in titleMatches.Cast<Match>()
|
|
|
|
where !string.IsNullOrEmpty(m.Value) && m.Value.Length > 2
|
|
|
|
select Encoding.UTF8.GetString(Encoding.GetEncoding("ISO-8859-8").GetBytes(m.Value.ToLower()));
|
|
|
|
titleWords = titleWords.ToArray();
|
|
|
|
|
|
|
|
return queryWords.All(word => titleWords.Contains(word));
|
|
|
|
}
|
2020-12-22 17:21:00 +00:00
|
|
|
|
|
|
|
private string GetAbsoluteUrl(string url)
|
|
|
|
{
|
|
|
|
url = url.Trim();
|
|
|
|
if (!url.StartsWith("http"))
|
|
|
|
return SiteLink + url.TrimStart('/');
|
|
|
|
return url;
|
|
|
|
}
|
2022-01-16 10:30:26 +00:00
|
|
|
|
|
|
|
private string Base64Decode(string base64EncodedData)
|
|
|
|
{
|
|
|
|
var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
|
|
|
|
return Encoding.UTF8.GetString(base64EncodedBytes);
|
|
|
|
}
|
2020-04-07 19:58:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|