vbulletin 0.0.4

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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Lloyd Pick
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,27 @@
1
+ = vBulletin
2
+
3
+ This is a gem to help extract data from vBulletin Forums, specifically those which you have no control over. It attempts
4
+ to fetch the requested data as quickly as possible while using the least amount of bandwidth overall.
5
+
6
+ == Examples
7
+
8
+ api = VBulletin::Base.new('http://forums.heroesofnewerth.com') # no trailing slash
9
+ api.login('Limi', 'md5_hash_of_your_password_goes_here')
10
+ posts = api.search.find_posts_by_user_id(6)
11
+ => [#<VBulletin::Post:0xb73a8d1c @created_at="Yesterday, 10:56 PM", @author_id="6", @content="This is a post on a thread", @id="12171587", @author_name="Maliken">, #<VBulletin::Post:0xb738e2dc @created_at="Yesterday, 05:06 PM", @author_id="6", @content="This is another post", @id="12170283", @author_name="Maliken">]
12
+
13
+ posts.first.thread
14
+ => #<VBulletin::Thread:0xb73b2768 @title="Hon needs Blizzard and Starfall", @id="149612", @created_at="07-19-2010 07:20 PM">
15
+
16
+ == Note on Patches/Pull Requests
17
+
18
+ * Fork the project.
19
+ * Make your feature addition or bug fix.
20
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
21
+ * Commit, do not mess with rakefile, version, or history.
22
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
23
+ * Send me a pull request. Bonus points for topic branches.
24
+
25
+ == Copyright
26
+
27
+ Copyright (c) 2010 Lloyd Pick. See LICENSE for details.
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "vbulletin"
8
+ gem.summary = %Q{Provides a way to access data of a vBulletin forum}
9
+ gem.description = %Q{Provides a way to access data of a vBulletin forum, specifically ones that you don't control}
10
+ gem.email = "lloydpick@gmail.com"
11
+ gem.homepage = "http://github.com/lloydpick/vbulletin"
12
+ gem.authors = ["Lloyd Pick"]
13
+ gem.version = '0.0.4'
14
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ gem.add_dependency('mechanize', '1.0.0')
17
+ gem.add_dependency('nokogiri', '1.4.2')
18
+ gem.add_dependency('activesupport')
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/test_*.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ begin
33
+ require 'rcov/rcovtask'
34
+ Rcov::RcovTask.new do |test|
35
+ test.libs << 'test'
36
+ test.pattern = 'test/**/test_*.rb'
37
+ test.verbose = true
38
+ end
39
+ rescue LoadError
40
+ task :rcov do
41
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
42
+ end
43
+ end
44
+
45
+ task :test => :check_dependencies
46
+
47
+ task :default => :test
48
+
49
+ require 'rake/rdoctask'
50
+ Rake::RDocTask.new do |rdoc|
51
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "vbulletin #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+
3
+ gem 'nokogiri', '1.4.2'
4
+ gem 'mechanize', '1.0.0'
5
+ gem 'activesupport'
6
+ require 'mechanize'
7
+
8
+ require 'uri'
9
+ require 'cgi'
10
+
11
+ require "#{File.dirname(__FILE__)}/vbulletin/base.rb"
12
+ require "#{File.dirname(__FILE__)}/vbulletin/forum.rb"
13
+ require "#{File.dirname(__FILE__)}/vbulletin/search.rb"
14
+ require "#{File.dirname(__FILE__)}/vbulletin/thread.rb"
15
+ require "#{File.dirname(__FILE__)}/vbulletin/post.rb"
@@ -0,0 +1,75 @@
1
+ module VBulletin
2
+ class Base
3
+
4
+ attr_accessor :uri, :mechanize, :debug
5
+
6
+ def initialize(url, options = {})
7
+ @uri = URI::parse(url)
8
+ @debug = options[:debug] || false
9
+ @api = self
10
+ end
11
+
12
+ def login(username, password)
13
+ mechanize = Mechanize.new
14
+ mechanize.get(construct_full_url('login.php', { 'do' => 'login' })) do |login_page|
15
+
16
+ # Submit the login form
17
+ login_page.form_with(:action => 'login.php?do=login') do |f|
18
+ f.vb_login_username = username
19
+ f.vb_login_md5password = password
20
+ end.click_button
21
+
22
+ end
23
+
24
+ #raise mechanize.inspect
25
+ self.mechanize = mechanize
26
+
27
+ end
28
+
29
+ def get_index
30
+ index = self.mechanize.get(construct_full_url('index.php'))
31
+ puts index.body
32
+ end
33
+
34
+ def forums
35
+ VBulletin::Forum.new(self)
36
+ end
37
+
38
+ def search
39
+ VBulletin::Search.new(self)
40
+ end
41
+
42
+
43
+
44
+ def construct_url(path, params = nil)
45
+ "#{self.uri.path}/#{path}#{VBulletin::Base.hash2get(params)}"
46
+ end
47
+
48
+ def construct_full_url(path, params = nil)
49
+ "#{self.uri.scheme}://#{self.uri.host}#{construct_url(path, params)}"
50
+ end
51
+
52
+ private
53
+ # Converts a hash to a GET string
54
+ def self.hash2get(h)
55
+ unless h.nil?
56
+ get_string = "?"
57
+ h.each_pair do |key, value|
58
+ if value.is_a?(String)
59
+ get_string += "#{key.to_s}=#{CGI::escape(value.to_s)}&"
60
+ elsif value.is_a?(Integer)
61
+ get_string += "#{key.to_s}=#{CGI::escape(value.to_s)}&"
62
+ elsif value.is_a?(Array)
63
+ value.each do |vals|
64
+ get_string += "#{key.to_s}=#{CGI::escape(vals.to_s)}&"
65
+ end
66
+ end
67
+ end
68
+ get_string
69
+ end
70
+ end
71
+
72
+
73
+
74
+ end
75
+ end
@@ -0,0 +1,21 @@
1
+ module VBulletin
2
+ class Forum < Base
3
+
4
+ def initialize(api, options = {})
5
+ @api = api
6
+ @debug = options[:debug] || false
7
+ end
8
+
9
+ def all
10
+ parse_index(@api.construct_full_url("index.php"))
11
+ end
12
+
13
+ private
14
+ def parse_index(url)
15
+ if (result = @api.mechanize.get(url))
16
+ puts result.body
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ module VBulletin
2
+ class Post < Base
3
+
4
+ attr_reader :id, :author_id, :author_name, :content, :api, :created_at
5
+
6
+ def initialize(api, *params)
7
+ @api = api
8
+ params.each do |key|
9
+ key.each { |k, v| instance_variable_set("@#{k}", v) }
10
+ end
11
+ end
12
+
13
+ def created_at
14
+ # Yesterday at 05:06 PM
15
+ @created_at.gsub!('Yesterday', Date.yesterday.strftime("%m-%d-%Y"))
16
+ @created_at.gsub!(',', '')
17
+ @created_at = DateTime.strptime(@created_at, '%m-%d-%Y %I:%M %p')
18
+ end
19
+
20
+ def thread
21
+ @api.search.find_thread_by_post_id(self.id)
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,56 @@
1
+ module VBulletin
2
+ class Search < Base
3
+
4
+ def initialize(api, options = {})
5
+ @api = api
6
+ @debug = options[:debug] || false
7
+ end
8
+
9
+ def find_posts_by_user_id(user_id)
10
+ parse_index(@api.construct_full_url("search.php", { 'do' => 'finduser', 'u' => user_id }))
11
+ end
12
+
13
+ def find_thread_by_post_id(post_id)
14
+ if (result = @api.mechanize.get(@api.construct_full_url("printthread.php", { 'p' => post_id, 'pp' => 1 })))
15
+ thread_link = result.search('//a[@accesskey="3"]').first
16
+ thread_title = thread_link.content
17
+ thread_id = CGI.parse(URI.parse(thread_link['href']).query)['t'][0]
18
+ thread_author = result.search('//td[@class="page"]/table/tr/td').first
19
+ thread_created_at = result.search('//td[@class="page"]/table/tr/td[@class="smallfont"]').first.inner_html
20
+ VBulletin::Thread.new(:id => thread_id, :title => thread_title, :created_at => thread_created_at)
21
+ end
22
+ end
23
+
24
+ private
25
+ def parse_index(url)
26
+ if (result = @api.mechanize.get(url))
27
+ if (result = @api.mechanize.get(result.uri.to_s + "&perpage=2"))
28
+ parse_search_results(result)
29
+ end
30
+ end
31
+ end
32
+
33
+ def parse_search_results(page)
34
+ posts = []
35
+ page.search('//div[@class="smallfont"]/em/a').each do |link|
36
+ posts << CGI.parse(URI.parse(link['href']).query)['p'][0]
37
+ end
38
+
39
+ vb_posts = []
40
+
41
+ posts.each do |post_id|
42
+ if (result = @api.mechanize.get(@api.construct_full_url("showpost.php", { 'p' => post_id })))
43
+ post_content = result.search("//div[@id=\"post_message_#{post_id}\"]").first.inner_html.strip
44
+ #post_thread_name = result.search('//td[@class="tcat"]/div[@class="smallfont"]/a').first.children
45
+ post_author_name = result.search("//div[@id=\"postmenu_#{post_id}\"]/a/span/span").first.content
46
+ post_created_at = result.search('//td[@id="currentPost"]').first.content.strip
47
+ post_author_id = CGI.parse(URI.parse(result.search("//div[@id=\"postmenu_#{post_id}\"]/a").first['href']).query)['u'][0]
48
+ vb_posts << VBulletin::Post.new(@api, :id => post_id, :content => post_content, :author_id => post_author_id, :author_name => post_author_name, :created_at => post_created_at)
49
+ end
50
+ end
51
+
52
+ vb_posts
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,20 @@
1
+ module VBulletin
2
+ class Thread < Base
3
+
4
+ attr_reader :id, :title, :api, :created_at
5
+
6
+ def initialize(*params)
7
+ params.each do |key|
8
+ key.each { |k, v| instance_variable_set("@#{k}", v) }
9
+ end
10
+ end
11
+
12
+ def created_at
13
+ # Yesterday at 05:06 PM
14
+ @created_at.gsub!('Yesterday', Date.yesterday.strftime("%m-%d-%Y"))
15
+ @created_at.gsub!(',', '')
16
+ @created_at = DateTime.strptime(@created_at, '%m-%d-%Y %I:%M %p')
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'vbulletin'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestVbulletin < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,67 @@
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{vbulletin}
8
+ s.version = "0.0.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Lloyd Pick"]
12
+ s.date = %q{2010-07-21}
13
+ s.description = %q{Provides a way to access data of a vBulletin forum, specifically ones that you don't control}
14
+ s.email = %q{lloydpick@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "lib/vbulletin.rb",
26
+ "lib/vbulletin/base.rb",
27
+ "lib/vbulletin/forum.rb",
28
+ "lib/vbulletin/post.rb",
29
+ "lib/vbulletin/search.rb",
30
+ "lib/vbulletin/thread.rb",
31
+ "test/helper.rb",
32
+ "test/test_vbulletin.rb",
33
+ "vbulletin.gemspec"
34
+ ]
35
+ s.homepage = %q{http://github.com/lloydpick/vbulletin}
36
+ s.rdoc_options = ["--charset=UTF-8"]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = %q{1.3.7}
39
+ s.summary = %q{Provides a way to access data of a vBulletin forum}
40
+ s.test_files = [
41
+ "test/test_vbulletin.rb",
42
+ "test/helper.rb"
43
+ ]
44
+
45
+ if s.respond_to? :specification_version then
46
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
51
+ s.add_runtime_dependency(%q<mechanize>, ["= 1.0.0"])
52
+ s.add_runtime_dependency(%q<nokogiri>, ["= 1.4.2"])
53
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
54
+ else
55
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
56
+ s.add_dependency(%q<mechanize>, ["= 1.0.0"])
57
+ s.add_dependency(%q<nokogiri>, ["= 1.4.2"])
58
+ s.add_dependency(%q<activesupport>, [">= 0"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
62
+ s.add_dependency(%q<mechanize>, ["= 1.0.0"])
63
+ s.add_dependency(%q<nokogiri>, ["= 1.4.2"])
64
+ s.add_dependency(%q<activesupport>, [">= 0"])
65
+ end
66
+ end
67
+
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vbulletin
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 4
10
+ version: 0.0.4
11
+ platform: ruby
12
+ authors:
13
+ - Lloyd Pick
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-21 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: thoughtbot-shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: mechanize
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - "="
42
+ - !ruby/object:Gem::Version
43
+ hash: 23
44
+ segments:
45
+ - 1
46
+ - 0
47
+ - 0
48
+ version: 1.0.0
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: nokogiri
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - "="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 1
62
+ - 4
63
+ - 2
64
+ version: 1.4.2
65
+ type: :runtime
66
+ version_requirements: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ name: activesupport
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ type: :runtime
80
+ version_requirements: *id004
81
+ description: Provides a way to access data of a vBulletin forum, specifically ones that you don't control
82
+ email: lloydpick@gmail.com
83
+ executables: []
84
+
85
+ extensions: []
86
+
87
+ extra_rdoc_files:
88
+ - LICENSE
89
+ - README.rdoc
90
+ files:
91
+ - .document
92
+ - .gitignore
93
+ - LICENSE
94
+ - README.rdoc
95
+ - Rakefile
96
+ - lib/vbulletin.rb
97
+ - lib/vbulletin/base.rb
98
+ - lib/vbulletin/forum.rb
99
+ - lib/vbulletin/post.rb
100
+ - lib/vbulletin/search.rb
101
+ - lib/vbulletin/thread.rb
102
+ - test/helper.rb
103
+ - test/test_vbulletin.rb
104
+ - vbulletin.gemspec
105
+ has_rdoc: true
106
+ homepage: http://github.com/lloydpick/vbulletin
107
+ licenses: []
108
+
109
+ post_install_message:
110
+ rdoc_options:
111
+ - --charset=UTF-8
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ hash: 3
129
+ segments:
130
+ - 0
131
+ version: "0"
132
+ requirements: []
133
+
134
+ rubyforge_project:
135
+ rubygems_version: 1.3.7
136
+ signing_key:
137
+ specification_version: 3
138
+ summary: Provides a way to access data of a vBulletin forum
139
+ test_files:
140
+ - test/test_vbulletin.rb
141
+ - test/helper.rb