mediawiki-butt 0.11.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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',