rump -- Ruby Upload Metaweblog Post

Author:	Chip Camden
Date:	June, 2010
Site:	http://chipstips.com/?tag=rbrump


This utility allows you to write blog posts in plain text (with a little
Ruby thrown in) and then upload them to a blog host that supports the
MetaWeblog API (e.g., WordPress).  If your blog doesn't support the
API, you can still use this utility to generate HTML to paste into your
blog platform -- see PREVIEWING below.


rump [-e "commands"] [-p previewfile | -f ID | -d ID | -u ID] [-v] [file ...]


"commands"	Are Ruby statements to be executed after all of the files
		have been evaluated.  You can specify more than one -e,
		and the separate command strings will be evaluated
		together with an intervening newline.  You can also embed
		a semi-colon to separate commands within a string.

previewfile	Is the name of an RHTML file to use as a template for
		previewing the output, without posting.

ID		Is the post ID to fetch (-f), delete (-d) or update (-u).

file		Are zero or more files to evaluate.  Each file also
		contains Ruby statements.  Files will be evaluated in the
		order given.  If a file is "-", then STDIN will be

-v		Indicates verbose mode.  Currently, the only verbose
		output is to indicate successful submission, with the
		returned post ID and a permalink, if the structure is given.

Typically, you could invoke rump with two files: a configuration file
that is probably common to a blog site, and a file containing a blog
post.  The -e option is provided so you can temporarily override a
setting in one of these files without having to edit them.  Of course,
you can diverge from the typical in any way you please.

If -p, -f, or -u are not supplied, then the post will be uploaded as a
new post.  If more than one of these switches occurs, -p has precedence,
followed by -f, then -u.

A configuration file would look something like the provided file


server    "SERVERDOMIAN.TLD"	# URL of the MetaWeblog API server
xmlrpc    "/xmlrpc.php"		# Server's path to the MetaWeblog API
username  "USERNAME"		# Your username for posting
password  "PASSWORD"		# and password
permalink "http://SERVERDOMAIN.TLD/?p=%d"	# Permalink structure
blogid    1			# Which blog on this server?
publish   true			# Publish posts (false to save as draft)


while a typical post would look more like the provided file testpost:


title "Here's a test of submitting"
content <<END
Mary had a little lamb, it's fleece was white as snow.

Here's a second paragraph.  It has <strong>bold</strong>
and <em>italic</em> text.

How about an image?

<img src="http://chipstips.com/images/Chip3.jpg"/>
category "well"
tags "tag,tag2"


A previewfile will be passed to eruby for formatting.  See the section


In addition to all available Ruby syntax, rump provides the following

category(name) => array

Adds the category named name to the array of categories for the post,
returning the full array of categories.

content(text) => string

Appends the string in text to the post's content, and returns the complete
text for the post.

emit(name, content) => nil

Used by -f when generating code.  Uses puts to emit:

name <<END_NAME

replace(what,with) => array

Adds an element to the array of text replacements, returning the complete
array.  Before the post is submitted or after the post is fetched, each what
will be replaced with with in the post's content.  You can use Regexp's or strings.

strip_single_newlines => array

Adds a replacement for lone newline characters to replace them with
spaces.  This prevents an end-of-line from being taken literally by your
blog, but still allows two or more newlines to signal a paragraph.

tags(text) => string

Adds text to the tags for the post (should be comma-separated tags),
and returns the new complete set of tags.  This only works for blogs that
recognize the MetaWeblog element "mt_keywords" for tags (e.g., WordPress).

title(text) => string

Appends the string in text to the post's title, and returns the new

Additionally, any undefined method name will be taken as an options
setting.  Thus,

server "example.com"

is equivalent to:

$options[:server] = "example.com"

Options that actually affect anything include:

blogid		(number) the ID of the blog on your server.  This is
		typically 1, which is the default.

delete		(number) the ID of the post to delete from the server.  Default
		is nil.

fetch		(number) the ID of the post to fetch from the server.  Default
		is nil.

password	(string) the password for posting on your blog.  This has
		no default value, and is required.

permalink	(string) format for permalink structure.  This is passed
		to sprintf with the post ID as an argument.  So, a WordPress
		example might look like  "http://example.com/?p=%d".  The
		default is nil.

preview		(string) name of an RHTML file to use as a preview
		template.  If this option is specified, the post will not
		be uploaded, but rather previewed.  Default is nil, but
		may be set with the -p command line option.

publish		(boolean) true to publish the post, or false to save it
		as a draft.  The default value is true.

server		(string) the URI of the MetaWeblog server (usually your
		blog's home URI).  This has no default value, and is

update		(number) the ID of the post to update on the server.  Default
		is nil.

username	(string) the username for posting on your blog.  This has
		no default value, and is required.

verbose		(boolean) verbose mode.  This is initially nil, and set to
		true by the "-v" command line option.

xmlrpc		(string) the path on the server to the script that
		processes XMLRPC requests.  On WordPress, this is
		"/xmlrpc.php", which is the default value.

A number of global variables are also accessible by your scripts, should
you require finer control.  These are:

$options	Hash of :option => value, where :option is one of the
		options listed above.

$post		Hash of :element => value, where :element is one of the
		allowed elements in the MetaWeblog newPost request.
		These include :description (the content), :title,
		:categories, and :mt_keywords, among others.

$replace	Array of arrays of [what, with] that represent substitutions
		to perform after all files and commands have been
		evaluated but before submitting the post, or after
		fetching it.


It's often useful to see how your post will look on the blog before
publishing it.  This can be accomplished by using the -p (or --preview)
option followed by the name of an RHTML file that will be passed to
eruby.  You can then pipe the output to your favorite browser, or
redirect it to a file as HTML.

The included file preview.rhtml provides an example previewfile.

Your eruby script should require the file rump_preview.rb:

<% require "rump_preview" %>

This will insure that the global variables $post and $options are
defined, as well as providing a number of useful methods:

content		(string) returns the content of the post, with all
		double newlines converted to </p><p> pairs, all
		remaining single newlines converted to <br/>, and the
		entire content enclosed in <p> and </p>.

tags		(string) alias for $post[:mt_keywords]

Additionally, any undefined method name resolves to $post[:name], so
'title' and 'categories' can be used to access those members, for
instance.  If $post[:name] is nil, then $options[:name] will be used --
so 'publish', 'server', etc. can be referenced directly.


When piping the output to a browser, you may find the included script
'farg' useful.  For instance, Firefox does not take input on STDIN -- it
must be passed as a file argument instead.  farg allows you to do this,
by redirecting STDIN to a temporary file, passing that as a file
argument to a command, and then deleting the file.


	farg cmd

where	cmd	is a printf format string specifying the command to
		execute, where the first format token will be replaced
		by the name of the temporary file.


	farg 'firefox %s'

This example sends STDIN to firefox as a web page.


I've also included an example script named 'rump_preview' that evaluates
a rump file named .rump along with STDIN, and previews it using
preview.rhtml.  If an argument is passed, it is taken as the name of the
browser to launch.  Otherwise, it sends the result to STDOUT.

A sample .vimrc file (dot.vimrc) shows how you can map keyboard shortcuts
as follows:

F7		Fetch a post into the buffer, after user enters post ID
F8		Update a post, after user enters post ID
F9		Preview the current page, saving it as <file>.html
F10		Preview the current page in w3m
F11		Preview the current page in firefox
F12		Post the current page

These key mappings assume that a file named .rump exists in the current
directory to specify the server information.  The fetch makes use of
unquote.rump (included) to remove smart quotes.