pixiv_api 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +8 -0
  6. data/Guardfile +14 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +33 -0
  9. data/Rakefile +6 -0
  10. data/lib/pixiv_api.rb +22 -0
  11. data/lib/pixiv_api/array_response.rb +23 -0
  12. data/lib/pixiv_api/authentication.rb +60 -0
  13. data/lib/pixiv_api/client.rb +72 -0
  14. data/lib/pixiv_api/configuration.rb +48 -0
  15. data/lib/pixiv_api/pixiv_blob.rb +41 -0
  16. data/lib/pixiv_api/request.rb +18 -0
  17. data/lib/pixiv_api/request/favorite_users.rb +19 -0
  18. data/lib/pixiv_api/request/friends.rb +9 -0
  19. data/lib/pixiv_api/request/novels.rb +21 -0
  20. data/lib/pixiv_api/request/profiles.rb +9 -0
  21. data/lib/pixiv_api/request/promotions.rb +20 -0
  22. data/lib/pixiv_api/request/ranking.rb +9 -0
  23. data/lib/pixiv_api/request/search.rb +10 -0
  24. data/lib/pixiv_api/request/signup.rb +25 -0
  25. data/lib/pixiv_api/request/trends.rb +16 -0
  26. data/lib/pixiv_api/request/upload_work.rb +27 -0
  27. data/lib/pixiv_api/request/users.rb +13 -0
  28. data/lib/pixiv_api/request/util.rb +38 -0
  29. data/lib/pixiv_api/request/version.rb +9 -0
  30. data/lib/pixiv_api/request/works.rb +21 -0
  31. data/lib/pixiv_api/response.rb +134 -0
  32. data/lib/pixiv_api/response/action.rb +23 -0
  33. data/lib/pixiv_api/response/friend.rb +25 -0
  34. data/lib/pixiv_api/response/identity.rb +12 -0
  35. data/lib/pixiv_api/response/illustration.rb +6 -0
  36. data/lib/pixiv_api/response/manga.rb +6 -0
  37. data/lib/pixiv_api/response/novel.rb +15 -0
  38. data/lib/pixiv_api/response/pagination.rb +25 -0
  39. data/lib/pixiv_api/response/promotion.rb +11 -0
  40. data/lib/pixiv_api/response/request.rb +26 -0
  41. data/lib/pixiv_api/response/signup_validation_result.rb +7 -0
  42. data/lib/pixiv_api/response/tag.rb +9 -0
  43. data/lib/pixiv_api/response/ugoira.rb +18 -0
  44. data/lib/pixiv_api/response/upload_status.rb +7 -0
  45. data/lib/pixiv_api/response/upload_token.rb +7 -0
  46. data/lib/pixiv_api/response/user.rb +15 -0
  47. data/lib/pixiv_api/response/version.rb +7 -0
  48. data/lib/pixiv_api/response/work.rb +46 -0
  49. data/lib/pixiv_api/version.rb +3 -0
  50. data/pixiv_api.gemspec +32 -0
  51. data/spec/pixiv_api/authentication_spec.rb +57 -0
  52. data/spec/pixiv_api/client_spec.rb +28 -0
  53. data/spec/pixiv_api/configuration_spec.rb +41 -0
  54. data/spec/pixiv_api/pixiv_blob_spec.rb +23 -0
  55. data/spec/pixiv_api/request/favorite_users_spec.rb +47 -0
  56. data/spec/pixiv_api/request/friends_spec.rb +14 -0
  57. data/spec/pixiv_api/request/novels_spec.rb +37 -0
  58. data/spec/pixiv_api/request/profiles_spec.rb +13 -0
  59. data/spec/pixiv_api/request/signup_spec.rb +76 -0
  60. data/spec/pixiv_api/request/upload_work_spec.rb +41 -0
  61. data/spec/pixiv_api/request/users_spec.rb +32 -0
  62. data/spec/pixiv_api/request/works_spec.rb +16 -0
  63. data/spec/pixiv_api/version_spec.rb +7 -0
  64. data/spec/pixiv_api_spec.rb +8 -0
  65. metadata +275 -0
@@ -0,0 +1,25 @@
1
+ module PixivApi
2
+ class Response
3
+ class Pagination < Response
4
+ def self.from_response(response, *attributes)
5
+ new(response, *attributes)
6
+ end
7
+
8
+ def self.define_pagination_url(*attrs)
9
+ attrs.each do |attr|
10
+ define_method "#{attr}_url" do
11
+ if self[attr]
12
+ params = @request.params.merge('page' => self[attr])
13
+ url = @request.url
14
+ url.query = URI.encode_www_form(params)
15
+ url
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ attr_reader :previous, :next, :current, :per_page, :total, :pages
22
+ define_pagination_url :previous, :next, :current
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module PixivApi
2
+ class Response
3
+ class Promotion < Response
4
+ def self.from_response(response, attributes)
5
+ new(response, attributes)
6
+ end
7
+
8
+ attr_reader :px_user_external_site_ads_id, :user_id, :site_id, :ads
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ module PixivApi
2
+ class Response
3
+ class Request
4
+ def initialize(response)
5
+ @response = response
6
+ @env = response.response.env
7
+ end
8
+
9
+ def full_url
10
+ @env.url
11
+ end
12
+
13
+ def url
14
+ URI(full_url.to_s.gsub(/\?.*$/, ''))
15
+ end
16
+
17
+ def query
18
+ @env.url.query
19
+ end
20
+
21
+ def params
22
+ Rack::Utils.parse_query(query)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ module PixivApi
2
+ class Response
3
+ class SignupValidationResult < Response
4
+ attr_reader :is_valid, :mail_address, :pixiv_id, :user_name, :password, :password_again, :sex, :birthday
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module PixivApi
2
+ class Response
3
+ class Tag < Response
4
+ attr_reader :name, :count, :total_count
5
+
6
+ define_attributes_method :works, Response::Work
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module PixivApi
2
+ class Response
3
+ class Ugoira < Work
4
+ def frames
5
+ @attributes['metadata']['frames']
6
+ end
7
+
8
+ def zip_urls
9
+ @attributes['metadata']['zip_urls'].map do |zip_urls, memo|
10
+ zip_urls.each_with_object({}) do |(key, value), memo|
11
+ memo[key] = blob_image_url(value)
12
+ end
13
+ end
14
+ end
15
+ memoize(:zip_urls)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ module PixivApi
2
+ class Response
3
+ class UploadStatus < Response
4
+ attr_reader :status, :id, :title, :publicity, :age_limit
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module PixivApi
2
+ class Response
3
+ class UploadToken < Response
4
+ attr_reader :upload_token
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module PixivApi
2
+ class Response
3
+ class User < Identity
4
+ attr_reader :id, :account, :name, :is_following, :is_follower,
5
+ :is_friend, :is_premium, :stats, :profile, :email
6
+
7
+ define_blob_method :profile_image_urls
8
+
9
+ def avatar_url
10
+ blob_profile_image_urls['px_50x50']
11
+ end
12
+ memoize(:avatar_url)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module PixivApi
2
+ class Response
3
+ class Version < Response
4
+ attr_reader :version
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,46 @@
1
+ module PixivApi
2
+ class Response
3
+ class Work < Identity
4
+ def self.from_response(response, *args)
5
+ attributes = args.extract_options!
6
+
7
+ base = case attributes['type']
8
+ when 'illustration'
9
+ Illustration
10
+ when 'manga'
11
+ Manga
12
+ when 'ugoira'
13
+ Ugoira
14
+ else
15
+ raise NotImplementedError, 'unknown type given.'
16
+ end
17
+
18
+ base.new(response, attributes)
19
+ end
20
+
21
+ attr_reader :id, :age_limit, :caption, :favorite_id,
22
+ :height, :is_linked, :is_manga, :publicity,
23
+ :stats, :title, :tools, :width, :page_count,
24
+ :book_style, :type, :metadata
25
+
26
+ define_attribute_method :user, Response::User
27
+
28
+ define_blob_method :image_urls
29
+
30
+ define_time_method :created_time, :reuploaded_time
31
+
32
+ def pages
33
+ @attributes['metadata']['pages'].map do |base, memo|
34
+ base['image_urls'].each_with_object({}) do |(key, value), memo|
35
+ memo[key] = blob_image_url(value)
36
+ end
37
+ end
38
+ rescue
39
+ # XXX: workの種類によってはエラーが起こる?
40
+ []
41
+ end
42
+
43
+ memoize(:pages)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module PixivApi
2
+ VERSION = '0.0.4'
3
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pixiv_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'pixiv_api'
8
+ spec.version = PixivApi::VERSION
9
+ spec.authors = ['alpaca-tc']
10
+ spec.email = ['alpaca-tc@alpaca.tc']
11
+
12
+ spec.summary = %q{pixiv public api client}
13
+ spec.description = %q{pixiv public api client.}
14
+ spec.homepage = 'https://github.com/pixiv/pixiv-api-ruby'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.test_files = Dir['spec/**/*_spec.rb']
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'oauth2', '~> 1.0'
22
+ spec.add_dependency 'memoizable', '~> 0.4'
23
+ spec.add_dependency 'activesupport', '>= 4.0'
24
+ spec.add_development_dependency 'bundler', '~> 1.10'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rspec', '~> 3.3'
27
+ spec.add_development_dependency 'guard', '~> 2.13'
28
+ spec.add_development_dependency 'guard-rspec', '~> 4.6'
29
+ spec.add_development_dependency 'vcr', '~> 2.9'
30
+ spec.add_development_dependency 'webmock', '~> 1.21'
31
+ spec.add_development_dependency 'pry', '~> 0.10'
32
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PixivApi::Authentication do
4
+ stub_pixiv_api_configuration
5
+
6
+ let(:initialized) { described_class.new(id: id, password: password) }
7
+ let(:id) { 'gami' }
8
+ let(:password) { 'password' }
9
+
10
+ shared_examples_for 'a token response' do
11
+ it 'contains tokens' do
12
+ expect(authentication.body['access_token']).to_not be_nil
13
+ expect(authentication.body['refresh_token']).to_not be_nil
14
+ expect(authentication.body['expires_in']).to_not be_nil
15
+ expect(authentication.body['scope']).to_not be_nil
16
+ end
17
+ end
18
+
19
+ describe '#initialize' do
20
+ xcontext 'not stubbed request' do
21
+ subject(:authentication) do
22
+ vcr_turned_off! do
23
+ initialized
24
+ end
25
+ end
26
+ let(:password) { "Write gami's password here" } # DO NOT commit this line.
27
+
28
+ it_behaves_like 'a token response'
29
+ end
30
+
31
+ context 'stubbed request' do
32
+ subject(:authentication) do
33
+ cassette cassette_path do
34
+ initialized
35
+ end
36
+ end
37
+
38
+ context 'when fail to authenticate user' do
39
+ let(:cassette_path) { 'authentication_failure' }
40
+ it { expect { authentication }.to raise_error(described_class::InvalidAuthError) }
41
+ end
42
+
43
+ context 'when authenticated user was successfully' do
44
+ let(:cassette_path) { 'authentication_success' }
45
+ it_behaves_like 'a token response'
46
+ end
47
+ end
48
+ end
49
+
50
+ describe '#to_client' do
51
+ subject(:authentication) do
52
+ cassette('authentication_success') { initialized }.to_client
53
+ end
54
+
55
+ it { is_expected.to be_a(PixivApi::Client) }
56
+ end
57
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PixivApi::Client do
4
+ subject(:client) do
5
+ described_class.new(
6
+ access_token: access_token,
7
+ refresh_token: refresh_token,
8
+ expires_at: expires_at
9
+ )
10
+ end
11
+
12
+ let(:access_token) { 'access_token' }
13
+ let(:refresh_token) { 'refresh_token' }
14
+ let(:expires_at) { Time.now.to_i }
15
+
16
+ context 'when configuration is not completed' do
17
+ describe '#initialize' do
18
+ it 'initializes oauth access token' do
19
+ expect { client }.to raise_error(PixivApi::Configuration::MissingConfigurationError)
20
+ end
21
+ end
22
+ end
23
+
24
+ context 'when configuration is completed' do
25
+ stub_pixiv_api_configuration
26
+ it { expect { subject }.to_not raise_error }
27
+ end
28
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PixivApi::Configuration do
4
+ let(:configuration) { described_class.new }
5
+
6
+ describe '#require_keys!' do
7
+ subject do
8
+ -> { configuration.require_keys! }
9
+ end
10
+
11
+ context 'when missing required keys' do
12
+ it { is_expected.to raise_error(described_class::MissingConfigurationError) }
13
+ end
14
+
15
+ context 'when configuration contains required keys' do
16
+ before do
17
+ %i(client_id client_secret site authorize_url token_url).each do |key|
18
+ configuration[key] = true
19
+ end
20
+ end
21
+
22
+ it { is_expected.to_not raise_error }
23
+ end
24
+ end
25
+
26
+ describe '#[]' do
27
+ subject do
28
+ -> { configuration[key] = true }
29
+ end
30
+
31
+ context 'given unknown key' do
32
+ let(:key) { :unknown }
33
+ it { is_expected.to raise_error(described_class::InvalidKeyError) }
34
+ end
35
+
36
+ context 'given known key' do
37
+ let(:key) { :client_id }
38
+ it { is_expected.to_not raise_error }
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PixivApi::PixivBlob do
4
+ let(:url) { 'http://i2.pixiv.net/c/600x600/img-master/img/2015/07/26/21/49/36/51625741_p0_master1200.jpg' }
5
+ subject(:blob) { described_class.new(url) }
6
+
7
+ describe '#read' do
8
+ subject { blob.read }
9
+
10
+ it 'returns content' do
11
+ is_expected.to_not be_nil
12
+ end
13
+ end
14
+
15
+ describe '#to_path' do
16
+ subject { blob.to_path }
17
+
18
+ it 'returns content' do
19
+ is_expected.to_not be_nil
20
+ expect(File).to be_exists(subject)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PixivApi::Request::FavoriteUsers do
4
+ stub_pixiv_api_client
5
+ let(:user_id) { 341433 }
6
+
7
+ describe '#favorite_users' do
8
+ subject do
9
+ cassette 'favorite_users_success' do
10
+ client.favorite_users
11
+ end
12
+ end
13
+
14
+ it 'builds array of PixivApiResponse::User' do
15
+ is_expected.to all(be_a(PixivApi::Response::User))
16
+ end
17
+
18
+ it_behaves_like 'contained pagination'
19
+ end
20
+
21
+ describe '#delete_favorite_users' do
22
+ subject do
23
+ cassette cassettle_path do
24
+ client.delete_favorite_users(user_ids: [user_id])
25
+ end
26
+ end
27
+
28
+ context 'when deleted favorite user was successfully' do
29
+ let(:cassettle_path) { 'delete_favorite_users_success' }
30
+
31
+ it 'builds array of PixivApiResponse::Action' do
32
+ is_expected.to be_a(PixivApi::Response::Action)
33
+ expect(subject).to be_success
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#favorite_user' do
39
+ subject do
40
+ cassette 'favorite_user_success' do
41
+ client.favorite_user(user_id: user_id, publicity: 'public')
42
+ end
43
+ end
44
+
45
+ it { is_expected.to be_a(PixivApi::Response::Action) }
46
+ end
47
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe PixivApi::Request::Friends do
4
+ stub_pixiv_api_client
5
+
6
+ describe '#friends' do
7
+ subject do
8
+ cassette('users_friends_success') { client.friends }
9
+ end
10
+
11
+ it { is_expected.to all(be_a(PixivApi::Response::Friend)) }
12
+ it_behaves_like 'contained pagination'
13
+ end
14
+ end