wordpressto 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ wordpressto is released under the MIT License.
2
+
3
+ Copyright (c) 2010 John Leach
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of the acts_as_xapian software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including without
8
+ limitation the rights to use, copy, modify, merge, publish, distribute,
9
+ sublicense, and/or sell copies of the Software, and to permit persons to whom
10
+ the Software is furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = Wordpressto
2
+
3
+ Wordpressto is a Ruby library for reading from and writing to
4
+ {Wordpress}[http://www.wordpress.org] blogs via their XMLRPC
5
+ interface.
6
+
7
+ It was extracted from another project and isn't yet feature complete,
8
+ but it is still useful. The documentation is lacking and the test
9
+ suite is not complete. Remember though: release early and release
10
+ often!
11
+
12
+ == Installation
13
+
14
+ sudo gem install wordpressto
15
+
16
+ == Documentation
17
+
18
+ require 'wordpressto'
19
+ blog = Wordpressto::WordpressBlog.new :url => 'http://www.example.com/xmlrpc.php',
20
+ :username => 'john', :password=> 'letmein'
21
+
22
+ # Output the list of categories
23
+ blog.categories.each { |c| puts c.name }
24
+
25
+ # Get the 20 most recent posts
26
+ blog.posts.find_recent(:limit => 20)
27
+
28
+ # Create a new blog post
29
+ post = blog.posts.new(:title => 'Test', :description => 'This is a test',
30
+ :keywords => 'test, testing', :published => true)
31
+ post.save
32
+
33
+ # Edit a blog post
34
+ post = blog.posts.find(123)
35
+ post.title = "Edited title"
36
+ post.save
37
+
38
+ # Upload an attachment
39
+ attachment = blog.attachments.new(:name => 'Photo of me', :filename => '/home/john/me.jpg')
40
+ attachment.save
41
+
42
+
43
+ = More Info
44
+
45
+ Author:: John Leach (mailto:john@johnleach.co.uk)
46
+ Copyright:: Copyright (c) 2010 John Leach
47
+ License:: MIT
48
+ Github:: http://github.com/johnl/wordpressto/tree/master
@@ -0,0 +1,232 @@
1
+ require 'wordpressto/base'
2
+ require 'wordpressto/category_collection'
3
+ module Wordpressto
4
+ require "xmlrpc/client"
5
+ require 'uri'
6
+ require 'mime/types'
7
+
8
+ class WordpressBlog
9
+ attr_accessor :url, :username, :password, :blog_id
10
+
11
+ def initialize(options = { })
12
+ @username = options[:username] if options[:username]
13
+ @password = options[:password] if options[:password]
14
+ @blog_id = options[:blog_id] || 1
15
+ @url = options[:url] if options[:url]
16
+ end
17
+
18
+ def posts
19
+ @post_collection ||= WordpressPostCollection.new(:conn => self)
20
+ end
21
+
22
+ def attachments
23
+ @attachments ||= WordpressAttachmentCollection.new(:conn => self)
24
+ end
25
+
26
+ def categories
27
+ @categories ||= CategoryCollection.new(:conn => self)
28
+ end
29
+
30
+ def get_recent_posts(limit = 10)
31
+ call('metaWeblog.getRecentPosts', blog_id, username, password, limit)
32
+ end
33
+
34
+ def get_post(qid)
35
+ call('metaWeblog.getPost', qid, username, password)
36
+ end
37
+
38
+ def edit_post(qid, attributes, published = nil)
39
+ cargs = ['metaWeblog.editPost', qid, username, password, attributes]
40
+ cargs << published unless published.nil?
41
+ call(*cargs)
42
+ end
43
+
44
+ def new_post(attributes, published = nil)
45
+ cargs = ['metaWeblog.newPost', blog_id, username, password, attributes]
46
+ cargs << published unless published.nil?
47
+ call(*cargs)
48
+ end
49
+
50
+ def upload_file(name, mimetype, bits, overwrite = false)
51
+ call('wp.uploadFile', blog_id, username, password,
52
+ { :name => name, :type => mimetype, :bits => XMLRPC::Base64.new(bits), :overwrite => overwrite })
53
+ end
54
+
55
+ def call(*args)
56
+ xmlrpc.call(*args)
57
+ rescue XMLRPC::FaultException => e
58
+ if e.message =~ /XML-RPC services are disabled/
59
+ raise Wordpressto::ConnectionFailure, e.message
60
+ else
61
+ raise Wordpressto::Error, e.message
62
+ end
63
+ end
64
+
65
+ def xmlrpc
66
+ @xclient ||= XMLRPC::Client.new2(url)
67
+ end
68
+
69
+ end
70
+
71
+ class WordpressAttachmentCollection < Base
72
+ def new(attributes)
73
+ WordpressAttachment.new(attributes, :conn => conn)
74
+ end
75
+ end
76
+
77
+ class WordpressAttachment < Base
78
+ attr_accessor :name, :mimetype, :file, :filename, :url
79
+
80
+ def initialize(attributes, options = { })
81
+ super(options)
82
+ self.name = attributes[:name]
83
+ self.filename = attributes[:filename]
84
+ self.mimetype = attributes[:mimetype]
85
+ self.file = attributes[:file]
86
+ end
87
+
88
+ def save
89
+ ret = conn.upload_file(name, mimetype, bits)
90
+ self.url = ret["url"]
91
+ self
92
+ end
93
+
94
+ def mimetype
95
+ @mimetype ||= MIME::Types.type_for(name).to_s
96
+ end
97
+
98
+ def name
99
+ @name ||= File.basename(filename)
100
+ end
101
+
102
+ private
103
+
104
+ def bits
105
+ file.read
106
+ end
107
+
108
+ def file
109
+ @file ||= File.open(filename)
110
+ end
111
+ end
112
+
113
+ class WordpressPostCollection < Base
114
+ def find_recent(options = { })
115
+ options = { :limit => 10 }.merge(options)
116
+ posts = conn.get_recent_posts(options[:limit])
117
+ posts.collect { |post| WordpressPost.new(post, :conn => conn) }
118
+ end
119
+
120
+ def find(qid, options = { })
121
+ if qid.is_a?(Array)
122
+ qid.collect { |sqid| find(sqid) }
123
+ elsif qid == :recent
124
+ find_recent(options)
125
+ else
126
+ post = conn.get_post(qid)
127
+ WordpressPost.new(post, :conn => conn)
128
+ end
129
+ end
130
+
131
+ def new(attributes = { })
132
+ WordpressPost.new(attributes, :conn => conn)
133
+ end
134
+
135
+ end
136
+
137
+
138
+ class WordpressPost < Base
139
+ attr_accessor :title, :description
140
+ attr_accessor :created_at
141
+ attr_accessor :keywords, :categories, :published
142
+
143
+ def initialize(attributes = { }, options = { })
144
+ super(options)
145
+ self.attributes = attributes
146
+ end
147
+
148
+ def attributes=(attr)
149
+ symbolized_attr = { }
150
+ attr = attr.each { |k,v| symbolized_attr[k.to_sym] = v }
151
+ attr = symbolized_attr
152
+ @title = attr[:title]
153
+ @keywords = attr[:mt_keywords].to_s.split(/,|;/).collect { |k| k.strip }
154
+ @categories = attr[:categories]
155
+ @description = attr[:description]
156
+ @created_at = attr[:dateCreated]
157
+ @id = attr[:postid]
158
+ @userid = attr[:userid]
159
+ @published = attr[:published]
160
+ end
161
+
162
+ def id
163
+ @id
164
+ end
165
+
166
+ def save
167
+ id ? update : create
168
+ end
169
+
170
+ def update
171
+ conn.edit_post(id, attributes, published)
172
+ self
173
+ end
174
+
175
+ def create
176
+ @id = conn.new_post(attributes, published)
177
+ self
178
+ end
179
+
180
+ def publish
181
+ self.published = true
182
+ save
183
+ end
184
+
185
+ def keywords
186
+ if @keywords.is_a? String
187
+ @keywords = @keywords.split(",")
188
+ elsif @keywords.is_a? Array
189
+ @keywords
190
+ else
191
+ []
192
+ end
193
+ end
194
+
195
+ def created_at
196
+ @created_at
197
+ end
198
+
199
+ def categories
200
+ if @categories.nil?
201
+ []
202
+ elsif @categories.is_a?(Array)
203
+ @categories
204
+ elsif @categories.is_a(String)
205
+ @categories = @categories.split(",")
206
+ else
207
+ []
208
+ end
209
+ end
210
+
211
+ def attributes
212
+ h = { }
213
+ h[:title] = title if title
214
+ h[:description] = description if description
215
+ h[:dateCreated] = created_at if created_at
216
+ h[:mt_keywords] = keywords.join(",")
217
+ h[:categories] = categories if categories
218
+ h
219
+ end
220
+
221
+ def reload
222
+ if id
223
+ saved_id = id
224
+ self.attributes = conn.posts.find(id).attributes
225
+ @id = saved_id
226
+ true
227
+ end
228
+ end
229
+
230
+
231
+ end
232
+ end
@@ -0,0 +1,14 @@
1
+ module Wordpressto
2
+ class Error < StandardError ; end
3
+ class ConnectionFailure < Error ; end
4
+
5
+ class Base
6
+ def initialize(options = { })
7
+ @conn = options[:conn] || options[:connection]
8
+ end
9
+
10
+ def conn
11
+ @conn
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ module Wordpressto
2
+ class Category
3
+ attr_reader :id, :category_id, :description, :name, :url, :rss_url, :conn
4
+
5
+ def initialize(attributes = {}, options = {})
6
+ @id = attributes[:id]
7
+ @category_id = attributes[:category_id] || 0
8
+ @description = attributes[:description]
9
+ @name = attributes[:name]
10
+ @url = attributes[:url]
11
+ @rss_url = attributes[:rss_url]
12
+ @slug = attributes[:slug]
13
+ @conn = options[:conn]
14
+ end
15
+
16
+ def self.new_from_xmlrpc(attributes, options = {})
17
+ self.new( { :id => attributes['categoryId'], :category_id => attributes['parentId'],
18
+ :description => attributes['description'], :name => attributes['categoryName'],
19
+ :url => attributes['htmlUrl'], :rss_url => attributes['rssUrl'] },
20
+ options )
21
+ end
22
+
23
+ def save
24
+ @id = conn.call 'wp.newCategory', conn.blog_id, conn.username, conn.password, to_xmlrpc_struct
25
+ end
26
+
27
+ def to_xmlrpc_struct
28
+ { "name" => name, "slug" => slug, "parent_id" => category_id, "description" => description.to_s }
29
+ end
30
+
31
+ def slug
32
+ @slug ||= @name.to_s.downcase.strip.gsub(/\s/, '-')
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,37 @@
1
+ require 'wordpressto/category'
2
+ module Wordpressto
3
+ class CategoryCollection < Base
4
+ include Enumerable
5
+
6
+ def initialize(*args)
7
+ super(*args)
8
+ end
9
+
10
+ def all
11
+ @categories ||= load
12
+ end
13
+
14
+ # retrieve the categories via xmlrpc
15
+ def load
16
+ cats = []
17
+ conn.call('wp.getCategories', conn.blog_id, conn.username, conn.password).each do |c|
18
+ cats << Category.new_from_xmlrpc(c, :conn => conn)
19
+ end
20
+ @categories = cats
21
+ end
22
+
23
+ def [](i)
24
+ all[i]
25
+ end
26
+
27
+ def each
28
+ all.each { |c| yield c }
29
+ end
30
+
31
+ def create(attributes)
32
+ new_cat = Category.new(attributes, :conn => conn)
33
+ new_cat.save
34
+ new_cat
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,12 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe CategoryCollection do
4
+ it "should retrieve categories via xmlrpc" do
5
+ blog = a_wordpress_blog
6
+ blog.xmlrpc.should_receive(:call).once.with('wp.getCategories', blog.blog_id, blog.username, blog.password).and_return([{}, {}, {}])
7
+ cats = blog.categories.load
8
+ cats.size.should == 3
9
+ cats.first.should be_a_kind_of Category
10
+ cats.first.conn.should == blog
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe Category do
4
+ describe "create" do
5
+ it "should call wp.newCategory" do
6
+ blog = a_wordpress_blog
7
+ blog.xmlrpc.should_receive(:call).once.with('wp.newCategory', blog.blog_id, blog.username, blog.password,
8
+ hash_including("name" => valid_category_options[:name])).and_return(10)
9
+ blog.categories.create valid_category_options
10
+ end
11
+
12
+ it "should return a Category instance with the right id" do
13
+ blog = a_wordpress_blog
14
+ blog.xmlrpc.should_receive(:call).once.and_return(10)
15
+ blog.categories.create(valid_category_options).id.should == 10
16
+ end
17
+ end
18
+
19
+ it "should generate a slug from the title if not provided" do
20
+ Category.new(:name => "Blog Posts ").slug.should == "blog-posts"
21
+ Category.new(:name => "Blog Posts", :slug => 'posts').slug.should == "posts"
22
+ Category.new(:name => nil).slug.should be_empty
23
+ end
24
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format n
3
+ --loadby mtime
4
+ --reverse
5
+
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'lib/wordpressto.rb'
3
+ include Wordpressto
4
+
5
+ def valid_wordpress_blog_options
6
+ { :username => 'lily', :password => 'lilybeans', :url => 'http://example.com', :blog_id => 666 }
7
+ end
8
+
9
+ def valid_wordpress_post_options
10
+ { :title => "Test Post", :description => "The text of the post", :dateCreated => Time.at(1284243726),
11
+ :mt_keywords => 'test,post,example', :categories => 'blog' }
12
+ end
13
+
14
+ def a_wordpress_blog
15
+ WordpressBlog.new(valid_wordpress_blog_options)
16
+ end
17
+
18
+ def valid_wordpress_upload_options
19
+ { :name => "A file", :type => "application/octet-stream",
20
+ :bits => "12345678910", :overwrite => false }
21
+ end
22
+
23
+ def valid_category_options
24
+ { :name => 'Posts', :slug => 'posts', :parent_id => nil, :description => "Blog posts" }
25
+ end
@@ -0,0 +1,119 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe WordpressBlog do
4
+
5
+ describe "initialize" do
6
+ it "take the :username, :password, :url and :blog_id options" do
7
+ blog = a_wordpress_blog
8
+ blog.username.should == valid_wordpress_blog_options[:username]
9
+ blog.password.should == valid_wordpress_blog_options[:password]
10
+ blog.blog_id.should == valid_wordpress_blog_options[:blog_id]
11
+ end
12
+
13
+ it "should default to blog_id 1" do
14
+ WordpressBlog.new.blog_id.should == 1
15
+ end
16
+ end
17
+
18
+ it "should return an XMLRPC::Client" do
19
+ xmlrpc = a_wordpress_blog.send(:xmlrpc)
20
+ xmlrpc.should be_a_kind_of XMLRPC::Client
21
+ end
22
+
23
+ it "should make xmlrpc calls to metaWeblog.getPost" do
24
+ blog = a_wordpress_blog
25
+ blog.send(:xmlrpc).should_receive(:call).once.with('metaWeblog.getPost',
26
+ 999, blog.username, blog.password )
27
+ blog.get_post(999)
28
+ end
29
+
30
+ it "should make xmlrpc calls to metaWeblog.getRecentPosts" do
31
+ blog = a_wordpress_blog
32
+ blog.send(:xmlrpc).should_receive(:call).once.with('metaWeblog.getRecentPosts',
33
+ blog.blog_id, blog.username, blog.password, 345)
34
+ blog.get_recent_posts(345)
35
+ end
36
+
37
+ describe "edit_post" do
38
+
39
+ it "should make xmlrpc calls to metaWeblog.editPost with no published arg by default" do
40
+ blog = a_wordpress_blog
41
+ blog.send(:xmlrpc).should_receive(:call).once.with('metaWeblog.editPost',
42
+ 98, blog.username, blog.password,
43
+ valid_wordpress_post_options)
44
+ blog.edit_post(98, valid_wordpress_post_options)
45
+ end
46
+
47
+ it "should make xmlrpc calls to metaWeblog.editPost with published = true" do
48
+ blog = a_wordpress_blog
49
+ blog.send(:xmlrpc).should_receive(:call).once.with('metaWeblog.editPost',
50
+ 98, blog.username, blog.password,
51
+ valid_wordpress_post_options, true)
52
+ blog.edit_post(98, valid_wordpress_post_options, true)
53
+ end
54
+
55
+ it "should make xmlrpc calls to metaWeblog.editPost with published = false" do
56
+ blog = a_wordpress_blog
57
+ blog.send(:xmlrpc).should_receive(:call).once.with('metaWeblog.editPost',
58
+ 98, blog.username, blog.password,
59
+ valid_wordpress_post_options, false)
60
+ blog.edit_post(98, valid_wordpress_post_options, false)
61
+ end
62
+
63
+
64
+ end
65
+
66
+ describe "new_post" do
67
+ it "should make metaWeblog.newPost calls with no published arg by default" do
68
+ blog = a_wordpress_blog
69
+ blog.send(:xmlrpc).should_receive(:call).once.with('metaWeblog.newPost',
70
+ blog.blog_id, blog.username, blog.password,
71
+ valid_wordpress_post_options)
72
+ blog.new_post(valid_wordpress_post_options)
73
+ end
74
+
75
+ it "should make metaWeblog.newPost calls with published = true" do
76
+ blog = a_wordpress_blog
77
+ blog.send(:xmlrpc).should_receive(:call).once.with('metaWeblog.newPost',
78
+ blog.blog_id, blog.username, blog.password,
79
+ valid_wordpress_post_options, true)
80
+ blog.new_post(valid_wordpress_post_options, true)
81
+ end
82
+
83
+ it "should make metaWeblog.newPost calls with published = false" do
84
+ blog = a_wordpress_blog
85
+ blog.send(:xmlrpc).should_receive(:call).once.with('metaWeblog.newPost',
86
+ blog.blog_id, blog.username, blog.password,
87
+ valid_wordpress_post_options, false)
88
+ blog.new_post(valid_wordpress_post_options, false)
89
+ end
90
+
91
+ end
92
+
93
+ describe "upload_file" do
94
+ it "should make wp.uploadFile calls" do
95
+ blog = a_wordpress_blog
96
+ xmlrpc_valid_wordpress_upload_options = valid_wordpress_upload_options.merge({
97
+ :bits => XMLRPC::Base64.new(valid_wordpress_upload_options[:bits])
98
+ })
99
+ blog.send(:xmlrpc).should_receive(:call).once.with('wp.uploadFile', blog.blog_id, blog.username,
100
+ blog.password,
101
+ hash_including({
102
+ :name => valid_wordpress_upload_options[:name],
103
+ :type => valid_wordpress_upload_options[:type],
104
+ :overwrite => valid_wordpress_upload_options[:overwrite],
105
+ :bits => an_instance_of(XMLRPC::Base64)
106
+ }))
107
+ args = [:name, :type, :bits, :overwrite].collect { |k| valid_wordpress_upload_options[k] }
108
+ blog.upload_file(*args)
109
+ end
110
+ end
111
+
112
+ it "should return a CategoryCollection" do
113
+ blog = a_wordpress_blog
114
+ blog.categories.should be_a_kind_of CategoryCollection
115
+ blog.categories.conn.should == blog
116
+ end
117
+
118
+ end
119
+
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wordpressto
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - John Leach
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-09-12 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: mime-types
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rake
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :development
61
+ version_requirements: *id003
62
+ description: A Ruby library to interact with the Wordpress XMLRPC interface
63
+ email: john@johnleach.co.uk
64
+ executables: []
65
+
66
+ extensions: []
67
+
68
+ extra_rdoc_files:
69
+ - README.rdoc
70
+ - LICENSE
71
+ files:
72
+ - lib/wordpressto.rb
73
+ - lib/wordpressto/base.rb
74
+ - lib/wordpressto/category.rb
75
+ - lib/wordpressto/category_collection.rb
76
+ - README.rdoc
77
+ - LICENSE
78
+ - spec/spec_helper.rb
79
+ - spec/wordpress_blog_spec.rb
80
+ - spec/category_collection_spec.rb
81
+ - spec/category_spec.rb
82
+ - spec/spec.opts
83
+ has_rdoc: true
84
+ homepage: http://github.com/johnl/wordpressto
85
+ licenses: []
86
+
87
+ post_install_message:
88
+ rdoc_options:
89
+ - --title
90
+ - Wordpressto
91
+ - --main
92
+ - README.rdoc
93
+ - --line-numbers
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ requirements: []
115
+
116
+ rubyforge_project:
117
+ rubygems_version: 1.3.7
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: A Ruby library to interact with the Wordpress XMLRPC interface
121
+ test_files:
122
+ - spec/spec_helper.rb
123
+ - spec/wordpress_blog_spec.rb
124
+ - spec/category_collection_spec.rb
125
+ - spec/category_spec.rb
126
+ - spec/spec.opts