This is just a maintenance release, nothing too exciting:
== 0.3.5 2008-05-03
* Make sure atom:entries appears last.
* Better examples in the documentation.
* Gave Feeds authors and contributors.
* Fixed a couple warnings.
This is just a maintenance release, nothing too exciting:
Some mysterious anonymous person asked me for a tutorial on using rAtom within Rails. So I'll show you all how I do it.
class Post < ActiveRecord::Base
def to_atom
Atom::Entry.new do |entry|
entry.title = self.title
entry.updated = self.updated_at
entry.published = self.created_at
entry.author = Atom::Person.new(:name => self.author)
entry.links << Atom::Link.new(:rel => 'alternate',
:href => "/posts/#{self.id}")
entry.content = Atom::Content::Html.new(self.content)
end
end
endThe advantage of returning a rAtom object here is that the atom representation is then composable, for example if you have a Blog class that has many posts you can do this:
class Blog < ActiveRecord::Base
has_many :posts
def to_atom
Atom::Feed.new do |feed|
feed.title = self.title
feed.links << Atom::Link.new(:rel => 'alternate',
:href => "/blogs/#{self.id}")
self.posts.each do |post|
feed.entries << post.to_atom
end
end
end
endclass BlogsController << ApplicationController
def show
@blog = Blog.find(params[:id])
respond_to do |format|
format.atom { render :xml => @blog.to_atom.to_xml }
end
end
end entry.links << Atom::Link.new(:rel => 'alternate',
:href => "/posts/#{self.id}")I've just release rAtom 0.3.0. This version adds support for simple extension elements and also checks that content is in UTF-8 before serializing to XML.
As defined in the Atom Syndication Format, simple extension elements consist of XML elements from a non-Atom namespace that have no attributes or child elements, i.e. they are empty or only contain text content. These elements are treated as a name value pair where the element namespace and local name make up the key and the content of the element is the value, empty elements will be treated as an empty string.
To access extension elements use the [] method on the Feed or Entry. For example, if we are parsing the follow Atom document with extensions:
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:ex="http://example.org">
<title>Feed with extensions</title>
<ex:myelement>Something important</ex:myelement>
</feed>
We could then access the extension element on the feed using:
> feed["http://example.org", "myelement"]
=> ["Something important"]
Note that the return value is an array. This is because XML allows multiple instances of the element.
To set an extension element you append to the array:
> feed['http://example.org', 'myelement'] << 'Something less important'
=> ["Something important", "Something less important"]You can then call to_xml and rAtom will serialize the extension elements into xml.
> puts feed.to_xml
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<myelement xmlns="http://example.org">Something important</myelement>
<myelement xmlns="http://example.org">Something less important</myelement>
</feed>
Notice that the output repeats the xmlns attribute for each of the extensions, this is semantically the same the input XML, just a bit ugly. It seems to be a limitation of the libxml-Ruby API. But if anyone knows a work around I'd gladly accept a patch (or even advice).
You can get rAtom via gem:
> gem install ratom
or from Github.
rAtom is a Ruby Gem for working with the Atom Syndication Format and the Atom Publishing Protocol (APP).
rAtom was originally built to support the communication between a number of applications built by Peerworks[http://peerworks.org], via the Atom Publishing protocol. However, it supports, or aims to support, all the Atom Syndication Format and Publication Protocol and can be used to access Atom feeds or to script publishing entries to a blog supporting APP.
Features:
# sudo gem install ratomfeed = Atom::Feed.load_feed(URI.parse("http://example.com/feed.atom"))
feed.each_entry do |entry|
# do cool stuff
end
feed = Atom::Feed.new do |feed|
feed.title = "My Cool Feed"
feed.id = "http://example.com/my_feed.atom"
feed.updated = Time.now
end
> puts feed.to_xml
<feed xmlns="http://www.w3.org/2005/Atom">
<title>My Cool Feed</title>
<id>http://example.com/my_feed.atom</id>
<updated>2008-03-03T23:19:44+10:30</updated>
</feed>
collection = Atom::Pub::Collection.new(:href => 'http://example.org/myblog')entry = Atom::Entry.new do |entry|
entry.title = "I have discovered rAtom"
entry.authors << name =""> 'A happy developer')
entry.updated = Time.now
entry.id = "http://example.org/myblog/newpost"
entry.content = Atom::Content::Html.new("<p>rAtom lets me post to my blog using Ruby, how cool!</p>")
end
published_entry = collection.publish(entry)I've recently started using Erlang on a project. This is my first foray into Erlang and I'm using Joe Armstong's new book Programming Erlang as introductory material. It is a great introduction to the language, although I wish it covered more of the OTP. I suppose there is the OTP Design Principles guide but sometimes a good paper book written in conversational style is better when you are learning.
In the book Joe describes building an Erlang project using make and most of the downloadable bits of Erlang code use make too; this makes sense, make is virtually ubiquitous. However the other components of this project are Ruby on Rails applications and make heavy use of Rake, so I figure why subject myself to Make when I can use the beautiful Rake.
Here is my Rakefile for building an Erlang project.
require 'rake/clean'
INCLUDE = "include"
ERLC_FLAGS = "-I#{INCLUDE} +warn_unused_vars +warn_unused_import"
SRC = FileList['src/*.erl']
OBJ = SRC.pathmap("%{src,ebin}X.beam")
CLEAN.include("ebin/*.beam")
directory 'ebin'
rule ".beam" => ["%{ebin,src}X.erl"] do |t|
sh "erlc -pa ebin -W #{ERLC_FLAGS} -o ebin #{t.source}"
end
task :compile => ['ebin'] + OBJ
task :default => :compile
rake compile which builds all the .erl files in the src subdirectory into the .beam files in the ebin directory. Files will only be built if they have changes since the last build. You also get rake clean which deletes all the .beam files from the ebin directory.I recently started using ActiveResource on a project. ActiveResource is the client side of the REST picture, that is it can consume the REST style web services you get with Rails, think of it as ActiveRecord for HTTP.
One of the difficult parts of using ActiveResource is testing. You don't want to run it over a real HTTP connection, for one it would significantly slow down your tests and secondly you don't know what horrible side effects it might have. So you need some way to fake a HTTP connection and HTTP requests and responses. Enter the HttpMock class.
HttpMock is a fairly nice class put together by the Rails folk that allows you to register a bunch of request and response pairs for a fake HTTP connection. When you call a method on an ActiveResource in a test, it calls the HttpMock class instead of trying to create a real connection. It is fairly easy to use, although there is no documentation the blogging community has come to the rescue.
Here is a quick example:
@matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
ActiveResource::HttpMock.respond_to do |mock|
mock.get "/people/1.xml", {}, @matz
end ActiveResource::HttpMock.respond_to do |mock|
mock.delete "/people/1.xml", {}, nil, 200
end1 def test_delete
2 assert Person.delete(1)
3 ActiveResource::HttpMock.respond_to do |mock|
4 mock.get "/people/1.xml", {}, nil, 404
5 end
6 assert_raises(ActiveResource::ResourceNotFound) { Person.find(1) }
7 end
def delete(id, options = {})
connection.delete(element_path(id, options))
end def delete(id, options = {})
true
end def test_delete
assert Person.delete(1)
assert ActiveResource::HttpMock.requests.include?(ActiveResource::Request.new(:delete, "/people/1.xml", nil, {}))
end ActiveResource::HttpMock.expects do |http|
http.delete "/people/1.xml", {}, nil, 200
end
class Array
def hash_by(attribute)
self.inject({}) do |hash, e|
hash[e.send(attribute)] = e
hash
end
end
end