diff --git a/src/NzbDrone.Common/Extensions/UrlExtensions.cs b/src/NzbDrone.Common/Extensions/UrlExtensions.cs index d71cfec15..fbe1832a8 100644 --- a/src/NzbDrone.Common/Extensions/UrlExtensions.cs +++ b/src/NzbDrone.Common/Extensions/UrlExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Web; namespace NzbDrone.Common.Extensions { @@ -18,5 +19,24 @@ namespace NzbDrone.Common.Extensions return Uri.TryCreate(path, UriKind.Absolute, out var uri) && uri.IsWellFormedOriginalString(); } + + public static Uri RemoveQueryParam(this Uri url, string name) + { + var uriBuilder = new UriBuilder(url); + var query = HttpUtility.ParseQueryString(uriBuilder.Query); + + query.Remove(name); + uriBuilder.Query = query.ToString() ?? string.Empty; + + return uriBuilder.Uri; + } + + public static string GetQueryParam(this Uri url, string name) + { + var uriBuilder = new UriBuilder(url); + var query = HttpUtility.ParseQueryString(uriBuilder.Query); + + return query[name]; + } } } diff --git a/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs b/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs index e56be44e3..a16adec35 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs @@ -56,11 +56,13 @@ namespace NzbDrone.Core.Indexers.Definitions public override async Task Download(Uri link) { - if (Settings.Freeleech) + var downloadLink = link.RemoveQueryParam("canUseToken"); + + if (Settings.Freeleech && bool.TryParse(link.GetQueryParam("canUseToken"), out var canUseToken) && canUseToken) { - _logger.Debug($"Attempting to use freeleech token for {link.AbsoluteUri}"); + _logger.Debug("Attempting to use freeleech token for {0}", downloadLink.AbsoluteUri); - var idMatch = TorrentIdRegex.Match(link.AbsoluteUri); + var idMatch = TorrentIdRegex.Match(downloadLink.AbsoluteUri); if (idMatch.Success) { var id = int.Parse(idMatch.Groups["id"].Value); @@ -79,20 +81,20 @@ namespace NzbDrone.Core.Indexers.Definitions if (resource.Success) { - _logger.Debug($"Successfully to used freeleech token for torrentid ${id}"); + _logger.Debug("Successfully to used freeleech token for torrentid {0}", id); } else { - _logger.Debug($"Failed to use freeleech token: ${resource.Error}"); + _logger.Debug("Failed to use freeleech token: {0}", resource.Error); } } else { - _logger.Debug($"Could not get torrent id from link ${link.AbsoluteUri}, skipping freeleech"); + _logger.Debug("Could not get torrent id from link {0}, skipping freeleech", downloadLink.AbsoluteUri); } } - return await base.Download(link).ConfigureAwait(false); + return await base.Download(downloadLink).ConfigureAwait(false); } protected override IDictionary GetCookies() @@ -485,8 +487,10 @@ namespace NzbDrone.Core.Indexers.Definitions release.Title += " [VIP]"; } - release.DownloadUrl = _settings.BaseUrl + "tor/download.php?tid=" + id; - release.InfoUrl = _settings.BaseUrl + "t/" + id; + var isFreeLeech = item.Free || item.PersonalFreeLeech || (hasUserVip && item.FreeVip); + + release.DownloadUrl = GetDownloadUrl(id, !isFreeLeech); + release.InfoUrl = $"{_settings.BaseUrl}t/{id}"; release.Guid = release.InfoUrl; release.Categories = _categories.MapTrackerCatToNewznab(item.Category); release.PublishDate = DateTime.ParseExact(item.Added, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime(); @@ -495,7 +499,7 @@ namespace NzbDrone.Core.Indexers.Definitions release.Seeders = item.Seeders; release.Peers = item.Leechers + release.Seeders; release.Size = ParseUtil.GetBytes(item.Size); - release.DownloadVolumeFactor = item.Free ? 0 : hasUserVip && item.FreeVip ? 0 : 1; + release.DownloadVolumeFactor = isFreeLeech ? 0 : 1; release.UploadVolumeFactor = 1; release.MinimumRatio = 1; release.MinimumSeedTime = 259200; // 72 hours @@ -509,6 +513,20 @@ namespace NzbDrone.Core.Indexers.Definitions return releaseInfos.ToArray(); } + private string GetDownloadUrl(int torrentId, bool canUseToken) + { + var url = new HttpUri(_settings.BaseUrl) + .CombinePath("/tor/download.php") + .AddQueryParam("tid", torrentId); + + if (_settings.Freeleech && canUseToken) + { + url = url.AddQueryParam("canUseToken", "true"); + } + + return url.FullUri; + } + private bool HasUserVip(Dictionary cookies) { var cacheKey = "myanonamouse_user_class_" + _settings.ToJson().SHA256Hash(); @@ -587,14 +605,19 @@ namespace NzbDrone.Core.Indexers.Definitions { [FieldOption(Label="All torrents", Hint = "Search everything")] All = 0, + [FieldOption(Label="Only active", Hint = "Last update had 1+ seeders")] Active = 1, + [FieldOption(Label="Freeleech", Hint = "Freeleech torrents")] Freeleech = 2, + [FieldOption(Label="Freeleech or VIP", Hint = "Freeleech or VIP torrents")] FreeleechOrVip = 3, + [FieldOption(Label="VIP", Hint = "VIP torrents")] Vip = 4, + [FieldOption(Label="Not VIP", Hint = "Torrents not VIP")] NotVip = 5, } @@ -611,6 +634,8 @@ namespace NzbDrone.Core.Indexers.Definitions public string Filetype { get; set; } public bool Vip { get; set; } public bool Free { get; set; } + [JsonProperty(PropertyName = "personal_freeleech")] + public bool PersonalFreeLeech { get; set; } [JsonProperty(PropertyName = "fl_vip")] public bool FreeVip { get; set; } public string Category { get; set; }