mediawiki-butt 2.0.1 → 3.0.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 +4 -4
- data/CHANGELOG.md +14 -0
- data/lib/mediawiki/administration.rb +2 -2
- data/lib/mediawiki/auth.rb +19 -41
- data/lib/mediawiki/butt.rb +27 -30
- data/lib/mediawiki/edit.rb +6 -9
- data/lib/mediawiki/query/meta/meta.rb +27 -0
- data/lib/mediawiki/query/properties/properties.rb +0 -29
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7716798bbc8877e9a116dfde230ca4a4db7a9914
|
4
|
+
data.tar.gz: 75fa4f657ee01443634762697672f8142d0c9387
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af78a66c15e2ba113cbb140037d1ca1294aa740d93e5a089dc2881228a3c087cb293aaa61fa574441217afe295affe93a6aa35055ebd7f31921a1032b9bd270e
|
7
|
+
data.tar.gz: 45e1c4885a3cf8e7ba01523573d60899b246b03ec49471efd98e8911275ab84496190adba89037e80216d2dc39a10de2e43716d856e6d6d5a13bcc4883ba730f
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,18 @@
|
|
1
1
|
# Changelog
|
2
|
+
## Version 3
|
3
|
+
### Version 3.0.0
|
4
|
+
**Breaking changes!**
|
5
|
+
* Update token system for MediaWiki 1.27+ (#45, #46, #65, #67).
|
6
|
+
* `login` no longer takes a third `token` parameter.
|
7
|
+
* `create_account` no longer takes a fifth `token` parameter.
|
8
|
+
* `create_account_email` no longer takes a fifth `token` parameter.
|
9
|
+
* `MediaWiki::Query::Properties#get_token` has been replaced by `MediaWiki::Query::Meta#get_token`. This only takes one parameter, as opposed to the old method's two parameters, which is the type of token to receive. Valid types are verified in the `MediaWiki::Query::Meta::TOKEN_TYPES` array.
|
10
|
+
* Remove unnecessary `autoparse`, `header`, and `override_assertion` parameters from `post` (#68).
|
11
|
+
* The returned value is now always a parsed hash, never an HTTPMessage directly.
|
12
|
+
* Initialization parameter defaults are more likely what is to be used now (#62, #66).
|
13
|
+
* `:query_limit_default` is now defaulted to `'max'`.
|
14
|
+
* `:use_continuation` is now defaulted to `true`.
|
15
|
+
|
2
16
|
## Version 2
|
3
17
|
### Version 2.0.1
|
4
18
|
* Fix NoMethodError in `get_templates_in_page` when called for pages with no templates (#61)
|
@@ -17,7 +17,7 @@ module MediaWiki
|
|
17
17
|
expiry: expiry
|
18
18
|
}
|
19
19
|
|
20
|
-
token = get_token
|
20
|
+
token = get_token
|
21
21
|
params[:reason] = reason if reason
|
22
22
|
params[:nocreate] = '1' if nocreate
|
23
23
|
params[:token] = token
|
@@ -43,7 +43,7 @@ module MediaWiki
|
|
43
43
|
action: 'unblock',
|
44
44
|
user: user
|
45
45
|
}
|
46
|
-
token = get_token
|
46
|
+
token = get_token
|
47
47
|
params[:reason] = reason if reason
|
48
48
|
params[:token] = token
|
49
49
|
|
data/lib/mediawiki/auth.rb
CHANGED
@@ -5,34 +5,30 @@ module MediaWiki
|
|
5
5
|
# Logs the user into the wiki. This is generally required for editing and getting restricted data.
|
6
6
|
# @param username [String] The username
|
7
7
|
# @param password [String] The password
|
8
|
-
# @param token [String] The login token to use. Only set this if you know what you are doing. You probably want
|
9
|
-
# to just let the function get the token and set it on its own.
|
10
|
-
# @see #check_login
|
11
8
|
# @see https://www.mediawiki.org/wiki/API:Login MediaWiki Login API Docs
|
12
9
|
# @since 0.1.0
|
13
10
|
# @raise [AuthenticationError]
|
14
11
|
# @return [Boolean] True if the login was successful.
|
15
|
-
def login(username, password
|
12
|
+
def login(username, password)
|
13
|
+
# Save the assertion value while trying to log in, because otherwise the assertion will prevent us from logging in
|
14
|
+
assertion_value = @assertion.clone
|
15
|
+
@assertion = nil
|
16
|
+
|
16
17
|
params = {
|
17
18
|
action: 'login',
|
18
19
|
lgname: username,
|
19
|
-
lgpassword: password
|
20
|
+
lgpassword: password,
|
21
|
+
lgtoken: get_token('login')
|
20
22
|
}
|
21
|
-
params[:lgtoken] = token if token
|
22
|
-
header = {}
|
23
|
-
header['Set-Cookie'] = @cookie if @cookie
|
24
23
|
|
25
|
-
response = post(params
|
26
|
-
result = response['login']['result']
|
24
|
+
response = post(params)
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
26
|
+
@assertion = assertion_value
|
27
|
+
|
28
|
+
result = response['login']['result']
|
32
29
|
|
33
30
|
if result == 'Success'
|
34
|
-
@
|
35
|
-
@name = username
|
31
|
+
@name = response['login']['lgusername']
|
36
32
|
@logged_in = true
|
37
33
|
return true
|
38
34
|
end
|
@@ -50,7 +46,7 @@ module MediaWiki
|
|
50
46
|
action: 'logout'
|
51
47
|
}
|
52
48
|
|
53
|
-
post(params
|
49
|
+
post(params)
|
54
50
|
@logged_in = false
|
55
51
|
|
56
52
|
true
|
@@ -65,18 +61,16 @@ module MediaWiki
|
|
65
61
|
# @param language [String] The language code to be set as default for the account. Defaults to 'en', or English.
|
66
62
|
# Use the language code, not the name.
|
67
63
|
# @param reason [String] The reason for creating the account, as shown in the account creation log. Optional.
|
68
|
-
# @param token [String] The account creation token to use. Only set this if you know what you are doing. You
|
69
|
-
# probably want to just let the function get the token and set it on its own.
|
70
64
|
# @see #check_create
|
71
65
|
# @see https://www.mediawiki.org/wiki/API:Account_creation MediaWiki Account Creation Docs
|
72
66
|
# @since 0.1.0
|
73
67
|
# @return [Boolean] True if successful, false if not.
|
74
|
-
def create_account(username, password, language = 'en', reason = nil
|
68
|
+
def create_account(username, password, language = 'en', reason = nil)
|
75
69
|
params = {
|
76
70
|
name: username,
|
77
71
|
password: password,
|
78
72
|
language: language,
|
79
|
-
token:
|
73
|
+
token: get_token('createaccount')
|
80
74
|
}
|
81
75
|
params[:reason] = reason unless reason.nil?
|
82
76
|
|
@@ -85,15 +79,7 @@ module MediaWiki
|
|
85
79
|
raise MediaWiki::Butt::AuthenticationError.new(result['error']['code'])
|
86
80
|
end
|
87
81
|
|
88
|
-
|
89
|
-
@tokens.clear
|
90
|
-
|
91
|
-
return true
|
92
|
-
elsif result['createaccount']['result'] == 'NeedToken'
|
93
|
-
return create_account(username, password, language, reason, result['createaccount']['token'])
|
94
|
-
end
|
95
|
-
|
96
|
-
false
|
82
|
+
result['createaccount']['result'] == 'Success'
|
97
83
|
end
|
98
84
|
|
99
85
|
# Creates an account using the random password sent by email procedure.
|
@@ -103,13 +89,13 @@ module MediaWiki
|
|
103
89
|
# @see https://www.mediawiki.org/wiki/API:Account_creation MediaWiki Account Creation Docs
|
104
90
|
# @since 0.1.0
|
105
91
|
# @return [Boolean] True if successful, false if not.
|
106
|
-
def create_account_email(username, email, language = 'en', reason = nil
|
92
|
+
def create_account_email(username, email, language = 'en', reason = nil)
|
107
93
|
params = {
|
108
94
|
name: username,
|
109
95
|
email: email,
|
110
96
|
mailpassword: 'value',
|
111
97
|
language: language,
|
112
|
-
token:
|
98
|
+
token: get_token('createaccount')
|
113
99
|
}
|
114
100
|
params[:reason] = reason unless reason.nil?
|
115
101
|
|
@@ -118,15 +104,7 @@ module MediaWiki
|
|
118
104
|
raise MediaWiki::Butt::AuthenticationError.new(result['error']['code'])
|
119
105
|
end
|
120
106
|
|
121
|
-
|
122
|
-
@tokens.clear
|
123
|
-
|
124
|
-
return true
|
125
|
-
elsif result['createaccount']['result'] == 'NeedToken'
|
126
|
-
return create_account_email(username, email, language, reason, result['createaccount']['token'])
|
127
|
-
end
|
128
|
-
|
129
|
-
false
|
107
|
+
result['createaccount']['result'] == 'Success'
|
130
108
|
end
|
131
109
|
end
|
132
110
|
end
|
data/lib/mediawiki/butt.rb
CHANGED
@@ -34,56 +34,53 @@ module MediaWiki
|
|
34
34
|
# @option opts [String] :custom_agent A custom User-Agent to use. Optional.
|
35
35
|
# @option opts [Fixnum] :query_limit_default The query limit to use if no limit parameter is explicitly given to
|
36
36
|
# the various query methods. In other words, if you pass a limit parameter to the valid query methods, it will
|
37
|
-
# use that, otherwise, it will use this. Defaults to
|
38
|
-
#
|
39
|
-
# @option opts [Boolean] :use_continuation Whether to use the continuation API on queries.
|
37
|
+
# use that, otherwise, it will use this. Defaults to 'max' to use MW's default max for each API.
|
38
|
+
# @option opts [Boolean] :use_continuation Whether to use the continuation API on queries. Defaults to true.
|
40
39
|
# @option opts [Symbol] :assertion If set to :user or :bot, will use the assert parameter in all requests.
|
41
40
|
# Setting this will open up the possibility for NotLoggedInErrors and NotBotErrors. It is important to keep in
|
42
41
|
# mind that methods that check if the user is logged in do not use the API, but check if the user has *ever*
|
43
42
|
# logged in as this Butt instance. In other words, it is a safety check for performance and not a valid API check.
|
44
43
|
def initialize(url, opts = {})
|
45
44
|
@url = url =~ /api.php$/ ? url : "#{url}/api.php"
|
46
|
-
@query_limit_default = opts[:query_limit_default] ||
|
45
|
+
@query_limit_default = opts[:query_limit_default] || 'max'
|
47
46
|
@client = HTTPClient.new
|
48
47
|
@uri = URI.parse(@url)
|
49
48
|
@logged_in = false
|
50
49
|
@custom_agent = opts[:custom_agent]
|
51
|
-
@use_continuation = opts[:use_continuation]
|
50
|
+
@use_continuation = opts[:use_continuation] || true
|
52
51
|
|
53
52
|
assertion = opts[:assertion]
|
54
53
|
@assertion = assertion == :user || assertion == :bot ? assertion : nil
|
55
54
|
end
|
56
55
|
|
57
|
-
# Performs
|
56
|
+
# Performs an HTTP POST request and provides the response. This method generally should not be used by the
|
58
57
|
# user, unless there is not a helper method provided by Butt for a particular action.
|
59
|
-
# @param params [Hash] A
|
60
|
-
# information.
|
61
|
-
#
|
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.
|
58
|
+
# @param params [Hash] A hash containing MediaWiki API parameters. Please see the MediaWiki API for more
|
59
|
+
# information. The method automatically sets the format and assert values, unless they are specified in this
|
60
|
+
# hash argument.
|
65
61
|
# @since 0.1.0
|
66
|
-
# @return [Hash] Parsed JSON
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
header
|
74
|
-
|
75
|
-
|
76
|
-
|
62
|
+
# @return [Hash] Parsed JSON returned by the MediaWiki API
|
63
|
+
def post(params)
|
64
|
+
base_params = {
|
65
|
+
format: 'json'
|
66
|
+
}
|
67
|
+
base_params[:assert] = @assertion.to_s if @assertion
|
68
|
+
params = base_params.merge(params)
|
69
|
+
header = {}
|
70
|
+
if defined? @custom_agent
|
71
|
+
header['User-Agent'] = @custom_agent
|
72
|
+
else
|
73
|
+
header['User-Agent'] = @logged_in ? "#{@name}/MediaWiki::Butt" : 'NotLoggedIn/MediaWiki::Butt'
|
74
|
+
end
|
77
75
|
|
78
|
-
|
79
|
-
parsed = JSON.parse(res.body)
|
76
|
+
response = JSON.parse(@client.post(@uri, params, header).body)
|
80
77
|
|
81
|
-
if
|
82
|
-
code =
|
83
|
-
fail MediaWiki::Butt::NotLoggedInError.new(
|
84
|
-
fail MediaWiki::Butt::NotBotError.new(
|
78
|
+
if @assertion
|
79
|
+
code = response.dig('error', 'code')
|
80
|
+
fail MediaWiki::Butt::NotLoggedInError.new(response['error']['info']) if code == 'assertuserfailed'
|
81
|
+
fail MediaWiki::Butt::NotBotError.new(response['error']['info']) if code == 'assertbotfailed'
|
85
82
|
end
|
86
|
-
|
83
|
+
response
|
87
84
|
end
|
88
85
|
|
89
86
|
# Performs a Mediawiki API query and provides the response, dealing with continuation as necessary.
|
data/lib/mediawiki/edit.rb
CHANGED
@@ -24,7 +24,7 @@ module MediaWiki
|
|
24
24
|
text: text,
|
25
25
|
nocreate: 1,
|
26
26
|
format: 'json',
|
27
|
-
token: get_token
|
27
|
+
token: get_token
|
28
28
|
}
|
29
29
|
|
30
30
|
params[:summary] ||= opts[:summary]
|
@@ -63,7 +63,7 @@ module MediaWiki
|
|
63
63
|
summary: opts[:summary],
|
64
64
|
createonly: 1,
|
65
65
|
format: 'json',
|
66
|
-
token: get_token
|
66
|
+
token: get_token
|
67
67
|
}
|
68
68
|
|
69
69
|
params[:bot] = '1' if opts[:bot]
|
@@ -90,7 +90,7 @@ module MediaWiki
|
|
90
90
|
params = {
|
91
91
|
action: 'upload',
|
92
92
|
url: url,
|
93
|
-
|
93
|
+
token: get_token
|
94
94
|
}
|
95
95
|
|
96
96
|
filename = filename.nil? ? url.split('/')[-1] : filename.sub(/^File:/, '')
|
@@ -99,9 +99,7 @@ module MediaWiki
|
|
99
99
|
allowed_extensions = get_allowed_file_extensions
|
100
100
|
raise MediaWiki::Butt::UploadInvalidFileExtError.new unless allowed_extensions.include?(ext)
|
101
101
|
|
102
|
-
token = get_token('edit', filename)
|
103
102
|
params[:filename] = filename
|
104
|
-
params[:token] = token
|
105
103
|
|
106
104
|
response = post(params)
|
107
105
|
|
@@ -133,7 +131,7 @@ module MediaWiki
|
|
133
131
|
action: 'move',
|
134
132
|
from: from,
|
135
133
|
to: to,
|
136
|
-
token: get_token
|
134
|
+
token: get_token
|
137
135
|
}
|
138
136
|
|
139
137
|
params[:reason] ||= opts[:reason]
|
@@ -158,12 +156,11 @@ module MediaWiki
|
|
158
156
|
def delete(title, reason = nil)
|
159
157
|
params = {
|
160
158
|
action: 'delete',
|
161
|
-
title: title
|
159
|
+
title: title,
|
160
|
+
token: get_token
|
162
161
|
}
|
163
162
|
|
164
|
-
token = get_token('delete', title)
|
165
163
|
params[:reason] = reason unless reason.nil?
|
166
|
-
params[:token] = token
|
167
164
|
|
168
165
|
response = post(params)
|
169
166
|
return true if response['delete']
|
@@ -8,6 +8,33 @@ module MediaWiki
|
|
8
8
|
include MediaWiki::Query::Meta::UserInfo
|
9
9
|
include MediaWiki::Query::Meta::FileRepoInfo
|
10
10
|
include MediaWiki::Query::Meta::UserInfo
|
11
|
+
|
12
|
+
# All valid types of tokens. Taken from API:Tokens on MediaWiki.
|
13
|
+
TOKEN_TYPES = %w(csrf watch patrol rollback userrights login createaccount)
|
14
|
+
|
15
|
+
# Obtains a token for the current user (or lack thereof) for specific actions. This uses the functionality
|
16
|
+
# introduced in MediaWiki 1.27
|
17
|
+
# @param type [String, Array<String>] The type of token to get. See #TOKEN_TYPES to see the valid types. If it
|
18
|
+
# is invalid, it will default to 'csrf'. If it is an array, it will join by a pipe for the API.
|
19
|
+
# @return [String, Hash<String => String>] Either a token or a set of tokens organized by type. If multiple
|
20
|
+
# valid types are provided in the parameter, it returns a hash identical to the API response (see API docs).
|
21
|
+
def get_token(type = 'csrf')
|
22
|
+
params = {
|
23
|
+
action: 'query',
|
24
|
+
meta: 'tokens'
|
25
|
+
}
|
26
|
+
|
27
|
+
if type.is_a?(Array)
|
28
|
+
type = (type - TOKEN_TYPES).empty? ? type.join('|') : 'csrf'
|
29
|
+
else
|
30
|
+
type = TOKEN_TYPES.include?(type) ? type : 'csrf'
|
31
|
+
end
|
32
|
+
params[:type] = type
|
33
|
+
|
34
|
+
resp = post(params)
|
35
|
+
tokens = resp['query']['tokens']
|
36
|
+
tokens.size > 1 ? tokens : tokens["#{type}token"]
|
37
|
+
end
|
11
38
|
end
|
12
39
|
end
|
13
40
|
end
|
@@ -8,35 +8,6 @@ module MediaWiki
|
|
8
8
|
include MediaWiki::Query::Properties::Contributors
|
9
9
|
include MediaWiki::Query::Properties::Pages
|
10
10
|
include MediaWiki::Query::Properties::Files
|
11
|
-
|
12
|
-
# Gets the token for the given type. This method should rarely be used by normal users.
|
13
|
-
# @param type [String] The type of token.
|
14
|
-
# @param title [String] The page title for the token. Optional.
|
15
|
-
# @see https://www.mediawiki.org/wiki/API:Info MediaWiki Info API Docs
|
16
|
-
# @since 0.5.0
|
17
|
-
# @return [String] The token. If the butt isn't logged in, it returns with '+\\'.
|
18
|
-
def get_token(type, title = nil)
|
19
|
-
return '+\\' unless @logged_in
|
20
|
-
|
21
|
-
# There is some weird thing with MediaWiki where you must pass a valid inprop parameter in order to get any
|
22
|
-
# response at all. This is why there is a displaytitle inprop as well as gibberish in the titles parameter.
|
23
|
-
# And to avoid normalization, it's capitalized.
|
24
|
-
params = {
|
25
|
-
action: 'query',
|
26
|
-
prop: 'info',
|
27
|
-
inprop: 'displaytitle',
|
28
|
-
intoken: type
|
29
|
-
}
|
30
|
-
|
31
|
-
title = 'Somegibberish' if title.nil?
|
32
|
-
params[:titles] = title
|
33
|
-
response = post(params)
|
34
|
-
revid = nil
|
35
|
-
response['query']['pages'].each { |r, _| revid = r }
|
36
|
-
|
37
|
-
# URL encoding is not needed for some reason.
|
38
|
-
response['query']['pages'][revid]["#{type}token"]
|
39
|
-
end
|
40
11
|
end
|
41
12
|
end
|
42
13
|
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:
|
4
|
+
version: 3.0.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: 2017-
|
12
|
+
date: 2017-10-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httpclient
|