nhentai-api-tiffceet-patch
Version:
nHentai Node.JS API client.
412 lines (350 loc) • 20.1 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>Source: api.js | nhentai-api</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/prettify-jsdoc.css">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/tui-doc.css">
</head>
<body>
<nav class="lnb" id="lnb">
<div class="logo" style="width: 65px; height: 13px">
<a href="index.html" rel="noopener noreferrer" target="_blank">
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCA1Ij48dGV4dCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjEwMCUiIGZpbGw9IndoaXRlIiB0ZXh0TGVuZ3RoPSIzMCIgZm9udC1zaXplPSI1IiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgc3R5bGU9InRleHQtdHJhbnNmb3JtOnVwcGVyY2FzZSI+bmhlbnRhaS1hcGk8L3RleHQ+PC9zdmc+" width="100%" height="100%">
</a>
</div>
<div class="title">
<h1><a href="index.html" class="link">nhentai-api</a></h1>
<span class="version">v3.0.2</span>
</div>
<div class="search-container" id="search-container">
<input type="text" placeholder="Search">
<ul></ul>
</div>
<div class="lnb-api hidden"><h3>Modules</h3><ul><li><a href="module-API.html">API</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:API_sub"><div class="member-type">Typedef</div><ul class="inner"><li><a href="module-API.html#~APIArgs">APIArgs</a></li></ul></div></li><li><a href="module-Book.html">Book</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Book_sub"><div class="member-type">Typedef</div><ul class="inner"><li><a href="module-Book.html#~BookTitle">BookTitle</a></li></ul></div></li><li><a href="module-Image.html">Image</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Image_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="module-Image.html#~known">known</a></li></ul><div class="member-type">Methods</div><ul class="inner"><li><a href="module-Image.html#~get">get</a></li></ul><div class="member-type">Typedef</div><ul class="inner"><li><a href="module-Image.html#~ImageTypes">ImageTypes</a></li></ul></div></li><li><a href="module-Search.html">Search</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Search_sub"></div></li><li><a href="module-Tag.html">Tag</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Tag_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="module-Tag.html#~known">known</a></li></ul><div class="member-type">Methods</div><ul class="inner"><li><a href="module-Tag.html#~get">get</a></li></ul><div class="member-type">Typedef</div><ul class="inner"><li><a href="module-Tag.html#~TagTypes">TagTypes</a></li></ul></div></li></ul></div><div class="lnb-api hidden"><h3>Classes</h3><ul><li><a href="module-API-API.html">API</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:API~API_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="module-API-API.html#APIPath">APIPath</a></li><li><a href="module-API-API.html#net">net</a></li></ul><div class="member-type">Methods</div><ul class="inner"><li><a href="module-API-API.html#getAPIArgs">getAPIArgs</a></li><li><a href="module-API-API.html#getBook">getBook</a></li><li><a href="module-API-API.html#getImageURL">getImageURL</a></li><li><a href="module-API-API.html#getThumbURL">getThumbURL</a></li><li><a href="module-API-API.html#request">request</a></li><li><a href="module-API-API.html#search">search</a></li><li><a href="module-API-API.html#searchAlike">searchAlike</a></li><li><a href="module-API-API.html#searchTagged">searchTagged</a></li></ul></div></li><li><a href="module-API-APIPath.html">APIPath</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:API~APIPath_sub"><div class="member-type">Methods</div><ul class="inner"><li><a href="module-API-APIPath.html#.book">book</a></li><li><a href="module-API-APIPath.html#.bookCover">bookCover</a></li><li><a href="module-API-APIPath.html#.bookPage">bookPage</a></li><li><a href="module-API-APIPath.html#.bookThumb">bookThumb</a></li><li><a href="module-API-APIPath.html#.search">search</a></li><li><a href="module-API-APIPath.html#.searchAlike">searchAlike</a></li><li><a href="module-API-APIPath.html#.searchTagged">searchTagged</a></li></ul></div></li><li><a href="module-Book-Book.html">Book</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Book~Book_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="module-Book-Book.html#cover">cover</a></li><li><a href="module-Book-Book.html#favorites">favorites</a></li><li><a href="module-Book-Book.html#id">id</a></li><li><a href="module-Book-Book.html#isKnown">isKnown</a></li><li><a href="module-Book-Book.html#media">media</a></li><li><a href="module-Book-Book.html#pages">pages</a></li><li><a href="module-Book-Book.html#scanlator">scanlator</a></li><li><a href="module-Book-Book.html#tags">tags</a></li><li><a href="module-Book-Book.html#title">title</a></li><li><a href="module-Book-Book.html#Unknown">Unknown</a></li><li><a href="module-Book-Book.html#UnknownBook">UnknownBook</a></li><li><a href="module-Book-Book.html#uploaded">uploaded</a></li></ul><div class="member-type">Methods</div><ul class="inner"><li><a href="module-Book-Book.html#.parse">parse</a></li><li><a href="module-Book-Book.html#hasTag">hasTag</a></li><li><a href="module-Book-Book.html#hasTagWith">hasTagWith</a></li><li><a href="module-Book-Book.html#pushPage">pushPage</a></li><li><a href="module-Book-Book.html#pushTag">pushTag</a></li><li><a href="module-Book-Book.html#setCover">setCover</a></li></ul></div></li><li><a href="module-Book-UnknownBook.html">UnknownBook</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Book~UnknownBook_sub"></div></li><li><a href="module-Image-Image.html">Image</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Image~Image_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="module-Image-Image.html#book">book</a></li><li><a href="module-Image-Image.html#filename">filename</a></li><li><a href="module-Image-Image.html#height">height</a></li><li><a href="module-Image-Image.html#id">id</a></li><li><a href="module-Image-Image.html#isCover">isCover</a></li><li><a href="module-Image-Image.html#type">type</a></li><li><a href="module-Image-Image.html#types">types</a></li><li><a href="module-Image-Image.html#width">width</a></li></ul><div class="member-type">Methods</div><ul class="inner"><li><a href="module-Image-Image.html#.parse">parse</a></li></ul></div></li><li><a href="module-Image-ImageType.html">ImageType</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Image~ImageType_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="module-Image-ImageType.html#extension">extension</a></li><li><a href="module-Image-ImageType.html#isKnown">isKnown</a></li><li><a href="module-Image-ImageType.html#knownTypes">knownTypes</a></li><li><a href="module-Image-ImageType.html#type">type</a></li></ul></div></li><li><a href="module-Image-UnknownImageType.html">UnknownImageType</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Image~UnknownImageType_sub"></div></li><li><a href="module-Search-Search.html">Search</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Search~Search_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="module-Search-Search.html#books">books</a></li><li><a href="module-Search-Search.html#page">page</a></li><li><a href="module-Search-Search.html#pages">pages</a></li><li><a href="module-Search-Search.html#perPage">perPage</a></li></ul><div class="member-type">Methods</div><ul class="inner"><li><a href="module-Search-Search.html#.parse">parse</a></li><li><a href="module-Search-Search.html#pushBook">pushBook</a></li></ul></div></li><li><a href="module-Tag-Tag.html">Tag</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Tag~Tag_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="module-Tag-Tag.html#types">types</a></li></ul><div class="member-type">Methods</div><ul class="inner"><li><a href="module-Tag-Tag.html#.get">get</a></li><li><a href="module-Tag-Tag.html#compare">compare</a></li></ul></div></li><li><a href="module-Tag-TagType.html">TagType</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Tag~TagType_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="module-Tag-TagType.html#isKnown">isKnown</a></li><li><a href="module-Tag-TagType.html#knownTypes">knownTypes</a></li><li><a href="module-Tag-TagType.html#type">type</a></li></ul></div></li><li><a href="module-Tag-UnknownTagType.html">UnknownTagType</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="module:Tag~UnknownTagType_sub"></div></li></ul></div><div class="lnb-api hidden"><h3>Global</h3><ul><li class="hidden"><a href="global.html#APIBook">APIBook</a></li><li class="hidden"><a href="global.html#APIImage">APIImage</a></li><li class="hidden"><a href="global.html#APISearch">APISearch</a></li><li class="hidden"><a href="global.html#APITag">APITag</a></li><li class="hidden"><a href="global.html#httpAgent">httpAgent</a></li><li class="hidden"><a href="global.html#nHentaiHosts">nHentaiHosts</a></li><li class="hidden"><a href="global.html#nHentaiOptions">nHentaiOptions</a></li><li><a href="global.html#processOptions">processOptions</a></li></ul></div>
</nav>
<div id="resizer"></div>
<div class="main" id="main">
<section>
<article>
<pre class="prettyprint source linenums"><code>/**
* @module API
*/
import processOptions from './options';
import http from 'http';
import https from 'https';
import { version, } from '../package.json';
import Search from './search';
import Book from './book';
import Tag from './tag';
import Image from './image';
/**
* API arguments
* @typedef {object} APIArgs
* @property {string} host API host.
* @property {Function} apiPath API endpoint URL path generator.
*/
/**
* Class used for building URL paths to nHentai API endpoints.
* This class is internal and has only static methods.
* @class
*/
class APIPath {
/**
* Search by query endpoint.
* @param {string} query Search query.
* @param {number} [page=1] Page ID.
* @returns {string} URL path.
*/
static search(query, page = 1) {
return `/api/galleries/search?query=${query}&page=${page}`;
}
/**
* Search by tag endpoint.
* @param {number} tagID Tag ID.
* @param {number} [page=1] Page ID.
* @returns {string} URL path.
*/
static searchTagged(tagID, page = 1) {
return `/api/galleries/tagged?tag_id=${tagID}&page=${page}`;
}
/**
* Search alike endpoint.
* @param {number} bookID Book ID.
* @returns {string} URL path.
*/
static searchAlike(bookID) {
return `/api/gallery/${bookID}/related`;
}
/**
* Book content endpoint.
* @param {number} bookID Book ID.
* @returns {string} URL path.
*/
static book(bookID) {
return `/api/gallery/${bookID}`;
}
/**
* Book's cover image endpoint.
* @param {number} mediaID Media ID.
* @param {string} extension Image extension.
* @returns {string} URL path.
*/
static bookCover(mediaID, extension) {
return `/galleries/${mediaID}/cover.${extension}`;
}
/**
* Book's page image endpoint.
* @param {number} mediaID Media ID.
* @param {number} page Page ID.
* @param {string} extension Image extension.
* @returns {string} URL path.
*/
static bookPage(mediaID, page, extension) {
return `/galleries/${mediaID}/${page}.${extension}`;
}
/**
* Book's page's thumbnail image endpoint.
* @param {number} mediaID Media ID.
* @param {number} page Page ID.
* @param {string} extension Image extension.
* @returns {string} URL path.
*/
static bookThumb(mediaID, page, extension) {
return `/galleries/${mediaID}/${page}t.${extension}`;
}
}
/**
* Class used for interaction with nHentai API.
* @class
*/
class API {
/**
* API path class
* @type {APIPath}
* @static
* @private
*/
static APIPath = APIPath;
/**
* Applies provided options on top of defaults.
* @param {nHentaiOptions} options Options to apply.
*/
constructor(options = {}) {
let params = processOptions(options);
Object.assign(this, params);
}
/**
* Get http(s) module depending on `options.ssl`.
* @type {https|http}
*/
get net() {
return this.ssl
? https
: http;
}
/**
* JSON get request.
* @param {object} options HTTP(S) request options.
* @param {string} options.host Host.
* @param {string} options.path Path.
* @returns {Promise<object>} Parsed JSON.
*/
request(options) {
let {
net,
agent,
} = this;
return new Promise((resolve, reject) => {
Object.assign(options, {
agent,
headers: {
'User-Agent': `nhentai-api-client/${version} Node.js/${process.versions.node}`,
},
});
net.get(options, response => {
const
{ statusCode, } = response,
contentType = response.headers['content-type'];
let error;
if (statusCode !== 200)
error = new Error(`Request failed with status code ${statusCode}`);
else if (!(/^application\/json/).test(contentType))
error = new Error(`Invalid content-type - expected application/json but received ${contentType}`);
if (error) {
response.resume();
reject(error);
return;
}
response.setEncoding('utf8');
let rawData = '';
response.on('data', (chunk) => rawData += chunk);
response.on('end', () => {
try {
resolve(JSON.parse(rawData));
} catch (error) {
reject(error);
}
});
}).on('error', error => reject(error));
});
}
/**
* Get API arguments.
* This is internal method.
* @param {string} hostType Host type.
* @param {string} api Endpoint type.
* @returns {APIArgs} API arguments.
* @private
*/
getAPIArgs(hostType, api) {
let {
hosts: {
[hostType]: host,
},
constructor: {
APIPath: {
[api]: apiPath,
},
},
} = this;
return {
host,
apiPath,
};
}
/**
* Search by query.
* @param {string} query Query.
* @param {number} [page=1] Page ID.
* @returns {Promise<Search>} Search instance.
* @async
*/
async search(query, page = 1) {
let { host, apiPath, } = this.getAPIArgs('api', 'search'),
search = Search.parse(
await this.request({
host,
path: apiPath(query, page),
})
);
search.page = page;
return search;
}
/**
* Search related books.
* @param {number|Book} book Book instance or Book ID.
* @returns {Promise<Search>} Search instance.
* @async
*/
async searchAlike(book) {
let { host, apiPath, } = this.getAPIArgs('api', 'searchAlike');
return Search.parse(
await this.request({
host,
path: apiPath(
book instanceof Book
? book.id
: +book
),
})
);
}
/**
* Search by tag id.
* @param {number|Tag} tag Tag or Tag ID.
* @param {number} [page=1] Page ID.
* @returns {Promise<Search>} Search instance.
* @async
*/
async searchTagged(tag, page = 1) {
let { host, apiPath, } = this.getAPIArgs('api', 'searchTagged'),
search = Search.parse(
await this.request({
host,
path: apiPath(
tag instanceof Tag
? tag.id
: +tag,
page
),
})
);
search.page = page;
return search;
}
/**
* Get book by id.
* @param {number} bookID Book ID.
* @returns {Promise<Book>} Book instance.
* @async
*/
async getBook(bookID) {
let { host, apiPath, } = this.getAPIArgs('api', 'book');
return Book.parse(
await this.request({
host,
path: apiPath(bookID),
})
);
}
/**
* Get image URL.
* @param {Image} image Image.
* @returns {string} Image URL.
*/
getImageURL(image) {
if (image instanceof Image) {
let { host, apiPath, } = image.isCover
? this.getAPIArgs('thumbs', 'bookCover')
: this.getAPIArgs('images', 'bookPage');
return `http${this.ssl ? 's' : ''}://${host}` + (image.isCover
? apiPath(image.book.media, image.type.extension)
: apiPath(image.book.media, image.id, image.type.extension));
}
throw new Error('image must be Image instance.');
}
/**
* Get image thumbnail URL.
* @param {Image} image Image.
* @returns {string} Image thumbnail URL.
*/
getThumbURL(image) {
if (image instanceof Image && !image.isCover) {
let { host, apiPath, } = this.getAPIArgs('thumbs', 'bookThumb');
return `http${this.ssl ? 's' : ''}://${host}`
+ apiPath(image.book.media, image.id, image.type.extension);
}
throw new Error('image must be Image instance and not book cover.');
}
}
export default API;
</code></pre>
</article>
</section>
</div>
<footer>
<img class="logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCA1Ij48dGV4dCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjAiIHk9IjEwMCUiIGZpbGw9IndoaXRlIiB0ZXh0TGVuZ3RoPSIzMCIgZm9udC1zaXplPSI1IiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiIgc3R5bGU9InRleHQtdHJhbnNmb3JtOnVwcGVyY2FzZSI+bmhlbnRhaS1hcGk8L3RleHQ+PC9zdmc+" style="width: 65px; height: 13px">
<div class="footer-text">nhentai-api</div>
</footer>
<script>prettyPrint();</script>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tui-doc.js"></script>
<script src="scripts/linenumber.js"></script>
<script>
var id = '_sub'.replace(/"/g, '_');
var selectedApi = document.getElementById(id); // do not use jquery selector
var $selectedApi = $(selectedApi);
$selectedApi.removeClass('hidden');
$selectedApi.parent().find('.glyphicon').removeClass('glyphicon-plus').addClass('glyphicon-minus');
showLnbApi();
</script>
</body>
</html>