Class: WikiBot::Bot

Inherits:
Object
  • Object
show all
Defined in:
lib/wikibot/core/bot.rb

Defined Under Namespace

Classes: LoginError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(username, password, options = {}) ⇒ Bot

Returns a new instance of Bot.

[View source]

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/wikibot/core/bot.rb', line 17

def initialize(username, password, options = {})
  @cookies = OpenHash.new
  @api_hits = 0
  @page_writes = 0

  api = options[:api] || "http://en.wikipedia.org/w/api.php"
   = options[:auto_login] || false
  @readonly = options[:readonly] || false
  @debug = options[:debug] || false

  @config = {
    :username   => username,
    :password   => password,
    :api        => api,
    :logged_in  => false
  }.to_openhash

  # Set up cURL:
  @curl = Curl::Easy.new do |c|
    c.headers["User-Agent"] = self.user_agent
    c.headers["Accept-Encoding"] = "gzip" # Request gzip-encoded content from MediaWiki
   end

   if 
end

Instance Attribute Details

#api_hitsObject (readonly)

How many times the API was queried


12
13
14
# File 'lib/wikibot/core/bot.rb', line 12

def api_hits
  @api_hits
end

#configObject (readonly)

Returns the value of attribute config.


11
12
13
# File 'lib/wikibot/core/bot.rb', line 11

def config
  @config
end

#debugObject

In debug mode, no writes will be made to the wiki


14
15
16
# File 'lib/wikibot/core/bot.rb', line 14

def debug
  @debug
end

#page_writesObject

How many write operations were performed


13
14
15
# File 'lib/wikibot/core/bot.rb', line 13

def page_writes
  @page_writes
end

#readonlyObject

Writes will not be made


15
16
17
# File 'lib/wikibot/core/bot.rb', line 15

def readonly
  @readonly
end

Instance Method Details

#category(name) ⇒ Object

[View source]

184
185
186
# File 'lib/wikibot/core/bot.rb', line 184

def category(name)
  WikiBot::Category.new(self, name)
end

#edit_token(page = "Main Page") ⇒ Object

[View source]

155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/wikibot/core/bot.rb', line 155

def edit_token(page = "Main Page")
  return nil unless logged_in?
  @config.edit_token ||= begin
    data = {
      :action     => :query, 
      :prop       => :info,
      :intoken    => :edit,
      :titles     => page 
    }

    query_api(:get, data).query.pages.page.edittoken
  end
end

#format_date(date) ⇒ Object

[View source]

188
189
190
191
192
193
# File 'lib/wikibot/core/bot.rb', line 188

def format_date(date)
  # Formats a date into the Wikipedia format
  time = date.strftime("%H:%M")
  month = date.strftime("%B")
  "#{time}, #{date.day} #{month} #{date.year} (UTC)"
end

#logged_in?Boolean

Returns:

  • (Boolean)
[View source]

115
116
117
# File 'lib/wikibot/core/bot.rb', line 115

def logged_in?
  @config.logged_in 
end

#loginObject

Raises:

[View source]

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/wikibot/core/bot.rb', line 119

def 
  return if logged_in?

  data = {
    :action     => :login, 
    :lgname     => @config.username,
    :lgpassword => @config.password
  }

  response = query_api(:post, data).

  if response.result == "NeedToken"
    data = {
      :action     => :login, 
      :lgname     => @config.username,
      :lgpassword => @config.password,
      :lgtoken    => response.token
    }

    response = query_api(:post, data).
  end

  raise LoginError, response.result unless response.result == "Success"

  @config.cookieprefix = response.cookieprefix 
  @config.logged_in = true
end

#logoutObject

[View source]

147
148
149
150
151
152
153
# File 'lib/wikibot/core/bot.rb', line 147

def logout
  return unless logged_in?

  query_api(:post, { :action => :logout })
  @config.logged_in = false
  @config.edit_token = nil
end

#page(name) ⇒ Object

[View source]

180
181
182
# File 'lib/wikibot/core/bot.rb', line 180

def page(name)
  WikiBot::Page.new(self, name)
end

#query_api(method, raw_data = {}) ⇒ Object

[View source]

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/wikibot/core/bot.rb', line 52

def query_api(method, raw_data = {})
  # Send a query to the API and handle the response
  url = @config.api
  raw_data = raw_data.to_openhash

  raw_data[:format] = :xml if raw_data.format.nil?

  # Setup cookie headers for the request
  @curl.headers["Cookie"] = @cookies.inject([]) do |memo, pair|
    key, val = pair
    memo.push(CGI::escape(key) + "=" + CGI::escape(val))
  end.join("; ") unless @cookies.nil?

  response_xml = {}

  while true
    if method == :post
      data = raw_data.to_post_fields
    elsif method == :get
      url = url.chomp("?") + "?" + raw_data.to_querystring
      data = nil
    end

    @curl.url = url
    @curl.headers["Expect"] = nil # MediaWiki will give a 417 error if Expect is set

    @curl.on_debug { |type, data| p data } if @debug
    
    @gzip = false
    @curl.on_header do |data|
      header, text = data.split(":").map(&:strip)
      if header == "Set-Cookie"
        # If Set-Cookie headers are given in the response, set the cookies
        parts = text.split(";")
        cookie_name, cookie_value = parts[0].split("=")
        @cookies[cookie_name] = cookie_value
      elsif header == "Content-Encoding"
        # If the respons is gzip encoded we'll have to decode it before use
        @gzip = true if text == "gzip"
      end
      data.length
    end

    params = ["http_#{method}".to_sym]
    params.push(*data) unless data.nil? or (data.is_a? Array and data.empty?)
    @curl.send(*params)
    @api_hits += 1

    raise CurbError.new(@curl) unless @curl.response_code == 200
    
    body = @gzip ? Zlib::GzipReader.new(StringIO.new(@curl.body_str)).read : @curl.body_str 

    xml = XmlSimple.xml_in(body, {'ForceArray' => false})
    raise APIError.new(xml['error']['code'], xml['error']['info']) if xml['error']

    response_xml.deep_merge! xml
    break unless xml['query-continue']
    raw_data.merge! xml['query-continue'][xml['query-continue'].keys.first]
  end

  response_xml.to_openhash
end

#statsObject

Get wiki stats

[View source]

170
171
172
173
174
175
176
177
178
# File 'lib/wikibot/core/bot.rb', line 170

def stats
  data = {
    :action       => :query,
    :meta         => :siteinfo,
    :siprop       => :statistics
  }

  query_api(:get, data).query.statistics
end

#user_agentObject

[View source]

48
49
50
# File 'lib/wikibot/core/bot.rb', line 48

def user_agent
  "#{@config.username}/#{self.version} WikiBot/#{WikiBot::VERSION} (https://github.com/dvandersluis/wikibot)"
end

#versionObject

Raises:

  • (NotImplementedError)
[View source]

43
44
45
46
# File 'lib/wikibot/core/bot.rb', line 43

def version
  # Specifies the client bot's version
  raise NotImplementedError
end