Drew Short
5 years ago
3 changed files with 144 additions and 3 deletions
@ -1,3 +1,130 @@ |
|||
/** |
|||
* Szurubooru api client |
|||
*/ |
|||
|
|||
let axios = require('axios'); |
|||
let { logger } = require('../../logging'); |
|||
|
|||
function getRandomInt(min, max) { |
|||
min = Math.ceil(min); |
|||
max = Math.floor(max); |
|||
return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
|
|||
} |
|||
|
|||
class SzurubooruClient { |
|||
|
|||
_randomSearchQueryValues = "type:image,animated,video sort:random"; |
|||
_randomSearchUrlTemplate = "%s/posts/?offset=%s&limit=%d&query=%s"; |
|||
|
|||
constructor(url, username, token) { |
|||
this.url = url; |
|||
this.baseUrl = url.replace('/api', ''); |
|||
this.username = username; |
|||
this.token = token; |
|||
this.updateRandomScope(); |
|||
} |
|||
|
|||
getRandomSearchUrl(offset, limit, tags = []) { |
|||
var searchQuery = this._randomSearchQueryValues; |
|||
if (tags !== null && tags.length > 0) { |
|||
searchQuery = this._randomSearchQueryValues + tags.join(" "); |
|||
} |
|||
return this.url + '/posts/?offset=' + offset + '&limit=' + limit + '&query=' + searchQuery; |
|||
} |
|||
|
|||
/** |
|||
* Determine a sane range of offset values |
|||
* |
|||
* @param {*} limit The content limit of a single page |
|||
* @param {*} total The number of objects to search through |
|||
*/ |
|||
getValidOffsetRange(limit, total) { |
|||
let offsetOverflow = total % limit; |
|||
var offsetCeiling = (Math.round(total / limit)); |
|||
if (offsetOverflow === 0) { |
|||
offsetCeiling -= 1; |
|||
} |
|||
return [0, offsetCeiling]; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Determine a random offset based on the potential random search size |
|||
* |
|||
* Because Szurubooru doesn't randomize each sort:random search request, we must |
|||
* manually calculate a random offset for each request to simulate randomness in the |
|||
* posts returned. |
|||
* |
|||
* @param {*} self |
|||
* @param {*} imageCount |
|||
*/ |
|||
getRandomSearchParameters(imageCount = null) { |
|||
let resultLimit = 10; |
|||
var offsetRange = [0, 1]; |
|||
if (imageCount === null) { |
|||
offsetRange = this.getValidOffsetRange(resultLimit, this.randomImageCount); |
|||
} else { |
|||
offsetRange = this.getValidOffsetRange(resultLimit, imageCount); |
|||
} |
|||
return [resultLimit, getRandomInt(offsetRange[0], offsetRange[1])]; |
|||
} |
|||
|
|||
|
|||
async updateRandomScope() { |
|||
let client = this; |
|||
let target = this.getRandomSearchUrl(0, 1); |
|||
await this.makeGetRequest(target).then((result) => { |
|||
client.randomImageCount = result.total; |
|||
}); |
|||
|
|||
} |
|||
|
|||
makeGetRequest(url) { |
|||
logger.debug("Making get request to %s", url); |
|||
return axios.get(url, { |
|||
headers: { |
|||
"Authorization": "Token " + Buffer.from(this.username + ':' + this.token).toString('base64'), |
|||
"Accept": "application/json" |
|||
} |
|||
}).then((response) => { |
|||
logger.debug("Recieved: %o", response.data); |
|||
return response.data; |
|||
}, (err) => { |
|||
logger.error("Unexpected client error: %o", err); |
|||
return null; |
|||
}); |
|||
return self._handle_response("GET", url, None, response) |
|||
} |
|||
|
|||
/** |
|||
* Return a random post matching the optionally provided tags. |
|||
* |
|||
* @param {*} self |
|||
* @param {*} tags |
|||
*/ |
|||
getRandomPost(tags = []) { |
|||
let client = this; |
|||
var resultLimit = 0; |
|||
var randomSearchOffset = 0; |
|||
if (tags.length === 0) { |
|||
let randomSearchParameters = this.getRandomSearchParameters(); |
|||
resultLimit = randomSearchParameters[0]; |
|||
randomSearchOffset = randomSearchParameters[1]; |
|||
} |
|||
let searchUrl = this.getRandomSearchUrl(randomSearchOffset, resultLimit, tags); |
|||
return this.makeGetRequest(searchUrl) |
|||
.then((data) => { |
|||
if (data !== null) { |
|||
let limitSpace = Math.min(resultLimit, data.results.length - 1); |
|||
let randomPost = data.results[getRandomInt(0, limitSpace)]; |
|||
return client.baseUrl + '/' + randomPost.contentUrl; |
|||
} else { |
|||
return null |
|||
} |
|||
}, (err) => { |
|||
|
|||
}) |
|||
} |
|||
} |
|||
|
|||
exports.Client = SzurubooruClient; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue