impostor 0.2.1 → 1.0.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/.gemtest +0 -0
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +47 -0
- data/History.txt +8 -0
- data/Manifest.txt +87 -55
- data/README.txt +11 -11
- data/Rakefile +16 -20
- data/lib/impostor/auth.rb +103 -0
- data/lib/impostor/config.rb +171 -0
- data/lib/impostor/errors.rb +67 -0
- data/lib/impostor/phpbb2.rb +202 -0
- data/lib/impostor/phpbb3.rb +199 -0
- data/lib/impostor/post.rb +111 -0
- data/lib/impostor/topic.rb +115 -0
- data/lib/impostor/wwf79.rb +186 -0
- data/lib/impostor/wwf80.rb +190 -0
- data/lib/impostor.rb +108 -5
- data/spec/auth_spec.rb +148 -0
- data/spec/base_spec_helper.rb +12 -0
- data/{test/test_helper.rb → spec/caged_net_http.rb} +8 -17
- data/spec/config_spec.rb +136 -0
- data/spec/fixtures/junk.html +1 -0
- data/{test → spec}/fixtures/phpbb2-get-new_topic-form-good-response.html +0 -0
- data/{test → spec}/fixtures/phpbb2-get-viewtopic-for-new-topic-good-response.html +11 -11
- data/{test → spec}/fixtures/phpbb2-get-viewtopic-for-new-topic-malformed-response.html +0 -0
- data/{test → spec}/fixtures/phpbb2-index.html +0 -0
- data/{test → spec}/fixtures/phpbb2-logged-in.html +0 -0
- data/{test → spec}/fixtures/phpbb2-login.html +0 -0
- data/{test → spec}/fixtures/phpbb2-not-logged-in.html +0 -0
- data/{test → spec}/fixtures/phpbb2-post-new_topic-good-response.html +0 -0
- data/{test → spec}/fixtures/phpbb2-post-reply-good-response.html +0 -0
- data/{test → spec}/fixtures/phpbb2-post-reply-throttled-response.html +0 -0
- data/{test → spec}/fixtures/phpbb2-too-many-posts.html +0 -0
- data/{test → spec}/fixtures/phpbb3-get-new-topic-form-good-response.html +0 -0
- data/{test → spec}/fixtures/phpbb3-get-reply-form-good-response.html +0 -0
- data/{test → spec}/fixtures/phpbb3-logged-in.html +0 -0
- data/{test → spec}/fixtures/phpbb3-login.html +0 -0
- data/{test → spec}/fixtures/phpbb3-not-logged-in.html +0 -0
- data/{test → spec}/fixtures/phpbb3-post-new_topic-good-response.html +0 -0
- data/{test → spec}/fixtures/phpbb3-post-reply-good-response.html +0 -0
- data/spec/fixtures/vcr_cassettes/phpbb2-should-be-overlimit-creating-topic.yml +1308 -0
- data/spec/fixtures/vcr_cassettes/phpbb2-should-create-topic.yml +923 -0
- data/spec/fixtures/vcr_cassettes/phpbb2-should-login.yml +360 -0
- data/spec/fixtures/vcr_cassettes/phpbb2-should-not-create-new-topic.yml +497 -0
- data/spec/fixtures/vcr_cassettes/phpbb2-should-not-login.yml +287 -0
- data/spec/fixtures/vcr_cassettes/phpbb2-should-not-post.yml +497 -0
- data/spec/fixtures/vcr_cassettes/phpbb2-should-overlimit-error-post.yml +1140 -0
- data/spec/fixtures/vcr_cassettes/phpbb2-should-post.yml +751 -0
- data/spec/fixtures/vcr_cassettes/phpbb3-should-be-overlimit-creating-topic.yml +995 -0
- data/spec/fixtures/vcr_cassettes/phpbb3-should-create-topic.yml +675 -0
- data/spec/fixtures/vcr_cassettes/phpbb3-should-login.yml +245 -0
- data/spec/fixtures/vcr_cassettes/phpbb3-should-not-create-new-topic.yml +350 -0
- data/spec/fixtures/vcr_cassettes/phpbb3-should-not-login.yml +253 -0
- data/spec/fixtures/vcr_cassettes/phpbb3-should-not-post.yml +350 -0
- data/spec/fixtures/vcr_cassettes/phpbb3-should-overlimit-error-post.yml +1046 -0
- data/spec/fixtures/vcr_cassettes/phpbb3-should-post.yml +605 -0
- data/{test → spec}/fixtures/wwf79-forum_posts.html +0 -0
- data/{test → spec}/fixtures/wwf79-general-new-topic-error.html +0 -0
- data/{test → spec}/fixtures/wwf79-general-posting-error.html +0 -0
- data/{test → spec}/fixtures/wwf79-good-post-forum_posts.html +1 -1
- data/{test → spec}/fixtures/wwf79-index.html +0 -0
- data/{test → spec}/fixtures/wwf79-logged-in.html +0 -0
- data/{test → spec}/fixtures/wwf79-login.html +0 -0
- data/{test → spec}/fixtures/wwf79-new-topic-forum_posts-response.html +0 -0
- data/{test → spec}/fixtures/wwf79-new-topic-post_message_form.html +0 -0
- data/{test → spec}/fixtures/wwf79-not-logged-in.html +0 -0
- data/{test → spec}/fixtures/wwf79-too-many-posts.html +0 -0
- data/{test → spec}/fixtures/wwf79-too-many-topics.html +0 -0
- data/{test → spec}/fixtures/wwf80-general-posting-error.html +0 -0
- data/{test → spec}/fixtures/wwf80-get-new_topic-form-good-response.html +0 -0
- data/{test → spec}/fixtures/wwf80-get-viewtopic-for-new-topic-good-response.html +0 -0
- data/{test → spec}/fixtures/wwf80-index.html +0 -0
- data/{test → spec}/fixtures/wwf80-logged-in.html +0 -0
- data/{test → spec}/fixtures/wwf80-login.html +0 -0
- data/{test → spec}/fixtures/wwf80-new_reply_form.html +0 -0
- data/{test → spec}/fixtures/wwf80-not-logged-in.html +0 -0
- data/{test → spec}/fixtures/wwf80-post-new_topic-good-response.html +1 -1
- data/{test → spec}/fixtures/wwf80-post-reply-good-response.html +0 -0
- data/{test → spec}/fixtures/wwf80-too-many-posts.html +0 -0
- data/spec/impostor_spec_helper.rb +162 -0
- data/spec/integration/phpbb2_spec.rb +111 -0
- data/spec/integration/phpbb3_spec.rb +109 -0
- data/spec/integration_spec_helper.rb +7 -0
- data/spec/phpbb2_spec.rb +346 -0
- data/spec/phpbb3_spec.rb +332 -0
- data/spec/post_spec.rb +134 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/test_impostor.rb +12 -0
- data/spec/topic_spec.rb +143 -0
- data/spec/wwf79_spec.rb +342 -0
- data/spec/wwf80_spec.rb +339 -0
- metadata +156 -87
- data/lib/www/impostor/phpbb2.rb +0 -258
- data/lib/www/impostor/phpbb3.rb +0 -236
- data/lib/www/impostor/wwf79.rb +0 -254
- data/lib/www/impostor/wwf80.rb +0 -264
- data/lib/www/impostor.rb +0 -269
- data/test/test_github.rb +0 -12
- data/test/test_www_impostor.rb +0 -165
- data/test/test_www_impostor_phpbb2.rb +0 -536
- data/test/test_www_impostor_phpbb3.rb +0 -483
- data/test/test_www_impostor_wwf79.rb +0 -535
- data/test/test_www_impostor_wwf80.rb +0 -535
- data/vendor/plugins/impostor/lib/autotest/discover.rb +0 -3
- data/vendor/plugins/impostor/lib/autotest/impostor.rb +0 -49
data/lib/www/impostor/phpbb2.rb
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'hpricot'
|
|
3
|
-
gem 'mechanize', '>= 0.7.0'
|
|
4
|
-
require 'mechanize'
|
|
5
|
-
require 'cgi'
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
# phpBB2 version of the Impostor
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
class WWW::Impostor
|
|
12
|
-
|
|
13
|
-
class Phpbb2 < 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 => :phpbb2,
|
|
24
|
-
# :app_root => 'http://example.com/forum/',
|
|
25
|
-
# :login_page => 'login.php',
|
|
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=newtopic&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('post') rescue nil
|
|
80
|
-
button = form.buttons.with.name('post').first rescue nil
|
|
81
|
-
raise PostError.new("post form not found") unless button && form
|
|
82
|
-
|
|
83
|
-
# set up the form and submit it
|
|
84
|
-
form.subject = subject
|
|
85
|
-
form.message = message
|
|
86
|
-
form['disable_html'] = nil
|
|
87
|
-
form['disable_bbcode'] = 'on'
|
|
88
|
-
form['disable_smilies'] = 'on'
|
|
89
|
-
begin
|
|
90
|
-
page = @agent.submit(form, button)
|
|
91
|
-
rescue StandardError => err
|
|
92
|
-
raise PostError.new(err)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# if the response is correct there will be a meta link that looks something like
|
|
96
|
-
# <meta http-equiv="refresh" content="3;url=viewtopic.php?p=29#29">
|
|
97
|
-
#
|
|
98
|
-
# this link needs to be followed, the page it leads to will give us
|
|
99
|
-
# the topic id that was created for the topic name that we created
|
|
100
|
-
a = (page.search("//meta[@http-equiv='refresh']").attr('content') rescue nil)
|
|
101
|
-
a = (/url=(.*)/.match(a)[1] rescue nil)
|
|
102
|
-
raise PostError.new('unexpected new topic response from refresh') unless a
|
|
103
|
-
|
|
104
|
-
a = URI.join(app_root, a)
|
|
105
|
-
page = @agent.get(a)
|
|
106
|
-
link = (page.search("//link[@rel='prev']").first['href'] rescue nil)
|
|
107
|
-
raise PostError.new('unexpected new topic response from link prev') unless link
|
|
108
|
-
|
|
109
|
-
# t=XXX will be our new topic id, i.e.
|
|
110
|
-
# <link rel="prev" href="http://localhost/phpBB2/viewtopic.php?t=5&view=previous" title="View previous topic"
|
|
111
|
-
u = (URI.parse(link) rescue nil)
|
|
112
|
-
topic = (CGI::parse(u.query)['t'][0] rescue nil)
|
|
113
|
-
topic = topic.to_i
|
|
114
|
-
raise PostError.new('unexpected new topic ID') unless topic > 0
|
|
115
|
-
|
|
116
|
-
# save new topic id and topic name
|
|
117
|
-
add_subject(forum, topic, subject)
|
|
118
|
-
@forum=forum; @topic=topic; @subject=subject; @message=message
|
|
119
|
-
true
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
##
|
|
123
|
-
# Attempt to post to the forum
|
|
124
|
-
|
|
125
|
-
def post(forum = @forum, topic = @topic, message = @message)
|
|
126
|
-
raise PostError.new("forum not set") unless forum
|
|
127
|
-
raise PostError.new("topic not set") unless topic
|
|
128
|
-
raise PostError.new("message not set") unless message
|
|
129
|
-
|
|
130
|
-
login
|
|
131
|
-
raise PostError.new("not logged in") unless @loggedin
|
|
132
|
-
|
|
133
|
-
uri = posting_page
|
|
134
|
-
uri.query = "mode=reply&t=#{topic}"
|
|
135
|
-
|
|
136
|
-
# get the submit form
|
|
137
|
-
begin
|
|
138
|
-
page = @agent.get(uri)
|
|
139
|
-
rescue StandardError => err
|
|
140
|
-
raise PostError.new(err)
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
form = page.form('post') rescue nil
|
|
144
|
-
button = form.buttons.with.name('post').first rescue nil
|
|
145
|
-
raise PostError.new("post form not found") unless button && form
|
|
146
|
-
|
|
147
|
-
# set up the form and submit it
|
|
148
|
-
form.message = message
|
|
149
|
-
form['disable_html'] = nil
|
|
150
|
-
form['disable_bbcode'] = 'on'
|
|
151
|
-
form['disable_smilies'] = 'on'
|
|
152
|
-
begin
|
|
153
|
-
page = @agent.submit(form, button)
|
|
154
|
-
rescue StandardError => err
|
|
155
|
-
raise PostError.new(err)
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
mes = page.search("//span[@class='gen']").last
|
|
159
|
-
posted = mes.innerText =~ /Your message has been entered successfully./ rescue false
|
|
160
|
-
if posted
|
|
161
|
-
@forum=forum; @topic=topic; @subject=get_subject(forum,topic); @message=message
|
|
162
|
-
return true
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
too_many = (mes.innerText =~
|
|
166
|
-
/You cannot make another post so soon after your last; please try again in a short while./ rescue
|
|
167
|
-
false)
|
|
168
|
-
raise ThrottledError.new("too many posts in too short amount of time") if too_many
|
|
169
|
-
|
|
170
|
-
# false otherwise, should we raise an exception instead?
|
|
171
|
-
false
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
##
|
|
175
|
-
# Get the posting page for the application (specific to phpBB2)
|
|
176
|
-
|
|
177
|
-
def posting_page
|
|
178
|
-
URI.join(app_root, config[:posting_page])
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
##
|
|
182
|
-
# does the work of logging into phpbb
|
|
183
|
-
|
|
184
|
-
def login
|
|
185
|
-
return true if @loggedin
|
|
186
|
-
|
|
187
|
-
# get the login page
|
|
188
|
-
page = fetch_login_page
|
|
189
|
-
|
|
190
|
-
# return if we are already logged in from a cookie state
|
|
191
|
-
return true if logged_in?(page)
|
|
192
|
-
|
|
193
|
-
# setup the form and submit
|
|
194
|
-
form, button = login_form_and_button(page)
|
|
195
|
-
page = post_login(form, button)
|
|
196
|
-
|
|
197
|
-
# set up the rest of the state if we are logged in
|
|
198
|
-
@loggedin = logged_in?(page)
|
|
199
|
-
load_topics if @loggedin
|
|
200
|
-
|
|
201
|
-
@loggedin
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
def version
|
|
205
|
-
@version ||= self.class.to_s
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
protected
|
|
209
|
-
|
|
210
|
-
##
|
|
211
|
-
# does the work of posting the login form
|
|
212
|
-
|
|
213
|
-
def post_login(form, button)
|
|
214
|
-
begin
|
|
215
|
-
page = @agent.submit(form, button)
|
|
216
|
-
rescue StandardError => err
|
|
217
|
-
raise LoginError.new(err)
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
##
|
|
222
|
-
# returns the login form and its button from the login page
|
|
223
|
-
|
|
224
|
-
def login_form_and_button(page)
|
|
225
|
-
form = page.forms.first rescue nil
|
|
226
|
-
raise LoginError.new("unknown login page format") unless form
|
|
227
|
-
|
|
228
|
-
button = page.forms.first.buttons.with.name('login').first
|
|
229
|
-
form['username'] = username
|
|
230
|
-
form['password'] = password
|
|
231
|
-
form['autologin'] = 'on'
|
|
232
|
-
|
|
233
|
-
return form, button
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
##
|
|
237
|
-
# fetches the login page
|
|
238
|
-
|
|
239
|
-
def fetch_login_page
|
|
240
|
-
begin
|
|
241
|
-
page = @agent.get(login_page)
|
|
242
|
-
rescue StandardError => err
|
|
243
|
-
raise LoginError.new(err)
|
|
244
|
-
end
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
##
|
|
248
|
-
# Checks if the agent is already logged by stored cookie
|
|
249
|
-
|
|
250
|
-
def logged_in?(page)
|
|
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
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
end
|
|
258
|
-
end
|
data/lib/www/impostor/phpbb3.rb
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
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
|