diff --git a/library/index.d.ts b/library/index.d.ts index dc2b8cf..e72ab4f 100644 --- a/library/index.d.ts +++ b/library/index.d.ts @@ -1,8 +1,8 @@ export as namespace hitomi; interface PageRange { - startPage: number; - endPage?: number; + startIndex: number; + endIndex?: number; } export interface Image { diff --git a/library/index.js b/library/index.js index 414a078..31882ce 100644 --- a/library/index.js +++ b/library/index.js @@ -1 +1 @@ -"use strict";var __awaiter=this&&this.__awaiter||function(e,t,r,a){return new(r||(r=Promise))(function(n,i){function l(e){try{s(a.next(e))}catch(e){i(e)}}function o(e){try{s(a.throw(e))}catch(e){i(e)}}function s(e){var t;e.done?n(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(l,o)}s((a=a.apply(e,t||[])).next())})},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.queryTag=exports.parseTag=exports.getGalleryIdList=exports.getGalleryData=exports.getNozomiUrl=exports.getGalleryUrl=exports.getImageUrl=void 0;const https_1=__importDefault(require("https")),tls_1=__importDefault(require("tls")),node_fetch_1=__importDefault(require("node-fetch"));Number.isInteger=function(e){return!(Number.parseInt(e)!==Number(e)||!Number.isFinite(e)||"object"==typeof e)};class Agent extends https_1.default.Agent{createConnection(e,t){return e.servername=void 0,tls_1.default.connect(e,t)}}const requestOption={method:"GET",agent:new Agent({rejectUnauthorized:!1,keepAlive:!0}),headers:{Accept:"*/*","Accept-Encoding":"gzip, deflate, br",Connection:"keep-alive"}};function getImageUrl(e,t,r){const a=void 0!==r&&r.isThumbnail;switch(t){case"jpg":if(a||"jpg"===e.extension)break;throw Error("Invalid extension");case"png":if("png"!==e.extension)throw Error("Invalid extension");if(a)throw Error("Invalid extension for thumbnail");break;case"avif":if(e.hasAvif)break;throw Error("Invalid extension");case"webp":if(e.hasWebp){if(a)throw Error("Invalid extension for thumbnail");break}throw Error("Invalid extension")}if(!/^[0-9a-f]{64}$/.test(e.hash))throw Error("Invalid hash value");if(!Number.isInteger(e.index)||e.index<0)throw Error("Invalid image index");if(a&&0!==e.index)throw Error("Invalid index for thumbnail");const n=`${e.hash.slice(-1)}/${e.hash.slice(-3,-1)}/${e.hash}`;let i,l;if(a)i="tn",l="jpg"===t||"png"===t?"bigtn":"avifbigtn";else{let r=3,a=Number.parseInt(e.hash.slice(-3,-1),16);a<48&&(r=2),a<9&&(a=1),i=`${String.fromCharCode(a%r+97)}`,"jpg"===t||"png"===t?(i+="b",l="images"):(i+="a",l=`${t}`)}return`https://${i}.hitomi.la/${l}/${n}.${t}`}function getGalleryUrl(e){const t=encodeURIComponent(null!==e.titleJapanese?e.titleJapanese:e.title).replace(/\(|\)|'|%(2(0|2|3|5|F)|3(C|E|F)|5(B|D)|7(B|D))/g,"-"),r=null!==e.languageLocalName?`-${encodeURIComponent(e.languageLocalName)}`:"";return`https://hitomi.la/${e.type}/${t}${r}-${e.id}.html`.toLocaleLowerCase()}function getNozomiUrl(e){let t="",r="",a="all";switch(e.type){case"male":case"female":t="tag/",r=`${e.type}:${e.name.replace(/_/g," ")}`;break;case"language":r="index",a=e.name;break;default:t=`${e.type}/`,r=e.name.replace(/_/g," ")}return`https://ltn.hitomi.la/n/${t}${r}-${a}.nozomi`}function getGalleryData(e,t){if(!Number.isInteger(e)||Number.isInteger(e)&&e<1)throw Error("Invalid id value");const r=void 0===t||t.includeFiles;return new Promise(function(t,a){try{node_fetch_1.default(`https://ltn.hitomi.la/galleries/${e}.js`,requestOption).then(function(e){return e.text()}).then(function(e){const a=JSON.parse(e.slice(18));let n={id:a.id,title:a.title,titleJapanese:a.japanese_title,type:a.type,language:a.language,languageLocalName:a.language_localname,artists:[],groups:[],series:[],characters:[],tags:[],files:null,publishedDate:new Date(`${a.date}:00`.replace(" ","T"))};for(let e=0;e')[1];return void 0===o?void t(n):(null===(r=o.match(/(?<=\/artist\/)[a-z0-9%]+(?=-all\.html)/g))||void 0===r||r.map(function(e,t,r){null===n.artists&&(n.artists=[]),n.artists.push(decodeURIComponent(e))}),null===(a=o.match(/(?<=\/group\/)[a-z0-9%]+(?=-all\.html)/g))||void 0===a||a.map(function(e,t,r){null===n.groups&&(n.groups=[]),n.groups.push(decodeURIComponent(e))}),null===(i=o.match(/(?<=\/series\/)[a-z0-9%]+(?=-all\.html)/g))||void 0===i||i.map(function(e,t,r){null===n.series&&(n.series=[]),n.series.push(decodeURIComponent(e))}),null===(l=o.match(/(?<=\/character\/)[a-z0-9%]+(?=-all\.html)/g))||void 0===l||l.map(function(e,t,r){null===n.characters&&(n.characters=[]),n.characters.push(decodeURIComponent(e))}),void t(n))})})}catch(e){return void a(e)}})}function getGalleryIdList(e,t){if(!Number.isInteger(e.startPage)||Number.isInteger(e.startPage)&&e.startPage<0)throw Error("Invalid startPage value");if(void 0!==e.endPage&&(!Number.isInteger(e.endPage)||Number.isInteger(e.endPage)&&e.endPage<=e.startPage))throw Error("Invalid endPage value");return new Promise(function(r,a){try{const n=4*e.startPage,i=void 0!==e.endPage?n+4*e.endPage-1:"",l=void 0!==t&&t.reverse;node_fetch_1.default("https://ltn.hitomi.la/index-all.nozomi",Object.assign(Object.assign({},requestOption),{headers:{Range:`bytes=${n}-${i}`}})).then(function(e){return e.arrayBuffer()}).then(function(e){const t=new DataView(e),a=t.byteLength/4;let n=[];if(l)for(let e=0;e')[1];void 0!==o&&(null===(n=o.match(/(?<=\/artist\/)[a-z0-9%]+(?=-all\.html)/g))||void 0===n||n.map(function(e,t,n){a.artists.push(decodeURIComponent(e))}),null===(r=o.match(/(?<=\/group\/)[a-z0-9%]+(?=-all\.html)/g))||void 0===r||r.map(function(e,t,n){a.groups.push(decodeURIComponent(e))}),null===(i=o.match(/(?<=\/series\/)[a-z0-9%]+(?=-all\.html)/g))||void 0===i||i.map(function(e,t,n){a.series.push(decodeURIComponent(e))}),null===(l=o.match(/(?<=\/character\/)[a-z0-9%]+(?=-all\.html)/g))||void 0===l||l.map(function(e,t,n){a.characters.push(decodeURIComponent(e))})),t(a)})})}catch(e){return void r(e)}})}function getGalleryIdList(e,t){if(!Number.isInteger(e.startIndex)||Number.isInteger(e.startIndex)&&e.startIndex<0)throw Error("Invalid startIndex value");if(void 0!==e.endIndex&&(!Number.isInteger(e.endIndex)||Number.isInteger(e.endIndex)&&e.endIndex<=e.startIndex))throw Error("Invalid endIndex value");return new Promise(function(n,r){try{const a=4*e.startIndex,i=void 0!==e.endIndex?a+4*(e.endIndex+1)-1:"",l=void 0!==t&&t.reverse;node_fetch_1.default("https://ltn.hitomi.la/index-all.nozomi",Object.assign(Object.assign({},requestOption),{headers:{Range:`bytes=${a}-${i}`}})).then(function(e){return e.arrayBuffer()}).then(function(e){const t=new DataView(e),r=t.byteLength/4;let a=[];if(l)for(let e=0;e { - return _response.text() + return _response.text(); }) .then(function (_responseText: string): void | PromiseLike { const galleryContentHtml: string = _responseText.split('content">')[1]; - if(typeof(galleryContentHtml) === 'undefined') { - resolve(galleryData); - return; - } else { + if(typeof(galleryContentHtml) !== 'undefined') { galleryContentHtml.match(/(?<=\/artist\/)[a-z0-9%]+(?=-all\.html)/g) ?.map(function (value: string, index: number, array: string[]): void { - if(galleryData['artists'] === null) { - galleryData['artists'] = []; - } - galleryData['artists'].push(decodeURIComponent(value)); }); galleryContentHtml.match(/(?<=\/group\/)[a-z0-9%]+(?=-all\.html)/g) ?.map(function (value: string, index: number, array: string[]): void { - if(galleryData['groups'] === null) { - galleryData['groups'] = []; - } - galleryData['groups'].push(decodeURIComponent(value)); }); galleryContentHtml.match(/(?<=\/series\/)[a-z0-9%]+(?=-all\.html)/g) ?.map(function (value: string, index: number, array: string[]): void { - if(galleryData['series'] === null) { - galleryData['series'] = []; - } - galleryData['series'].push(decodeURIComponent(value)); }); galleryContentHtml.match(/(?<=\/character\/)[a-z0-9%]+(?=-all\.html)/g) ?.map(function (value: string, index: number, array: string[]): void { - if(galleryData['characters'] === null) { - galleryData['characters'] = []; - } - galleryData['characters'].push(decodeURIComponent(value)); }); - - resolve(galleryData); - return; } + + resolve(galleryData); + return; }); }); } catch(error: any) { reject(error); return; } - }) + }); } export function getGalleryIdList(range: PageRange, option?: { reverse: boolean; }): Promise { - if(!Number.isInteger(range['startPage']) || (Number.isInteger(range['startPage']) && range['startPage'] < 0)) { - throw Error('Invalid startPage value'); - } else if(typeof(range['endPage']) !== 'undefined' && (!Number.isInteger(range['endPage']) || (Number.isInteger(range['endPage']) && range['endPage'] <= range['startPage']))) { - throw Error('Invalid endPage value'); + if(!Number.isInteger(range['startIndex']) || (Number.isInteger(range['startIndex']) && range['startIndex'] < 0)) { + throw Error('Invalid startIndex value'); + } else if(typeof(range['endIndex']) !== 'undefined' && (!Number.isInteger(range['endIndex']) || (Number.isInteger(range['endIndex']) && range['endIndex'] <= range['startIndex']))) { + throw Error('Invalid endIndex value'); } return new Promise(function (resolve: (value: number[] | PromiseLike) => void, reject: (reason: any) => void) { try { - const startByte: number = range['startPage'] * 4; - const endByte: number | string = typeof(range['endPage']) !== 'undefined' ? startByte + range['endPage'] * 4 - 1 : ''; + const startByte: number = range['startIndex'] * 4; + const endByte: number | string = typeof(range['endIndex']) !== 'undefined' ? startByte + (range['endIndex'] + 1) * 4 - 1 : ''; const reverse: boolean = typeof(option) !== 'undefined' ? option['reverse'] : false; fetch('https://ltn.hitomi.la/index-all.nozomi', { @@ -389,7 +372,7 @@ export function parseTag(tagString: string): Tag[] { type: type, name: name, isNegative: tagStringList[i].startsWith('-') - }) + }); } return tagList; @@ -421,7 +404,7 @@ export function queryTag(tagList: Tag[]): Promise { let idList: number[] = []; if(positiveTagList.length === 0) { - idList = await getGalleryIdList({ startPage: 0 }); + idList = await getGalleryIdList({ startIndex: 0 }); } for(let i = 0; i < positiveTagList.length; i++) {