impostor 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,4 +1,10 @@
1
- == 0.0.1 / 2008-02-02
1
+ ### 0.2.0 / 2008-07-30 (don't use this code for spam)
2
+
3
+ * 1 minor enhancement:
4
+ * support for phpBB3
5
+
6
+ ### 0.0.1 / 2008-02-02
2
7
 
3
8
  * 1 major enhancement
4
9
  * Birthday!
10
+
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 automatic posts to the following forum applications:
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 specefic to wwf79, wwf80, phpbb2, etc.
20
- # read the impostor docs for options to the kind of forum in use
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', 3..6).join("\n\n")
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']
@@ -5,7 +5,7 @@ require 'mechanize'
5
5
  require 'cgi'
6
6
 
7
7
  ##
8
- # phpBB version of the Impostor
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[@class='mainmenu']")
252
- return false unless mm
253
- mm.each do |m|
254
- return true if (m.innerText =~ /Log out \[ #{username} \]/ rescue false)
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
data/lib/www/impostor.rb CHANGED
@@ -51,7 +51,7 @@ module WWW
51
51
  ##
52
52
  # Gem version of Impostor
53
53
 
54
- VERSION = '0.0.1'
54
+ VERSION = '0.1.0'
55
55
 
56
56
  ##
57
57
  # An application error