wordpress 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ === 1.0.3 / 2009-06-05
2
+
3
+ * 1 major enhancement
4
+
5
+ * Stubbed test and refactored code
6
+
7
+ === 1.0.1 / 2009-06-05
8
+
9
+ * 1 major enhancement
10
+
11
+ * Added the ability to post and check account properties
12
+
13
+ === 1.0.0 / 2009-05-28
14
+
15
+ * 1 major enhancement
16
+
17
+ * Birthday!
18
+
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/wordpress
6
+ lib/wordpress.rb
7
+ test/test_wordpress.rb
@@ -0,0 +1,104 @@
1
+ = wordpress
2
+
3
+ * http://github.com/jordandobson/wordpress/tree/master
4
+
5
+ == DESCRIPTION:
6
+
7
+ The Wordpress gem provides posting to a Wordpress.com blog or a self hosted wordpress by providing your username, password, login url(if you host your blog) and your blog content. With this gem, you have access to add a text entry on Wordpress blog by providing these options: title text, body text, and a tag array. You must include at least title text or body text with your post.
8
+
9
+ Posting images with posts, posting only images and pulling down your posts will be available very soon.
10
+
11
+ == FEATURES/PROBLEMS:
12
+
13
+ * Either Title or Body is optional
14
+ * Adding Images are not yet implemented
15
+ * Posting Only, Reading & Images are not yet included
16
+ * Check if a username and password are valid
17
+ * Check if a provided login_url is valid
18
+ * Get the users blog url
19
+ * This is very throughly tested
20
+
21
+ == SYNOPSIS:
22
+
23
+ 1. Instantiate your account
24
+
25
+ * You can provide just the username and password
26
+
27
+ account = Wordpress::Client.new('username', 'password')
28
+
29
+ * Or you can provide the ID as a string or integer
30
+
31
+ account = Wordpress::Client.new('username', 'password', 'http://blog.mysite.com/wp-login.php')
32
+
33
+ 2. Get more info about the user's account if you need it
34
+
35
+ * Check if the user is valid
36
+
37
+ account.valid_user?
38
+
39
+ * Check if the specified login page is valid
40
+
41
+ account.valid_login_page?
42
+
43
+ * Get the users blog page url
44
+
45
+ account.blog_url
46
+
47
+ * Get a list of your sites and additional info
48
+
49
+ account.account_info
50
+
51
+ 3. Setup your post
52
+
53
+ * You must at least include the title or body
54
+
55
+ account.title = "My Title"
56
+ account.body = "My Body Text"
57
+ account.tags = ["Glue", "Posterous", "Ruby", "Made By Squad"]
58
+
59
+ 4. Add your post to Posterous.com
60
+
61
+ * Set this to a variable to work with the response
62
+
63
+ response = account.add_post
64
+
65
+ 5. You get a success or error hash back or nil
66
+
67
+ * Your response should look something like this if successful
68
+
69
+ response #=> { "rsp" => { "post" => { "title" => "My Title", "url" => "http://getglue.wordpress.com/2009/06/06/my-title/", "id" => "69" }, "stat" => "ok" } }
70
+
71
+ * See the tests for this gem for failure responses and responses for other methods
72
+
73
+ == REQUIREMENTS:
74
+
75
+ * mechanize, & Mocha (For Tests)
76
+
77
+ == INSTALL:
78
+
79
+ * sudo gem install wordpress -include-dependencies
80
+
81
+ == LICENSE:
82
+
83
+ (The MIT License)
84
+
85
+ Copyright (c) 2009 Jordan Dobson
86
+
87
+ Permission is hereby granted, free of charge, to any person obtaining
88
+ a copy of this software and associated documentation files (the
89
+ 'Software'), to deal in the Software without restriction, including
90
+ without limitation the rights to use, copy, modify, merge, publish,
91
+ distribute, sublicense, and/or sell copies of the Software, and to
92
+ permit persons to whom the Software is furnished to do so, subject to
93
+ the following conditions:
94
+
95
+ The above copyright notice and this permission notice shall be
96
+ included in all copies or substantial portions of the Software.
97
+
98
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
99
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
100
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
101
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
102
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
103
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
104
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,13 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/wordpress.rb'
6
+
7
+ Hoe.new('wordpress', Wordpress::VERSION) do |p|
8
+ # p.rubyforge_name = 'wordpressx' # if different than lowercase project name
9
+ p.developer('Jordan Dobson', 'jordan.dobson@madebysquad.com')
10
+ p.extra_deps = ['mechanize', 'mocha']
11
+ end
12
+
13
+ # vim: syntax=Ruby
@@ -0,0 +1 @@
1
+ #!/usr/bin/env ruby
@@ -0,0 +1,107 @@
1
+ require 'rubygems'
2
+ require 'mechanize'
3
+
4
+ module Wordpress
5
+
6
+ VERSION = '0.1.4'
7
+
8
+ class AuthError < StandardError; end
9
+ class PostError < StandardError; end
10
+ class HostError < StandardError; end
11
+
12
+ class Client
13
+
14
+ DEFAULT_URL = 'http://wordpress.com/wp-login.php'
15
+ LOGIN_FORM = 'loginform'
16
+ POST_FORM = 'post'
17
+ IS_ADMIN = 'body.wp-admin'
18
+ IS_LOGIN = 'body.login'
19
+
20
+ attr_accessor :title, :body
21
+ attr_reader :login_url, :username, :password, :tags, :post_url, :agent
22
+
23
+ def initialize usr, pwd, login_url = DEFAULT_URL
24
+ raise AuthError, "Blank Username or Password or not a string." \
25
+ if !usr.is_a?(String) || !pwd.is_a?(String) || usr == '' || pwd == ''
26
+
27
+ raise AuthError, "Url should end with wp-login.php" \
28
+ unless login_url =~ /\/wp-login[.]php$/
29
+
30
+ @username = usr
31
+ @password = pwd
32
+ @login_url = login_url
33
+ @agent = WWW::Mechanize.new
34
+ @post_url = @tags = @title = @body = nil
35
+ end
36
+
37
+ def tags= ary
38
+ raise TagError, 'Tags must added using an array' if !ary.is_a?(Array)
39
+ @tags = ary.join(", ")
40
+ end
41
+
42
+ def valid_login_page?
43
+ !login_page.search("form[name=#{LOGIN_FORM}]").empty?
44
+ end
45
+
46
+ def valid_user?
47
+ logged_into? dashboard_page
48
+ end
49
+
50
+ def blog_url
51
+ begin
52
+ a = dashboard_page.search("#{IS_ADMIN} #wphead h1 a")
53
+ rescue SocketError
54
+ end
55
+ a && a.first && a.first['href'] ? a.first['href'] : nil
56
+ end
57
+
58
+ def add_post
59
+ raise PostError, "A post requires a title or body." unless @title || @body
60
+ post_form = dashboard_page.form(POST_FORM)
61
+ raise HostError, "Missing QuickPress on dashboard page or bad account." unless post_form
62
+ post_form = build_post(post_form)
63
+ post_response @agent.submit(post_form, post_form.buttons.last)
64
+ end
65
+
66
+ private
67
+
68
+ def login_page
69
+ @agent.get @login_url
70
+ end
71
+
72
+ def dashboard_page
73
+ page = login_page
74
+ login_form = page.form(LOGIN_FORM)
75
+ if login_form
76
+ login_form.log = @username
77
+ login_form.pwd = @password
78
+ page = @agent.submit login_form
79
+ end
80
+ puts page.inspect
81
+ page
82
+ end
83
+
84
+ def logged_into? page
85
+ !page.search(IS_ADMIN).empty?
86
+ end
87
+
88
+ def build_post f
89
+ f.post_title = @title
90
+ f.content = @body
91
+ f.tags_input = @tags
92
+ f
93
+ end
94
+
95
+ def post_response page
96
+ a = page.search("div.message p a")
97
+ if a && a.first && a.last
98
+ url = a.first['href'] ? a.first['href'].gsub("?preview=1", "") : nil
99
+ pid = a.last['href'] ? a.last['href'].sub(/.*post=(\d*)/,'\1') : nil
100
+ if pid && url
101
+ return { "rsp" => { "post" => { "title" => "#{@title}", "url" => "#{url}", "id" => "#{pid}" }, "stat" => "ok" }}
102
+ end
103
+ end
104
+ { "rsp" => { "err" => { "msg" => "Post was unsuccessful.", "title" => "#{@title}" }, "stat" => "fail" }}
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,196 @@
1
+ require "test/unit"
2
+ require "wordpress"
3
+ require "mocha"
4
+
5
+ ######
6
+ # USED TO TEST PRIVATE METHODS
7
+ class Class
8
+ def private_methods
9
+ m = self.private_instance_methods
10
+ self.class_eval { public( *m ) }
11
+ yield
12
+ self.class_eval { private( *m ) }
13
+ end
14
+ end
15
+
16
+ class TestWordpress < Test::Unit::TestCase
17
+
18
+ def setup
19
+ @u = 'jordandobson'
20
+ @p = 'password'
21
+
22
+ @account = Wordpress::Client.new @u, @p
23
+ @account_bad = Wordpress::Client.new @u, 'x'
24
+ @account_invalid_login_page = Wordpress::Client.new @u, @p, 'http://notapage.gd/wp-login.php'
25
+ @account_hosted_account = Wordpress::Client.new @u, @p, 'http://blog.getglue.net/wp-login.php'
26
+
27
+ login_html = '<html><body class="login"><form name="loginform"></form></body></html>'
28
+ admin_html = '<html><body class="wp-admin"><div id="wphead"><h1><a href="http://getglue.wordpress.com/" title="Visit Site">Get Glue</a></h1></div><form name="post"><input type="text" name="post_title"/><textarea name="content"></textarea><input type="text" name="tags_input"/><input type="submit" name="publish" /></form></body></html>'
29
+ success_html = '<div class="message"><p><a href="http://success.com/2009/?preview=1">preview</a><a href="http://success.com/wp-admin/post.php?post=99">edit</a></p></div>'
30
+ fail_html = '<div class="message"><p></p></div>'
31
+
32
+ @login_pg = setup_mock_mechanize_pg login_html
33
+ @admin_pg = setup_mock_mechanize_pg admin_html
34
+ @success_pg = setup_mock_mechanize_pg success_html
35
+ @fail_pg = setup_mock_mechanize_pg fail_html
36
+
37
+ end
38
+
39
+ def setup_mock_mechanize_pg html
40
+ WWW::Mechanize::Page.new(nil, {'content-type' => 'text/html'}, html, 200)
41
+ end
42
+
43
+ def test_sets_account_info_on_initialize
44
+ actual = Wordpress::Client.new @u, @p
45
+ assert_equal [@u, @p], [actual.username, actual.password]
46
+ end
47
+
48
+ def test_raises_if_username_is_blank
49
+ assert_raise Wordpress::AuthError do
50
+ Wordpress::Client.new "", @p
51
+ end
52
+ end
53
+
54
+ def test_raises_if_password_is_blank
55
+ assert_raise Wordpress::AuthError do
56
+ Wordpress::Client.new @u, ""
57
+ end
58
+ end
59
+
60
+ def test_raises_if_password_is_not_srting
61
+ assert_raise Wordpress::AuthError do
62
+ Wordpress::Client.new @u, 00
63
+ end
64
+ end
65
+
66
+ def test_raises_if_username_is_not_srting
67
+ assert_raise Wordpress::AuthError do
68
+ Wordpress::Client.new 00, @p
69
+ end
70
+ end
71
+
72
+ def test_login_url_uses_default_if_witheld
73
+ assert_equal Wordpress::Client::DEFAULT_URL, @account.login_url
74
+ end
75
+
76
+ def test_users_url_does_not_raise
77
+ assert_equal 'http://notapage.gd/wp-login.php', @account_invalid_login_page.login_url
78
+ end
79
+
80
+ def test_raises_on_bad_login_url
81
+ assert_raise Wordpress::AuthError do
82
+ Wordpress::Client.new @u, @p, 'http://bad.login/url.php'
83
+ end
84
+ end
85
+
86
+ def test_login_page_is_valid
87
+ actual = Wordpress::Client.new @u, @p
88
+ actual.stubs(:login_page).returns(@login_pg)
89
+ assert_equal true, actual.valid_login_page?
90
+ end
91
+
92
+ def test_login_page_is_invalid
93
+ @account_invalid_login_page.stubs(:login_page).returns(@fail_pg)
94
+ assert_equal false, @account_invalid_login_page.valid_login_page?
95
+ end
96
+
97
+ def test_is_a_valid_user
98
+ @account.stubs(:dashboard_page).returns(@admin_pg)
99
+ assert_equal true, @account.valid_user?
100
+ end
101
+
102
+ def test_is_an_invalid_user
103
+ @account_bad.stubs(:dashboard_page).returns(@login_pg)
104
+ assert_equal false, @account_bad.valid_user?
105
+ end
106
+
107
+ def test_is_a_valid_hosted_user
108
+ @account_hosted_account.stubs(:dashboard_page).returns(@admin_pg)
109
+ assert_equal true, @account_hosted_account.valid_user?
110
+ end
111
+
112
+ def test_private_logged_in_is_true
113
+ Wordpress::Client.private_methods {
114
+ assert_equal true, @account.logged_into?(@admin_pg)
115
+ }
116
+ end
117
+
118
+ def test_private_logged_in_is_false
119
+ Wordpress::Client.private_methods {
120
+ assert_equal false, @account.logged_into?(@login_pg)
121
+ }
122
+ end
123
+
124
+ def test_returns_blog_url
125
+ @account_hosted_account.stubs(:dashboard_page).returns(@admin_pg)
126
+ assert_equal 'http://getglue.wordpress.com/', @account_hosted_account.blog_url
127
+ end
128
+
129
+ def test_returns_blog_url_bad
130
+ @account_invalid_login_page.stubs(:dashboard_page).raises(SocketError)
131
+ assert_nil @account_invalid_login_page.blog_url
132
+ end
133
+
134
+ def test_add_post_raises_without_title_or_body
135
+ assert_raise Wordpress::PostError do
136
+ @account.add_post
137
+ end
138
+ end
139
+
140
+ def test_add_post_raises_without_post_form
141
+ @account_bad.stubs(:dashboard_page).returns(@fail_pg)
142
+ @account_bad.title = "Fail"
143
+ assert_raise Wordpress::HostError do
144
+ @account_bad.add_post
145
+ end
146
+ end
147
+
148
+ def test_post_response_returns_good_response
149
+ Wordpress::Client.private_methods {
150
+ assert_equal "ok", @account.post_response(@success_pg)["rsp"]["stat"]
151
+ }
152
+ end
153
+
154
+ def test_add_post_returns_fail
155
+ Wordpress::Client.private_methods {
156
+ title = "My Title"
157
+ @account.title = title
158
+ res = @account.post_response(@fail_pg)
159
+ assert_equal "fail", res["rsp"]["stat"]
160
+ assert_equal "Post was unsuccessful.", res["rsp"]["err"]["msg"]
161
+ assert_equal title, res["rsp"]["err"]["title"]
162
+ }
163
+ end
164
+
165
+ def test_add_post_returns_ok
166
+ @account.stubs(:dashboard_page).returns(@admin_pg)
167
+ @account.agent.stubs(:submit).returns(@success_pg)
168
+ title = "My Title"
169
+ @account.title = title
170
+ @account.body = "Body Text ..."
171
+ actual = @account.add_post
172
+ assert_equal "ok", actual["rsp"]["stat"]
173
+ assert_equal title, actual["rsp"]["post"]["title"]
174
+ assert_equal "99", actual["rsp"]["post"]["id"]
175
+ assert_equal "http://success.com/2009/", actual["rsp"]["post"]["url"]
176
+ end
177
+
178
+ def test_add_post_returns_ok_with_only_title
179
+ @account.stubs(:dashboard_page).returns(@admin_pg)
180
+ @account.agent.stubs(:submit).returns(@success_pg)
181
+ title = "My Title"
182
+ @account.title = "My Title"
183
+ actual = @account.add_post
184
+ assert_equal "ok", actual["rsp"]["stat"]
185
+ assert_equal title, actual["rsp"]["post"]["title"]
186
+ end
187
+
188
+ def test_add_post_returns_ok_with_only_body
189
+ @account.stubs(:dashboard_page).returns(@admin_pg)
190
+ @account.agent.stubs(:submit).returns(@success_pg)
191
+ @account.body = "Body Text ..."
192
+ actual = @account.add_post
193
+ assert_equal "ok", actual["rsp"]["stat"]
194
+ assert_equal "", actual["rsp"]["post"]["title"]
195
+ end
196
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wordpress
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Jordan Dobson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-08 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: mechanize
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: mocha
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: hoe
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.12.2
44
+ version:
45
+ description: |-
46
+ The Wordpress gem provides posting to a Wordpress.com blog or a self hosted wordpress by providing your username, password, login url(if you host your blog) and your blog content. With this gem, you have access to add a text entry on Wordpress blog by providing these options: title text, body text, and a tag array. You must include at least title text or body text with your post.
47
+
48
+ Posting images with posts, posting only images and pulling down your posts will be available very soon.
49
+ email:
50
+ - jordan.dobson@madebysquad.com
51
+ executables:
52
+ - wordpress
53
+ extensions: []
54
+
55
+ extra_rdoc_files:
56
+ - History.txt
57
+ - Manifest.txt
58
+ - README.txt
59
+ files:
60
+ - History.txt
61
+ - Manifest.txt
62
+ - README.txt
63
+ - Rakefile
64
+ - bin/wordpress
65
+ - lib/wordpress.rb
66
+ - test/test_wordpress.rb
67
+ has_rdoc: true
68
+ homepage: http://github.com/jordandobson/wordpress/tree/master
69
+ licenses: []
70
+
71
+ post_install_message:
72
+ rdoc_options:
73
+ - --main
74
+ - README.txt
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: "0"
88
+ version:
89
+ requirements: []
90
+
91
+ rubyforge_project: wordpress
92
+ rubygems_version: 1.3.3
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: The Wordpress gem provides posting to a Wordpress.com blog or a self hosted wordpress by providing your username, password, login url(if you host your blog) and your blog content
96
+ test_files:
97
+ - test/test_wordpress.rb