Class: Pixiv::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/pixiv/client.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pixiv_id, password) {|agent| ... } ⇒ Pixiv::Client #initialize(agent) ⇒ Pixiv::Client

A new instance of Client, logged in with the given credentials

Overloads:

  • #initialize(pixiv_id, password) {|agent| ... } ⇒ Pixiv::Client

    Parameters:

    • pixiv_id (String)
    • password (String)

    Yields:

    • (agent)

      (optional) gives a chance to customize the agent before logging in

  • #initialize(agent) ⇒ Pixiv::Client

    Parameters:

    • agent (Mechanize::HTTP::Agent)

27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/pixiv/client.rb', line 27

def initialize(*args)
  if args.size < 2
    @agent = args.first || self.class.new_agent
    yield @agent if block_given?
    ensure_logged_in
  else
    pixiv_id, password = *args
    @agent = self.class.new_agent
    yield @agent if block_given?
    (pixiv_id, password)
  end
end

Instance Attribute Details

#agentMechanize::HTTP::Agent (readonly)

Returns:

  • (Mechanize::HTTP::Agent)

15
16
17
# File 'lib/pixiv/client.rb', line 15

def agent
  @agent
end

#member_idInteger (readonly)

Returns:

  • (Integer)

17
18
19
# File 'lib/pixiv/client.rb', line 17

def member_id
  @member_id
end

Class Method Details

.new_agentMechanize::HTTP::Agent

A new agent

Returns:

  • (Mechanize::HTTP::Agent)

5
6
7
8
9
10
11
12
# File 'lib/pixiv/client.rb', line 5

def self.new_agent
  agent = Mechanize.new
  agent.max_history = 1
  agent.pluggable_parser['image/gif'] = Mechanize::Download
  agent.pluggable_parser['image/jpeg'] = Mechanize::Download
  agent.pluggable_parser['image/png'] = Mechanize::Download
  agent
end

Instance Method Details

#bookmark_list(member_or_id = member_id, page = 1) ⇒ Pixiv::BookmarkList

Returns bookmark list bound to self.

Parameters:

  • member_or_id (Pixiv::Member, Integer) (defaults to: member_id)
  • page (Integer) (defaults to: 1)

Returns:


84
85
86
# File 'lib/pixiv/client.rb', line 84

def bookmark_list(member_or_id = member_id, page = 1)
  illust_list_with_class(BookmarkList, member_or_id, page)
end

#bookmarks(member_or_id = member_id, page = 1, opts = {}) ⇒ Pixiv::PageCollection::Enumerator

Parameters:

  • member_or_id (Pixiv::Member, Integer) (defaults to: member_id)
  • page (Integer) (defaults to: 1)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :include_deleted (Boolean) — default: false

    whether the returning enumerator yields deleted illust as nil or not

Returns:


122
123
124
# File 'lib/pixiv/client.rb', line 122

def bookmarks(member_or_id = member_id, page = 1, opts = {})
  illusts(bookmark_list(member_or_id, page), opts)
end

#download_illust(illust, io_or_filename, size = :original) ⇒ Object

Downloads the image to io_or_filename

Parameters:

  • illust (Pixiv::Illust)
  • io_or_filename (#write, String, Array<String, Symbol, #call>)

    io or filename or pattern for #filename_from_pattern

  • size (Symbol) (defaults to: :original)

    image size (:small, :medium, or :original)


141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/pixiv/client.rb', line 141

def download_illust(illust, io_or_filename, size = :original)
  size = {:s => :small, :m => :medium, :o => :original}[size] || size
  url = illust.__send__("#{size}_image_url")
  referer = case size
            when :small then nil
            when :medium then illust.url
            when :original then illust.url
            else raise ArgumentError, "unknown size `#{size}`"
            end
  save_to = io_or_filename
  if save_to.is_a?(Array)
    save_to = filename_from_pattern(save_to, illust, url)
  end
  FileUtils.mkdir_p(File.dirname(save_to)) unless save_to.respond_to?(:write)
  @agent.download(url, save_to, [], referer)
end

#download_manga(illust, pattern, &block) ⇒ Object

TODO:

Document &block

Note:

illust#manga? must be true

Downloads the images to pattern

Parameters:


163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/pixiv/client.rb', line 163

def download_manga(illust, pattern, &block)
  action = DownloadActionRegistry.new(&block)
  illust.original_image_urls.each_with_index do |url, n|
    begin
      action.before_each.call(url, n) if action.before_each
      filename = filename_from_pattern(pattern, illust, url)
      FileUtils.mkdir_p(File.dirname(filename))
      @agent.download(url, filename, [], illust.original_image_referer)
      action.after_each.call(url, n) if action.after_each
    rescue
      action.on_error ? action.on_error.call($!) : raise
    end
  end
end

#filename_from_pattern(pattern, illust, url) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Generate filename from pattern in context of illust and url

The pattern is an array of string, symbol, or object that responds to #call. Each component of the pattern is replaced by the following rules and then the pattern is concatenated as the returning filename.

  • :image_name in the pattern is replaced with the base name of the url

  • Any other symbol is replaced with the value of illust.send(the_symbol)

  • #call-able object is replaced with the value of the_object.call(illust)

  • String is left as-is

Parameters:

  • pattern (Array<String, Symbol, #call>)
  • illust (Pixiv::Illust)
  • url (String)

Returns:

  • (String)

    filename


194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/pixiv/client.rb', line 194

def filename_from_pattern(pattern, illust, url)
  pattern.map {|i|
    if i == :image_name
      name = File.basename(url)
      if name =~ /\.(\w+)\?\d+$/
        name += '.' + $1
      end
      name
    elsif i.is_a?(Symbol) then illust.send(i)
    elsif i.respond_to?(:call) then i.call(illust)
    else i
    end
  }.join('')
end

#illust(illust_id) ⇒ Pixiv::Illust

Returns illust bound to self.

Parameters:

  • illust_id (Integer)

Returns:


65
66
67
68
69
# File 'lib/pixiv/client.rb', line 65

def illust(illust_id)
  attrs = {illust_id: illust_id}
  illust = Illust.lazy_new(attrs) { agent.get(Illust.url(illust_id)) }
  illust.bind(self)
end

#illusts(list, opts = {}) ⇒ Pixiv::PageCollection::Enumerator

Parameters:

Options Hash (opts):

  • :include_deleted (Boolean) — default: false

    whether the returning enumerator yields deleted illust as nil or not

Returns:


108
109
110
# File 'lib/pixiv/client.rb', line 108

def illusts(list, opts = {})
  PageCollection::Enumerator.new(self, list, !!opts[:include_deleted])
end

#login(pixiv_id, password) ⇒ Object

Log in to Pixiv

Parameters:

  • pixiv_id (String)
  • password (String)

Raises:


43
44
45
46
47
48
49
50
51
52
53
# File 'lib/pixiv/client.rb', line 43

def (pixiv_id, password)
  doc = agent.get("https://accounts.pixiv.net/login?lang=ja&source=pc&view_type=page")
  return if doc && doc.body =~ /logout/
  form = doc.forms_with(action: '/login').first
  puts doc.body and raise Error::LoginFailed, 'login form is not available' unless form
  form.pixiv_id = pixiv_id
  form.password = password
  doc = agent.submit(form)
  raise Error::LoginFailed unless doc && doc.body =~ /logout/
  @member_id = member_id_from_mypage(doc)
end

#member(member_id = member_id) ⇒ Pixiv::Member

Returns member bound to self.

Parameters:

  • member_id (Integer) (defaults to: member_id)

Returns:


57
58
59
60
61
# File 'lib/pixiv/client.rb', line 57

def member(member_id = member_id)
  attrs = {member_id: member_id}
  member = Member.lazy_new(attrs) { agent.get(Member.url(member_id)) }
  member.bind(self)
end

#private_bookmark_list(member_or_id = member_id, page = 1) ⇒ Pixiv::PrivateBookmarkList

Returns private bookmark list bound to self.

Parameters:

  • member_or_id (Pixiv::Member, Integer) (defaults to: member_id)
  • page (Integer) (defaults to: 1)

Returns:


91
92
93
# File 'lib/pixiv/client.rb', line 91

def private_bookmark_list(member_or_id = member_id, page = 1)
  illust_list_with_class(PrivateBookmarkList, member_or_id, page)
end

#private_bookmarks(page = 1, opts = {}) ⇒ Pixiv::PageCollection::Enumerator

Parameters:

  • page (Integer) (defaults to: 1)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :include_deleted (Boolean) — default: false

    whether the returning enumerator yields deleted illust as nil or not

Returns:


128
129
130
# File 'lib/pixiv/client.rb', line 128

def private_bookmarks(page = 1, opts = {})
  illusts(private_bookmark_list(member_id, page), opts)
end

#search(query, opts = {}) ⇒ Object


133
134
135
# File 'lib/pixiv/client.rb', line 133

def search(query, opts = {})
  illusts(search_result_list(query, opts))
end

#search_result_list(query, opts = {}) ⇒ Object


95
96
97
98
99
100
# File 'lib/pixiv/client.rb', line 95

def search_result_list(query, opts = {})
  attrs = {query: query, search_opts: opts}
  SearchResultList.lazy_new(attrs) {
    agent.get(SearchResultList.url(query, opts))
  }.bind(self)
end

#work_list(member_or_id = member_id, page = 1) ⇒ Pixiv::WorkList

Returns work list bound to self.

Parameters:

  • member_or_id (Pixiv::Member, Integer) (defaults to: member_id)
  • page (Integer) (defaults to: 1)

Returns:


74
75
76
77
78
79
# File 'lib/pixiv/client.rb', line 74

def work_list(member_or_id = member_id, page = 1)
  list = illust_list_with_class(WorkList, member_or_id, page)
  # Cheat; member_name will not found on your own work list.
  list.send(:set_attrs!, member_name: member.name) if list.owner_id == member_id
  list
end

#works(member_or_id = member_id, page = 1, opts = {}) ⇒ Pixiv::PageCollection::Enumerator

Parameters:

  • member_or_id (Pixiv::Member, Integer) (defaults to: member_id)
  • page (Integer) (defaults to: 1)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :include_deleted (Boolean) — default: false

    whether the returning enumerator yields deleted illust as nil or not

Returns:


115
116
117
# File 'lib/pixiv/client.rb', line 115

def works(member_or_id = member_id, page = 1, opts = {})
  illusts(work_list(member_or_id, page), opts)
end