mediawiki-gateway 0.1.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 (47) hide show
  1. data/.gitignore +3 -0
  2. data/README +12 -0
  3. data/Rakefile +40 -0
  4. data/VERSION +1 -0
  5. data/config/hosts.yml +17 -0
  6. data/doc/classes/MediaWiki.html +189 -0
  7. data/doc/classes/MediaWiki/Config.html +269 -0
  8. data/doc/classes/MediaWiki/Gateway.html +952 -0
  9. data/doc/created.rid +1 -0
  10. data/doc/files/README_txt.html +117 -0
  11. data/doc/files/media_wiki/config_rb.html +108 -0
  12. data/doc/files/media_wiki/gateway_rb.html +113 -0
  13. data/doc/files/media_wiki/utils_rb.html +101 -0
  14. data/doc/files/script/create_page_rb.html +115 -0
  15. data/doc/files/script/delete_book_rb.html +108 -0
  16. data/doc/files/script/export_xml_rb.html +114 -0
  17. data/doc/files/script/get_page_rb.html +114 -0
  18. data/doc/files/script/import_xml_rb.html +114 -0
  19. data/doc/files/script/undelete_page_rb.html +101 -0
  20. data/doc/files/script/upload_commons_rb.html +109 -0
  21. data/doc/files/script/upload_file_rb.html +115 -0
  22. data/doc/fr_class_index.html +29 -0
  23. data/doc/fr_file_index.html +38 -0
  24. data/doc/fr_method_index.html +49 -0
  25. data/doc/index.html +24 -0
  26. data/doc/rdoc-style.css +208 -0
  27. data/lib/media_wiki.rb +3 -0
  28. data/lib/media_wiki/config.rb +69 -0
  29. data/lib/media_wiki/gateway.rb +307 -0
  30. data/lib/media_wiki/utils.rb +18 -0
  31. data/mediawiki-gateway.gemspec +88 -0
  32. data/script/create_page.rb +14 -0
  33. data/script/delete_book.rb +14 -0
  34. data/script/export_xml.rb +14 -0
  35. data/script/get_page.rb +12 -0
  36. data/script/import_xml.rb +14 -0
  37. data/script/run_fake_media_wiki.rb +8 -0
  38. data/script/undelete_page.rb +15 -0
  39. data/script/upload_commons.rb +42 -0
  40. data/script/upload_file.rb +14 -0
  41. data/spec/fake_media_wiki/api_pages.rb +131 -0
  42. data/spec/fake_media_wiki/app.rb +262 -0
  43. data/spec/fake_media_wiki/query_handling.rb +112 -0
  44. data/spec/gateway_spec.old +535 -0
  45. data/spec/gateway_spec.rb +653 -0
  46. data/spec/import-test-data.xml +68 -0
  47. metadata +115 -0
@@ -0,0 +1,18 @@
1
+ module MediaWiki
2
+
3
+ class << self
4
+
5
+ def version
6
+ "0.0.1"
7
+ end
8
+
9
+ # Convert a Wiki page name ("getting there & away") to URI-safe format ("getting_there_%26_away"),
10
+ # taking care not to mangle slashes
11
+ # [wiki] Page name string in Wiki format
12
+ def wiki_to_uri(wiki)
13
+ wiki.to_s.split('/').map {|chunk| CGI.escape(chunk.tr(' ', '_')) }.join('/') if wiki
14
+ end
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,88 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{mediawiki-gateway}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jani Patokallio"]
12
+ s.date = %q{2010-10-01}
13
+ s.description = %q{}
14
+ s.email = %q{jpatokal@iki.fi}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "config/hosts.yml",
24
+ "doc/classes/MediaWiki.html",
25
+ "doc/classes/MediaWiki/Config.html",
26
+ "doc/classes/MediaWiki/Gateway.html",
27
+ "doc/created.rid",
28
+ "doc/files/README_txt.html",
29
+ "doc/files/media_wiki/config_rb.html",
30
+ "doc/files/media_wiki/gateway_rb.html",
31
+ "doc/files/media_wiki/utils_rb.html",
32
+ "doc/files/script/create_page_rb.html",
33
+ "doc/files/script/delete_book_rb.html",
34
+ "doc/files/script/export_xml_rb.html",
35
+ "doc/files/script/get_page_rb.html",
36
+ "doc/files/script/import_xml_rb.html",
37
+ "doc/files/script/undelete_page_rb.html",
38
+ "doc/files/script/upload_commons_rb.html",
39
+ "doc/files/script/upload_file_rb.html",
40
+ "doc/fr_class_index.html",
41
+ "doc/fr_file_index.html",
42
+ "doc/fr_method_index.html",
43
+ "doc/index.html",
44
+ "doc/rdoc-style.css",
45
+ "lib/media_wiki.rb",
46
+ "lib/media_wiki/config.rb",
47
+ "lib/media_wiki/gateway.rb",
48
+ "lib/media_wiki/utils.rb",
49
+ "mediawiki-gateway.gemspec",
50
+ "script/create_page.rb",
51
+ "script/delete_book.rb",
52
+ "script/export_xml.rb",
53
+ "script/get_page.rb",
54
+ "script/import_xml.rb",
55
+ "script/run_fake_media_wiki.rb",
56
+ "script/undelete_page.rb",
57
+ "script/upload_commons.rb",
58
+ "script/upload_file.rb",
59
+ "spec/fake_media_wiki/api_pages.rb",
60
+ "spec/fake_media_wiki/app.rb",
61
+ "spec/fake_media_wiki/query_handling.rb",
62
+ "spec/gateway_spec.old",
63
+ "spec/gateway_spec.rb",
64
+ "spec/import-test-data.xml"
65
+ ]
66
+ s.homepage = %q{http://github.com/jpatokal/media_wiki_gateway}
67
+ s.rdoc_options = ["--charset=UTF-8"]
68
+ s.require_paths = ["lib"]
69
+ s.rubygems_version = %q{1.3.7}
70
+ s.summary = %q{Connect to the mediawiki API}
71
+ s.test_files = [
72
+ "spec/fake_media_wiki/api_pages.rb",
73
+ "spec/fake_media_wiki/app.rb",
74
+ "spec/fake_media_wiki/query_handling.rb",
75
+ "spec/gateway_spec.rb"
76
+ ]
77
+
78
+ if s.respond_to? :specification_version then
79
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
80
+ s.specification_version = 3
81
+
82
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
83
+ else
84
+ end
85
+ else
86
+ end
87
+ end
88
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Sample script for fetching a page's current contents in Wiki markup
4
+ #
5
+ require 'media_wiki/gateway'
6
+ require 'media_wiki/config'
7
+
8
+ config = MediaWiki::Config.new ARGV
9
+ config.abort("Name of article is mandatory.") unless config.article
10
+
11
+ mw = MediaWiki::Gateway.new(config.url, Logger::DEBUG)
12
+ mw.login(config.user, config.pw)
13
+ content = ARGF.read.to_s
14
+ puts mw.create(config.article, content, {:overwrite => true, :summary => config.summary})
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ require 'media_wiki/gateway'
3
+
4
+ if ARGV.length <1
5
+ raise "Syntax: delete_batch.rb <wiki-api-url> <startswith_pattern>"
6
+ end
7
+
8
+ rw = MediaWiki::Gateway.new(ARGV[0])
9
+ rw.list(ARGV[1]).each do |title|
10
+ print "Deleting #{title}..."
11
+ rw.delete(title)
12
+ end
13
+ print "Done."
14
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Export MediaWiki pages as XML
4
+ #
5
+ require 'media_wiki/gateway'
6
+
7
+ if ARGV.length < 3
8
+ raise "Syntax: export_xml.rb <host> <user> <password> [page page page...]"
9
+ end
10
+
11
+ mw = MediaWiki::Gateway.new(ARGV[0])
12
+ mw.login(ARGV[1], ARGV[2])
13
+ print mw.export(ARGV[3..-1])
14
+
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Sample script for fetching a page's current contents in Wiki markup
4
+ #
5
+ require 'media_wiki/gateway'
6
+
7
+ if ARGV.length < 2
8
+ raise "Syntax: get_page.rb <host> <name>"
9
+ end
10
+
11
+ mw = MediaWiki::Gateway.new(ARGV[0])
12
+ puts mw.get(ARGV[1])
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Import a MediaWiki XML dump
4
+ #
5
+ require 'media_wiki/gateway'
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
+
@@ -0,0 +1,8 @@
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
+
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../../config/environment'
3
+
4
+ if ARGV.length <1
5
+ raise "Syntax: undelete.rb <initial-pattern> [environment]\n Sample: undelete.rb 'Book:Shanghai 5' devint"
6
+ end
7
+
8
+ host = ARGV[1] ? "webvip.mediawiki.#{ARGV[1]}.lpo" : LonelyPlanet::OnRails.environment.services[:atlas_mediawiki]
9
+ rw = MediaWiki::Gateway.new(host)
10
+ rw.login('atlasmw', 'wombat')
11
+ # Warning: List only works on existing pages (deleted & reimported), there's a separate unimplemented op for listing currently deleted pages
12
+ rw.list(ARGV[0]).each do |title|
13
+ print "Undeleting #{title}... #{rw.undelete(title)} revisions restored.\n"
14
+ end
15
+ print "Done."
@@ -0,0 +1,42 @@
1
+ require 'lib/media_wiki/gateway'
2
+ require 'lib/media_wiki/config'
3
+
4
+ config = MediaWiki::Config.new(ARGV, "upload")
5
+ file = ARGV[0]
6
+ config.abort("Name of file to upload is mandatory.") unless file
7
+
8
+ mw = MediaWiki::Gateway.new(config.url)
9
+ mw.login(config.user, config.pw)
10
+
11
+ puts "Login successful."
12
+ puts "Description of file:"
13
+ desc = STDIN.gets.chomp
14
+ puts "Date of file:"
15
+ date = STDIN.gets.chomp
16
+ puts "Target filename: (leave blank to use existing name)"
17
+ target = STDIN.gets.chomp
18
+ target = config.target if target.empty?
19
+ puts "Categories, separated by commas:"
20
+ cats = STDIN.gets.chomp.split(",")
21
+ cats = "[[Category:" + cats.join("]]\n[[Category:") + "]]" unless cats.empty?
22
+
23
+ template = <<-TEMPLATE
24
+ == Summary ==
25
+ {{Information
26
+ |Description={{en|1=%DESC%}}
27
+ |Source={{own}}
28
+ |Author=[[User:%USER%|%USER%]]
29
+ |Date=%DATE%
30
+ |Permission=
31
+ |other_versions=
32
+ }}
33
+
34
+ == Licensing ==
35
+ {{self|cc-by-sa-3.0|GFDL}}
36
+
37
+ %CATS%
38
+ TEMPLATE
39
+ desc = template.gsub('%USER%', config.user).gsub('%DESC%', desc).gsub('%DATE%', date).gsub('%CATS%', cats)
40
+ puts "Uploading #{file} to #{target}..."
41
+ mw.upload(file, {:target => target, :description => desc, :summary => "Uploaded by MediaWiki::Gateway"})
42
+ puts "Done."
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Sample script for fetching a page's current contents in Wiki markup
4
+ #
5
+ require 'media_wiki/gateway'
6
+ require 'media_wiki/config'
7
+
8
+ config = MediaWiki::Config.new(ARGV, "upload")
9
+ config.abort("Name of file to upload is mandatory.") unless ARGV[0]
10
+
11
+ mw = MediaWiki::Gateway.new(config.url, Logger::DEBUG)
12
+ mw.login(config.user, config.pw)
13
+ mw.upload(ARGV[0], {:target => config.target, :description => config.desc, :summary => config.summary})
14
+
@@ -0,0 +1,131 @@
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)
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
+ }
32
+ end
33
+
34
+ def get(title)
35
+ @pages[title]
36
+ end
37
+
38
+ def list(prefix)
39
+ @pages.select do |key, page|
40
+ key =~ /^#{prefix}/
41
+ end
42
+ end
43
+
44
+ def search(searchkey, namespaces)
45
+ raise FakeMediaWiki::ApiError.new("srparam-search", "empty search string is not allowed") if searchkey.empty?
46
+ @pages.select do |key, page|
47
+ page[:content] =~ /#{searchkey}/ and namespaces.include? page[:namespace].to_s
48
+ end
49
+ end
50
+
51
+ def delete(title)
52
+ @pages.delete(title)
53
+ end
54
+
55
+ def undelete(title)
56
+ if @pages[title]
57
+ 0
58
+ else
59
+ add(title, "Undeleted content")
60
+ 1
61
+ end
62
+ end
63
+ end
64
+
65
+ class ApiToken
66
+ ADMIN_TOKEN = "admin_token+\\"
67
+ REGULAR_TOKEN = "regular_token+\\"
68
+ BLANK_TOKEN = "+\\"
69
+
70
+ def initialize(params)
71
+ @token_str = params[:token]
72
+ @token_in = params[:intoken]
73
+ end
74
+
75
+ def set_type(type)
76
+ @token_in = type
77
+ end
78
+
79
+ def validate
80
+ unless @token_str
81
+ raise FakeMediaWiki::ApiError.new("notoken", "The token parameter must be set")
82
+ end
83
+ end
84
+
85
+ def validate_admin
86
+ validate
87
+ if @token_str != ADMIN_TOKEN
88
+ raise FakeMediaWiki::ApiError.new("badtoken", "Invalid token")
89
+ end
90
+ end
91
+
92
+ def request(user)
93
+ @user = user
94
+ respond_to?(requested_token_type) ? send(requested_token_type) : nil
95
+ end
96
+
97
+ def requested_token_type
98
+ "#{@token_in}token".to_sym
99
+ end
100
+
101
+ def importtoken
102
+ if @user && @user[:is_admin]
103
+ ADMIN_TOKEN
104
+ else
105
+ nil
106
+ end
107
+ end
108
+ alias_method :deletetoken, :importtoken
109
+ alias_method :undeletetoken, :importtoken
110
+
111
+ def edittoken
112
+ if @user
113
+ REGULAR_TOKEN
114
+ else
115
+ BLANK_TOKEN
116
+ end
117
+ end
118
+ end
119
+
120
+ class ApiError < StandardError
121
+
122
+ attr_reader :code, :message
123
+
124
+ def initialize(code, message)
125
+ @code = code
126
+ @message = message
127
+ end
128
+
129
+ end
130
+
131
+ end
@@ -0,0 +1,262 @@
1
+ require 'rubygems'
2
+ require 'sinatra/base'
3
+ require 'spec/fake_media_wiki/api_pages'
4
+ require 'spec/fake_media_wiki/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('Level/Level/Index', '{{#include:Foo}} {{#include:Bar}}')
32
+ @pages.add_namespace(100, "Book")
33
+ @pages.add('Book:Italy', 'Introduction')
34
+ @pages.add_namespace(200, "Sandbox")
35
+
36
+ @extensions = { 'FooExtension' => 'r1', 'BarExtension' => 'r2' }
37
+
38
+ @logged_in_users = []
39
+ end
40
+
41
+ def next_id
42
+ @sequence_id += 1
43
+ end
44
+
45
+ def add_user(username, password, domain, is_admin)
46
+ @users[username] = {
47
+ :userid => next_id,
48
+ :username => username,
49
+ :password => password,
50
+ :domain => domain,
51
+ :is_admin => is_admin
52
+ }
53
+ end
54
+
55
+ def logged_in(username)
56
+ @logged_in_users.include?(username)
57
+ end
58
+
59
+ post "/w/api.php" do
60
+ begin
61
+ @token = ApiToken.new(params)
62
+ action = params[:action]
63
+ if respond_to?(action)
64
+ content_type "application/xml"
65
+ return send(action)
66
+ end
67
+
68
+ halt(404, "Page not found")
69
+ rescue FakeMediaWiki::ApiError => e
70
+ return api_error_response(e.code, e.message)
71
+ end
72
+ end
73
+
74
+ def import
75
+ @token.validate_admin
76
+
77
+ api_response do |_|
78
+ _.import do
79
+ _.page(nil, :title => "Main Page", :ns => 0, :revisions => 0)
80
+ _.page(nil, :title => "Template:Header", :ns => 10, :revisions => 1)
81
+ end
82
+ end
83
+ end
84
+
85
+ def validate_page_overwrite(current_page)
86
+ if current_page && params[:createonly]
87
+ raise FakeMediaWiki::ApiError.new("articleexists", "The article you tried to create has been created already")
88
+ end
89
+ end
90
+
91
+ def edit
92
+ @token.validate
93
+
94
+ title = params[:title]
95
+ current_page = @pages.get(title)
96
+ validate_page_overwrite(current_page)
97
+
98
+ new_page = @pages.add(title, params[:text])
99
+ page_info = {:result => "Success", :pageid => new_page[:pageid], :title => new_page[:title], :newrevid => new_page[:pageid]}
100
+ if current_page
101
+ page_info.merge!(:oldrevid => current_page[:pageid])
102
+ else
103
+ page_info.merge!(:new => "", :oldrevid => 0)
104
+ end
105
+
106
+ api_response do |_|
107
+ _.edit(nil, page_info)
108
+ end
109
+ end
110
+
111
+ def delete
112
+ @token.validate_admin
113
+
114
+ title = params[:title]
115
+ raise FakeMediaWiki::ApiError.new("missingtitle", "The page you requested doesn't exist") unless @pages.get(title)
116
+ @pages.delete(title)
117
+
118
+ api_response do |_|
119
+ _.delete(nil, {:title => title, :reason => "Default reason"})
120
+ end
121
+ end
122
+
123
+ def undelete
124
+ @token.validate_admin
125
+
126
+ title = params[:title]
127
+ revisions = @pages.undelete(title)
128
+ api_response do |_|
129
+ _.undelete(nil, {:title => title, :revisions => revisions})
130
+ end
131
+ end
132
+
133
+ def upload
134
+ @token.validate
135
+
136
+ filename = params[:filename]
137
+ @pages.add(filename, params[:file])
138
+ api_response do |_|
139
+ _.upload(nil, {:filename => filename, :result => "Success"})
140
+ end
141
+ end
142
+
143
+ def parse
144
+ page = @pages.get(params[:page])
145
+ api_response do |_|
146
+ _.parse({ :revid => page ? page[:pageid] : 0}) do
147
+ _.text("Sample <B>HTML</B> content")
148
+ end
149
+ end
150
+ end
151
+
152
+ include QueryHandling
153
+
154
+ def api_response
155
+ builder do |_|
156
+ _.api do |_|
157
+ yield(_)
158
+ end
159
+ end
160
+ end
161
+
162
+ def api_error_response(code, info)
163
+ api_response do |_|
164
+ _.error(nil,
165
+ :code => code,
166
+ :info => info)
167
+ end
168
+ end
169
+
170
+ def query_pages
171
+ api_response do |_|
172
+ _.query do
173
+ _.pages do
174
+ requested_page_titles.each do |title|
175
+ yield(_, title, @pages.get(title))
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ def get_revisions
183
+ query_pages do |_, title, page|
184
+ if page.nil?
185
+ _.page(nil, { :title => title, :ns => '0', :missing => "" })
186
+ else
187
+ page = page.dup
188
+ content = page.delete(:content)
189
+ _.page(page.merge({ :ns => 0 })) do
190
+ _.revisions do
191
+ _.rev(content)
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ end
198
+
199
+ def user
200
+ username = request.cookies['login']
201
+ @users[username] if logged_in(username)
202
+ end
203
+
204
+ def requested_page_titles
205
+ params[:titles].split("|")
206
+ end
207
+
208
+ def get_token
209
+ token_str = @token.request(user)
210
+ query_pages do |_, title, page|
211
+ page = page ? page.dup : {}
212
+ page[params[:intoken] + "token"] = token_str if token_str
213
+ _.page(nil, page.merge({ :ns => 0 }))
214
+ end
215
+ end
216
+
217
+ def get_undelete_token
218
+ @token.set_type 'undelete'
219
+ token_str = @token.request(user)
220
+ api_response do |_|
221
+ _.query do
222
+ _.deletedrevs do
223
+ requested_page_titles.select {|title| ! @pages.get(title) }.each do |title|
224
+ _.page(nil, { :title => title, :token => token_str })
225
+ end
226
+ end
227
+ end
228
+ end
229
+ end
230
+
231
+ def login
232
+ user = @users[params[:lgname]]
233
+ if user and user[:domain] == params[:lgdomain]
234
+ if params[:lgpassword] == user[:password]
235
+ @logged_in_users << user[:username]
236
+ response.set_cookie('login', user[:username])
237
+ result = { :result => "Success", :lguserid => "1", :lgusername => "Atlasmw"}
238
+ else
239
+ result = { :result => "WrongPass" }
240
+ end
241
+ else
242
+ result = { :result => "NotExists" }
243
+ end
244
+
245
+ api_response do |_|
246
+ _.login(nil, result)
247
+ end
248
+ end
249
+
250
+ end
251
+
252
+ class WikiPage
253
+
254
+ def initialize(options={})
255
+ options.each { |k, v| send("#{k}=", v) }
256
+ end
257
+
258
+ attr_accessor :content, :author
259
+
260
+ end
261
+
262
+ end