Greasy Fork镜像 支持简体中文。

Furaffinity-Request-Helper

Helper Library to simplify requests to Furaffinity

目前為 2024-11-18 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/483952/1486330/Furaffinity-Request-Helper.js

  1. // ==UserScript==
  2. // @name Furaffinity-Request-Helper
  3. // @namespace Violentmonkey Scripts
  4. // @grant none
  5. // @version 1.1.0
  6. // @author Midori Dragon
  7. // @description Helper Library to simplify requests to Furaffinity
  8. // @icon https://www.furaffinity.net/themes/beta/img/banners/fa_logo.png?v2
  9. // @license MIT
  10. // ==/UserScript==
  11. // jshint esversion: 8
  12. (() => {
  13. "use strict";
  14. class Semaphore {
  15. constructor(maxConcurrency) {
  16. this.maxConcurrency = maxConcurrency, this.currentConcurrency = 0, this.waitingQueue = [];
  17. }
  18. acquire() {
  19. return new Promise(((resolve, _) => {
  20. this.currentConcurrency < this.maxConcurrency ? (this.currentConcurrency++, resolve()) : this.waitingQueue.push(resolve);
  21. }));
  22. }
  23. release() {
  24. if (this.waitingQueue.length > 0) {
  25. this.waitingQueue.shift()();
  26. } else this.currentConcurrency--;
  27. }
  28. }
  29. class PercentHelper {
  30. constructor() {
  31. throw new Error("The PercentHelper class is static and cannot be instantiated.");
  32. }
  33. static percentAll={};
  34. static setPercentValue(id, value) {
  35. return !!(id && value && PercentHelper.percentAll.hasOwnProperty(id)) && (PercentHelper.percentAll[id] = value,
  36. !0);
  37. }
  38. static getPercentValue(id, decimalPlaces = 2) {
  39. if (!id) return -1;
  40. const percent = PercentHelper.percentAll[id];
  41. return percent ? parseFloat(percent.toFixed(decimalPlaces)) : -1;
  42. }
  43. static createPercentValue(uniqueId) {
  44. return uniqueId || (uniqueId = Date.now() + Math.random()), PercentHelper.percentAll[uniqueId] = 0,
  45. uniqueId;
  46. }
  47. static deletePercentValue(id) {
  48. PercentHelper.percentAll.hasOwnProperty(id) && delete PercentHelper.percentAll[id];
  49. }
  50. }
  51. class WaitAndCallAction {
  52. constructor(action, usePercent, delay) {
  53. this.action = action, this.delay = delay, this.intervalId, this.usePercent = usePercent,
  54. this._running = !1;
  55. }
  56. start() {
  57. if (this.action && this.delay && !1 === this._running) return this._running = !0,
  58. this.usePercent && PercentHelper.createPercentValue(this.intervalId.toString()),
  59. this.intervalId = setInterval((() => {
  60. this.usePercent ? this.action(PercentHelper.getPercentValue(this.intervalId.toString())) : this.action();
  61. }), this.delay), this.intervalId;
  62. }
  63. stop() {
  64. this._running && (this._running = !1, clearInterval(this.intervalId), this.usePercent && PercentHelper.deletePercentValue(this.intervalId.toString()));
  65. }
  66. static async callFunctionAsync(functionToCall, params, action, delay, usePercent) {
  67. const waitAndCallAction = new WaitAndCallAction(action, usePercent, delay), percentId = waitAndCallAction.start();
  68. usePercent && params.push(percentId);
  69. const result = await functionToCall(...params);
  70. return waitAndCallAction.stop(), result;
  71. }
  72. static callFunction(functionToCall, params, action, delay, usePercent) {
  73. const waitAndCallAction = new WaitAndCallAction(action, usePercent, delay), percentId = waitAndCallAction.start();
  74. usePercent && params.push(percentId);
  75. const result = functionToCall(...params);
  76. return waitAndCallAction.stop(), result;
  77. }
  78. }
  79. class Logger {
  80. constructor() {
  81. throw new Error("The Logger class is static and cannot be instantiated.");
  82. }
  83. static logMessage(message) {
  84. FuraffinityRequests.logLevel >= 3 && console.log(message);
  85. }
  86. static logWarning(message) {
  87. FuraffinityRequests.logLevel >= 2 && console.warn(message);
  88. }
  89. static logError(message) {
  90. FuraffinityRequests.logLevel >= 1 && console.error(message);
  91. }
  92. static setLogLevel(level) {
  93. FuraffinityRequests.logLevel = level;
  94. }
  95. }
  96. class IdArray {
  97. constructor() {
  98. throw new Error("The IdArray class is static and cannot be instantiated.");
  99. }
  100. static getTillId(collection, toId) {
  101. const result = [];
  102. for (const elem of Array.from(collection)) if (result.push(elem), elem.id.toString().replace("sid-", "") == toId) break;
  103. return result;
  104. }
  105. static getSinceId(collection, fromId) {
  106. const array = Array.from(collection);
  107. array.reverse();
  108. const result = [];
  109. for (const elem of array) if (result.push(elem), elem.id.toString().replace("sid-", "") == fromId) break;
  110. return result.reverse(), result;
  111. }
  112. static getBetweenIds(collection, fromId, toId) {
  113. const array = Array.from(collection);
  114. let startIndex = -1, endIndex = -1;
  115. for (let i = 0; i < array.length && (array[i].id.toString().replace("sid-", "") == fromId && (startIndex = i),
  116. array[i].id.toString().replace("sid-", "") == toId && (endIndex = i), -1 == startIndex || -1 == endIndex); i++) ;
  117. if (-1 == startIndex && -1 == endIndex) return array;
  118. -1 == startIndex && (startIndex = 0), -1 == endIndex && (endIndex = array.length - 1);
  119. const result = [];
  120. for (let i = startIndex; i <= endIndex; i++) result.push(array[i]);
  121. return result;
  122. }
  123. static containsId(collection, id) {
  124. for (const elem of Array.from(collection)) if (elem.id.toString().replace("sid-", "") == id) return !0;
  125. return !1;
  126. }
  127. }
  128. class Scraps {
  129. constructor(semaphore) {
  130. this.semaphore = semaphore;
  131. }
  132. static get hardLink() {
  133. return FuraffinityRequests.getUrl() + "/scraps/";
  134. }
  135. async getFiguresBetweenIds(username, fromId, toId, action, delay = 100) {
  136. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, toId, null, "scraps", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, fromId, null, "scraps", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, fromId, toId, null, null, "scraps", this.semaphore ], action, delay, !0);
  137. }
  138. async getFiguresBetweenIdsBetweenPages(username, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
  139. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, toId, fromPageNumber, "scraps", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, fromId, toPageNumber, "scraps", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, fromId, toId, fromPageNumber, toPageNumber, "scraps", this.semaphore ], action, delay, !0);
  140. }
  141. async getFiguresBetweenPages(username, fromPageNumber, toPageNumber, action, delay = 100) {
  142. return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillPage, [ username, toPageNumber, "scraps", this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSincePage, [ username, fromPageNumber, "scraps", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenPages, [ username, fromPageNumber, toPageNumber, "scraps", this.semaphore ], action, delay, !0);
  143. }
  144. async getFigures(username, pageNumber, action, delay = 100) {
  145. return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFigures, [ username, null, pageNumber, "scraps", this.semaphore ], action, delay);
  146. }
  147. async getPage(username, pageNumber, action, delay = 100) {
  148. return await WaitAndCallAction.callFunctionAsync(Page.getGalleryPage, [ username, null, pageNumber, "scraps", this.semaphore ], action, delay);
  149. }
  150. }
  151. class Favorites {
  152. constructor(semaphore) {
  153. this.semaphore = semaphore;
  154. }
  155. static get hardLink() {
  156. return FuraffinityRequests.getUrl() + "/favorites/";
  157. }
  158. async getFiguresBetweenIds(username, fromId, toId, action, delay = 100) {
  159. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, toId, null, "favorites", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, fromId, null, "favorites", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, fromId, toId, null, null, "favorites", this.semaphore ], action, delay, !0);
  160. }
  161. async getFiguresBetweenIdsBetweenPages(username, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
  162. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, toId, fromPageNumber, "favorites", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, fromId, toPageNumber, "favorites", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, fromId, toId, fromPageNumber, toPageNumber, "favorites", this.semaphore ], action, delay, !0);
  163. }
  164. async getFiguresBetweenPages(username, fromPageNumber, toPageNumber, action, delay = 100) {
  165. return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillPage, [ username, toPageNumber, "favorites", this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSincePage, [ username, fromPageNumber, "favorites", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenPages, [ username, fromPageNumber, toPageNumber, "favorites", this.semaphore ], action, delay, !0);
  166. }
  167. async getFigures(username, pageNumber, action, delay = 100) {
  168. return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFigures, [ username, null, pageNumber, "favorites", this.semaphore ], action, delay);
  169. }
  170. async getPage(username, pageNumber, action, delay = 100) {
  171. return await WaitAndCallAction.callFunctionAsync(Page.getGalleryPage, [ username, null, pageNumber, "favorites", this.semaphore ], action, delay);
  172. }
  173. }
  174. class Journals {
  175. constructor(semaphore) {
  176. this.semaphore = semaphore;
  177. }
  178. static get hardLink() {
  179. return FuraffinityRequests.getUrl() + "/journals/";
  180. }
  181. async getFiguresBetweenIds(username, fromId, toId, action, delay = 100) {
  182. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsTillId, [ username, toId, null, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsSinceId, [ username, fromId, null, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsBetweenIds, [ username, fromId, toId, null, null, this.semaphore ], action, delay);
  183. }
  184. async getFiguresBetweenIdsBetweenPages(username, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
  185. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsTillId, [ username, toId, fromPageNumber, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsSinceId, [ username, fromId, toPageNumber, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsBetweenIds, [ username, fromId, toId, fromPageNumber, toPageNumber, this.semaphore ], action, delay);
  186. }
  187. async getSectionsBetweenPages(username, fromPageNumber, toPageNumber, action, delay = 100) {
  188. return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsTillPage, [ username, toPageNumber, this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsSincePage, [ username, fromPageNumber, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSectionsBetweenPages, [ username, fromPageNumber, toPageNumber, this.semaphore ], action, delay, !0);
  189. }
  190. async getSections(username, pageNumber, action, delay = 100) {
  191. return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getJournalsSections, [ username, pageNumber, this.semaphore ], action, delay);
  192. }
  193. async getPage(username, pageNumber, action, delay = 100) {
  194. return await WaitAndCallAction.callFunctionAsync(Page.getJournalsPage, [ username, pageNumber, this.semaphore ], action, delay);
  195. }
  196. }
  197. class Search {
  198. constructor(semaphore) {
  199. this.semaphore = semaphore;
  200. }
  201. static get hardLink() {
  202. return FuraffinityRequests.getUrl() + "/search/";
  203. }
  204. get newSearchOptions() {
  205. return new SearchOptions;
  206. }
  207. get SearchOptions() {
  208. return SearchOptions;
  209. }
  210. async getFiguresBetweenIds(fromId, toId, searchOptions, action, delay = 100) {
  211. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresTillId, [ toId, null, searchOptions, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresSinceId, [ fromId, null, searchOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresBetweenIds, [ fromId, toId, null, null, searchOptions, this.semaphore ], action, delay, !0);
  212. }
  213. async getFiguresBetweenIdsBetweenPages(fromId, toId, fromPageNumber, toPageNumber, searchOptions, action, delay = 100) {
  214. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresTillId, [ toId, fromPageNumber, searchOptions, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresSinceId, [ fromId, toPageNumber, searchOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresBetweenIds, [ fromId, toId, fromPageNumber, toPageNumber, searchOptions, this.semaphore ], action, delay, !0);
  215. }
  216. async getFiguresBetweenPages(fromPageNumber, toPageNumber, searchOptions, action, delay = 100) {
  217. return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresTillPage, [ toPageNumber, searchOptions, this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresSincePage, [ fromPageNumber, searchOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFiguresBetweenPages, [ fromPageNumber, toPageNumber, searchOptions, this.semaphore ], action, delay, !0);
  218. }
  219. async getFigures(pageNumber, searchOptions, action, delay = 100) {
  220. return await WaitAndCallAction.callFunctionAsync(SearchRequests.getSearchFigures, [ pageNumber, searchOptions, this.semaphore ], action, delay);
  221. }
  222. async getPage(pageNumber, searchOptions, action, delay = 100) {
  223. return await WaitAndCallAction.callFunctionAsync(Page.getSearchPage, [ pageNumber, searchOptions, this.semaphore ], action, delay);
  224. }
  225. }
  226. class SearchOptions {
  227. constructor() {
  228. this.input = "", this.orderBy = SearchOptions.orderBy.relevancy, this.orderDirection = SearchOptions.orderDirection.descending,
  229. this.range = SearchOptions.range.alltime, this.rangeFrom = null, this.rangeTo = null,
  230. this.ratingGeneral = !0, this.ratingMature = !0, this.ratingAdult = !0, this.typeArt = !0,
  231. this.typeMusic = !0, this.typeFlash = !0, this.typeStory = !0, this.typePhotos = !0,
  232. this.typePoetry = !0, this.matching = SearchOptions.matching.all;
  233. }
  234. static get orderBy() {
  235. return {
  236. relevancy: "relevancy",
  237. date: "date",
  238. popularity: "popularity"
  239. };
  240. }
  241. static get orderDirection() {
  242. return {
  243. ascending: "asc",
  244. descending: "desc"
  245. };
  246. }
  247. static get range() {
  248. return {
  249. "1day": "1day",
  250. "3days": "3days",
  251. "7days": "7days",
  252. "30days": "30days",
  253. "90days": "90days",
  254. "1year": "1year",
  255. "3years": "3years",
  256. "5years": "5years",
  257. alltime: "all",
  258. manual: "manual"
  259. };
  260. }
  261. static get matching() {
  262. return {
  263. all: "all",
  264. any: "any",
  265. extended: "extended"
  266. };
  267. }
  268. }
  269. class SearchRequests {
  270. constructor(semaphore) {
  271. this.semaphore = semaphore, this.Browse = new Browse(this.semaphore), this.Search = new Search(this.semaphore);
  272. }
  273. static async getBrowseFiguresTillId(toId, fromPage, browseOptions, semaphore) {
  274. if (!toId) return Logger.logError("No toId given"), null;
  275. let allFigures = [], running = !0, i = 1;
  276. for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
  277. const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
  278. let currFigureId;
  279. figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getTillId(figures, toId)),
  280. running = !1) : (allFigures.push(figures), i++);
  281. }
  282. return 0 === allFigures.length ? null : allFigures;
  283. }
  284. static async getBrowseFiguresSinceId(fromId, toPage, browseOptions, semaphore) {
  285. if (!fromId) return Logger.logError("No fromId given"), null;
  286. let lastFigureId, running = !0, i = 1;
  287. for (;running; ) {
  288. if (toPage && toPage >= 1 && i == toPage) {
  289. running = !1;
  290. break;
  291. }
  292. const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
  293. let currFigureId = lastFigureId;
  294. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
  295. }
  296. let allFigures = [];
  297. for (lastFigureId = null, running = !0; running; ) {
  298. const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
  299. let currFigureId = lastFigureId;
  300. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : (allFigures.push(IdArray.getSinceId(figures, fromId)),
  301. i++);
  302. }
  303. return 0 === allFigures.length ? null : allFigures;
  304. }
  305. static async getBrowseFiguresBetweenIds(fromId, toId, fromPage, toPage, browseOptions, semaphore, percentId) {
  306. if (!fromId) return Logger.logError("No fromId given"), null;
  307. if (!toId) return Logger.logError("No toId given"), null;
  308. let lastFigureId;
  309. (!fromPage || fromPage <= 0 || !toPage || toPage <= 1) && (Logger.logWarning("No fromPage or toPage given. Percentages can not be calculated."),
  310. percentId = null);
  311. let running = !0, i = 1;
  312. for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
  313. const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
  314. let currFigureId = lastFigureId;
  315. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
  316. }
  317. let allFigures = [];
  318. for (lastFigureId = null, running = !0; running; ) {
  319. if (toPage && toPage >= 1 && i == toPage) {
  320. running = !1;
  321. break;
  322. }
  323. const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
  324. let currFigureId = lastFigureId;
  325. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getBetweenIds(figures, fromId, toId)),
  326. running = !1) : (allFigures.push(figures), i++);
  327. }
  328. if (percentId) {
  329. const progress = 1 / toPage * 100;
  330. PercentHelper.setPercentValue(percentId, progress);
  331. }
  332. return 0 === allFigures.length ? null : allFigures;
  333. }
  334. static async getBrowseFiguresTillPage(toPageNumber, browseOptions, semaphore, percentId) {
  335. if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
  336. if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"),
  337. null;
  338. let allFigures = [], completedPages = 0;
  339. for (let i = 1; i <= toPageNumber; i++) {
  340. const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
  341. if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++,
  342. percentId) {
  343. const progress = completedPages / toPageNumber * 100;
  344. PercentHelper.setPercentValue(percentId, progress);
  345. }
  346. }
  347. return 0 === allFigures.length ? null : allFigures;
  348. }
  349. static async getBrowseFiguresSincePage(fromPageNumber, browseOptions, semaphore) {
  350. if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
  351. if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"),
  352. null;
  353. let allFigures = [], running = !0, i = fromPageNumber;
  354. for (;running; ) {
  355. const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
  356. let currFigureId;
  357. figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : (allFigures.push(figures),
  358. i++);
  359. }
  360. return 0 === allFigures.length ? null : allFigures;
  361. }
  362. static async getBrowseFiguresBetweenPages(fromPageNumber, toPageNumber, browseOptions, semaphore, percentId) {
  363. if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
  364. if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"),
  365. null;
  366. if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
  367. if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"),
  368. null;
  369. let allFigures = [];
  370. const direction = fromPageNumber < toPageNumber ? 1 : -1, totalPages = Math.abs(toPageNumber - fromPageNumber) + 1;
  371. let completedPages = 0;
  372. for (let i = fromPageNumber; i <= toPageNumber; i += direction) {
  373. const figures = await SearchRequests.getBrowseFigures(i, browseOptions, semaphore);
  374. if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++,
  375. percentId) {
  376. const progress = completedPages / totalPages * 100;
  377. PercentHelper.setPercentValue(percentId, progress);
  378. }
  379. }
  380. return 0 === allFigures.length ? null : allFigures;
  381. }
  382. static async getBrowseFigures(pageNumber, browseOptions, semaphore) {
  383. const galleryDoc = await Page.getBrowsePage(pageNumber, browseOptions, semaphore);
  384. if (!galleryDoc || !(galleryDoc instanceof Document) || galleryDoc.getElementById("no-images")) return Logger.logMessage(`No images found at browse on page "${pageNumber}".`),
  385. null;
  386. const figures = galleryDoc.getElementsByTagName("figure");
  387. return figures && 0 !== figures.length ? figures : (Logger.logMessage(`No figures found at browse on page "${pageNumber}".`),
  388. null);
  389. }
  390. static async getSearchFiguresTillId(toId, fromPage, searchOptions, semaphore) {
  391. if (!toId) return Logger.logError("No toId given"), null;
  392. let allFigures = [], running = !0, i = 1;
  393. for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
  394. const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
  395. let currFigureId;
  396. figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getTillId(figures, toId)),
  397. running = !1) : (allFigures.push(figures), i++);
  398. }
  399. return 0 === allFigures.length ? null : allFigures;
  400. }
  401. static async getSearchFiguresSinceId(fromId, toPage, searchOptions, semaphore) {
  402. if (!fromId) return Logger.logError("No fromId given"), null;
  403. let lastFigureId, running = !0, i = 1;
  404. for (;running; ) {
  405. if (toPage && toPage >= 1 && i == toPage) {
  406. running = !1;
  407. break;
  408. }
  409. const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
  410. let currFigureId = lastFigureId;
  411. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
  412. }
  413. let allFigures = [];
  414. for (lastFigureId = null, running = !0; running; ) {
  415. const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
  416. let currFigureId = lastFigureId;
  417. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : (allFigures.push(IdArray.getSinceId(figures, fromId)),
  418. i++);
  419. }
  420. return 0 === allFigures.length ? null : allFigures;
  421. }
  422. static async getSearchFiguresBetweenIds(fromId, toId, fromPage, toPage, searchOptions, semaphore, percentId) {
  423. if (!fromId) return Logger.logError("No fromId given"), null;
  424. if (!toId) return Logger.logError("No toId given"), null;
  425. let lastFigureId;
  426. (!fromPage || fromPage <= 0 || !toPage || toPage <= 1) && (Logger.logWarning("No fromPage or toPage given. Percentages can not be calculated."),
  427. percentId = null);
  428. let running = !0, i = 1;
  429. for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
  430. const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
  431. let currFigureId = lastFigureId;
  432. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
  433. }
  434. let allFigures = [];
  435. for (lastFigureId = null, running = !0; running; ) {
  436. if (toPage && toPage >= 1 && i == toPage) {
  437. running = !1;
  438. break;
  439. }
  440. const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
  441. let currFigureId = lastFigureId;
  442. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getBetweenIds(figures, fromId, toId)),
  443. running = !1) : (allFigures.push(figures), i++);
  444. }
  445. if (percentId) {
  446. const progress = 1 / toPage * 100;
  447. PercentHelper.setPercentValue(percentId, progress);
  448. }
  449. return 0 === allFigures.length ? null : allFigures;
  450. }
  451. static async getSearchFiguresTillPage(toPageNumber, searchOptions, semaphore, percentId) {
  452. if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
  453. if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"),
  454. null;
  455. let allFigures = [], completedPages = 0;
  456. for (let i = 1; i <= toPageNumber; i++) {
  457. const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
  458. if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++,
  459. percentId) {
  460. const progress = completedPages / toPageNumber * 100;
  461. PercentHelper.setPercentValue(percentId, progress);
  462. }
  463. }
  464. return 0 === allFigures.length ? null : allFigures;
  465. }
  466. static async getSearchFiguresSincePage(fromPageNumber, searchOptions, semaphore) {
  467. if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
  468. if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"),
  469. null;
  470. let allFigures = [], running = !0, i = fromPageNumber;
  471. for (;running; ) {
  472. const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
  473. let currFigureId;
  474. figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : (allFigures.push(figures),
  475. i++);
  476. }
  477. return 0 === allFigures.length ? null : allFigures;
  478. }
  479. static async getSearchFiguresBetweenPages(fromPageNumber, toPageNumber, searchOptions, semaphore, percentId) {
  480. if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
  481. if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"),
  482. null;
  483. if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
  484. if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"),
  485. null;
  486. let allFigures = [];
  487. const direction = fromPageNumber < toPageNumber ? 1 : -1, totalPages = Math.abs(toPageNumber - fromPageNumber) + 1;
  488. let completedPages = 0;
  489. for (let i = fromPageNumber; i <= toPageNumber; i += direction) {
  490. const figures = await SearchRequests.getSearchFigures(i, searchOptions, semaphore);
  491. if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++,
  492. percentId) {
  493. const progress = completedPages / totalPages * 100;
  494. PercentHelper.setPercentValue(percentId, progress);
  495. }
  496. }
  497. return 0 === allFigures.length ? null : allFigures;
  498. }
  499. static async getSearchFigures(pageNumber, searchOptions, semaphore) {
  500. const galleryDoc = await Page.getSearchPage(pageNumber, searchOptions, semaphore);
  501. if (!galleryDoc || !(galleryDoc instanceof Document) || galleryDoc.getElementById("no-images")) return Logger.logMessage(`No images found at search on page "${pageNumber}".`),
  502. null;
  503. const figures = galleryDoc.getElementsByTagName("figure");
  504. return figures && 0 !== figures.length ? figures : (Logger.logMessage(`No figures found at search on page "${pageNumber}".`),
  505. null);
  506. }
  507. }
  508. class Browse {
  509. constructor(semaphore) {
  510. this.semaphore = semaphore;
  511. }
  512. static get hardLink() {
  513. return FuraffinityRequests.getUrl() + "/browse/";
  514. }
  515. get newBrowseOptions() {
  516. return new BrowseOptions;
  517. }
  518. get BrowseOptions() {
  519. return BrowseOptions;
  520. }
  521. async getFiguresBetweenIds(fromId, toId, browseOptions, action, delay = 100) {
  522. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresTillId, [ toId, null, browseOptions, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresSinceId, [ fromId, null, browseOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresBetweenIds, [ fromId, toId, null, null, browseOptions, this.semaphore ], action, delay, !0);
  523. }
  524. async getFiguresBetweenIdsBetweenPages(fromId, toId, fromPageNumber, toPageNumber, browseOptions, action, delay = 100) {
  525. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresTillId, [ toId, fromPageNumber, browseOptions, this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresSinceId, [ fromId, toPageNumber, browseOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresBetweenIds, [ fromId, toId, fromPageNumber, toPageNumber, browseOptions, this.semaphore ], action, delay, !0);
  526. }
  527. async getFiguresBetweenPages(fromPageNumber, toPageNumber, browseOptions, action, delay = 100) {
  528. return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresTillPage, [ toPageNumber, browseOptions, this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresSincePage, [ fromPageNumber, browseOptions, this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFiguresBetweenPages, [ fromPageNumber, toPageNumber, browseOptions, this.semaphore ], action, delay, !0);
  529. }
  530. async getFigures(pageNumber, browseOptions, action, delay = 100) {
  531. return await WaitAndCallAction.callFunctionAsync(SearchRequests.getBrowseFigures, [ pageNumber, browseOptions, this.semaphore ], action, delay);
  532. }
  533. async getPage(pageNumber, browseOptions, action, delay = 100) {
  534. return await WaitAndCallAction.callFunctionAsync(Page.getBrowsePage, [ pageNumber, browseOptions, this.semaphore ], action, delay);
  535. }
  536. }
  537. class BrowseOptions {
  538. constructor() {
  539. this.category = BrowseOptions.category.all, this.type = BrowseOptions.type.all,
  540. this.species = BrowseOptions.species.any, this.gender = BrowseOptions.gender.any,
  541. this.results = BrowseOptions.results[72], this.ratingGeneral = !0, this.ratingMature = !0,
  542. this.ratingAdult = !0;
  543. }
  544. static get category() {
  545. return {
  546. all: 1,
  547. "artwork-digital": 2,
  548. "artwork-traditional": 3,
  549. "cel-shading": 4,
  550. crafting: 5,
  551. designs: 6,
  552. flash: 7,
  553. fursuiting: 8,
  554. icons: 9,
  555. mosaics: 10,
  556. photography: 11,
  557. "food-recipes": 32,
  558. sculpting: 12,
  559. story: 13,
  560. poetry: 14,
  561. prose: 15,
  562. music: 16,
  563. podcasts: 17,
  564. skins: 18,
  565. handhelds: 19,
  566. resources: 20,
  567. adoptables: 21,
  568. auctions: 22,
  569. contests: 23,
  570. "current-events": 24,
  571. desktops: 25,
  572. stockart: 26,
  573. screenshots: 27,
  574. scraps: 28,
  575. wallpaper: 29,
  576. "ych-sale": 30,
  577. other: 31
  578. };
  579. }
  580. static get type() {
  581. return {
  582. all: 1,
  583. abstract: 2,
  584. "animal-related-non-anthro": 3,
  585. anime: 4,
  586. comics: 5,
  587. doodle: 6,
  588. fanart: 7,
  589. fantasy: 8,
  590. human: 9,
  591. portraits: 10,
  592. scenery: 11,
  593. "still-life": 12,
  594. tutorials: 13,
  595. miscellaneous: 14,
  596. "baby-fur": 101,
  597. bondage: 102,
  598. digimon: 103,
  599. "fat-furs": 104,
  600. "fetish-other": 105,
  601. fursuit: 106,
  602. gore: 119,
  603. hyper: 107,
  604. hypnosis: 121,
  605. inflation: 108,
  606. micro: 109,
  607. muscle: 110,
  608. "my-little-pony": 111,
  609. paw: 112,
  610. pokemon: 113,
  611. pregnancy: 114,
  612. sonic: 115,
  613. transformation: 116,
  614. "tf-tg": 120,
  615. vore: 117,
  616. "water-sports": 118,
  617. "general-furry-art": 100,
  618. techno: 201,
  619. trance: 202,
  620. house: 203,
  621. "90s": 204,
  622. "80s": 205,
  623. "70s": 206,
  624. "60s": 207,
  625. "pre-60s": 208,
  626. classical: 209,
  627. "game-music": 210,
  628. rock: 211,
  629. pop: 212,
  630. rap: 213,
  631. industrial: 214,
  632. "other-music": 200
  633. };
  634. }
  635. static get species() {
  636. return {
  637. any: 1,
  638. "airborne-vehicle": 10001,
  639. alien: 5001,
  640. amphibian: 1e3,
  641. aquatic: 2e3,
  642. avian: 3e3,
  643. bear: 6002,
  644. bovine: 6007,
  645. canine: 6017,
  646. cervine: 6018,
  647. dog: 6010,
  648. dragon: 4e3,
  649. equine: 10009,
  650. exotic: 5e3,
  651. feline: 6030,
  652. fox: 6075,
  653. slime: 10007,
  654. "hybrid-species": 10002,
  655. inanimate: 10006,
  656. insect: 8003,
  657. "land-vehicle": 10003,
  658. mammal: 6e3,
  659. marsupial: 6042,
  660. mustelid: 6051,
  661. plant: 10008,
  662. primate: 6058,
  663. reptilian: 7e3,
  664. robot: 10004,
  665. rodent: 6067,
  666. "sea-vehicle": 10005,
  667. taur: 5025,
  668. vulpine: 6015,
  669. "original-species": 11014,
  670. character: 11015,
  671. aeromorph: 11001,
  672. "angel-dragon": 11002,
  673. avali: 11012,
  674. chakat: 5003,
  675. citra: 5005,
  676. crux: 5006,
  677. dracat: 5009,
  678. dutch: 11003,
  679. felkin: 11011,
  680. ferrin: 11004,
  681. jogauni: 11005,
  682. langurhali: 5014,
  683. nevrean: 11006,
  684. protogen: 11007,
  685. rexouium: 11016,
  686. sergal: 5021,
  687. synx: 11010,
  688. wickerbeast: 11013,
  689. yinglet: 11009,
  690. zorgoia: 11008,
  691. angel: 12001,
  692. centaur: 12002,
  693. cerberus: 12003,
  694. "shape-shifter": 12038,
  695. chimera: 12004,
  696. chupacabra: 12005,
  697. cockatrice: 12006,
  698. daemon: 5007,
  699. demon: 12007,
  700. "displacer-beast": 12008,
  701. dragonborn: 12009,
  702. drow: 12010,
  703. dwarf: 12011,
  704. "eastern-dragon": 4001,
  705. elf: 5011,
  706. gargoyle: 5012,
  707. goblin: 12012,
  708. golem: 12013,
  709. gryphon: 3007,
  710. harpy: 12014,
  711. hellhound: 12015,
  712. hippogriff: 12016,
  713. hobbit: 12017,
  714. hydra: 4002,
  715. imp: 12018,
  716. incubus: 12019,
  717. jackalope: 12020,
  718. kirin: 12021,
  719. kitsune: 12022,
  720. kobold: 12023,
  721. lamia: 12024,
  722. manticore: 12025,
  723. minotaur: 12026,
  724. naga: 5016,
  725. nephilim: 12027,
  726. orc: 5018,
  727. pegasus: 12028,
  728. peryton: 12029,
  729. phoenix: 3010,
  730. sasquatch: 12030,
  731. satyr: 5020,
  732. sphinx: 12031,
  733. succubus: 12032,
  734. tiefling: 12033,
  735. troll: 12034,
  736. unicorn: 5023,
  737. "water-dragon": 12035,
  738. werewolf: 12036,
  739. "western-dragon": 4004,
  740. wyvern: 4005,
  741. yokai: 12037,
  742. alicorn: 13001,
  743. argonian: 5002,
  744. asari: 13002,
  745. bangaa: 13003,
  746. "bubble-dragon": 13004,
  747. burmecian: 13005,
  748. charr: 13006,
  749. chiss: 13007,
  750. chocobo: 5004,
  751. deathclaw: 13008,
  752. digimon: 5008,
  753. draenei: 5010,
  754. drell: 13009,
  755. elcor: 13010,
  756. ewok: 13011,
  757. hanar: 13012,
  758. hrothgar: 13013,
  759. iksar: 5013,
  760. kaiju: 5015,
  761. kelpie: 13041,
  762. kemonomimi: 13014,
  763. khajiit: 13015,
  764. koopa: 13016,
  765. krogan: 13017,
  766. lombax: 13018,
  767. mimiga: 13019,
  768. mobian: 13020,
  769. moogle: 5017,
  770. neopet: 13021,
  771. "nu-mou": 13022,
  772. pokemon: 5019,
  773. "pony-mlp": 13023,
  774. protoss: 13024,
  775. quarian: 13025,
  776. ronso: 13026,
  777. salarian: 13027,
  778. sangheili: 13028,
  779. tauntaun: 13029,
  780. tauren: 13030,
  781. trandoshan: 13031,
  782. transformer: 13032,
  783. turian: 13033,
  784. twilek: 13034,
  785. viera: 13035,
  786. wookiee: 13036,
  787. xenomorph: 5024,
  788. yautja: 13037,
  789. yordle: 13038,
  790. yoshi: 13039,
  791. zerg: 13040,
  792. aardvark: 14001,
  793. aardwolf: 14002,
  794. "african-wild-dog": 14003,
  795. akita: 14004,
  796. albatross: 14005,
  797. crocodile: 7001,
  798. alpaca: 14006,
  799. anaconda: 14007,
  800. anteater: 14008,
  801. antelope: 6004,
  802. arachnid: 8e3,
  803. "arctic-fox": 14009,
  804. armadillo: 14010,
  805. axolotl: 14011,
  806. baboon: 14012,
  807. badger: 6045,
  808. bat: 6001,
  809. beaver: 6064,
  810. bee: 14013,
  811. binturong: 14014,
  812. bison: 14015,
  813. "blue-jay": 14016,
  814. "border-collie": 14017,
  815. "brown-bear": 14018,
  816. buffalo: 14019,
  817. "buffalo-bison": 14020,
  818. "bull-terrier": 14021,
  819. butterfly: 14022,
  820. caiman: 14023,
  821. camel: 6074,
  822. capybara: 14024,
  823. caribou: 14025,
  824. caterpillar: 14026,
  825. cephalopod: 2001,
  826. chameleon: 14027,
  827. cheetah: 6021,
  828. chicken: 14028,
  829. chimpanzee: 14029,
  830. chinchilla: 14030,
  831. chipmunk: 14031,
  832. civet: 14032,
  833. "clouded-leopard": 14033,
  834. coatimundi: 14034,
  835. cockatiel: 14035,
  836. corgi: 14036,
  837. corvid: 3001,
  838. cougar: 6022,
  839. cow: 6003,
  840. coyote: 6008,
  841. crab: 14037,
  842. crane: 14038,
  843. crayfish: 14039,
  844. crow: 3002,
  845. crustacean: 14040,
  846. dalmatian: 14041,
  847. deer: 14042,
  848. dhole: 14043,
  849. dingo: 6011,
  850. dinosaur: 8001,
  851. doberman: 6009,
  852. dolphin: 2002,
  853. donkey: 6019,
  854. duck: 3003,
  855. eagle: 3004,
  856. eel: 14044,
  857. elephant: 14045,
  858. falcon: 3005,
  859. fennec: 6072,
  860. ferret: 6046,
  861. finch: 14046,
  862. fish: 2005,
  863. flamingo: 14047,
  864. fossa: 14048,
  865. frog: 1001,
  866. gazelle: 6005,
  867. gecko: 7003,
  868. genet: 14049,
  869. "german-shepherd": 6012,
  870. gibbon: 14050,
  871. giraffe: 6031,
  872. goat: 6006,
  873. goose: 3006,
  874. gorilla: 6054,
  875. "gray-fox": 14051,
  876. "great-dane": 14052,
  877. "grizzly-bear": 14053,
  878. "guinea-pig": 14054,
  879. hamster: 14055,
  880. hawk: 3008,
  881. hedgehog: 6032,
  882. heron: 14056,
  883. hippopotamus: 6033,
  884. honeybee: 14057,
  885. horse: 6034,
  886. housecat: 6020,
  887. human: 6055,
  888. humanoid: 14058,
  889. hummingbird: 14059,
  890. husky: 6014,
  891. hyena: 6035,
  892. iguana: 7004,
  893. impala: 14060,
  894. jackal: 6013,
  895. jaguar: 6023,
  896. kangaroo: 6038,
  897. "kangaroo-mouse": 14061,
  898. "kangaroo-rat": 14062,
  899. kinkajou: 14063,
  900. "kit-fox": 14064,
  901. koala: 6039,
  902. "kodiak-bear": 14065,
  903. "komodo-dragon": 14066,
  904. labrador: 14067,
  905. lemur: 6056,
  906. leopard: 6024,
  907. liger: 14068,
  908. linsang: 14069,
  909. lion: 6025,
  910. lizard: 7005,
  911. llama: 6036,
  912. lobster: 14070,
  913. "longhair-cat": 14071,
  914. lynx: 6026,
  915. magpie: 14072,
  916. "maine-coon": 14073,
  917. malamute: 14074,
  918. "mammal-feline": 14075,
  919. "mammal-herd": 14076,
  920. "mammal-marsupial": 14077,
  921. "mammal-mustelid": 14078,
  922. "mammal-other predator": 14079,
  923. "mammal-prey": 14080,
  924. "mammal-primate": 14081,
  925. "mammal-rodent": 14082,
  926. manatee: 14083,
  927. mandrill: 14084,
  928. "maned-wolf": 14085,
  929. mantid: 8004,
  930. marmoset: 14086,
  931. marten: 14087,
  932. meerkat: 6043,
  933. mink: 6048,
  934. mole: 14088,
  935. mongoose: 6044,
  936. "monitor-lizard": 14089,
  937. monkey: 6057,
  938. moose: 14090,
  939. moth: 14091,
  940. mouse: 6065,
  941. "musk-deer": 14092,
  942. "musk-ox": 14093,
  943. newt: 1002,
  944. ocelot: 6027,
  945. octopus: 14094,
  946. okapi: 14095,
  947. olingo: 14096,
  948. opossum: 6037,
  949. orangutan: 14097,
  950. orca: 14098,
  951. oryx: 14099,
  952. ostrich: 14100,
  953. otter: 6047,
  954. owl: 3009,
  955. panda: 6052,
  956. pangolin: 14101,
  957. panther: 6028,
  958. parakeet: 14102,
  959. parrot: 14103,
  960. peacock: 14104,
  961. penguin: 14105,
  962. "persian-cat": 14106,
  963. pig: 6053,
  964. pigeon: 14107,
  965. pika: 14108,
  966. "pine-marten": 14109,
  967. platypus: 14110,
  968. "polar-bear": 14111,
  969. pony: 6073,
  970. poodle: 14112,
  971. porcupine: 14113,
  972. porpoise: 2004,
  973. procyonid: 14114,
  974. puffin: 14115,
  975. quoll: 6040,
  976. rabbit: 6059,
  977. raccoon: 6060,
  978. rat: 6061,
  979. ray: 14116,
  980. "red-fox": 14117,
  981. "red-panda": 6062,
  982. reindeer: 14118,
  983. reptillian: 14119,
  984. rhinoceros: 6063,
  985. robin: 14120,
  986. rottweiler: 14121,
  987. sabercats: 14122,
  988. sabertooth: 14123,
  989. salamander: 1003,
  990. scorpion: 8005,
  991. seagull: 14124,
  992. seahorse: 14125,
  993. seal: 6068,
  994. "secretary-bird": 14126,
  995. "serpent-dragon": 4003,
  996. serval: 14127,
  997. shark: 2006,
  998. sheep: 14128,
  999. "shiba-inu": 14129,
  1000. "shorthair-cat": 14130,
  1001. shrew: 14131,
  1002. siamese: 14132,
  1003. sifaka: 14133,
  1004. "silver-fox": 14134,
  1005. skunk: 6069,
  1006. sloth: 14135,
  1007. snail: 14136,
  1008. "snake-serpent": 7006,
  1009. "snow-leopard": 14137,
  1010. sparrow: 14138,
  1011. squid: 14139,
  1012. squirrel: 6070,
  1013. stoat: 14140,
  1014. stork: 14141,
  1015. "sugar-glider": 14142,
  1016. "sun-bear": 14143,
  1017. swan: 3011,
  1018. "swift-fox": 14144,
  1019. tanuki: 5022,
  1020. tapir: 14145,
  1021. "tasmanian-devil": 14146,
  1022. thylacine: 14147,
  1023. tiger: 6029,
  1024. toucan: 14148,
  1025. turtle: 7007,
  1026. vulture: 14149,
  1027. wallaby: 6041,
  1028. walrus: 14150,
  1029. wasp: 14151,
  1030. weasel: 6049,
  1031. whale: 2003,
  1032. wolf: 6016,
  1033. wolverine: 6050,
  1034. zebra: 6071
  1035. };
  1036. }
  1037. static get gender() {
  1038. return {
  1039. any: 0,
  1040. male: 2,
  1041. female: 3,
  1042. herm: 4,
  1043. intersex: 11,
  1044. "trans-male": 8,
  1045. "trans-female": 9,
  1046. "non-binary": 10,
  1047. multiple: 6,
  1048. other: 7,
  1049. "not-specified": 7
  1050. };
  1051. }
  1052. static get results() {
  1053. return {
  1054. 24: 24,
  1055. 48: 48,
  1056. 72: 72,
  1057. 96: 96,
  1058. 128: 128
  1059. };
  1060. }
  1061. }
  1062. class Page {
  1063. static async getGalleryPage(username, folderId, pageNumber, galleryType, semaphore) {
  1064. if ("journals" == galleryType) return await Page.getJournalsPage(username, pageNumber, semaphore);
  1065. if ("browse" == galleryType) return await Page.getBrowsePage(pageNumber, null, semaphore);
  1066. if (!username) return Logger.logError("No username given"), null;
  1067. if (!pageNumber) return Logger.logError("No page number given"), null;
  1068. let url;
  1069. switch (pageNumber <= 0 && (Logger.logWarning("Page number is less 1. Using default 1 instead."),
  1070. pageNumber = 1), galleryType || (Logger.logWarning("No gallery type given. Using default 'Gallery' instead."),
  1071. galleryType = "gallery"), username.endsWith("/") || (username += "/"), galleryType) {
  1072. case "gallery":
  1073. url = Gallery.hardLink + username;
  1074. break;
  1075.  
  1076. case "scraps":
  1077. url = Scraps.hardLink + username;
  1078. break;
  1079.  
  1080. case "favorites":
  1081. url = Favorites.hardLink + username;
  1082. }
  1083. return folderId && (url += "folder/" + folderId + "/"), url ? await FuraffinityRequests.getHTML(url + pageNumber, semaphore) : null;
  1084. }
  1085. static async getJournalsPage(username, pageNumber, semaphore) {
  1086. if (!username) return Logger.logError("No username given"), null;
  1087. if (!pageNumber) return Logger.logError("No page number given"), null;
  1088. if (pageNumber <= 0) return Logger.logError("Page number must be greater than 0"),
  1089. null;
  1090. username.endsWith("/") || (username += "/");
  1091. const url = Journals.hardLink + username;
  1092. return url ? await FuraffinityRequests.getHTML(url + pageNumber, semaphore) : null;
  1093. }
  1094. static async getBrowsePage(pageNumber, browseOptions, semaphore) {
  1095. if (!pageNumber) return Logger.logError("No page number given"), null;
  1096. if (pageNumber <= 0) return Logger.logError("Page number must be greater than 0"),
  1097. null;
  1098. browseOptions || (browseOptions = new BrowseOptions);
  1099. const payload = {
  1100. cat: browseOptions.category,
  1101. atype: browseOptions.type,
  1102. species: browseOptions.species,
  1103. gender: browseOptions.gender,
  1104. perpage: browseOptions.results,
  1105. page: pageNumber,
  1106. rating_general: browseOptions.ratingGeneral ? "on" : "off",
  1107. rating_mature: browseOptions.ratingMature ? "on" : "off",
  1108. rating_adult: browseOptions.ratingAdult ? "on" : "off"
  1109. };
  1110. for (const key in payload) null != payload[key] && null != payload[key] && 0 != payload[key] && "off" != payload[key] || delete payload[key];
  1111. const payloadArray = Object.entries(payload), url = Browse.hardLink;
  1112. return url ? await FuraffinityRequests.postHTML(url, payloadArray, semaphore) : null;
  1113. }
  1114. static async getSearchPage(pageNumber, searchOptions, semaphore) {
  1115. if (!pageNumber) return Logger.logError("No page number given"), null;
  1116. if (pageNumber <= 0) return Logger.logError("Page number must be greater than 0"),
  1117. null;
  1118. searchOptions || (searchOptions = new SearchOptions);
  1119. const payload = {
  1120. page: pageNumber,
  1121. q: searchOptions.input,
  1122. "order-by": searchOptions.orderBy,
  1123. "order-direction": searchOptions.orderDirection,
  1124. range: searchOptions.range,
  1125. range_from: "",
  1126. range_to: "",
  1127. "rating-general": searchOptions.ratingGeneral ? 1 : 0,
  1128. "rating-mature": searchOptions.ratingMature ? 1 : 0,
  1129. "rating-adult": searchOptions.ratingAdult ? 1 : 0,
  1130. "type-art": searchOptions.typeArt ? 1 : 0,
  1131. "type-music": searchOptions.typeMusic ? 1 : 0,
  1132. "type-flash": searchOptions.typeFlash ? 1 : 0,
  1133. "type-story": searchOptions.typeStory ? 1 : 0,
  1134. "type-photos": searchOptions.typePhotos ? 1 : 0,
  1135. "type-poetry": searchOptions.typePoetry ? 1 : 0,
  1136. mode: searchOptions.matching
  1137. };
  1138. for (const key in payload) null != payload[key] && null != payload[key] && 0 != payload[key] && "off" != payload[key] || delete payload[key];
  1139. if (searchOptions.rangeFrom instanceof Date && searchOptions.rangeFrom) {
  1140. const formattedDate = `${searchOptions.rangeFrom.getFullYear()}-${(searchOptions.rangeFrom.getMonth() + 1).toString().padStart(2, "0")}-${searchOptions.rangeFrom.getDate().toString().padStart(2, "0")}`;
  1141. payload.range_from = formattedDate;
  1142. } else "string" == typeof searchOptions.rangeFrom && searchOptions.rangeFrom && (payload.range_from = searchOptions.rangeFrom);
  1143. if (searchOptions.rangeTo instanceof Date && searchOptions.rangeTo) {
  1144. const formattedDate = `${searchOptions.rangeTo.getFullYear()}-${(searchOptions.rangeTo.getMonth() + 1).toString().padStart(2, "0")}-${searchOptions.rangeTo.getDate().toString().padStart(2, "0")}`;
  1145. payload.range_to = formattedDate;
  1146. } else "string" == typeof searchOptions.rangeTo && searchOptions.rangeTo && (payload.range_to = searchOptions.rangeTo);
  1147. const payloadArray = Object.entries(payload), url = Search.hardLink;
  1148. return url ? await FuraffinityRequests.postHTML(url, payloadArray, semaphore) : null;
  1149. }
  1150. }
  1151. class Gallery {
  1152. constructor(semaphore) {
  1153. this.semaphore = semaphore;
  1154. }
  1155. static get hardLink() {
  1156. return FuraffinityRequests.getUrl() + "/gallery/";
  1157. }
  1158. async getFiguresBetweenIds(username, fromId, toId, action, delay = 100) {
  1159. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, null, toId, null, "gallery", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, null, fromId, null, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, null, fromId, toId, null, null, "gallery", this.semaphore ], action, delay, !0);
  1160. }
  1161. async getFiguresInFolderBetweenIds(username, folderId, fromId, toId, action, delay = 100) {
  1162. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, folderId, toId, null, "gallery", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, folderId, fromId, null, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, folderId, fromId, toId, null, null, "gallery", this.semaphore ], action, delay, !0);
  1163. }
  1164. async getFiguresBetweenIdsBetweenPages(username, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
  1165. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, null, toId, fromPageNumber, "gallery", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, null, fromId, toPageNumber, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, null, fromId, toId, fromPageNumber, toPageNumber, "gallery", this.semaphore ], action, delay, !0);
  1166. }
  1167. async getFiguresInFolderBetweenIdsBetweenPages(username, folderId, fromId, toId, fromPageNumber, toPageNumber, action, delay = 100) {
  1168. return fromId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillId, [ username, folderId, toId, fromPageNumber, "gallery", this.semaphore ], action, delay) : toId <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSinceId, [ username, folderId, fromId, toPageNumber, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenIds, [ username, folderId, fromId, toId, fromPageNumber, toPageNumber, "gallery", this.semaphore ], action, delay, !0);
  1169. }
  1170. async getFiguresBetweenPages(username, fromPageNumber, toPageNumber, action, delay = 100) {
  1171. return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillPage, [ username, null, toPageNumber, "gallery", this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSincePage, [ username, null, fromPageNumber, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenPages, [ username, null, fromPageNumber, toPageNumber, "gallery", this.semaphore ], action, delay, !0);
  1172. }
  1173. async getFiguresInFolderBetweenPages(username, folderId, fromPageNumber, toPageNumber, action, delay = 100) {
  1174. return fromPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresTillPage, [ username, folderId, toPageNumber, "gallery", this.semaphore ], action, delay, !0) : toPageNumber <= 0 ? await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresSincePage, [ username, folderId, fromPageNumber, "gallery", this.semaphore ], action, delay) : await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFiguresBetweenPages, [ username, folderId, fromPageNumber, toPageNumber, "gallery", this.semaphore ], action, delay, !0);
  1175. }
  1176. async getFigures(username, pageNumber, action, delay = 100) {
  1177. return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFigures, [ username, null, pageNumber, "gallery", this.semaphore ], action, delay);
  1178. }
  1179. async getFiguresInFolder(username, folderId, pageNumber, action, delay = 100) {
  1180. return await WaitAndCallAction.callFunctionAsync(GalleryRequests.getGalleryFigures, [ username, folderId, pageNumber, "gallery", this.semaphore ], action, delay);
  1181. }
  1182. async getPage(username, pageNumber, action, delay = 100) {
  1183. return await WaitAndCallAction.callFunctionAsync(Page.getGalleryPage, [ username, null, pageNumber, "gallery", this.semaphore ], action, delay);
  1184. }
  1185. async getPageInFolder(username, folderId, pageNumber, action, delay = 100) {
  1186. return await WaitAndCallAction.callFunctionAsync(Page.getGalleryPage, [ username, folderId, pageNumber, "gallery", this.semaphore ], action, delay);
  1187. }
  1188. }
  1189. class GalleryRequests {
  1190. constructor(semaphore) {
  1191. this.semaphore = semaphore, this.Gallery = new Gallery(semaphore), this.Scraps = new Scraps(semaphore),
  1192. this.Favorites = new Favorites(semaphore), this.Journals = new Journals(semaphore);
  1193. }
  1194. static async getGalleryFiguresTillId(username, folderId, toId, fromPage, galleryType, semaphore) {
  1195. if (!toId) return Logger.logError("No toId given"), null;
  1196. let allFigures = [], running = !0, i = 1;
  1197. for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
  1198. const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
  1199. let currFigureId;
  1200. figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getTillId(figures, toId)),
  1201. running = !1) : (allFigures.push(figures), i++);
  1202. }
  1203. return 0 === allFigures.length ? null : allFigures;
  1204. }
  1205. static async getGalleryFiguresSinceId(username, folderId, fromId, toPage, galleryType, semaphore) {
  1206. if (!fromId) return Logger.logError("No fromId given"), null;
  1207. let lastFigureId, running = !0, i = 1;
  1208. for (;running; ) {
  1209. if (toPage && toPage >= 1 && i == toPage) {
  1210. running = !1;
  1211. break;
  1212. }
  1213. const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
  1214. let currFigureId = lastFigureId;
  1215. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
  1216. }
  1217. let allFigures = [];
  1218. for (lastFigureId = null, running = !0; running; ) {
  1219. const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
  1220. let currFigureId = lastFigureId;
  1221. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : (allFigures.push(IdArray.getSinceId(figures, fromId)),
  1222. i++);
  1223. }
  1224. return 0 === allFigures.length ? null : allFigures;
  1225. }
  1226. static async getGalleryFiguresBetweenIds(username, folderId, fromId, toId, fromPage, toPage, galleryType, semaphore, percentId) {
  1227. if (!fromId) return Logger.logError("No fromId given"), null;
  1228. if (!toId) return Logger.logError("No toId given"), null;
  1229. let lastFigureId;
  1230. (!fromPage || fromPage <= 0 || !toPage || toPage <= 1) && (Logger.logWarning("No fromPage or toPage given. Percentages can not be calculated."),
  1231. percentId = null);
  1232. let running = !0, i = 1;
  1233. for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
  1234. const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
  1235. let currFigureId = lastFigureId;
  1236. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId || IdArray.containsId(figures, fromId) ? running = !1 : i++;
  1237. }
  1238. let allFigures = [];
  1239. for (lastFigureId = null, running = !0; running; ) {
  1240. if (toPage && toPage >= 1 && i == toPage) {
  1241. running = !1;
  1242. break;
  1243. }
  1244. const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
  1245. let currFigureId = lastFigureId;
  1246. figures && 0 !== figures.length && (currFigureId = figures[0].id), currFigureId == lastFigureId ? running = !1 : IdArray.containsId(figures, toId) ? (allFigures.push(IdArray.getBetweenIds(figures, fromId, toId)),
  1247. running = !1) : (allFigures.push(figures), i++);
  1248. }
  1249. if (percentId) {
  1250. const progress = 1 / toPage * 100;
  1251. PercentHelper.setPercentValue(percentId, progress);
  1252. }
  1253. return 0 === allFigures.length ? null : allFigures;
  1254. }
  1255. static async getGalleryFiguresTillPage(username, folderId, toPageNumber, galleryType, semaphore, percentId) {
  1256. if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
  1257. if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"),
  1258. null;
  1259. let allFigures = [], completedPages = 0;
  1260. for (let i = 1; i <= toPageNumber; i++) {
  1261. const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
  1262. if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++,
  1263. percentId) {
  1264. const progress = completedPages / toPageNumber * 100;
  1265. PercentHelper.setPercentValue(percentId, progress);
  1266. }
  1267. }
  1268. return 0 === allFigures.length ? null : allFigures;
  1269. }
  1270. static async getGalleryFiguresSincePage(username, folderId, fromPageNumber, galleryType, semaphore) {
  1271. if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
  1272. if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"),
  1273. null;
  1274. let allFigures = [], running = !0, i = fromPageNumber;
  1275. for (;running; ) {
  1276. const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
  1277. let currFigureId;
  1278. figures && 0 !== figures.length && (currFigureId = figures[0].id), null == currFigureId ? running = !1 : (allFigures.push(figures),
  1279. i++);
  1280. }
  1281. return 0 === allFigures.length ? null : allFigures;
  1282. }
  1283. static async getGalleryFiguresBetweenPages(username, folderId, fromPageNumber, toPageNumber, galleryType, semaphore, percentId) {
  1284. if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
  1285. if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"),
  1286. null;
  1287. if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
  1288. if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"),
  1289. null;
  1290. let allFigures = [];
  1291. const direction = fromPageNumber < toPageNumber ? 1 : -1, totalPages = Math.abs(toPageNumber - fromPageNumber) + 1;
  1292. let completedPages = 0;
  1293. for (let i = fromPageNumber; i <= toPageNumber; i += direction) {
  1294. const figures = await GalleryRequests.getGalleryFigures(username, folderId, i, galleryType, semaphore);
  1295. if (figures && 0 !== figures.length && allFigures.push(figures), completedPages++,
  1296. percentId) {
  1297. const progress = completedPages / totalPages * 100;
  1298. PercentHelper.setPercentValue(percentId, progress);
  1299. }
  1300. }
  1301. return 0 === allFigures.length ? null : allFigures;
  1302. }
  1303. static async getGalleryFigures(username, folderId, pageNumber, galleryType, semaphore) {
  1304. const galleryDoc = await Page.getGalleryPage(username, folderId, pageNumber, galleryType, semaphore);
  1305. if (!galleryDoc || !(galleryDoc instanceof Document) || galleryDoc.getElementById("no-images")) return Logger.logMessage(`No images found at ${galleryType} of "${username}" on page "${pageNumber}".`),
  1306. null;
  1307. const figures = galleryDoc.getElementsByTagName("figure");
  1308. return figures && 0 !== figures.length ? figures : (Logger.logMessage(`No figures found at ${galleryType} of "${username}" on page "${pageNumber}".`),
  1309. null);
  1310. }
  1311. static async getJournalsSectionsTillId(username, toId, fromPage, semaphore) {
  1312. if (toId) return Logger.logError("No toId given"), null;
  1313. let allSections = [], running = !0, i = 1;
  1314. for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
  1315. const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
  1316. let currSectionId;
  1317. sections && 0 !== sections.length && (currSectionId = sections[0].id), null == currSectionId ? running = !1 : IdArray.containsId(sections, toId) ? (allSections.push(IdArray.getTillId(sections, toId)),
  1318. running = !1) : (allSections.push(sections), i++);
  1319. }
  1320. return 0 === allSections.length ? null : allSections;
  1321. }
  1322. static async getJournalsSectionsSinceId(username, fromId, toPage, semaphore) {
  1323. if (!fromId) return Logger.logError("No fromId given"), null;
  1324. let lastSectionId, running = !0, i = 1;
  1325. for (;running; ) {
  1326. if (toPage && toPage >= 1 && i == toPage) {
  1327. running = !1;
  1328. break;
  1329. }
  1330. const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
  1331. let currSectionId = lastSectionId;
  1332. sections && 0 !== sections.length && (currSectionId = sections[0].id), currSectionId == lastSectionId || IdArray.containsId(sections, fromId) ? running = !1 : i++;
  1333. }
  1334. let allSections = [];
  1335. for (lastSectionId = null, running = !0; running; ) {
  1336. const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
  1337. let currSectionId = lastSectionId;
  1338. sections && 0 !== sections.length && (currSectionId = sections[0].id), currSectionId == lastSectionId ? running = !1 : (allSections.push(IdArray.getSinceId(sections, fromId)),
  1339. i++);
  1340. }
  1341. return 0 === allSections.length ? null : allSections;
  1342. }
  1343. static async getJournalsSectionsBetweenIds(username, fromId, toId, fromPage, toPage, semaphore, percentId) {
  1344. if (!fromId) return Logger.logError("No fromId given"), null;
  1345. if (!toId) return Logger.logError("No toId given"), null;
  1346. let lastSectionId;
  1347. (!fromPage || fromPage <= 0 || !toPage || toPage <= 1) && (Logger.logWarning("No fromPage or toPage given. Percentages can not be calculated."),
  1348. percentId = null);
  1349. let running = !0, i = 1;
  1350. for (fromPage && fromPage >= 1 && (i = fromPage); running; ) {
  1351. const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
  1352. let currSectionId = lastSectionId;
  1353. sections && 0 !== sections.length && (currSectionId = sections[0].id), currSectionId == lastSectionId || IdArray.containsId(sections, fromId) ? running = !1 : i++;
  1354. }
  1355. let allSections = [];
  1356. lastSectionId = null, running = !0;
  1357. for (;running; ) {
  1358. if (toPage && toPage >= 1 && i == toPage) {
  1359. running = !1;
  1360. break;
  1361. }
  1362. const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
  1363. let currFigureId = lastSectionId;
  1364. sections && 0 !== sections.length && (currFigureId = sections[0].id), currFigureId == lastSectionId ? running = !1 : IdArray.containsId(sections, toId) ? (allSections.push(IdArray.getBetweenIds(sections, fromId, toId)),
  1365. running = !1) : (allSections.push(sections), i++);
  1366. }
  1367. if (percentId) {
  1368. const progress = 1 / toPage * 100;
  1369. PercentHelper.setPercentValue(percentId, progress);
  1370. }
  1371. return 0 === allSections.length ? null : allSections;
  1372. }
  1373. static async getJournalsSectionsTillPage(username, toPageNumber, semaphore, percentId) {
  1374. if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
  1375. if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"),
  1376. null;
  1377. let allSections = [], completedPages = 0;
  1378. for (let i = 1; i <= toPageNumber; i++) {
  1379. const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
  1380. if (sections && 0 !== sections.length && allSections.push(sections), completedPages++,
  1381. percentId) {
  1382. const progress = completedPages / toPageNumber * 100;
  1383. PercentHelper.setPercentValue(percentId, progress);
  1384. }
  1385. }
  1386. return 0 === allSections.length ? null : allSections;
  1387. }
  1388. static async getJournalsSectionsSincePage(username, fromPageNumber, semaphore) {
  1389. if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
  1390. if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"),
  1391. null;
  1392. let allSections = [], running = !0, i = fromPageNumber;
  1393. for (;running; ) {
  1394. const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
  1395. if (sections && 0 !== sections.length) {
  1396. null == sections[0].id ? running = !1 : (allSections.push(sections), i++);
  1397. }
  1398. }
  1399. return 0 === allSections.length ? null : allSections;
  1400. }
  1401. static async getJournalsSectionsBetweenPages(username, fromPageNumber, toPageNumber, semaphore, percentId) {
  1402. if (!fromPageNumber) return Logger.logError("No fromPageNumber given"), null;
  1403. if (fromPageNumber <= 0) return Logger.logError("fromPageNumber must be greater than 0"),
  1404. null;
  1405. if (!toPageNumber) return Logger.logError("No toPageNumber given"), null;
  1406. if (toPageNumber <= 0) return Logger.logError("toPageNumber must be greater than 0"),
  1407. null;
  1408. let allSections = [], direction = fromPageNumber < toPageNumber ? 1 : -1;
  1409. const totalPages = Math.abs(toPageNumber - fromPageNumber) + 1;
  1410. let completedPages = 0;
  1411. for (let i = fromPageNumber; i <= toPageNumber; i += direction) {
  1412. const sections = await GalleryRequests.getJournalsSections(username, i, semaphore);
  1413. sections && allSections.push(sections), completedPages++;
  1414. const progress = completedPages / totalPages * 100;
  1415. PercentHelper.setPercentValue(percentId, progress);
  1416. }
  1417. return 0 === allSections.length ? null : allSections;
  1418. }
  1419. static async getJournalsSections(username, pageNumber, semaphore) {
  1420. const galleryDoc = await Page.getJournalsPage(username, pageNumber, semaphore);
  1421. if (!galleryDoc) return Logger.logMessage(`No journals found at "${username}" on page "${pageNumber}".`),
  1422. null;
  1423. const columnPage = galleryDoc.getElementById("columnpage");
  1424. if (!columnPage) return Logger.logMessage(`No column page found at "${username}" on page "${pageNumber}".`),
  1425. null;
  1426. const sections = columnPage.getElementsByTagName("section");
  1427. return sections && 0 !== sections.length ? sections : (Logger.logMessage(`No journals found at "${username}" on page "${pageNumber}".`),
  1428. null);
  1429. }
  1430. }
  1431. class UserRequests {
  1432. constructor(semaphore) {
  1433. this.semaphore = semaphore, this.GalleryRequests = new GalleryRequests(semaphore),
  1434. this.SearchRequests = new SearchRequests(semaphore);
  1435. }
  1436. static get hardLinks() {
  1437. return {
  1438. user: FuraffinityRequests.getUrl() + "/user/",
  1439. watch: FuraffinityRequests.getUrl() + "/watch/",
  1440. unwatch: FuraffinityRequests.getUrl() + "/unwatch/",
  1441. block: FuraffinityRequests.getUrl() + "/block/",
  1442. unblock: FuraffinityRequests.getUrl() + "/unblock/"
  1443. };
  1444. }
  1445. async getUserPage(username, action, delay = 100) {
  1446. return await WaitAndCallAction.callFunctionAsync(getUserPageLocal, [ username, this.semaphore ], action, delay);
  1447. }
  1448. async watchUser(username, watchKey, action, delay = 100) {
  1449. return await WaitAndCallAction.callFunctionAsync(watchUserLocal, [ username, watchKey, this.semaphore ], action, delay);
  1450. }
  1451. async unwatchUser(username, unwatchKey, action, delay = 100) {
  1452. return await WaitAndCallAction.callFunctionAsync(unwatchUserLocal, [ username, unwatchKey, this.semaphore ], action, delay);
  1453. }
  1454. async blockUser(username, blockKey, action, delay = 100) {
  1455. return await WaitAndCallAction.callFunctionAsync(blockUserLocal, [ username, blockKey, this.semaphore ], action, delay);
  1456. }
  1457. async unblockUser(username, unblockKey, action, delay = 100) {
  1458. return await WaitAndCallAction.callFunctionAsync(unblockUserLocal, [ username, unblockKey, this.semaphore ], action, delay);
  1459. }
  1460. }
  1461. async function getUserPageLocal(username, semaphore) {
  1462. if (!username) return Logger.logWarning("No username given"), null;
  1463. UserRequests.hardLinks.user.endsWith("/") || (UserRequests.hardLinks.user += "/");
  1464. const url = UserRequests.hardLinks.user + username;
  1465. return url ? await FuraffinityRequests.getHTML(url, semaphore) : null;
  1466. }
  1467. async function watchUserLocal(username, watchKey, semaphore) {
  1468. if (!username) return Logger.logWarning("No username given"), null;
  1469. if (!watchKey) return Logger.logWarning("No watch key given"), null;
  1470. UserRequests.hardLinks.watch.endsWith("/") || (UserRequests.hardLinks.watch += "/");
  1471. const url = UserRequests.hardLinks.watch + username + "?key=" + watchKey;
  1472. return !!url && !!await FuraffinityRequests.getHTML(url, semaphore);
  1473. }
  1474. async function unwatchUserLocal(username, unwatchKey, semaphore) {
  1475. if (!username) return Logger.logWarning("No username given"), null;
  1476. if (!unwatchKey) return Logger.logWarning("No unwatch key given"), null;
  1477. UserRequests.hardLinks.unwatch.endsWith("/") || (UserRequests.hardLinks.unwatch += "/");
  1478. const url = UserRequests.hardLinks.unwatch + username + "?key=" + unwatchKey;
  1479. return !!url && !!await FuraffinityRequests.getHTML(url, semaphore);
  1480. }
  1481. async function blockUserLocal(username, blockKey, semaphore) {
  1482. if (!username) return Logger.logWarning("No username given"), null;
  1483. if (!blockKey) return Logger.logWarning("No block key given"), null;
  1484. UserRequests.hardLinks.block.endsWith("/") || (UserRequests.hardLinks.block += "/");
  1485. const url = UserRequests.hardLinks.block + username + "?key=" + blockKey;
  1486. return !!url && !!await FuraffinityRequests.getHTML(url, semaphore);
  1487. }
  1488. async function unblockUserLocal(username, unblockKey, semaphore) {
  1489. if (!username) return Logger.logWarning("No username given"), null;
  1490. if (!unblockKey) return Logger.logWarning("No unblock key given"), null;
  1491. UserRequests.hardLinks.unblock.endsWith("/") || (UserRequests.hardLinks.unblock += "/");
  1492. const url = UserRequests.hardLinks.unblock + username + "?key=" + unblockKey;
  1493. return !!url && !!await FuraffinityRequests.getHTML(url, semaphore);
  1494. }
  1495. class NewSubmissions {
  1496. constructor(semaphore) {
  1497. this.semaphore = semaphore;
  1498. }
  1499. static get hardLink() {
  1500. return FuraffinityRequests.getUrl() + "/msg/submissions/";
  1501. }
  1502. async getSubmissionsPage(firstSubmissionId, action, delay = 100) {
  1503. return await WaitAndCallAction.callFunctionAsync(getSubmissionsPageLocal, [ firstSubmissionId, this.semaphore ], action, delay);
  1504. }
  1505. async removeSubmissions(submissionIds, action, delay = 100) {
  1506. return await WaitAndCallAction.callFunctionAsync(removeSubmissionsLocal, [ submissionIds, this.semaphore ], action, delay);
  1507. }
  1508. async nukeSubmissions(action, delay = 100) {
  1509. return await WaitAndCallAction.callFunctionAsync(nukeSubmissionsLocal, [ this.semaphore ], action, delay);
  1510. }
  1511. }
  1512. async function getSubmissionsPageLocal(firstSubmissionId, semaphore) {
  1513. return firstSubmissionId ? await FuraffinityRequests.getHTML(`${NewSubmissions.hardLink}new~${firstSubmissionId}@72/`, semaphore) : await FuraffinityRequests.getHTML(`${NewSubmissions.hardLink}new@72/`, semaphore);
  1514. }
  1515. async function removeSubmissionsLocal(submissionIds, semaphore) {
  1516. if (!submissionIds || 0 == submissionIds.length) return void Logger.logWarning("No submission ids to remove");
  1517. const payload = [];
  1518. for (const submissionId of submissionIds) payload.push({
  1519. key: "submissions[]",
  1520. value: submissionId
  1521. });
  1522. return payload.push({
  1523. key: "messagecenter-action",
  1524. value: Message.hardActions.remove
  1525. }), await FuraffinityRequests.postHTML(`${NewSubmissions.hardLink}new@72/`, payload, semaphore);
  1526. }
  1527. async function nukeSubmissionsLocal(semaphore) {
  1528. const payload = [];
  1529. return payload.push({
  1530. key: "messagecenter-action",
  1531. value: Message.hardActions.nuke
  1532. }), await FuraffinityRequests.postHTML(`${NewSubmissions.hardLink}new@72/`, payload, semaphore);
  1533. }
  1534. class Message {
  1535. constructor(semaphore) {
  1536. this.semaphore = semaphore, this.NewSubmissions = new NewSubmissions(semaphore);
  1537. }
  1538. static hardActions={
  1539. remove: "remove_checked",
  1540. nuke: "nuke_notifications"
  1541. };
  1542. }
  1543. class AccountInformation {
  1544. constructor(semaphore) {
  1545. this.semaphore = semaphore;
  1546. }
  1547. static get hardLinks() {
  1548. return {
  1549. settings: FuraffinityRequests.getUrl() + "/controls/settings/",
  1550. siteSettings: FuraffinityRequests.getUrl() + "/controls/site-settings/",
  1551. userSettings: FuraffinityRequests.getUrl() + "/controls/user-settings/"
  1552. };
  1553. }
  1554. async getSettingsPage(action, delay = 100) {
  1555. return await WaitAndCallAction.callFunctionAsync(getSettingsPageLocal, [ this.semaphore ], action, delay);
  1556. }
  1557. async getSiteSettingsPage(action, delay = 100) {
  1558. return await WaitAndCallAction.callFunctionAsync(getSiteSettingsPageLocal, [ this.semaphore ], action, delay);
  1559. }
  1560. async getUserSettingsPage(action, delay = 100) {
  1561. return await WaitAndCallAction.callFunctionAsync(getUserSettingsPageLocal, [ this.semaphore ], action, delay);
  1562. }
  1563. }
  1564. async function getSettingsPageLocal(semaphore) {
  1565. return AccountInformation.hardLinks.settings.endsWith("/") || (AccountInformation.hardLinks.settings += "/"),
  1566. await FuraffinityRequests.getHTML(AccountInformation.hardLinks.settings, semaphore);
  1567. }
  1568. async function getSiteSettingsPageLocal(semaphore) {
  1569. return AccountInformation.hardLinks.siteSettings.endsWith("/") || (AccountInformation.hardLinks.siteSettings += "/"),
  1570. await FuraffinityRequests.getHTML(AccountInformation.hardLinks.siteSettings, semaphore);
  1571. }
  1572. async function getUserSettingsPageLocal(semaphore) {
  1573. return AccountInformation.hardLinks.userSettings.endsWith("/") || (AccountInformation.hardLinks.userSettings += "/"),
  1574. await FuraffinityRequests.getHTML(AccountInformation.hardLinks.userSettings, semaphore);
  1575. }
  1576. class UserProfile {
  1577. constructor(semaphore) {
  1578. this.semaphore = semaphore;
  1579. }
  1580. static get hardLinks() {
  1581. return {
  1582. profile: FuraffinityRequests.getUrl() + "/controls/profile/",
  1583. profilebanner: FuraffinityRequests.getUrl() + "/controls/profilebanner/",
  1584. contacts: FuraffinityRequests.getUrl() + "/controls/contacts/",
  1585. avatar: FuraffinityRequests.getUrl() + "/controls/avatar/"
  1586. };
  1587. }
  1588. async getProfilePage(action, delay = 100) {
  1589. return await WaitAndCallAction.callFunctionAsync(getProfilePageLocal, [ this.semaphore ], action, delay);
  1590. }
  1591. async getProfilebannerPage(action, delay = 100) {
  1592. return await WaitAndCallAction.callFunctionAsync(getProfilebannerPageLocal, [ this.semaphore ], action, delay);
  1593. }
  1594. async getContactsPage(action, delay = 100) {
  1595. return await WaitAndCallAction.callFunctionAsync(getContactsPageLocal, [ this.semaphore ], action, delay);
  1596. }
  1597. async getAvatarPage(action, delay = 100) {
  1598. return await WaitAndCallAction.callFunctionAsync(getAvatarPageLocal, [ this.semaphore ], action, delay);
  1599. }
  1600. }
  1601. async function getProfilePageLocal(semaphore) {
  1602. return UserProfile.hardLinks.profile.endsWith("/") || (UserProfile.hardLinks.profile += "/"),
  1603. await FuraffinityRequests.getHTML(UserProfile.hardLinks.profile, semaphore);
  1604. }
  1605. async function getProfilebannerPageLocal(semaphore) {
  1606. return UserProfile.hardLinks.profilebanner.endsWith("/") || (UserProfile.hardLinks.profilebanner += "/"),
  1607. await FuraffinityRequests.getHTML(UserProfile.hardLinks.profilebanner, semaphore);
  1608. }
  1609. async function getContactsPageLocal(semaphore) {
  1610. return UserProfile.hardLinks.contacts.endsWith("/") || (UserProfile.hardLinks.contacts += "/"),
  1611. await FuraffinityRequests.getHTML(UserProfile.hardLinks.contacts, semaphore);
  1612. }
  1613. async function getAvatarPageLocal(semaphore) {
  1614. return UserProfile.hardLinks.avatar.endsWith("/") || (UserProfile.hardLinks.avatar += "/"),
  1615. await FuraffinityRequests.getHTML(UserProfile.hardLinks.avatar, semaphore);
  1616. }
  1617. class ManageContent {
  1618. constructor(semaphore) {
  1619. this.semaphore = semaphore;
  1620. }
  1621. static get hardLinks() {
  1622. return {
  1623. submissions: FuraffinityRequests.getUrl() + "/controls/submissions/",
  1624. folders: FuraffinityRequests.getUrl() + "/controls/folders/submissions/",
  1625. journals: FuraffinityRequests.getUrl() + "/controls/journal/",
  1626. favorites: FuraffinityRequests.getUrl() + "/controls/favorites/",
  1627. buddylist: FuraffinityRequests.getUrl() + "/controls/buddylist/",
  1628. shouts: FuraffinityRequests.getUrl() + "/controls/shouts/",
  1629. badges: FuraffinityRequests.getUrl() + "/controls/badges/"
  1630. };
  1631. }
  1632. async getFoldersPages(action, delay = 100) {
  1633. return await WaitAndCallAction.callFunctionAsync(getContentFoldersLocal, [ this.semaphore ], action, delay);
  1634. }
  1635. async getAllWatchesPages(action, delay = 100) {
  1636. return await WaitAndCallAction.callFunctionAsync(getContentAllWatchesPagesLocal, [ this.semaphore ], action, delay);
  1637. }
  1638. async getWatchesPage(pageNumber, action, delay = 100) {
  1639. return await WaitAndCallAction.callFunctionAsync(getWatchesPageLocal, [ pageNumber, this.semaphore ], action, delay);
  1640. }
  1641. }
  1642. async function getContentFoldersLocal(semaphore) {
  1643. return ManageContent.hardLinks.folders.endsWith("/") || (ManageContent.hardLinks.folders += "/"),
  1644. await FuraffinityRequests.getHTML(ManageContent.hardLinks.folders, semaphore);
  1645. }
  1646. async function getContentAllWatchesPagesLocal(semaphore) {
  1647. ManageContent.hardLinks.buddylist.endsWith("/") || (ManageContent.hardLinks.buddylist += "/");
  1648. let usersDoc = await FuraffinityRequests.getHTML(ManageContent.hardLinks.buddylist + "x", semaphore);
  1649. const pages = usersDoc.getElementById("columnpage").querySelector('div[class="section-body"').querySelectorAll(":scope > a");
  1650. let userPageDocs = [];
  1651. for (let i = 1; i <= pages.length; i++) usersDoc = await getWatchesPageLocal(i, semaphore),
  1652. usersDoc && userPageDocs.push(usersDoc);
  1653. return 0 == userPageDocs.length ? null : userPageDocs;
  1654. }
  1655. async function getWatchesPageLocal(pageNumber, semaphore) {
  1656. return pageNumber ? (pageNumber <= 0 && (Logger.logWarning("Page number is less 1. Using default 1 instead."),
  1657. pageNumber = 1), ManageContent.hardLinks.buddylist.endsWith("/") || (ManageContent.hardLinks.buddylist += "/"),
  1658. await FuraffinityRequests.getHTML(ManageContent.hardLinks.buddylist + pageNumber, semaphore)) : (Logger.logError("No page number given"),
  1659. null);
  1660. }
  1661. class Security {
  1662. constructor(semaphore) {
  1663. this.semaphore = semaphore;
  1664. }
  1665. static get hardLinks() {
  1666. return {
  1667. sessions: FuraffinityRequests.getUrl() + "/controls/sessions/logins/",
  1668. logs: FuraffinityRequests.getUrl() + "/controls/logs/",
  1669. labels: FuraffinityRequests.getUrl() + "/controls/labels/"
  1670. };
  1671. }
  1672. async getSessionsPage(action, delay = 100) {
  1673. return await WaitAndCallAction.callFunctionAsync(getSecuritySessionsPageLocal, [ this.semaphore ], action, delay);
  1674. }
  1675. async getLogsPage(action, delay = 100) {
  1676. return await WaitAndCallAction.callFunctionAsync(getSecurityLogsPageLocal, [ this.semaphore ], action, delay);
  1677. }
  1678. async getLabelsPage(action, delay = 100) {
  1679. return await WaitAndCallAction.callFunctionAsync(getSecurityLabelsPageLocal, [ this.semaphore ], action, delay);
  1680. }
  1681. }
  1682. async function getSecuritySessionsPageLocal(semaphore) {
  1683. return Security.hardLinks.sessions.endsWith("/") || (Security.hardLinks.sessions += "/"),
  1684. await FuraffinityRequests.getHTML(Security.hardLinks.sessions, semaphore);
  1685. }
  1686. async function getSecurityLogsPageLocal(semaphore) {
  1687. return Security.hardLinks.logs.endsWith("/") || (Security.hardLinks.logs += "/"),
  1688. await FuraffinityRequests.getHTML(Security.hardLinks.logs, semaphore);
  1689. }
  1690. async function getSecurityLabelsPageLocal(semaphore) {
  1691. return Security.hardLinks.labels.endsWith("/") || (Security.hardLinks.labels += "/"),
  1692. await FuraffinityRequests.getHTML(Security.hardLinks.labels, semaphore);
  1693. }
  1694. class PersonalUserRequests {
  1695. constructor(semaphore) {
  1696. this.semaphore = semaphore, this.MessageRequests = new Message(semaphore), this.AccountInformation = new AccountInformation(semaphore),
  1697. this.UserProfile = new UserProfile(semaphore), this.ManageContent = new ManageContent(semaphore),
  1698. this.Security = new Security(semaphore);
  1699. }
  1700. }
  1701. class SubmissionRequests {
  1702. constructor(semaphore) {
  1703. this.semaphore = semaphore;
  1704. }
  1705. static get hardLinks() {
  1706. return {
  1707. view: FuraffinityRequests.getUrl() + "/view/",
  1708. fav: FuraffinityRequests.getUrl() + "/fav/",
  1709. unfav: FuraffinityRequests.getUrl() + "/unfav/",
  1710. journal: FuraffinityRequests.getUrl() + "/journal/"
  1711. };
  1712. }
  1713. async getSubmissionPage(submissionId, action, delay = 100) {
  1714. return await WaitAndCallAction.callFunctionAsync(getSubmissionPageLocal, [ submissionId, this.semaphore ], action, delay);
  1715. }
  1716. async favSubmission(submissionId, favKey, action, delay = 100) {
  1717. return await WaitAndCallAction.callFunctionAsync(favSubmissionLocal, [ submissionId, favKey, this.semaphore ], action, delay);
  1718. }
  1719. async unfavSubmission(submissionId, unfavKey, action, delay = 100) {
  1720. return await WaitAndCallAction.callFunctionAsync(unfavSubmissionLocal, [ submissionId, unfavKey, this.semaphore ], action, delay);
  1721. }
  1722. async getJournalPage(journalId, action, delay = 100) {
  1723. return await WaitAndCallAction.callFunctionAsync(getJournalPageLocal, [ journalId, this.semaphore ], action, delay);
  1724. }
  1725. }
  1726. async function getSubmissionPageLocal(submissionId, semaphore) {
  1727. if (!submissionId) return Logger.logError("No submissionId given"), null;
  1728. SubmissionRequests.hardLinks.view.endsWith("/") || (SubmissionRequests.hardLinks.view += "/");
  1729. const url = SubmissionRequests.hardLinks.view + submissionId;
  1730. return url ? await FuraffinityRequests.getHTML(url, semaphore) : null;
  1731. }
  1732. async function favSubmissionLocal(submissionId, favKey, semaphore) {
  1733. if (!submissionId) return void Logger.logError("No submissionId given");
  1734. if (!favKey) return void Logger.logError("No favKey given");
  1735. SubmissionRequests.hardLinks.fav.endsWith("/") || (SubmissionRequests.hardLinks.fav += "/");
  1736. const url = SubmissionRequests.hardLinks.fav + submissionId + "?key=" + favKey;
  1737. if (url) {
  1738. const resultDoc = await FuraffinityRequests.getHTML(url, semaphore);
  1739. try {
  1740. const standardpage = resultDoc.getElementById("standardpage");
  1741. if (standardpage) {
  1742. const blocked = standardpage.querySelector('div[class="redirect-message"]');
  1743. if (blocked && blocked.textContent.includes("blocked")) return;
  1744. }
  1745. return getFavKeyLocal(resultDoc);
  1746. } catch {}
  1747. }
  1748. }
  1749. async function unfavSubmissionLocal(submissionId, unfavKey, semaphore) {
  1750. if (!submissionId) return void Logger.logError("No submissionId given");
  1751. if (!unfavKey) return void Logger.logError("No unfavKey given");
  1752. SubmissionRequests.hardLinks.unfav.endsWith("/") || (SubmissionRequests.hardLinks.unfav += "/");
  1753. const url = SubmissionRequests.hardLinks.unfav + submissionId + "?key=" + unfavKey;
  1754. if (url) {
  1755. const resultDoc = await FuraffinityRequests.getHTML(url, semaphore);
  1756. if (resultDoc) {
  1757. return getFavKeyLocal(resultDoc);
  1758. }
  1759. }
  1760. }
  1761. async function getJournalPageLocal(journalId, semaphore) {
  1762. if (!journalId) return Logger.logError("No journalId given"), null;
  1763. SubmissionRequests.hardLinks.journal.endsWith("/") || (SubmissionRequests.hardLinks.journal += "/");
  1764. const url = SubmissionRequests.hardLinks.journal + journalId;
  1765. return url ? await FuraffinityRequests.getHTML(url, semaphore) : null;
  1766. }
  1767. function getFavKeyLocal(doc) {
  1768. const buttons = doc.getElementById("columnpage").querySelector('div[class*="favorite-nav"').querySelectorAll('a[class*="button"][href]');
  1769. let favButton;
  1770. for (const button of Array.from(buttons)) button.textContent.toLowerCase().includes("fav") && (favButton = button);
  1771. if (favButton) {
  1772. return favButton.getAttribute("href").split("?key=")[1];
  1773. }
  1774. }
  1775. class FuraffinityRequests {
  1776. constructor(maxAmountRequests = 2) {
  1777. this._semaphore = new Semaphore(maxAmountRequests), this.UserRequests = new UserRequests(this._semaphore),
  1778. this.PersonalUserRequests = new PersonalUserRequests(this._semaphore), this.SubmissionRequests = new SubmissionRequests(this._semaphore);
  1779. }
  1780. set maxAmountRequests(value) {
  1781. this._semaphore.maxConcurrency != value && (this._semaphore.maxConcurrency = value);
  1782. }
  1783. get maxAmountRequests() {
  1784. return this._semaphore.maxConcurrency;
  1785. }
  1786. static set useHttps(value) {
  1787. FuraffinityRequests._useHttps != value && (FuraffinityRequests._useHttps = value,
  1788. FuraffinityRequests._httpsString = value ? "https://" : "http://");
  1789. }
  1790. static get useHttps() {
  1791. return FuraffinityRequests._useHttps;
  1792. }
  1793. static logLevel=1;
  1794. static domain="www.furaffinity.net";
  1795. static _httpsString="https://";
  1796. static _useHttps=!0;
  1797. static getUrl() {
  1798. return FuraffinityRequests._httpsString + FuraffinityRequests.domain;
  1799. }
  1800. static async getHTML(url, semaphore, action, delay = 100) {
  1801. const waitAndCallAction = new WaitAndCallAction(action, null, delay);
  1802. waitAndCallAction.start();
  1803. const html = await async function(url, semaphore) {
  1804. Logger.logMessage(`Requesting '${url}'`);
  1805. const semaphoreActive = semaphore && semaphore.maxConcurrency > 0;
  1806. semaphoreActive && await semaphore.acquire();
  1807. try {
  1808. const response = await fetch(url), html = await response.text(), parser = new DOMParser;
  1809. return parser.parseFromString(html, "text/html");
  1810. } catch (error) {
  1811. Logger.logError(error);
  1812. } finally {
  1813. semaphoreActive && semaphore.release();
  1814. }
  1815. }(url, semaphore);
  1816. return waitAndCallAction.stop(), html;
  1817. }
  1818. static async postHTML(url, payload, semaphore, action, delay = 100) {
  1819. const waitAndCallAction = new WaitAndCallAction(action, null, delay);
  1820. waitAndCallAction.start();
  1821. const html = await async function(url, payload, semaphore) {
  1822. const semaphoreActive = semaphore && semaphore.maxConcurrency > 0;
  1823. semaphoreActive && await semaphore.acquire();
  1824. try {
  1825. const response = await fetch(url, {
  1826. method: "POST",
  1827. body: new URLSearchParams(payload).toString(),
  1828. headers: {
  1829. "Content-Type": "application/x-www-form-urlencoded"
  1830. }
  1831. });
  1832. if (!response.ok) return void Logger.logError(`HTTP error! Status: ${response.status}`);
  1833. const responseData = await response.text();
  1834. try {
  1835. const parser = new DOMParser;
  1836. return parser.parseFromString(responseData, "text/html");
  1837. } catch {
  1838. return responseData;
  1839. }
  1840. } catch (error) {
  1841. Logger.logError(error);
  1842. } finally {
  1843. semaphoreActive && semaphore.release();
  1844. }
  1845. }(url, payload, semaphore);
  1846. return waitAndCallAction.stop(), html;
  1847. }
  1848. }
  1849. Object.defineProperty(window, "FARequestHelper", {
  1850. get: () => FuraffinityRequests
  1851. });
  1852. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址