Created
February 12, 2010 19:25
-
-
Save outoftime/302888 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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