pixiv_api 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +8 -0
- data/Guardfile +14 -0
- data/LICENSE.txt +21 -0
- data/README.md +33 -0
- data/Rakefile +6 -0
- data/lib/pixiv_api.rb +22 -0
- data/lib/pixiv_api/array_response.rb +23 -0
- data/lib/pixiv_api/authentication.rb +60 -0
- data/lib/pixiv_api/client.rb +72 -0
- data/lib/pixiv_api/configuration.rb +48 -0
- data/lib/pixiv_api/pixiv_blob.rb +41 -0
- data/lib/pixiv_api/request.rb +18 -0
- data/lib/pixiv_api/request/favorite_users.rb +19 -0
- data/lib/pixiv_api/request/friends.rb +9 -0
- data/lib/pixiv_api/request/novels.rb +21 -0
- data/lib/pixiv_api/request/profiles.rb +9 -0
- data/lib/pixiv_api/request/promotions.rb +20 -0
- data/lib/pixiv_api/request/ranking.rb +9 -0
- data/lib/pixiv_api/request/search.rb +10 -0
- data/lib/pixiv_api/request/signup.rb +25 -0
- data/lib/pixiv_api/request/trends.rb +16 -0
- data/lib/pixiv_api/request/upload_work.rb +27 -0
- data/lib/pixiv_api/request/users.rb +13 -0
- data/lib/pixiv_api/request/util.rb +38 -0
- data/lib/pixiv_api/request/version.rb +9 -0
- data/lib/pixiv_api/request/works.rb +21 -0
- data/lib/pixiv_api/response.rb +134 -0
- data/lib/pixiv_api/response/action.rb +23 -0
- data/lib/pixiv_api/response/friend.rb +25 -0
- data/lib/pixiv_api/response/identity.rb +12 -0
- data/lib/pixiv_api/response/illustration.rb +6 -0
- data/lib/pixiv_api/response/manga.rb +6 -0
- data/lib/pixiv_api/response/novel.rb +15 -0
- data/lib/pixiv_api/response/pagination.rb +25 -0
- data/lib/pixiv_api/response/promotion.rb +11 -0
- data/lib/pixiv_api/response/request.rb +26 -0
- data/lib/pixiv_api/response/signup_validation_result.rb +7 -0
- data/lib/pixiv_api/response/tag.rb +9 -0
- data/lib/pixiv_api/response/ugoira.rb +18 -0
- data/lib/pixiv_api/response/upload_status.rb +7 -0
- data/lib/pixiv_api/response/upload_token.rb +7 -0
- data/lib/pixiv_api/response/user.rb +15 -0
- data/lib/pixiv_api/response/version.rb +7 -0
- data/lib/pixiv_api/response/work.rb +46 -0
- data/lib/pixiv_api/version.rb +3 -0
- data/pixiv_api.gemspec +32 -0
- data/spec/pixiv_api/authentication_spec.rb +57 -0
- data/spec/pixiv_api/client_spec.rb +28 -0
- data/spec/pixiv_api/configuration_spec.rb +41 -0
- data/spec/pixiv_api/pixiv_blob_spec.rb +23 -0
- data/spec/pixiv_api/request/favorite_users_spec.rb +47 -0
- data/spec/pixiv_api/request/friends_spec.rb +14 -0
- data/spec/pixiv_api/request/novels_spec.rb +37 -0
- data/spec/pixiv_api/request/profiles_spec.rb +13 -0
- data/spec/pixiv_api/request/signup_spec.rb +76 -0
- data/spec/pixiv_api/request/upload_work_spec.rb +41 -0
- data/spec/pixiv_api/request/users_spec.rb +32 -0
- data/spec/pixiv_api/request/works_spec.rb +16 -0
- data/spec/pixiv_api/version_spec.rb +7 -0
- data/spec/pixiv_api_spec.rb +8 -0
- metadata +275 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 961ad581d6a5b885d569658d903f45de1e6ef087
|
4
|
+
data.tar.gz: a56caea6f1ab24fcdda97b62e20f98aedbc8835b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9bb6d66208eeed8bdd055a34f14a1246790e88f32fa10f8018c648626990dc99c1306fb69b9260e2d529581e1c7d0e107941a19c306d2d8bfee44ec7d2700ece
|
7
|
+
data.tar.gz: 6647a7baca1df1e35315598b2f05dd52b26dba0845e359f3dd343d2f61c808450e52bad47ac59b8c702bb425b04a9c014df5bcae295f4fb15d41ede80bdb36a7
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
2
|
+
require 'guard/rspec/dsl'
|
3
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
4
|
+
|
5
|
+
# RSpec files
|
6
|
+
rspec = dsl.rspec
|
7
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
8
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
9
|
+
watch(rspec.spec_files)
|
10
|
+
|
11
|
+
# Ruby files
|
12
|
+
ruby = dsl.ruby
|
13
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
14
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 alpaca-tc
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# PixivApi
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Add this line to your application's Gemfile:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
gem 'pixiv_api', github: 'pixiv/pixiv-api-ruby'
|
9
|
+
```
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
```
|
14
|
+
# Setup
|
15
|
+
PixivApi.configure do |config|
|
16
|
+
config[:client_id] = '...'
|
17
|
+
config[:client_secret] = '...'
|
18
|
+
config[:site] = '...'
|
19
|
+
config[:authorize_url] = '...'
|
20
|
+
config[:token_url] = '...'
|
21
|
+
end
|
22
|
+
|
23
|
+
user = User.first # Sign in with Oauth2
|
24
|
+
|
25
|
+
client = PixivApi::Client.new(
|
26
|
+
access_token: user.access_token,
|
27
|
+
refresh_token: user.refresh_token,
|
28
|
+
expires_at: user.expires_at
|
29
|
+
)
|
30
|
+
|
31
|
+
client.me # => return '/v1/me.json'
|
32
|
+
client.work(id: 1) # => '/v1/works/:id.json'
|
33
|
+
```
|
data/Rakefile
ADDED
data/lib/pixiv_api.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'active_support/core_ext/array/extract_options'
|
2
|
+
require 'active_support/core_ext/hash/deep_merge'
|
3
|
+
|
4
|
+
module PixivApi
|
5
|
+
autoload :VERSION, 'pixiv_api/version'
|
6
|
+
autoload :Client, 'pixiv_api/client'
|
7
|
+
autoload :Authentication, 'pixiv_api/authentication'
|
8
|
+
autoload :ArrayResponse, 'pixiv_api/array_response'
|
9
|
+
autoload :Configuration, 'pixiv_api/configuration'
|
10
|
+
autoload :Identity, 'pixiv_api/identity'
|
11
|
+
autoload :Request, 'pixiv_api/request'
|
12
|
+
autoload :Response, 'pixiv_api/response'
|
13
|
+
autoload :PixivBlob, 'pixiv_api/pixiv_blob'
|
14
|
+
|
15
|
+
def self.configure
|
16
|
+
yield(configuration)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.configuration
|
20
|
+
@configuration ||= Configuration.new
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'memoizable'
|
2
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
3
|
+
|
4
|
+
module PixivApi
|
5
|
+
class ArrayResponse < Array
|
6
|
+
def self.from_response(response, klass, array)
|
7
|
+
new(response).tap do |array_response|
|
8
|
+
array.each do |attributes|
|
9
|
+
array_response << klass.from_response(response, attributes)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(response)
|
15
|
+
super()
|
16
|
+
@response = response
|
17
|
+
end
|
18
|
+
|
19
|
+
def pagination
|
20
|
+
@pagination ||= Response::Pagination.new(@response, @response.parsed['pagination'])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module PixivApi
|
5
|
+
class Authentication
|
6
|
+
# Authentication provides password authentication for development.
|
7
|
+
class InvalidAuthError < StandardError; end
|
8
|
+
|
9
|
+
def initialize(id:, password:)
|
10
|
+
connection = Faraday.new(default_options) do |conn|
|
11
|
+
# Set default middleware
|
12
|
+
conn.request :multipart
|
13
|
+
conn.request :url_encoded
|
14
|
+
conn.adapter Faraday.default_adapter
|
15
|
+
end
|
16
|
+
|
17
|
+
@response = connection.post(
|
18
|
+
URI(configuration[:token_url]).path,
|
19
|
+
client_id: configuration[:client_id],
|
20
|
+
client_secret: configuration[:client_secret],
|
21
|
+
grant_type: 'password',
|
22
|
+
username: id,
|
23
|
+
password: password
|
24
|
+
)
|
25
|
+
|
26
|
+
raise InvalidAuthError, body['errors'].to_s unless success?
|
27
|
+
end
|
28
|
+
|
29
|
+
def body
|
30
|
+
@body ||= JSON.parse(@response.body).freeze
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_client
|
34
|
+
PixivApi::Client.new(
|
35
|
+
access_token: body['access_token'],
|
36
|
+
refresh_token: body['refresh_token'],
|
37
|
+
expires_at: Time.now.to_i + body['expires_in']
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def success?
|
42
|
+
@response.success?
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def configuration
|
48
|
+
PixivApi.configuration.tap(&:require_keys!)
|
49
|
+
end
|
50
|
+
|
51
|
+
def default_options
|
52
|
+
{
|
53
|
+
headers: {
|
54
|
+
'Host' => URI(configuration[:token_url]).host,
|
55
|
+
},
|
56
|
+
url: configuration[:site],
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'oauth2'
|
3
|
+
|
4
|
+
module PixivApi
|
5
|
+
class Client
|
6
|
+
class UnsupportedApiError < NotImplementedError; end
|
7
|
+
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
include Request::FavoriteUsers
|
11
|
+
include Request::Friends
|
12
|
+
include Request::Novels
|
13
|
+
include Request::Profiles
|
14
|
+
include Request::Promotions
|
15
|
+
include Request::Ranking
|
16
|
+
include Request::Search
|
17
|
+
include Request::Trends
|
18
|
+
include Request::Users
|
19
|
+
include Request::Util
|
20
|
+
include Request::Version
|
21
|
+
include Request::Works
|
22
|
+
include Request::UploadWork
|
23
|
+
include Request::Signup
|
24
|
+
|
25
|
+
attr_reader :client, :access_token
|
26
|
+
|
27
|
+
def_delegators :@access_token, :get, :post, :put, :patch, :delete
|
28
|
+
|
29
|
+
# For development
|
30
|
+
def self.from_account(id:, password:)
|
31
|
+
PixivApi::Authentication.new(id: id, password: password).to_client
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(access_token:, refresh_token:, expires_at:)
|
35
|
+
token_hash = {
|
36
|
+
access_token: access_token,
|
37
|
+
refresh_token: refresh_token,
|
38
|
+
expires_at: expires_at.to_i
|
39
|
+
}
|
40
|
+
|
41
|
+
@client = OAuth2::Client.new(*client_configuration) do |builder|
|
42
|
+
builder.request :multipart
|
43
|
+
builder.request :url_encoded
|
44
|
+
builder.adapter Faraday.default_adapter
|
45
|
+
end
|
46
|
+
@access_token = OAuth2::AccessToken.from_hash(client, token_hash)
|
47
|
+
end
|
48
|
+
|
49
|
+
def refresh!
|
50
|
+
@access_token = @access_token.refresh!
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def unsupported!(path)
|
56
|
+
raise PixivApi::Client::UnsupportedApiError, "route of #{path} is not supported."
|
57
|
+
end
|
58
|
+
|
59
|
+
def client_configuration
|
60
|
+
configuration = PixivApi.configuration
|
61
|
+
configuration.require_keys! # 必要な設定がなされているかチェック
|
62
|
+
|
63
|
+
[
|
64
|
+
configuration.client_id,
|
65
|
+
configuration.client_secret,
|
66
|
+
site: configuration.site,
|
67
|
+
authorize_url: configuration.authorize_url,
|
68
|
+
token_url: configuration.token_url
|
69
|
+
]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
3
|
+
module PixivApi
|
4
|
+
class Configuration < Hash
|
5
|
+
class MissingConfigurationError < StandardError; end
|
6
|
+
class InvalidKeyError < StandardError; end
|
7
|
+
|
8
|
+
REQUIRED_KEYS = %i(
|
9
|
+
client_id client_secret site authorize_url token_url
|
10
|
+
)
|
11
|
+
|
12
|
+
OPTIONAL_KEYS = %i(
|
13
|
+
cache_dir
|
14
|
+
)
|
15
|
+
|
16
|
+
(REQUIRED_KEYS + OPTIONAL_KEYS).each do |key|
|
17
|
+
define_method key do
|
18
|
+
self[key]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def cache_dir
|
23
|
+
self[:cache_dir] || Dir.mktmpdir('pixiv-api')
|
24
|
+
end
|
25
|
+
|
26
|
+
def []=(key, value)
|
27
|
+
if allowed_keys.include?(key)
|
28
|
+
super
|
29
|
+
else
|
30
|
+
raise InvalidKeyError, "#{key} is not configuration key."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def require_keys!
|
35
|
+
REQUIRED_KEYS.each do |key|
|
36
|
+
raise MissingConfigurationError, "configuration requires '#{key}'" unless self[key]
|
37
|
+
end
|
38
|
+
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def allowed_keys
|
45
|
+
REQUIRED_KEYS + OPTIONAL_KEYS
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module PixivApi
|
5
|
+
class PixivBlob
|
6
|
+
REFERER = 'https://www.pixiv.net/'
|
7
|
+
|
8
|
+
attr_accessor :url
|
9
|
+
|
10
|
+
def initialize(url)
|
11
|
+
@url = url
|
12
|
+
end
|
13
|
+
|
14
|
+
def read
|
15
|
+
open(&:read)
|
16
|
+
end
|
17
|
+
|
18
|
+
def open(&block)
|
19
|
+
File.open(filepath, &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_path
|
23
|
+
filepath
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def filepath
|
29
|
+
File.join(PixivApi.configuration.cache_dir, filename).tap do |filepath|
|
30
|
+
OpenURI.open_uri(url, 'Referer' => REFERER) do |uri|
|
31
|
+
File.open(filepath, 'wb') { |f| f.write(uri.read) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def filename
|
37
|
+
extname = File.extname(@url).downcase
|
38
|
+
"#{SecureRandom.uuid}#{extname}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module PixivApi
|
2
|
+
module Request
|
3
|
+
require 'pixiv_api/request/favorite_users'
|
4
|
+
require 'pixiv_api/request/friends'
|
5
|
+
require 'pixiv_api/request/novels'
|
6
|
+
require 'pixiv_api/request/profiles'
|
7
|
+
require 'pixiv_api/request/promotions'
|
8
|
+
require 'pixiv_api/request/ranking'
|
9
|
+
require 'pixiv_api/request/search'
|
10
|
+
require 'pixiv_api/request/signup'
|
11
|
+
require 'pixiv_api/request/trends'
|
12
|
+
require 'pixiv_api/request/upload_work'
|
13
|
+
require 'pixiv_api/request/users'
|
14
|
+
require 'pixiv_api/request/util'
|
15
|
+
require 'pixiv_api/request/version'
|
16
|
+
require 'pixiv_api/request/works'
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module PixivApi
|
2
|
+
module Request
|
3
|
+
module FavoriteUsers
|
4
|
+
def favorite_users(*args)
|
5
|
+
objects_from_response(Response::User, :get, '/v1/me/favorite-users.json', args.extract_options!)
|
6
|
+
end
|
7
|
+
|
8
|
+
def delete_favorite_users(user_ids: [], **args)
|
9
|
+
options = args.deep_merge(params: { delete_ids: user_ids.join(',') })
|
10
|
+
action_from_response(:delete, '/v1/me/favorite-users.json', options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def favorite_user(user_id:, publicity:, **args)
|
14
|
+
options = args.deep_merge(params: { target_user_id: user_id, publicity: publicity })
|
15
|
+
action_from_response(:post, '/v1/me/favorite-users.json', options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PixivApi
|
2
|
+
module Request
|
3
|
+
module Novels
|
4
|
+
def my_novels(*args)
|
5
|
+
unsupported!('/v1/me/novels.json')
|
6
|
+
end
|
7
|
+
|
8
|
+
def novels(*args)
|
9
|
+
unsupported!('/v1/novels.json')
|
10
|
+
end
|
11
|
+
|
12
|
+
def user_novels(user_id:, **args)
|
13
|
+
unsupported!('/v1/users/:user_id/novels.json')
|
14
|
+
end
|
15
|
+
|
16
|
+
def novel(id:, **args)
|
17
|
+
unsupported!('/v1/novels/:id.json')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|