Baphomet is the dedicated bot for nulloctet matrix
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
4.2 KiB

  1. /**
  2. * Szurubooru api client
  3. */
  4. let axios = require('axios');
  5. let { logger } = require('../../logging');
  6. function getRandomInt(min, max) {
  7. min = Math.ceil(min);
  8. max = Math.floor(max);
  9. return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
  10. }
  11. class SzurubooruClient {
  12. _randomSearchQueryValues = "type:image,animated,video sort:random";
  13. _randomSearchUrlTemplate = "%s/posts/?offset=%s&limit=%d&query=%s";
  14. constructor(url, username, token) {
  15. this.url = url;
  16. this.baseUrl = url.replace('/api', '');
  17. this.username = username;
  18. this.token = token;
  19. this.updateRandomScope();
  20. }
  21. getRandomSearchUrl(offset, limit, tags = []) {
  22. var searchQuery = this._randomSearchQueryValues;
  23. if (tags !== null && tags.length > 0) {
  24. searchQuery = this._randomSearchQueryValues + tags.join(" ");
  25. }
  26. return this.url + '/posts/?offset=' + offset + '&limit=' + limit + '&query=' + searchQuery;
  27. }
  28. /**
  29. * Determine a sane range of offset values
  30. *
  31. * @param {*} limit The content limit of a single page
  32. * @param {*} total The number of objects to search through
  33. */
  34. getValidOffsetRange(limit, total) {
  35. let offsetOverflow = total % limit;
  36. var offsetCeiling = (Math.round(total / limit));
  37. if (offsetOverflow === 0) {
  38. offsetCeiling -= 1;
  39. }
  40. return [0, offsetCeiling];
  41. }
  42. /**
  43. * Determine a random offset based on the potential random search size
  44. *
  45. * Because Szurubooru doesn't randomize each sort:random search request, we must
  46. * manually calculate a random offset for each request to simulate randomness in the
  47. * posts returned.
  48. *
  49. * @param {*} self
  50. * @param {*} imageCount
  51. */
  52. getRandomSearchParameters(imageCount = null) {
  53. let resultLimit = 10;
  54. var offsetRange = [0, 1];
  55. if (imageCount === null) {
  56. offsetRange = this.getValidOffsetRange(resultLimit, this.randomImageCount);
  57. } else {
  58. offsetRange = this.getValidOffsetRange(resultLimit, imageCount);
  59. }
  60. return [resultLimit, getRandomInt(offsetRange[0], offsetRange[1])];
  61. }
  62. async updateRandomScope() {
  63. let client = this;
  64. let target = this.getRandomSearchUrl(0, 1);
  65. await this.makeGetRequest(target).then((result) => {
  66. client.randomImageCount = result.total;
  67. });
  68. }
  69. makeGetRequest(url) {
  70. logger.debug("Making get request to %s", url);
  71. return axios.get(url, {
  72. headers: {
  73. "Authorization": "Token " + Buffer.from(this.username + ':' + this.token).toString('base64'),
  74. "Accept": "application/json"
  75. }
  76. }).then((response) => {
  77. logger.debug("Recieved: %o", response.data);
  78. return response.data;
  79. }, (err) => {
  80. logger.error("Unexpected client error: %o", err);
  81. return null;
  82. });
  83. return self._handle_response("GET", url, None, response)
  84. }
  85. /**
  86. * Return a random post matching the optionally provided tags.
  87. *
  88. * @param {*} self
  89. * @param {*} tags
  90. */
  91. getRandomPost(tags = []) {
  92. let client = this;
  93. var resultLimit = 0;
  94. var randomSearchOffset = 0;
  95. if (tags.length === 0) {
  96. let randomSearchParameters = this.getRandomSearchParameters();
  97. resultLimit = randomSearchParameters[0];
  98. randomSearchOffset = randomSearchParameters[1];
  99. }
  100. let searchUrl = this.getRandomSearchUrl(randomSearchOffset, resultLimit, tags);
  101. return this.makeGetRequest(searchUrl)
  102. .then((data) => {
  103. if (data !== null) {
  104. let limitSpace = Math.min(resultLimit, data.results.length - 1);
  105. let randomPost = data.results[getRandomInt(0, limitSpace)];
  106. return client.baseUrl + '/' + randomPost.contentUrl;
  107. } else {
  108. return null
  109. }
  110. }, (err) => {
  111. })
  112. }
  113. }
  114. exports.Client = SzurubooruClient;