mediawiki-gateway 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile +3 -0
- data/Gemfile.lock +12 -0
- data/{README → README.md} +18 -14
- data/Rakefile +3 -4
- data/lib/media_wiki.rb +1 -1
- data/lib/media_wiki/gateway.rb +251 -173
- data/lib/media_wiki/utils.rb +1 -1
- data/mediawiki-gateway.gemspec +14 -5
- data/spec/fake_media_wiki/api_pages.rb +3 -3
- data/spec/gateway_spec.rb +20 -18
- data/spec/spec_helper.rb +11 -6
- metadata +47 -5
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZjkxNDFhNzdhOGU1ZjU2YjIwNjA5YmI5MDQzYTg3YjBjZjMwNWI1Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OWE3MjhiNjU1N2I2NzE4NWRmMGZmNmI0MGYyYmZhNTI5NjkyYmY5Ng==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDRhMGVkZGM3ODI4MDg4MTRhNDU0NDU1YzdmZDhkZTBmNjhhZjg4NTE2ZGMy
|
10
|
+
ZjE0MGE5NTQ5NTFmOTU0ODEyODE4MTUzMjE0ODM5ODcxZDkxZDQ0MGE0NTBh
|
11
|
+
NzM1N2UxOGRlNDJmMzkyYzk1ODg5ODlhNjQyYjUxYmQyMTdjY2M=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MTI4N2Q2Y2Q2ZmYzNjdhMjBmNGQ5MzcwNzczMzRhYzdjMDNkNWIyYjNiYmU0
|
14
|
+
OTRiZjkzMzVkOWFkNzliOTI3OTdmYjg3MjMzMjRmOTY4ZWQxMjU0ZGYzZDEy
|
15
|
+
ZWY4NTQ3OTdlNWQxY2ViZjkyZWMyM2U0YmJiZDFlMTAzMTE1M2I=
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -16,6 +16,7 @@ GEM
|
|
16
16
|
debugger-ruby_core_source (~> 1.2.3)
|
17
17
|
debugger-linecache (1.2.0)
|
18
18
|
debugger-ruby_core_source (1.2.3)
|
19
|
+
diff-lcs (1.2.5)
|
19
20
|
git (1.2.5)
|
20
21
|
i18n (0.6.0)
|
21
22
|
jeweler (1.8.4)
|
@@ -36,6 +37,14 @@ GEM
|
|
36
37
|
mime-types (>= 1.16)
|
37
38
|
rr (1.0.4)
|
38
39
|
rspec (1.3.2)
|
40
|
+
rspec-core (3.0.3)
|
41
|
+
rspec-support (~> 3.0.0)
|
42
|
+
rspec-expectations (3.0.3)
|
43
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
44
|
+
rspec-support (~> 3.0.0)
|
45
|
+
rspec-mocks (3.0.3)
|
46
|
+
rspec-support (~> 3.0.0)
|
47
|
+
rspec-support (3.0.3)
|
39
48
|
sham_rack (1.3.4)
|
40
49
|
rack
|
41
50
|
simplecov (0.6.4)
|
@@ -60,6 +69,9 @@ DEPENDENCIES
|
|
60
69
|
rest-client (>= 1.3.0)
|
61
70
|
rr
|
62
71
|
rspec (~> 1.3)
|
72
|
+
rspec-core
|
73
|
+
rspec-expectations
|
74
|
+
rspec-mocks
|
63
75
|
sham_rack
|
64
76
|
simplecov
|
65
77
|
sinatra
|
data/{README → README.md}
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# MediaWiki::Gateway
|
2
2
|
|
3
3
|
A Ruby framework for MediaWiki API manipulation. Features out of the box:
|
4
4
|
|
@@ -11,36 +11,40 @@ A Ruby framework for MediaWiki API manipulation. Features out of the box:
|
|
11
11
|
* Should work with both Ruby 1.8 and 1.9
|
12
12
|
|
13
13
|
Gem: http://rubygems.org/gems/mediawiki-gateway
|
14
|
+
|
14
15
|
RDoc: http://rubydoc.info/gems/mediawiki-gateway
|
16
|
+
|
15
17
|
Git: https://github.com/jpatokal/mediawiki-gateway
|
16
18
|
|
17
|
-
|
19
|
+
## Example
|
18
20
|
|
19
21
|
Simple page creation script:
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
require 'media_wiki'
|
24
|
+
mw = MediaWiki::Gateway.new('http://my-wiki.example/w/api.php')
|
25
|
+
mw.login('RubyBot', 'pa$$w0rd')
|
26
|
+
mw.create('PageTitle', 'Hello world!', :summary => 'My first page')
|
25
27
|
|
26
|
-
|
28
|
+
## Development environment
|
27
29
|
|
28
30
|
To compile and test MediaWiki::Gateway locally, Bundler and Ruby 1.9+ are expected.
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
+
rvm install 1.9.3-p194
|
33
|
+
bundle install
|
32
34
|
|
33
35
|
This will list the available options:
|
34
|
-
|
36
|
+
|
37
|
+
bundle exec rake -T
|
35
38
|
|
36
39
|
To build and install the gem use:
|
37
|
-
bundle exec rake install
|
38
40
|
|
39
|
-
|
41
|
+
bundle exec rake install
|
42
|
+
|
43
|
+
## Status
|
40
44
|
|
41
|
-
This gem is no longer in active development.
|
45
|
+
This gem is no longer in active development. Pull requests that fix bugs or add new features are more than welcome, but asking for new features is unlikely to make them materialize out of thin air.
|
42
46
|
|
43
|
-
|
47
|
+
## Credits
|
44
48
|
|
45
49
|
Maintained by Jani Patokallio.
|
46
50
|
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'thread'
|
|
2
2
|
require 'rake'
|
3
3
|
require "rubygems/package_task"
|
4
4
|
require 'rdoc/task'
|
5
|
-
require '
|
5
|
+
require 'rspec/core/rake_task'
|
6
6
|
require_relative 'lib/media_wiki'
|
7
7
|
|
8
8
|
task :default => ['spec']
|
@@ -19,9 +19,8 @@ RDoc::Task.new do |rd|
|
|
19
19
|
end
|
20
20
|
|
21
21
|
desc "Run all specs"
|
22
|
-
|
23
|
-
t.
|
24
|
-
t.spec_opts = ['--debugger']
|
22
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
23
|
+
t.pattern = FileList['spec/**/*.rb']
|
25
24
|
end
|
26
25
|
|
27
26
|
|
data/lib/media_wiki.rb
CHANGED
data/lib/media_wiki/gateway.rb
CHANGED
@@ -14,6 +14,7 @@ module MediaWiki
|
|
14
14
|
#
|
15
15
|
# [url] Path to API of target MediaWiki (eg. "http://en.wikipedia.org/w/api.php")
|
16
16
|
# [options] Hash of options
|
17
|
+
# [http_options] Hash of options for RestClient::Request (via http_send)
|
17
18
|
#
|
18
19
|
# Options:
|
19
20
|
# [:bot] When set to true, executes API queries with the bot parameter (see http://www.mediawiki.org/wiki/API:Edit#Parameters). Defaults to false.
|
@@ -24,7 +25,7 @@ module MediaWiki
|
|
24
25
|
# [:maxlag] Maximum allowed server lag (see http://www.mediawiki.org/wiki/Manual:Maxlag_parameter), defaults to 5 seconds.
|
25
26
|
# [:retry_count] Number of times to try before giving up if MediaWiki returns 503 Service Unavailable, defaults to 3 (original request plus two retries).
|
26
27
|
# [:retry_delay] Seconds to wait before retry if MediaWiki returns 503 Service Unavailable, defaults to 10 seconds.
|
27
|
-
def initialize(url, options={})
|
28
|
+
def initialize(url, options={}, http_options={})
|
28
29
|
default_options = {
|
29
30
|
:bot => false,
|
30
31
|
:limit => 500,
|
@@ -36,6 +37,7 @@ module MediaWiki
|
|
36
37
|
:max_results => 500
|
37
38
|
}
|
38
39
|
@options = default_options.merge(options)
|
40
|
+
@http_options = http_options
|
39
41
|
@wiki_url = url
|
40
42
|
@log = Logger.new(@options[:logdevice])
|
41
43
|
@log.level = @options[:loglevel]
|
@@ -50,11 +52,17 @@ module MediaWiki
|
|
50
52
|
# [username] Username
|
51
53
|
# [password] Password
|
52
54
|
# [domain] Domain for authentication plugin logins (eg. LDAP), optional -- defaults to 'local' if not given
|
55
|
+
# [options] Hash of additional options
|
53
56
|
#
|
54
57
|
# Throws MediaWiki::Unauthorized if login fails
|
55
|
-
def login(username, password, domain = 'local')
|
56
|
-
|
57
|
-
|
58
|
+
def login(username, password, domain = 'local', options = {})
|
59
|
+
make_api_request(options.merge(
|
60
|
+
'action' => 'login',
|
61
|
+
'lgname' => username,
|
62
|
+
'lgpassword' => password,
|
63
|
+
'lgdomain' => domain
|
64
|
+
))
|
65
|
+
|
58
66
|
@password = password
|
59
67
|
@username = username
|
60
68
|
end
|
@@ -62,27 +70,36 @@ module MediaWiki
|
|
62
70
|
# Fetch MediaWiki page in MediaWiki format. Does not follow redirects.
|
63
71
|
#
|
64
72
|
# [page_title] Page title to fetch
|
73
|
+
# [options] Hash of additional options
|
65
74
|
#
|
66
75
|
# Returns content of page as string, nil if the page does not exist.
|
67
|
-
def get(page_title)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
76
|
+
def get(page_title, options = {})
|
77
|
+
page = make_api_request(options.merge(
|
78
|
+
'action' => 'query',
|
79
|
+
'prop' => 'revisions',
|
80
|
+
'rvprop' => 'content',
|
81
|
+
'titles' => page_title
|
82
|
+
)).first.elements['query/pages/page']
|
83
|
+
|
84
|
+
page.elements['revisions/rev'].text || '' if valid_page?(page)
|
73
85
|
end
|
74
86
|
|
75
87
|
# Fetch latest revision ID of a MediaWiki page. Does not follow redirects.
|
76
88
|
#
|
77
89
|
# [page_title] Page title to fetch
|
90
|
+
# [options] Hash of additional options
|
78
91
|
#
|
79
92
|
# Returns revision ID as a string, nil if the page does not exist.
|
80
|
-
def revision(page_title)
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
93
|
+
def revision(page_title, options = {})
|
94
|
+
page = make_api_request(options.merge(
|
95
|
+
'action' => 'query',
|
96
|
+
'prop' => 'revisions',
|
97
|
+
'rvprop' => 'ids',
|
98
|
+
'rvlimit' => 1,
|
99
|
+
'titles' => page_title
|
100
|
+
)).first.elements['query/pages/page']
|
101
|
+
|
102
|
+
page.elements['revisions/rev'].attributes['revid'] if valid_page?(page)
|
86
103
|
end
|
87
104
|
|
88
105
|
# Render a MediaWiki page as HTML
|
@@ -110,7 +127,7 @@ module MediaWiki
|
|
110
127
|
# OPTIMIZE: unifiy the keys in +options+ like symbolize_keys! but w/o
|
111
128
|
if options["linkbase"] or options[:linkbase]
|
112
129
|
linkbase = options["linkbase"] || options[:linkbase]
|
113
|
-
rendered = rendered.gsub(/\shref="\/wiki\/([\w\(\)
|
130
|
+
rendered = rendered.gsub(/\shref="\/wiki\/([\w\(\)\-\.%:,]*)"/, ' href="' + linkbase + '/wiki/\1"')
|
114
131
|
end
|
115
132
|
if options["noeditsections"] or options[:noeditsections]
|
116
133
|
rendered = rendered.gsub(/<span class="editsection">\[.+\]<\/span>/, '')
|
@@ -240,21 +257,28 @@ module MediaWiki
|
|
240
257
|
# Delete one page. (MediaWiki API does not support deleting multiple pages at a time.)
|
241
258
|
#
|
242
259
|
# [title] Title of page to delete
|
243
|
-
|
244
|
-
|
245
|
-
make_api_request(
|
260
|
+
# [options] Hash of additional options
|
261
|
+
def delete(title, options = {})
|
262
|
+
make_api_request(options.merge(
|
263
|
+
'action' => 'delete',
|
264
|
+
'title' => title,
|
265
|
+
'token' => get_token('delete', title)
|
266
|
+
))
|
246
267
|
end
|
247
268
|
|
248
269
|
# Undelete all revisions of one page.
|
249
270
|
#
|
250
271
|
# [title] Title of page to undelete
|
272
|
+
# [options] Hash of additional options
|
251
273
|
#
|
252
274
|
# Returns number of revisions undeleted, or zero if nothing to undelete
|
253
|
-
def undelete(title)
|
254
|
-
token = get_undelete_token(title)
|
255
|
-
|
256
|
-
|
257
|
-
|
275
|
+
def undelete(title, options = {})
|
276
|
+
if token = get_undelete_token(title)
|
277
|
+
make_api_request(options.merge(
|
278
|
+
'action' => 'undelete',
|
279
|
+
'title' => title,
|
280
|
+
'token' => token
|
281
|
+
)).first.elements['undelete'].attributes['revisions'].to_i
|
258
282
|
else
|
259
283
|
0 # No revisions to undelete
|
260
284
|
end
|
@@ -267,22 +291,15 @@ module MediaWiki
|
|
267
291
|
#
|
268
292
|
# Returns array of page titles (empty if no matches)
|
269
293
|
def list(key, options = {})
|
270
|
-
|
271
|
-
apfrom = nil
|
272
|
-
key, namespace = key.split(":", 2).reverse
|
294
|
+
key, namespace = key.split(':', 2).reverse
|
273
295
|
namespace = namespaces_by_prefix[namespace] || 0
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
'apnamespace' => namespace})
|
282
|
-
res, apfrom = make_api_request(form_data, '//query-continue/allpages/@apfrom')
|
283
|
-
titles += REXML::XPath.match(res, "//p").map { |x| x.attributes["title"] }
|
284
|
-
end while apfrom
|
285
|
-
titles
|
296
|
+
|
297
|
+
iterate_query('allpages', '//p', 'title', 'apfrom', options.merge(
|
298
|
+
'list' => 'allpages',
|
299
|
+
'apprefix' => key,
|
300
|
+
'apnamespace' => namespace,
|
301
|
+
'aplimit' => @options[:limit]
|
302
|
+
))
|
286
303
|
end
|
287
304
|
|
288
305
|
# Get a list of pages that are members of a category
|
@@ -292,42 +309,25 @@ module MediaWiki
|
|
292
309
|
#
|
293
310
|
# Returns array of page titles (empty if no matches)
|
294
311
|
def category_members(category, options = {})
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
{'action' => 'query',
|
300
|
-
'list' => 'categorymembers',
|
301
|
-
'apfrom' => apfrom,
|
302
|
-
'cmtitle' => category,
|
303
|
-
'cmlimit' => @options[:limit]})
|
304
|
-
res, apfrom = make_api_request(form_data, '//query-continue/categorymembers/@apfrom')
|
305
|
-
titles += REXML::XPath.match(res, "//cm").map { |x| x.attributes["title"] }
|
306
|
-
end while apfrom
|
307
|
-
titles
|
312
|
+
iterate_query('categorymembers', '//cm', 'title', 'cmcontinue', options.merge(
|
313
|
+
'cmtitle' => category,
|
314
|
+
'cmlimit' => @options[:limit]
|
315
|
+
))
|
308
316
|
end
|
309
317
|
|
310
318
|
# Get a list of pages that link to a target page
|
311
319
|
#
|
312
320
|
# [title] Link target page
|
313
321
|
# [filter] "all" links (default), "redirects" only, or "nonredirects" (plain links only)
|
322
|
+
# [options] Hash of additional options
|
314
323
|
#
|
315
324
|
# Returns array of page titles (empty if no matches)
|
316
|
-
def backlinks(title, filter =
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
'list' => 'backlinks',
|
323
|
-
'bltitle' => title,
|
324
|
-
'blfilterredir' => filter,
|
325
|
-
'bllimit' => @options[:limit] }
|
326
|
-
form_data['blcontinue'] = blcontinue if blcontinue
|
327
|
-
res, blcontinue = make_api_request(form_data, '//query-continue/backlinks/@blcontinue')
|
328
|
-
titles += REXML::XPath.match(res, "//bl").map { |x| x.attributes["title"] }
|
329
|
-
end while blcontinue
|
330
|
-
titles
|
325
|
+
def backlinks(title, filter = 'all', options = {})
|
326
|
+
iterate_query('backlinks', '//bl', 'title', 'blcontinue', options.merge(
|
327
|
+
'bltitle' => title,
|
328
|
+
'blfilterredir' => filter,
|
329
|
+
'bllimit' => @options[:limit]
|
330
|
+
))
|
331
331
|
end
|
332
332
|
|
333
333
|
# Get a list of pages with matching content in given namespaces
|
@@ -336,29 +336,33 @@ module MediaWiki
|
|
336
336
|
# [namespaces] Array of namespace names to search (defaults to main only)
|
337
337
|
# [limit] Maximum number of hits to ask for (defaults to 500; note that Wikimedia Foundation wikis allow only 50 for normal users)
|
338
338
|
# [max_results] Maximum total number of results to return
|
339
|
+
# [options] Hash of additional options
|
339
340
|
#
|
340
341
|
# Returns array of page titles (empty if no matches)
|
341
|
-
def search(key, namespaces=nil, limit
|
342
|
+
def search(key, namespaces = nil, limit = @options[:limit], max_results = @options[:max_results], options = {})
|
342
343
|
titles = []
|
343
344
|
offset = 0
|
344
|
-
in_progress = true
|
345
345
|
|
346
|
-
form_data =
|
347
|
-
'
|
348
|
-
'
|
346
|
+
form_data = options.merge(
|
347
|
+
'action' => 'query',
|
348
|
+
'list' => 'search',
|
349
|
+
'srwhat' => 'text',
|
349
350
|
'srsearch' => key,
|
350
|
-
'srlimit'
|
351
|
-
|
351
|
+
'srlimit' => limit
|
352
|
+
)
|
353
|
+
|
352
354
|
if namespaces
|
353
355
|
namespaces = [ namespaces ] unless namespaces.kind_of? Array
|
354
356
|
form_data['srnamespace'] = namespaces.map! do |ns| namespaces_by_prefix[ns] end.join('|')
|
355
357
|
end
|
358
|
+
|
356
359
|
begin
|
357
360
|
form_data['sroffset'] = offset if offset
|
358
361
|
form_data['srlimit'] = [limit, max_results - offset.to_i].min
|
359
362
|
res, offset = make_api_request(form_data, '//query-continue/search/@sroffset')
|
360
363
|
titles += REXML::XPath.match(res, "//p").map { |x| x.attributes["title"] }
|
361
364
|
end while offset && offset.to_i < max_results.to_i
|
365
|
+
|
362
366
|
titles
|
363
367
|
end
|
364
368
|
|
@@ -368,18 +372,9 @@ module MediaWiki
|
|
368
372
|
#
|
369
373
|
# Returns array of user names (empty if no matches)
|
370
374
|
def users(options = {})
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
form_data = options.merge(
|
375
|
-
{'action' => 'query',
|
376
|
-
'list' => 'allusers',
|
377
|
-
'aufrom' => aufrom,
|
378
|
-
'aulimit' => @options[:limit]})
|
379
|
-
res, aufrom = make_api_request(form_data, '//query-continue/allusers/@aufrom')
|
380
|
-
names += REXML::XPath.match(res, "//u").map { |x| x.attributes["name"] }
|
381
|
-
end while aufrom
|
382
|
-
names
|
375
|
+
iterate_query('allusers', '//u', 'name', 'aufrom', options.merge(
|
376
|
+
'aulimit' => @options[:limit]
|
377
|
+
))
|
383
378
|
end
|
384
379
|
|
385
380
|
# Get user contributions
|
@@ -391,20 +386,16 @@ module MediaWiki
|
|
391
386
|
# Returns array of hashes containing the "item" attributes defined here: http://www.mediawiki.org/wiki/API:Usercontribs
|
392
387
|
def contributions(user, count = nil, options = {})
|
393
388
|
result = []
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
result += REXML::XPath.match(res, "//item").map { |x| x.attributes.inject({}) { |hash, data| hash[data.first] = data.last; hash } }
|
405
|
-
break if count and result.size >= count
|
406
|
-
end while ucstart
|
407
|
-
result
|
389
|
+
|
390
|
+
iterate_query('usercontribs', '//item', nil, 'uccontinue', options.merge(
|
391
|
+
'ucuser' => user,
|
392
|
+
'uclimit' => @options[:limit]
|
393
|
+
)) { |element|
|
394
|
+
result << hash = {}
|
395
|
+
element.attributes.each { |key, value| hash[key] = value }
|
396
|
+
}
|
397
|
+
|
398
|
+
count ? result.take(count) : result
|
408
399
|
end
|
409
400
|
|
410
401
|
# Upload a file, or get the status of pending uploads. Several
|
@@ -490,27 +481,33 @@ module MediaWiki
|
|
490
481
|
#
|
491
482
|
# _article_or_pageid_ is the title or pageid of a single article
|
492
483
|
# _imlimit_ is the maximum number of images to return (defaults to 200)
|
484
|
+
# _options_ is the hash of additional options
|
493
485
|
#
|
494
486
|
# Example:
|
495
487
|
# images = mw.images('Gaborone')
|
496
488
|
# _images_ would contain ['File:Gaborone at night.jpg', 'File:Gaborone2.png', ...]
|
489
|
+
def images(article_or_pageid, imlimit = 200, options = {})
|
490
|
+
form_data = options.merge(
|
491
|
+
'action' => 'query',
|
492
|
+
'prop' => 'images',
|
493
|
+
'imlimit' => imlimit,
|
494
|
+
'redirects' => true
|
495
|
+
)
|
497
496
|
|
498
|
-
def images(article_or_pageid, imlimit = 200)
|
499
|
-
form_data = {'action' => 'query', 'prop' => 'images', 'imlimit' => imlimit, 'redirects' => true}
|
500
497
|
case article_or_pageid
|
501
498
|
when Fixnum
|
502
499
|
form_data['pageids'] = article_or_pageid
|
503
500
|
else
|
504
501
|
form_data['titles'] = article_or_pageid
|
505
502
|
end
|
506
|
-
xml,
|
503
|
+
xml, _ = make_api_request(form_data)
|
507
504
|
page = xml.elements["query/pages/page"]
|
508
505
|
if valid_page? page
|
509
506
|
if xml.elements["query/redirects/r"]
|
510
507
|
# We're dealing with redirect here.
|
511
508
|
images(page.attributes["pageid"].to_i, imlimit)
|
512
509
|
else
|
513
|
-
|
510
|
+
REXML::XPath.match(page, "images/im").map { |x| x.attributes["title"] }
|
514
511
|
end
|
515
512
|
else
|
516
513
|
nil
|
@@ -521,18 +518,25 @@ module MediaWiki
|
|
521
518
|
#
|
522
519
|
# _article_or_pageid_ is the title or pageid of a single article
|
523
520
|
# _lllimit_ is the maximum number of langlinks to return (defaults to 500, the maximum)
|
521
|
+
# _options_ is the hash of additional options
|
524
522
|
#
|
525
523
|
# Example:
|
526
524
|
# langlinks = mw.langlinks('Jerusalem')
|
527
|
-
def langlinks(article_or_pageid, lllimit = 500)
|
528
|
-
form_data =
|
525
|
+
def langlinks(article_or_pageid, lllimit = 500, options = {})
|
526
|
+
form_data = options.merge(
|
527
|
+
'action' => 'query',
|
528
|
+
'prop' => 'langlinks',
|
529
|
+
'lllimit' => lllimit,
|
530
|
+
'redirects' => true
|
531
|
+
)
|
532
|
+
|
529
533
|
case article_or_pageid
|
530
534
|
when Fixnum
|
531
535
|
form_data['pageids'] = article_or_pageid
|
532
536
|
else
|
533
537
|
form_data['titles'] = article_or_pageid
|
534
538
|
end
|
535
|
-
xml,
|
539
|
+
xml, _ = make_api_request(form_data)
|
536
540
|
page = xml.elements["query/pages/page"]
|
537
541
|
if valid_page? page
|
538
542
|
if xml.elements["query/redirects/r"]
|
@@ -604,7 +608,7 @@ module MediaWiki
|
|
604
608
|
form_data['titles'] = "File:#{file_name_or_page_id}"
|
605
609
|
end
|
606
610
|
|
607
|
-
xml,
|
611
|
+
xml, _ = make_api_request(form_data)
|
608
612
|
page = xml.elements["query/pages/page"]
|
609
613
|
if valid_page? page
|
610
614
|
if xml.elements["query/redirects/r"]
|
@@ -635,34 +639,47 @@ module MediaWiki
|
|
635
639
|
# Imports a MediaWiki XML dump
|
636
640
|
#
|
637
641
|
# [xml] String or array of page names to fetch
|
642
|
+
# [options] Hash of additional options
|
638
643
|
#
|
639
644
|
# Returns XML array <api><import><page/><page/>...
|
640
645
|
# <page revisions="1"> (or more) means successfully imported
|
641
646
|
# <page revisions="0"> means duplicate, not imported
|
642
|
-
def import(xmlfile)
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
647
|
+
def import(xmlfile, options = {})
|
648
|
+
make_api_request(options.merge(
|
649
|
+
'action' => 'import',
|
650
|
+
'xml' => File.new(xmlfile),
|
651
|
+
'token' => get_token('import', 'Main Page'), # NB: dummy page name
|
652
|
+
'format' => 'xml'
|
653
|
+
))
|
648
654
|
end
|
649
655
|
|
650
656
|
# Exports a page or set of pages
|
651
657
|
#
|
652
658
|
# [page_titles] String or array of page titles to fetch
|
659
|
+
# [options] Hash of additional options
|
653
660
|
#
|
654
661
|
# Returns MediaWiki XML dump
|
655
|
-
def export(page_titles)
|
656
|
-
|
657
|
-
|
662
|
+
def export(page_titles, options = {})
|
663
|
+
make_api_request(options.merge(
|
664
|
+
'action' => 'query',
|
665
|
+
'titles' => Array(page_titles).join('|'),
|
666
|
+
'export' => nil,
|
667
|
+
'exportnowrap' => nil
|
668
|
+
)).first
|
658
669
|
end
|
659
670
|
|
660
671
|
# Get a list of all known namespaces
|
661
672
|
#
|
673
|
+
# [options] Hash of additional options
|
674
|
+
#
|
662
675
|
# Returns array of namespaces (name => id)
|
663
|
-
def namespaces_by_prefix
|
664
|
-
|
665
|
-
|
676
|
+
def namespaces_by_prefix(options = {})
|
677
|
+
res = make_api_request(options.merge(
|
678
|
+
'action' => 'query',
|
679
|
+
'meta' => 'siteinfo',
|
680
|
+
'siprop' => 'namespaces'
|
681
|
+
)).first
|
682
|
+
|
666
683
|
REXML::XPath.match(res, "//ns").inject(Hash.new) do |namespaces, namespace|
|
667
684
|
prefix = namespace.attributes["canonical"] || ""
|
668
685
|
namespaces[prefix] = namespace.attributes["id"].to_i
|
@@ -672,10 +689,16 @@ module MediaWiki
|
|
672
689
|
|
673
690
|
# Get a list of all installed (and registered) extensions
|
674
691
|
#
|
692
|
+
# [options] Hash of additional options
|
693
|
+
#
|
675
694
|
# Returns array of extensions (name => version)
|
676
|
-
def extensions
|
677
|
-
|
678
|
-
|
695
|
+
def extensions(options = {})
|
696
|
+
res = make_api_request(options.merge(
|
697
|
+
'action' => 'query',
|
698
|
+
'meta' => 'siteinfo',
|
699
|
+
'siprop' => 'extensions'
|
700
|
+
)).first
|
701
|
+
|
679
702
|
REXML::XPath.match(res, "//ext").inject(Hash.new) do |extensions, extension|
|
680
703
|
name = extension.attributes["name"] || ""
|
681
704
|
extensions[name] = extension.attributes["version"]
|
@@ -688,11 +711,18 @@ module MediaWiki
|
|
688
711
|
# [user] Username to send mail to (name only: eg. 'Bob', not 'User:Bob')
|
689
712
|
# [subject] Subject of message
|
690
713
|
# [content] Content of message
|
714
|
+
# [options] Hash of additional options
|
691
715
|
#
|
692
716
|
# Will raise a 'noemail' APIError if the target user does not have a confirmed email address, see http://www.mediawiki.org/wiki/API:E-mail for details.
|
693
|
-
def email_user(user, subject, text)
|
694
|
-
|
695
|
-
|
717
|
+
def email_user(user, subject, text, options = {})
|
718
|
+
res = make_api_request(options.merge(
|
719
|
+
'action' => 'emailuser',
|
720
|
+
'target' => user,
|
721
|
+
'subject' => subject,
|
722
|
+
'text' => text,
|
723
|
+
'token' => get_token('email', "User:#{user}")
|
724
|
+
)).first
|
725
|
+
|
696
726
|
res.elements['emailuser'].attributes['result'] == 'Success'
|
697
727
|
end
|
698
728
|
|
@@ -700,33 +730,33 @@ module MediaWiki
|
|
700
730
|
#
|
701
731
|
# [query] Semantic Mediawiki query
|
702
732
|
# [params] Array of additional parameters or options, eg. mainlabel=Foo or ?Place (optional)
|
733
|
+
# [options] Hash of additional options
|
703
734
|
#
|
704
735
|
# Returns result as an HTML string
|
705
|
-
def semantic_query(query, params = [])
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
736
|
+
def semantic_query(query, params = [], options = {})
|
737
|
+
unless smw_version = extensions['Semantic MediaWiki']
|
738
|
+
raise MediaWiki::Exception, 'Semantic MediaWiki extension not installed.'
|
739
|
+
end
|
740
|
+
|
741
|
+
if smw_version.to_f >= 1.7
|
742
|
+
make_api_request(options.merge(
|
743
|
+
'action' => 'ask',
|
744
|
+
'query' => "#{query}|#{params.join('|')}"
|
745
|
+
)).first
|
746
|
+
else
|
747
|
+
make_api_request(options.merge(
|
748
|
+
'action' => 'parse',
|
749
|
+
'prop' => 'text',
|
750
|
+
'text' => "{{#ask:#{query}|#{params.push('format=list').join('|')}}}"
|
751
|
+
)).first.elements['parse/text'].text
|
752
|
+
end
|
721
753
|
end
|
722
754
|
|
723
755
|
# Create a new account
|
724
756
|
#
|
725
757
|
# [options] is +Hash+ passed as query arguments. See https://www.mediawiki.org/wiki/API:Account_creation#Parameters for more information.
|
726
758
|
def create_account(options)
|
727
|
-
|
728
|
-
res, dummy = make_api_request(form_data)
|
729
|
-
res
|
759
|
+
make_api_request(options.merge('action' => 'createaccount')).first
|
730
760
|
end
|
731
761
|
|
732
762
|
# Sets options for currenlty logged in user
|
@@ -735,8 +765,12 @@ module MediaWiki
|
|
735
765
|
# [optionname] a +String+ indicating which option to change (optional)
|
736
766
|
# [optionvalue] the new value for optionname - allows pipe characters (optional)
|
737
767
|
# [reset] a +Boolean+ indicating if all preferences should be reset to site defaults (optional)
|
738
|
-
|
739
|
-
|
768
|
+
# [options] Hash of additional options
|
769
|
+
def options(changes = {}, optionname = nil, optionvalue = nil, reset = false, options = {})
|
770
|
+
form_data = options.merge(
|
771
|
+
'action' => 'options',
|
772
|
+
'token' => get_options_token
|
773
|
+
)
|
740
774
|
|
741
775
|
if changes.present?
|
742
776
|
form_data['change'] = changes.map { |key, value| "#{key}=#{value}" }.join('|')
|
@@ -750,8 +784,7 @@ module MediaWiki
|
|
750
784
|
form_data['reset'] = true
|
751
785
|
end
|
752
786
|
|
753
|
-
|
754
|
-
res
|
787
|
+
make_api_request(form_data).first
|
755
788
|
end
|
756
789
|
|
757
790
|
# Set groups for a user
|
@@ -759,9 +792,10 @@ module MediaWiki
|
|
759
792
|
# [user] Username of user to modify
|
760
793
|
# [groups_to_add] Groups to add user to, as an array or a string if a single group (optional)
|
761
794
|
# [groups_to_remove] Groups to remove user from, as an array or a string if a single group (optional)
|
762
|
-
|
795
|
+
# [options] Hash of additional options
|
796
|
+
def set_groups(user, groups_to_add = [], groups_to_remove = [], comment = '', options = {})
|
763
797
|
token = get_userrights_token(user)
|
764
|
-
userrights(user, token, groups_to_add, groups_to_remove, comment)
|
798
|
+
userrights(user, token, groups_to_add, groups_to_remove, comment, options)
|
765
799
|
end
|
766
800
|
|
767
801
|
# Review current revision of an article (requires FlaggedRevisions extension, see http://www.mediawiki.org/wiki/Extension:FlaggedRevs)
|
@@ -769,12 +803,20 @@ module MediaWiki
|
|
769
803
|
# [title] Title of article to review
|
770
804
|
# [flags] Hash of flags and values to set, eg. { "accuracy" => "1", "depth" => "2" }
|
771
805
|
# [comment] Comment to add to review (optional)
|
772
|
-
|
806
|
+
# [options] Hash of additional options
|
807
|
+
def review(title, flags, comment = "Reviewed by MediaWiki::Gateway", options = {})
|
773
808
|
raise APIError.new('missingtitle', "Article #{title} not found") unless revid = revision(title)
|
774
|
-
|
775
|
-
form_data.merge
|
776
|
-
|
777
|
-
|
809
|
+
|
810
|
+
form_data = options.merge(
|
811
|
+
'action' => 'review',
|
812
|
+
'revid' => revid,
|
813
|
+
'token' => get_token('edit', title),
|
814
|
+
'comment' => comment
|
815
|
+
)
|
816
|
+
|
817
|
+
flags.each { |k, v| form_data["flag_#{k}"] = v }
|
818
|
+
|
819
|
+
make_api_request(form_data).first
|
778
820
|
end
|
779
821
|
|
780
822
|
private
|
@@ -782,7 +824,7 @@ module MediaWiki
|
|
782
824
|
# Fetch token (type 'delete', 'edit', 'email', 'import', 'move', 'protect')
|
783
825
|
def get_token(type, page_titles)
|
784
826
|
form_data = {'action' => 'query', 'prop' => 'info', 'intoken' => type, 'titles' => page_titles}
|
785
|
-
res,
|
827
|
+
res, _ = make_api_request(form_data)
|
786
828
|
token = res.elements["query/pages/page"].attributes[type + "token"]
|
787
829
|
raise Unauthorized.new "User is not permitted to perform this operation: #{type}" if token.nil?
|
788
830
|
token
|
@@ -790,7 +832,7 @@ module MediaWiki
|
|
790
832
|
|
791
833
|
def get_undelete_token(page_titles)
|
792
834
|
form_data = {'action' => 'query', 'list' => 'deletedrevs', 'prop' => 'info', 'drprop' => 'token', 'titles' => page_titles}
|
793
|
-
res,
|
835
|
+
res, _ = make_api_request(form_data)
|
794
836
|
if res.elements["query/deletedrevs/page"]
|
795
837
|
token = res.elements["query/deletedrevs/page"].attributes["token"]
|
796
838
|
raise Unauthorized.new "User is not permitted to perform this operation: #{type}" if token.nil?
|
@@ -803,7 +845,7 @@ module MediaWiki
|
|
803
845
|
# User rights management (aka group assignment)
|
804
846
|
def get_userrights_token(user)
|
805
847
|
form_data = {'action' => 'query', 'list' => 'users', 'ustoken' => 'userrights', 'ususers' => user}
|
806
|
-
res,
|
848
|
+
res, _ = make_api_request(form_data)
|
807
849
|
token = res.elements["query/users/user"].attributes["userrightstoken"]
|
808
850
|
|
809
851
|
@log.debug("RESPONSE: #{res.to_s}")
|
@@ -820,26 +862,28 @@ module MediaWiki
|
|
820
862
|
|
821
863
|
def get_options_token
|
822
864
|
form_data = { 'action' => 'tokens', 'type' => 'options' }
|
823
|
-
res,
|
865
|
+
res, _ = make_api_request(form_data)
|
824
866
|
res.elements['tokens'].attributes['optionstoken']
|
825
867
|
end
|
826
868
|
|
827
|
-
def userrights(user, token, groups_to_add, groups_to_remove, reason)
|
869
|
+
def userrights(user, token, groups_to_add, groups_to_remove, reason, options = {})
|
828
870
|
# groups_to_add and groups_to_remove can be a string or an array. Turn them into MediaWiki's pipe-delimited list format.
|
829
871
|
if groups_to_add.is_a? Array
|
830
872
|
groups_to_add = groups_to_add.join('|')
|
831
873
|
end
|
874
|
+
|
832
875
|
if groups_to_remove.is_a? Array
|
833
876
|
groups_to_remove = groups_to_remove.join('|')
|
834
877
|
end
|
835
878
|
|
836
|
-
|
837
|
-
'
|
879
|
+
make_api_request(options.merge(
|
880
|
+
'action' => 'userrights',
|
881
|
+
'user' => user,
|
882
|
+
'token' => token,
|
883
|
+
'add' => groups_to_add,
|
838
884
|
'remove' => groups_to_remove,
|
839
885
|
'reason' => reason
|
840
|
-
|
841
|
-
res, dummy = make_api_request(form_data)
|
842
|
-
res
|
886
|
+
)).first
|
843
887
|
end
|
844
888
|
|
845
889
|
|
@@ -867,6 +911,39 @@ module MediaWiki
|
|
867
911
|
make_api_request(form_data).first.elements['query']
|
868
912
|
end
|
869
913
|
|
914
|
+
# Iterate over query results
|
915
|
+
#
|
916
|
+
# [list] list name to query
|
917
|
+
# [res_xpath] XPath selector for results
|
918
|
+
# [attr] attribute name to extract, if any
|
919
|
+
# [param] parameter name to continue query
|
920
|
+
# [options] additional query options
|
921
|
+
#
|
922
|
+
# Yields each attribute value, or, if +attr+ is nil, each REXML::Element.
|
923
|
+
def iterate_query(list, res_xpath, attr, param, options, &block)
|
924
|
+
items, block = [], lambda { |item| items << item } unless block
|
925
|
+
|
926
|
+
attribute_names = %w[from continue].map { |name|
|
927
|
+
"name()='#{param[0, 2]}#{name}'"
|
928
|
+
}
|
929
|
+
|
930
|
+
req_xpath = "//query-continue/#{list}/@*[#{attribute_names.join(' or ')}]"
|
931
|
+
res_xpath = "//query/#{list}/#{res_xpath}" unless res_xpath.start_with?('/')
|
932
|
+
|
933
|
+
options, continue = options.merge('action' => 'query', 'list' => list), nil
|
934
|
+
|
935
|
+
loop {
|
936
|
+
res, continue = make_api_request(options, req_xpath)
|
937
|
+
|
938
|
+
REXML::XPath.match(res, res_xpath).each { |element|
|
939
|
+
block[attr ? element.attributes[attr] : element]
|
940
|
+
}
|
941
|
+
|
942
|
+
continue ? options[param] = continue : break
|
943
|
+
}
|
944
|
+
|
945
|
+
items
|
946
|
+
end
|
870
947
|
|
871
948
|
# Make generic request to API
|
872
949
|
#
|
@@ -912,23 +989,24 @@ module MediaWiki
|
|
912
989
|
elsif action == 'createaccount'
|
913
990
|
raise Unauthorized.new("Account creation failed: #{action_result}")
|
914
991
|
end
|
915
|
-
|
992
|
+
end
|
916
993
|
end
|
917
|
-
|
918
|
-
continue = (continue_xpath and doc.elements['query-continue']) ? REXML::XPath.first(doc, continue_xpath).value : nil
|
994
|
+
continue = (continue_xpath and doc.elements['query-continue']) ? REXML::XPath.first(doc, continue_xpath) : nil
|
919
995
|
return [doc, continue]
|
920
996
|
end
|
921
997
|
end
|
922
998
|
|
923
999
|
# Execute the HTTP request using either GET or POST as appropriate
|
924
1000
|
def http_send url, form_data, headers, &block
|
1001
|
+
opts = @http_options.merge(:url => url, :headers => headers)
|
1002
|
+
|
925
1003
|
if form_data['action'] == 'query'
|
926
1004
|
log.debug("GET: #{form_data.inspect}, #{@cookies.inspect}")
|
927
1005
|
headers[:params] = form_data
|
928
|
-
RestClient.
|
1006
|
+
RestClient::Request.execute(opts.update(:method => :get), &block)
|
929
1007
|
else
|
930
1008
|
log.debug("POST: #{form_data.inspect}, #{@cookies.inspect}")
|
931
|
-
RestClient.post
|
1009
|
+
RestClient::Request.execute(opts.update(:method => :post, :payload => form_data), &block)
|
932
1010
|
end
|
933
1011
|
end
|
934
1012
|
|
@@ -939,7 +1017,7 @@ module MediaWiki
|
|
939
1017
|
begin
|
940
1018
|
res = res.force_encoding("UTF-8") if res.respond_to?(:force_encoding)
|
941
1019
|
doc = REXML::Document.new(res).root
|
942
|
-
rescue REXML::ParseException
|
1020
|
+
rescue REXML::ParseException
|
943
1021
|
raise MediaWiki::Exception.new "Response is not XML. Are you sure you are pointing to api.php?"
|
944
1022
|
end
|
945
1023
|
log.debug("RES: #{doc}")
|
data/lib/media_wiki/utils.rb
CHANGED
@@ -21,7 +21,7 @@ module MediaWiki
|
|
21
21
|
# [title] Page name string in Wiki format
|
22
22
|
def get_path_to_subpage(title)
|
23
23
|
return nil unless title and title.include? '/'
|
24
|
-
|
24
|
+
title.split(/\/([^\/]*)$/).first
|
25
25
|
end
|
26
26
|
|
27
27
|
# Extract subpage name. If there is no hierarchy above, return page name.
|
data/mediawiki-gateway.gemspec
CHANGED
@@ -2,21 +2,21 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: mediawiki-gateway 0.6.
|
5
|
+
# stub: mediawiki-gateway 0.6.1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "mediawiki-gateway"
|
9
|
-
s.version = "0.6.
|
9
|
+
s.version = "0.6.1"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Jani Patokallio"]
|
14
|
-
s.date = "2014-
|
14
|
+
s.date = "2014-07-28"
|
15
15
|
s.description = ""
|
16
16
|
s.email = "jpatokal@iki.fi"
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"LICENSE",
|
19
|
-
"README"
|
19
|
+
"README.md"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
".ruby-version",
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
"Gemfile",
|
25
25
|
"Gemfile.lock",
|
26
26
|
"LICENSE",
|
27
|
-
"README",
|
27
|
+
"README.md",
|
28
28
|
"Rakefile",
|
29
29
|
"config/hosts.yml",
|
30
30
|
"lib/media_wiki.rb",
|
@@ -70,6 +70,9 @@ Gem::Specification.new do |s|
|
|
70
70
|
s.add_development_dependency(%q<rr>, [">= 0"])
|
71
71
|
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
72
72
|
s.add_development_dependency(%q<rspec>, ["~> 1.3"])
|
73
|
+
s.add_development_dependency(%q<rspec-core>, [">= 0"])
|
74
|
+
s.add_development_dependency(%q<rspec-expectations>, [">= 0"])
|
75
|
+
s.add_development_dependency(%q<rspec-mocks>, [">= 0"])
|
73
76
|
s.add_development_dependency(%q<debugger>, [">= 0"])
|
74
77
|
s.add_development_dependency(%q<sinatra>, [">= 0"])
|
75
78
|
s.add_development_dependency(%q<activemodel>, [">= 0"])
|
@@ -82,6 +85,9 @@ Gem::Specification.new do |s|
|
|
82
85
|
s.add_dependency(%q<rr>, [">= 0"])
|
83
86
|
s.add_dependency(%q<simplecov>, [">= 0"])
|
84
87
|
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
88
|
+
s.add_dependency(%q<rspec-core>, [">= 0"])
|
89
|
+
s.add_dependency(%q<rspec-expectations>, [">= 0"])
|
90
|
+
s.add_dependency(%q<rspec-mocks>, [">= 0"])
|
85
91
|
s.add_dependency(%q<debugger>, [">= 0"])
|
86
92
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
87
93
|
s.add_dependency(%q<activemodel>, [">= 0"])
|
@@ -95,6 +101,9 @@ Gem::Specification.new do |s|
|
|
95
101
|
s.add_dependency(%q<rr>, [">= 0"])
|
96
102
|
s.add_dependency(%q<simplecov>, [">= 0"])
|
97
103
|
s.add_dependency(%q<rspec>, ["~> 1.3"])
|
104
|
+
s.add_dependency(%q<rspec-core>, [">= 0"])
|
105
|
+
s.add_dependency(%q<rspec-expectations>, [">= 0"])
|
106
|
+
s.add_dependency(%q<rspec-mocks>, [">= 0"])
|
98
107
|
s.add_dependency(%q<debugger>, [">= 0"])
|
99
108
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
100
109
|
s.add_dependency(%q<activemodel>, [">= 0"])
|
@@ -64,9 +64,9 @@ module FakeMediaWiki
|
|
64
64
|
end
|
65
65
|
|
66
66
|
class ApiToken
|
67
|
-
ADMIN_TOKEN = "admin_token+\\"
|
68
|
-
REGULAR_TOKEN = "regular_token+\\"
|
69
|
-
BLANK_TOKEN = "+\\"
|
67
|
+
ADMIN_TOKEN = "admin_token+\\" unless const_defined?(:ADMIN_TOKEN)
|
68
|
+
REGULAR_TOKEN = "regular_token+\\" unless const_defined?(:REGULAR_TOKEN)
|
69
|
+
BLANK_TOKEN = "+\\" unless const_defined?(:BLANK_TOKEN)
|
70
70
|
|
71
71
|
def initialize(params)
|
72
72
|
@token_str = params[:token]
|
data/spec/gateway_spec.rb
CHANGED
@@ -3,11 +3,8 @@ require 'spec_helper'
|
|
3
3
|
# Kickstart fake media wiki app
|
4
4
|
require 'sham_rack'
|
5
5
|
require_relative 'fake_media_wiki/app'
|
6
|
-
|
7
|
-
|
8
|
-
# This is a horrible workaround for some bizarre conflict with later versions of ShamRack/Rack/Sinatra/Builder/...
|
9
|
-
$fake_media_wiki = $fake_media_wiki.instance_eval('app').instance_eval('@app').instance_eval('@app').app.app.app.app.app
|
10
|
-
end
|
6
|
+
|
7
|
+
$fake_media_wiki = FakeMediaWiki::App.new!
|
11
8
|
ShamRack.mount($fake_media_wiki, 'dummy-wiki.example')
|
12
9
|
|
13
10
|
describe MediaWiki::Gateway do
|
@@ -190,22 +187,26 @@ describe MediaWiki::Gateway do
|
|
190
187
|
describe "when wiki returns 503" do
|
191
188
|
|
192
189
|
before do
|
193
|
-
@log =
|
194
|
-
stub(@log).debug { }
|
195
|
-
stub(@log).warn { }
|
190
|
+
@log = double(:debug => nil, :warn => nil)
|
196
191
|
@fail_gateway = MediaWiki::Gateway.new('http://dummy-wiki.example/w/api.php', {:maxlag => -1, :retry_delay => 0})
|
197
|
-
|
192
|
+
allow(@fail_gateway).to receive(:log) { @log }
|
198
193
|
end
|
199
194
|
|
200
195
|
it "should retry twice and fail" do
|
201
196
|
lambda {
|
202
197
|
@fail_gateway.get("")
|
203
198
|
}.should raise_error
|
204
|
-
@log.should have_received.
|
199
|
+
@log.should have_received(:warn).with("503 Service Unavailable: Maxlag exceeded. Retry in 0 seconds.").twice
|
205
200
|
end
|
206
201
|
|
207
202
|
end
|
208
203
|
|
204
|
+
it "should pass options to RestClient::Request" do
|
205
|
+
gateway = MediaWiki::Gateway.new('http://dummy-wiki.example/w/api.php', {}, :verify_ssl => false)
|
206
|
+
RestClient::Request.should receive(:execute).with(hash_including(:verify_ssl => false)).and_return([double(:elements => {})])
|
207
|
+
gateway.get("").should be_nil
|
208
|
+
end
|
209
|
+
|
209
210
|
end
|
210
211
|
|
211
212
|
describe "#redirect?" do
|
@@ -213,7 +214,7 @@ describe MediaWiki::Gateway do
|
|
213
214
|
describe "for an existing redirect page" do
|
214
215
|
|
215
216
|
it "returns true" do
|
216
|
-
@gateway.redirect?("Redirect").should
|
217
|
+
@gateway.redirect?("Redirect").should == true
|
217
218
|
end
|
218
219
|
|
219
220
|
end
|
@@ -221,7 +222,7 @@ describe MediaWiki::Gateway do
|
|
221
222
|
describe "for an existing non-redirect page" do
|
222
223
|
|
223
224
|
it "returns false" do
|
224
|
-
@gateway.redirect?("Main Page").should
|
225
|
+
@gateway.redirect?("Main Page").should == false
|
225
226
|
end
|
226
227
|
|
227
228
|
end
|
@@ -229,7 +230,7 @@ describe MediaWiki::Gateway do
|
|
229
230
|
describe "for a missing wiki page" do
|
230
231
|
|
231
232
|
it "returns false" do
|
232
|
-
@gateway.redirect?("page/missing").should
|
233
|
+
@gateway.redirect?("page/missing").should == false
|
233
234
|
end
|
234
235
|
|
235
236
|
end
|
@@ -389,19 +390,20 @@ describe MediaWiki::Gateway do
|
|
389
390
|
describe "when uploading a new file" do
|
390
391
|
|
391
392
|
before do
|
392
|
-
|
393
|
-
|
393
|
+
@path = 'some/path/sample_image.jpg'
|
394
|
+
allow(File).to receive(:new).with(@path).and_return('SAMPLEIMAGEDATA')
|
395
|
+
@page = @gateway.upload(@path)
|
394
396
|
end
|
395
397
|
|
396
398
|
it "should open the file" do
|
397
|
-
File.should have_received.
|
399
|
+
File.should have_received(:new).with(@path)
|
398
400
|
end
|
399
401
|
|
400
402
|
it "should upload the file" do
|
401
403
|
expected = <<-XML
|
402
404
|
<api>
|
403
405
|
<upload result="Success" filename="sample_image.jpg"/>
|
404
|
-
|
406
|
+
</api>
|
405
407
|
XML
|
406
408
|
Hash.from_xml(@page.first.to_s).should == Hash.from_xml(expected)
|
407
409
|
end
|
@@ -617,7 +619,7 @@ describe MediaWiki::Gateway do
|
|
617
619
|
end
|
618
620
|
|
619
621
|
it "should return at most the maximum number of results asked" do
|
620
|
-
@search.should
|
622
|
+
@search.size.should == 1
|
621
623
|
end
|
622
624
|
end
|
623
625
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
begin
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start
|
4
|
+
rescue LoadError
|
5
|
+
warn 'SimpleCov not available. Install it with: gem install simplecov'
|
6
|
+
end
|
3
7
|
|
4
8
|
require 'media_wiki'
|
5
9
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
RSpec.configure { |config|
|
11
|
+
%w[expect mock].each { |what|
|
12
|
+
config.send("#{what}_with", :rspec) { |c| c.syntax = [:should, :expect] }
|
13
|
+
}
|
14
|
+
}
|
10
15
|
|
11
16
|
# :nodoc: Rails 2.3.x: Hash#to_xml is defined in active_support
|
12
17
|
# :nodoc: Rails 3: #to_xml is defined in ActiveModel::Serializers::Xml
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mediawiki-gateway
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jani Patokallio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -122,6 +122,48 @@ dependencies:
|
|
122
122
|
- - ~>
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '1.3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec-core
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ! '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rspec-expectations
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ! '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rspec-mocks
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ! '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ! '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
125
167
|
- !ruby/object:Gem::Dependency
|
126
168
|
name: debugger
|
127
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,14 +212,14 @@ executables: []
|
|
170
212
|
extensions: []
|
171
213
|
extra_rdoc_files:
|
172
214
|
- LICENSE
|
173
|
-
- README
|
215
|
+
- README.md
|
174
216
|
files:
|
175
217
|
- .ruby-version
|
176
218
|
- .rvmrc
|
177
219
|
- Gemfile
|
178
220
|
- Gemfile.lock
|
179
221
|
- LICENSE
|
180
|
-
- README
|
222
|
+
- README.md
|
181
223
|
- Rakefile
|
182
224
|
- config/hosts.yml
|
183
225
|
- lib/media_wiki.rb
|
@@ -225,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
225
267
|
version: '0'
|
226
268
|
requirements: []
|
227
269
|
rubyforge_project:
|
228
|
-
rubygems_version: 2.
|
270
|
+
rubygems_version: 2.4.1
|
229
271
|
signing_key:
|
230
272
|
specification_version: 4
|
231
273
|
summary: Connect to the mediawiki API
|