Drew Short
5 years ago
3 changed files with 144 additions and 3 deletions
@ -1,3 +1,130 @@ |
|||||
/** |
/** |
||||
* Szurubooru api client |
* 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