booru 2.6.2 → 2.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Constants.d.ts +1 -1
- package/dist/Constants.js +91 -1
- package/dist/Utils.d.ts +2 -2
- package/dist/Utils.js +185 -1
- package/dist/boorus/Booru.d.ts +1 -1
- package/dist/boorus/Booru.js +237 -1
- package/dist/boorus/Derpibooru.js +49 -1
- package/dist/boorus/XmlBooru.js +28 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +122 -1
- package/dist/index.js.map +1 -1
- package/dist/sites.json +1 -1
- package/dist/structures/InternalSearchParameters.js +7 -1
- package/dist/structures/Post.js +299 -1
- package/dist/structures/SearchParameters.js +7 -1
- package/dist/structures/SearchResults.js +128 -1
- package/dist/structures/Site.js +51 -1
- package/dist/structures/SiteApi.js +7 -1
- package/dist/structures/SiteInfo.js +7 -1
- package/package.json +20 -20
package/dist/index.js
CHANGED
|
@@ -1 +1,122 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
* @module Index
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.Site = exports.SearchResults = exports.Post = exports.XmlBooru = exports.Derpibooru = exports.BooruError = exports.resolveSite = exports.sites = exports.BooruClass = exports.commonfy = exports.search = exports.forSite = void 0;
|
|
11
|
+
const Constants_1 = require("./Constants");
|
|
12
|
+
const util_1 = require("util");
|
|
13
|
+
const Booru_1 = __importDefault(require("./boorus/Booru"));
|
|
14
|
+
const Derpibooru_1 = __importDefault(require("./boorus/Derpibooru"));
|
|
15
|
+
exports.Derpibooru = Derpibooru_1.default;
|
|
16
|
+
const XmlBooru_1 = __importDefault(require("./boorus/XmlBooru"));
|
|
17
|
+
exports.XmlBooru = XmlBooru_1.default;
|
|
18
|
+
const Post_1 = __importDefault(require("./structures/Post"));
|
|
19
|
+
exports.Post = Post_1.default;
|
|
20
|
+
const SearchResults_1 = __importDefault(require("./structures/SearchResults"));
|
|
21
|
+
exports.SearchResults = SearchResults_1.default;
|
|
22
|
+
const Site_1 = __importDefault(require("./structures/Site"));
|
|
23
|
+
exports.Site = Site_1.default;
|
|
24
|
+
const Utils_1 = require("./Utils");
|
|
25
|
+
const BooruTypes = {
|
|
26
|
+
derpi: Derpibooru_1.default,
|
|
27
|
+
xml: XmlBooru_1.default,
|
|
28
|
+
};
|
|
29
|
+
const booruCache = {};
|
|
30
|
+
/**
|
|
31
|
+
* Create a new booru, if special type, use that booru, else use default Booru
|
|
32
|
+
*
|
|
33
|
+
* @param booruSite The site to use
|
|
34
|
+
* @param credentials The credentials to use, if any
|
|
35
|
+
* @return A new booru
|
|
36
|
+
*/
|
|
37
|
+
function booruFrom(booruSite, credentials) {
|
|
38
|
+
return new (booruSite.type !== undefined && BooruTypes[booruSite.type]
|
|
39
|
+
? BooruTypes[booruSite.type]
|
|
40
|
+
: Booru_1.default)(booruSite, credentials);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Create a new booru to search with
|
|
44
|
+
*
|
|
45
|
+
* @constructor
|
|
46
|
+
* @param {String} site The {@link Site} domain (or alias of it) to create a booru from
|
|
47
|
+
* @param {BooruCredentials} credentials The credentials to use on this booru
|
|
48
|
+
* @return {Booru} A booru to use
|
|
49
|
+
*/
|
|
50
|
+
function booruForSite(site, credentials) {
|
|
51
|
+
const rSite = (0, Utils_1.resolveSite)(site);
|
|
52
|
+
if (!rSite)
|
|
53
|
+
throw new Constants_1.BooruError('Site not supported');
|
|
54
|
+
const booruSite = new Site_1.default(Constants_1.sites[rSite]);
|
|
55
|
+
// If special type, use that booru, else use default Booru
|
|
56
|
+
return booruFrom(booruSite, credentials);
|
|
57
|
+
}
|
|
58
|
+
exports.forSite = booruForSite;
|
|
59
|
+
exports.default = booruForSite;
|
|
60
|
+
/**
|
|
61
|
+
* Searches a site for images with tags and returns the results
|
|
62
|
+
* @param {String} site The site to search
|
|
63
|
+
* @param {String[]|String} [tags=[]] Tags to search with
|
|
64
|
+
* @param {SearchParameters} [searchOptions={}] The options for searching
|
|
65
|
+
* if provided (Unused)
|
|
66
|
+
* @return {Promise<SearchResults>} A promise with the images as an array of objects
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```
|
|
70
|
+
* const Booru = require('booru')
|
|
71
|
+
* // Returns a promise with the latest cute glace pic from e926
|
|
72
|
+
* Booru.search('e926', ['glaceon', 'cute'])
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
function search(site, tags = [], { limit = 1, random = false, page = 0, credentials = {} } = {}) {
|
|
76
|
+
const rSite = (0, Utils_1.resolveSite)(site);
|
|
77
|
+
if (typeof limit === 'string') {
|
|
78
|
+
limit = parseInt(limit, 10);
|
|
79
|
+
}
|
|
80
|
+
if (rSite === null) {
|
|
81
|
+
throw new Constants_1.BooruError('Site not supported');
|
|
82
|
+
}
|
|
83
|
+
if (!Array.isArray(tags) && typeof tags !== 'string') {
|
|
84
|
+
throw new Constants_1.BooruError('`tags` should be an array or string');
|
|
85
|
+
}
|
|
86
|
+
if (typeof limit !== 'number' || Number.isNaN(limit)) {
|
|
87
|
+
throw new Constants_1.BooruError('`limit` should be an int');
|
|
88
|
+
}
|
|
89
|
+
const booruSite = new Site_1.default(Constants_1.sites[rSite]);
|
|
90
|
+
if (!booruCache[rSite]) {
|
|
91
|
+
booruCache[rSite] = booruFrom(booruSite, credentials);
|
|
92
|
+
}
|
|
93
|
+
// This is ugly and a hack, I know this
|
|
94
|
+
booruCache[rSite].credentials = credentials;
|
|
95
|
+
return booruCache[rSite].search(tags, { limit, random, page });
|
|
96
|
+
}
|
|
97
|
+
exports.search = search;
|
|
98
|
+
// eslint-disable-next-line no-empty,@typescript-eslint/no-empty-function
|
|
99
|
+
const deprecatedCommonfy = (0, util_1.deprecate)(() => { }, 'Common is now deprecated, just access the properties directly');
|
|
100
|
+
/**
|
|
101
|
+
* Deprecated, now a noop
|
|
102
|
+
* <p>This will be removed *soon* please stop using it</p>
|
|
103
|
+
* <p>Just access <code><{@link Post}>.prop</code>, no need to commonfy anymore
|
|
104
|
+
*
|
|
105
|
+
* @deprecated Just use <code><{@link Post}>.prop</code> instead
|
|
106
|
+
* @param {Post[]} images Array of {@link Post} objects
|
|
107
|
+
* @return {Promise<Post[]>} Array of {@link Post} objects
|
|
108
|
+
*/
|
|
109
|
+
function commonfy(images) {
|
|
110
|
+
deprecatedCommonfy();
|
|
111
|
+
return Promise.resolve(images);
|
|
112
|
+
}
|
|
113
|
+
exports.commonfy = commonfy;
|
|
114
|
+
var Booru_2 = require("./boorus/Booru");
|
|
115
|
+
Object.defineProperty(exports, "BooruClass", { enumerable: true, get: function () { return Booru_2.Booru; } });
|
|
116
|
+
var Constants_2 = require("./Constants");
|
|
117
|
+
Object.defineProperty(exports, "sites", { enumerable: true, get: function () { return Constants_2.sites; } });
|
|
118
|
+
var Utils_2 = require("./Utils");
|
|
119
|
+
Object.defineProperty(exports, "resolveSite", { enumerable: true, get: function () { return Utils_2.resolveSite; } });
|
|
120
|
+
var Constants_3 = require("./Constants");
|
|
121
|
+
Object.defineProperty(exports, "BooruError", { enumerable: true, get: function () { return Constants_3.BooruError; } });
|
|
122
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;AAEH,2CAAwD;AAExD,+BAAgC;AAChC,2DAAwD;AACxD,qEAA4C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/sites.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"e621.net":{"domain":"e621.net","aliases":["e6","e621"],"nsfw":true,"api":{"search":"/posts.json?","postView":"/post/show/"},"random":true},"e926.net":{"domain":"e926.net","aliases":["e9","e926"],"nsfw":false,"api":{"search":"/posts.json?","postView":"/post/show/"},"random":true,"defaultTags":["rating:safe"]},"hypnohub.net":{"domain":"hypnohub.net","aliases":["hh","hypno","hypnohub"],"nsfw":true,"api":{"search":"/index.php?page=dapi&s=post&q=index&json=1&","postView":"/post/show/"},"paginate":"pid","random":
|
|
1
|
+
{"e621.net":{"domain":"e621.net","aliases":["e6","e621"],"nsfw":true,"api":{"search":"/posts.json?","postView":"/post/show/"},"random":true},"e926.net":{"domain":"e926.net","aliases":["e9","e926"],"nsfw":false,"api":{"search":"/posts.json?","postView":"/post/show/"},"random":true,"defaultTags":["rating:safe"]},"hypnohub.net":{"domain":"hypnohub.net","aliases":["hh","hypno","hypnohub"],"nsfw":true,"api":{"search":"/index.php?page=dapi&s=post&q=index&json=1&","postView":"/post/show/"},"paginate":"pid","random":false},"danbooru.donmai.us":{"domain":"danbooru.donmai.us","aliases":["db","dan","danbooru"],"nsfw":true,"api":{"search":"/posts.json?","postView":"/posts/"},"random":true},"konachan.com":{"domain":"konachan.com","aliases":["kc","konac","kcom"],"nsfw":true,"api":{"search":"/post.json?","postView":"/post/show/"},"random":true},"konachan.net":{"domain":"konachan.net","aliases":["kn","konan","knet"],"nsfw":false,"api":{"search":"/post.json?","postView":"/post/show/"},"random":true},"yande.re":{"domain":"yande.re","aliases":["yd","yand","yandere"],"nsfw":true,"api":{"search":"/post.json?","postView":"/post/show/"},"random":true},"gelbooru.com":{"domain":"gelbooru.com","aliases":["gb","gel","gelbooru"],"nsfw":true,"api":{"search":"/index.php?page=dapi&s=post&q=index&json=1&","postView":"/index.php?page=post&s=view&json=1&id="},"paginate":"pid","random":false},"rule34.xxx":{"domain":"api.rule34.xxx","aliases":["r34","rule34"],"nsfw":true,"api":{"search":"/index.php?page=dapi&s=post&q=index&json=1&","postView":"/index.php?page=post&s=view&json=1&id="},"paginate":"pid","random":false},"safebooru.org":{"domain":"safebooru.org","aliases":["sb","safe","safebooru"],"nsfw":false,"api":{"search":"/index.php?page=dapi&s=post&q=index&json=1&","postView":"/index.php?page=post&s=view&json=1&id="},"paginate":"pid","random":false},"tbib.org":{"domain":"tbib.org","aliases":["tb","tbib","big"],"nsfw":false,"api":{"search":"/index.php?page=dapi&s=post&q=index&json=1&","postView":"/index.php?page=post&s=view&json=1&id="},"paginate":"pid","random":false},"xbooru.com":{"domain":"xbooru.com","aliases":["xb","xbooru"],"nsfw":true,"api":{"search":"/index.php?page=dapi&s=post&q=index&json=1&","postView":"/index.php?page=post&s=view&json=1&id="},"paginate":"pid","random":false},"rule34.paheal.net":{"domain":"rule34.paheal.net","type":"xml","aliases":["pa","paheal"],"nsfw":true,"api":{"search":"/api/danbooru/find_posts/index.xml?","postView":"/post/view/"},"random":false},"derpibooru.org":{"domain":"derpibooru.org","type":"derpi","aliases":["dp","derp","derpi","derpibooru"],"nsfw":true,"api":{"search":"/api/v1/json/search/images?","postView":"/images/"},"tagQuery":"q","tagJoin":",","random":"sf=random"},"realbooru.com":{"domain":"realbooru.com","aliases":["rb","realbooru"],"nsfw":true,"api":{"search":"/index.php?page=dapi&s=post&q=index&json=1&","postView":"/index.php?page=post&s=view&id="},"paginate":"pid","random":false}}
|
package/dist/structures/Post.js
CHANGED
|
@@ -1 +1,299 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
* @module Structures
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const util_1 = require("util");
|
|
8
|
+
// eslint-disable-next-line no-empty,@typescript-eslint/no-empty-function
|
|
9
|
+
const common = (0, util_1.deprecate)(() => { }, 'Common is now deprecated, just access the properties directly');
|
|
10
|
+
/**
|
|
11
|
+
* Tries to figure out what the image url should be
|
|
12
|
+
*
|
|
13
|
+
* @param {string} url why
|
|
14
|
+
* @param {*} data boorus
|
|
15
|
+
* @param {Booru} booru so hard
|
|
16
|
+
*/
|
|
17
|
+
function parseImageUrl(url, data, booru) {
|
|
18
|
+
// If the image's file_url is *still* undefined or the source is empty or it's deleted
|
|
19
|
+
// Thanks danbooru *grumble grumble*
|
|
20
|
+
if (!url || url.trim() === '' || data.is_deleted) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
if (url.startsWith('/data')) {
|
|
24
|
+
url = `https://danbooru.donmai.us${url}`;
|
|
25
|
+
}
|
|
26
|
+
if (url.startsWith('/cached')) {
|
|
27
|
+
url = `https://danbooru.donmai.us${url}`;
|
|
28
|
+
}
|
|
29
|
+
if (url.startsWith('/_images')) {
|
|
30
|
+
url = `https://dollbooru.org${url}`;
|
|
31
|
+
}
|
|
32
|
+
if (url.startsWith('//derpicdn.net')) {
|
|
33
|
+
url = `https:${data.image}`;
|
|
34
|
+
}
|
|
35
|
+
// Why???
|
|
36
|
+
if (!data.file_url && data.directory !== undefined) {
|
|
37
|
+
// Danbooru-based boorus sometimes sort their files into directories
|
|
38
|
+
// There's 2 directories, one named after the first 2 characters of the hash
|
|
39
|
+
// and one named after the next 2 characters of the hash
|
|
40
|
+
// Sometimes we get it in the API response as `data.directory`, sometimes it's null
|
|
41
|
+
// for some ungodly reason
|
|
42
|
+
// I despise the danbooru api honestly
|
|
43
|
+
const directory = data.directory ?? `${data.hash.substr(0, 2)}/${data.hash.substr(2, 2)}`;
|
|
44
|
+
url = `//${booru.domain}/images/${directory}/${data.image}`;
|
|
45
|
+
}
|
|
46
|
+
if (!url.startsWith('http')) {
|
|
47
|
+
url = `https:${url}`;
|
|
48
|
+
}
|
|
49
|
+
return encodeURI(url);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Takes and transforms tags from the booru's api into a common format
|
|
53
|
+
* (which is an array of strings)
|
|
54
|
+
* @param {any} data The data from the booru
|
|
55
|
+
* @returns {string[]} The tags as a string array, and not just a string or an object
|
|
56
|
+
*/
|
|
57
|
+
function getTags(data) {
|
|
58
|
+
let tags = [];
|
|
59
|
+
if (Array.isArray(data.tags)) {
|
|
60
|
+
tags = data.tags;
|
|
61
|
+
}
|
|
62
|
+
else if (data.tags && data.tags.general) {
|
|
63
|
+
tags = Object.values(data.tags).flat();
|
|
64
|
+
}
|
|
65
|
+
else if (typeof data.tags === 'string') {
|
|
66
|
+
tags = fromTagString(data.tags);
|
|
67
|
+
}
|
|
68
|
+
else if (typeof data.tag_string === 'string') {
|
|
69
|
+
tags = fromTagString(data.tag_string);
|
|
70
|
+
}
|
|
71
|
+
return tags.filter((v) => v !== '');
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parses a string of tags into an array of tags, doing some sanitization
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* fromTagString('tag1 tag2 tag3') => ['tag1', 'tag2', 'tag3']
|
|
78
|
+
* fromTagString('tag1 tag,2 tag3 ') => ['tag1', 'tag2', 'tag3']
|
|
79
|
+
* @param tags The tags as a string
|
|
80
|
+
* @returns The string, parsed into an array of tags
|
|
81
|
+
*/
|
|
82
|
+
function fromTagString(tags) {
|
|
83
|
+
return tags.split(' ').map((v) => v.replace(/,/g, ''));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* An image from a booru with a few common props
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```
|
|
90
|
+
* Post {
|
|
91
|
+
* fileUrl: 'https://aaaa.com/image.jpg',
|
|
92
|
+
* id: '124125',
|
|
93
|
+
* tags: ['cat', 'cute'],
|
|
94
|
+
* score: 5,
|
|
95
|
+
* source: 'https://giraffeduck.com/aaaa.png',
|
|
96
|
+
* rating: 's'
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
class Post {
|
|
101
|
+
/** The {@link Booru} it came from */
|
|
102
|
+
booru;
|
|
103
|
+
/** The direct link to the file */
|
|
104
|
+
fileUrl;
|
|
105
|
+
/** The height of the file */
|
|
106
|
+
height;
|
|
107
|
+
/** The width of the file */
|
|
108
|
+
width;
|
|
109
|
+
/** The url to the medium-sized image (if available) */
|
|
110
|
+
sampleUrl;
|
|
111
|
+
/** The height of the medium-sized image (if available) */
|
|
112
|
+
sampleHeight;
|
|
113
|
+
/** The width of the medium-sized image (if available) */
|
|
114
|
+
sampleWidth;
|
|
115
|
+
/** The url to the smallest image (if available) */
|
|
116
|
+
previewUrl;
|
|
117
|
+
/** The height of the smallest image (if available) */
|
|
118
|
+
previewHeight;
|
|
119
|
+
/** The width of the smallest image (if available) */
|
|
120
|
+
previewWidth;
|
|
121
|
+
/** The id of this post */
|
|
122
|
+
id;
|
|
123
|
+
/** If this post is available (ie. not deleted, not banned, has file url) */
|
|
124
|
+
available;
|
|
125
|
+
/** The tags of this post */
|
|
126
|
+
tags;
|
|
127
|
+
/** The score of this post */
|
|
128
|
+
score;
|
|
129
|
+
/** The source of this post, if available */
|
|
130
|
+
source;
|
|
131
|
+
/**
|
|
132
|
+
* The rating of the image, as just the first letter
|
|
133
|
+
* (s/q/e/u) => safe/questionable/explicit/unrated
|
|
134
|
+
*/
|
|
135
|
+
rating;
|
|
136
|
+
/** The Date this post was created at */
|
|
137
|
+
createdAt;
|
|
138
|
+
/** All the data given by the booru @private */
|
|
139
|
+
data;
|
|
140
|
+
/**
|
|
141
|
+
* Create an image from a booru
|
|
142
|
+
*
|
|
143
|
+
* @param {Object} data The raw data from the Booru
|
|
144
|
+
* @param {Booru} booru The booru that created the image
|
|
145
|
+
*/
|
|
146
|
+
constructor(data, booru) {
|
|
147
|
+
// eslint-disable-next-line complexity
|
|
148
|
+
// Damn wild mix of boorus
|
|
149
|
+
this.data = data;
|
|
150
|
+
this.booru = booru;
|
|
151
|
+
// Again, thanks danbooru
|
|
152
|
+
const deletedOrBanned = data.is_deleted || data.is_banned;
|
|
153
|
+
this.fileUrl = parseImageUrl(data.file_url ||
|
|
154
|
+
data.image ||
|
|
155
|
+
(deletedOrBanned ? data.source : undefined) ||
|
|
156
|
+
(data.file && data.file.url) ||
|
|
157
|
+
(data.representations && data.representations.full), data, booru);
|
|
158
|
+
this.available = !deletedOrBanned && this.fileUrl !== null;
|
|
159
|
+
this.height = parseInt(data.height || data.image_height || (data.file && data.file.height), 10);
|
|
160
|
+
this.width = parseInt(data.width || data.image_width || (data.file && data.file.width), 10);
|
|
161
|
+
this.sampleUrl = parseImageUrl(data.sample_url ||
|
|
162
|
+
data.large_file_url ||
|
|
163
|
+
(data.representations && data.representations.large) ||
|
|
164
|
+
(data.sample && data.sample.url), data, booru);
|
|
165
|
+
this.sampleHeight = parseInt(data.sample_height || (data.sample && data.sample.height), 10);
|
|
166
|
+
this.sampleWidth = parseInt(data.sample_width || (data.sample && data.sample.width), 10);
|
|
167
|
+
this.previewUrl = parseImageUrl(data.preview_url ||
|
|
168
|
+
data.preview_file_url ||
|
|
169
|
+
(data.representations && data.representations.small) ||
|
|
170
|
+
(data.preview && data.preview.url), data, booru);
|
|
171
|
+
this.previewHeight = parseInt(data.preview_height || (data.preview && data.preview.height), 10);
|
|
172
|
+
this.previewWidth = parseInt(data.preview_width || (data.preview && data.preview.width), 10);
|
|
173
|
+
this.id = data.id ? data.id.toString() : 'No ID available';
|
|
174
|
+
this.tags = getTags(data);
|
|
175
|
+
if (data.score && data.score.total !== undefined) {
|
|
176
|
+
this.score = data.score.total;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
this.score = data.score ? parseInt(data.score, 10) : data.score;
|
|
180
|
+
}
|
|
181
|
+
this.source = data.source || data.sources || data.source_url;
|
|
182
|
+
this.rating =
|
|
183
|
+
data.rating ||
|
|
184
|
+
/(safe|suggestive|questionable|explicit)/i.exec(data.tags) ||
|
|
185
|
+
'u';
|
|
186
|
+
if (Array.isArray(this.rating)) {
|
|
187
|
+
this.rating = this.rating[0];
|
|
188
|
+
}
|
|
189
|
+
// Thanks derpibooru
|
|
190
|
+
if (this.rating === 'suggestive') {
|
|
191
|
+
this.rating = 'q';
|
|
192
|
+
}
|
|
193
|
+
this.rating = this.rating.charAt(0);
|
|
194
|
+
this.createdAt = null;
|
|
195
|
+
// eslint-disable-next-line
|
|
196
|
+
if (typeof data.created_at === 'object') {
|
|
197
|
+
this.createdAt = new Date(data.created_at.s * 1000 + data.created_at.n / 1000000000);
|
|
198
|
+
}
|
|
199
|
+
else if (typeof data.created_at === 'number') {
|
|
200
|
+
this.createdAt = new Date(data.created_at * 1000);
|
|
201
|
+
}
|
|
202
|
+
else if (typeof data.created_at === 'string') {
|
|
203
|
+
this.createdAt = new Date(data.created_at);
|
|
204
|
+
}
|
|
205
|
+
else if (typeof data.change === 'number') {
|
|
206
|
+
this.createdAt = new Date(data.change * 1000);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
this.createdAt = new Date(data.created_at || data.date);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* The direct link to the file
|
|
214
|
+
* <p>It's prefered to use `.fileUrl` instead because camelCase
|
|
215
|
+
*/
|
|
216
|
+
get file_url() {
|
|
217
|
+
return this.fileUrl;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* The url to the medium-sized image (if available)
|
|
221
|
+
* <p>It's prefered to use `.sampleUrl` instead because camelCase
|
|
222
|
+
*/
|
|
223
|
+
get sample_url() {
|
|
224
|
+
return this.sampleUrl;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* The height of the medium-sized image (if available)
|
|
228
|
+
* <p>It's prefered to use `.sampleHeight` instead because camelCase
|
|
229
|
+
*/
|
|
230
|
+
get sample_height() {
|
|
231
|
+
return this.sampleHeight;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* The width of the medium-sized image (if available)
|
|
235
|
+
* <p>It's prefered to use `.sampleWidth` instead because camelCase
|
|
236
|
+
*/
|
|
237
|
+
get sample_width() {
|
|
238
|
+
return this.sampleWidth;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* The url to the smallest image (if available)
|
|
242
|
+
* <p>It's prefered to use `.previewUrl` instead because camelCase
|
|
243
|
+
*/
|
|
244
|
+
get preview_url() {
|
|
245
|
+
return this.previewUrl;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The height of the smallest image (if available)
|
|
249
|
+
* <p>It's prefered to use `.previewHeight` instead because camelCase
|
|
250
|
+
*/
|
|
251
|
+
get preview_height() {
|
|
252
|
+
return this.previewHeight;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* The width of the smallest image (if available)
|
|
256
|
+
* <p>It's prefered to use `.previewWidth` instead because camelCase
|
|
257
|
+
*/
|
|
258
|
+
get preview_width() {
|
|
259
|
+
return this.previewWidth;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Get the post view (url to the post) of this image
|
|
263
|
+
*
|
|
264
|
+
* @type {String}
|
|
265
|
+
* @example
|
|
266
|
+
* ```
|
|
267
|
+
* const e9 = Booru('e9')
|
|
268
|
+
* const imgs = e9.search(['cat', 'dog'])
|
|
269
|
+
*
|
|
270
|
+
* // Log the post url of the first image
|
|
271
|
+
* console.log(imgs[0].postView)
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
get postView() {
|
|
275
|
+
return this.booru.postView(this.id);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Get some common props on the image
|
|
279
|
+
*
|
|
280
|
+
* @deprecated All common props are now attached directly to the image
|
|
281
|
+
* @type {Object}
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```
|
|
285
|
+
* image.id
|
|
286
|
+
* // deprecated, use this instead
|
|
287
|
+
* image.id
|
|
288
|
+
*
|
|
289
|
+
* // To access the post's raw data from the booru, do
|
|
290
|
+
* image._data.id
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
get common() {
|
|
294
|
+
common();
|
|
295
|
+
return this;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
exports.default = Post;
|
|
299
|
+
//# sourceMappingURL=Post.js.map
|
|
@@ -1 +1,128 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
* @module Structures
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
23
|
+
if (mod && mod.__esModule) return mod;
|
|
24
|
+
var result = {};
|
|
25
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
26
|
+
__setModuleDefault(result, mod);
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
const Utils = __importStar(require("../Utils"));
|
|
31
|
+
/**
|
|
32
|
+
* Represents a page of search results, works like an array of {@link Post}
|
|
33
|
+
* <p> Usable like an array and allows to easily get the next page
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```
|
|
37
|
+
* const Booru = require('booru')
|
|
38
|
+
* // Safebooru
|
|
39
|
+
* const sb = new Booru('sb')
|
|
40
|
+
*
|
|
41
|
+
* const imgs = await sb.search('cat')
|
|
42
|
+
*
|
|
43
|
+
* // Log the images from the first page, then from the second
|
|
44
|
+
* imgs.forEach(i => console.log(i.postView))
|
|
45
|
+
* const imgs2 = await imgs.nextPage()
|
|
46
|
+
* imgs2.forEach(i => console.log(i.postView))
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
class SearchResults extends Array {
|
|
50
|
+
/** The booru used for this search */
|
|
51
|
+
booru;
|
|
52
|
+
/** The page of this search */
|
|
53
|
+
page;
|
|
54
|
+
/** The tags used for this search */
|
|
55
|
+
tags;
|
|
56
|
+
/** The options used for this search */
|
|
57
|
+
options;
|
|
58
|
+
/** The posts from this search result */
|
|
59
|
+
posts;
|
|
60
|
+
/** @private */
|
|
61
|
+
constructor(posts, tags, options, booru) {
|
|
62
|
+
super(posts.length);
|
|
63
|
+
for (let i = 0; i < posts.length; i++) {
|
|
64
|
+
this[i] = posts[i];
|
|
65
|
+
}
|
|
66
|
+
this.posts = posts;
|
|
67
|
+
this.tags = tags;
|
|
68
|
+
this.options = options;
|
|
69
|
+
this.booru = booru;
|
|
70
|
+
this.page = options ? options.page || 0 : 0;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the first post in this result set
|
|
74
|
+
* @return {Post}
|
|
75
|
+
*/
|
|
76
|
+
get first() {
|
|
77
|
+
return this[0];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the last post in this result set
|
|
81
|
+
* @return {Post}
|
|
82
|
+
*/
|
|
83
|
+
get last() {
|
|
84
|
+
return this[this.length - 1];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get the next page
|
|
88
|
+
* <p>Works like <code>sb.search('cat', {page: 1}); sb.search('cat', {page: 2})</code>
|
|
89
|
+
* @return {Promise<SearchResults>}
|
|
90
|
+
*/
|
|
91
|
+
nextPage() {
|
|
92
|
+
const opts = this.options;
|
|
93
|
+
opts.page = this.page + 1;
|
|
94
|
+
return this.booru.search(this.tags, opts);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Create a new SearchResults with just images with the matching tags
|
|
98
|
+
*
|
|
99
|
+
* @param {String[]|String} tags The tags (or tag) to search for
|
|
100
|
+
* @param {Object} options The extra options for the search
|
|
101
|
+
* @param {Boolean} [options.invert=false] If the results should be inverted and
|
|
102
|
+
* return images *not* tagged
|
|
103
|
+
* @return {SearchResults}
|
|
104
|
+
*/
|
|
105
|
+
tagged(tags, { invert = false } = {}) {
|
|
106
|
+
if (!Array.isArray(tags)) {
|
|
107
|
+
tags = [tags];
|
|
108
|
+
}
|
|
109
|
+
const posts = [];
|
|
110
|
+
for (const p of this) {
|
|
111
|
+
const m = Utils.compareArrays(tags, p.tags).length;
|
|
112
|
+
if ((!invert && m > 0) || (invert && m === 0)) {
|
|
113
|
+
posts.push(p);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return new SearchResults(posts, this.tags, this.options, this.booru);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Returns a SearchResults with images *not* tagged with any of the specified tags (or tag)
|
|
120
|
+
* @param {String[]|String} tags The tags (or tag) to blacklist
|
|
121
|
+
* @return {SearchResults} The results without any images with the specified tags
|
|
122
|
+
*/
|
|
123
|
+
blacklist(tags) {
|
|
124
|
+
return this.tagged(tags, { invert: true });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.default = SearchResults;
|
|
128
|
+
//# sourceMappingURL=SearchResults.js.map
|