wikibot 0.2.0 → 0.2.1.1

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