wikibot 0.2.0 → 0.2.1.1

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.
data/Manifest CHANGED
@@ -6,4 +6,5 @@ lib/hash_ext.rb
6
6
  lib/openhash.rb
7
7
  lib/page.rb
8
8
  lib/wikibot.rb
9
+ wikibot.gemspec
9
10
  Manifest
data/README.textile CHANGED
@@ -4,14 +4,16 @@ h2. About
4
4
 
5
5
  WikiBot was originally a PHP-based framework for bots I run on Wikipedia, however when it broke due to changes in mediawiki code, I decided to rewrite it in Ruby, using the MediaWiki API instead of screen-scraping. This is the result.
6
6
 
7
- As you'll notice, the features it provides are rather sparse at the moment, as I've only been adding features that I require. When I get more time, I'll flesh it out more.
7
+ As you'll notice, the features it provides are somewhat sparse at the moment, as I've only been adding features that I require. When I get more time, I'll flesh it out more.
8
8
 
9
9
  h2. Gem Requirements
10
10
 
11
11
  * "taf2-curb":taf2 (a fork of curb; using the base curb gem might work but is untested)
12
12
  * "xml-simple":xml
13
13
  * "deep_merge":dm
14
+ * "andand":aa
14
15
 
15
16
  [taf2]http://github.com/taf2/curb/tree/master
16
17
  [xml]http://xml-simple.rubyforge.org/
17
18
  [dm]http://rubyforge.org/projects/deepmerge/
19
+ [aa]http://andand.rubyforge.org/
data/Rakefile CHANGED
@@ -2,14 +2,14 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('wikibot', '0.2.0') do |p|
5
+ Echoe.new('wikibot', '0.2.1.1') do |p|
6
6
  p.description = "Mediawiki Bot framework"
7
7
  p.url = "http://github.com/dvandersluis/wiki_bot"
8
8
  p.author = "Daniel Vandersluis"
9
9
  p.email = "daniel@codexed.com"
10
10
  p.ignore_pattern = ["tmp/*", "script/*"]
11
11
  p.development_dependencies = []
12
- p.runtime_dependencies = ['taf2-curb', 'xml-simple', 'deep_merge']
12
+ p.runtime_dependencies = ['taf2-curb >=0.5.4.0', 'xml-simple >=1.0.12', 'deep_merge >=0.1.0', 'andand >=1.3.1']
13
13
  end
14
14
 
15
15
  Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/lib/category.rb CHANGED
@@ -1,48 +1,54 @@
1
1
  module WikiBot
2
2
  class Category < Page
3
3
  def category_info
4
- data = {
5
- :action => :query,
6
- :titles => @name,
7
- :prop => :categoryinfo
8
- }
4
+ @category_info ||= begin
5
+ data = {
6
+ :action => :query,
7
+ :titles => @name,
8
+ :prop => :categoryinfo
9
+ }
9
10
 
10
- # The query API returns nothing for an empty cat, so we'll return a hash with all the normal
11
- # properties set to 0 instead
12
- empty_cat = { "pages" => 0, "size" => 0, "files" => 0, "subcats" => 0, "hidden" => "" }
13
- @wiki_bot.query_api(:get, data).query.pages.page.categoryinfo || empty_cat
11
+ # The query API returns nothing for an empty cat, so we'll return a hash with all the normal
12
+ # properties set to 0 instead
13
+ empty_cat = { :pages => 0, :size => 0, :files => 0, :subcats => 0, :hidden => "" }.to_openhash
14
+ @wiki_bot.query_api(:get, data).query.pages.page.categoryinfo || empty_cat
15
+ end
14
16
  end
15
17
 
16
18
  def members(sort = :sortkey, dir = :desc, namespace = nil)
17
- data = {
18
- :action => :query,
19
- :list => :categorymembers,
20
- :cmtitle => @name,
21
- :cmsort => sort,
22
- :cmdir => dir,
23
- :cmnamespace => namespace
24
- }
19
+ @members ||= begin
20
+ data = {
21
+ :action => :query,
22
+ :list => :categorymembers,
23
+ :cmtitle => @name,
24
+ :cmsort => sort,
25
+ :cmdir => dir,
26
+ :cmnamespace => namespace
27
+ }
25
28
 
26
- @wiki_bot.query_api(:get, data).query.categorymembers.cm
29
+ @wiki_bot.query_api(:get, data).query.categorymembers.cm.map { |m| Page.new(@wiki_bot, m["title"]) }
30
+ end
27
31
  end
28
32
 
29
33
  # Returns a hash of how many pages live in a category
30
34
  def count(include_subcats = false)
31
- out = {}
32
- ci = category_info
35
+ @count ||= begin
36
+ out = {}
37
+ ci = category_info
33
38
 
34
- out[@name] = {
35
- :pages => ci.pages.to_i
36
- }
39
+ out[@name] = {
40
+ :pages => ci.pages.to_i
41
+ }
37
42
 
38
- if include_subcats and ci.subcats.to_i > 0
39
- out[@name][:subcats] = {}
40
- members.each do |m|
41
- out[@name][:subcats].merge! WikiPage.new(@wiki_bot, m.title).count(include_subcats)
43
+ if include_subcats and ci.subcats.to_i > 0
44
+ out[@name][:subcats] = {}
45
+ members.each do |m|
46
+ out[@name][:subcats].merge! self.class.new(@wiki_bot, m["title"]).count(include_subcats)
47
+ end
42
48
  end
43
- end
44
49
 
45
- out
50
+ out
51
+ end
46
52
  end
47
53
  end
48
54
  end
data/lib/hash_ext.rb CHANGED
@@ -14,4 +14,8 @@ class Hash
14
14
  memo.push "#{CGI::escape(key.to_s)}=#{CGI::escape(val.to_s)}"
15
15
  end.join("&")
16
16
  end
17
+
18
+ def to_openhash
19
+ OpenHash.new(self)
20
+ end
17
21
  end
data/lib/openhash.rb CHANGED
@@ -14,10 +14,14 @@ class OpenHash < Hash
14
14
  # Allow hash properties to be referenced by dot notation
15
15
  def method_missing(name, *args)
16
16
  name = name.to_s
17
- if self.include? name
18
- self[name]
19
- elsif self.include? name.to_sym
20
- self[name.to_sym]
17
+ k = name.sub(/[?!=]$/, '')
18
+
19
+ if name =~ /=$/ && !args.empty?
20
+ self[k] = args.first
21
+ elsif self.include? k
22
+ self[k]
23
+ elsif self.include? k.to_sym
24
+ self[k.to_sym]
21
25
  end
22
26
  end
23
27
  end
data/lib/page.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'rubygems'
2
+ require 'andand'
3
+
1
4
  module WikiBot
2
5
  class Page
3
6
  class WriteError < StandardError; end
@@ -12,7 +15,8 @@ module WikiBot
12
15
 
13
16
  ###
14
17
  # Read from page
15
- def content
18
+ def content(reload = false)
19
+ @content = nil if reload
16
20
  @content ||= begin
17
21
  data = {
18
22
  :action => :query,
@@ -26,7 +30,8 @@ module WikiBot
26
30
  end
27
31
 
28
32
  # Parse page content
29
- def text
33
+ def text(reload = false)
34
+ @text = nil if reload
30
35
  @text ||= begin
31
36
  data = {
32
37
  :action => :parse,
@@ -42,7 +47,8 @@ module WikiBot
42
47
  def categories(show = :all)
43
48
  # Cache hidden and non-hidden categories separately
44
49
  @categories ||= begin
45
- puts "Loading category data"
50
+ @category_names = nil # Reset @category_names
51
+
46
52
  data = {
47
53
  :action => :query,
48
54
  :titles => @name,
@@ -50,9 +56,10 @@ module WikiBot
50
56
  :clshow => "!hidden"
51
57
  }
52
58
 
53
- categories = @wiki_bot.query_api(:get, data).query.pages.page.categories.cl
59
+ categories = @wiki_bot.query_api(:get, data).query.pages.page.categories.andand.cl || []
60
+
54
61
  categories = categories.inject([]) do |memo, category|
55
- memo.push(WikiBot::Category.new(@wiki_bot, category.title))
62
+ memo.push(WikiBot::Category.new(@wiki_bot, category["title"]))
56
63
  end
57
64
 
58
65
  data = {
@@ -62,9 +69,9 @@ module WikiBot
62
69
  :clshow => "hidden"
63
70
  }
64
71
 
65
- hidden_categories = @wiki_bot.query_api(:get, data).query.pages.page.categories.cl
72
+ hidden_categories = @wiki_bot.query_api(:get, data).query.pages.page.categories.andand.cl || []
66
73
  hidden_categories = hidden_categories.inject([]) do |memo, category|
67
- memo.push(WikiBot::Category.new(@wiki_bot, category.title))
74
+ memo.push(WikiBot::Category.new(@wiki_bot, category["title"]))
68
75
  end
69
76
 
70
77
  {:nonhidden => categories, :hidden => hidden_categories}
@@ -76,7 +83,7 @@ module WikiBot
76
83
  end
77
84
 
78
85
  def category_names(show = :all)
79
- categories(show).map{ |c| c.name }
86
+ @category_names ||= categories(show).map{ |c| c.name }
80
87
  end
81
88
 
82
89
  ###
data/lib/wikibot.rb CHANGED
@@ -28,20 +28,19 @@ module WikiBot
28
28
  class Bot
29
29
  class LoginError < StandardError; end
30
30
 
31
- @@version = "0.2.0" # WikiBot version
31
+ @@version = "0.2.1" # WikiBot version
32
32
 
33
33
  cattr_reader :version
34
- cattr_accessor :cookiejar # Filename where cookies will be stored
34
+ #cattr_accessor :cookiejar # Filename where cookies will be stored
35
35
 
36
36
  attr_reader :config
37
- attr_reader :api_hits
38
- attr_accessor :page_writes
39
- attr_accessor :debug # In debug mode, no writes will be made to the wiki
40
- attr_accessor :readonly # Writes will not be made
37
+ attr_reader :api_hits # How many times the API was queried
38
+ attr_accessor :page_writes # How many write operations were performed
39
+ attr_accessor :debug # In debug mode, no writes will be made to the wiki
40
+ attr_accessor :readonly # Writes will not be made
41
41
 
42
42
  def initialize(username, password, options = {})
43
- @config = Hash.new
44
- @cookies = Hash.new
43
+ @cookies = OpenHash.new
45
44
  @api_hits = 0
46
45
  @page_writes = 0
47
46
 
@@ -55,11 +54,11 @@ module WikiBot
55
54
  :password => password,
56
55
  :api => api,
57
56
  :logged_in => false
58
- }
57
+ }.to_openhash
59
58
 
60
59
  # Set up cURL:
61
60
  @curl = Curl::Easy.new do |c|
62
- c.headers["User-Agent"] = "Mozilla/5.0 Curb/Taf2/0.2.8 WikiBot/#{config[:username]}/#{@@version}"
61
+ c.headers["User-Agent"] = "Mozilla/5.0 Curb/Taf2/0.2.8 WikiBot/#{@config.username}/#{@@version}"
63
62
  #c.enable_cookies = true
64
63
  #c.cookiejar = @@cookiejar
65
64
  end
@@ -68,10 +67,13 @@ module WikiBot
68
67
  end
69
68
 
70
69
  def query_api(method, raw_data = {})
71
- url = @config[:api]
70
+ # Send a query to the API and handle the response
71
+ url = @config.api
72
+ raw_data = raw_data.to_openhash
72
73
 
73
- raw_data[:format] = :xml if !(raw_data.include? :format and raw_data.include? 'format')
74
+ raw_data[:format] = :xml if raw_data.format.nil?
74
75
 
76
+ # Setup cookie headers for the request
75
77
  @curl.headers["Cookie"] = @cookies.inject([]) do |memo, pair|
76
78
  key, val = pair
77
79
  memo.push(CGI::escape(key) + "=" + CGI::escape(val))
@@ -107,11 +109,9 @@ module WikiBot
107
109
  data.length
108
110
  end
109
111
 
110
- if data.nil? or (data.is_a? Array and data.empty?)
111
- @curl.send("http_#{method}".to_sym)
112
- else
113
- @curl.send("http_#{method}".to_sym, *data)
114
- end
112
+ params = ["http_#{method}".to_sym]
113
+ params.push(*data) unless data.nil? or (data.is_a? Array and data.empty?)
114
+ @curl.send(*params)
115
115
  @api_hits += 1
116
116
 
117
117
  raise CurbError.new(@curl) unless @curl.response_code == 200
@@ -127,16 +127,20 @@ module WikiBot
127
127
  end
128
128
  end
129
129
 
130
- OpenHash.new(response_xml)
130
+ response_xml.to_openhash
131
131
  end
132
132
 
133
+ def logged_in?
134
+ @config.logged_in
135
+ end
136
+
133
137
  def login
134
- return if @config[:logged_in]
138
+ return if logged_in?
135
139
 
136
140
  data = {
137
141
  :action => :login,
138
- :lgname => @config[:username],
139
- :lgpassword => @config[:password]
142
+ :lgname => @config.username,
143
+ :lgpassword => @config.password
140
144
  }
141
145
 
142
146
  response = query_api(:post, data).login
@@ -144,8 +148,8 @@ module WikiBot
144
148
  if response.result == "NeedToken"
145
149
  data = {
146
150
  :action => :login,
147
- :lgname => @config[:username],
148
- :lgpassword => @config[:password],
151
+ :lgname => @config.username,
152
+ :lgpassword => @config.password,
149
153
  :lgtoken => response.token
150
154
  }
151
155
 
@@ -154,20 +158,21 @@ module WikiBot
154
158
 
155
159
  raise LoginError, response.result unless response.result == "Success"
156
160
 
157
- @config[:cookieprefix] = response.cookieprefix
158
- @config[:logged_in] = true
161
+ @config.cookieprefix = response.cookieprefix
162
+ @config.logged_in = true
159
163
  end
160
164
 
161
165
  def logout
162
- return if !@config[:logged_in]
166
+ return unless logged_in?
163
167
 
164
168
  query_api(:post, { :action => :logout })
165
- @config[:logged_in] = false
166
- @config[:edit_token] = nil
169
+ @config.logged_in = false
170
+ @config.edit_token = nil
167
171
  end
168
172
 
169
173
  def edit_token(page = "Main Page")
170
- @config[:edit_token] ||= begin
174
+ return nil unless logged_in?
175
+ @config.edit_token ||= begin
171
176
  data = {
172
177
  :action => :query,
173
178
  :prop => :info,
data/wikibot.gemspec CHANGED
@@ -2,20 +2,20 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{wikibot}
5
- s.version = "0.2.0"
5
+ s.version = "0.2.1.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Daniel Vandersluis"]
9
- s.date = %q{2010-04-09}
9
+ s.date = %q{2010-07-29}
10
10
  s.description = %q{Mediawiki Bot framework}
11
11
  s.email = %q{daniel@codexed.com}
12
12
  s.extra_rdoc_files = ["README.textile", "lib/category.rb", "lib/class_ext.rb", "lib/hash_ext.rb", "lib/openhash.rb", "lib/page.rb", "lib/wikibot.rb"]
13
- s.files = ["README.textile", "Rakefile", "lib/category.rb", "lib/class_ext.rb", "lib/hash_ext.rb", "lib/openhash.rb", "lib/page.rb", "lib/wikibot.rb", "Manifest", "wikibot.gemspec"]
13
+ s.files = ["README.textile", "Rakefile", "lib/category.rb", "lib/class_ext.rb", "lib/hash_ext.rb", "lib/openhash.rb", "lib/page.rb", "lib/wikibot.rb", "wikibot.gemspec", "Manifest"]
14
14
  s.homepage = %q{http://github.com/dvandersluis/wiki_bot}
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Wikibot", "--main", "README.textile"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{wikibot}
18
- s.rubygems_version = %q{1.3.5}
18
+ s.rubygems_version = %q{1.3.6}
19
19
  s.summary = %q{Mediawiki Bot framework}
20
20
 
21
21
  if s.respond_to? :specification_version then
@@ -23,17 +23,20 @@ Gem::Specification.new do |s|
23
23
  s.specification_version = 3
24
24
 
25
25
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
- s.add_runtime_dependency(%q<taf2-curb>, [">= 0"])
27
- s.add_runtime_dependency(%q<xml-simple>, [">= 0"])
28
- s.add_runtime_dependency(%q<deep_merge>, [">= 0"])
26
+ s.add_runtime_dependency(%q<taf2-curb>, [">= 0.5.4.0"])
27
+ s.add_runtime_dependency(%q<xml-simple>, [">= 1.0.12"])
28
+ s.add_runtime_dependency(%q<deep_merge>, [">= 0.1.0"])
29
+ s.add_runtime_dependency(%q<andand>, [">= 1.3.1"])
29
30
  else
30
- s.add_dependency(%q<taf2-curb>, [">= 0"])
31
- s.add_dependency(%q<xml-simple>, [">= 0"])
32
- s.add_dependency(%q<deep_merge>, [">= 0"])
31
+ s.add_dependency(%q<taf2-curb>, [">= 0.5.4.0"])
32
+ s.add_dependency(%q<xml-simple>, [">= 1.0.12"])
33
+ s.add_dependency(%q<deep_merge>, [">= 0.1.0"])
34
+ s.add_dependency(%q<andand>, [">= 1.3.1"])
33
35
  end
34
36
  else
35
- s.add_dependency(%q<taf2-curb>, [">= 0"])
36
- s.add_dependency(%q<xml-simple>, [">= 0"])
37
- s.add_dependency(%q<deep_merge>, [">= 0"])
37
+ s.add_dependency(%q<taf2-curb>, [">= 0.5.4.0"])
38
+ s.add_dependency(%q<xml-simple>, [">= 1.0.12"])
39
+ s.add_dependency(%q<deep_merge>, [">= 0.1.0"])
40
+ s.add_dependency(%q<andand>, [">= 1.3.1"])
38
41
  end
39
42
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wikibot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 1
9
+ - 1
10
+ version: 0.2.1.1
5
11
  platform: ruby
6
12
  authors:
7
13
  - Daniel Vandersluis
@@ -9,39 +15,66 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-04-09 00:00:00 -06:00
18
+ date: 2010-07-29 00:00:00 -06:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: taf2-curb
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
20
25
  requirements:
21
26
  - - ">="
22
27
  - !ruby/object:Gem::Version
23
- version: "0"
24
- version:
28
+ segments:
29
+ - 0
30
+ - 5
31
+ - 4
32
+ - 0
33
+ version: 0.5.4.0
34
+ type: :runtime
35
+ version_requirements: *id001
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: xml-simple
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
30
40
  requirements:
31
41
  - - ">="
32
42
  - !ruby/object:Gem::Version
33
- version: "0"
34
- version:
43
+ segments:
44
+ - 1
45
+ - 0
46
+ - 12
47
+ version: 1.0.12
48
+ type: :runtime
49
+ version_requirements: *id002
35
50
  - !ruby/object:Gem::Dependency
36
51
  name: deep_merge
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 0
59
+ - 1
60
+ - 0
61
+ version: 0.1.0
37
62
  type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: andand
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
40
68
  requirements:
41
69
  - - ">="
42
70
  - !ruby/object:Gem::Version
43
- version: "0"
44
- version:
71
+ segments:
72
+ - 1
73
+ - 3
74
+ - 1
75
+ version: 1.3.1
76
+ type: :runtime
77
+ version_requirements: *id004
45
78
  description: Mediawiki Bot framework
46
79
  email: daniel@codexed.com
47
80
  executables: []
@@ -65,8 +98,8 @@ files:
65
98
  - lib/openhash.rb
66
99
  - lib/page.rb
67
100
  - lib/wikibot.rb
68
- - Manifest
69
101
  - wikibot.gemspec
102
+ - Manifest
70
103
  has_rdoc: true
71
104
  homepage: http://github.com/dvandersluis/wiki_bot
72
105
  licenses: []
@@ -85,18 +118,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
118
  requirements:
86
119
  - - ">="
87
120
  - !ruby/object:Gem::Version
121
+ segments:
122
+ - 0
88
123
  version: "0"
89
- version:
90
124
  required_rubygems_version: !ruby/object:Gem::Requirement
91
125
  requirements:
92
126
  - - ">="
93
127
  - !ruby/object:Gem::Version
128
+ segments:
129
+ - 1
130
+ - 2
94
131
  version: "1.2"
95
- version:
96
132
  requirements: []
97
133
 
98
134
  rubyforge_project: wikibot
99
- rubygems_version: 1.3.5
135
+ rubygems_version: 1.3.6
100
136
  signing_key:
101
137
  specification_version: 3
102
138
  summary: Mediawiki Bot framework