module sites.nhentai; import config.downloaderconfig; import sites.basesite; /++ + This class handles downloads for the site `nhentai.net` +/ class NHentai : BaseSite { import std.conv : to; import std.regex : regex, match; import std.net.curl : get; import core.stdc.stdlib : exit, EXIT_FAILURE; /++ + This is the base url for all images +/ immutable string imageUrl = "https://i.nhentai.net/galleries/"; /++ + This function gets the name of the the manga by the url +/ override string getNameFromUrl(string url) { // Get the site content string siteContent = to!string(get(url)); // Find the name of the manga auto nameRegex = `

(.*)

`.regex; auto nameMatch = match(siteContent, nameRegex); // Return only the name not the hmtl tags return nameMatch.captures[1]; } override string[] getImageUrlsFromBase(string url) { // Check if the url is a nhentai url if(indexOf(url, "/g/") == -1) { writefln(`[!] The given url doesn't contain "/g/" it was ignored!`); // FIXME: no! :< exit(EXIT_FAILURE); } // Regex patterns for finding ulrs and stuff auto contentIDRegex = "https://t.nhentai.net/galleries/([0-9].*)/cover.jpg"; auto pageCountRegex = "
([0-9].*) pages
"; // Download the hmtl auto coverHtml = to!string(get(url)); // Find the content id auto contentIDMatch = match(coverHtml, contentIDRegex).captures[1]; writeln(contentIDMatch); // Find the number of pages auto pageNumberMatch = match(coverHtml, pageCountRegex).captures[1]; // Convert the page number to an integer immutable int pageNumber = to!int(pageNumberMatch); // Generate a list of all the images string[] urls; for(int i = 1; i < pageNumber; i++) { // Craft the url with all parameters urls ~= imageUrl ~ contentIDMatch ~ "/" ~ to!string(i) ~ ".jpg"; } return urls; } /++ + This constructor just calls the inherited constructor +/ public this(Config config) { super(config); } }