Showing posts with label tools. Show all posts
Showing posts with label tools. Show all posts

2012-12-01

foo

There is a tradition of using metasyntactic variables in computer science.

The time has finally come; my alma mater is shutting down my student account to reclaim space, so I pulled all my files off today. As I was watching the scp output scroll by, I realized, "I have a LOT of files names 'foo'."

Then I started to wonder; just how many files do I have? My inexact counting came up with 10 before I realized there must be a way to ask the system itself.

So, enter foo.sh:

find . -iname foo.\* |
  sed -n  's/^.\+\/\([^\/]\+\)$/\1/p' |
  awk '{count[$1]++} END { for (j in count) print j": "count[j]; }'

Which conveniently answers the question for me:

foo.sh: 1
Foo.java: 1
foo.c: 6
foo.txt: 2
foo.h: 1
foo.s: 1
Foo.class: 1
foo.c,v: 1
foo.cpp: 11

21! 21 source files named foo. Ah ah ah ah

:wq

2012-02-26

Of Keyboard Maps and あおえう

I picked up a new keyboard today. After searching around for a while, I determined that there are no US layout keyboards in my price range in Japan. So, I picked up a manly pink keyboard, instead.

A pink keyboard. Manly pink.
The layout, not surprisingly, is a JP-106 key. Unfortunately, I didn't have a handy layout for Dvorak on a JP-106 (not to be confused with Japanese Dvorak), so I did a little searching and found exactly what I wanted on the intartubes: Dvorak JP-106 Layout. This is especially awesome because there are layouts for both X and the Linux console.

There's only one change that I would make, and that's to make the key to the right of "A" another Control, like God intended.

:wq

2011-10-01

The Hipster PDA

I've been rocking a variant of the hipster PDA for about a week now. I've been using a small spiral quad-ruled, microperf notebook and a mechanical pencil instead of their suggestion of index cards, binder clips, and a pen.

Since moving to Japan, this has been pretty much invaluable. I can copy down any information I want (in English or Japanese), including making more useful directions out of the routes that google maps gives me (example). Blocks are numbered instead of streets being named here, so Google's algorithm that works so well in Western countries utterly fails to give useful Japanese directions. Since I can't print out the map anyway, I'm left to analyze it and write directions into the notebook that make sense, like "Take the right between blocks 23 and 24." That's usually more useful on the ground anyway. If I overshoot and find myself along block 24, I know that I've gone too far.

Using the hipster PDA also means that I can do random reads and writes without draining the battery. If I were out in the middle of nowhere and didn't know where my next electricity was coming from, this would be an even better thing. But, my dictionary already takes batteries; having one fewer device to charge when I get home is nice. Sometimes, the simplest answer really is the best.

:wq

2011-09-23

essidtop

In the spirit of all the *top tools, I wrote a little one for WiFi today. It's based on one I did earlier for measuring throughput using ipfw pipe counters, to see how much bandwidth things like streaming video and minecraft really take (answers: surprisingly little, and unsurprisingly a lot).

What I really need to do is abstract this out into a more generalized topify type of class, so that I can just write the data retrieval and data formatting functions, and then get a top-like auto-updating display out of it. This may only work on xterm, because it uses a specific control code to do the screen clear. This is much easier than installing and configuring the terminal control gems for ruby.

Usage: ./essidtop.rb wlan0. This will require root privileges, and you should probably change the #! line if your ruby is installed into someplace other than /usr/bin. Probably requires ruby 1.9 (because of the case statement).

#!/usr/bin/ruby

def get_stats(card)
	vals = {}

	cell = nil
	current = {
		:mac     => '??:??:??:??:??:??',
		:essid   => 'Unknown',
		:channel => '-1',
		:snratio => 0,
		:key     => '???'
	}

	%x[/usr/sbin/iwlist #{card} scan].each_line do |ln|
		ln.chomp!
		ln.gsub!(/^\s+/, '')
		ln.gsub!(/\s+$/, '')

		case ln
			when /^Cell ([[:digit:]]+) - Address: ([A-Fa-f[:digit:]:]+)$/ then
				unless (cell.nil?) then
					vals[cell] = current
					current = {
						:mac     => '??:??:??:??:??:??',
						:essid   => 'Unknown',
						:channel => '-1',
						:snratio => 0,
						:key     => '???'
					}
				end

				cell = $1
				current[:mac] = $2

			when /^ESSID:"(.*)"$/ then
				current[:essid] = $1

			when /^Channel:([[:digit:]]+)$/ then
				current[:channel] = $1

			when /^Quality=([[:digit:]]+)\/([[:digit:]]+)\s/ then
				current[:snratio] = (100 * ($1.to_f / $2.to_f)).to_i

			when /^Encryption key:(on|off)/ then
				current[:key] = $1

			else
				#puts "Unmatched: '#{ln}'"
		end
	end

	unless (cell.nil?) then
		vals[cell] = current
	end

	vals
end

card = ARGV[0]

loop do
	stats = get_stats card

	if ($stdout.isatty) then
		printf "\e[H\e[2J"
	end

	# foreach key in stats
	printf "Cell %-17s Ch SN Enc ESSID\n" % 'Mac'
	stats.each do |k,v|
		# print out line
		printf "%-4s %-17s %02d %02d %3s %s\n" % [k, v[:mac], v[:channel].to_i,v[:snratio], v[:key], v[:essid]]
	end

	sleep 10
end
:wq

2011-08-30

Documentation for Fun and Profit with AsciiDoc!

(editor's note: neither fun nor profit guaranteed)

For the last week, I've been writing documentation of various things in preparation for leaving my current job. We have one app in particular that had fairly sparse end-user documentation, and it's safe to say that I'm the only perlaphile in the office, so I started using vim to write a README file for it.

One thing let to another, and vim started syntax highlighting the file on me, so I pulled up a quick :se syntax to see what the heck was going on.

Lo and behold, I found out that vim uses AsciiDoc for its README (and .txt) syntax highlighting. This little gem makes writing documentation in plaintext pretty easy, and before I knew it, I was knee deep in constructing a man page for the scripts that I was documenting.

The basics of AsciiDoc's man syntax are simple and straightforward:

= A_PROGRAM(1) =

NAME
----
a_program - This program does something cool.

SYNOPSIS
--------
a_program [--frob]

USAGE
-----
--frob::
  twiddles the frobs (disable frob-twiddling with --no-frob)

BUGS
----
Does not actually twiddle frobs.

SEE ALSO
--------
a_program.conf(5)

...and so on. The top line is the document title, and has to include a section number to be valid for man. Then, every section (NAME and SYNOPSIS are required, and must be first) is underlined. The :: syntax is for a definition list, which works great for documenting argument lists. It's so easy and neat to be able to write man pages in something easier than perldoc that I actually was accused of enjoying writing documentation.

The real gem today came in the form of a Makefile, though:

all: a_program.1 a_program.html
%.1: %.txt
	asciidoc -b manpage -d docbook -o - %< | docbook2man -
%.html: %.txt
	asciidoc -b manpage -d html -o %@ %<

Now, with just make, I can generate both the man pages, and HTML documentation for people who are into that sort of thing.

:wq

2011-05-17

Now where did I put that file...

Hacking on the backup scripts at work, we realized that all the scripts had hard-coded paths to the installation directory. I could have just made the changes on a new branch (actually, I did), but anything that can be done can be overdone.

Original scripts:

#!/bin/sh

. /path/to/here/config

In PHP, I would have just used something along the lines of dirname(__FILE__). Bash kind-of has an analog of __FILE__ with $0, which works great, except that this script is meant to be run from cron:

ln -s /usr/local/bin/backup /etc/cron.daily/

In this instance, $0 is /etc/cron.daily/backup, which obviously isn't going to work correctly.

Turns out, there's a utility readlink for exactly this purpose. If the argument is a symbolic link, it prints just the target to stdout. Otherwise, it exits with error code 1. So, getting dirname(__FILE__) in bash makes the script start out:

#!/bin/sh

. "$(dirname $(readlink $0 || echo $0))/config"

Either $0 is a symlink, and we grab the path to where it points, or it's a real file, and we just echo it. Either way, what gets passed to dirname is a real file, and so we get the correct path whether the script runs from cron, or logged into the shell.

:wq

2010-07-04

Restoring a System Image from Windows Backup

Previously, I mentioned that I had lost a hard drive, and the importance of backing up files.

If you're running a Windows 7 system, go do yourself a favor and turn on Windows Backup to an external CIFS server. I'll wait.

Everybody backing up regularly now? Good.

Yesterday, I finally threw a new hard drive in my dead system and flipped the switch again. As expected, the system complained that the hard drive was unbootable, and I started rooting around for my Windows 7 disc.

Rather than installing, there's a Repair your computer link. Tell it you want to restore a system image, let it connect to the network, select your system image, and go grab a book. This took me about 40min over a 100Mbit link, so it was comparable timewise to a full install.

That's it. The system will reboot automagically, at which point you probably want to pull out the disc.

That's it; log in and run Windows Update a few times and you're back in business.

:wq

2010-06-20

Blogger Editing via ${EDITOR} - GoogleCL

Google CL allows the use of google tools over command line. This allows amazing things like editing google docs in vim (or emacs, if you're into that sort of thing). There's also blogger and picasa functionality, and you can dump your entire google calendar to stdout (in csv format, so start brushing up on your awk).

One of the things that's blatantly missing, however, is blogger integration with your favorite editor. Hopefully, this post will fix that, as it's doubling as my test of google-cl blogger integration and my blogger script.

#!/bin/sh

GOOGLE=/usr/bin/google
BLOGFILE=`mktemp`

ed=${VISUAL-${EDITOR-/usr/bin/vim}}

timestamp=`date -r "${BLOGFILE}" +%s`

${ed} "${BLOGFILE}"

newtime=`date -r "${BLOGFILE}" +%s`

if [ $? -eq 0 -a "${newtime}" -gt "${timestamp}" ]; then
 title=`head -1 "${BLOGFILE}"`
 /bin/sed -i '1d' "${BLOGFILE}"
 echo 'Posting to blog "fmt >/dev/internets"'
 ${GOOGLE} blogger post --title "${title}" "${@}" "${BLOGFILE}"
fi

rm "${BLOGFILE}"

File inclusion courtesy of :r. Now that makes me happy.

:wq

2010-06-09

Git Trick: Multiple remotes

git is a wonderful little vcs. It took a while for me to warm up to it, but now I could never go back to svn or cvs. RCS still holds a special place in my heart, and is so damn useful I can't give it up completely. But these days, my vcs world is all git-based.

I'm sure there's a way to do this multiple-remote trick in bzr and hg, but I don't use them, so haven't bothered to figure it out. If I need hg, there's always hg-git, which may earn its own entry soon.

git makes it easy to track multiple remote branches, which is ostensibly used for sharing work between colleagues. i.e. I can 'merge steve/master' to bring all Steve's unpublished changes to master into my current local branch. This is great for hacking in small groups or pairs without needing a central server. However, the true power of this, I think, is that any git url can be a remote.

So, for example, I'm building a site based on dabl, and I want to keep it up to date with the latest changes. Now, up until last week, that meant I would check out dabl, check out my code, and then copy the files in and commit. Something like this:

git clone dabl
git clone my-project
cp -R dabl/{libraries,helpers} my-project/
cd my-project
git commit -a -v -m 'Updated dabl'
git push origin master

Now, of course that `git commit -a` wipes out any local changes. That means that, for example, anything in helpers/ that gets modified in both my-project and dabl will be replaced by the dabl version. Usually, that's fine because I've pushed the changes from my-project upstream. Where there would logically be a conflict, it is happily ignored in favor of the upstream version. Of course, upstream is the same procedure but in the reverse direction, and has the same pitfalls.

The solution is to recognize that these are both git repositories in their own right. Just add the dabl repository to my-project. Updating is as easy as:

git fetch dabl
git merge dabl/master

Now, I have the latest version of my upstream code, with all the benefits of merging it in. This is what I really wanted in the first place. I love cp, but it's never going to give me an octopus merge.

But, that's only one half of the problem. Is there any way pushing upstream could be aided by this?

Okay, it would be pretty anti-climactic if the answer to that were no. As it turns out, pushing upstream is the reverse of pulling from upstream (like with the cp "solution"); you just have to be a little more careful. Lets say I need to push HEAD on master upstream:

git checkout dabl/master
git cherry-pick master
git push dabl HEAD:master

Yes, it really is that easy. "master" is a valid commit-ish, so you can cherry-pick it. You can even do exciting things like master^ and master~3. And of course, you can name a commit by its hash or tag if you want to be really safe. In practice, it generally helps to be really safe.

A word of caution: DO NOT make your other remote call its refs "origin." This will give you and everyone you work with headaches as you will switch repositories instead of merging. And I mean "switch" in the svn sense of the word (i.e. "rebase"). Name it something sane and unique, like the name of the project.

:wq

2010-04-03

Managing your Checking Account with PocketMoney

Balancing your checkbook is one of those chores, like taxes, that everyone hates but does anyway. Of course, unlike taxes, you slack off for a month and the feds don't come busting down your door. So you slack off for another month...

If you're like me, you have several abortive attempts to use the check register that came with your checkbook to manage your money. My current check register even includes a handy three-year calendar for 2003, 2004, and 2005. The only real use I have for this ancient piece of banking technology is to track when I've overdrawn my account. After each time that happens, there's another 1/4 to 1/2 page of studiously usage until I start forgetting again.

Part of the problem with using a check register is that hardly anyone even takes checks anymore. I write around 30 or 40 checks a year; all of them are for paying bills, so I don't even bring my checkbook with me when I go out. I also don't generally carry cash, so that means a lot of miscellaneous debit and credit card transactions. And, lets be honest, who actually wants to carry a checkbook just to record all of those so they can balance their checkbook at the end of the month?

Of course, one thing I do always have with me is my iPhone. And, as they say, there's an app for that (several of them, actually). PocketMoney is the one that I finally settled on. There's a free trial, so really there's no excuse not to at least take it for a test drive. Training myself to use this was definitely easier than training to use a check register, and the built-in budgeting tools are impressive. When I've got the app handy, "I'll record this $1.40 at Starbucks when I get home" is really hard to justify.

One of PocketMoney's most useful features is the different budgeting schedules. If you get paid bi-weekly, enter that as the repeat period. The program will automatically pro-rate your budget based on how many weeks (or partial weeks) are in the given month. Enter Rent monthly, Groceries weekly, Salary bi-weekly, and Auto Insurance quarterly, and the app will take care of all the calculations to give you correct budget breakdowns by any time range you choose.

For me, though, the real power of this app comes when combined with online banking and online bill-pay. The recurring transactions feature lets you schedule automatically repeating transactions, so you never forget about an automatic withdrawal again. Online banking means that I can balance my "checkbook" against my bank account daily, weekly, or just whenever I remember and have an extra 10 minutes to spend on it. For me, this is a whole lot more convenient than remembering at the beginning of the month when I get my bank statement in the mail. Plus, since I have everything synchronized, I know how much money I don't have and can keep from overdrawing yet again.

:wq

2009-12-06

fsdb_ufs - The UFS File System Debugger

Previously, I mentioned that I had run across fsdb and planned to spend some time playing around with it. I had some time last week, so here's a few simple notes on it.

There are 2 automagic variables in fsdb: ";" and ".". ";" represents the current i-node, and "." is the current location on disk. Between the two of them, you can do things like "go to i-node X and read the first 16 bytes." Then, since "." has been updated, you can readily read the next 16 bytes from the file, and so on until you hit the end of the file or disk.

All commands (except "shell escape") must begin with an i-node specification. ":" is the current i-node, but you can specify another i-node with "#:inode". The third part of the command tells fsdb how to update the value of ":". "inode mode" updates the value to the given inode, as long as it's already allocated. "dir mode" updates : to the given directory entry, ordered by inode (this is not the same order as the directory listing is in). This makes it much easier to modify directory entries than trying to fill over the correct bytes in the directory.

"?" is the "formatted output" command. It is similar in feel to gdb's "print" command, but there are file-system specific formats, such as "inode" and "dir." ("/" is unformatted output).

Some examples:

/dev/lofi/1 > 2:inode?ino
i#: 2              md: d---rwxr-xr-x  uid: 29b7          gid: 12c     
ln: 6              bs: 2              sz : c_flags : 0           200                 

db#0: 170          
        accessed: Mon Nov 30 16:31:46 2009
        modified: Mon Nov 30 16:26:25 2009
        created : Mon Nov 30 16:26:25 2009

inode 2 is special in UFS; it is always the root of the filesystem (inode 3 seems to always be lost+found, as well). The output format looks curiously like the output from stat, except that it doesn't actually stat() the file.

/dev/lofi/1 > 2:
/dev/lofi/1 > :ls -l
/:
i#: 2           ./
i#: 2           ../
i#: 4           bin/
i#: d           etc/
i#: 3           lost+found/
i#: 5           sbin/

:ls is a shorthand for listing the current directory or inode. There is also :cd which is easier than listing the current directory, finding the entry you want, and then updating the value of : to it.

Note that all the inodes are in hex. There is a :base command to change both the input and output bases (:base=0xa is decimal; :base=0x8 is octal, etc).

Updating a directory entry is done with N:dir=M. This sets directory slot N (starting from 0) to inode M. For example:

/dev/lofi/1 > :cd bin
/dev/lofi/1 > :ls -l
/bin:
i#: 4           ./
i#: 2           ../
i#: 9           alink?
i#: a           blink?
i#: b           clink@
i#: 6           cp*
i#: 8           ls*
i#: 7           mv*
/dev/lofi/1 > 6:dir:nm,10/c
   58454:       b   l   i   n   k   \0  \0  \0  \0  \0  \0  \?  \?  \?  \0  \?
/dev/lofi/1 > 6:dir=0x09
i#: 9           blink
/dev/lofi/1 > :ls -l
/bin:
i#: 4           ./
i#: 2           ../
i#: 9           alink?
i#: 9           blink?
i#: b           clink@
i#: 6           cp*
i#: 8           ls*
i#: 7           mv*

So, what have we done here? Since blink and alink now share the same inode number, they are hard links of the same symlink. Running 9:inode?ino reveals that fsdb updated the link count for the inode automatically, so we don't have to worry about file system corruption if we unlink one of these later.

N:dir:nm,10/c outputs the first 16 characters of the name of directory slot N (directory slot N's name to ". plus 0x10", unformatted output, characters). The man page seems to point to outputting the name of a file being possible by N:dir:nm,*/c, but that reads to the end of the block, not to the first terminating null.

Renaming a file is done by writing to the "nm" value. This won't allocate any extra space for the filename, so the filename is truncated if it is longer than the already allocated space. Here is the hard way to re-name those nasty files named "\008\008\008\008...".

/dev/lofi/1 > :ls -l
/bin:
i#: 4           ./
i#: 2           ../
i#: 9           alink?
i#: 9           blink?
i#: b           clink@
i#: 6           cp*
i#: 8           ls*
i#: 7           mv*
/dev/lofi/1 > 7:dir:nm,10/c
   58464:       c   l   i   n   k   \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
/dev/lofi/1 > 7:dir:nm="dlink"
i#: b           dlink
/dev/lofi/1 > :ls -l
/bin:
i#: 4           ./
i#: 2           ../
i#: 9           alink?
i#: 9           blink?
i#: 6           cp*
i#: b           dlink@
i#: 8           ls*
i#: 7           mv*

Now you can impress all your sysadmin friends by creating hard links and renaming files.

But what about something you can't do with normal shell tools?

/dev/lofi/1 > :cd
/dev/lofi/1 > :cd etc
/dev/lofi/1 > :ls -l
/etc:
i#: d           ./
i#: 2           ../
i#: e           etc@
/dev/lofi/1 > 2:dir:nm,10/c
  178c20:       e   t   c   \0  t   \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
/dev/lofi/1 > 2:dir=0xd
i#: d           etc
/dev/lofi/1 > :ls -l
/etc:
i#: d           ./
i#: 2           ../
i#: d           etc/

Exit fsdb and remount the file system to see changes (yes, this is required; I suspected caching, but this occurs even with files that haven't been looked at yet).

$ ls -lain etc
total 6
        13 drwxr-xr-x   2 10679    300          512 Nov 30 16:26 .
         2 drwxr-xr-x   6 10679    300          512 Nov 30 16:26 ..
        13 drwxr-xr-x   2 10679    300          512 Nov 30 16:26 etc

And there you have it, a hard-linked directory. ln has been lying to you this entire time.

:wq

2009-12-03

GraphViz for Fun and Profit

A long time ago, in a data center far, far away, we had a NIS server. It was a good little NIS server. It knew of usernames, and passwords, and automounter maps, and netgroups. Ah, the joys of NIS netgroups. There is one basic form of netgroup that we used:

([computer],[user],-)

Specifies a computer, user, or computer/user combination ("-" indicates "any user"). In addition, netgroups can contain other netgroups, so you get a nice graph of which netgroups are part of other netgroups.

Along with this wonderful little NIS server, there was an old Python script which would run through and generate a set of webpages to graphically display netgroup relations. If netgroup A contains netgroups B and C, and C contains D, we could check the generated graph to see:

    A
   / \
  B   C
      |
      D

Fast forward a decade or so to an insanely large NIS tree, with netgroups for things we've long since thrown away (e.g. line-printer-access). When we upgraded from NIS to LDAP as the backend directory service, we kept the netgroups around, though. Still in their NIS format. Of course, our wonderful little Python app broke because of the transition to LDAP, but nobody wanted to admit to knowing enough Python to fix it.

So in working on the replacement for our Python app, I got to learn a whole new set of tools. Graphviz is a suite of tools for displaying graphs and trees. A friend of mine showed me his Perl program to generate "dot" diagrams for Tic-tac-toe (turns out the only winning move really is not to play), and I realized that just redoing the generator in ruby or Perl would be much easier than trying to tackle Python's LDAP bindings (not to mention debugging Python).

The "dot" language spec, while exhaustive, isn't very helpful for learning the language. The User Manual, though slightly dated, serves as a much gentler introduction. The syntax allows for a lot of room for error, once you get the basics down: semi-colons are (nearly) optional; whitespace isn't counted for or against you; and nodes that aren't pre-declared are created without complaint.

The most basic directed graph is something like:

digraph G {
    foo -> bar;
    bar -> blort;
    foo -> quux;
}

Generating that from a list of netgroups in ruby is also quite simple:

puts "digraph G {"

netgroups.each do |netgroup|
    netgroup.children.each do |child|
        puts "\"#{netgroup.name}\" -> \"#{child.name}\";"
    end
end

puts "}"

Which can then be used to generate a nice image by:

./generator.rb | dot -Tpng -o image.png

This is exactly what we used to have (except in dia) for our Python/NIS version, except that that had a page for the subgraph at every node. So, clicking on C (using dot-generated HTML image maps) should pop up a page with:

    C
    |
    D

The original script had all the busy work to figure out which nodes to include on subgraphs done in native Python, and tons of generated dia files that got passed on to generate the images and image maps. Graphviz, however, includes "gvpr," an awk-like tool for graphs written in "dot."

BEGIN{} and END{} blocks function exactly the same as in awk.
BEG_G{} and END_G{} blocks are called at the beginning and end of each graph to be processed.
N{} blocks are called for each node, and
E{} blocks are called for each edge.

Just like awk, there is an optional test parameter (inside [], not //) to specify which "things" to operate on. For example:

N [ color == "blue" ] { color = "red" }
E [ color == "red" ] { color = "blue" }

turns all the blue nodes red and all the red edges blue. There is a whole API built in to work with graphs, nodes, and edges within gvpr, which includes a rich set of tools for "subgraphs."

Say we want to generate a graph from a couple nodes in the original graph we were given (known as "root" in gvpr).

graph_t g = subg( root, "SubGraph" ); /* create a new subgraph */
subnode( g, node( root, "C" ) );  /* add node "C" to the subgraph */
subnode( g, node( root, "D" ) );  /* add node "D" to the subgraph */

Now, this is just the nodes. To copy the edges, we could loop through all the edges from "C" (there are for and while in gvpr), or, we can "induce" the edge relations:

induce( g );

Which the man page states "extends g to its node-induced subgraph extension in its root graph." Roughly translated to English, this means "draw all the edges as they are in the original graph."

Add in some writeG() calls to output to files, and several Python files are now around 15 lines of gvpr, 40 lines of ruby, and a shell script to fire it all off.

:wq

2009-11-19

Test Blog Post with BlogWriter Lite

This is a test blog post from BlogWriter Lite.

Though I haven't yet used it, BlogPress' free version has a camera button built in; I assume this works in conjunction with the integrated Picaso client to allow posting of images stored on the iPhone or taking images with the webcam and posting them immediately.

BlogWriter doesn't have any image support in the free version, but supposedly the full version does offer HTML and image support.

Neither program allows for turning the phone sideways and using the landscape keyboard, which would be really nice.

:wq

2009-11-18

Blogging From the iPhone

I just downloaded a couple mobile blogging apps for iPhone that support the Blogger API. BlogWriter and BlogPress both have free trial versions, so I figured my first attempt to get things working would be with them. If I can't connect at all to blogspot, then it's no money out of my pocket for the experiment.

A word from the not-so-wise: look up your username and password when setting up something on the iPhone. I could have posted this 3 hours earlier if I hadn't been entering the wrong password to my gmail account. Thank you, Firefox, for letting me forget.

After the 3 hours of learning about XML-RPC, the nasty guts of the original Blogger API, and how to integrate with Drupal/Joomla, I finally have two working mobile blogging apps.

BlogWriter seems to be aimed at a larger community of bloggers. It supports Blogger, WordPress, and anything that can speak the Blogger API at a custom URI.

BlogPress, despite being a portmanteau of Blogger and WordPress, only supports Blogger. The configuration is simple (provided you know your password), but it does require both Blogger/BlogSpot and Picaso credentials. They're the same now, though, and thankfully the app pre-filled my Picaso login information.

BlogPress also appears to be able to work with drafts; I don't yet know I'd they're only local to the iPhone or if it's integrated into the main Blogger web interface.

This just in: BlogPress doesn't turn sideways. Really a bummer because the iPhone keyboard is much easier to use in landscape orientation. Spellcheck and autocorrect can only do so much.

That's really all I have to compare until I actually use BlogWriter. So far, though, it looks like blogging on the iPhone is definitely doable, even without Google's SMS and e-mail hacks.

:wq