mediawiki-butt 1.2.0 → 1.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ac2473bbed75da107401d8c5dceeca3e2ed6b3c
4
- data.tar.gz: 36463ff0c4f70d87ce6d6f62994d7ff03cf4b47a
3
+ metadata.gz: 3d0b018bfc1617afe7610706ea9347c71ad79a57
4
+ data.tar.gz: 5c356aeacdbcd8697eed165665335c48afb38fdd
5
5
  SHA512:
6
- metadata.gz: 208c930ffa7dc8913b4c2b51bc6a82a46f1f55319d2ba92bf33eb139579dfbb8dff5b17327636df5235e651f63381ae4c808f84263868ca931a0cf1c9232035e
7
- data.tar.gz: ef133085ca55bd92f603d43430c4c100d17011c0d64427950463c4e18856da642c2f2270df33e722c1efda9b971484d5a6e416767ed2b487e719ee444001acfc
6
+ metadata.gz: abff053b2c91f898e7d97996c2c866b1269b1461e9d8bf50c7670aaeabd60994d8248fc79b494d6600b9da947722d31a50d0f282223cb468ab16a0a4dffd9dbf
7
+ data.tar.gz: 3357c256bbfe5b77270e014011a36e45a3ae74bac3f432c5585a555c1e0a1f6ad6d267d202ba63161bcf986a946cacb2f372012e23bd9351bb103b81b7fed43b
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
  ## Version 1
3
+ ### Version 1.3.0
4
+ **Security update!**
5
+ * Add support for the Assert API (PR #51).
6
+ * New `:assertion` option in initialize opts. It takes either `:user` or `:bot`.
7
+ * New `override_assertion` parameter in `post` to prevent assertion errors being thrown.
8
+ * **Note**: Assertions will only happen if `post`'s `autoparse` parameter is true.
9
+ * New NotLoggedInError and NotBotError for the according assertions.
10
+ * `Butt#user_bot?` no longer has a parameter. It now queries with an assertion rather than checking the user's groups.
11
+ * New method `Butt#logged_in?` to check if the current instance is logged in.
12
+
3
13
  ### Version 1.2.0
4
14
  * Add support for the Purge API (#48)
5
15
 
@@ -22,7 +22,7 @@ module MediaWiki
22
22
  header = {}
23
23
  header['Set-Cookie'] = @cookie if @cookie
24
24
 
25
- response = post(params, true, header)
25
+ response = post(params, true, header, true)
26
26
  result = response['login']['result']
27
27
 
28
28
  if result == 'NeedToken'
@@ -50,7 +50,7 @@ module MediaWiki
50
50
  action: 'logout'
51
51
  }
52
52
 
53
- post(params)
53
+ post(params, true, nil, true)
54
54
  @logged_in = false
55
55
 
56
56
  true
@@ -25,6 +25,7 @@ module MediaWiki
25
25
 
26
26
  attr_accessor :query_limit_default
27
27
  attr_accessor :use_continuation
28
+ attr_accessor :assertion
28
29
 
29
30
  # Creates a new instance of MediaWiki::Butt.
30
31
  # @param url [String] The FULL wiki URL. api.php can be omitted, but it will make harsh assumptions about
@@ -36,6 +37,10 @@ module MediaWiki
36
37
  # use that, otherwise, it will use this. Defaults to 500. It can be set to 'max' to use MW's default max for
37
38
  # each API.
38
39
  # @option opts [Boolean] :use_continuation Whether to use the continuation API on queries.
40
+ # @option opts [Symbol] :assertion If set to :user or :bot, will use the assert parameter in all requests.
41
+ # Setting this will open up the possibility for NotLoggedInErrors and NotBotErrors. It is important to keep in
42
+ # mind that methods that check if the user is logged in do not use the API, but check if the user has *ever*
43
+ # logged in as this Butt instance. In other words, it is a safety check for performance and not a valid API check.
39
44
  def initialize(url, opts = {})
40
45
  @url = url =~ /api.php$/ ? url : "#{url}/api.php"
41
46
  @query_limit_default = opts[:query_limit_default] || 500
@@ -44,6 +49,9 @@ module MediaWiki
44
49
  @logged_in = false
45
50
  @custom_agent = opts[:custom_agent]
46
51
  @use_continuation = opts[:use_continuation]
52
+
53
+ assertion = opts[:assertion]
54
+ @assertion = assertion == :user || assertion == :bot ? assertion : nil
47
55
  end
48
56
 
49
57
  # Performs a generic HTTP POST request and provides the response. This method generally should not be used by the
@@ -52,11 +60,14 @@ module MediaWiki
52
60
  # information.
53
61
  # @param autoparse [Boolean] Whether or not to provide a parsed version of the response's JSON.
54
62
  # @param header [Hash] The header hash. Optional.
63
+ # @param override_assertion [Boolean] Whether to override the @assertion check. This is used in #login because
64
+ # that can never be done while already logged in.
55
65
  # @since 0.1.0
56
66
  # @return [Hash] Parsed JSON if autoparse is true.
57
67
  # @return [HTTPMessage] Raw HTTP response if autoparse is not true.
58
- def post(params, autoparse = true, header = nil)
68
+ def post(params, autoparse = true, header = nil, override_assertion = false)
59
69
  params[:format] = 'json'
70
+ params[:assert] = @assertion.to_s if @assertion && !override_assertion && !params.key?(:assert)
60
71
  header = {} if header.nil?
61
72
 
62
73
  header['User-Agent'] = @logged_in ? "#{@name}/MediaWiki::Butt" : 'NotLoggedIn/MediaWiki::Butt'
@@ -64,7 +75,15 @@ module MediaWiki
64
75
 
65
76
  res = @client.post(@uri, params, header)
66
77
 
67
- autoparse ? JSON.parse(res.body) : res
78
+ return res unless autoparse
79
+ parsed = JSON.parse(res.body)
80
+
81
+ if !override_assertion || @assertion
82
+ code = parsed.dig('error', 'code')
83
+ fail MediaWiki::Butt::NotLoggedInError.new(parsed['error']['info']) if code == 'assertuserfailed'
84
+ fail MediaWiki::Butt::NotBotError.new(parsed['error']['info']) if code == 'assertbotfailed'
85
+ end
86
+ parsed
68
87
  end
69
88
 
70
89
  # Performs a Mediawiki API query and provides the response, dealing with continuation as necessary.
@@ -92,28 +111,49 @@ module MediaWiki
92
111
  base_return
93
112
  end
94
113
 
114
+ # Helper method for query methods that return a two-dimensional hashes in which the keys are not relevant to the
115
+ # returning value. In most cases this key is a redundant page or revision ID that is also available in the object.
116
+ # @param (see #query_ary)
117
+ def query_ary_irrelevant_keys(params, base_response_key, property_key)
118
+ query(params) do |return_val, query|
119
+ return_val.concat(query[base_response_key].values.collect { |obj| obj[property_key] })
120
+ end
121
+ end
122
+
95
123
  # Helper method for query methods that return an array built from the query objects.
96
124
  # @param params [Hash] A hash containing MediaWiki API parameters.
97
- # @param
125
+ # @param base_response_key [String] The key inside the "query" object to collect.
126
+ # @param property_key [String] The key inside the object (under the base_response_key) to collect.
98
127
  def query_ary(params, base_response_key, property_key)
99
128
  query(params) do |return_val, query|
100
- query[base_response_key].each { |obj| return_val << obj[property_key] }
129
+ return_val.concat(query[base_response_key].collect { |obj| obj[property_key] })
101
130
  end
102
131
  end
103
132
 
104
133
  # Gets whether the currently logged in user is a bot.
105
- # @param username [String] The username to check. Optional. Defaults to
106
- # the currently logged in user if nil.
107
134
  # @return [Boolean] true if logged in as a bot, false if not logged in or
108
135
  # logged in as a non-bot
109
136
  # @since 0.1.0 as is_current_user_bot
110
137
  # @since 0.3.0 as is_user_bot?
111
138
  # @since 0.4.1 as user_bot?
112
- def user_bot?(username = nil)
113
- groups = false
114
- name = username || @name
115
- groups = get_usergroups(name) if name
116
- groups && groups.include?('bot')
139
+ def user_bot?
140
+ begin
141
+ post({ action: 'query', assert: 'bot' })
142
+ true
143
+ rescue MediaWiki::Butt::NotBotError
144
+ false
145
+ end
146
+ end
147
+
148
+ # Checks whether this instance is logged in.
149
+ # @return [Boolean] true if logged in, false if not.
150
+ def logged_in?
151
+ begin
152
+ post({ action: 'query', assert: 'user' })
153
+ true
154
+ rescue MediaWiki::Butt::NotLoggedInError
155
+ false
156
+ end
117
157
  end
118
158
 
119
159
  protected
@@ -219,5 +219,9 @@ module MediaWiki
219
219
  # Extension:Flow
220
220
  'FLW_TOPIC'.freeze => 2600
221
221
  }.freeze
222
+
223
+ # @return [Proc] A proc that returns the missing page ID, -1. This is useful for using methods like Enumerable#find
224
+ # and not creating a new Proc object for every call.
225
+ MISSING_PAGEID_PROC = Proc.new { '-1' }
222
226
  end
223
227
  end
@@ -3,5 +3,7 @@ module MediaWiki
3
3
  class AuthenticationError < StandardError; end
4
4
  class EditError < StandardError; end
5
5
  class BlockError < StandardError; end
6
+ class NotLoggedInError < StandardError; end
7
+ class NotBotError < StandardError; end
6
8
  end
7
9
  end
@@ -41,17 +41,12 @@ module MediaWiki
41
41
  params[:action] = 'purge'
42
42
  params[:titles] = titles.join('|')
43
43
 
44
- response = post(params)
45
-
46
- ret = {}
47
-
48
- response['purge'].each do |hash|
44
+ post(params)['purge'].inject({}) do |result, hash|
49
45
  title = hash['title']
50
- ret[title] = hash.key?('purged') && !hash.key?('missing')
46
+ result[title] = hash.key?('purged') && !hash.key?('missing')
51
47
  warn "Invalid purge (#{title}) #{hash['invalidreason']}" if hash.key?('invalid')
48
+ result
52
49
  end
53
-
54
- ret
55
50
  end
56
51
  end
57
52
  end
@@ -184,7 +184,7 @@ module MediaWiki
184
184
  }
185
185
 
186
186
  query(params) do |return_val, query|
187
- query['querypage']['results'].each { |result| return_val << result['title'] }
187
+ return_val.concat(query['querypage']['results'].collect { |result| result['title'] })
188
188
  end
189
189
  end
190
190
  end
@@ -34,9 +34,7 @@ module MediaWiki
34
34
  params[:rcstart] = start.xmlschema unless start.nil?
35
35
  params[:rcend] = stop.xmlschema unless stop.nil?
36
36
 
37
- response = post(params)
38
- ret = []
39
- response['query']['recentchanges'].each do |change|
37
+ post(params)['query']['recentchanges'].collect do |change|
40
38
  old_length = change['oldlen']
41
39
  new_length = change['newlen']
42
40
  diff_length = new_length - old_length
@@ -68,10 +66,8 @@ module MediaWiki
68
66
  hash[:logid] = change['logid']
69
67
  end
70
68
 
71
- ret << hash
69
+ hash
72
70
  end
73
-
74
- ret
75
71
  end
76
72
 
77
73
  # Gets the recent deleted revisions.
@@ -90,9 +86,7 @@ module MediaWiki
90
86
  params[:drstart] = start.xmlschema unless start.nil?
91
87
  params[:drend] = stop.xmlschema unless stop.nil?
92
88
 
93
- response = post(params)
94
- ret = []
95
- response['query']['deletedrevs'].each do |rev|
89
+ post(params)['query']['deletedrevs'].collect do |rev|
96
90
  r = rev['revisions'][0]
97
91
  hash = {
98
92
  timestamp: DateTime.xmlschema(r['timestamp']),
@@ -100,10 +94,9 @@ module MediaWiki
100
94
  comment: r['comment'],
101
95
  title: rev['title']
102
96
  }
103
- ret << hash
104
- end
105
97
 
106
- ret
98
+ hash
99
+ end
107
100
  end
108
101
  end
109
102
  end
@@ -36,19 +36,13 @@ module MediaWiki
36
36
  # @return [Array<String>] All of the user's groups.
37
37
  # @return [Boolean] False if username is nil and not logged in.
38
38
  def get_usergroups(username = nil)
39
- ret = []
40
39
  if username.nil?
41
40
  return false unless @logged_in
42
- info = get_userlists('groups')
43
- info['query']['userinfo']['groups'].each { |i| ret << i }
41
+ get_userlists('groups')['query']['userinfo']['groups']
44
42
  else
45
43
  info = get_userlists('groups', username)
46
- info['query']['users'].each do |i|
47
- i['groups'].each { |g| ret << g }
48
- end
44
+ info['query']['users'].collect { |i| i['groups'] }.flatten
49
45
  end
50
-
51
- ret
52
46
  end
53
47
 
54
48
  # Gets the user rights for the user.
@@ -58,21 +52,14 @@ module MediaWiki
58
52
  # @return [Array<String>] All of the user's groups.
59
53
  # @return [Boolean] False if username is nil and not logged in.
60
54
  def get_userrights(username = nil)
61
- ret = []
62
55
  if username.nil?
63
56
  return false unless @logged_in
64
57
  info = get_userlists('rights')
65
- info['query']['userinfo']['rights'].each { |i| ret << i }
58
+ info['query']['userinfo']['rights']
66
59
  else
67
60
  info = get_userlists('rights', username)
68
- info['query']['users'].each do |i|
69
- i['rights'].each do |g|
70
- ret << g
71
- end
72
- end
61
+ info['query']['users'].find { |hash| hash['name'] == username }['rights']
73
62
  end
74
-
75
- ret
76
63
  end
77
64
 
78
65
  # Gets contribution count for the user.
@@ -83,17 +70,14 @@ module MediaWiki
83
70
  # @return [Boolean] False if username is nil and not logged in.
84
71
  # @return [Fixnum] The number of contributions the user has made.
85
72
  def get_contrib_count(username = nil)
86
- count = nil
87
73
  if username.nil?
88
74
  return false unless @logged_in
89
75
  info = get_userlists('editcount')
90
- count = info['query']['userinfo']['editcount']
76
+ info['query']['userinfo']['editcount']
91
77
  else
92
78
  info = get_userlists('editcount', username)
93
- info['query']['users'].each { |i| count = i['editcount'] }
79
+ info['query']['users'].find { |hash| hash['name'] == username }['editcount']
94
80
  end
95
-
96
- count
97
81
  end
98
82
 
99
83
  # Gets when the user registered.
@@ -104,7 +88,6 @@ module MediaWiki
104
88
  # @return [DateTime] The registration date and time as a DateTime object.
105
89
  # @return [Boolean] False when no username is provided and not logged in, or the user doesn't exist.
106
90
  def get_registration_time(username = nil)
107
- time = nil
108
91
  # Do note that in Userinfo, registration is called registrationdate.
109
92
  if username.nil?
110
93
  return false unless @logged_in
@@ -112,7 +95,7 @@ module MediaWiki
112
95
  time = info['query']['userinfo']['registrationdate']
113
96
  else
114
97
  info = get_userlists('registration', username)
115
- info['query']['users'].each { |i| time = i['registration'] }
98
+ time = info['query']['users'].find { |hash| hash['name'] == username }['registration']
116
99
  end
117
100
 
118
101
  return false if time.nil?
@@ -126,11 +109,8 @@ module MediaWiki
126
109
  # @since 0.4.0
127
110
  # @return [String] The gender. 'male', 'female', or 'unknown'.
128
111
  def get_user_gender(username)
129
- gender = nil
130
112
  info = get_userlists('gender', username)
131
- info['query']['users'].each { |i| gender = i['gender'] }
132
-
133
- gender
113
+ info['query']['users'].find { |hash| hash['name'] == username }['gender']
134
114
  end
135
115
 
136
116
  # Gets the latest contributions by the user until the limit.
@@ -41,26 +41,14 @@ module MediaWiki
41
41
  # @since 0.7.0
42
42
  # @return [Array<String>] All repository names that are marked as local.
43
43
  def get_local_filerepos
44
- response = get_filerepoinfo('name|local')
45
- ret = []
46
- response['query']['repos'].each do |h|
47
- ret << h['name'] if h.key?('local')
48
- end
49
-
50
- ret
44
+ get_filerepoinfo('name|local')['query']['repos'].select { |h| h.key?('local') }.collect { |h| h['name'] }
51
45
  end
52
46
 
53
47
  # Gets an array containing all repositories that aren't local.
54
48
  # @since 0.7.0
55
49
  # @return [Array<String>] All repositories that are not marked as local.
56
50
  def get_nonlocal_filerepos
57
- response = get_filerepoinfo('name|local')
58
- ret = []
59
- response['query']['repos'].each do |h|
60
- ret << h['name'] unless h.key?('local')
61
- end
62
-
63
- ret
51
+ get_filerepoinfo('name|local')['query']['repos'].reject { |h| h.key?('local') }.collect { |h| h['name'] }
64
52
  end
65
53
 
66
54
  # Gets the repository names and their according URLs.
@@ -41,10 +41,7 @@ module MediaWiki
41
41
  # @since 0.6.0
42
42
  # @return [Array<String>] All extension names.
43
43
  def get_extensions
44
- response = get_siteinfo('extensions')
45
- ret = []
46
- response['query']['extensions'].each { |e| ret << e['name'] }
47
- ret
44
+ get_siteinfo('extensions')['query']['extensions'].collect { |e| e['name'] }
48
45
  end
49
46
 
50
47
  # Gets all languages and their codes.
@@ -123,12 +120,7 @@ module MediaWiki
123
120
  # @since 0.6.0
124
121
  # @return [Array<String>] All file extensions.
125
122
  def get_allowed_file_extensions
126
- response = get_siteinfo('fileextensions')
127
- ret = []
128
- response['query']['fileextensions'].each do |e|
129
- ret << e['ext']
130
- end
131
- ret
123
+ get_siteinfo('fileextensions')['query']['fileextensions'].collect { |e| e['ext'] }
132
124
  end
133
125
 
134
126
  # Gets the response for the restrictions siteinfo API. Not really for use by users, mostly for the other two
@@ -136,28 +128,21 @@ module MediaWiki
136
128
  # @since 0.6.0
137
129
  # @return [Hash<String, Array<String>>] All restriction data. See the other restriction methods.
138
130
  def get_restrictions_data
139
- response = get_siteinfo('restrictions')
140
- response['query']['restrictions']
131
+ get_siteinfo('restrictions')['query']['restrictions']
141
132
  end
142
133
 
143
134
  # Gets all restriction/protection types.
144
135
  # @since 0.6.0
145
136
  # @return [Array<String>] All protection types.
146
137
  def get_restriction_types
147
- restrictions = get_restrictions_data
148
- ret = []
149
- restrictions['types'].each { |t| ret << t }
150
- ret
138
+ get_restrictions_data['types']
151
139
  end
152
140
 
153
141
  # Gets all restriction/protection levels.
154
142
  # @since 0.6.0
155
143
  # @return [Array<String>] All protection levels.
156
144
  def get_restriction_levels
157
- restrictions = get_restrictions_data
158
- ret = []
159
- restrictions['levels'].each { |l| ret << l }
160
- ret
145
+ get_restrictions_data['levels']
161
146
  end
162
147
 
163
148
  # Gets all skins and their codes.
@@ -176,36 +161,21 @@ module MediaWiki
176
161
  # @since 0.6.0
177
162
  # @return [Array<String>] All extension tags.
178
163
  def get_extension_tags
179
- response = get_siteinfo('extensiontags')
180
- ret = []
181
- response['query']['extensiontags'].each do |t|
182
- ret << t
183
- end
184
- ret
164
+ get_siteinfo('extensiontags')['query']['extensiontags']
185
165
  end
186
166
 
187
167
  # Gets all function hooks.
188
168
  # @since 0.6.0
189
169
  # @return [Array<String>] All function hooks.
190
170
  def get_function_hooks
191
- response = get_siteinfo('functionhooks')
192
- ret = []
193
- response['query']['functionhooks'].each do |h|
194
- ret << h
195
- end
196
- ret
171
+ get_siteinfo('functionhooks')['query']['functionhooks']
197
172
  end
198
173
 
199
174
  # Gets all variables that are usable on the wiki, such as NUMBEROFPAGES.
200
175
  # @since 0.6.0
201
176
  # @return [Array<String>] All variable string values.
202
177
  def get_variables
203
- response = get_siteinfo('variables')
204
- ret = []
205
- response['query']['variables'].each do |v|
206
- ret << v
207
- end
208
- ret
178
+ get_siteinfo('variables')['query']['variables']
209
179
  end
210
180
  end
211
181
  end
@@ -45,27 +45,19 @@ module MediaWiki
45
45
  # Gets a hash-of-arrays containing all the groups the user can add and remove people from.
46
46
  # @since 0.7.0
47
47
  # @return [Boolean] False if get_current_user_meta is false
48
- # @return [Hash<String, Array<String>>] All the groups that the user can add, remove, add-self, and remove-self.
48
+ # @return [Hash<String, Array<String>>] All the groups that the user can :add, :remove, :addself, and
49
+ # :remove-self.
49
50
  def get_changeable_groups
50
51
  response = get_current_user_meta('changeablegroups')
51
52
  return false unless response
52
53
 
53
- ret = {}
54
- add = []
55
- remove = []
56
- addself = []
57
- removeself = []
58
54
  changeablegroups = response['query']['userinfo']['changeablegroups']
59
- changeablegroups['add'].each { |g| add.push(g) }
60
- changeablegroups['remove'].each { |g| remove.push(g) }
61
- changeablegroups['add-self'].each { |g| addself.push(g) }
62
- changeablegroups['remove-self'].each { |g| removeself.push(g) }
63
- ret['add'] = add
64
- ret['remove'] = remove
65
- ret['addself'] = addself
66
- ret['removeself'] = removeself
67
-
68
- ret
55
+ {
56
+ :add => changeablegroups['add'],
57
+ :remove => changeablegroups['remove'],
58
+ :addself => changeablegroups['add-self'],
59
+ :removeself => changeablegroups['add-self']
60
+ }
69
61
  end
70
62
 
71
63
  # Gets the currently logged in user's real name.
@@ -1,4 +1,5 @@
1
1
  require_relative '../query'
2
+ require_relative '../../constants'
2
3
 
3
4
  module MediaWiki
4
5
  module Query
@@ -28,8 +29,7 @@ module MediaWiki
28
29
  # @return [Array<String>] All usernames for the contributors.
29
30
  def get_logged_in_contributors(title, limit = @query_limit_default)
30
31
  get_contributors_response(title, limit) do |return_val, query|
31
- pageid = nil
32
- query['pages'].each { |r, _| pageid = r }
32
+ pageid = query['pages'].keys.find(MediaWiki::Constants::MISSING_PAGEID_PROC) { |id| id != '-1' }
33
33
  return if query['pages'][pageid].key?('missing')
34
34
  query['pages'][pageid]['contributors'].each { |c| return_val << c['name'] }
35
35
  end
@@ -62,8 +62,7 @@ module MediaWiki
62
62
  ret = 0
63
63
 
64
64
  get_contributors_response(title, limit) do |_, query|
65
- pageid = nil
66
- query['pages'].each { |r, __| pageid = r }
65
+ pageid = query['pages'].keys.find(MediaWiki::Constants::MISSING_PAGEID_PROC) { |id| id != '-1' }
67
66
  return if query['pages'][pageid].key?('missing')
68
67
  ret += query['pages'][pageid]['anoncontributors'].to_i
69
68
  end
@@ -1,4 +1,5 @@
1
1
  require_relative '../query'
2
+ require_relative '../../constants'
2
3
 
3
4
  module MediaWiki
4
5
  module Query
@@ -37,7 +38,7 @@ module MediaWiki
37
38
  dflimit: get_limited(limit)
38
39
  }
39
40
 
40
- query_ary(params, 'pages', 'title')
41
+ query_ary_irrelevant_keys(params, 'pages', 'title')
41
42
  end
42
43
 
43
44
  # Gets the size of an image in bytes.
@@ -82,14 +83,9 @@ module MediaWiki
82
83
  }
83
84
 
84
85
  response = post(params)
85
- pageid = nil
86
- response['query']['pages'].each { |r, _| pageid = r }
86
+ pageid = response['query']['pages'].keys.find(MediaWiki::Constants::MISSING_PAGEID_PROC) { |id| id != '-1'}
87
87
  return nil if pageid == '-1'
88
- ret = {}
89
- response['query']['pages'][pageid]['imageinfo'].each do |i|
90
- i.each { |k, v| ret[k] = v }
91
- end
92
- ret
88
+ response['query']['pages'][pageid]['imageinfo'].reduce({}, :merge)
93
89
  end
94
90
  end
95
91
  end
@@ -1,4 +1,5 @@
1
1
  require_relative '../query'
2
+ require_relative '../../constants'
2
3
 
3
4
  module MediaWiki
4
5
  module Query
@@ -17,14 +18,9 @@ module MediaWiki
17
18
  }
18
19
 
19
20
  query(params) do |return_val, query|
20
- pageid = nil
21
- query['pages'].each do |r, _|
22
- pageid = r
23
- break
24
- end
25
-
21
+ pageid = query['pages'].keys.find(MediaWiki::Constants::MISSING_PAGEID_PROC) { |id| id != '-1' }
26
22
  return if query['pages'][pageid].key?('missing')
27
- query['pages'][pageid].fetch('categories', []).each { |c| return_val << c['title'] }
23
+ return_val.concat(query['pages'][pageid].fetch('categories', []).collect { |c| c['title'] })
28
24
  end
29
25
  end
30
26
 
@@ -44,11 +40,8 @@ module MediaWiki
44
40
  }
45
41
 
46
42
  response = post(params)
47
- revid = nil
48
- response['query']['pages'].each { |r, _| revid = r }
49
-
43
+ revid = response['query']['pages'].keys.find(MediaWiki::Constants::MISSING_PAGEID_PROC) { |id| id != '-1' }
50
44
  revision = response['query']['pages'][revid]
51
-
52
45
  revision['missing'] == '' ? nil : revision['revisions'][0]['*']
53
46
  end
54
47
 
@@ -66,10 +59,7 @@ module MediaWiki
66
59
  titles: title
67
60
  }
68
61
 
69
- response = post(params)
70
- response['query']['pages'].each do |revid, _|
71
- return revid == '-1' ? nil : revid.to_i
72
- end
62
+ post(params)['query']['pages'].keys.find { |id| id != '-1' }&.to_i
73
63
  end
74
64
 
75
65
  # Gets all the external links on a given page.
@@ -88,10 +78,9 @@ module MediaWiki
88
78
  }
89
79
 
90
80
  query(params) do |return_val, query|
91
- query['pages'].each do |revid, _|
92
- return if revid == '-1'
93
- query['pages'][revid]['extlinks'].each { |l| return_val << l['*'] }
94
- end
81
+ pageid = query['pages'].keys.find { |id| id != '-1' }
82
+ return unless pageid
83
+ return_val.concat(query['pages'][pageid]['extlinks'].collect { |l| l['*'] })
95
84
  end
96
85
  end
97
86
 
@@ -104,17 +93,7 @@ module MediaWiki
104
93
  # @return [Nil] If the page does not exist.
105
94
  def do_i_watch?(title)
106
95
  return false unless @logged_in
107
- params = {
108
- action: 'query',
109
- titles: title,
110
- prop: 'info',
111
- inprop: 'watched'
112
- }
113
-
114
- response = post(params)
115
- response['query']['pages'].each do |revid, _|
116
- return revid == '-1' ? nil : response['query']['pages'][revid].key?('watched')
117
- end
96
+ page_info_contains_key(title, 'watched', 'watched')
118
97
  end
119
98
 
120
99
  # Gets whether the current user (can be anonymous) can read the page.
@@ -124,17 +103,7 @@ module MediaWiki
124
103
  # @return [Boolean] Whether the user can read the page.
125
104
  # @return [Nil] If the page does not exist.
126
105
  def can_i_read?(title)
127
- params = {
128
- action: 'query',
129
- titles: title,
130
- prop: 'info',
131
- inprop: 'readable'
132
- }
133
-
134
- response = post(params)
135
- response['query']['pages'].each do |revid, _|
136
- return revid == '-1' ? nil : response['query']['pages'][revid].key?('readable')
137
- end
106
+ page_info_contains_key(title, 'readable', 'readable')
138
107
  end
139
108
 
140
109
  # Gets whether the given page is a redirect.
@@ -144,16 +113,7 @@ module MediaWiki
144
113
  # @return [Boolean] Whether the page is a redirect.
145
114
  # @return [Nil] If the page does not exist.
146
115
  def page_redirect?(title)
147
- params = {
148
- action: 'query',
149
- titles: title,
150
- prop: 'info'
151
- }
152
-
153
- response = post(params)
154
- response['query']['pages'].each do |revid, _|
155
- return revid == '-1' ? nil : response['query']['pages'][revid].key?('redirect')
156
- end
116
+ page_info_contains_key(title, 'redirect')
157
117
  end
158
118
 
159
119
  # Gets whether the given page only has one edit.
@@ -163,16 +123,7 @@ module MediaWiki
163
123
  # @return [Boolean] Whether the page only has one edit.
164
124
  # @return [Nil] If the page does not exist.
165
125
  def page_new?(title)
166
- params = {
167
- action: 'query',
168
- titles: title,
169
- prop: 'info'
170
- }
171
-
172
- response = post(params)
173
- response['query']['pages'].each do |revid, _|
174
- return revid == '-1' ? nil : response['query']['pages'][revid].key?('new')
175
- end
126
+ page_info_contains_key(title, 'new')
176
127
  end
177
128
 
178
129
  # Gets the number of users that watch the given page.
@@ -182,17 +133,7 @@ module MediaWiki
182
133
  # @return [Fixnum] The number of watchers.
183
134
  # @return [Nil] If the page does not exist.
184
135
  def get_number_of_watchers(title)
185
- params = {
186
- action: 'query',
187
- titles: title,
188
- prop: 'info',
189
- inprop: 'watchers'
190
- }
191
-
192
- response = post(params)
193
- response['query']['pages'].each do |revid, _|
194
- return revid == '-1' ? nil : response['query']['pages'][revid]['watchers']
195
- end
136
+ page_info_get_val(title, 'watchers', 'watchers')
196
137
  end
197
138
 
198
139
  # Gets the way the title is actually displayed, after any in-page changes to its display, e.g., using a
@@ -203,17 +144,7 @@ module MediaWiki
203
144
  # @return [String] The page's display title.
204
145
  # @return [Nil] If the page does not exist.
205
146
  def get_display_title(title)
206
- params = {
207
- action: 'query',
208
- titles: title,
209
- prop: 'info',
210
- inprop: 'displaytitle'
211
- }
212
-
213
- response = post(params)
214
- response['query']['pages'].each do |revid, _|
215
- return revid == '-1' ? nil : response['query']['pages'][revid]['displaytitle']
216
- end
147
+ page_info_get_val(title, 'displaytitle', 'displaytitle')
217
148
  end
218
149
 
219
150
  # Gets the levels of protection on the page.
@@ -234,14 +165,15 @@ module MediaWiki
234
165
  }
235
166
 
236
167
  response = post(params)
237
- response['query']['pages'].each do |revid, _|
238
- return if revid == '-1'
239
- protection = response['query']['pages'][revid]['protection']
240
- protection.each do |p|
241
- p.keys.each { |k| p[k.to_sym] = p.delete(k) }
242
- end
243
- return protection
168
+
169
+ pageid = response['query']['pages'].keys.find { |id| id != '-1' }
170
+ return unless pageid
171
+ protection = response['query']['pages'][pageid]['protection']
172
+ protection.each do |p|
173
+ p.keys.each { |k| p[k.to_sym] = p.delete(k) }
244
174
  end
175
+
176
+ protection
245
177
  end
246
178
 
247
179
  # Gets the size, in bytes, of the page.
@@ -251,16 +183,7 @@ module MediaWiki
251
183
  # @return [Fixnum] The number of bytes.
252
184
  # @return [Nil] If the page does not exist.
253
185
  def get_page_size(title)
254
- params = {
255
- action: 'query',
256
- titles: title,
257
- prop: 'info'
258
- }
259
-
260
- response = post(params)
261
- response['query']['pages'].each do |revid, _|
262
- return revid == '-1' ? nil : response['query']['pages'][revid]['length']
263
- end
186
+ page_info_get_val(title, 'length')
264
187
  end
265
188
 
266
189
  # Gets all of the images in the given page.
@@ -277,10 +200,9 @@ module MediaWiki
277
200
  }
278
201
 
279
202
  query(params) do |return_val, query|
280
- query['pages'].each do |revid, _|
281
- return if revid == '-1'
282
- query['pages'][revid]['images'].each { |img| return_val << img['title'] }
283
- end
203
+ pageid = query['pages'].keys.find { |id| id != '-1' }
204
+ return unless pageid
205
+ return_val.concat(query['pages'][pageid]['images'].collect { |img| img['title'] })
284
206
  end
285
207
  end
286
208
 
@@ -298,10 +220,9 @@ module MediaWiki
298
220
  }
299
221
 
300
222
  query(params) do |return_val, query|
301
- query['pages'].each do |revid, _|
302
- return if revid == '-1'
303
- query['pages'][revid]['templates'].each { |template| return_val << template['title'] }
304
- end
223
+ pageid = query['pages'].keys.find { |id| id != '-1' }
224
+ return unless pageid
225
+ return_val.concat(query['pages'][pageid]['templates'].collect { |template| template['title'] })
305
226
  end
306
227
  end
307
228
 
@@ -319,12 +240,10 @@ module MediaWiki
319
240
  }
320
241
 
321
242
  query(params) do |return_val, query|
322
- query['pages'].each do |revid, _|
323
- return if revid == '-1'
324
- query['pages'][revid].fetch('iwlinks', []).each do |l|
325
- return_val << { prefix: l['prefix'], title: l['*'] }
326
- end
327
- end
243
+ pageid = query['pages'].keys.find { |id| id != '-1' }
244
+ return unless pageid
245
+ iwlinks = query['pages'][pageid].fetch('iwlinks', [])
246
+ return_val.concat(iwlinks.collect { |l| { prefix: l['prefix'], title: l['*']} })
328
247
  end
329
248
  end
330
249
 
@@ -344,16 +263,15 @@ module MediaWiki
344
263
  }
345
264
 
346
265
  query(params) do |return_val, query|
347
- query['pages'].each do |revid, _|
348
- return if revid == '-1'
349
- query['pages'][revid]['langlinks'].each do |l|
350
- return_val[l['lang'].to_sym] = {
351
- url: l['url'],
352
- langname: l['langname'],
353
- autonym: l['autonym'],
354
- title: l['*']
355
- }
356
- end
266
+ pageid = query['pages'].keys.find { |id| id != '-1' }
267
+ return unless pageid
268
+ query['pages'][pageid]['langlinks'].each do |l|
269
+ return_val[l['lang'].to_sym] = {
270
+ url: l['url'],
271
+ langname: l['langname'],
272
+ autonym: l['autonym'],
273
+ title: l['*']
274
+ }
357
275
  end
358
276
  end
359
277
  end
@@ -372,12 +290,54 @@ module MediaWiki
372
290
  }
373
291
 
374
292
  query(params) do |return_val, query|
375
- query['pages'].each do |revid, _|
376
- return if revid == '-1'
377
- query['pages'][revid]['links'].each { |l| return_val << l['title'] }
378
- end
293
+ pageid = query['pages'].keys.find { |id| id != '-1' }
294
+ return unless pageid
295
+ return_val.concat(query['pages'][pageid]['links'].collect { |l| l['title'] })
379
296
  end
380
297
  end
298
+
299
+ private
300
+
301
+ # Performs a query for the page info with the provided property.
302
+ # @param title [String] The page name
303
+ # @param inprop [String] The inprop to use. See the MediaWiki API documentation.
304
+ # @return (see #post)
305
+ def get_basic_page_info(title, inprop = nil)
306
+ params = {
307
+ action: 'query',
308
+ titles: title,
309
+ prop: 'info'
310
+ }
311
+ params[:inprop] = inprop if inprop
312
+
313
+ post(params)
314
+ end
315
+
316
+ # Performs a query for the page info with the provided property. Checks if the first non-missing page returned
317
+ # contains the provided key.
318
+ # @param title [String] The page name
319
+ # @param key [String] The key to check for
320
+ # @param inprop [String] The inprop to use. See the MediaWiki API documentation.
321
+ # @return [Nil] If the page is not found.
322
+ # @return [Boolean] If the page object contains the provided key.
323
+ def page_info_contains_key(title, key, inprop = nil)
324
+ response = get_basic_page_info(title, inprop)
325
+ pageid = response['query']['pages'].keys.find { |id| id != '-1' }
326
+ return unless pageid
327
+ response['query']['pages'][pageid].key?(key)
328
+ end
329
+
330
+ # Performs a query for the page info with the provided property, and returns a value by the provided key in
331
+ # the page's returned object.
332
+ # @param (see #page_info_contains_key)
333
+ # @return [Nil] If the page is not found.
334
+ # @return [Any] The returned value for the key.
335
+ def page_info_get_val(title, key, inprop = nil)
336
+ response = get_basic_page_info(title, inprop)
337
+ pageid = response['query']['pages'].keys.find { |id| id != '-1' }
338
+ return unless pageid
339
+ response['query']['pages'][pageid][key]
340
+ end
381
341
  end
382
342
  end
383
343
  end
@@ -36,17 +36,16 @@ module MediaWiki
36
36
  success_key = 'unwatched'
37
37
  end
38
38
 
39
- response = post(params)
40
- ret = {}
41
- response['watch'].each do |entry|
39
+ post(params)['watch'].inject({}) do |result, entry|
42
40
  title = entry['title']
43
41
  if entry.key?(success_key)
44
- ret[title] = entry.key?('missing') ? nil : true
42
+ result[title] = entry.key?('missing') ? nil : true
45
43
  else
46
- ret[title] = false
44
+ result[title] = false
47
45
  end
46
+
47
+ result
48
48
  end
49
- ret
50
49
  end
51
50
  end
52
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mediawiki-butt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eli Foster
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-09-10 00:00:00.000000000 Z
12
+ date: 2016-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httpclient