2020-02-09 02:35:16 +00:00
using System ;
2020-01-06 22:41:51 +00:00
using System.Collections.Generic ;
using System.Collections.Specialized ;
2020-05-03 23:35:52 +00:00
using System.Diagnostics.CodeAnalysis ;
2020-01-06 22:41:51 +00:00
using System.Globalization ;
using System.Linq ;
using System.Net ;
using System.Text ;
using System.Text.RegularExpressions ;
using System.Threading.Tasks ;
using AngleSharp.Dom ;
2021-02-13 20:57:18 +00:00
using AngleSharp.Html.Dom ;
2020-01-06 22:41:51 +00:00
using AngleSharp.Html.Parser ;
using Jackett.Common.Models ;
using Jackett.Common.Models.IndexerConfig ;
using Jackett.Common.Services.Interfaces ;
using Jackett.Common.Utils ;
using Newtonsoft.Json.Linq ;
using NLog ;
using static Jackett . Common . Models . IndexerConfig . ConfigurationData ;
2020-02-09 18:08:34 +00:00
using WebClient = Jackett . Common . Utils . Clients . WebClient ;
2020-01-06 22:41:51 +00:00
namespace Jackett.Common.Indexers
{
2020-05-03 23:35:52 +00:00
[ExcludeFromCodeCoverage]
2023-03-09 14:06:12 +00:00
public class DivxTotal : IndexerBase
2020-01-06 22:41:51 +00:00
{
2023-03-09 14:06:12 +00:00
public override string Id = > "divxtotal" ;
public override string Name = > "DivxTotal" ;
public override string Description = > "DivxTotal is a SPANISH site for Movies, TV series and Software" ;
2023-04-08 03:47:51 +00:00
public override string SiteLink { get ; protected set ; } = "https://www.divxtotal.wf/" ;
2023-03-09 14:06:12 +00:00
public override string [ ] LegacySiteLinks = > new [ ]
{
"https://www.divxtotal.one/" ,
"https://www.divxtotal.ch/" ,
"https://www.divxtotal.nz/" ,
"https://www.divxtotal.li/" ,
"https://www.divxtotal.nu/" ,
"https://www.divxtotal.se/" ,
"https://www.divxtotal.pm/" ,
"https://www.divxtotal.re/" ,
"https://www.divxtotal.nl/" ,
"https://www.divxtotal.ac/" ,
"https://www.divxtotal.dev/" ,
"https://www.divxtotal.ms/" ,
"https://www.divxtotal.fi/" ,
2023-04-08 03:47:51 +00:00
"https://www.divxtotal.cat/" ,
"https://www.divxtotal.pl/"
2023-03-09 14:06:12 +00:00
} ;
public override string Language = > "es-ES" ;
public override string Type = > "public" ;
2023-03-10 11:20:29 +00:00
public override TorznabCapabilities TorznabCaps = > SetCapabilities ( ) ;
2020-09-12 12:43:25 +00:00
private const string DownloadLink = "/download_tt.php" ;
2021-02-13 20:57:18 +00:00
private const int MaxNrOfResults = 100 ;
private const int MaxPageLoads = 3 ;
2020-01-11 07:48:12 +00:00
private static class DivxTotalCategories
{
public static string Peliculas = > "peliculas" ;
public static string PeliculasHd = > "peliculas-hd" ;
public static string Peliculas3D = > "peliculas-3-d" ;
public static string PeliculasDvdr = > "peliculas-dvdr" ;
public static string Series = > "series" ;
public static string Programas = > "programas" ;
public static string Otros = > "otros" ;
}
2021-02-13 20:57:18 +00:00
2020-01-11 07:48:12 +00:00
private static class DivxTotalFizeSizes
{
public static long Peliculas = > 2147483648 ; // 2 GB
public static long PeliculasDvdr = > 5368709120 ; // 5 GB
2021-09-13 00:38:24 +00:00
public static long Series = > 536870912 ; // 512 MB
public static long Otros = > 536870912 ; // 512 MB
2020-01-11 07:48:12 +00:00
}
2020-01-06 22:41:51 +00:00
2020-12-11 22:14:21 +00:00
public DivxTotal ( IIndexerConfigurationService configService , WebClient w , Logger l , IProtectionService ps ,
2023-03-09 14:06:12 +00:00
ICacheService cs )
2023-03-10 11:20:29 +00:00
: base ( configService : configService ,
2020-05-11 19:59:28 +00:00
client : w ,
logger : l ,
p : ps ,
2020-12-11 22:14:21 +00:00
cacheService : cs ,
2020-05-11 19:59:28 +00:00
configData : new ConfigurationData ( ) )
2020-01-06 22:41:51 +00:00
{
2021-03-16 23:29:26 +00:00
var matchWords = new BoolConfigurationItem ( "Match words in title" ) { Value = true } ;
2020-01-06 22:41:51 +00:00
configData . AddDynamic ( "MatchWords" , matchWords ) ;
2022-04-17 06:20:52 +00:00
configData . AddDynamic ( "flaresolverr" , new DisplayInfoConfigurationItem ( "FlareSolverr" , "This site may use Cloudflare DDoS Protection, therefore Jackett requires <a href=\"https://github.com/Jackett/Jackett#configuring-flaresolverr\" target=\"_blank\">FlareSolverr</a> to access it." ) ) ;
2023-03-10 11:20:29 +00:00
}
private TorznabCapabilities SetCapabilities ( )
{
var caps = new TorznabCapabilities
{
TvSearchParams = new List < TvSearchParam >
{
TvSearchParam . Q , TvSearchParam . Season , TvSearchParam . Ep
} ,
MovieSearchParams = new List < MovieSearchParam >
{
MovieSearchParam . Q
}
} ;
caps . Categories . AddCategoryMapping ( DivxTotalCategories . Peliculas , TorznabCatType . MoviesSD , "Peliculas" ) ;
caps . Categories . AddCategoryMapping ( DivxTotalCategories . PeliculasHd , TorznabCatType . MoviesHD , "Peliculas HD" ) ;
caps . Categories . AddCategoryMapping ( DivxTotalCategories . Peliculas3D , TorznabCatType . Movies3D , "Peliculas 3D" ) ;
caps . Categories . AddCategoryMapping ( DivxTotalCategories . PeliculasDvdr , TorznabCatType . MoviesDVD , "Peliculas DVD-r" ) ;
caps . Categories . AddCategoryMapping ( DivxTotalCategories . Series , TorznabCatType . TVSD , "Series" ) ;
caps . Categories . AddCategoryMapping ( DivxTotalCategories . Programas , TorznabCatType . PC , "Programas" ) ;
caps . Categories . AddCategoryMapping ( DivxTotalCategories . Otros , TorznabCatType . OtherMisc , "Otros" ) ;
2020-12-20 14:59:27 +00:00
2023-03-10 11:20:29 +00:00
return caps ;
2020-01-06 22:41:51 +00:00
}
public override async Task < IndexerConfigurationStatus > ApplyConfiguration ( JToken configJson )
{
2020-12-11 23:12:40 +00:00
LoadValuesFromJson ( configJson ) ;
2020-01-06 22:41:51 +00:00
var releases = await PerformQuery ( new TorznabQuery ( ) ) ;
await ConfigureIfOK ( string . Empty , releases . Any ( ) , ( ) = >
2020-01-11 07:08:18 +00:00
throw new Exception ( "Could not find releases from this URL" ) ) ;
2020-01-06 22:41:51 +00:00
return IndexerConfigurationStatus . Completed ;
}
protected override async Task < IEnumerable < ReleaseInfo > > PerformQuery ( TorznabQuery query )
{
2021-02-13 20:57:18 +00:00
var newQuery = query . Clone ( ) ;
2020-01-06 22:41:51 +00:00
var releases = new List < ReleaseInfo > ( ) ;
2021-03-16 23:29:26 +00:00
var matchWords = ( ( BoolConfigurationItem ) configData . GetDynamic ( "MatchWords" ) ) . Value ;
2021-02-13 20:57:18 +00:00
matchWords = newQuery . SearchTerm ! = "" & & matchWords ;
2020-01-06 22:41:51 +00:00
2020-01-11 07:48:12 +00:00
// we remove parts from the original query
2021-02-13 20:57:18 +00:00
newQuery = ParseQuery ( newQuery ) ;
var qc = new NameValueCollection { { "s" , newQuery . SearchTerm } } ;
2020-01-06 22:41:51 +00:00
var page = 1 ;
2021-02-13 20:57:18 +00:00
IHtmlDocument htmlDocument = null ;
2020-01-06 22:41:51 +00:00
do
{
var url = SiteLink + "page/" + page + "/?" + qc . GetQueryString ( ) ;
2021-02-13 20:57:18 +00:00
string htmlString ;
try
{
htmlString = await LoadWebPageAsync ( url ) ;
}
catch
{
logger . Error ( $"DivxTotal: Failed to load url {url}" ) ;
return releases ;
}
2020-01-06 22:41:51 +00:00
try
{
2021-02-13 20:57:18 +00:00
htmlDocument = ParseHtmlIntoDocument ( htmlString ) ;
2020-01-06 22:41:51 +00:00
2021-02-13 20:57:18 +00:00
var table = htmlDocument . QuerySelector ( "table.table" ) ;
2020-01-11 07:08:18 +00:00
if ( table = = null )
break ;
2021-02-13 20:57:18 +00:00
var rows = table . QuerySelectorAll ( "tbody > tr" ) ;
2020-01-06 22:41:51 +00:00
foreach ( var row in rows )
{
2020-03-01 19:01:59 +00:00
try
{
2021-02-13 20:57:18 +00:00
var rels = await ParseReleasesAsync ( row , newQuery , matchWords ) ;
if ( rels . Any ( ) )
{
releases . AddRange ( rels ) ;
}
2020-03-01 19:01:59 +00:00
}
catch ( Exception ex )
{
2020-05-11 19:59:28 +00:00
logger . Error ( $"CardigannIndexer ({Id}): Error while parsing row '{row.ToHtmlPretty()}':\n\n{ex}" ) ;
2020-03-01 19:01:59 +00:00
}
2020-01-06 22:41:51 +00:00
}
}
catch ( Exception ex )
{
2021-02-13 20:57:18 +00:00
OnParseError ( htmlString , ex ) ;
2020-01-06 22:41:51 +00:00
}
2021-02-13 20:57:18 +00:00
page + + ;
2020-01-06 22:41:51 +00:00
2021-02-13 20:57:18 +00:00
} while ( page < = MaxPageLoads & &
releases . Count < MaxNrOfResults & &
! IsLastPageOfQueryResult ( htmlDocument ) ) ;
2020-01-06 22:41:51 +00:00
return releases ;
}
2021-02-13 20:57:18 +00:00
/// <Exception cref="ExceptionWithConfigData" />
private async Task < string > LoadWebPageAsync ( string url )
{
var result = await RequestWithCookiesAsync ( url ) ;
return result . Status = = HttpStatusCode . OK
? result . ContentString
: throw new ExceptionWithConfigData ( result . ContentString , configData ) ;
}
private IHtmlDocument ParseHtmlIntoDocument ( string htmlContentString )
= > new HtmlParser ( ) . ParseDocument ( htmlContentString ) ;
private bool IsLastPageOfQueryResult ( IHtmlDocument htmlDocument )
{
if ( htmlDocument = = null )
return true ;
var nextPageAnchor = htmlDocument . QuerySelector ( "ul.pagination > li.active + li > a" ) ;
return nextPageAnchor = = null ;
}
2020-01-06 22:41:51 +00:00
public override async Task < byte [ ] > Download ( Uri link )
{
// for tv series we already have the link
var downloadUrl = link . ToString ( ) ;
// for other categories we have to do another step
2020-09-12 12:43:25 +00:00
if ( ! downloadUrl . Contains ( DownloadLink ) )
2020-01-06 22:41:51 +00:00
{
2021-02-13 20:57:18 +00:00
var htmlString = await LoadWebPageAsync ( downloadUrl ) ;
var htmlDocument = ParseHtmlIntoDocument ( htmlString ) ;
downloadUrl = GetDownloadLink ( htmlDocument ) ;
2020-01-06 22:41:51 +00:00
}
var content = await base . Download ( new Uri ( downloadUrl ) ) ;
return content ;
}
2021-02-13 20:57:18 +00:00
private async Task < List < ReleaseInfo > > ParseReleasesAsync ( IParentNode row , TorznabQuery query , bool matchWords )
2020-01-06 22:41:51 +00:00
{
2021-02-13 20:57:18 +00:00
var releases = new List < ReleaseInfo > ( ) ;
2020-01-06 22:41:51 +00:00
var anchor = row . QuerySelector ( "a" ) ;
var title = anchor . TextContent . Trim ( ) ;
2021-02-13 20:57:18 +00:00
// match the words in the query with the titles
if ( matchWords & & ! CheckTitleMatchWords ( query . SearchTerm , title ) )
return releases ;
var detailsStr = anchor . GetAttribute ( "href" ) ;
2020-11-08 02:11:27 +00:00
var cat = detailsStr . Split ( '/' ) [ 3 ] ;
2020-01-06 22:41:51 +00:00
// return results only for requested categories
2022-04-24 19:42:14 +00:00
if ( query . Categories . Any ( ) & & ! MapTorznabCapsToTrackers ( query ) . Contains ( cat ) )
2021-02-13 20:57:18 +00:00
return releases ;
2020-01-06 22:41:51 +00:00
2021-02-13 20:57:18 +00:00
var publishStr = row . QuerySelectorAll ( "td" ) [ 2 ] . TextContent . Trim ( ) ;
var publishDate = TryToParseDate ( publishStr , DateTime . Now ) ;
var sizeStr = row . QuerySelectorAll ( "td" ) [ 3 ] . TextContent . Trim ( ) ;
2020-01-06 22:41:51 +00:00
// parsing is different for each category
2020-01-11 07:48:12 +00:00
if ( cat = = DivxTotalCategories . Series )
2021-02-13 20:57:18 +00:00
{
var seriesReleases = await ParseSeriesReleaseAsync ( query , detailsStr , cat , publishDate ) ;
releases . AddRange ( seriesReleases ) ;
}
2020-02-09 02:35:16 +00:00
else if ( query . Episode = = null ) // if it's scene series, we don't return other categories
2020-01-06 22:41:51 +00:00
{
2020-01-11 07:48:12 +00:00
if ( cat = = DivxTotalCategories . Peliculas | | cat = = DivxTotalCategories . PeliculasHd | |
cat = = DivxTotalCategories . Peliculas3D | | cat = = DivxTotalCategories . PeliculasDvdr )
2021-02-13 20:57:18 +00:00
{
var movieRelease = ParseMovieRelease ( query , title , detailsStr , cat , publishDate , sizeStr ) ;
releases . Add ( movieRelease ) ;
}
2020-01-11 07:48:12 +00:00
else
{
var size = TryToParseSize ( sizeStr , DivxTotalFizeSizes . Otros ) ;
2021-02-13 20:57:18 +00:00
var release = GenerateRelease ( title , detailsStr , detailsStr , cat , publishDate , size ) ;
releases . Add ( release ) ;
2020-01-11 07:48:12 +00:00
}
2020-01-06 22:41:51 +00:00
}
2021-02-13 20:57:18 +00:00
return releases ;
2020-01-06 22:41:51 +00:00
}
2021-02-13 20:57:18 +00:00
private async Task < List < ReleaseInfo > > ParseSeriesReleaseAsync ( TorznabQuery query , string detailsStr , string cat , DateTime publishDate )
2020-01-06 22:41:51 +00:00
{
2021-02-13 20:57:18 +00:00
var seriesReleases = new List < ReleaseInfo > ( ) ;
2020-01-06 22:41:51 +00:00
2021-02-13 20:57:18 +00:00
var htmlString = await LoadWebPageAsync ( detailsStr ) ;
var htmlDocument = ParseHtmlIntoDocument ( htmlString ) ;
2020-01-06 22:41:51 +00:00
2022-07-05 06:38:02 +00:00
var tables = htmlDocument . QuerySelectorAll ( "table.rwd-table" ) ;
2020-01-06 22:41:51 +00:00
foreach ( var table in tables )
{
2021-02-13 20:57:18 +00:00
var rows = table . QuerySelectorAll ( "tbody > tr" ) ;
2020-01-06 22:41:51 +00:00
foreach ( var row in rows )
{
var anchor = row . QuerySelector ( "a" ) ;
var episodeTitle = anchor . TextContent . Trim ( ) ;
2021-05-16 18:13:54 +00:00
2020-01-11 07:48:12 +00:00
// Convert the title to Scene format
episodeTitle = ParseDivxTotalSeriesTitle ( episodeTitle , query ) ;
// if the original query was in scene format, we filter the results to match episode
// query.Episode != null means scene title
if ( query . Episode ! = null & & ! episodeTitle . Contains ( query . GetEpisodeSearchString ( ) ) )
continue ;
2020-01-06 22:41:51 +00:00
2021-02-13 20:57:18 +00:00
var downloadLink = GetDownloadLink ( row ) ;
2022-07-05 06:38:02 +00:00
seriesReleases . Add ( GenerateRelease ( episodeTitle , detailsStr , downloadLink , cat , publishDate , DivxTotalFizeSizes . Series ) ) ;
2020-01-06 22:41:51 +00:00
}
}
2021-02-13 20:57:18 +00:00
return seriesReleases ;
2020-01-06 22:41:51 +00:00
}
2021-02-13 20:57:18 +00:00
private ReleaseInfo ParseMovieRelease ( TorznabQuery query , string title , string detailsStr , string cat , DateTime publishDate , string sizeStr )
2020-01-11 07:48:12 +00:00
{
// parse tags in title, we need to put the year after the real title (before the tags)
// La Maldicion ( HD-CAM)
// Mascotas 2 4K (1080p) (DUAL)
// Dragon Ball Super: Broly [2018] [DVD9] [PAL] [Español]
var tags = "" ;
var queryMatches = Regex . Matches ( title , @"[\[\(]([^\]\)]+)[\]\)]" , RegexOptions . IgnoreCase ) ;
foreach ( Match m in queryMatches )
{
tags + = " " + m . Groups [ 1 ] . Value . Trim ( ) ;
title = title . Replace ( m . Groups [ 0 ] . Value , "" ) ;
}
title = title . Trim ( ) ;
title = Regex . Replace ( title , " 4K$" , "" , RegexOptions . IgnoreCase ) ;
// add the year
title = query . Year ! = null ? title + " " + query . Year : title ;
// add the tags
title + = tags . ToUpper ( ) ;
// add suffix and calculate the size
var size = TryToParseSize ( sizeStr , DivxTotalFizeSizes . Peliculas ) ;
if ( cat = = DivxTotalCategories . Peliculas )
title + = " SPANISH DVDRip XviD" ;
else if ( cat = = DivxTotalCategories . PeliculasHd | | cat = = DivxTotalCategories . Peliculas3D )
title + = " SPANISH BDRip x264" ;
else if ( cat = = DivxTotalCategories . PeliculasDvdr )
{
2020-02-09 02:35:16 +00:00
title + = " SPANISH DVDR" ;
size = TryToParseSize ( sizeStr , DivxTotalFizeSizes . PeliculasDvdr ) ;
2020-01-11 07:48:12 +00:00
}
else
throw new Exception ( "Unknown category " + cat ) ;
2021-02-13 20:57:18 +00:00
var movieRelease = GenerateRelease ( title , detailsStr , detailsStr , cat , publishDate , size ) ;
return movieRelease ;
2020-01-11 07:48:12 +00:00
}
2021-02-13 20:57:18 +00:00
private ReleaseInfo GenerateRelease ( string title , string detailsStr , string downloadLink , string cat , DateTime publishDate , long size )
2020-01-06 22:41:51 +00:00
{
2020-03-26 22:15:28 +00:00
var link = new Uri ( downloadLink ) ;
2020-11-08 02:11:27 +00:00
var details = new Uri ( detailsStr ) ;
2020-03-26 22:15:28 +00:00
var release = new ReleaseInfo
{
Title = title ,
2020-11-08 02:11:27 +00:00
Details = details ,
2020-03-26 22:15:28 +00:00
Link = link ,
Guid = link ,
Category = MapTrackerCatToNewznab ( cat ) ,
PublishDate = publishDate ,
Size = size ,
Files = 1 ,
Seeders = 1 ,
Peers = 2 ,
DownloadVolumeFactor = 0 ,
2020-10-19 21:19:10 +00:00
UploadVolumeFactor = 1
2020-03-26 22:15:28 +00:00
} ;
2021-02-13 20:57:18 +00:00
return release ;
2020-01-06 22:41:51 +00:00
}
2020-09-12 12:43:25 +00:00
private static string GetDownloadLink ( IParentNode dom ) = >
dom . QuerySelector ( $"a[href*=\" { DownloadLink } \ "]" ) ? . GetAttribute ( "href" ) ;
2020-01-06 22:41:51 +00:00
2020-01-11 07:08:18 +00:00
private static bool CheckTitleMatchWords ( string queryStr , string title )
2020-01-06 22:41:51 +00:00
{
// this code split the words, remove words with 2 letters or less, remove accents and lowercase
2020-01-11 07:08:18 +00:00
var queryMatches = Regex . Matches ( queryStr , @"\b[\w']*\b" ) ;
2020-01-06 22:41:51 +00:00
var queryWords = from m in queryMatches . Cast < Match > ( )
2020-02-09 02:35:16 +00:00
where ! string . IsNullOrEmpty ( m . Value ) & & m . Value . Length > 2
select Encoding . UTF8 . GetString ( Encoding . GetEncoding ( "ISO-8859-8" ) . GetBytes ( m . Value . ToLower ( ) ) ) ;
2020-01-06 22:41:51 +00:00
2020-01-11 07:08:18 +00:00
var titleMatches = Regex . Matches ( title , @"\b[\w']*\b" ) ;
2020-01-06 22:41:51 +00:00
var titleWords = from m in titleMatches . Cast < Match > ( )
2020-02-09 02:35:16 +00:00
where ! string . IsNullOrEmpty ( m . Value ) & & m . Value . Length > 2
select Encoding . UTF8 . GetString ( Encoding . GetEncoding ( "ISO-8859-8" ) . GetBytes ( m . Value . ToLower ( ) ) ) ;
2020-01-06 22:41:51 +00:00
titleWords = titleWords . ToArray ( ) ;
2020-01-11 07:08:18 +00:00
return queryWords . All ( word = > titleWords . Contains ( word ) ) ;
2020-01-06 22:41:51 +00:00
}
2020-01-11 07:48:12 +00:00
private static TorznabQuery ParseQuery ( TorznabQuery query )
{
// Eg. Marco.Polo.2014.S02E08
// the season/episode part is already parsed by Jackett
// query.SanitizedSearchTerm = Marco.Polo.2014.
// query.Season = 2
// query.Episode = 8
var searchTerm = query . SanitizedSearchTerm ;
// replace punctuation symbols with spaces
// searchTerm = Marco Polo 2014
searchTerm = Regex . Replace ( searchTerm , @"[-._\(\)@/\\\[\]\+\%]" , " " ) ;
searchTerm = Regex . Replace ( searchTerm , @"\s+" , " " ) ;
searchTerm = searchTerm . Trim ( ) ;
// we parse the year and remove it from search
// searchTerm = Marco Polo
// query.Year = 2014
var r = new Regex ( "([ ]+([0-9]{4}))$" , RegexOptions . IgnoreCase ) ;
var m = r . Match ( searchTerm ) ;
if ( m . Success )
{
query . Year = int . Parse ( m . Groups [ 2 ] . Value ) ;
searchTerm = searchTerm . Replace ( m . Groups [ 1 ] . Value , "" ) ;
}
// remove some words
searchTerm = Regex . Replace ( searchTerm , @"\b(espa[ñn]ol|spanish|castellano|spa)\b" , "" , RegexOptions . IgnoreCase ) ;
query . SearchTerm = searchTerm ;
return query ;
}
private static string ParseDivxTotalSeriesTitle ( string episodeTitle , TorznabQuery query )
2020-01-06 22:41:51 +00:00
{
2020-01-11 07:48:12 +00:00
// episodeTitle = American Horror Story6x04
2020-01-06 22:41:51 +00:00
var newTitle = episodeTitle ;
try
{
2020-01-11 07:48:12 +00:00
var r = new Regex ( "(([0-9]+)x([0-9]+)[^0-9]*)$" , RegexOptions . IgnoreCase ) ;
2020-01-11 07:08:18 +00:00
var m = r . Match ( newTitle ) ;
2020-01-06 22:41:51 +00:00
if ( m . Success )
{
var season = "S" + m . Groups [ 2 ] . Value . PadLeft ( 2 , '0' ) ;
var episode = "E" + m . Groups [ 3 ] . Value . PadLeft ( 2 , '0' ) ;
2020-01-11 07:48:12 +00:00
// if the original query was in scene format, we have to put the year back
// query.Episode != null means scene title
var year = query . Episode ! = null & & query . Year ! = null ? " " + query . Year : "" ;
newTitle = newTitle . Replace ( m . Groups [ 1 ] . Value , year + " " + season + episode ) ;
2020-01-06 22:41:51 +00:00
}
}
catch ( Exception e )
{
Console . WriteLine ( e ) ;
throw ;
}
2020-01-11 07:48:12 +00:00
newTitle + = " SPANISH SDTV XviD" ;
// return American Horror Story S06E04 SPANISH SDTV XviD
2020-01-06 22:41:51 +00:00
return newTitle ;
}
2020-01-11 07:08:18 +00:00
private static DateTime TryToParseDate ( string dateToParse , DateTime dateDefault )
2020-01-06 22:41:51 +00:00
{
try
{
2020-01-11 07:08:18 +00:00
return DateTime . ParseExact ( dateToParse , "dd-MM-yyyy" , CultureInfo . InvariantCulture ) ;
2020-01-06 22:41:51 +00:00
}
catch
{
2020-07-21 21:00:22 +00:00
return dateDefault ;
2020-01-06 22:41:51 +00:00
}
}
2020-01-11 07:08:18 +00:00
private static long TryToParseSize ( string sizeToParse , long sizeDefault )
2020-01-06 22:41:51 +00:00
{
try
2020-02-09 02:35:16 +00:00
{
2023-02-24 23:22:13 +00:00
var parsedSize = ParseUtil . GetBytes ( sizeToParse ) ;
2020-07-21 21:00:22 +00:00
return parsedSize > 0 ? parsedSize : sizeDefault ;
2020-01-06 22:41:51 +00:00
}
catch
{
2020-07-21 21:00:22 +00:00
return sizeDefault ;
2020-01-06 22:41:51 +00:00
}
}
}
}