pixiv 0.0.3 → 0.0.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.
data/README.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  A client library for [pixiv](http://www.pixiv.net/)
4
4
 
5
+ [![Build Status](https://secure.travis-ci.org/uasi/pixiv.png?branch=master)][travis]
6
+ [![Dependency Status](https://gemnasium.com/uasi/pixiv.png?travis)][gemnasium]
7
+ [![Code Climate](https://codeclimate.com/badge.png)][codeclimate]
8
+
9
+ [travis]: http://travis-ci.org/uasi/pixiv
10
+ [gemnasium]: https://gemnasium.com/uasi/pixiv
11
+ [codeclimate]: https://codeclimate.com/github/uasi/pixiv
12
+
5
13
  ## Important Note
6
14
 
7
15
  The pixiv Guidelines [[en][Guidelines.en], [ja][Guidelines.ja]] prohibit to
@@ -16,23 +16,45 @@ def init
16
16
  require 'bundler/setup'
17
17
  Bundler.require
18
18
 
19
- $pixiv = Pixiv.new(id, password) do |agent|
19
+ $pixiv = Pixiv.client(id, password) do |agent|
20
20
  agent.user_agent_alias = 'Mac Safari'
21
21
  agent.set_proxy(*proxy) if proxy
22
22
  end
23
23
 
24
24
  Kernel.const_set(:P, $pixiv)
25
25
  Kernel.const_set(:M, $pixiv.member)
26
+ Kernel.const_set(:WL, $pixiv.work_list)
27
+ Kernel.const_set(:BL, $pixiv.bookmark_list)
28
+ Kernel.const_set(:PBL, $pixiv.private_bookmark_list)
29
+ Kernel.const_set(:Ws, $pixiv.works)
30
+ Kernel.const_set(:Bs, $pixiv.bookmarks)
31
+ Kernel.const_set(:PBs, $pixiv.private_bookmarks)
32
+ end
33
+
34
+ def M(id)
35
+ $pixiv.member(id)
26
36
  end
27
37
 
28
38
  def I(id)
29
39
  $pixiv.illust(id)
30
40
  end
31
41
 
32
- def M(id)
33
- $pixiv.member(id)
42
+ def WL(member, p = 1)
43
+ $pixiv.work_list(member, p)
44
+ end
45
+
46
+ def BL(member, p = 1)
47
+ $pixiv.bookmark_list(member, p)
48
+ end
49
+
50
+ def PBL(p = 1)
51
+ $pixiv.private_bookmark_list(p)
52
+ end
53
+
54
+ def Ws(member)
55
+ $pixiv.works(member)
34
56
  end
35
57
 
36
- def BL(member_id, p = 1)
37
- $pixiv.bookmark_list(member_id, p)
58
+ def Bs(member)
59
+ $pixiv.bookmarks(member)
38
60
  end
@@ -1,17 +1,29 @@
1
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
2
 
10
3
  module Pixiv
4
+ autoload :BookmarkList, 'pixiv/bookmark_list'
5
+ autoload :Client, 'pixiv/client'
6
+ autoload :Error, 'pixiv/error'
7
+ autoload :Illust, 'pixiv/illust'
8
+ autoload :IllustList, 'pixiv/illust_list'
9
+ autoload :Member, 'pixiv/member'
10
+ autoload :OwnedIllustList, 'pixiv/owned_illust_list'
11
+ autoload :Page, 'pixiv/page'
12
+ autoload :PageCollection, 'pixiv/page_collection'
13
+ autoload :PrivateBookmarkList, 'pixiv/bookmark_list'
14
+ autoload :WorkList, 'pixiv/work_list'
15
+
11
16
  ROOT_URL = 'http://www.pixiv.net'
12
17
 
18
+ # @deprecated Use {.client} instead. Will be removed in 0.1.0.
13
19
  # Delegates to {Pixiv::Client#initialize}
14
20
  def self.new(*args, &block)
15
21
  Pixiv::Client.new(*args, &block)
16
22
  end
23
+
24
+ # See {Pixiv::Client#initialize}
25
+ # @return [Pixiv::Client]
26
+ def self.client(*args, &block)
27
+ Pixiv::Client.new(*args, &block)
28
+ end
17
29
  end
@@ -1,50 +1,28 @@
1
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}"
2
+ class BookmarkList < OwnedIllustList
3
+ # (see super.url)
4
+ def self.url(member_id, page = 1)
5
+ "#{ROOT_URL}/bookmark.php?id=#{member_id}&rest=show&p=#{page}"
11
6
  end
12
7
 
13
8
  # @return [Integer]
14
- lazy_attr_reader(:bookmarks_count) { at!('a[href="/bookmark.php?type=illust_all"]').inner_text.match(/(\d+)/).to_a[1].to_i }
15
- # @return [Integer]
16
- lazy_attr_reader(:page_num) { at!('li.pages-current').inner_text.to_i }
17
- # @return [Boolean]
18
- lazy_attr_reader(:last?) { at!('li.pages-current').next_element.inner_text.to_i == 0 }
19
- # @return [Integer]
20
- lazy_attr_reader(:member_id) { doc.body.match(/pixiv\.context\.userId = '(\d+)'/).to_a[1].to_i }
21
- # @return [Array<Integer>]
22
- lazy_attr_reader(:illust_ids) { search!('li[id^="li_"] a[href^="member_illust.php?mode=medium"]').map {|n| n['href'].match(/illust_id=(\d+)$/).to_a[1].to_i } }
9
+ lazy_attr_reader(:total_count) {
10
+ node = at!('a[href="/bookmark.php?type=illust_all"]')
11
+ node.inner_text.match(/\d+/).to_s.to_i
12
+ }
23
13
  # @return [Array<Hash{Symbol=>Object}, nil>]
24
- lazy_attr_reader(:illust_hashes) {
25
- search!('li[id^="li_"]').map {|node| illust_hash_from_bookmark_item(node) }
14
+ lazy_attr_reader(:page_hashes) {
15
+ search!('li[id^="li_"]').map {|n| hash_from_list_item(n) }
26
16
  }
27
17
 
28
- alias page_hashes illust_hashes
29
-
30
- # @return [String]
31
- def url; self.class.url(member_id, page_num) end
32
- # @return [Boolean]
33
- def first?; page_num == 1 end
34
- # @return [String]
35
- def next_url; last? ? nil : self.class.url(member_id, page_num + 1) end
36
- # @return [String]
37
- def prev_url; first? ? nil : self.class.url(member_id, page_num - 1) end
38
- # @return [Class<Pixiv::Page>]
39
- def page_class; Illust end
40
- # @return [Array<String>]
41
- def page_urls; illust_ids.map {|illust_id| Illust.url(illust_id) } end
18
+ # @deprecated Use {#total_count} instead.
19
+ alias bookmarks_count total_count
42
20
 
43
21
  private
44
22
 
45
- # @param [Nokogiri::HTML::Node] node
23
+ # @param [Nokogiri::XML::Node] node
46
24
  # @return [Hash{Symbol=>Object}] illust_hash
47
- def illust_hash_from_bookmark_item(node)
25
+ def hash_from_list_item(node)
48
26
  return nil if node.at('img[src*="limit_unknown_s.png"]')
49
27
  member_node = node.at('a[href^="member_illust.php?id="]')
50
28
  illust_node = node.at('a')
@@ -59,4 +37,11 @@ module Pixiv
59
37
  }
60
38
  end
61
39
  end
40
+
41
+ class PrivateBookmarkList < BookmarkList
42
+ # (see super.url)
43
+ def self.url(member_id, page = 1)
44
+ "#{ROOT_URL}/bookmark.php?id=#{member_id}&rest=hide&p=#{page}"
45
+ end
46
+ end
62
47
  end
@@ -52,6 +52,14 @@ module Pixiv
52
52
  @member_id = member_id_from_mypage(doc)
53
53
  end
54
54
 
55
+ # @param [Integer] member_id
56
+ # @return [Pixiv::Member] member bound to +self+
57
+ def member(member_id = member_id)
58
+ attrs = {member_id: member_id}
59
+ member = Member.lazy_new(attrs) { agent.get(Member.url(member_id)) }
60
+ member.bind(self)
61
+ end
62
+
55
63
  # @param [Integer] illust_id
56
64
  # @return [Pixiv::Illust] illust bound to +self+
57
65
  def illust(illust_id)
@@ -60,37 +68,60 @@ module Pixiv
60
68
  illust.bind(self)
61
69
  end
62
70
 
63
- # @param [Integer] member_id
64
- # @return [Pixiv::Member] member bound to +self+
65
- def member(member_id = member_id)
66
- attrs = {member_id: member_id}
67
- member = Member.lazy_new(attrs) { agent.get(Member.url(member_id)) }
68
- member.bind(self)
71
+ # @param [Pixiv::Member, Integer] member_or_id
72
+ # @param [Integer] page
73
+ # @return [Pixiv::WorkList] work list bound to +self+
74
+ def work_list(member_or_id = member_id, page = 1)
75
+ illust_list_with_class(WorkList, member_or_id, page)
76
+ end
77
+
78
+ # @param [Pixiv::Member, Integer] member_or_id
79
+ # @param [Integer] page
80
+ # @return [Pixiv::BookmarkList] bookmark list bound to +self+
81
+ def bookmark_list(member_or_id = member_id, page = 1)
82
+ illust_list_with_class(BookmarkList, member_or_id, page)
69
83
  end
70
84
 
71
- # @param [Pixiv::Member, Integer] member_or_member_id
85
+ # @param [Pixiv::Member, Integer] member_or_id
72
86
  # @param [Integer] page_num
73
- def bookmark_list(member_or_member_id = member_id, page_num = 1)
74
- x = member_or_member_id
75
- member_id = x.is_a?(Member) ? x.member_id : x
76
- attrs = {member_id: member_id, page_num: page_num}
77
- BookmarkList.lazy_new(attrs) { agent.get(BookmarkList.url(member_id, page_num)) }
78
- end
79
-
80
- # @param [Pixiv::BookmarkList, Pixiv::Member, Integer] list_or_member
81
- # @param [Hash] opts
82
- # @option opts [Boolean] :include_deleted (false)
83
- # whether the returning enumerator yields deleted illust as +nil+ or not
84
- # @return [Pixiv::PageCollection::Enumerator]
85
- def bookmarks(list_or_member, opts = {})
86
- list = list_or_member.is_a?(BookmarkList) ? list_or_member
87
- : bookmark_list(list_or_member)
87
+ # @return [Pixiv::PrivateBookmarkList] private bookmark list bound to +self+
88
+ def private_bookmark_list(member_or_id = member_id, page = 1)
89
+ illust_list_with_class(PrivateBookmarkList, member_or_id, page)
90
+ end
91
+
92
+ # @param [Pixiv::IllustList] list
93
+ # @!macro [new] opts_and_return
94
+ # @param [Hash] opts
95
+ # @option opts [Boolean] :include_deleted (false)
96
+ # whether the returning enumerator yields deleted illust as +nil+ or not
97
+ # @return [Pixiv::PageCollection::Enumerator]
98
+ def illusts(list, opts = {})
88
99
  PageCollection::Enumerator.new(self, list, !!opts[:include_deleted])
89
100
  end
90
101
 
102
+ # @param [Pixiv::Member, Integer] member_or_id
103
+ # @param [Integer] page
104
+ # @!macro opts_and_return
105
+ def works(member_or_id = member_id, page = 1, opts = {})
106
+ illusts(work_list(member_or_id, page), opts)
107
+ end
108
+
109
+ # @param [Pixiv::Member, Integer] member_or_id
110
+ # @param [Integer] page
111
+ # @!macro opts_and_return
112
+ def bookmarks(member_or_id = member_id, page = 1, opts = {})
113
+ illusts(bookmark_list(member_or_id, page), opts)
114
+ end
115
+
116
+ # @param [Integer] page
117
+ # @!macro opts_and_return
118
+ def private_bookmarks(page = 1, opts = {})
119
+ illusts(private_bookmark_list(member_id, page), opts)
120
+ end
121
+
91
122
  # Downloads the image to +io_or_filename+
92
123
  # @param [Pixiv::Illust] illust
93
- # @param [#write, String, Array<String, Symbol, #call>] io_or_filename io or filename or pattern (see {#filename_from_pattern})
124
+ # @param [#write, String, Array<String, Symbol, #call>] io_or_filename io or filename or pattern for {#filename_from_pattern}
94
125
  # @param [Symbol] size image size (+:small+, +:medium+, or +:original+)
95
126
  def download_illust(illust, io_or_filename, size = :original)
96
127
  size = {:s => :small, :m => :medium, :o => :original}[size] || size
@@ -111,7 +142,7 @@ module Pixiv
111
142
 
112
143
  # Downloads the images to +pattern+
113
144
  # @param [Pixiv::Illust] illust the manga to download
114
- # @param [Array<String, Symbol, #call>] pattern pattern (see {#filename_from_pattern})
145
+ # @param [Array<String, Symbol, #call>] pattern pattern for {#filename_from_pattern}
115
146
  # @note +illust#manga?+ must be +true+
116
147
  # @todo Document +&block+
117
148
  def download_manga(illust, pattern, &block)
@@ -129,20 +160,9 @@ module Pixiv
129
160
  end
130
161
  end
131
162
 
132
- protected
133
-
134
- def ensure_logged_in
135
- doc = agent.get("#{ROOT_URL}/mypage.php")
136
- raise Error::LoginFailed unless doc.body =~ /logout/
137
- @member_id = member_id_from_mypage(doc)
138
- end
139
-
140
- def member_id_from_mypage(doc)
141
- doc.at('.profile_area a')['href'].match(/(\d+)$/).to_a[1].to_i
142
- end
143
-
144
163
  # Generate filename from +pattern+ in context of +illust+ and +url+
145
164
  #
165
+ # @api private
146
166
  # @param [Array<String, Symbol, #call>] pattern
147
167
  # @param [Pixiv::Illust] illust
148
168
  # @param [String] url
@@ -153,7 +173,7 @@ module Pixiv
153
173
  # the +pattern+ is concatenated as the returning +filename+.
154
174
  #
155
175
  # * +:image_name+ in the +pattern+ is replaced with the base name of the +url+
156
- # * Any other symbol is replaced with the value of +illust.__send__(the_symbol)+
176
+ # * Any other symbol is replaced with the value of +illust.send(the_symbol)+
157
177
  # * +#call+-able object is replaced with the value of +the_object.call(illust)+
158
178
  # * String is left as-is
159
179
  def filename_from_pattern(pattern, illust, url)
@@ -164,12 +184,33 @@ module Pixiv
164
184
  name += '.' + $1
165
185
  end
166
186
  name
167
- elsif i.is_a?(Symbol) then illust.__send__(i)
187
+ elsif i.is_a?(Symbol) then illust.send(i)
168
188
  elsif i.respond_to?(:call) then i.call(illust)
169
189
  else i
170
190
  end
171
191
  }.join('')
172
192
  end
193
+
194
+ protected
195
+
196
+ def illust_list_with_class(list_class, member_or_id, page)
197
+ it = member_or_id
198
+ id = it.is_a?(Member) ? it.member_id : it.to_i
199
+ attrs = {member_id: id} # Don't set page or it will prevent checking bounds.
200
+ list_class.lazy_new(attrs) {
201
+ agent.get(list_class.url(id, page))
202
+ }.bind(self)
203
+ end
204
+
205
+ def ensure_logged_in
206
+ doc = agent.get("#{ROOT_URL}/mypage.php")
207
+ raise Error::LoginFailed unless doc.body =~ /logout/
208
+ @member_id = member_id_from_mypage(doc)
209
+ end
210
+
211
+ def member_id_from_mypage(doc)
212
+ doc.at('.profile_area a')['href'].match(/\d+$/).to_s.to_i
213
+ end
173
214
  end
174
215
 
175
216
  # @private
@@ -32,10 +32,11 @@ module Pixiv
32
32
  }
33
33
  # @return [String]
34
34
  lazy_attr_reader(:title) { at!('.work-info h1.title').inner_text }
35
- # @return [Integer]
35
+ # @return [Integer, nil]
36
36
  lazy_attr_reader(:num_pages) {
37
- n = doc.at('//ul[@class="meta"]/li[2]')
38
- n && n.inner_text.match(/(\d+)P$/).to_a[1].to_i
37
+ node = doc.at('//ul[@class="meta"]/li[2]')
38
+ n = node ? node.inner_text.match(/(\d+)P$/).to_a[1] : nil
39
+ n && n.to_i
39
40
  }
40
41
  # @return [Array<String>]
41
42
  lazy_attr_reader(:tag_names) { search!('ul.tags a.text').map {|n| n.inner_text } }
@@ -71,4 +72,23 @@ module Pixiv
71
72
  @image_url_components ||= small_image_url.match(%r{^(.+)_s(\.\w+(?:\?\d+)?)$}).to_a[1, 3]
72
73
  end
73
74
  end
75
+
76
+ module Illust::WithClient
77
+ include Page::WithClient
78
+
79
+ # @return [Pixiv::Member]
80
+ def member
81
+ client.member(member_id)
82
+ end
83
+
84
+ # (see Pixiv::Client#download_illust)
85
+ def download_illust(io_or_filename, size = :original)
86
+ client.download_illust(self, io_or_filename, size)
87
+ end
88
+
89
+ # (see Pixiv::Client#download_manga)
90
+ def download_manga(pattern, &block)
91
+ client.download_manga(self, pattern, &block)
92
+ end
93
+ end
74
94
  end
@@ -0,0 +1,46 @@
1
+ module Pixiv
2
+ # @abstract
3
+ class IllustList < Page
4
+ include PageCollection
5
+
6
+ # @return [Integer]
7
+ attr_reader :page
8
+ # @return [Integer]
9
+ attr_reader :total_count
10
+
11
+ def page_class
12
+ Illust
13
+ end
14
+
15
+ # Don't just do `alias illust_hashes page_hashes`;
16
+ # the illust_hashes intends to call the page_hashes
17
+ # overridden in a subclass.
18
+
19
+ # An array of illust attrs extracted from doc
20
+ # @return [Array<{Symbol=>Object}, nil>]
21
+ def illust_hashes
22
+ page_hashes
23
+ end
24
+
25
+ # Ditto.
26
+
27
+ # URLs extracted from doc
28
+ # @return [Array<{Symbol=>Object}, nil>]
29
+ def illust_urls
30
+ page_urls
31
+ end
32
+ end
33
+
34
+ module IllustList::WithClient
35
+ include Page::WithClient
36
+ include Enumerable
37
+
38
+ # @yieldparam [Illust] illust
39
+ def each
40
+ illust_hashes.each do |attrs|
41
+ url = attrs.delete(:url)
42
+ yield Illust.lazy_new(attrs) { client.agent.get(url) }
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,58 @@
1
+ module Pixiv
2
+ # Illust list owned by a member
3
+ #
4
+ # @abstract
5
+ #
6
+ # Implements common methods for bookmark.php and member_illust.php.
7
+ class OwnedIllustList < IllustList
8
+ # Returns the URL for given +member_id+ and +page+
9
+ # @param [Integer] member_id
10
+ # @param [Integer] page
11
+ # @return [String]
12
+ def self.url(member_id, page = 1)
13
+ raise NotImplementError
14
+ end
15
+
16
+ # @return [Integer]
17
+ lazy_attr_reader(:page) {
18
+ at!('li.pages-current').inner_text.to_i
19
+ }
20
+ # @return [Boolean]
21
+ lazy_attr_reader(:last?) {
22
+ at!('li.pages-current').next_element.inner_text.to_i == 0
23
+ }
24
+ # @return [Integer]
25
+ lazy_attr_reader(:member_id) {
26
+ doc.body.match(/pixiv\.context\.userId = '(\d+)'/).to_a[1].to_i
27
+ }
28
+
29
+ # @return [String]
30
+ def url
31
+ self.class.url(member_id, page)
32
+ end
33
+
34
+ # @return [Boolean]
35
+ def first?
36
+ page == 1
37
+ end
38
+
39
+ # @return [String]
40
+ def next_url
41
+ last? ? nil : self.class.url(member_id, page + 1)
42
+ end
43
+
44
+ # @return [String]
45
+ def prev_url
46
+ first? ? nil : self.class.url(member_id, page - 1)
47
+ end
48
+ end
49
+
50
+ module OwnedIllustList::WithClient
51
+ include IllustList::WithClient
52
+
53
+ # @return [Pixiv::Member]
54
+ def member
55
+ client.member(member_id)
56
+ end
57
+ end
58
+ end
@@ -2,13 +2,13 @@ module Pixiv
2
2
  class Page
3
3
  # A new Page
4
4
  # @param [Hash{Symbol=>Object}] attrs
5
- # @yieldreturn [Nokogiri::HTML::Document]
5
+ # @yieldreturn [Nokogiri::XML::Document]
6
6
  def self.lazy_new(attrs = {}, &doc_creator)
7
7
  self.new(doc_creator, attrs)
8
8
  end
9
9
 
10
10
  # @overload initialize(doc, attrs = {})
11
- # @param [Nokogiri::HTTP::Document] doc
11
+ # @param [Nokogiri::XML::Document] doc
12
12
  # @param [Hash{Symbol=>Object}] attrs
13
13
  # @overload initialize(doc_creator, attrs = {})
14
14
  # @param [#call] doc_creator
@@ -27,10 +27,10 @@ module Pixiv
27
27
  # @param [String, Symbol] attr_name
28
28
  # @return [Boolean]
29
29
  def fetched?(attr_name = :doc)
30
- instance_variable_get(:"@#{attr_name}") != nil
30
+ instance_variable_defined?(:"@#{attr_name}")
31
31
  end
32
32
 
33
- # @return [Nokogiri::HTTP::Document]
33
+ # @return [Nokogiri::XML::Document]
34
34
  def doc
35
35
  @doc ||= begin
36
36
  doc = @doc_creator.call
@@ -50,6 +50,7 @@ module Pixiv
50
50
  end
51
51
 
52
52
  # Bind +self+ to +client+
53
+ # @api private
53
54
  # @return self
54
55
  def bind(client)
55
56
  if self.class.const_defined?(:WithClient)
@@ -98,14 +99,14 @@ module Pixiv
98
99
 
99
100
  # +node.at(path)+ or raise error
100
101
  # @param [String] path XPath or CSS path
101
- # @return [Nokogiri::HTML::Node]
102
+ # @return [Nokogiri::XML::Node]
102
103
  def at!(path, node = doc)
103
104
  node.at(path) or raise Error::NodeNotFound, "node for `#{path}` not found"
104
105
  end
105
106
 
106
107
  # +node.search(path) or raise error
107
108
  # @param [String] path XPath or CSS path
108
- # @return [Array<Nokogiri::HTML::Node>]
109
+ # @return [Array<Nokogiri::XML::Node>]
109
110
  def search!(path, node = doc)
110
111
  node.search(path) or raise Error::NodeNotFound, "node for `#{path}` not found"
111
112
  end
@@ -1,31 +1,43 @@
1
1
  module Pixiv
2
2
  module PageCollection
3
3
  def first?
4
- raise NotImplementError
4
+ next_url.nil?
5
5
  end
6
6
 
7
7
  def last?
8
- raise NotImplementError
8
+ prev_url.nil?
9
9
  end
10
10
 
11
+ private
12
+ def not_implemented!
13
+ name = caller[0][/`([^']*)'/, 1]
14
+ raise NotImplementedError,
15
+ "unimplemented method `#{name}' for #{self}"
16
+ end
17
+ public
18
+
11
19
  def next_url
12
- raise NotImplementError
20
+ not_implemented!
13
21
  end
14
22
 
15
23
  def prev_url
16
- raise NotImplementError
24
+ not_implemented!
17
25
  end
18
26
 
19
27
  def page_class
20
- raise NotImplementError
28
+ not_implemented!
29
+ end
30
+
31
+ def page_hashes
32
+ not_implemented!
21
33
  end
22
34
 
23
35
  def page_urls
24
- raise NotImplementError
36
+ page_hashes.map {|h| h[:url] }
25
37
  end
26
38
 
27
- def page_hash
28
- page_urls.map {|url| {url: url} }
39
+ def size
40
+ page_hashes.size
29
41
  end
30
42
  end
31
43
 
@@ -67,6 +79,23 @@ module Pixiv
67
79
  end
68
80
  end
69
81
 
82
+ def each_collection
83
+ collection = @collection
84
+ loop do
85
+ yield collection
86
+ next_url = collection.next_url or break
87
+ collection = collection.class.lazy_new { @client.agent.get(next_url) }
88
+ end
89
+ end
90
+
91
+ def count(*item)
92
+ if item.empty? && !block_given? && @collection.respond_to?(:total_count)
93
+ @collection.total_count
94
+ else
95
+ super
96
+ end
97
+ end
98
+
70
99
  private
71
100
 
72
101
  def pages_from_collection(collection)
@@ -77,13 +106,5 @@ module Pixiv
77
106
  end
78
107
  }
79
108
  end
80
-
81
- def each_collection(collection = @collection)
82
- loop do
83
- yield collection
84
- break unless collection.next_url
85
- collection = collection.class.new(@client.agent.get(collection.next_url))
86
- end
87
- end
88
109
  end
89
110
  end
@@ -1,3 +1,3 @@
1
1
  module Pixiv
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -0,0 +1,37 @@
1
+ module Pixiv
2
+ class WorkList < OwnedIllustList
3
+ # (see super.url)
4
+ def self.url(member_id, page = 1)
5
+ "#{ROOT_URL}/member_illust.php?id=#{member_id}&p=#{page}"
6
+ end
7
+
8
+ # @return [Integer]
9
+ lazy_attr_reader(:total_count) {
10
+ node = at!('.layout-cell .count-badge')
11
+ node.inner_text.match(/\d+/).to_s.to_i
12
+ }
13
+ # @return [Array<Hash{Symbol=>Object}, nil>]
14
+ lazy_attr_reader(:page_hashes) {
15
+ node = search!('.display_works li') \
16
+ .xpath('self::node()[not(starts-with(a[1]/@href, "/bookmark"))]')
17
+ node.map {|n| hash_from_list_item(n) }
18
+ }
19
+
20
+ private
21
+
22
+ # @param [Nokogiri::XML::Node] node
23
+ # @return [Hash{Symbol=>Object}] illust_hash
24
+ def hash_from_list_item(node)
25
+ return nil if node.at('img[src*="limit_unknown_s.png"]')
26
+ illust_node = node.at('a')
27
+ illust_id = illust_node['href'].match(/illust_id=(\d+)/).to_a[1].to_i
28
+ {
29
+ url: Illust.url(illust_id),
30
+ illust_id: illust_id,
31
+ title: illust_node.inner_text,
32
+ member_id: member_id,
33
+ small_image_url: illust_node.at('img')['src'],
34
+ }
35
+ end
36
+ end
37
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pixiv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-25 00:00:00.000000000 Z
12
+ date: 2012-12-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mechanize
@@ -94,10 +94,13 @@ files:
94
94
  - lib/pixiv/client.rb
95
95
  - lib/pixiv/error.rb
96
96
  - lib/pixiv/illust.rb
97
+ - lib/pixiv/illust_list.rb
97
98
  - lib/pixiv/member.rb
99
+ - lib/pixiv/owned_illust_list.rb
98
100
  - lib/pixiv/page.rb
99
101
  - lib/pixiv/page_collection.rb
100
102
  - lib/pixiv/version.rb
103
+ - lib/pixiv/work_list.rb
101
104
  - pixiv.gemspec
102
105
  - spec/fixtures/empty.html
103
106
  - spec/fixtures/illust_345.html
@@ -118,18 +121,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
121
  - - ! '>='
119
122
  - !ruby/object:Gem::Version
120
123
  version: '0'
121
- segments:
122
- - 0
123
- hash: -1798318064021145738
124
124
  required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  none: false
126
126
  requirements:
127
127
  - - ! '>='
128
128
  - !ruby/object:Gem::Version
129
129
  version: '0'
130
- segments:
131
- - 0
132
- hash: -1798318064021145738
133
130
  requirements: []
134
131
  rubyforge_project:
135
132
  rubygems_version: 1.8.24
@@ -144,3 +141,4 @@ test_files:
144
141
  - spec/pixiv/member_spec.rb
145
142
  - spec/pixiv/page_spec.rb
146
143
  - spec/spec_helper.rb
144
+ has_rdoc: