parent
394544f8a0
commit
639facf933
@ -0,0 +1,267 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using FluentValidation;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.Definitions
|
||||
{
|
||||
public class Milkie : HttpIndexerBase<MilkieSettings>
|
||||
{
|
||||
public override string Name => "Milkie";
|
||||
|
||||
public override string BaseUrl => "https://milkie.cc/";
|
||||
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
|
||||
public override IndexerCapabilities Capabilities => SetCapabilities();
|
||||
|
||||
public Milkie(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
|
||||
: base(httpClient, indexerStatusService, configService, logger)
|
||||
{
|
||||
}
|
||||
|
||||
public override IIndexerRequestGenerator GetRequestGenerator()
|
||||
{
|
||||
return new MilkieRequestGenerator() { Settings = Settings, Capabilities = Capabilities, BaseUrl = BaseUrl };
|
||||
}
|
||||
|
||||
public override IParseIndexerResponse GetParser()
|
||||
{
|
||||
return new MilkieParser(Settings, Capabilities.Categories, BaseUrl);
|
||||
}
|
||||
|
||||
private IndexerCapabilities SetCapabilities()
|
||||
{
|
||||
var caps = new IndexerCapabilities
|
||||
{
|
||||
TvSearchParams = new List<TvSearchParam>
|
||||
{
|
||||
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
|
||||
},
|
||||
MovieSearchParams = new List<MovieSearchParam>
|
||||
{
|
||||
MovieSearchParam.Q
|
||||
},
|
||||
MusicSearchParams = new List<MusicSearchParam>
|
||||
{
|
||||
MusicSearchParam.Q
|
||||
},
|
||||
BookSearchParams = new List<BookSearchParam>
|
||||
{
|
||||
BookSearchParam.Q
|
||||
}
|
||||
};
|
||||
|
||||
caps.Categories.AddCategoryMapping("1", NewznabStandardCategory.Movies, "Movies");
|
||||
caps.Categories.AddCategoryMapping("2", NewznabStandardCategory.TV, "TV");
|
||||
caps.Categories.AddCategoryMapping("3", NewznabStandardCategory.Audio, "Music");
|
||||
caps.Categories.AddCategoryMapping("4", NewznabStandardCategory.PCGames, "Games");
|
||||
caps.Categories.AddCategoryMapping("5", NewznabStandardCategory.Books, "Ebook");
|
||||
caps.Categories.AddCategoryMapping("6", NewznabStandardCategory.PC, "Apps");
|
||||
caps.Categories.AddCategoryMapping("7", NewznabStandardCategory.XXX, "Adult");
|
||||
return caps;
|
||||
}
|
||||
}
|
||||
|
||||
public class MilkieRequestGenerator : IIndexerRequestGenerator
|
||||
{
|
||||
public MilkieSettings Settings { get; set; }
|
||||
public IndexerCapabilities Capabilities { get; set; }
|
||||
public string BaseUrl { get; set; }
|
||||
|
||||
public MilkieRequestGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
private IEnumerable<IndexerRequest> GetPagedRequests(string term, int[] categories, string imdbId = null)
|
||||
{
|
||||
var searchUrl = BaseUrl + "api/v1/torrents";
|
||||
|
||||
var qc = new NameValueCollection
|
||||
{
|
||||
{ "ps", "100" }
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(term))
|
||||
{
|
||||
qc.Add("query", term);
|
||||
}
|
||||
|
||||
if (categories != null && categories.Length > 0)
|
||||
{
|
||||
qc.Add("categories", string.Join(",", Capabilities.Categories.MapTorznabCapsToTrackers(categories)));
|
||||
}
|
||||
|
||||
searchUrl = searchUrl + "?" + qc.GetQueryString();
|
||||
|
||||
var request = new IndexerRequest(searchUrl, HttpAccept.Json);
|
||||
|
||||
request.HttpRequest.Headers.Add("x-milkie-auth", Settings.ApiKey);
|
||||
|
||||
yield return request;
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SearchTerm), searchCriteria.Categories, searchCriteria.ImdbId));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SearchTerm), searchCriteria.Categories));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SearchTerm), searchCriteria.Categories, searchCriteria.ImdbId));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SearchTerm), searchCriteria.Categories));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SearchTerm), searchCriteria.Categories));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public Func<IDictionary<string, string>> GetCookies { get; set; }
|
||||
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
|
||||
}
|
||||
|
||||
public class MilkieParser : IParseIndexerResponse
|
||||
{
|
||||
private readonly MilkieSettings _settings;
|
||||
private readonly IndexerCapabilitiesCategories _categories;
|
||||
private readonly string _baseUrl;
|
||||
|
||||
public MilkieParser(MilkieSettings settings, IndexerCapabilitiesCategories categories, string baseUrl)
|
||||
{
|
||||
_settings = settings;
|
||||
_categories = categories;
|
||||
_baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
|
||||
{
|
||||
var torrentInfos = new List<TorrentInfo>();
|
||||
|
||||
var response = JsonConvert.DeserializeObject<MilkieResponse>(indexerResponse.Content);
|
||||
|
||||
var dlQueryParams = new NameValueCollection
|
||||
{
|
||||
{ "key", _settings.ApiKey }
|
||||
};
|
||||
|
||||
foreach (var torrent in response.Torrents)
|
||||
{
|
||||
var torrentUrl = _baseUrl + "api/v1/torrents";
|
||||
var link = $"{torrentUrl}/{torrent.Id}/torrent?{dlQueryParams.GetQueryString()}";
|
||||
var details = $"{_baseUrl}browse/{torrent.Id}";
|
||||
var publishDate = DateTimeUtil.FromUnknown(torrent.CreatedAt);
|
||||
|
||||
var release = new TorrentInfo
|
||||
{
|
||||
Title = torrent.ReleaseName,
|
||||
DownloadUrl = link,
|
||||
InfoUrl = details,
|
||||
Guid = details,
|
||||
PublishDate = publishDate,
|
||||
Category = _categories.MapTrackerCatToNewznab(torrent.Category.ToString()),
|
||||
Size = torrent.Size,
|
||||
Seeders = torrent.Seeders,
|
||||
Peers = torrent.Seeders + torrent.PartialSeeders + torrent.Leechers,
|
||||
Grabs = torrent.Downloaded,
|
||||
UploadVolumeFactor = 1,
|
||||
DownloadVolumeFactor = 0,
|
||||
MinimumRatio = 1,
|
||||
MinimumSeedTime = 172800 // 48 hours
|
||||
};
|
||||
|
||||
torrentInfos.Add(release);
|
||||
}
|
||||
|
||||
return torrentInfos.ToArray();
|
||||
}
|
||||
|
||||
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
|
||||
}
|
||||
|
||||
public class MilkieSettingsValidator : AbstractValidator<MilkieSettings>
|
||||
{
|
||||
public MilkieSettingsValidator()
|
||||
{
|
||||
RuleFor(c => c.ApiKey).NotEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public class MilkieSettings : IProviderConfig
|
||||
{
|
||||
private static readonly MilkieSettingsValidator Validator = new MilkieSettingsValidator();
|
||||
|
||||
public MilkieSettings()
|
||||
{
|
||||
ApiKey = "";
|
||||
}
|
||||
|
||||
public string BaseUrl { get; set; }
|
||||
|
||||
[FieldDefinition(1, Label = "Apikey", HelpText = "Site ApiKey", Privacy = PrivacyLevel.ApiKey)]
|
||||
public string ApiKey { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
|
||||
public class MilkieResponse
|
||||
{
|
||||
public int Hits { get; set; }
|
||||
public int Took { get; set; }
|
||||
public MilkieTorrent[] Torrents { get; set; }
|
||||
}
|
||||
|
||||
public class MilkieTorrent
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string ReleaseName { get; set; }
|
||||
public int Category { get; set; }
|
||||
public int Downloaded { get; set; }
|
||||
public int Seeders { get; set; }
|
||||
public int PartialSeeders { get; set; }
|
||||
public int Leechers { get; set; }
|
||||
public long Size { get; set; }
|
||||
public string CreatedAt { get; set; }
|
||||
}
|
||||
}
|
Loading…
Reference in new issue