wordpress 0.1.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,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