mediawiki-gateway 0.6.2 → 1.0.0.rc1

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/COPYING +22 -0
  3. data/ChangeLog +16 -0
  4. data/README.md +80 -21
  5. data/Rakefile +28 -34
  6. data/bin/mediawiki-gateway +203 -0
  7. data/lib/media_wiki.rb +4 -9
  8. data/lib/media_wiki/exception.rb +11 -8
  9. data/lib/media_wiki/fake_wiki.rb +636 -0
  10. data/lib/media_wiki/gateway.rb +105 -940
  11. data/lib/media_wiki/gateway/files.rb +173 -0
  12. data/lib/media_wiki/gateway/pages.rb +400 -0
  13. data/lib/media_wiki/gateway/query.rb +98 -0
  14. data/lib/media_wiki/gateway/site.rb +101 -0
  15. data/lib/media_wiki/gateway/users.rb +182 -0
  16. data/lib/media_wiki/utils.rb +47 -13
  17. data/lib/media_wiki/version.rb +27 -0
  18. data/lib/mediawiki-gateway.rb +1 -0
  19. data/spec/{import-test-data.xml → data/import.xml} +0 -0
  20. data/spec/media_wiki/gateway/files_spec.rb +34 -0
  21. data/spec/media_wiki/gateway/pages_spec.rb +390 -0
  22. data/spec/media_wiki/gateway/query_spec.rb +84 -0
  23. data/spec/media_wiki/gateway/site_spec.rb +122 -0
  24. data/spec/media_wiki/gateway/users_spec.rb +171 -0
  25. data/spec/media_wiki/gateway_spec.rb +129 -0
  26. data/spec/{live_gateway_spec.rb → media_wiki/live_gateway_spec.rb} +31 -35
  27. data/spec/{utils_spec.rb → media_wiki/utils_spec.rb} +41 -39
  28. data/spec/spec_helper.rb +17 -16
  29. metadata +77 -135
  30. data/.ruby-version +0 -1
  31. data/.rvmrc +0 -34
  32. data/Gemfile +0 -19
  33. data/Gemfile.lock +0 -77
  34. data/LICENSE +0 -21
  35. data/config/hosts.yml +0 -17
  36. data/lib/media_wiki/config.rb +0 -69
  37. data/mediawiki-gateway.gemspec +0 -113
  38. data/samples/README +0 -18
  39. data/samples/create_page.rb +0 -13
  40. data/samples/delete_batch.rb +0 -14
  41. data/samples/download_batch.rb +0 -15
  42. data/samples/email_user.rb +0 -14
  43. data/samples/export_xml.rb +0 -14
  44. data/samples/get_page.rb +0 -11
  45. data/samples/import_xml.rb +0 -14
  46. data/samples/run_fake_media_wiki.rb +0 -8
  47. data/samples/search_content.rb +0 -12
  48. data/samples/semantic_query.rb +0 -17
  49. data/samples/upload_commons.rb +0 -45
  50. data/samples/upload_file.rb +0 -13
  51. data/spec/fake_media_wiki/api_pages.rb +0 -135
  52. data/spec/fake_media_wiki/app.rb +0 -360
  53. data/spec/fake_media_wiki/query_handling.rb +0 -136
  54. data/spec/gateway_spec.rb +0 -888
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Sample script for fetching a page's current contents in Wiki markup
4
- #
5
- require './lib/media_wiki'
6
-
7
- config = MediaWiki::Config.new ARGV
8
- config.abort("Name of article is mandatory.") unless config.article
9
-
10
- mw = MediaWiki::Gateway.new(config.url, { :loglevel => Logger::DEBUG } )
11
- puts mw.get(config.article)
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Import a MediaWiki XML dump
4
- #
5
- require './lib/media_wiki'
6
-
7
- if ARGV.length < 3
8
- raise "Syntax: import_xml.rb <host> <username> <password> <file>"
9
- end
10
-
11
- mw = MediaWiki::Gateway.new(ARGV[0], Logger::DEBUG)
12
- mw.login(ARGV[1], ARGV[2])
13
- mw.import(ARGV[3])
14
-
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # Helper script for running a live FakeMediaWiki instance instead of just shamracking it.
3
- require 'rubygems'
4
- require 'sinatra/base'
5
- require 'spec/fake_media_wiki/app'
6
-
7
- FakeMediaWiki::App.run! :host => 'localhost', :port => 9090
8
-
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Sample script for searching page contents in a Wiki
4
- #
5
- require './lib/media_wiki'
6
-
7
- config = MediaWiki::Config.new ARGV
8
- config.abort("Please specify search key as article name (-a)") unless config.article
9
-
10
- mw = MediaWiki::Gateway.new(config.url, { :loglevel => Logger::DEBUG } )
11
- mw.login(config.user, config.pw)
12
- puts mw.search(config.article, nil, 50)
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Sample script for querying Semantic MediaWiki data
4
- #
5
-
6
- require './lib/media_wiki'
7
-
8
- mw = MediaWiki::Gateway.new(ARGV[0])
9
-
10
- params = []
11
- i = 2
12
- until i == ARGV.length
13
- params << ARGV[i]
14
- i += 1
15
- end
16
-
17
- puts mw.semantic_query(ARGV[1], params)
@@ -1,45 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Sample script for uploading files to Mediawiki Commons (interactive)
4
-
5
- require './lib/media_wiki'
6
-
7
- config = MediaWiki::Config.new(ARGV, "upload")
8
- file = ARGV[0]
9
- config.abort("Name of file to upload is mandatory.") unless file
10
-
11
- mw = MediaWiki::Gateway.new(config.url)
12
- mw.login(config.user, config.pw)
13
-
14
- puts "Login successful."
15
- puts "Description of file:"
16
- desc = STDIN.gets.chomp
17
- puts "Date of file:"
18
- date = STDIN.gets.chomp
19
- puts "Target filename: (leave blank to use existing name)"
20
- target = STDIN.gets.chomp
21
- target = config.target if target.empty?
22
- puts "Categories, separated by commas:"
23
- cats = STDIN.gets.chomp.split(",")
24
- cats = "[[Category:" + cats.join("]]\n[[Category:") + "]]" unless cats.empty?
25
-
26
- template = <<-TEMPLATE
27
- == Summary ==
28
- {{Information
29
- |Description={{en|1=%DESC%}}
30
- |Source={{own}}
31
- |Author=[[User:%USER%|%USER%]]
32
- |Date=%DATE%
33
- |Permission=
34
- |other_versions=
35
- }}
36
-
37
- == Licensing ==
38
- {{self|cc-by-sa-3.0|GFDL}}
39
-
40
- %CATS%
41
- TEMPLATE
42
- desc = template.gsub('%USER%', config.user).gsub('%DESC%', desc).gsub('%DATE%', date).gsub('%CATS%', cats)
43
- puts "Uploading #{file} to #{target}..."
44
- mw.upload(file, {:target => target, :description => desc, :summary => "Uploaded by MediaWiki::Gateway"})
45
- puts "Done."
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Sample script for fetching a page's current contents in Wiki markup
4
- #
5
- require './lib/media_wiki'
6
-
7
- config = MediaWiki::Config.new(ARGV, "upload")
8
- config.abort("Name of file to upload is mandatory.") unless ARGV[0]
9
-
10
- mw = MediaWiki::Gateway.new(config.url, { :loglevel => Logger::DEBUG } )
11
- mw.login(config.user, config.pw)
12
- mw.upload(ARGV[0], {:target => config.target, :description => config.desc, :summary => config.summary})
13
-
@@ -1,135 +0,0 @@
1
- module FakeMediaWiki
2
-
3
- class ApiPages
4
-
5
- def initialize
6
- @page_id = 0
7
- @pages = {}
8
- @namespaces = { "" => 0 }
9
- end
10
-
11
- def add_namespace(id, prefix)
12
- @namespaces[prefix] = id
13
- end
14
-
15
- def namespaces_by_prefix
16
- @namespaces
17
- end
18
-
19
- def namespaces_by_id
20
- @namespaces.invert
21
- end
22
-
23
- def add(title, content, redirect=false)
24
- @page_id += 1
25
- dummy, prefix = title.split(":", 2).reverse
26
- @pages[title] = {
27
- :pageid => @page_id,
28
- :namespace => namespaces_by_prefix[prefix || ""],
29
- :title => title,
30
- :content => content,
31
- :redirect => redirect
32
- }
33
- end
34
-
35
- def get(title)
36
- @pages[title]
37
- end
38
-
39
- def list(prefix)
40
- @pages.select do |key, page|
41
- key =~ /^#{prefix}/
42
- end
43
- end
44
-
45
- def search(searchkey, namespaces)
46
- raise FakeMediaWiki::ApiError.new("srparam-search", "empty search string is not allowed") if searchkey.empty?
47
- @pages.select do |key, page|
48
- page[:content] =~ /#{searchkey}/ and namespaces.include? page[:namespace].to_s
49
- end
50
- end
51
-
52
- def delete(title)
53
- @pages.delete(title)
54
- end
55
-
56
- def undelete(title)
57
- if @pages[title]
58
- 0
59
- else
60
- add(title, "Undeleted content")
61
- 1
62
- end
63
- end
64
- end
65
-
66
- class ApiToken
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
-
71
- def initialize(params)
72
- @token_str = params[:token]
73
- @token_in = params[:intoken]
74
- end
75
-
76
- def set_type(type)
77
- @token_in = type
78
- end
79
-
80
- def validate
81
- unless @token_str
82
- raise FakeMediaWiki::ApiError.new("notoken", "The token parameter must be set")
83
- end
84
- end
85
-
86
- def validate_admin
87
- validate
88
- if @token_str != ADMIN_TOKEN
89
- raise FakeMediaWiki::ApiError.new("badtoken", "Invalid token")
90
- end
91
- end
92
-
93
- def request(user)
94
- @user = user
95
- respond_to?(requested_token_type) ? send(requested_token_type) : nil
96
- end
97
-
98
- def requested_token_type
99
- "#{@token_in}token".to_sym
100
- end
101
-
102
- def importtoken
103
- if @user && @user[:is_admin]
104
- ADMIN_TOKEN
105
- else
106
- nil
107
- end
108
- end
109
- alias_method :deletetoken, :importtoken
110
- alias_method :undeletetoken, :importtoken
111
- alias_method :userrightstoken, :importtoken
112
- alias_method :createusertoken, :importtoken
113
-
114
- def edittoken
115
- if @user
116
- REGULAR_TOKEN
117
- else
118
- BLANK_TOKEN
119
- end
120
- end
121
- alias_method :optionstoken, :edittoken
122
- end
123
-
124
- class ApiError < StandardError
125
-
126
- attr_reader :code, :message
127
-
128
- def initialize(code, message)
129
- @code = code
130
- @message = message
131
- end
132
-
133
- end
134
-
135
- end
@@ -1,360 +0,0 @@
1
- require 'rubygems'
2
- require 'sinatra/base'
3
- require_relative 'api_pages'
4
- require_relative 'query_handling'
5
-
6
- # A simple Rack app that stubs out a web service, for testing.
7
-
8
- module FakeMediaWiki
9
-
10
- class App < Sinatra::Base
11
-
12
- set :show_exceptions, false
13
- set :environment, :development
14
-
15
- def initialize
16
- reset
17
- super
18
- end
19
-
20
- def reset
21
- @sequence_id = 0
22
-
23
- @users = {}
24
- add_user('atlasmw', 'wombat', 'local', true)
25
- add_user('nonadmin', 'sekrit', 'local', false)
26
- add_user('ldapuser', 'ldappass', 'ldapdomain', false)
27
-
28
- @pages = ApiPages.new
29
- @pages.add('Main Page', 'Content')
30
- @pages.add('Main 2', 'Content')
31
- @pages.add('Empty', '')
32
- @pages.add('Level/Level/Index', '{{#include:Foo}} {{#include:Bar}}')
33
- @pages.add_namespace(100, "Book")
34
- @pages.add('Book:Italy', 'Introduction')
35
- @pages.add_namespace(200, "Sandbox")
36
- @pages.add('Foopage', 'Content')
37
- @pages.add('Redirect', '#REDIRECT', true)
38
-
39
- @extensions = { 'FooExtension' => 'r1', 'BarExtension' => 'r2', 'Semantic MediaWiki' => '1.5' }
40
-
41
- @logged_in_users = []
42
- end
43
-
44
- def next_id
45
- @sequence_id += 1
46
- end
47
-
48
- def add_user(username, password, domain, is_admin)
49
- @users[username] = {
50
- :userid => next_id,
51
- :username => username,
52
- :password => password,
53
- :domain => domain,
54
- :is_admin => is_admin
55
- }
56
- end
57
-
58
- def logged_in(username)
59
- @logged_in_users.include?(username)
60
- end
61
-
62
- get "/w/api.php" do
63
- handle_request if params[:action] == 'query'
64
- end
65
-
66
- post "/w/api.php" do
67
- handle_request
68
- end
69
-
70
- def handle_request
71
- begin
72
- halt(503, "Maxlag exceeded") if params[:maxlag].to_i < 0
73
-
74
- @token = ApiToken.new(params)
75
- action = params[:action]
76
- if respond_to?(action)
77
- content_type "application/xml"
78
- return send(action)
79
- end
80
-
81
- halt(404, "Page not found")
82
- rescue FakeMediaWiki::ApiError => e
83
- return api_error_response(e.code, e.message)
84
- end
85
- end
86
-
87
- def import
88
- @token.validate_admin
89
-
90
- api_response do |_|
91
- _.import do
92
- _.page(nil, :title => "Main Page", :ns => 0, :revisions => 0)
93
- _.page(nil, :title => "Template:Header", :ns => 10, :revisions => 1)
94
- end
95
- end
96
- end
97
-
98
- def validate_page_overwrite(current_page)
99
- if current_page && params[:createonly]
100
- raise FakeMediaWiki::ApiError.new("articleexists", "The article you tried to create has been created already")
101
- end
102
- end
103
-
104
- def edit
105
- @token.validate
106
-
107
- title = params[:title]
108
- current_page = @pages.get(title)
109
- validate_page_overwrite(current_page)
110
-
111
- new_page = @pages.add(title, params[:text])
112
- page_info = {:result => "Success", :pageid => new_page[:pageid], :title => new_page[:title], :newrevid => new_page[:pageid]}
113
- if current_page
114
- page_info.merge!(:oldrevid => current_page[:pageid])
115
- else
116
- page_info.merge!(:new => "", :oldrevid => 0)
117
- end
118
-
119
- api_response do |_|
120
- _.edit(nil, page_info)
121
- end
122
- end
123
-
124
- def delete
125
- @token.validate_admin
126
-
127
- title = params[:title]
128
- raise FakeMediaWiki::ApiError.new("missingtitle", "The page you requested doesn't exist") unless @pages.get(title)
129
- @pages.delete(title)
130
-
131
- api_response do |_|
132
- _.delete(nil, {:title => title, :reason => "Default reason"})
133
- end
134
- end
135
-
136
- def undelete
137
- @token.validate_admin
138
-
139
- title = params[:title]
140
- revisions = @pages.undelete(title)
141
- api_response do |_|
142
- _.undelete(nil, {:title => title, :revisions => revisions})
143
- end
144
- end
145
-
146
- def upload
147
- @token.validate
148
-
149
- filename = params[:filename]
150
- @pages.add(filename, params[:file])
151
- api_response do |_|
152
- _.upload(nil, {:filename => filename, :result => "Success"})
153
- end
154
- end
155
-
156
- def parse
157
- page = @pages.get(params[:page])
158
- api_response do |_|
159
- _.parse({ :revid => page ? page[:pageid] : 0}) do
160
- if params[:page] == "Foopage"
161
- _.text('Sample <B>HTML</B> content.' \
162
- '<img width="150" height="150" class="thumbimage" src="http://upload.wikimedia.org/foo/Ruby_logo.svg" alt="Ruby logo.svg"/>' \
163
- '<span class="editsection">[<a title="Edit section: Nomenclature" href="/w/index.php?title=Seat_of_local_government&amp;action=edit&amp;section=1">edit</a>]</span>' \
164
- '<a title="Interpreted language" href="/wiki/Interpreted_language">interpreted language</a>'
165
- )
166
- else
167
- _.text('Sample <B>HTML</B> content.')
168
- end
169
- end
170
- end
171
- end
172
-
173
- include QueryHandling
174
-
175
- def api_response(api_attr = {}, &block)
176
- builder do |_|
177
- if block_given?
178
- _.api(api_attr, &block)
179
- else
180
- _.api(api_attr)
181
- end
182
- end
183
- end
184
-
185
- def api_error_response(code, info)
186
- api_response do |_|
187
- _.error(nil,
188
- :code => code,
189
- :info => info)
190
- end
191
- end
192
-
193
- def query_pages
194
- api_response do |_|
195
- _.query do
196
- _.pages do
197
- requested_page_titles.each do |title|
198
- yield(_, title, @pages.get(title))
199
- end
200
- end
201
- end
202
- end
203
- end
204
-
205
- def get_info
206
- query_pages do |_, title, page|
207
- attributes = { :title => title, :ns => '0'}
208
- if page.nil?
209
- attributes[:missing] = ""
210
- else
211
- attributes[:redirect] = "" if page[:redirect]
212
- end
213
- _.page(nil, attributes)
214
- end
215
- end
216
-
217
- def get_revisions
218
- query_pages do |_, title, page|
219
- if page.nil?
220
- _.page(nil, { :title => title, :ns => '0', :missing => "" })
221
- else
222
- page = page.dup
223
- content = page.delete(:content)
224
- _.page(page.merge({ :ns => 0 })) do
225
- _.revisions do
226
- _.rev(content)
227
- end
228
- end
229
- end
230
- end
231
- end
232
-
233
- def user
234
- username = request.cookies['login']
235
- @users[username] if logged_in(username)
236
- end
237
-
238
- def requested_page_titles
239
- params[:titles].split("|")
240
- end
241
-
242
- def tokens
243
- @token.request(user)
244
-
245
- api_response do |_|
246
- _.tokens(:optionstoken => @token.optionstoken)
247
- end
248
- end
249
-
250
- def get_token
251
- token_str = @token.request(user)
252
- query_pages do |_, title, page|
253
- page = page ? page.dup : {}
254
- page[params[:intoken] + "token"] = token_str if token_str
255
- _.page(nil, page.merge({ :ns => 0 }))
256
- end
257
- end
258
-
259
- def get_undelete_token
260
- @token.set_type 'undelete'
261
- token_str = @token.request(user)
262
- api_response do |_|
263
- _.query do
264
- _.deletedrevs do
265
- requested_page_titles.select {|title| ! @pages.get(title) }.each do |title|
266
- _.page(nil, { :title => title, :token => token_str })
267
- end
268
- end
269
- end
270
- end
271
- end
272
-
273
- def get_userrights_token(username)
274
- @token.set_type 'userrights'
275
- token_str = @token.request(user)
276
-
277
- user_to_manage = @users[username]
278
-
279
- if user_to_manage
280
- api_response do |_|
281
- _.query do
282
- _.users do
283
- _.user(nil, { :name => user_to_manage[:username], :userrightstoken => token_str })
284
- end
285
- end
286
- end
287
- else
288
- api_response do |_|
289
- _.error(nil, { :code => 'nosuchuser', :info => "The user '#{params[:ususer].to_s}' does not exist"} )
290
- end
291
- end
292
- end
293
-
294
- def login
295
- user = @users[params[:lgname]]
296
- if user and user[:domain] == params[:lgdomain]
297
- if params[:lgpassword] == user[:password]
298
- @logged_in_users << user[:username]
299
- response.set_cookie('login', user[:username])
300
- result = { :result => "Success", :lguserid => "1", :lgusername => "Atlasmw"}
301
- else
302
- result = { :result => "WrongPass" }
303
- end
304
- else
305
- result = { :result => "NotExists" }
306
- end
307
-
308
- api_response do |_|
309
- _.login(nil, result)
310
- end
311
- end
312
-
313
- def createaccount
314
- api_response do |_|
315
- @token.request(user)
316
-
317
- if params[:token].present?
318
- @token.validate_admin
319
- add_user(params[:name], params[:password], 'local', false)
320
- _.createaccount(:token => @token.createusertoken, :userid => @users.length, :username => params[:name], :result => 'success')
321
- else
322
- _.createaccount(:token => @token.createusertoken, :result => 'needtoken')
323
- end
324
- end
325
- end
326
-
327
- def options
328
- api_response(:options => 'success')
329
- end
330
-
331
- def userrights
332
- api_response do |_|
333
- _.userrights({:user => params[:user]}) do
334
- _.removed do
335
- params[:remove].split('|').each do |removed_group|
336
- _.group(removed_group)
337
- end
338
- end
339
- _.added do
340
- params[:add].split('|').each do |added_group|
341
- _.group(added_group)
342
- end
343
- end
344
- end
345
- end
346
- end
347
-
348
- end
349
-
350
- class WikiPage
351
-
352
- def initialize(options={})
353
- options.each { |k, v| send("#{k}=", v) }
354
- end
355
-
356
- attr_accessor :content, :author
357
-
358
- end
359
-
360
- end