Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

277 lines (211 sloc) 9.567 kb
;;; posterous.el --- Emacs integration for posterous.com
(defvar posterous-version "0.2")
;; Maintainer: Sarah Mount <snim2@snim2.org>
;; Author: Sarah Mount <snim2@snim2.org>
;; Jonas Bernoulli <jonasbernoulli@gmail.com>
;; zanoni https://github.com/zanoni
;; Tim Disney <tim.disney@gmail.com>
;; Version: 0.2
;; Created: 14 May 2010
;; Keywords: posterous blog
;; Last-Updated: Mon Feb 27 08:50:54 GMT 2012
;; By: Sarah Mount
;; Update: Tidied documentation, fixed posterous-new-markdown-post
;; URL: https://github.com/snim2/posterous.el
;; This file is NOT part of GNU Emacs.
;; This is free software; you can redistribute it and/or modify it under
;; the terms of the GNU General Public License as published by the Free
;; Software Foundation; either version 2, or (at your option) any later
;; version.
;;
;; This is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
;; for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
;; MA 02111-1307, USA.
;;; Commentary:
;; Emacs integration for posterous.com.
;; It currently supports posting text (only) to posterous.
;; Place the .el file somewhere on you load path (e.g. ~/.emacs.d/) and
;; set the following variables in your .emacs or init.el file:
;; posterous-email -- your email address or username on posterous.com
;; posterous-password -- your password on posterous.com
;; and you can interact with posterous.com using the functions:
;; M-x posterous-getsites
;; -- places a list of sites that you own on posterous.com.
;; -- Includes siteids.
;; -- Currently still formatted as XML.
;; M-x posterous-region
;; -- post a region of text to posterous
;; M-x posterous-region-private
;; -- post a region of text to posterous as a private post.
;; M-x posterous-buffer
;; -- post a buffer of text to posterous.
;; M-x posterous-buffer-private
;; -- post a buffer of text to posterous as a private post.
;; M-x posterous-new-markdown-post
;; -- Create a new post with a nice markdown template and put into
;; markdown mode.
;; If you do not wish to post to your default posterous site, you can
;; customise the variable:
;; posterous-default-siteid
;; to discover the siteids of all your sites, use M-x posterous-getsites.
;; If you do not wish to autopost to your social networks connected to
;; your posterous.com account, place the following in your Emacs
;; configuration file:
;; (setq posterous-suppress-autopost)
;;; Code:
(require 'url)
(require 'xml)
(defcustom posterous-email nil
"Email address or username on posterous.com."
:type 'string
:group 'posterous)
(defcustom posterous-password nil
"User password for posterous.com."
:type 'string
:group 'posterous)
(defcustom posterous-default-siteid nil
"Siteid for default posterous blog to post to. If this variable is null the user's default site will be used."
:type 'string
:group 'posterous)
(defcustom posterous-suppress-autopost nil
"Do NOT automatically send posterous posts to social networks."
:type 'boolean
:group 'posterous)
(defconst posterous-base-url "http://posterous.com/api/"
"Base posterous URL.")
(defconst posterous-getsites-url (concat posterous-base-url "getsites")
"Posterous URL for retrieving a list of posterous blogs.")
(defconst posterous-post-url (concat posterous-base-url "newpost")
"Posterous URL for posting new content.")
(defconst posterous-update-url (concat posterous-base-url "updatepost")
"Posterous URL for updating an existing post.")
(defconst posterous-comment-url (concat posterous-base-url "newcomment")
"Posterous URL for posting a new comment on an existing post.")
(defconst posterous-result-buffer "*posterous*"
"Buffer name for copying responses from posterous.com.")
(defun posterous-new-markdown-post ()
"Create a new post with a nice markdown template and put into markdown mode."
(interactive)
(let (title)
(setq title (read-from-minibuffer "Post title: "))
(switch-to-buffer (get-buffer-create title))
(markdown-mode)
(insert "<markdown>\n\n</markdown>"))
)
(defun posterous-getsites ()
"Get a list of sites owned by this user."
(interactive)
(let ((url-request-method "GET")
(url-request-extra-headers
`(("Authorization" . ,(base64-encode-string
(format "%s:%s" posterous-email posterous-password))))))
(save-excursion
(if (null posterous-email)
(setq posterous-email (read-from-minibuffer "Email address: ")))
(if (null posterous-password)
(setq posterous-password (read-from-minibuffer "Posterous password: ")))
(url-retrieve posterous-getsites-url 'posterous-getsites-callback))))
(defun posterous-post-base (post private media title tags autopost)
"Generic POST to posterous function. Called by posterous-post-generic."
(let ((url-request-method "POST")
(url-request-extra-headers
`(("Content-Type" . "application/x-www-form-urlencoded")
("Authorization" . ,(base64-encode-string
(format "%s:%s" posterous-email posterous-password)))))
(url-request-data
(concat "site_id=" (url-hexify-string posterous-default-siteid)
"&title=" (url-hexify-string title) ;; title
"&body=" (url-hexify-string post) ;; body
"&autopost=" (url-hexify-string autopost) ;; autopost
"&private=" (url-hexify-string private) ;; private
"&tags=" (url-hexify-string tags) ;; tags
"&media=" (url-hexify-string media) ;; media
)))
(url-retrieve posterous-post-url 'posterous-post-callback)))
(defun posterous-post-generic (start end private media)
"Generic post function called by all interactive functions."
(let (post title tags autopost)
(setq post (buffer-substring start end))
(setq title (read-from-minibuffer "Post title: "))
(setq tags (read-from-minibuffer "Tags (comma-separated): "))
(if (null posterous-email)
(setq posterous-email (read-from-minibuffer "Email address: ")))
(if (null posterous-password)
(setq posterous-password (read-from-minibuffer "Posterous password: ")))
(if posterous-suppress-autopost
(setq autopost "1")
(setq autopost "0"))
(posterous-post-base post private media title tags autopost)))
(defun posterous-region (start end)
"Post a region of text to posterous."
(interactive "r")
(save-excursion
(posterous-post-generic start end "0" "")))
(defun posterous-region-private (start end)
"Post a region of text to posterous as a private post."
(interactive "r")
(save-excursion
(posterous-post-generic start end "1" "")))
(defun posterous-buffer ()
"Post a whole buffer to posterous."
(interactive)
(save-excursion
(posterous-region (point-min) (point-max))))
(defun posterous-buffer-private ()
"Post a whole buffer to posterous as a private post."
(interactive)
(save-excursion
(posterous-region (point-min) (point-max))))
(defun posterous-getsites-callback (response)
"Deal with an HTTP RESPONSE from posterous.com. Remove the HTTP header, parse the XML returned from posterous."
(rename-buffer posterous-result-buffer)
;;; Delete HTTP header
(goto-char (point-min))
(search-forward-regexp "\n\n")
(delete-region (point-min) (point))
(set-buffer-modified-p nil)
(switch-to-buffer (current-buffer)))
;;; Parse XML returned by posterous.com
; (let* ((root (xml-parse-region (point-min) (point-max)))
; (rsp (car root)))))
(defun posterous-post-callback (response)
"Deal with an HTTP response from posterous.com.
Remove the HTTP header, parse the XML returned from posterous.
"
(rename-buffer posterous-result-buffer)
;;; Delete HTTP header
(goto-char (point-min))
(search-forward-regexp "\n\n")
(delete-region (point-min) (point))
(set-buffer-modified-p nil)
(switch-to-buffer (current-buffer))
;;; Parse XML returned by posterous.com
(let* ((root (xml-parse-region (point-min) (point-max)))
(rsp (car root))
(attrs (xml-node-attributes rsp))
(stat (cdr (assq 'stat attrs))))
(cond ((null stat)
(message "No status returned from posterous.com. Unknown error."))
;;; Posting was successful.
((string-equal stat "ok")
(let* ((post (car (xml-get-children rsp 'post)))
(id (car (xml-get-children post 'id)))
(text-id (car (xml-node-children id)))
(url (car (xml-get-children post 'url)))
(text-url (car (xml-node-children url))))
(message "New post at has id %s at: %s" text-id text-url)))
;;; Posting failed.
((string-equal stat "fail")
(let* ((err (car (xml-get-children rsp 'err)))
(err-attrs (xml-node-attributes err))
(msg (cdr (assq 'msg err-attrs))))
(message "Posting to posterous failed: %s." msg)))))
(kill-buffer (current-buffer)))
(provide 'posterous)
;;; posterous.el ends here
Jump to Line
Something went wrong with that request. Please try again.