mediawiki-butt 0.11.1 → 1.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -5
  3. data/lib/mediawiki/administration.rb +18 -17
  4. data/lib/mediawiki/auth.rb +52 -193
  5. data/lib/mediawiki/butt.rb +51 -32
  6. data/lib/mediawiki/constants.rb +127 -130
  7. data/lib/mediawiki/edit.rb +58 -71
  8. data/lib/mediawiki/exceptions.rb +2 -123
  9. data/lib/mediawiki/query/lists/all.rb +35 -45
  10. data/lib/mediawiki/query/lists/backlinks.rb +23 -34
  11. data/lib/mediawiki/query/lists/categories.rb +17 -28
  12. data/lib/mediawiki/query/lists/log/block.rb +17 -33
  13. data/lib/mediawiki/query/lists/log/delete.rb +8 -24
  14. data/lib/mediawiki/query/lists/log/import.rb +9 -24
  15. data/lib/mediawiki/query/lists/log/log.rb +36 -63
  16. data/lib/mediawiki/query/lists/log/merge.rb +5 -12
  17. data/lib/mediawiki/query/lists/log/move.rb +6 -20
  18. data/lib/mediawiki/query/lists/log/newusers.rb +13 -36
  19. data/lib/mediawiki/query/lists/log/patrol.rb +5 -13
  20. data/lib/mediawiki/query/lists/log/protect.rb +20 -50
  21. data/lib/mediawiki/query/lists/log/rights.rb +10 -24
  22. data/lib/mediawiki/query/lists/log/upload.rb +10 -24
  23. data/lib/mediawiki/query/lists/miscellaneous.rb +10 -19
  24. data/lib/mediawiki/query/lists/querypage.rb +60 -62
  25. data/lib/mediawiki/query/lists/recent_changes.rb +18 -30
  26. data/lib/mediawiki/query/lists/search.rb +14 -29
  27. data/lib/mediawiki/query/lists/users.rb +43 -61
  28. data/lib/mediawiki/query/meta/filerepoinfo.rb +18 -20
  29. data/lib/mediawiki/query/meta/siteinfo.rb +30 -33
  30. data/lib/mediawiki/query/meta/userinfo.rb +48 -66
  31. data/lib/mediawiki/query/properties/contributors.rb +18 -22
  32. data/lib/mediawiki/query/properties/files.rb +18 -20
  33. data/lib/mediawiki/query/properties/pages.rb +129 -211
  34. data/lib/mediawiki/query/properties/properties.rb +20 -25
  35. data/lib/mediawiki/query/query.rb +0 -25
  36. data/lib/mediawiki/utils.rb +9 -8
  37. data/lib/mediawiki/watch.rb +52 -0
  38. metadata +6 -4
@@ -1,18 +1,21 @@
1
+ require_relative 'exceptions'
2
+
1
3
  module MediaWiki
2
4
  module Edit
3
5
  # Performs a standard non-creation edit.
4
6
  # @param title [String] The page title.
5
7
  # @param text [String] The new content.
6
8
  # @param minor [Boolean] Will mark the edit as minor if true.
7
- # Defaults to false.
8
- # @param bot [Boolean] Will mark the edit as bot edit if true.
9
- # Defualts to true, for your convenience, bot developers.
9
+ # @param bot [Boolean] Will mark the edit as bot edit if true. Defaults to true, for your convenience, bot
10
+ # developers.
10
11
  # @param summary [String] The edit summary. Optional.
11
- # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing
12
- # wiki content on the MediaWiki API documentation
12
+ # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing wiki content on the MediaWiki API
13
+ # documentation
13
14
  # @see https://www.mediawiki.org/wiki/API:Edit MediaWiki Edit API Docs
14
15
  # @since 0.2.0
15
- # @return [String] The new revision ID, or if it failed, the error code.
16
+ # @raise [EditError] if the edit failed somehow
17
+ # @return [String] The new revision ID
18
+ # @return [Boolean] False if there was no change in the edit.
16
19
  def edit(title, text, minor = false, bot = true, summary = nil)
17
20
  params = {
18
21
  action: 'edit',
@@ -31,24 +34,26 @@ module MediaWiki
31
34
 
32
35
  response = post(params)
33
36
 
34
- if response['edit']['result'] == 'Success'
35
- return response['edit']['newrevid']
36
- else
37
- return response['error']['code']
37
+ if response.dig('edit', 'result') == 'Success'
38
+ return false if response.dig('edit', 'nochange')
39
+ return response.dig('edit', 'newrevid')
38
40
  end
41
+
42
+ raise MediaWiki::Butt::EditError.new(response.dig('error', 'code') || 'Unknown error code')
39
43
  end
40
44
 
41
45
  # Creates a new page.
42
46
  # @param title [String] The new page's title.
43
47
  # @param text [String] The new page's content.
44
- # @param summary [String] The edit summary. Defaults to 'New page'.
45
- # @param bot [Boolean] Will mark the edit as a bot edit if true.
46
- # Defaults to true, for your convenience, bot developers.
47
- # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing
48
- # wiki content on the MediaWiki API documentation
48
+ # @param summary [String] The edit summary.
49
+ # @param bot [Boolean] Will mark the edit as a bot edit if true. Defaults to true, for your convenience, bot
50
+ # developers.
51
+ # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing wiki content on the MediaWiki API
52
+ # documentation
49
53
  # @see https://www.mediawiki.org/wiki/API:Edit MediaWiki Edit API Docs
50
54
  # @since 0.3.0
51
- # @return [String] The new page ID, or if it failed, the error code.
55
+ # @raise [EditError] If there was some error when creating the page.
56
+ # @return [String] The new page ID
52
57
  def create_page(title, text, summary = 'New page', bot = true)
53
58
  params = {
54
59
  action: 'edit',
@@ -66,26 +71,21 @@ module MediaWiki
66
71
 
67
72
  response = post(params)
68
73
 
69
- if response['edit']['result'] == 'Success'
70
- return response['edit']['pageid']
71
- else
72
- return response['error']['code']
73
- end
74
+ return response['edit']['pageid'] if response.dig('edit', 'result') == 'Success'
75
+ raise MediaWiki::Butt::EditError.new(response.dig('error', 'code') || 'Unknown error code')
74
76
  end
75
77
 
76
78
  # Uploads a file from a URL.
77
79
  # @param url [String] The URL to the file.
78
- # @param filename [String] The preferred filename.
79
- # This can include File: at the beginning, but it will be removed
80
- # through regex. Optional. If ommitted, it will be everything after
81
- # the last slash in the URL.
82
- # @return [Boolean] True if the upload was successful, false if the
83
- # file extension is not valid.
84
- # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing
85
- # wiki content on the MediaWiki API documentation
80
+ # @param filename [String] The preferred filename. This can include File: at the beginning, but it will be
81
+ # removed through regex. Optional. If omitted, it will be everything after the last slash in the URL.
82
+ # @return [Boolean] True if the upload was successful, false if the file extension is not valid.
83
+ # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing wiki content on the MediaWiki API
84
+ # documentation
86
85
  # @see https://www.mediawiki.org/wiki/API:Upload MediaWiki Upload API Docs
87
86
  # @since 0.3.0
88
- # @return [String] The warning's key if it was unsuccessful.
87
+ # @return [Boolean] Whether the upload was successful. It is likely that if it returns false, it also raised a
88
+ # warning.
89
89
  def upload(url, filename = nil)
90
90
  params = {
91
91
  action: 'upload',
@@ -93,45 +93,37 @@ module MediaWiki
93
93
  format: 'json'
94
94
  }
95
95
 
96
- if filename.nil?
97
- filename = url.split('/')[-1]
98
- else
99
- filename = filename.sub(/^File:/, '')
100
- end
96
+ filename = filename.nil? ? url.split('/')[-1] : filename.sub(/^File:/, '')
101
97
 
102
98
  ext = filename.split('.')[-1]
103
99
  allowed_extensions = get_allowed_file_extensions
104
- if allowed_extensions.include? ext
105
-
106
- token = get_token('edit', filename)
107
- params[:filename] = filename
108
- params[:token] = token
109
-
110
- response = post(params)
111
- if response['upload']['result'] == 'Success'
112
- return true
113
- elsif response['upload']['result'] == 'Warning'
114
- return response['upload']['warnings'].keys[0]
115
- end
116
- else
117
- return false
100
+ return false unless allowed_extensions.include?(ext)
101
+
102
+ token = get_token('edit', filename)
103
+ params[:filename] = filename
104
+ params[:token] = token
105
+
106
+ response = post(params)
107
+
108
+ response.dig('upload', 'warnings')&.each do |warning|
109
+ warn warning
118
110
  end
111
+
112
+ response.dig('upload', 'result') == 'Success'
119
113
  end
120
114
 
121
115
  # Performs a move on a page.
122
116
  # @param from [String] The page to be moved.
123
117
  # @param to [String] The destination of the move.
124
- # @param reason [String] The reason for the move, which shows up in the log.
125
- # Optionl.
118
+ # @param reason [String] The reason for the move, which shows up in the log. Optional.
126
119
  # @param talk [Boolean] Whether to move the associated talk page.
127
- # Defaults to true.
128
- # @param redirect [Boolean] Whether to create a redirect. Defaults to false.
129
- # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing
130
- # wiki content on the MediaWiki API documentation
120
+ # @param redirect [Boolean] Whether to create a redirect.
121
+ # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing wiki content on the MediaWiki API
122
+ # documentation
131
123
  # @see https://www.mediawiki.org/wiki/API:Move MediaWiki Move API Docs
132
124
  # @since 0.5.0
125
+ # @raise [EditError]
133
126
  # @return [Boolean] True if it was successful.
134
- # @return [String] The error code if it was unsuccessful.
135
127
  def move(from, to, reason = nil, talk = true, redirect = false)
136
128
  params = {
137
129
  action: 'move',
@@ -141,27 +133,25 @@ module MediaWiki
141
133
 
142
134
  token = get_token('move', from)
143
135
  params[:reason] = reason unless reason.nil?
144
- params[:movetalk] = '1' if talk == true
145
- params[:noredirect] = '1' if redirect == false
136
+ params[:movetalk] = '1' if talk
137
+ params[:noredirect] = '1' if redirect
146
138
  params[:token] = token
147
139
 
148
140
  response = post(params)
149
- if !response['move'].nil?
150
- return true
151
- else
152
- return response['error']['code']
153
- end
141
+
142
+ return true if response['move']
143
+ raise MediaWiki::Butt::EditError.new(response.dig('error', 'code') || 'Unknown error code')
154
144
  end
155
145
 
156
146
  # Deletes a page.
157
147
  # @param title [String] The page to delete.
158
148
  # @param reason [String] The reason to be displayed in logs. Optional.
159
- # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing
160
- # wiki content on the MediaWiki API documentation
149
+ # @see https://www.mediawiki.org/wiki/API:Changing_wiki_content Changing wiki content on the MediaWiki API
150
+ # documentation
161
151
  # @see https://www.mediawiki.org/wiki/API:Delete MediaWiki Delete API Docs
162
152
  # @since 0.5.0
153
+ # @raise [EditError]
163
154
  # @return [Boolean] True if successful.
164
- # @return [String] The error code if it was not successful.
165
155
  def delete(title, reason = nil)
166
156
  params = {
167
157
  action: 'delete',
@@ -173,11 +163,8 @@ module MediaWiki
173
163
  params[:token] = token
174
164
 
175
165
  response = post(params)
176
- if !response['delete'].nil?
177
- return true
178
- else
179
- return response['error']['code']
180
- end
166
+ return true if response['delete']
167
+ raise MediaWiki::Butt::EditError.new(response.dig('error', 'code') || 'Unknown error code')
181
168
  end
182
169
  end
183
170
  end
@@ -1,128 +1,7 @@
1
1
  module MediaWiki
2
2
  class Butt
3
3
  class AuthenticationError < StandardError; end
4
-
5
- class NeedTokenMoreThanOnceError < AuthenticationError
6
- def message
7
- 'You tried to get the token more than once. You likely have some' \
8
- 'problem with your login call.'
9
- end
10
- end
11
-
12
- class NoNameError < AuthenticationError
13
- def message
14
- 'You did not set the lgname parameter.'
15
- end
16
- end
17
-
18
- class IllegalUsernameError < AuthenticationError
19
- def message
20
- 'You provided an illegal username.'
21
- end
22
- end
23
-
24
- class UsernameNotExistsError < AuthenticationError
25
- def message
26
- 'You provided a username that does not exist.'
27
- end
28
- end
29
-
30
- class EmptyPassError < AuthenticationError
31
- def message
32
- 'You did not set the lgpassword paremeter.'
33
- end
34
- end
35
-
36
- class WrongPassError < AuthenticationError
37
- def message
38
- 'The password you provided is not correct.'
39
- end
40
- end
41
-
42
- class WrongPluginPassError < AuthenticationError
43
- def message
44
- 'A plugin (not MediaWiki) claims your password is not correct.'
45
- end
46
- end
47
-
48
- class CreateBlockedError < AuthenticationError
49
- def message
50
- 'MediaWiki tried to automatically create an account for you, but your' \
51
- 'IP is blocked from account creation.'
52
- end
53
- end
54
-
55
- class ThrottledError < AuthenticationError
56
- def message
57
- 'You\'ve logged in too many times.'
58
- end
59
- end
60
-
61
- class BlockedError < AuthenticationError
62
- def message
63
- 'User is blocked.'
64
- end
65
- end
66
-
67
- # Start creation-specific errors
68
- class UserExistsError < AuthenticationError
69
- def message
70
- 'Username entered is already in use.'
71
- end
72
- end
73
-
74
- class UserPassMatchError < AuthenticationError
75
- def message
76
- 'Your password must be different from your username.'
77
- end
78
- end
79
-
80
- class PasswordLoginForbiddenError < AuthenticationError
81
- def message
82
- 'The use of this username and password has been forbidden.'
83
- end
84
- end
85
-
86
- class NoEmailTitleError < AuthenticationError
87
- def message
88
- 'No email address.'
89
- end
90
- end
91
-
92
- class InvalidEmailAddressError < AuthenticationError
93
- def message
94
- 'The email address is invalid.'
95
- end
96
- end
97
-
98
- class PasswordTooShortError < AuthenticationError
99
- def message
100
- 'The password was shorter than the value of $wgMinimalPasswordLength'
101
- end
102
- end
103
-
104
- class NoEmailError < AuthenticationError
105
- def message
106
- 'There is no email address recorded for the user.'
107
- end
108
- end
109
-
110
- class AbortedError < AuthenticationError
111
- def message
112
- 'Aborted by an extension.'
113
- end
114
- end
115
-
116
- class PermDeniedError < AuthenticationError
117
- def message
118
- 'You do not have the right to make an account.'
119
- end
120
- end
121
-
122
- class HookAbortedError < AuthenticationError
123
- def message
124
- 'An extension aborted the account creation.'
125
- end
126
- end
4
+ class EditError < StandardError; end
5
+ class BlockError < StandardError; end
127
6
  end
128
7
  end
@@ -3,14 +3,12 @@ module MediaWiki
3
3
  module Lists
4
4
  module All
5
5
  # Gets all categories on the entire wiki.
6
- # @param limit [Int] The maximum number of categories to get. Defaults
7
- # to 500. Cannot be greater than 500 for normal users, or 5000 for
8
- # bots.
9
- # @see https://www.mediawiki.org/wiki/API:Allcategories MediaWiki
10
- # Allcategories API Docs
6
+ # @param limit [Fixnum] The maximum number of categories to get. Cannot be greater than 500 for users or 5000
7
+ # for bots.
8
+ # @see https://www.mediawiki.org/wiki/API:Allcategories MediaWiki Allcategories API Docs
11
9
  # @since 0.7.0
12
- # @return [Array] An array of all categories.
13
- def get_all_categories(limit = 500)
10
+ # @return [Array<String>] An array of all categories.
11
+ def get_all_categories(limit = @query_limit_default)
14
12
  params = {
15
13
  action: 'query',
16
14
  list: 'allcategories',
@@ -26,13 +24,11 @@ module MediaWiki
26
24
  end
27
25
 
28
26
  # Gets all the images on the wiki.
29
- # @param limit [Int] The maximum number of images to get. Defaults to
30
- # 500. Cannot be greater than 500 for normal users, or 5000 for bots.
31
- # @see https://www.mediawiki.org/wiki/API:Allimages MediaWiki Allimages
32
- # API Docs
27
+ # @param (see #get_all_categories)
28
+ # @see https://www.mediawiki.org/wiki/API:Allimages MediaWiki Allimages API Docs
33
29
  # @since 0.7.0
34
- # @return [Array] An array of all images.
35
- def get_all_images(limit = 500)
30
+ # @return [Array<String>] An array of all images.
31
+ def get_all_images(limit = @query_limit_default)
36
32
  params = {
37
33
  action: 'query',
38
34
  list: 'allimages',
@@ -48,13 +44,12 @@ module MediaWiki
48
44
  end
49
45
 
50
46
  # Gets all pages within a namespace integer.
51
- # @param namespace [Int] The namespace ID.
52
- # @param limit [Int] See #get_all_images
53
- # @see https://www.mediawiki.org/wiki/API:Allpages MediaWiki Allpages
54
- # API Docs
47
+ # @param namespace [Fixnum] The namespace ID.
48
+ # @param (see #get_all_categories)
49
+ # @see https://www.mediawiki.org/wiki/API:Allpages MediaWiki Allpages API Docs
55
50
  # @since 0.8.0
56
- # @return [Array] An array of all page titles.
57
- def get_all_pages_in_namespace(namespace, limit = 500)
51
+ # @return [Array<String>] An array of all page titles.
52
+ def get_all_pages_in_namespace(namespace, limit = @query_limit_default)
58
53
  params = {
59
54
  action: 'query',
60
55
  list: 'allpages',
@@ -72,12 +67,11 @@ module MediaWiki
72
67
 
73
68
  # Gets all users, or all users in a group.
74
69
  # @param group [String] The group to limit this query to.
75
- # @param limit [Int] See #get_all_images.
76
- # @see https://www.mediawiki.org/wiki/API:Allusers MediaWiki Allusers
77
- # API Docs
70
+ # @param (see #get_all_categories)
71
+ # @see https://www.mediawiki.org/wiki/API:Allusers MediaWiki Allusers API Docs
78
72
  # @since 0.8.0
79
- # @return [Hash] A hash of all users, names are keys, IDs are values.
80
- def get_all_users(group = nil, limit = 500)
73
+ # @return [Hash<String, Fixnum>] A hash of all users, names are keys, IDs are values.
74
+ def get_all_users(group = nil, limit = @query_limit_default)
81
75
  params = {
82
76
  action: 'query',
83
77
  list: 'allusers',
@@ -93,13 +87,13 @@ module MediaWiki
93
87
  ret
94
88
  end
95
89
 
96
- # Gets all block IDs on the wiki. It seems like this only gets non-IP
97
- # blocks, but the MediaWiki docs are a bit unclear.
98
- # @param limit [Int] See #get_all_images.
90
+ # Gets all block IDs on the wiki. It seems like this only gets non-IP blocks, but the MediaWiki docs are a
91
+ # bit unclear.
92
+ # @param (see #get_all_categories)
99
93
  # @see https://www.mediawiki.org/wiki/API:Blocks MediaWiki Blocks API Docs
100
94
  # @since 0.8.0
101
- # @return [Array] All block IDs as strings.
102
- def get_all_blocks(limit = 500)
95
+ # @return [Array<Fixnum>] All block IDs as strings.
96
+ def get_all_blocks(limit = @query_limit_default)
103
97
  params = {
104
98
  action: 'query',
105
99
  list: 'blocks',
@@ -117,12 +111,11 @@ module MediaWiki
117
111
 
118
112
  # Gets all page titles that transclude a given page.
119
113
  # @param page [String] The page name.
120
- # @param limit [Int] See #get_all_images.
121
- # @see https://www.mediawiki.org/wiki/API:Embeddedin MediaWiki Embeddedin
122
- # API Docs
114
+ # @param (see #get_all_categories)
115
+ # @see https://www.mediawiki.org/wiki/API:Embeddedin MediaWiki Embeddedin API Docs
123
116
  # @since 0.8.0
124
- # @return [Array] All transcluder page titles.
125
- def get_all_transcluders(page, limit = 500)
117
+ # @return [Array<String>] All transcluder page titles.
118
+ def get_all_transcluders(page, limit = @query_limit_default)
126
119
  params = {
127
120
  action: 'query',
128
121
  list: 'embeddedin',
@@ -139,13 +132,11 @@ module MediaWiki
139
132
  end
140
133
 
141
134
  # Gets an array of all deleted or archived files on the wiki.
142
- # @param limit [Int] See #get_all_images
143
- # @see https://www.mediawiki.org/wiki/API:Filearchive MediaWiki
144
- # Filearchive API Docs
135
+ # @param (see #get_all_categories)
136
+ # @see https://www.mediawiki.org/wiki/API:Filearchive MediaWiki Filearchive API Docs
145
137
  # @since 0.8.0
146
- # @return [Array] All deleted file names. These are not titles, so they do
147
- # not include "File:".
148
- def get_all_deleted_files(limit = 500)
138
+ # @return [Array<String>] All deleted file names. These are not titles, so they do not include "File:".
139
+ def get_all_deleted_files(limit = @query_limit_default)
149
140
  params = {
150
141
  action: 'query',
151
142
  list: 'filearchive',
@@ -162,12 +153,11 @@ module MediaWiki
162
153
 
163
154
  # Gets a list of all protected pages, by protection level if provided.
164
155
  # @param protection_level [String] The protection level, e.g., sysop
165
- # @param limit [Int] See #get_all_images.
166
- # @see https://www.mediawiki.org/wiki/API:Protectedtitles MediaWiki
167
- # Protectedtitles API Docs
156
+ # @param (see #get_all_categories)
157
+ # @see https://www.mediawiki.org/wiki/API:Protectedtitles MediaWiki Protectedtitles API Docs
168
158
  # @since 0.8.0
169
- # @return [Array] All protected page titles.
170
- def get_all_protected_titles(protection_level = nil, limit = 500)
159
+ # @return [Array<String>] All protected page titles.
160
+ def get_all_protected_titles(protection_level = nil, limit = @query_limit_default)
171
161
  params = {
172
162
  action: 'query',
173
163
  list: 'protectedtitles',