Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

danbooru

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

danbooru - npm Package Compare versions

Comparing version 1.4.8 to 2.0.0

index.js

43

package.json
{
"name": "danbooru",
"version": "1.4.8",
"version": "2.0.0",
"description": "danbooru api wrapper",
"main": "lib/index.js",
"main": "index.js",
"directories": {
"test": "test"
},
"scripts": {
"build": "lsc -o lib src",
"doctoc": "doctoc --notitle README.md",
"clean": "rm -rf lib",
"test": "lsc test",
"prepublish": "npm run build",
"postpublish": "npm run clean"
"test": "tape test/*"
},

@@ -19,20 +17,9 @@ "repository": {

"keywords": [
"wrapper",
"tags",
"tag",
"search",
"posts",
"post",
"manga",
"images",
"image",
"gallery",
"favorites",
"favorite",
"danbooru",
"booru",
"api",
"anime"
"image",
"anime",
"manga"
],
"author": "Pudding <aideen@aideen.pw> (https://aideen.pw)",
"license": "ISC",

@@ -43,13 +30,7 @@ "bugs": {

"homepage": "https://github.com/stawberri/danbooru-node#readme",
"author": "Pudding <aideen@aideen.pw> (https://aideen.pw/)",
"devDependencies": {
"doctoc": "^1.0.0",
"livescript": "^1.4.0",
"nock": "^7.2.2",
"tape": "^4.5.1"
},
"dependencies": {
"args-js": "^0.10.11",
"extend": "^3.0.0",
"request": "^2.69.0"
"nock": "^9.0.13",
"tape": "^4.6.3"
}
}

@@ -7,194 +7,223 @@ # danbooru-node

My api wrapper is super simple! You just require it, then refer to [Danbooru's lovely api documentation](https://danbooru.donmai.us/wiki_pages/43568) and make requests!
```javascript
Danbooru = require('danbooru');
This package is an api wrapper intended to make [Danbooru's api](https://danbooru.donmai.us/wiki_pages/43568) even easier to work with.
Danbooru.search('rating:s order:rank', function(err, data) {
data.random()
.getLarge()
.pipe(require('fs').createWriteStream('random.jpg'));
});
```js
const Danbooru = require('danbooru')
let booru = new Danbooru()
booru.posts('fox_ears smile').then(async posts => {
let file = posts[0].file
let data = await file.download()
require('fs').writeFile(file.name, data))
})
```
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
This module has been updated to require Node.js 7. You can still install version 1 with `npm install danbooru@1` and [read its documentation on Github](https://github.com/stawberri/danbooru-node/tree/v1.4.8).
- [Making requests](#making-requests)
- [Danbooru.method([path], [params], [callback])](#danboorumethodpath-params-callback)
- [Danbooru.request([options], [callback])](#danboorurequestoptions-callback)
- [Authentication](#authentication)
- [[new] Danbooru([object], [api_key])](#new-danbooruobject-api_key)
- [Searching](#searching)
- [Danbooru.search([tags], [params], [callback])](#danboorusearchtags-params-callback)
- [searchData](#searchdata)
- [searchData.page](#searchdatapage)
- [searchData.load([page], [callback])](#searchdataloadpage-callback)
- [searchData.next([modifier], [callback])](#searchdatanextmodifier-callback)
- [searchData.prev([modifier], [callback])](#searchdataprevmodifier-callback)
- [searchData.tags](#searchdatatags)
- [searchData.add([tagMod], [callback])](#searchdataaddtagmod-callback)
- [searchData.add([tagMod], [callback])](#searchdataaddtagmod-callback-1)
- [searchData.random()](#searchdatarandom)
- [post](#post)
- [post.get([callback])](#postgetcallback)
- [post.getLarge([callback])](#postgetlargecallback)
- [post.getPreview([callback])](#postgetpreviewcallback)
- [post.favorite([yes], [callback])](#postfavoriteyes-callback)
- [post.url](#posturl)
## Danbooru class
This module exposes the `Danbooru` class. Instantiating it with no arguments creates an unauthenticated session, while passing it parameters allows you to log in. You can also specify an alternate base url. Your `api_key` is not your password, and you can find it on your profile page.
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
```js
// Unauthenticated session
let booru = new Danbooru()
## Making requests
// Login to your account with your username and api_key
let booru = new Danbooru('login', 'api_key')
```javascript
Danbooru.get('posts', {limit: 5, tags: 'cat_ears'}, function(err, data) {
if(err) throw err;
console.log(data); // All of your cute kittehgirls!
});
// Optionally provide a base url to use a different server
let booru = new Danbooru({
login: 'login',
api_key: 'api_key',
base: 'http://sonohara.donmai.us'
})
// Specify all three in one string
let booru = new Danbooru(`http://login:api_key@sonohara.donmai.us`)
```
You can also use `Danbooru.post()`, `Danbooru.put()`, and `Danbooru.delete()`. They all have the same parameters and give you the same callback!
### Safebooru subclass
### Danbooru.method([path], [params], [callback])
Perform a http request on Danbooru's api!
* `method` _property_. One of `get`, `post`, `put`, or `delete`, depending on what type of request you would like to make.
* `path` _string_. The API documentation mentions a base URL. You put that here! The slash and `.json` are optional. In fact, the entire thing is optional, but you won't get anything useful from omitting path.
* `params` _object_. Just provide your parameters as an object!
* `callback` _function(err, data)_. What do you wannya do after you get your api request?
- `err` _Error_. Node.js callbacks always give you an error for some reason. Here you go!
- `data` _object_. Parsing JSON output is an extra step, so you don't hafta do it! Here's an already-parsed object for you!
A `Safebooru` subclass is available that locks the base url to `https://safebooru.donmai.us`. This alternate server only serves "safe" images. Please refer to [Danbooru's definition of safe](https://danbooru.donmai.us/wiki_pages/10920), and remember that ratings for most posts can be changed by anyone.
### Danbooru.request([options], [callback])
A simple wrapper function for [request](https://www.npmjs.com/package/request), with `baseUrl` always set to Danbooru. Refer to [their documentation](https://www.npmjs.com/package/request#requestoptions-callback) for details.
* `options` _string_. _object_. A url or options for your request.
* `callback` _function(err, response, body)_. Callback function. `response` is a usual node HTTP response, while `body` is the body of that response, ready for using.
* **returns** _request_. Request object.
```js
// Unauthenticated safe images session
let booru = new Danbooru.Safebooru()
I'm providing this to give you an easy way to download images and make custom requests without having to type Danbooru's url:
// Login, but still only see safe posts
let booru = new Danbooru.Safebooru('login', 'api_key')
```
```javascript
Danbooru.request('/data/9b5d16968321eff393fea8d735d69de3.jpg')
.pipe(fs.create-write-stream('cutiefox.jpg'));
## Image posts
Images on Danbooru come with a bunch of tags and other metadata. These are bundled into packages called posts. There are two functions available to you to find them.
### Searching for posts
You can search for a tag string, or choose to use the full set of post listing parameters Danbooru makes available through its api. You may wish to refer to [Danbooru's search cheat sheet](https://danbooru.donmai.us/wiki_pages/43049) to decide on your search query.
This function returns a promise that resolves to an array of posts.
```js
// Perform a simple search for a tag string or array of tags
let postArray = await booru.posts('fox_ears smile')
let postArray = await booru.posts(['fox_ears', 'smile'])
// Specify parameters
let postArray = await booru.posts({
limit: 100,
page: 1,
tags: 'fox_ears smile',
random: true
})
```
## Authentication
You know what's a pain? Having to type the same stuff over and over again. You know what you hafta do if you want to be authenticated on Danbooru? Send your `login` and `api_key` over and over again.
### Fetching a post
If you know the numerical ID of a post, you can fetch it directly. This function returns a promise that resolves to a single post.
```javascript
authedBooru = new Danbooru({login: 'topsecret', api_key: 'evenmoresecret'});
authedBooru.post('favorites', {post_id: 2288637}, function(err, data) {
if(err) throw err;
console.log('Successfully favorited!'); // Wow, you do like kittehgirls!
});
```js
// Fetch a single post
let post = await booru.posts.get(2689871)
```
If that's still too much typing for you, you can use a shortcut!
```javascript
shortBooru = Danbooru('topsecret', 'evenmoresecret');
### Post object
This module parses posts and restructures them into an instance of `Post`.
```js
// Get the id of a post as an integer or a string
let id = post.id
let id = +post
let id = String(post)
// Get a post's raw data, as received from the server
let data = post.raw
// Look up a post's tags
let tags = post.tags
// Break up a post's tags into categories
let artists = post.tags.artist
let characters = post.tags.character
let copyrights = post.tags.copyright
let otherTags = post.tags.general
// Get a post's rating as a boolean
let isSafe = post.rating.s
let isSafe = post.rating.safe
let isQuestionable = post.rating.q
let isQuestionable = post.rating.questionable
let isExplicit = post.rating.e
let isExplicit = post.rating.explicit
// Or get it as a string
String(post.rating) === 's'
```
### [new] Danbooru([object], [api_key])
Save parameters for later. Returns a new Danbooru object that you can use to make requests with those saved parameters.
* `object` _object_. _string_. If you provide an object, it'll be used as default parameters for all requests you make! If you provide a string, it'll set your default `login` parameter to whatever you provide! If you provide neither, you'll create a new, empty `Danbooru` object.
* `api_key` _string_. If (and only if) you provided a string for `object`, this will be used as your default `api_key` parameter!
### Download object
Posts have a download object meant to make downloading files easier. You can access it with `post.file`.
## Searching
Note that you may occasionally encounter posts that have been deleted or marked as unavailable due to their tags. In this case, `post.file` will still return an object, but it will be missing most of its properties.
"But wait," you say, "APIs are supposed to help make my life easier! Why do I still have to type so much?" Well, I made a helper function called `.search()` for you, and as a bonus, its data object even gives you extra helper functions to get around more easily! The helper functions are also returned by `.search()`, so you can chain more nicely!
```js
// Fetch a post's file object
let file = post.file
// Check if it's actually available first
if(!('request' in file)) return
```javascript
Danbooru.search('1girl fox_ears', function(err, page1) {
if(err) throw err;
console.log(page1); // Foxgirls!
}).next(function(err, page2) {
if(err) throw err;
console.log(page2); // More foxgirls!
page2.next(function(err, page3) {
if(err) throw err;
console.log(page3); // So many foxgirls~ ♥
});
});
// Get some details about the file
let filename = file.name
let fileExtension = file.ext
let width = file.width
let height = file.height
let md5 = file.md5
let size = file.size
// Start a http request for the file
// let httpResponse = file.request()
// Or just get its data in a promise!
let dataPromise = file.download()
// Keep track of its download progress
dataPromise.data((bytesDownloaded, bytesTotal) => {
let percent = 100 * bytesDownloaded/bytesTotal
console.log(`Currently downloaded ${percent}%`)
})
// then() or await the promise to get a buffer of your image
let dataBuffer = await dataPromise
// You can also cancel a download
// dataPromise.abort()
```
### Danbooru.search([tags], [params], [callback])
Perform a search on Danbooru. A shortcut for `Danbooru.get('posts', {tags: tags, limit: 100, ...params}, callback)`, but also adds on extra methods to the data object you get. Visit [an api result](https://danbooru.donmai.us/posts.json?tags=fox_ears&limit=2) in your browser to inspect the data object provided.
* `tags` _string_. A space separated list of tags, and basically your Danbooru search query. You can try out your query visually on [Danbooru](https://danbooru.donmai.us/) or look up their [searching reference](https://danbooru.donmai.us/wiki_pages/43049) if you're not sure what to type.
* `params` _object_. These are just parameters that will be directly passed to Danbooru's API. It will contain `limit: 100`
by default, but you can change the number of posts you want by specifying it. Trying to specify `tags` won't do anything, because the `tags` parameter always overwrites the value of `tags` here, even if `tags` is empty or missing (which makes it default to empty).
* `callback` _function(err, searchData)_ Do something after your request comes back.
- `err` _Error_. Like always, an error object if there was one.
- `searchData` _object_. Whatever Danbooru's API returns, but with some extra methods and properties. More details below!
* **returns** _object_. Contains only my extra helper methods and properties from `searchData`. Also details below~
Posts also have a `preview` thumbnail image, and a `large` preview image that is used on post pages if the actual image is too large.
### searchData
Like I've said probably three times already, this data object is the one that Danbooru's api gives you, but with some nice helper functions! You can see sample API output by [visiting Danbooru](https://danbooru.donmai.us/posts.json?tags=fox_ears&limit=2). I haven't told you what the methods are yet, so~
```js
// Get thumbnail image
let preview = post.file.preview
// Preview images have less data associated with them
// This set of data is also available to large preview images
let name = preview.name
let extension = preview.ext
let response = preview.request()
let data = preview.download()
#### searchData.page
This is a property that tells you what your current page number is. You can't change it.
// Large preview images do not always exist, so check if they exist first.
if('large' in post.file) {
let largePreview = post.file.large
let largeBuffer = await largePreview.download()
}
```
#### searchData.load([page], [callback])
Calls `Danbooru.search()` again with the same tags and parameters as last time, but with the page of results you want! Trying to load a page number less than 1 will just set it to 1.
* `page` _number_. What page of results would you like? Defaults to your current page, so you can actually use `searchData.load(callback)` to refresh your data.
* `callback` _function(err, searchData)_. This literally gives you the same type of object as the `searchData` you're currently looking at.
#### searchData.next([modifier], [callback])
Calls `searchData.load(this.page + modifier, callback)`, which basically increases your page number by your specified modifier. This will usually give you older posts (unless you specify a negative modifier for some reason).
* `modifier` _number_. What number would you like to increment your page number by?
* `callback` _function(err, searchData)_. Same as above.
## Favorites
The `Danbooru` object exposes a function for fetching and setting favorites.
#### searchData.prev([modifier], [callback])
Calls `searchData.load(this.page - modifier, callback)`, which basically decreases your page number by your specified modifier. This will usually give you newer posts (unless you specify a negative modifier for some reason).
* `modifier` _number_. What number would you like to decrement your page number by?
* `callback` _function(err, searchData)_. Same as above.
This will throw an error with an unauthenticated session.
#### searchData.tags
This is a property that tells you what tags your search is currently for. You can't change it.
```js
// Get a post array of your favorites
let favoriteArray = await booru.favorites()
#### searchData.add([tagMod], [callback])
Calls `Danbooru.search()` again with the same parameters as last time, but with your `tagMod` added to the end of your `tags` and `page` set back to 1.
* `tagMod` _string_. This basically just takes your current tags and then adds these tags to it. In other words, effectively `Danbooru.search(searchData.tags + " " + tagMod, params, callback)`.
* `callback` _function(err, searchData)_. Meow.
// Add a favorite
// Returns a promise that resolves true on success, throws on error
let success = await booru.favorites.add(2689871)
let success = await booru.favorites.add(post) // Or use a post object
#### searchData.add([tagMod], [callback])
Calls `Danbooru.search()` again with the same parameters as last time, removing the tags in your `tagMod` from `tags` and `page` set back to 1.
* `tagMod` _string_. This list of tags is separated by spaces, and then any tags here are removed from your tags for your new search.
* `callback` _function(err, searchData)_. Nyaa.
// Remove a favorite
let success = await booru.favorites.delete(2689871, false)
let success = await booru.favorites.delete(post, false)
```
#### searchData.random()
Gives you a random post from the set of posts you've found. Doesn't return anything when you don't have any posts.
* **returns** _object_. A random post from `searchData`.
### post
When you're searching, you're probably looking for posts. When you're looking for posts, you probably wannya make get requests to their image URLs to be able to use them. Rather than make you write `Danbooru.request(post.file_url)` over and over again, how about we make things simpler for you? This example uses `random`, but you could also just go to any valid index and it would still work.
## Custom requests
This api wrapper is still missing a lot of things, so you can use its request method directly to access endpoints that haven't been wrapped yet.
```javascript
authBooru = new Danbooru('maidlover', 'maidsarecute');
authBooru.search('maid', function(err, data) {
if(err) throw err;
data.random().favorite(); // Favoriting a random maid~ H-how bold!
});
This function call returns a promise that resolves to a parsed json object. Any error encountered while trying to generate this object will be rejected.
```js
let objectPromise = booru.requestJson('METHOD path', {parameters})
```
#### post.get([callback])
This does a get request to your post's `file_url`, which is usually your post's full size image. This also uses [request](https://www.npmjs.com/package/request), just like `Danbooru.request()`.
* `callback` _function(err, response, body)_. Callback function. `response` is a usual node HTTP response, while `body` is your image data.
* **returns** _request_. Request object.
* objectPromise: A promise of the results of your api call
* method: `GET`, `POST`, `PUT`, or `DELETE`. If you leave this out, it'll be a `GET` request.
* path: Your api endpoint. The beginning slash and `.json` are optional.
* parameters: If this is a get request, this will be added to your querystring. It supports nested objects and arrays. If this is another type of request, it'll be sent as a json body.
#### post.getLarge([callback])
This does a get request to your post's `large_file_url`, which is a large image appropriate for browsers, but not original size. It's sometimes the same image as `file_url`. This also uses [request](https://www.npmjs.com/package/request), just like `Danbooru.request()`.
* `callback` _function(err, response, body)_. Callback function. `response` is a usual node HTTP response, while `body` is your image data.
* **returns** _request_. Request object.
```js
// GET /posts.json
let data = await booru.requestJson('posts')
#### post.getPreview([callback])
This does a get request to your post's `preview_file_url`, which is usually your post's tiny preview image, useful for thumbnails. This also uses [request](https://www.npmjs.com/package/request), just like `Danbooru.request()`.
* `callback` _function(err, response, body)_. Callback function. `response` is a usual node HTTP response, while `body` is your image data.
* **returns** _request_. Request object.
// GET /posts.json?limit=5&tags=1girl
let data = await booru.requestJson('posts', {limit: 5, tags: '1girl'})
#### post.favorite([yes], [callback])
This function only really works with an authenticated Danbooru object, but you can use it to quickly favorite or unfavorite a post!
* `yes` _boolean_. Defaults to yes. Pass `false` to perform an unfavorite instead.
* `callback` _function(err, data)_. It's a callback.
// GET /artists.json?search[id]=135024&search[is_active]=true
let data = await booru.requestJson('artists', {
search: {
id: 135024,
is_active: true
}
})
#### post.url
This property contains a human friendly post url. This is where you would find this post if you were manually browsing Danbooru in a browser.
// POST /favorites.json
// body: {"post_id": 2689871}
let data = await booru.requestJson('POST favorites', {post_id: 2689871})
// DELETE /favorites/2689871.json
let data = await booru.requestJson('DELETE favorites/2689871')
```

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc