@spacepumpkin/modified-nyaapi
Version:
Non-official api for getting torrent links from Nyaa.si and Nyaa.pantsu.cat
318 lines (272 loc) • 8.31 kB
JavaScript
const { extractFromHTML } = require('./scrap.js')
const URI = require('./url.json').url
const timeout = (time) => new Promise(resolve => setTimeout(resolve, time))
const { request } = require('@spacepumpkin/proxy-gateway')
const getResultsFromHTML = (url, includeMaxPage) => {
return new Promise((resolve, reject) => {
request(url)
.then((data) => {
const results = extractFromHTML(data.body, includeMaxPage)
resolve(results)
})
.catch(/* istanbul ignore next */(err) => reject(err))
})
}
/**
* Allows to scrap only one specific page of a research.
*
* @param {string} term Keywords describing the research.
* @param {number} p The page you want to look for.
* @param {object} opts Research options as described on the documentation.
*
* @returns {promise}
*/
const searchPage = (term = '', p, opts = {}, includeMaxPage) => {
return new Promise((resolve, reject) => {
if (!term) {
reject(new Error('[Nyaapi]: No term was given on search demand.'))
return
}
if (typeof term === 'object') {
opts = term
term = opts.term
p = p || opts.p
}
if (!p) {
reject(new Error('[Nyaapi]: No page number was given on search page demand.'))
return
}
const querystring = buildQueryString({
f: opts.filter || 0,
c: opts.category || '1_0',
q: term,
p: p,
s: opts.sort || 'id',
o: opts.direction || 'desc'
})
getResultsFromHTML(`${URI}${querystring}`, includeMaxPage).then(results => {
resolve(results)
}).catch(err => {
reject(err)
})
})
}
const buildQueryString = (qs) => {
return `?${Object.keys(qs).map(key => `${key}=${qs[key]}`).join('&')}`
}
/**
*
* Research anything you desire on nyaa.si and get all the results.
*
* @param {string} term Keywords describing the research.
* @param {Object} opts Research options as described on the documentation.
*
* @returns {promise}
*/
const searchAll = async (term = '', opts = {}) => {
if (!term || (typeof term === 'object' && !term.term)) {
throw new Error('[Nyaapi]: No search term was given.')
}
if (typeof term === 'object') {
opts = term
term = opts.term
}
const { results: allResults, maxPage } = await searchPage(term, 1, opts, true)
for (let page = 2; page <= maxPage; ++page) {
while (true) {
try {
const results = await searchPage(term, page, opts)
results.forEach(o => allResults.push(o))
break
} catch (e) {
await timeout(60 * 1000)
}
}
}
return allResults
}
/**
*
* Research anything you desire on nyaa.si.
*
* @param {string} term Keywords describing the research.
* @param {number} n Number of results wanted (Defaults to null).
* @param {Object} opts Research options as described on the documentation.
*
* @returns {promise}
*/
const search = async (term = '', n = null, opts = {}) => {
if (!term || (typeof term === 'object' && !term.term)) {
throw new Error('[Nyaapi]: No term given on search demand.')
}
if (typeof term === 'object') {
opts = term
term = opts.term
n = n || opts.n
}
// If there is no n, then the user's asking for all the results, right?
if (!n) {
return searchAll(term, opts)
} else {
let results = []
let tmpData = []
let _continue = true
let page = 1
const maxPage = Math.ceil(n / 75)
while (_continue && page <= maxPage) {
tmpData = await searchPage(term, page, opts)
results = results.concat(tmpData)
++page
_continue = tmpData.length
}
return results.slice(0, n)
}
}
/**
*
* Research anything you desire according to a certain user and a specific page on nyaa.si.
*
* @param {string} user The user you want to spy on.
* @param {string} term Keywords describing the research.
* @param {number} p The page you want to look for.
* @param {number} n Number of results wanted on this page (Defaults to null).
* @param {Object} opts Research options as described on the documentation.
*
* @returns {promise}
*/
const searchByUserAndByPage = async (user = null, term = '', p = null, n = null, opts = {}) => {
if (!user) throw new Error('[Nyaapi]: No user given on search demand.')
if (typeof user === 'object') {
opts = user
user = opts.user
p = opts.p
term = term || opts.term
n = n || opts.n || 75
}
if (!p) throw new Error('[Nyaapi]: No page given on search by page demand.')
const querystring = buildQueryString({
f: opts.filter || 0,
c: opts.category || '1_0',
q: term || '',
p
})
const results = getResultsFromHTML(`${URI}user/${user}${querystring}`, false)
return results.slice(0, n || results.length)
}
/**
*
* Research anything you desire according to a certain user on nyaa.si and get all the results.
*
* @param {string} user The user you want to spy on.
* @param {string} term Keywords describing the research.
* @param {Object} opts Research options as described on the documentation.
*
* @returns {promise}
*/
const searchAllByUser = async (user = null, term = '', opts = {}) => {
if (!user || (typeof user === 'object' && user && !user.user)) {
throw new Error('[Nyaapi]: No user was given.')
}
if (typeof user === 'object') {
opts = user
term = opts.term
user = opts.user
}
let page = 1
let results = []
let tmpData = []
while (page <= 15) {
// We stop at page === 15 because nyaa.si offers a maximum of 1000 results on standard research
results = results.concat(tmpData)
opts.user = user
opts.term = term
opts.p = page
try {
tmpData = await searchByUserAndByPage(opts)
++page
} catch (e) {
if (e.statusCode !== 404) throw e
break
}
}
return results
}
/**
*
* Research anything you desire according to a certain user on nyaa.si
*
* @param {string} user The user you want to spy on.
* @param {string} term Keywords describing the research.
* @param {number} n Number of results wanted on this page (Defaults to null).
* @param {Object} opts Research options as described on the documentation.
*
* @returns {promise}
*/
const searchByUser = async (user = null, term = '', n = null, opts = {}) => {
if (!user || (typeof user === 'object' && user && !user.user)) {
throw new Error('[Nyaapi]: No user given on search demand.')
}
if (typeof user === 'object') {
opts = user
user = opts.user
term = term || opts.term || ''
n = n || opts.n
}
// If there is no n, then the user's asking for all the results, right?
if (!n) {
return searchAllByUser(user, term, opts)
} else {
let results = []
let tmpData = []
let page = 1
let _continue = true
const maxPage = Math.ceil(n / 75)
while (_continue && page <= maxPage) {
opts.user = user
opts.term = term
opts.p = page
tmpData = await searchByUserAndByPage(opts)
results = results.concat(tmpData)
++page
_continue = tmpData.length
}
return results.slice(0, n)
}
}
/**
* List specific category on nyaa.si.
*
* @param {string} c Category to list.
* @param {number} p Page of the category.
* @param {object} opts Research options as described on the documentation.
*
* @returns {promise}
*/
const list = (c, p, opts = {}) => {
return new Promise((resolve, reject) => {
if (typeof c === 'object') {
opts = c
c = opts.c
p = p || opts.p
}
const querystring = buildQueryString({
f: opts.filter || 0,
c: c || '1_0',
p: p || 1,
s: opts.sort || 'id',
o: opts.direction || 'desc'
})
getResultsFromHTML(`${URI}${querystring}`, true).then(results => {
resolve(results)
}).catch(/* istanbul ignore next */(err) => reject(err))
})
}
module.exports = {
list,
search,
searchAll,
searchPage,
searchByUser,
searchAllByUser,
searchByUserAndByPage
}