Aside #10 – Send To Kindle WordPress plugin

Send to Kindle

Whilst uber geeking it up (streaming a HD Wired.com video podcast to my TV via a raspberry pi with the world’s teeniest usb wifi and a USB battery pack – my next RPi post will cover this!) I learned that WordPress has a new plugin for sending posts straight to your Kindle!

Great idea, since I’m always wanting to read some long post but don’t have the time, so would love a “read it later” button to push it to another device.

Installing the plugin

Here’s all it took to install on this blog:

Search for "Send to Kindle” from the plugin page on your wordpress install/site.

Send To Kindle - finding plugin 1

Find the “Send To Kindle” plugin from “Amazon Inc” and click “install”

Send To Kindle - finding plugin 2

Once installed you have a couple of options

Send To Kindle - plugin installed

You can configure the basics, such as where to display it, what font to use, what text to display (you’re limited to “Kindle”, “Send to Kindle”, or nothing..), which colour scheme to use, what size icon and of which colour, what colour background, and whether to display a border or not.

Send To Kindle - plugin setup - basic

If you want to mess around with the display yourself then the Advanced controls allow this, as well as some default settings of where to pull the post details from.

Send To Kindle - plugin setup - advanced

Then this will appear wherever you’ve chosen.

Button in action

Here it is on a post

Send To Kindle - button appearing

Clicking that  button pops up a window to get you to log in to your Amazon account …

Send To Kindle - Log In

and choose which device you send it to…

Send To Kindle - Configure Settings

Then content will be loaded and processed for Kindle viewing:

Send To Kindle - Awaiting Content  

Which means it ends up looking like this:

Send To Kindle - Content Loaded

Clicking the “Send” button first gives you a quick thinky thinky image:

Send To Kindle - Uploading

Before shortly letting you know it’s all ok

Send To Kindle - Upload Complete 

 

Viewing the post on your Kindle

You can then see this post on your Kindle the next time you turn it on in a Wifi (or 3G if your Kindle has Whispernet and you selected that as the delivery mechanism) area:

Here I have a couple of posts sent to my Kindle displaying on the home screen:

Send To Kindle - Viewing post content on Kindle - Listing

Selecting the RaspberryPi Part #2 post (which you can’t tell from the two on the home screen at the moment – I can probably sort this by changing the selectors in the advanced settings on the plugin page) here we have some basic text content:

Send To Kindle - Viewing post content on Kindle

Some image content:

Send To Kindle - Viewing post content on Kindle - Image

And some code example content:

Send To Kindle - Viewing post content on Kindle - Code

The code example is rendered via the wonderful SyntaxHighlighter plugin, hence the weird “view sourceprint?” link at the top of each one.

Summary

Pretty cool concept, huh? No idea if my posts are worth doing this to, but I like the idea of it. And it’s easy too; once installed you can either say “put this everywhere on every post” or just use the [sendToKindle] smart code.

Backing up WordPress to DropBox using the WPB2D Plugin

Send to Kindle

If you host your site on an Amazon EC2 Microinstance, be careful with the “WordPress Backup to Dropbox” plugin:

w2db_fail

Ahem..

I had to log on to the AWS EC2 portal, reboot the instance, then ssh in to restart the various services that hadn’t automatically restarted.. ugh.

Creating a SublimeText plugin to publish markdown to WordPress

Send to Kindle

I’ve been using SublimeText for a while now as a no-frills text editor; it has a nice Zen mode which hides all of the tabs and menus and pushes it to full screen which I’ve found perfect for taking notes during seminars:

SublimeText2 Zen mode

I have been trying to take notes using the markdown sytnax, but have found the process between taking the notes in markdown, converting them to HTML, and publishing the HTML to a blog a bit of a pain.

Given that SublimeText supports extension via plugin scripts written in Python, I’ve knocked together an extension which will

  1. convert the markdown to html
  2. push the html directly to wordpress

Before I get into the details of the script, maybe a little background would be useful:

What’s Markdown?

A lightweight markup language for writing human-readable content which can be compiled into HTML. Being able to write a lovely HTML blog post in a very basic text editor instead of the bloated Windows Live Writer is extremely refreshing.

For example, to make a line a <h1> header, prefix it with a #. For <h2>, use ##. For <h3> ###. Easy.

Want a link? Try surrounding it with square brackets and putting the url just after it in round brackets: [Something like this](which links here). It’s a really easy “language” and actually looks decent enough to just read on its own.

To include an image you just need to write ![alt text](image url)

A syntax reference page can be found here.

One problem I do have is the basic support for code highlighting within markdown is poor, obviously, since HTML only has a single <code> block. The Markdown generated HTML conflicts with my wordpress Syntaxhighlighter plugin, hence the ugly clode blocks in this post.

There is support for “fenced-code-blocks” wihtin many implementations of markdown, and with the library that I’m also using, but this is still not playing nicely with Syntaxhighlighter. I’m sure I’ll figure something out eventually – please bear with me until then.

I use the fantastic python-markdown2 library to convert markdown to HTML on the fly; I just had to copy the lib/markdown2.py file from the github repo into the sublimetext “plugins” directory – I created a Markdown subdirectory for it – and reference it from my script. i.e.,

post_content = str(markdown2.markdown(post_content,extras=["code-friendly"]))

What’s Python?

Python

A functional scripting language. I found it really quite tricky to work with and had to install PythonShell as a powershell-ish window for testing out python commands before putting them to work in the plugin script. What’s not great fun is that SublimeText2 installs a different version of Python to PythonShell to version 1 of SublimeText to any version you explicitly install yourself.

Some commands and syntax will work in one version of python and not others

One great example is setting up a proxy; the syntax for this is completely different between versions of python and whatever example code you’re reading might be using the syntax that your version of python doesn’t support.

Working with a functional language took a lot of getting used to; I’d want to return an object from a method but had to instead return a comma delimited list of base types. It’s all a little odd to me, and my messy code shows that!

What’s WordPress?

Wordpress

A popular free blog engine that’s used as a CMS for some small businesses. It has an XML RPC API which conforms to the MetaWeblog spec, and you can really dig into this by looking through the php files that make up a WordPress installation.

Since I’m using Amazon EC2 as my wordpress host I can use Kitty to SSH in and browse to /var/www/html/xmlrpc.php to see the metaweblog service api itself. That file references wp-includes/class-wp-xmlrpc-server.php which contains all of the underlying functionality for the api implementation. This is great reference material to make sure you’re passing the correct values of the correct types to the correct endpoints.

Details

The sublimemarkpress plugin is intended to:

  1. check the contents of a config file for your blog access details
  2. scan the contents of the active window to get the posts details, such as post ID (to make it an Update instead of a Create), tags, and status
  3. convert the text from Markdown to HTML
  4. Push the HTML to the metaweblog endpoint with the correct blog/post details

1. Getting the Blog setup details from a config file

The plugin relies on a settings file called “sublimemarkpress.sublime-settings” using the structure:

{
    "xmlrpcurl": <URL to xml rpc endpoint>,
    "username": <username>,
    "password": <password>
}

to read it:

s = sublime.load_settings("sublimemarkpress.sublime-settings")
mbURL = s.get("xmlrpcurl")
mbUsername = s.get("username")
mbPassword = s.get("password")

2. Get the text and strip out the blog post data

The plugin expects the top of your text file/active window to have optional tags to define blog post details:

<!-- 
#post_id:<id of existing post - optional>
#tags:<comma delimited list of post tags - optional>
#status:<draft or publish - optional>
-->

To get the entire contents of the active window:

all_lines_in_page = self.view.lines(sublime.Region(0, self.view.size()))

Then to extract the header details:

post_id, tags, status, has_header_content = self.GetHeaderContent(all_lines_in_page, header_lines)

where GetHeaderContent is the hack-y:

def GetHeaderContent(self, all_lines_in_page, header_lines):
    page_info = {"has_header_content":False,"post_id":None, "tags":"", "status":""}

    if self.view.substr(all_lines_in_page[0]).startswith("<!--"):
        page_info["has_header_content"] = True
        self.MoveCurrentLineToHeader(header_lines, all_lines_in_page)

        # post_id
        if self.view.substr(all_lines_in_page[0]).startswith("#post_id"):
            page_info["post_id"] = self.view.substr(all_lines_in_page[0]).split(":")[1]
            self.MoveCurrentLineToHeader(header_lines, all_lines_in_page)

        #post tags
        if self.view.substr(all_lines_in_page[0]).startswith("#tags"):
            page_info["tags"] = self.view.substr(all_lines_in_page[0]).split(":")[1]
            self.MoveCurrentLineToHeader(header_lines, all_lines_in_page)

        #post status
        if self.view.substr(all_lines_in_page[0]).startswith("#status"):
            page_info["status"] = self.view.substr(all_lines_in_page[0]).split(":")[1]
            self.MoveCurrentLineToHeader(header_lines, all_lines_in_page)

        self.MoveCurrentLineToHeader(header_lines, all_lines_in_page) # removes the closing comment tag
    return page_info["post_id"],page_info["tags"],page_info["status"],page_info["has_header_content"]

def MoveCurrentLineToHeader(self, header_lines, all_lines_in_page):
        header_lines.insert(len(header_lines),all_lines_in_page[0])
        all_lines_in_page.remove(all_lines_in_page[0])

3. Convert the rest from Markdown to HTML

As mentioned earlier, thanks to the great python-markdown2 library, this is simply a case of calling the “markdown” method, passing in the content to process:

post_content = str(markdown2.markdown(post_content,extras=["code-friendly"]))

I actually do a test to see if the markdown library can be imported first, then if it fails I don’t even try to convert from markdown to HTML:

can_markdown = False
try: 
    import markdown2 # markdown
    can_markdown = True
except ImportError:
    can_markdown = False

4. Post to metaweblog api

Build up the request using the blog details, post details, and HTML content:

content = self.BuildPostContent(self.view, {"content": post_content, "title": title, "tags": tags, "status": status})

def BuildPostContent(self, view, page_data):        
    return {"description": page_data["content"], "post_content": page_data["content"], "title": page_data["title"], "mt_keywords": page_data["tags"], "post_status": page_data["status"]}

Then submit it to the api:

proxy = xmlrpclib.ServerProxy(mbURL)

if post_id == None:
    post_id = proxy.metaWeblog.newPost(blog_id, mbUsername, mbPassword, content)
else:
    proxy.metaWeblog.editPost(post_id, mbUsername, mbPassword, content)

Extra bits and making it all work

To execute a command from a plugin within SublimeText, firstly you need to import the sublimetext library at the top:

import sublime, sublime_plugin # sublime

then name your class “something<command>” and have it take the “sublime_plugin.TextCommand” parameter:

class PublishCommand(sublime_plugin.TextCommand):

Then to run it you need to hit ctrl+’ to bring up the command window and type:

view.run_command("<name of the class minus the 'Command' suffix>")

e.g. for my plugin:

view.run_command("publish")

You can try this out with loads of the plugins included with a SublimeText install

That’s about it

All of this is in a small github repo. I’d appreciate it if you want to fork the repo and help show me how python should actually be structured. And written.

Known Issues

Categories

These need to be requested, looped through and matched against those associated with a post, added if those specified don’t exist, and the IDs associated with the post. Couldn’t be arsed.

As such, when you post to your blog you’ll see the entry is “uncategorised” and you’ll have to manually edit this.

Images

Since I’m just fooling around with a text editor, uploading images is still a little out of scope.

Random reference material

  • pyblog – for helping to work out the guts of how python interacts with the metaweblog api
  • I used Fiddler & Windows Live Writer for investigating traffic and finding out what the actual parameter being used to specify “tags” is within the metaweblog api: mt_keywords

EC2 Micro Instance Instability

Send to Kindle

It’s getting a bit daft now – the EC2 microinstance this blog is hosted on seems to keep restarting. When it comes back up, Apache and mysql are stopped, so the site is down.

As such, I’ve just logged in via SSH and fired off the command below to edit the startup script:

sudo nano /etc/rc.d/rc.local

Then added in the lines:

sudo /etc/init.d/httpd start
sudo /etc/init.d/mysqld start

Now whenever the microinstance restarts it will automatically restart Apache and mysql. I hope.

Just for good measure I also added in a line for logging so I have some idea of how often the instance restarts:

date >> /home/ec2-user/restartlog

I’ll add in an email alert or maybe just make it tweet the restart event as well.

EC2 MicroInstance: The WordPress Hosting Wonder

Send to Kindle

I managed to not notice that my blog had gone down after the EC2 outage earlier this year. So when I popped back on one day to find it wasn’t there any more I was a little concerned.

Popped over to PuTTY, opened up my EC2 connection to be presented with a login screen. So I tried the old usual login: “root”

EC2 Login

Ok, let’s  try that then:

EC2 Welcome

BRILLIANT!!

Uh..

Now what?

Crap. I can’t remember.

I faffed around for ages with “ls”, checking out what’s in “/opt/” and “/etc/” and getting a bit lost. How do I restart the damned web server?! Which web server did I install? Why do I not remember how to use linux?! ARGH!!

Oh, hey. Look – I just tapped “PgUp” and saw this:

EC2 PgUp

Hello. That’s a command to see what ports are open, as far as I remember. That’s the first command from 2bitcoder‘s EC2 WordPress tutorial.

Pressing the down key resulted in listing every command I’d ever entered:

login as: ec2-user
Authenticating with public key "imported-openssh-key"
Last login: Thu Sep  8 20:27:22 2011 from blah--blah-blah-blah.blah.blah.com

       __|  __|_  )  Amazon Linux AMI
       _|  (     /     Beta
      ___|\___|___|

See /etc/image-release-notes for latest release notes. :-) 
[ec2-user@ip-12-345-67-890 ~]$ apt-get install lighttpd
[ec2-user@ip-12-345-67-890 ~]$ ipkg install lighttpd
[ec2-user@ip-12-345-67-890 ~]$ yum install lighttpd
[ec2-user@ip-12-345-67-890 ~]$ sudo yum -y install lighttpd
[ec2-user@ip-12-345-67-890 ~]$ ls
[ec2-user@ip-12-345-67-890 ~]$ ls /
[ec2-user@ip-12-345-67-890 ~]$ ls /opt/
[ec2-user@ip-12-345-67-890 ~]$ ls /etc/
[ec2-user@ip-12-345-67-890 ~]$ ls /etc/httpd/
[ec2-user@ip-12-345-67-890 ~]$ ls /etc/httpd/run/
[ec2-user@ip-12-345-67-890 ~]$ sudo ls /etc/httpd/run/
[ec2-user@ip-12-345-67-890 ~]$ service httpd start
[ec2-user@ip-12-345-67-890 ~]$ httpd start
[ec2-user@ip-12-345-67-890 ~]$ sudo /etc/init.d/httpd start

I just had to hit “enter” a couple of times to replay some ancient commands to restart Apache and mysql and the site was back up and running! Phew!

So – if you’re using EC2 for hosting something and you can’t remember the very basic linux commands you fired off to get it working in the first place, fear not! PgUp is your friend!

WordPress (free) on an Amazon EC2 Micro Instance (free – for now)

Send to Kindle

This first post is about how it came to be. A bit philosophical, I know, but that’s the nature of tech sometimes..

This is a version of wordpress (free blog engine) installed in Amazon’s EC2 (Elastic Cloud Computing – or Elastic Computing Cloud – or something like that, starting with Elastic and then another two “C” words) (free). Which I think is both thrifty, and tekky geeky, and therefore pretty awesome.

Inspired by Jaimal’s post over on 2bit-coder and an email from Amazon about a free tier, I set about having a go.

The only things needed to change from Jaimal’s tutorial, are that the current free versions of the AWS Linux VM are not quite Fedora; although you do install using yum, you need to log in as “ec2-user” instead of “root”, you always have to whack a “sudo” in front of any command that needs any real privileges, and you can’t use “phpmyadmin” to set up your mysql instance for wordpress, so you have to go old skool and do it by hand.

Anyhoo. Introductions over, next up – more on random web-related tech to follow.

Semi-related references:

How to run WordPress on the NSLU2 (“hacked” router I own that I based some of the wordpress install and setup on)

Mercurial how-to (since I’ve also installed that on my EC2 instance and will follow up on that at some point)

Go back to top