PHP, Programming

Export iMessages and SMS conversations as HTML

A couple of years ago, I explained how to get instant message conversations exported out of iChat as HTML files. Now it’s 2016, and Messages has replaced iChat, and iMessages have replaced all interpersonal communication. So how do you get HTML transcripts of your iMessages and text messages? Here’s how: with my new OSX Messages Exporter script.

The script exports all of your text/iMessage conversations from Messages (including group chats) and generates HTML files for each conversation. Here’s a screenshot of the HTML file generated for a iMessage conversation between me and my brother:

Screen Shot 2016-06-20 at 10.15.35 PM

And here’s what a group conversation looks like:

Screen Shot 2016-06-20 at 10.22.55 PM

(For a look at the actual HTML, see the example.html file in the repository.)

I’ll admit that there are a number of existing solutions for exporting conversations out of Messages, but mine has some distinct advantages over them:

  1. It supports group conversations.
  2. It generates human- and machine-readable HTML.
  3. It saves all attachments.
  4. It uses contacts’ names, not just their phone numbers.
  5. I wrote it.

If you want to give it a spin, download it from GitHub and run

./messages-exporter.php --help

from the command line for the current usage instructions.

PHP, Programming

Quick and Dirty Command Line PHP

I do 99% of my programming in PHP, and when I’m on the command line, I would rather use the PHP functions I know than look up the Bash functions I don’t, so I wrote this PHP script and saved it in my $PATH as an executable file named p.

#!/usr/bin/env php

		array_slice( $argv, 2 )

This way, if I want to quickly get the length of a string, I can type:

$ p strlen paraskavedekatriaphobia

and get


instead of looking up that I could have done:

$ foo=paraskavedekatriaphobia && echo ${#foo}

(or apparently a dozen other methods of finding the length of a string in Bash).

It even works with Bash variables:

$ foo=acbdef
$ p strlen $foo

Thanks to all the time this script has saved me, I was able to write this post!

HTML, JavaScript, Photography, PHP, Programming

Turn your iPhoto library into a Web photo album

iPhoto is good for managing and organizing photos and photo metadata, but it’s not easy to get that information back out if you want to share more than a few photos. I recently finished scanning 13,000 family photos and importing them into iPhoto, and I wanted to be able to share all of those photos (complete with the faces I spent hours tagging) with my brothers and sisters.

I could just burn copies of the iPhoto library to discs, but not all of my siblings have Macs, and iPhoto may not be around for very long. I needed a way to export all of the photos and metadata in a format that I felt comfortable would be supported for a long time: the Web.

The result was a PHP script that exports an iPhoto library into folders of image files (one folder per event), generates JSON arrays of event and photo metadata, and builds a minimalist JavaScript-powered website that provides a simple photo viewing experience. The website can be put online, or it can be run entirely offline (like from a DVD, which is my plan for sharing with my family members). The code is all open source ( and the usage instructions are in the README.

Here’s a screenshot of the main page of the website it generates:


And here’s an example of a single photo’s page:

I know it’s a pretty niche project, but hopefully it will come in handy for anyone looking to make their iPhoto library more shareable and accessible, especially as Apple drops support for iPhoto in the near future.

iPhoto Disc Export

PHP, Programming, RSS

Easy-peasy podcasting

Want an easy way to generate a podcast or RSS feed? At Eliot’s request, I wrote a PHP script that generates an RSS feed based on the contents of its parent directory, so whenever you add files to that directory (or its subdirectories), the feed is updated with links to those files. It also supports enclosures, so if you add an audio or video file to the directory, that file will be available to podcast clients. If you modify a file in the directory, the feed updates the link so that subscribers will see that it has changed. It’s a no-fuss way to syndicate content without having to tie it into a CMS like WordPress or TypePad.

Here’s how to use it:

  1. Save this file as EasyFeed.php (or dir.php or feed.php, it doesn’t really matter).
  2. Copy it to a directory on your webserver.
  3. Subscribe to the feed with any RSS or podcasting client.

That’s all there is to it. For example, here’s the feed of all of the files I’ve ever uploaded for use in my blog. If you subscribe to that feed with iTunes, you’ll see that I’ve uploaded two audio files: programming.mp3 and calacanis.mp3. iTunes will automatically download them, as well as any other audio/video files I upload. No fuss, no muss.

Django, PHP, Programming, Project X, Python

What’s old is new again

A few weeks ago, I started a little side project, and I decided to write it in Python with the Django framework based on all of the good things I’ve heard about it. I may never go back to PHP.

It’s like this: imagine you’ve been driving the same 1987 Dodge Dynasty for the last 8 years. It gets you around, and you know exactly how to handle it. Most importantly, you’ve learned just what to do when it breaks down to get it going again. Then, one day, someone offers to trade you their brand-new Mustang for your Dynasty, straight-up. (They’re a collector of late ’80’s sedans, you see.) You are unsure, since you’ll have to learn how to handle this new car, but you accept, and your entire perspective on driving changes – the tired chore of going to the post office becomes your favorite pass-time; you’ve volunteering to take friends to the airport even when they have no flights to catch; and you can finally drive on the interstate since you know you won’t break down.

This is what it’s like to switch to Python after a lifetime of writing PHP. Programming is part problem-solving and part code-writing. With PHP, the fun of solving the problems overcomes the chore of writing the code; with Python, writing the code is enjoyable enough that I find myself wanting more problems to solve just so I can code the solutions. It’s a great feeling.

Brian Alvey, PHP, Recommendations, Software


This morning, I needed to troubleshoot an error that was occurring in my Feed Statistics plugin when running on a Windows machine as well as under PHP 5. Since I normally do all of my development in *nix environments, I didn’t have such an environment readily available. Having installed Apache, MySQL, and PHP on Windows XP before, I knew that I could do it, but it would probably take the better part of an hour.

I did a quick search for WAMP (Windows Apache MySQL PHP) and found the WAMP project – a single-file download that ostensibly installs Apache, MySQL, and PHP 5 in a Windows environment. I had tried this kind of package before with little luck, but this one literally took 3 minutes to set up, and after 5 minutes of debugging, I had found and fixed the bug in the plugin. Total time spent was less than 10 minutes when I had expected that it would take more than an hour – definitely one of the best software experiences I’ve had in recent memory.

(As for this post’s title, I think all of the comic references at Brian’s blog are rubbing off on me.)

Feed Statistics, PHP, Plugins, Programming, WordPress

Feed Statistics Plugin Fixed

If you had downloaded the Feed Statistics plugin for WordPress and couldn’t use it because of an error during activation, version 1.0.3 is for you. The “Plugin could not be activated because it triggered a fatal error” message was being caused by my usage of PHP’s short open tags, which I should have known are not enabled everywhere. Thanks to Veg for the help that led to the fix.

Download the zip file of the newest version here, and overwrite feed-statistics.php in your blog’s wp-content/plugins/ directory if you downloaded an earlier version. If you’re downloading it for the first time, just copy it to that directory and activate it from the Plugin administration menu.