Skip to content

Instantly share code, notes, and snippets.

@outoftime
Created February 12, 2010 19:25
Show Gist options
  • Save outoftime/302888 to your computer and use it in GitHub Desktop.
Save outoftime/302888 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#
# This is a simple script that allows you to post to Posterous from files on
# your computer. Currently accepted formats are HTML and markdown.
#
# USAGE
#
# posterous-post my-post.mkd
#
# CONFIGURATION
#
# Create a file called .posterousrc in your home directory. This file should
# be in YAML format and have at least the keys 'email' and 'password', which
# are the email and password you use to log in to Posterous. You can also add
# the 'site_id' key, which tells Posterous to post to a site other than your
# personal blog.
#
# YAML FRONT MATTER
#
# Posts are given metadata using YAML front matter. This idea is taken from the
# Jekyll blog engine and it works the same way. You can read about it here:
#
# http://wiki.github.com/mojombo/jekyll/yaml-front-matter
#
# The following keys are available; all are optional: title, autopost, private,
# date, source, source_link
#
# UPDATING POSTS
#
# The first time you create a post, the file is updated with the post's ID in
# the YAML front matter. So, be sure to reload the file before editing it. If
# you then post the file again, it will update the blog post rather than
# creating a new one.
#
# DEPENDENCIES
#
# * Ruby
# * Rubygems
# * Nokogiri
# * RDiscount
#
require 'rubygems'
require 'net/http'
require 'date'
require 'rdiscount'
require 'nokogiri'
NEW_POST_URI = URI.parse("http://posterous.com/api/newpost")
UPDATE_POST_URI = URI.parse("http://posterous.com/api/updatepost")
config = File.open(File.join(ENV['HOME'], '.posterousrc')) do |file|
YAML.load(file)
end
filename = ARGV[0]
post_meta, post_body = File.open(filename) do |file|
post_meta_yaml = ''
if file.gets =~ /^---\s*/
while (line = file.gets) !~ /^---\s*/
post_meta_yaml << line
end
else
file.rewind
end
[YAML.load(post_meta_yaml), file.read]
end
post_meta ||= {}
new_post = !post_meta.has_key?('post_id')
uri = new_post ? NEW_POST_URI : UPDATE_POST_URI
request = Net::HTTP::Post.new(uri.path)
request.basic_auth(config['email'], config['password'])
form_data = {}
form_data['title'] = post_meta['title'] if post_meta['title']
form_data['body'] =
case File.extname(filename)
when '.mkd', '.markdown'
RDiscount.new(post_body).to_html
when '.html'
post_body
else
abort "Didn't recognize extension #{File.extname(filename)}"
end
if new_post
form_data['site_id'] = config['site_id'] if config['site_id']
form_data['autopost'] = post_meta['autopost'] ? 1 : 0
form_data['private'] = post_meta['private'] ? 1 : 0
form_data['date'] = Time.parse(post_meta['date']).utc.xmlschema if post_meta['date']
form_data['source'] = post_meta['source'] if post_meta['source']
form_data['sourceLink'] = post_meta['source_link'] if post_meta['source_link']
else
form_data['post_id'] = post_meta['post_id']
end
request.set_form_data(form_data)
response = Net::HTTP.new(uri.host, uri.port).start do |http|
http.request(request)
end
response_xml = Nokogiri::XML(response.body)
if response.code_type == Net::HTTPOK
post_url = response_xml.xpath('rsp/post/longurl').text
if new_post
File.open(filename, 'w') do |file|
post_meta['post_id'] = response_xml.xpath('rsp/post/id').text.to_i
file.puts(YAML.dump(post_meta))
file.puts('---')
file.puts(post_body)
end
puts "Created post #{post_meta['title'].inspect} at #{post_url}"
else
puts "Updated post #{post_meta['title'].inspect} at #{post_url}"
end
else
abort(response_xml.xpath('rsp/err').attr('msg').text)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment