impostor 0.0.1 → 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.
- data/History.txt +7 -1
- data/Manifest.txt +9 -0
- data/README.txt +10 -3
- data/Rakefile +1 -1
- data/lib/www/impostor/phpbb2.rb +5 -7
- data/lib/www/impostor/phpbb3.rb +236 -0
- data/lib/www/impostor.rb +1 -1
- data/test/fixtures/phpbb2-not-logged-in.html +530 -145
- data/test/fixtures/phpbb3-get-new-topic-form-good-response.html +975 -0
- data/test/fixtures/phpbb3-get-reply-form-good-response.html +1015 -0
- data/test/fixtures/phpbb3-logged-in.html +512 -0
- data/test/fixtures/phpbb3-login.html +423 -0
- data/test/fixtures/phpbb3-not-logged-in.html +426 -0
- data/test/fixtures/phpbb3-post-new_topic-good-response.html +894 -0
- data/test/fixtures/phpbb3-post-reply-good-response.html +2077 -0
- data/test/test_www_impostor_phpbb3.rb +483 -0
- metadata +19 -27
- data.tar.gz.sig +0 -3
- metadata.gz.sig +0 -3
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -5,6 +5,7 @@ Rakefile
|
|
5
5
|
lib/impostor.rb
|
6
6
|
lib/www/impostor.rb
|
7
7
|
lib/www/impostor/phpbb2.rb
|
8
|
+
lib/www/impostor/phpbb3.rb
|
8
9
|
lib/www/impostor/wwf79.rb
|
9
10
|
lib/www/impostor/wwf80.rb
|
10
11
|
test/fixtures/phpbb2-get-new_topic-form-good-response.html
|
@@ -18,6 +19,13 @@ test/fixtures/phpbb2-post-new_topic-good-response.html
|
|
18
19
|
test/fixtures/phpbb2-post-reply-good-response.html
|
19
20
|
test/fixtures/phpbb2-post-reply-throttled-response.html
|
20
21
|
test/fixtures/phpbb2-too-many-posts.html
|
22
|
+
test/fixtures/phpbb3-get-new-topic-form-good-response.html
|
23
|
+
test/fixtures/phpbb3-get-reply-form-good-response.html
|
24
|
+
test/fixtures/phpbb3-logged-in.html
|
25
|
+
test/fixtures/phpbb3-login.html
|
26
|
+
test/fixtures/phpbb3-not-logged-in.html
|
27
|
+
test/fixtures/phpbb3-post-new_topic-good-response.html
|
28
|
+
test/fixtures/phpbb3-post-reply-good-response.html
|
21
29
|
test/fixtures/wwf79-forum_posts.html
|
22
30
|
test/fixtures/wwf79-general-new-topic-error.html
|
23
31
|
test/fixtures/wwf79-general-posting-error.html
|
@@ -44,6 +52,7 @@ test/fixtures/wwf80-too-many-posts.html
|
|
44
52
|
test/test_helper.rb
|
45
53
|
test/test_www_impostor.rb
|
46
54
|
test/test_www_impostor_phpbb2.rb
|
55
|
+
test/test_www_impostor_phpbb3.rb
|
47
56
|
test/test_www_impostor_wwf79.rb
|
48
57
|
test/test_www_impostor_wwf80.rb
|
49
58
|
vendor/plugins/impostor/lib/autotest/discover.rb
|
data/README.txt
CHANGED
@@ -8,16 +8,18 @@ imPOSTor posts messages to forums
|
|
8
8
|
|
9
9
|
== FEATURES/PROBLEMS:
|
10
10
|
|
11
|
-
Makes
|
11
|
+
Makes automated posts to the following forum applications:
|
12
12
|
|
13
13
|
* Web Wiz Forums (WWF) 7.9
|
14
14
|
* Web Wiz Forums (WWF) 8.0
|
15
15
|
* PHP Bullitin Board (phpBB) 2.0 (2.0.22)
|
16
|
+
* PHP Bullitin Board (phpBB) 3.0
|
16
17
|
|
17
18
|
== SYNOPSIS:
|
18
19
|
|
19
|
-
# config yaml has options
|
20
|
-
#
|
20
|
+
# config yaml has options specific to wwf79, phpbb2, etc.
|
21
|
+
# Read the impostor docs for configuration options for the kind of forum to
|
22
|
+
# be accessed.
|
21
23
|
# config can be keyed by symbols or strings
|
22
24
|
config = YAML::load_file('conf/impostor.yml')
|
23
25
|
post = WWW::Impostor.new(config)
|
@@ -35,6 +37,11 @@ post.logout
|
|
35
37
|
* mechanize
|
36
38
|
* hpricot
|
37
39
|
|
40
|
+
== SOURCE
|
41
|
+
|
42
|
+
git clone git://github.com/monde/impostor.git
|
43
|
+
svn co svn://rubyforge.org/var/svn/impostor/trunk impostor
|
44
|
+
|
38
45
|
== INSTALL:
|
39
46
|
|
40
47
|
* sudo gem install impostor
|
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ Hoe.new('impostor', WWW::Impostor::VERSION) do |p|
|
|
15
15
|
p.author = 'Mike Mondragon'
|
16
16
|
p.email = 'mikemondragon@gmail.com'
|
17
17
|
p.summary = 'imPOSTor posts messages to non-RESTful forums and blogs'
|
18
|
-
p.description = p.paragraphs_of('README.txt',
|
18
|
+
p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
19
19
|
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
20
20
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
21
21
|
p.extra_deps << ['hpricot', '>= 0.5.0']
|
data/lib/www/impostor/phpbb2.rb
CHANGED
@@ -5,7 +5,7 @@ require 'mechanize'
|
|
5
5
|
require 'cgi'
|
6
6
|
|
7
7
|
##
|
8
|
-
#
|
8
|
+
# phpBB2 version of the Impostor
|
9
9
|
#
|
10
10
|
|
11
11
|
class WWW::Impostor
|
@@ -248,12 +248,10 @@ class WWW::Impostor
|
|
248
248
|
# Checks if the agent is already logged by stored cookie
|
249
249
|
|
250
250
|
def logged_in?(page)
|
251
|
-
mm = page.search("//a[
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
end
|
256
|
-
false
|
251
|
+
mm = page.search( "//a" ).detect{|a| a.inner_html =~ /Log out \[ #{username} \]/i}
|
252
|
+
mm ||= page.search( "//a" ).detect{|a| a['href'] =~ /\/login\.php\?logout=true/}
|
253
|
+
|
254
|
+
mm.nil? ? false : true
|
257
255
|
end
|
258
256
|
|
259
257
|
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hpricot'
|
3
|
+
gem 'mechanize', '>= 0.7.0'
|
4
|
+
require 'mechanize'
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
##
|
8
|
+
# phpBB3 version of the Impostor
|
9
|
+
#
|
10
|
+
|
11
|
+
class WWW::Impostor
|
12
|
+
|
13
|
+
class Phpbb3 < WWW::Impostor
|
14
|
+
|
15
|
+
##
|
16
|
+
# After initializing the parent a mechanize agent is created
|
17
|
+
#
|
18
|
+
# Additional configuration parameters:
|
19
|
+
#
|
20
|
+
# :posting_page
|
21
|
+
#
|
22
|
+
# Typical configuration parameters
|
23
|
+
# { :type => :phpbb3,
|
24
|
+
# :app_root => 'http://example.com/forum/',
|
25
|
+
# :login_page => 'ucp.php?mode=login',
|
26
|
+
# :posting_page => 'posting.php',
|
27
|
+
# :user_agent => 'Windows IE 7',
|
28
|
+
# :username => 'myuser',
|
29
|
+
# :password => 'mypasswd' }
|
30
|
+
|
31
|
+
def initialize(config={})
|
32
|
+
super(config)
|
33
|
+
@agent = WWW::Mechanize.new
|
34
|
+
@agent.user_agent_alias = user_agent
|
35
|
+
# jar is a yaml file
|
36
|
+
@agent.cookie_jar.load(cookie_jar) if cookie_jar && File.exist?(cookie_jar)
|
37
|
+
@message = nil
|
38
|
+
@loggedin = false
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# clean up the state of the library and log out
|
43
|
+
|
44
|
+
def logout
|
45
|
+
return false unless @loggedin
|
46
|
+
|
47
|
+
@agent.cookie_jar.save_as(cookie_jar) if cookie_jar
|
48
|
+
save_topics
|
49
|
+
|
50
|
+
@forum = nil
|
51
|
+
@topic = nil
|
52
|
+
@message = nil
|
53
|
+
|
54
|
+
@loggedin = false
|
55
|
+
true
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# make a new topic
|
60
|
+
|
61
|
+
def new_topic(forum=@forum, subject=@subject, message=@message)
|
62
|
+
raise PostError.new("forum not set") unless forum
|
63
|
+
raise PostError.new("topic name not given") unless subject
|
64
|
+
raise PostError.new("message not set") unless message
|
65
|
+
|
66
|
+
login
|
67
|
+
raise PostError.new("not logged in") unless @loggedin
|
68
|
+
|
69
|
+
uri = posting_page
|
70
|
+
uri.query = "mode=post&f=#{forum}"
|
71
|
+
|
72
|
+
# get the submit form
|
73
|
+
begin
|
74
|
+
page = @agent.get(uri)
|
75
|
+
rescue StandardError => err
|
76
|
+
raise PostError.new(err)
|
77
|
+
end
|
78
|
+
|
79
|
+
form = page.form('postform') rescue nil
|
80
|
+
raise PostError.new("post form not found") unless form
|
81
|
+
button = form.buttons.detect{|b| b.name == 'post'}
|
82
|
+
raise PostError.new("post form button not found") unless button
|
83
|
+
|
84
|
+
# set up the form and submit it
|
85
|
+
form['subject'] = subject
|
86
|
+
form['message'] = message
|
87
|
+
form['lastclick'] = (form['lastclick'].to_i - 60).to_s
|
88
|
+
|
89
|
+
begin
|
90
|
+
page = @agent.submit(form, button)
|
91
|
+
rescue StandardError => err
|
92
|
+
raise PostError.new(err)
|
93
|
+
end
|
94
|
+
|
95
|
+
# new topic will be current page uri since phpbb3 will 302 to the new
|
96
|
+
# topic page, e.g.
|
97
|
+
# http://example.com/forum/viewtopic.php?f=37&t=52
|
98
|
+
topic = page.uri.query.split('&').detect{|a| a =~ /^t=/}.split('=').last.to_i rescue 0
|
99
|
+
raise PostError.new('unexpected new topic ID') unless topic > 0
|
100
|
+
|
101
|
+
# save new topic id and topic name
|
102
|
+
add_subject(forum, topic, subject)
|
103
|
+
@forum=forum; @topic=topic; @subject=subject; @message=message
|
104
|
+
true
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
# Attempt to post to the forum
|
109
|
+
|
110
|
+
def post(forum = @forum, topic = @topic, message = @message)
|
111
|
+
raise PostError.new("forum not set") unless forum
|
112
|
+
raise PostError.new("topic not set") unless topic
|
113
|
+
raise PostError.new("message not set") unless message
|
114
|
+
|
115
|
+
login
|
116
|
+
raise PostError.new("not logged in") unless @loggedin
|
117
|
+
|
118
|
+
uri = posting_page
|
119
|
+
uri.query = "mode=reply&f=#{forum}&t=#{topic}"
|
120
|
+
|
121
|
+
# get the submit form
|
122
|
+
begin
|
123
|
+
page = @agent.get(uri)
|
124
|
+
rescue StandardError => err
|
125
|
+
raise PostError.new(err)
|
126
|
+
end
|
127
|
+
|
128
|
+
form = page.form('postform') rescue nil
|
129
|
+
button = form.buttons.with.name('post').first rescue nil
|
130
|
+
raise PostError.new("post form not found") unless button && form
|
131
|
+
|
132
|
+
# set up the form and submit it
|
133
|
+
form.message = message
|
134
|
+
form['lastclick'] = (form['lastclick'].to_i - 60).to_s
|
135
|
+
|
136
|
+
begin
|
137
|
+
page = @agent.submit(form, button)
|
138
|
+
rescue StandardError => err
|
139
|
+
raise PostError.new(err)
|
140
|
+
end
|
141
|
+
|
142
|
+
# new post will be in current page uri since phpbb3 will 302 to the new
|
143
|
+
# post page post anchor, e.g.
|
144
|
+
# http://example.com/forum/viewtopic.php?f=37&t=52&p=3725#p3725
|
145
|
+
postid = page.uri.query.split('&').detect{|a| a =~ /^p=/}.split('=').last.to_i rescue 0
|
146
|
+
raise PostError.new("message did not post") unless postid > 0
|
147
|
+
|
148
|
+
@forum=forum; @topic=topic; @subject=get_subject(forum,topic); @message=message
|
149
|
+
|
150
|
+
true
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Get the posting page for the application (specific to phpBB3)
|
155
|
+
|
156
|
+
def posting_page
|
157
|
+
URI.join(app_root, config[:posting_page])
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# does the work of logging into phpbb
|
162
|
+
|
163
|
+
def login
|
164
|
+
return true if @loggedin
|
165
|
+
|
166
|
+
# get the login page
|
167
|
+
page = fetch_login_page
|
168
|
+
|
169
|
+
# return if we are already logged in from a cookie state
|
170
|
+
return true if logged_in?(page)
|
171
|
+
|
172
|
+
# setup the form and submit
|
173
|
+
form, button = login_form_and_button(page)
|
174
|
+
page = post_login(form, button)
|
175
|
+
|
176
|
+
# set up the rest of the state if we are logged in
|
177
|
+
@loggedin = logged_in?(page)
|
178
|
+
load_topics if @loggedin
|
179
|
+
|
180
|
+
@loggedin
|
181
|
+
end
|
182
|
+
|
183
|
+
def version
|
184
|
+
@version ||= self.class.to_s
|
185
|
+
end
|
186
|
+
|
187
|
+
protected
|
188
|
+
##
|
189
|
+
# does the work of posting the login form
|
190
|
+
|
191
|
+
def post_login(form, button)
|
192
|
+
begin
|
193
|
+
page = @agent.submit(form, button)
|
194
|
+
rescue StandardError => err
|
195
|
+
raise LoginError.new(err)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
##
|
200
|
+
# returns the login form and its button from the login page
|
201
|
+
|
202
|
+
def login_form_and_button(page)
|
203
|
+
form = page.forms.first rescue nil
|
204
|
+
raise LoginError.new("unknown login page format") unless form
|
205
|
+
|
206
|
+
button = form.buttons.with.name('login').first
|
207
|
+
form['username'] = username
|
208
|
+
form['password'] = password
|
209
|
+
form['autologin'] = 'on'
|
210
|
+
|
211
|
+
return form, button
|
212
|
+
end
|
213
|
+
|
214
|
+
##
|
215
|
+
# fetches the login page
|
216
|
+
|
217
|
+
def fetch_login_page
|
218
|
+
begin
|
219
|
+
page = @agent.get(login_page)
|
220
|
+
rescue StandardError => err
|
221
|
+
raise LoginError.new(err)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
##
|
226
|
+
# Checks if the agent is already logged by stored cookie
|
227
|
+
|
228
|
+
def logged_in?(page)
|
229
|
+
mm = page.search( "//a" ).detect{|a| a.inner_html =~ /Logout \[ #{username} \]/}
|
230
|
+
mm ||= page.search( "//a" ).detect{|a| a['href'] =~ /\.\/ucp.php\?mode=logout/}
|
231
|
+
|
232
|
+
mm.nil? ? false : true
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
end
|