pixiv 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Tomoki Aonuma
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # Pixiv gem
2
+
3
+ A client library for [pixiv](http://www.pixiv.net/)
4
+
5
+ ## Important Note
6
+
7
+ The pixiv Guidelines [[en][Guidelines.en], [ja][Guidelines.ja]] prohibit to
8
+ crawl the pixiv service. Do not abuse this library or you may be banned!
9
+
10
+ [Guidelines.en]: http://www.pixiv.net/guideline.php?lang=en
11
+ [Guidelines.ja]: http://www.pixiv.net/guideline.php?lang=ja
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'pixiv', github: 'uasi/pixiv'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ ## Usage
24
+
25
+ See [a sample script](https://gist.github.com/4362297)
26
+
27
+ ## Documentation
28
+
29
+ [Documentation for uasi/pixiv on rubydoc.info](http://rubydoc.info/github/uasi/pixiv/master/frames)
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/pixiv.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'mechanize'
2
+ require 'pixiv/error'
3
+ require 'pixiv/client'
4
+ require 'pixiv/page'
5
+ require 'pixiv/illust'
6
+ require 'pixiv/member'
7
+ require 'pixiv/page_collection'
8
+ require 'pixiv/bookmark_list'
9
+
10
+ module Pixiv
11
+ ROOT_URL = 'http://www.pixiv.net'
12
+
13
+ # Delegates to {Pixiv::Client#initialize}
14
+ def self.new(*args, &block)
15
+ Pixiv::Client.new(*args, &block)
16
+ end
17
+ end
@@ -0,0 +1,60 @@
1
+ module Pixiv
2
+ class BookmarkList < Page
3
+ include PageCollection
4
+
5
+ # Returns the URL for given +member_id+ and +page_num+
6
+ # @param [Integer] member_id
7
+ # @param [Integer] page_num
8
+ # @return [String]
9
+ def self.url(member_id, page_num = 1)
10
+ "#{ROOT_URL}/bookmark.php?id=#{member_id}&rest=show&p=#{page_num}"
11
+ end
12
+
13
+ # @return [Integer]
14
+ lazy_attr_reader(:page_num) { at!('li.pages-current').inner_text.to_i }
15
+ # @return [Boolean]
16
+ lazy_attr_reader(:last?) { at!('li.pages-current').next_element.inner_text.to_i == 0 }
17
+ # @return [Integer]
18
+ lazy_attr_reader(:member_id) { doc.body.match(/pixiv\.context\.userId = '(\d+)'/).to_a[1].to_i }
19
+ # @return [Array<Integer>]
20
+ lazy_attr_reader(:illust_ids) { search!('li[id^="li_"] a[href^="member_illust.php?mode=medium"]').map {|n| n.attr('href').match(/illust_id=(\d+)$/).to_a[1].to_i } }
21
+ # @return [Array<Hash{Symbol=>Object}>]
22
+ lazy_attr_reader(:illust_hashes) {
23
+ search!('li[id^="li_"]').map {|node| illust_hash_from_bookmark_item(node) }.compact
24
+ }
25
+
26
+ alias page_hashes illust_hashes
27
+
28
+ # @return [String]
29
+ def url; self.class.url(member_id, page_num) end
30
+ # @return [Boolean]
31
+ def first?; page_num == 1 end
32
+ # @return [String]
33
+ def next_url; last? ? nil : self.class.url(member_id, page_num + 1) end
34
+ # @return [String]
35
+ def prev_url; first? ? nil : self.class.url(member_id, page_num - 1) end
36
+ # @return [Class<Pixiv::Page>]
37
+ def page_class; Illust end
38
+ # @return [Array<String>]
39
+ def page_urls; illust_ids.map {|illust_id| Illust.url(illust_id) } end
40
+
41
+ private
42
+
43
+ # @param [Nokogiri::HTML::Node] node
44
+ # @return [Hash{Symbol=>Object}] illust_hash
45
+ def illust_hash_from_bookmark_item(node)
46
+ return nil if node.at('img[src*="limit_unknown_s.png"]')
47
+ member_node = node.at('a[href^="member_illust.php?id="]')
48
+ illust_node = node.at('a')
49
+ illust_id = illust_node['href'].match(/illust_id=(\d+)/).to_a[1].to_i
50
+ {
51
+ url: Illust.url(illust_id),
52
+ illust_id: illust_id,
53
+ title: illust_node.inner_text,
54
+ member_id: member_node['href'].match(/\?id=(\d+)/).to_a[1].to_i,
55
+ member_name: member_node.inner_text,
56
+ small_image_url: illust_node.at('img').attr('src'),
57
+ }
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,157 @@
1
+ module Pixiv
2
+ class Client
3
+ # A new agent
4
+ # @return [Mechanize::HTTP::Agent]
5
+ def self.new_agent
6
+ agent = Mechanize.new
7
+ agent.pluggable_parser['image/gif'] = Mechanize::Download
8
+ agent.pluggable_parser['image/jpeg'] = Mechanize::Download
9
+ agent.pluggable_parser['image/png'] = Mechanize::Download
10
+ agent
11
+ end
12
+
13
+ # @return [Mechanize::HTTP::Agent]
14
+ attr_reader :agent
15
+ # @return [Integer]
16
+ attr_reader :member_id
17
+
18
+ # A new instance of Client, logged in with the given credentials
19
+ # @overload initialize(pixiv_id, password)
20
+ # @param [String] pixiv_id
21
+ # @param [String] password
22
+ # @yield [agent] (optional) gives a chance to customize the +agent+ before logging in
23
+ # @overload initialize(agent)
24
+ # @param [Mechanize::HTTP::Agent] agent
25
+ # @return [Pixiv::Client]
26
+ def initialize(*args)
27
+ if args.size < 2
28
+ @agent = args.first || self.class.new_agent
29
+ yield @agent if block_given?
30
+ ensure_logged_in
31
+ else
32
+ pixiv_id, password = *args
33
+ @agent = self.class.new_agent
34
+ yield @agent if block_given?
35
+ login(pixiv_id, password)
36
+ end
37
+ end
38
+
39
+ # Log in to Pixiv
40
+ # @param [String] pixiv_id
41
+ # @param [String] password
42
+ def login(pixiv_id, password)
43
+ form = agent.get("#{ROOT_URL}/index.php").forms_with(:class => 'login-form').first
44
+ raise Error::LoginFailed, 'login form is not available' unless form
45
+ form.pixiv_id = pixiv_id
46
+ form.pass = password
47
+ doc = agent.submit(form)
48
+ raise Error::LoginFailed unless doc.body =~ /logout/
49
+ @member_id = member_id_from_mypage(doc)
50
+ end
51
+
52
+ # @param [Integer] illust_id
53
+ # @return [Pixiv::Illust]
54
+ def illust(illust_id)
55
+ attrs = {illust_id: illust_id}
56
+ Illust.lazy_new(attrs) { agent.get(Illust.url(illust_id)) }
57
+ end
58
+
59
+ # @param [Integer] member_id
60
+ # @return [Pixiv::Member]
61
+ def member(member_id = member_id)
62
+ attrs = {member_id: member_id}
63
+ Member.lazy_new(attrs) { agent.get(Member.url(member_id)) }
64
+ end
65
+
66
+ # @param [Pixiv::Member, Integer] member_or_member_id
67
+ # @param [Integer] page_num
68
+ def bookmark_list(member_or_member_id = member_id, page_num = 1)
69
+ x = member_or_member_id
70
+ member_id = x.is_a?(Member) ? x.member_id : x
71
+ attrs = {member_id: member_id, page_num: page_num}
72
+ BookmarkList.lazy_new(attrs) { agent.get(BookmarkList.url(member_id, page_num)) }
73
+ end
74
+
75
+ # @param [Pixiv::Member, Integer] member_or_member_id
76
+ # @param [Integer] page_num
77
+ def bookmarks(member_or_member_id = member_id, page_num = 1)
78
+ list = bookmark_list(member_or_member_id, page_num)
79
+ PageCollection::Enumerator.new(self, list)
80
+ end
81
+
82
+ # Downloads the image to +io_or_filename+
83
+ # @param [Pixiv::Illust] illust
84
+ # @param [#write, String, Array<String, Symbol, #call>] io_or_filename io or filename or pattern (see {#filename_from_pattern})
85
+ # @param [Symbol] size image size (+:small+, +:medium+, or +:original+)
86
+ def download_illust(illust, io_or_filename, size = :original)
87
+ size = {:s => :small, :m => :medium, :o => :original}[size] || size
88
+ url = illust.__send__("#{size}_image_url")
89
+ referer = case size
90
+ when :small then nil
91
+ when :medium then illust.url
92
+ when :original then illust.original_image_referer
93
+ else raise ArgumentError, "unknown size `#{size}`"
94
+ end
95
+ save_to = io_or_filename
96
+ if save_to.is_a?(Array)
97
+ save_to = filename_from_pattern(save_to, illust, url)
98
+ end
99
+ FileUtils.mkdir_p(File.dirname(save_to)) unless save_to.respond_to?(:write)
100
+ @agent.download(url, save_to, [], referer)
101
+ end
102
+
103
+ # Downloads the images to +pattern+
104
+ # @param [Pixiv::Illust] illust the manga to download
105
+ # @param [Array<String, Symbol, #call>] pattern pattern (see {#filename_from_pattern})
106
+ # @note +illust#manga?+ must be +true+
107
+ def download_manga(illust, pattern)
108
+ illust.original_image_urls.each do |url|
109
+ filename = filename_from_pattern(pattern, illust, url)
110
+ FileUtils.mkdir_p(File.dirname(filename))
111
+ @agent.download(url, filename, [], illust.original_image_referer)
112
+ end
113
+ end
114
+
115
+ protected
116
+
117
+ def ensure_logged_in
118
+ doc = agent.get("#{ROOT_URL}/mypage.php")
119
+ raise Error::LoginFailed unless doc.body =~ /logout/
120
+ @member_id = member_id_from_mypage(doc)
121
+ end
122
+
123
+ def member_id_from_mypage(doc)
124
+ doc.at('.profile_area a').attr('href').match(/(\d+)$/).to_a[1].to_i
125
+ end
126
+
127
+ # Generate filename from +pattern+ in context of +illust+ and +url+
128
+ #
129
+ # @param [Array<String, Symbol, #call>] pattern
130
+ # @param [Pixiv::Illust] illust
131
+ # @param [String] url
132
+ # @return [String] filename
133
+ #
134
+ # The +pattern+ is an array of string, symbol, or object that responds to +#call+.
135
+ # Each component of the +pattern+ is replaced by the following rules and then
136
+ # the +pattern+ is concatenated as the returning +filename+.
137
+ #
138
+ # * +:image_name+ in the +pattern+ is replaced with the base name of the +url+
139
+ # * Any other symbol is replaced with the value of +illust.__send__(the_symbol)+
140
+ # * +#call+-able object is replaced with the value of +the_object.call(illust)+
141
+ # * String is left as-is
142
+ def filename_from_pattern(pattern, illust, url)
143
+ pattern.map {|i|
144
+ if i == :image_name
145
+ name = File.basename(url)
146
+ if name =~ /\.(\w+)\?\d+$/
147
+ name += '.' + $1
148
+ end
149
+ name
150
+ elsif i.is_a?(Symbol) then illust.__send__(i)
151
+ elsif i.respond_to?(:call) then i.call(illust)
152
+ else i
153
+ end
154
+ }.join('')
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,6 @@
1
+ module Pixiv
2
+ class Error < StandardError; end
3
+ class Error::LoginFailed < Error; end
4
+ class Error::NodeNotFound < Error; end
5
+ end
6
+
@@ -0,0 +1,57 @@
1
+ module Pixiv
2
+ class Illust < Page
3
+ # Returns the URL for given +illust_id+
4
+ # @param [Integer] illust_id
5
+ # @return [String]
6
+ def self.url(illust_id)
7
+ "#{ROOT_URL}/member_illust.php?mode=medium&illust_id=#{illust_id}"
8
+ end
9
+
10
+ # @return [String]
11
+ lazy_attr_reader(:small_image_url) { at!('meta[property="og:image"]').attr('content') }
12
+ # @return [String]
13
+ lazy_attr_reader(:medium_image_url) { image_url_components.join('_m') }
14
+ # @return [String]
15
+ lazy_attr_reader(:original_image_url) { illust? && image_url_components.join('') }
16
+ # @return [Array<String>]
17
+ lazy_attr_reader(:original_image_urls) {
18
+ illust? ? [original_image_url]
19
+ : (0...num_pages).map {|n| image_url_components.join("_p#{n}") }
20
+ }
21
+ # @return [String]
22
+ lazy_attr_reader(:original_image_referer) { ROOT_URL + '/' + at!('//div[@class="works_display"]/a').attr('href') }
23
+ # @return [Integer]
24
+ lazy_attr_reader(:illust_id) { at!('#rpc_i_id').attr('title').to_i }
25
+ # @return [Integer]
26
+ lazy_attr_reader(:member_id) { at!('#rpc_u_id').attr('title').to_i }
27
+ # @return [String]
28
+ lazy_attr_reader(:member_name) { raise NotImplementError.new('XXX') }
29
+ # @return [String]
30
+ lazy_attr_reader(:title) { raise NotImplementError.new('XXX') }
31
+ # @return [Integer]
32
+ lazy_attr_reader(:num_pages) {
33
+ n = at!('//ul[@class="meta"]/li[2]').inner_text.match(/(\d+)P$/).to_a[1]
34
+ n && n.to_i
35
+ }
36
+
37
+ alias id illust_id
38
+ alias original_image_referrer original_image_referer # referrer vs. referer
39
+
40
+ # @return [String]
41
+ def url; self.class.url(illust_id) end
42
+ # @return [Boolean]
43
+ def illust?; !manga? end
44
+ # @return [Boolean]
45
+ def manga?; !!num_pages end
46
+ # @return [String]
47
+ def medium_image_url; image_url_components.join('_m') end
48
+ # @return [String]
49
+ def original_image_url; image_url_components.join('') end
50
+
51
+ private
52
+
53
+ def image_url_components
54
+ @image_url_components ||= small_image_url.match(%r{^(.+)_s(\.\w+(?:\?\d+)?)$}).to_a[1, 3]
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,22 @@
1
+ module Pixiv
2
+ class Member < Page
3
+ # Returns the URL for given +member_id+
4
+ # @param [Integer] member_id
5
+ # @return [String]
6
+ def self.url(member_id)
7
+ "#{ROOT_URL}/member.php?id=#{member_id}"
8
+ end
9
+
10
+ # @return [String]
11
+ lazy_attr_reader(:name) { at!('.profile_area h2').inner_text }
12
+ # @return [Integer]
13
+ lazy_attr_reader(:member_id) { at!('input[name="user_id"]').attr('value').to_i }
14
+ # return [Integer]
15
+ lazy_attr_reader(:pixiv_id) { at!('.profile_area img').attr('src').match(%r{/profile/([a-z_-]+)/}).to_a[1] }
16
+
17
+ alias id member_id
18
+
19
+ # @return [String]
20
+ def url; self.class.url(member_id) end
21
+ end
22
+ end
data/lib/pixiv/page.rb ADDED
@@ -0,0 +1,91 @@
1
+ module Pixiv
2
+ class Page
3
+ # A new Page
4
+ # @param [Hash{Symbol=>Object}] attrs
5
+ # @yieldreturn [Nokogiri::HTML::Document]
6
+ def self.lazy_new(attrs = {}, &doc_creator)
7
+ self.new(doc_creator, attrs)
8
+ end
9
+
10
+ # @overload initialize(doc, attrs = {})
11
+ # @param [Nokogiri::HTTP::Document] doc
12
+ # @param [Hash{Symbol=>Object}] attrs
13
+ # @overload initialize(doc_creator, attrs = {})
14
+ # @param [#call] doc_creator
15
+ # @param [Hash{Symbol=>Object}] attrs
16
+ def initialize(doc_or_doc_creator, attrs = {})
17
+ x = doc_or_doc_creator
18
+ if x.respond_to?(:call)
19
+ @doc_creator = x
20
+ else
21
+ @doc = x
22
+ end
23
+ set_attrs!(attrs)
24
+ end
25
+
26
+ # @return [Nokogiri::HTTP::Document]
27
+ def doc
28
+ @doc ||= begin
29
+ doc = @doc_creator.call
30
+ @doc_creator = nil
31
+ doc
32
+ end
33
+ end
34
+
35
+ # Fetch +#doc+ and lazy attrs
36
+ # @return [self]
37
+ def force
38
+ doc
39
+ (@@lazy_attr_readers || []).each do |reader|
40
+ __send__(reader) if respond_to?(reader)
41
+ end
42
+ self
43
+ end
44
+
45
+ protected
46
+
47
+ # Defines lazy attribute reader
48
+ # @!macro attach lazy_attr_reader
49
+ # @!attribute [r] $1
50
+ # Lazily returns $1
51
+ def self.lazy_attr_reader(name, &reader)
52
+ ivar = :"@#{name.to_s.sub(/\?$/, '_q_')}"
53
+ (@@lazy_attr_readers ||= []) << ivar
54
+ define_method(name) do
55
+ if instance_variable_defined?(ivar)
56
+ instance_variable_get(ivar)
57
+ else
58
+ instance_variable_set(ivar, instance_eval(&reader))
59
+ end
60
+ end
61
+ end
62
+
63
+ # Set attribute values
64
+ #
65
+ # @param [Hash{Symbol=>Object}] attrs
66
+ #
67
+ # If +#set_attr!+ sets a value to an attribute,
68
+ # the lazy attr of the same name gets to return that value
69
+ # so its block will never called.
70
+ def set_attrs!(attrs)
71
+ attrs.each do |name, value|
72
+ ivar = :"@#{name.to_s.sub(/\?$/, '_q_')}"
73
+ instance_variable_set(ivar, value)
74
+ end
75
+ end
76
+
77
+ # +node.at(path)+ or raise error
78
+ # @param [String] path XPath or CSS path
79
+ # @return [Nokogiri::HTML::Node]
80
+ def at!(path, node = doc)
81
+ node.at(path) || Error::NodeNotFound.new("node for `#{path}` not found").raise
82
+ end
83
+
84
+ # +node.search(path) or raise error
85
+ # @param [String] path XPath or CSS path
86
+ # @return [Array<Nokogiri::HTML::Node>]
87
+ def search!(path, node = doc)
88
+ node.search(path) || Error::NodeNotFound.new("node for `#{path}` not found").raise
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,81 @@
1
+ module Pixiv
2
+ module PageCollection
3
+ def first?
4
+ raise NotImplementError
5
+ end
6
+
7
+ def last?
8
+ raise NotImplementError
9
+ end
10
+
11
+ def next_url
12
+ raise NotImplementError
13
+ end
14
+
15
+ def prev_url
16
+ raise NotImplementError
17
+ end
18
+
19
+ def page_class
20
+ raise NotImplementError
21
+ end
22
+
23
+ def page_urls
24
+ raise NotImplementError
25
+ end
26
+
27
+ def page_hash
28
+ page_urls.map {|url| {url: url} }
29
+ end
30
+ end
31
+
32
+ class PageCollection::Enumerator
33
+ include Enumerable
34
+
35
+ def initialize(client, collection)
36
+ @client = client
37
+ @collection = collection
38
+ end
39
+
40
+ def each_page
41
+ each_collection do |collection|
42
+ pages_from_collection(collection).each do |page|
43
+ yield page
44
+ end
45
+ end
46
+ end
47
+
48
+ alias each each_page
49
+
50
+ def each_slice(n = nil)
51
+ if n
52
+ super
53
+ else
54
+ if block_given?
55
+ each_collection do |collection|
56
+ yield pages_from_collection(collection)
57
+ end
58
+ else
59
+ ::Enumerator.new {|y| each_slice {|slice| y << slice } }
60
+ end
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def pages_from_collection(collection)
67
+ collection.page_hashes.map {|attrs|
68
+ url = attrs.delete(:url)
69
+ collection.page_class.lazy_new(attrs) { @client.agent.get(url) }
70
+ }
71
+ end
72
+
73
+ def each_collection(collection = @collection)
74
+ loop do
75
+ yield collection
76
+ break unless collection.next_url
77
+ collection = collection.class.new(@client.agent.get(collection.next_url))
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,3 @@
1
+ module Pixiv
2
+ VERSION = "0.0.1"
3
+ end
data/pixiv.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pixiv/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "pixiv"
8
+ gem.version = Pixiv::VERSION
9
+ gem.authors = ["Tomoki Aonuma"]
10
+ gem.email = ["uasi@uasi.jp"]
11
+ gem.description = %q{A client library for Pixiv}
12
+ gem.summary = %q{A client library for Pixiv}
13
+ gem.homepage = "https://github.com/uasi/pixiv"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'mechanize', '~> 2.0'
21
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pixiv
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tomoki Aonuma
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mechanize
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ description: A client library for Pixiv
31
+ email:
32
+ - uasi@uasi.jp
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - LICENSE.txt
40
+ - README.md
41
+ - Rakefile
42
+ - lib/pixiv.rb
43
+ - lib/pixiv/bookmark_list.rb
44
+ - lib/pixiv/client.rb
45
+ - lib/pixiv/error.rb
46
+ - lib/pixiv/illust.rb
47
+ - lib/pixiv/member.rb
48
+ - lib/pixiv/page.rb
49
+ - lib/pixiv/page_collection.rb
50
+ - lib/pixiv/version.rb
51
+ - pixiv.gemspec
52
+ homepage: https://github.com/uasi/pixiv
53
+ licenses: []
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 1.8.24
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: A client library for Pixiv
76
+ test_files: []
77
+ has_rdoc: