Category: Productivity

How to use Tumblr as a web host for a blog you FULLY control, without paying anything

If you're not a computer nerd, buying web hosting can feel like buying a house. Or, worse, like buying a car. Or, even worse than that, a new computer.

It doesn't have to be painful. In fact, most people who want a simple blog or website don't even need to buy web hosting in the first place. And, this is the kicker, if you do end up buying web hosting, sooner or later you'll realize that you've invested your whole identity, or your business, or whatever's important to you, in a place that you don't actually have any control over, and can't easily leave. Backups will become important, but they're gonna be a massive headache. You may find yourself hitting resource quotas, or your credit card will be charged for hidden and contract "renewal" fees or some such bullshit like that, none of which you were told about when you signed up. And, worst of all, you could find yourself digitally gagged, censored, or even outright banned just because someone else on the same "shared server" you were assigned was behaving badly.

Fuck. That. Shit. And, more to the point, why on God's green Earth would you pay to be subjected to such bullshit?

With just a little bit of patience, enough computer know-how to understand how to click a few download links and move files from one folder to another, and a willingness to read this post, you can avoid every single one of those frustrating web host experiences, all while ending up with seamless, automatic backups of your entire blog, the ability to legally dodge shitty censorship and corporate contracts alike, and the ability to easily participate in the ever-expanding social media frenzy without spending hours managing all your different accounts manually. And did I mention it's free?

Read the full post, it's worth it.

Read more

On Being a Social Cyborg: How iCalendar Helps Me Fight Loneliness

Here’s a topic I’ve been meaning to write about ever since I was deeply depressed last Fall and Winter. Back then, I was incredibly lonely, and despite my best efforts I simply found it damn near impossible to do anything to improve my situation. That’s because my “best efforts” consistently lead me to dead-end resources that sounded good but that had no practical or immediately useful information; resources like WikiHow.com’s “How to Deal With Loneliness” article.

In their article, WikiHow contributors write:

Get involved in anything where you will meet people. If you are very shy, find a group for social anxiety, even if it has to be online (obviously it’s better if it’s not). Look on places like Craig’s List, or local news websites for your town for activities in your area. Volunteering can help. But don’t attend functions with the idea of making friends or meeting people. Being too demanding is a sign of loneliness. Try to go with no expectations whatsoever, and to enjoy yourself regardless of what happens. Look for activities that interest you, that also involve groups of people, like intramural sports, book clubs, church groups, political campaigns, concerts, art exhibitions, etc.

While it all “makes sense,” the WikiHow article reads like an elaborate horoscope. It’s incredibly annoying because it contains no meaningful, discrete, actionable items. Where, exactly, can I find “activities in my area”? And once I find them, how do I make sure I know about them when they are happening? And as if that wasn’t hard enough, how do I make the process workable under the extreme energy constraints that being depressed and lonely put me under? (See also: without using up too many “spoons”.)

Ironically, when I finally concocted a solution to this problem, I no longer had the time to write the blog post about solving the problem because I was so busy doing things and being social. I proceeded to pull myself out of my depression, have a pretty good (if still difficult at times) Spring and Summer, and even Fall in 2011. But now that the days are getting shorter and I’m increasingly feeling like my moods are walking on a tightrope of “happy” above a pit of bleakness, I figure it’s about time to document my process. That, and it seems people I know are running into the same problem, so hopefully sharing my own solution can really make a positive impact on others’ lives.

Creating a Cyborg’s Social Calendar

The basic problem was two-fold. First, I needed an easy way to discover local goings-on. Second, I needed a way to remember to actually attend events that I was interested in.

It turns out this is far more difficult to accomplish than one may at first believe since the set of events that I both want to attend and have the capability (energy, time, money, motivation, physical accessibility, etc.) to attend are actually relatively limited. Moreover, I also need to align the set of events that match both of those criteria with the knowledge that said event is occurring when it is occurring. It’s a bit like playing temporal Tetris.

In a nutshell, the solution I implemented was similarly two-fold. First, I cast an incredibly wide but low-cost sensor net, integrated directly into the process I already used for keeping track of my daily appointments. (See also the “no extra time” concept and its wide applicability). Second, I classified the “activities in my area” into two distinct groups: “engagements” (stuff I’ve said “yes” or “maybe” to) and “opportunities” (stuff I haven’t yet said “no” to).

Here’s what my calendar looks like after all the pieces of the system are in place:

As you can see, I have an enormous selection of activities I could participate in at any given time. Better yet, they all show up on my calendar without my ever needing to repeatedly go “look[ing] on places like Craig’s List” to find them, the events on my calendar update themselves, and I can show or hide sets of events on a whim.

The prerequisite tool for doing this is the iCalendar feed, which, in the words of Stanford University, is a popular calendar data exchange format which allows you to subscribe to a calendar and receive updates as calendar data changes. Each of those calendars under the “Subscriptions” heading in the screenshot of my iCal is actually an iCalendar feed from a remote website. iCalendar feeds are to calendars as RSS feeds are to blogs.

The first thing I did was add the event subscription feed from my Facebook. Do this:

  1. Log into your Facebook account and go to the “Events” page.
  2. Scroll to the very bottom of the page and click on the small “Export” link. This will reveal a personalized web address (URL) listing all upcoming Facebook events you’ve been invited to or have RSVP’ed either “Yes” or “Maybe” to, in iCalendar feed (.ics) format. Copy that URL.
  3. Back in iCal (or your calendaring application of choice), choose “Subscribe…” from the menu and paste in the URL you got from Facebook.
  4. Give this calendar subscription a meaningful name. I called it “Facebook Events” (see above screenshot).
  5. Set the “Refresh” interval to something that makes sense; I set it to once “every 15 minutes,” since the Facebook feed is one I check often because it changes so frequently. (For feeds from calendars that I check or that update less often, such as those of community groups, or calendars listing events that are far from home, I set the refresh rate much, much slower, such as once “every week.”)

Okay! Now, whenever a friend invites you to an event on Facebook, your calendar will be updated to reflect that event at the appropriate date and time. If you RSVP “No” to the event, it will disappear from your calendar when iCal next checks your Facebook iCalendar feed.

Repeat the same steps for any other event-management website that you use and that offers iCalendar feeds. Some services I use, such as Plancast.com and Meetup.com, actually offer two distinct iCalendar feeds, one for all of the events visible to you on the service, and one for events that you have RSVP’ed “Yes” to. Subscribe to both; in the screenshot of my iCal window, above, you’ll note the existence of a “‘meitar’ on Plancast” calendar as well as a “Plancast Subscriptions” calendar, and similarly a “My ‘Yes/Maybe’ Meetups” calendar as well as a “My Meetups” calendar.

Now that you’ve got a bunch of subscriptions, it behooves you to organize them in a way that makes sense to you. How you can do this will depend a little bit on the tools you have at your disposal. I found Apple iCal the best choice because of its Calendar Group feature, while I found Google Calendar an incredibly frustrating tool to use.

In iCal, I first created two calendar groups. The first one was called “Social Engagements,” into which I placed all the iCalendar feeds that showed me events to which I’ve RSVP’ed “Yes” to on the remote site. This included the Facebook, “‘meitar’ on Plancast”, and “My ‘Yes/Maybe’ Meetups” feed. The second group was called “Social Opportunities,” into which I placed all the other calendars.

Every time I learned about a new local venue, such as a nightclub, or a café, or a bookstore that had an open mic, I would scour its website to see if it offered an iCalendar feed. If it did, or if it used a tool that did, such as embedding a Google Calendar on their website,1 I’d add their feed to my “Social Opportunities” calendar group, too. I’d do the same every time I learned of a new event aggregating website, such as the IndyBay.org calendar or the Calagator Portland Tech Community calendar, which both offer feeds.

In very short order, I became one of the go-to people to ask about what was happening ’round town—including some towns I didn’t even live in!

However, as I travelled across the country speaking at conferences, I realized that my “Social Opportunities” group was getting cluttered with events that I could not actually attend because I was literally thousands of miles away from them. To solve that problem, I created distinct “Social Opportunities” calendar groups based on geographic region, and moved the individual subscriptions to the group with which they were geographically associated; the Occupy DC calendar feed is in the “Social Opportunities – DC” calendar group, and so on. I also created an “A-geographic” group to house feeds that listed events from all over the place.2

Some event-management services let you filter by geography, making this even easier. For instance, Yahoo!’s “Upcoming” event listing website shows you events by “place,” and you can subscribe to an iCalendar feed of just those events. For instance, here are the Upcoming events in Seattle, and here is the same information in iCalendar feed format. I added the feed of each Upcoming Place to which I regularly travel to its appropriate regional calendar group.

The benefits of this set up are obvious:

  • Visually overlay social opportunities on top of social engagements to ensure few conflicts, and help make the most informed choice about which events I want to go to when there are conflicts, to mitigate my social opportunity cost.
  • Toggle calendars on/off to find nearby activities. Ordinarily, I simply leave all the “opportunities” calendars deselected, so I’m just looking at my personal calendars and the “Engagements” group, since this view shows me “stuff I have to do today.” When I’m bored or I’m looking for new things to do in the upcoming week, however, I simply turn on the “opportunities” calendars. Voila! In 1 click, I’m browsing a wealth of stuff to do!3
  • Quickly orient oneself within the social space of a new city. If I’m taking a trip to Washington DC for a few days, all I have to do is deselect/uncheck the “Social Opportunities – SF/Bay Area” calendar group to hide all of my calendar subscriptions in that group, then select/check the “Social Opportunities – DC” calendar group and, voila, my calendar view has instantly shifted to showing me events that I can attend in Washington, DC.
  • Make RSVP’s meaningful: if I RSVP “Yes” to an event on Meetup, the event is automatically removed from my “Social Opportunities – A-geographic” calendar group and added to my “Social Engagements” calendar group.
  • Easily move event information from a calendar feed to a personal calendar using copy-and-paste without ever leaving the calendaring tool of your choice.

Of course, none of this matters with regards to feeling lonely if I don’t also show up at events in physical space. Admittedly, actually mustering the physical and social energy to get up and go is by far the hardest part of this whole process. Typing on a keyboard is all fine and well (rest assured I do more than enough of it!), but there is no substitute for actually being around other human beings face-to-face. Physically vibrating the air using one’s mouth and having those vibrations move another’s ear drum (or physically moving one’s hands and letting the photons bounce off those movements and onto the retina of another’s eyes, in the case of sign language) is a vital part of the experience of being social.

This system isn’t perfect, but the imperfections are mostly due to the way sites like Facebook handle RSVP information. For my purposes, though, this workflow gets me well over 80% of the way towards my goal, and since I’m actually a human (not a machine), I can deal with a little data pollution here and there. There’s also plenty more I could write about with regards to “being a social cyborg,” such as how I use my calendar in conjunction with my contact management application (my digital rolodex) to maintain “loose” or “weak” interpersonal ties with over 1,000 people spread across the world—again, using “no extra time.” But I’ll save that for another post.

For now, hopefully this gave you a better understanding why my most frequent response to being informed of a party is something along the lines of, “Can you send me a link (to Facebook/Meetup/Google Calendar)?” and also why I’m so, so, so critical of important websites like FetLife that seem to prioritize everything but user security and interoperability.

  1. Every public Google Calendar also publishes its information in an iCalendar feed. For example, rather than view the Occupy SF calendar on their website, just subscribe to the iCalendar feed provided by Google. Also, while you can create an aggregate view of multiple Google Calendars to embed on a Web page, it seems to me like this isn’t a feature offered for iCalendar feeds, so if you come across such a calendar, you’ll likely need to add the individual calendars’ feeds one by one. []
  2. Currently that’s just Meetup and Plancast, for me, since I’ve joined Meetup groups all over the country and I’ve subscribed to people on Plancast who live in dozens of cities. []
  3. Frustratingly, although Facebook also offers you a page listing events that you were not invited to but that your friends were, there seems to be no iCalendar feed of that list, forcing me to periodically check that page for events that would be “Social Opportunities” if I knew of them. Thankfully, to add them to my own calendar, I just RSVP “Yes” or (more likely) “Maybe.” []

HowTo: Use Rules to Automatically Manage Email in Apple Mail

After recently moving to San Francisco, I joined the San Francisco Freecyclers’ Network. Freecycle is a really cool set of local groups who prefer to give away items to people who want them instead of throwing them away into the trash. The group uses email to connect people who offer items and those who want them. In order to stay sane, a simple, conventional format for writing an email’s subject line lets you quickly figure out what’s on offer and where.

Thanks to this simple text convention in subject lines, I could trivially automate the process of sorting through the approximately 100 emails a day that the email list generates in order to single out only the emails that interest me. Here’s how I did it.

Define Your Goals

Before setting out on any task, it behooves you to take a moment and think about what it is you’re trying to accomplish. For me, with the San Francisco Freecycling Network (SFFN) email list, I wanted to achieve the following goals:

  • Keep my inbox clear of email from the SFFN list unless a message was particularly interesting.
  • Browse the SFFN messages when I wanted to look at them without having to go to the web site.
  • Highlight particularly interesting messages in my inbox visually and play a special sound to alert me that such email has been found in case Mail was running in the background (since free stuff gets taken fast!).

I defined “particularly interesting” messages as ones that offered items of need for my recent move. With this in mind, I set out to create email rules that accomplished each goal in turn.

Step 1: Create a mailbox to store the appropriate messages

I began by creating a new mailbox to store all the SFFN messages I was getting. This alternate mailbox would be the mailbox I would shunt all SFFN email to so as to keep my inbox clear of it. I called the mailbox simply “SFFN”.

Do this:

  1. From the Mailbox menu, select New Mailbox…. The New Mailbox sheet appears.
  2. Select any location (“On My Mac” is fine, as is the account that receives the mailing list messages), and give it a name.
  3. Click OK.

Step 2: Create an email rule to move all appropriate messages to the new mailbox

With the new mailbox created, I now needed to get all the appropriate messages in there and out of my inbox.

Apple Mail’s email rules work by looking at each incoming message and matching it against a set of conditions that you provide. If the message being evaluated matches the conditions you specify, such as “from the San Francisco Freecycler’s Network mailing list”, then an associated action is automatically performed. Every email you get is evaluated against every rule you have unless a rule moves the message to another mailbox or until you trigger the “stop evaluating rules” action.

Since moving an email message to a new mailbox ends the process of evaluating rules and moving messages to the SFFN mailbox I just created is the goal of the rule I’m creating, I decided to name the rule “END – SFFN”.

Do this:

  1. From the Mail menu, select Preferences…. The Mail Preferences window opens.
  2. Click the Rules button. The Rules pane appears.
  3. Click the Add Rule button. The Add Rule sheet appears:
    1. Enter a meaningful description (I chose “END – SFFN”) in the Description: field.
    2. Provide the conditions you want to match. Since all SFFN emails must be addressed to the mailing list, I simply provided the email address of the mailing list (sffn@yahoogroups.com) as the condition for the To header.
    3. Provide the actions you want Mail to perform. I simply wanted to move the matched messages to the SFFN mailbox.
  4. Click OK.

For me, the above configuration looked like this:

end-sffn-mail-rule

Step 3: Create an email rule to highlight a message of particular interest

At this point, any and all email I receive from the San Francisco Freecyclers’ Network is being moved to the SFFN mailbox I created for it. This is nice because it keeps my inbox clear, but it’s still not very helpful since I still have to go trudging through the SFFN mailbox in order to find anything that might be interesting to me. The whole point of this exercise is to reduce the amount of time I spend actively looking for interesting things and let my computer do that work for me. So the next step is to tell Mail what I’m looking for so it can show the interesting messages to me.

Now, as it happens I’m in need of a wireless router. Since “router” is an appropriately unique word, I’m going to tell Mail to look for that word in a subject line. However, since I only want Mail to tell me when a router is available and not when other people like me are looking for routers, I’ll also tell Mail to look for the keyword “OFFER” in the subject line. (And this is why the Freecycle guidelines tell users to format their subject lines in a conventional way.)

Finally, since I don’t want to have to go digging for the interesting email message and since my inbox is already going to be kept clear by the previous rule, I’ll simply have Mail highlight the message in a bright green color and leave the message in my inbox without moving it to the SFFN mailbox I created earlier.

Do this:

  1. From the Rules pane in Mail’s preferences, click Add Rule.
  2. Enter a meaningful description in the Description: field. (Since I’m looking for a router, I called it “SFFN – Search for OFFERed ‘router'”.)
  3. Provide the conditions you wish to match. For me, this meant email sent to the Freecycler’s mailing list with the two words “OFFER” and “router” in the subject line.
  4. Specify the actions you wish Mail to perform. I wanted Mail simply to color the message green and to leave the email go to the inbox (where it was originally destined for), so I chose “Stop evaluating rules”. (I also decided I’d want Mail to play a special sound to alert me that it had found something interesting. This is optional, of course.)
  5. Click OK.

When I was done creating my rule, the above configuration looked like this:

Screenshot of Mail.app rule to highlight incoming Freecycling emails offering a router.

I can now repeat this step as many times as desired to tell Mail to highlight other messages that may be of particular interest for some other reason. For instance, say instead of looking for a wireless router, I wanted to look for a toaster. I would simply need to click on “Duplicate Rule” and replace all instances of “router” with “toaster”.

Step 4: Place email rules in appropriate order

Since Mail will repeatedly check incoming email against all the active rules, we need to be sure to place the rules in the correct order. You can think of each email rule as part of large Rube Goldberg machine, each message getting funneled through some piece of the logic at each successive rule. That’s why I began the name of the first rule I created with “END,” so that I’d know it should be placed after the rest of the SFFN-related email rules.

I decided that I wanted Mail to look for anything related to cameras and, of course, to toasters. This gave me a total of 4 rules (three to search for items of interest, and one to keep my inbox clear). Since the three highlighting rules all perform the same action, it doesn’t really matter which order they go in, but it is important that all of them appear before the rule to move messages to the SFFN mailbox.

To order rules, simply click-and-drag them into the order you wish Mail to evaluate them in. When I was done, my Rules pane looked like this:

Screenshot of the Mail.app Rules pane with sorted rules.

Conclusion

Mail rules are an extremely powerful feature that most email clients have, but that too few people use. They can save you enormous amounts of time and increase your productivity by automating simple yet time-consuming tasks.

The conventional, standardized subject lines that the Freecycle mailing list uses simplifies the logic required to have your computer automatically process your messages for you. This is a useful observation because it can be applied to other areas of your life where using simple conventions can help to organize otherwise overwhelming information tasks into manageable batches. Although this particular example uses stock, simple commands, you can get as fancy as you like by having an action trigger an AppleScript.

Now, hopefully, finding some additional housewares and a wireless router for my new San Francisco apartment will be as easy as checking (but not manually sorting!) my own email!

Are you missing the point of using a version control tool?

The other day I gave a brief (and overly-hyper) talk about git, the (very) dumb, (very) fast version control system. It was part of SyPy‘s Git vs. Hg vs. Bzr night. Rather than be flamingly competitive, however, I had a lot of fun that night learning about the differences between the DSCM tools, which was especially interesting since I’ve only ever used Git in real life scenarios.

Since I’m a Subversion refugee, my only experience with different version control systems is mostly with the distinctions between the centralized versus the distributed models, not between the various tools you can use in either paradigm. What struck me when I first began using git was how conceptually similar it felt to using Subversion when I was using it by myself (as a lone developer) but how radically different it suddenly felt the moment I was sharing my code with someone else.

Now, I’m a die-hard individualist. I want things to happen my way as much as possible, and I don’t really care what happens for anyone else as long as when I interact with other people those interactions are as mutually beneficial as they can possibly be. That’s why I love DSCM tools so much.

Distributed source code management systems feel much more like translator tools between the ways in which people work as opposed to feeling like a dogma of workflow management processes, like centralized systems do. This paradigm appeals both to my preferred way to work and, as it turns out, helps more people stay more productive all at the same time.

This is also why I’m a firm believer that most of the people I’ve worked with in the past completely missed the point of using version control systems. It seems to me that most developers I’ve worked with have thought of SCM tools as “the ‘Save As…’ button on steroids.” While these developers are technically correct, their narrow view of what a VCS does means they aren’t taking advantage of the full potential of the concept.

The power of a version control system isn’t just in that it gives you the ability to easily hit the proverbial “Save As…” button as much as you want, but rather in that you get to retrieve those other versions when you’re ready for them, regardless of what your fellow developers are doing to the code on their machines. This means that a version control system’s real purpose is to insulate you from changes of any sort until you’re ready to deal with them. A good tool also does this reciprocally; it will insulate your fellow developers from the changes you’re making until they’re ready for them.

Admittedly, that’s not a very concrete “feature.” It’s more like a fundamental philosophical principle, which is probably why it’s so hard to encode into the physical manifestation of a tool. Then on top of all of that complicatedness you have to add things like usability and interoperability and resource efficiency. That’s where I learned about the majority of the distinctions between the various DSCM tools discussed in SyPy’s presentation.

However, for me, all of those things ultimately get evaluated against the following question: Does Feature X help insulate me from change (does it help in persisting my view of the state of the world until I’m ready for it to change), or not?

For example, Bazaar’s interesting notion of “nested commits” with dotted revision numbers is really intriguing because it’s much (much) more user-friendly than git’s notion of exposing SHA-1 hashes to (mere mortal) end user’s eyes. Yet, while it’s certainly less painful than copying-and-pasting hashes all over the place, there’s little fundamental difference in the way these mechanisms actually portray the state of the world to me. Any given SHA-1 will always be the exact same commit object. Any given dotted revision number will also always be the same commit (within one’s own unchanged repository).

In contrast, I learned from Martin Pool that Bazaar has a “push over SFTP” feature to let you “export” or “archive” a version of code by transmitting it over an SFTP connection. Now that really caught my attention because it’s an example of the version control tool acting like that translator I was mentioning earlier; the interoperability helps people not need to change until they want to. In this case, it means you never have to install Bazaar on a remote server to get your content there via the tool. That’s very cool—much cooler than the mundane technical fact that bzr supports the SFTP protocol out of the box.

Of course, it’s technically pretty trivial to write an expect or shell script wrapper to enable git (or whatever other tool you want to use) mimic this behavior. And that’s exactly the point: technology is always the easy part. It’s doing it right at a fundamental level that’s actually really difficult to do correctly.

Scrum-style Burn Down Chart in iWork ’08 Numbers.app

Ever since I was introduced to the Scrum methodology of software development, I’ve enjoyed my work so much more than before. Most of that enjoyment is due to a sense of visibility, of knowing what’s going on.

I find working without an accurate awareness of the situation at large very disorienting, and software and web development are notorious for being circumstances that change rapidly. That’s why one of my favorite things about Scrum is the burn down chart. This is nothing more complex than a simple graph that depicts how much work you bit off and how far along trying to chew it you actually are. The benefit, of course, is that it’s pretty obvious pretty quickly if you’ve bit off more than you can chew. ;)

So up ’til now, my team and I have been doing this all on paper. There’s a certain tactile appreciation I have for doing this sort of thing on paper, but of course there are disadvantages, too. For instance, you can’t easily archive the information. You can’t easily share it with remote contractors. You can’t automatically mine this valuable data with software tools. You get the picture.

There are a few cool plugins to some tools like Trac that do all this, but at first blush most of these tools seem to require that you move all of your Scrum’s planning into the digital world. That is, you can’t just do the burn down chart, you have to do all your estimation (MoSCoW desirability, sizing, estimating ideal hours) through some tool. That’s a big step, and I wanted something simpler.

So naturally, I came up with a spreadsheet in Numbers.app as my solution. I mean, how much simpler can you get? Sure, it’s not exactly “well integrated” with other tools, but your non-tech-savvy boss will probably love it, and AppleScript can be used to automate data extraction. Here’s what it looks like:

An example Scrum-style burn down chart in Apple's iWork '08 Numbers spreadsheeting application, complete with an actual chart.
An example Scrum-style burn down chart in Apple's iWork '08 Numbers spreadsheeting application, complete with an actual chart.

(Click the screenshot to get a full-size view.)

As you can see, the Numbers sheet is a simple table and a line chart. I’ve embedded instructions for how to use the chart into the example itself, which I’ll quote here:

This is a sample Scrum-style iteration burn down chart for software development created by Meitar Moscovitz. It can be used to plot a team’s progress throughout a development cycle (aka. “iteration” or “sprint”). This sample chart depicts a 3-week iteration (15 working days) with a 150-point target goal.

The X-axis represents time, and is thus labelled Time in Days, while the Y-axis represents the work to be completed, and is labelled Points.

The green line shows the team’s ideal velocity based upon the total number of points—termed the Remaining Initial Value—scheduled for completion in the graphed iteration.

The blue line shows the team’s actual velocity (or “completed work”), which is entered by the team leader (aka. Scrum Master) after each day in the Done column.

To use this chart: duplicate this sheet, enter your iteration’s total points in the Initial Value row of the Remaining column, and delete the values in the Done column except its initial value of 0. To add more days, copy and paste more rows into the table. Optionally, give the sheet and its contents new titles. ;)

Feel free to download the Example Burn Down Chart.numbers file and use it yourself. If you do use it, please leave a comment and let me know how you’re going. Thanks, and enjoy!

(Mike Cohn of Mountain Goat Software has got a similar spreadsheet for Excel you can download.)

Productivity: It’s not what you do, it’s how you do it, and twentysomethings do it better

I don’t believe I have ever before posted an entry that, for all intents and purposes, is just a link to another blog post. However, this blog post is simply so brilliant and yet so short and easily-digestable, that I have nothing more to say. Thus: Twentysomething: 7 Reasons Why My Generation Is More Productive Than Yours.

By those definitions, I’ve been a productive twentysomething-year-old since I was a pre-teen, which just goes to show you that age has nothing to do with it. Damn straight.

One Minute Mac Tip: Remove .DS_Store files from ZIP Archives

The Mac OS X Finder has some nifty features, one of which is an exceptionally useful contextual menu item to create ZIP archives of folders. Unfortunately, the Finder also has some really, really annoying habits, one of which is to create a file named .DS_Store in each folder a user opens (when not in Column view). What this means is that if you create a ZIP archive on your Mac and then send it to someone who unzips it without the Finder (such as a Windows user using the Windows Explorer), the recipient will see a lot of litter in the form of useless and meaningless .DS_Store files.

If you’re not afraid of the Terminal, this can be avoided. Put the following lines in your ~/.profile (or similar):

alias rmds='find . -name ".DS_Store" -type f -print0 | xargs -0 rm'

What this does is creates a new command that you can use (rmds) which recursively finds and deletes any regular file named “.DS_Store” starting from the current directory. Thus, running this command in the folder you are about to create an archive out of will clean it first, and will prevent unnecessary confusion on the part of your archive file recipient.

Alternatively, another way to do this is to use the command-line zip program and an (admittedly more complicated) pipeline to remove the .DS_Store files after they have been added to the archive. To do that, use this series of commands:

zip -d ZIPfile.zip `unzip -l ZIPfile.zip | grep .DS_Store | awk '{print $4}'`

where, naturally, ZIPfile.zip is the ZIP archive you want to remove the .DS_Store files from. Creating an alias out of that command (and making it work for paths that contain spaces) is left as an exercise for the reader. ;)

As an aside, the alias, find and xargs commands are incredibly useful in their own right and can be used to do a lot of pretty amazing things. As always, man command will give you the nitty gritty.

Also as an aside, you can stop the Finder from creating .DS_Store files entirely when browsing network volumes (like Windows shares) with another command, documented in Apple’s Knowledge Base.

One minute Mac tip: Schedule off-hours downloads by enabling `at`, `batch` UNIX job scheduling commands

In a lot of places in the world, many people still have to pay for bandwidth costs. I’m one of those people who just can’t afford to download lots of stuff during peak hours when my bandwidth might quickly get shaped or, worse, I’ll get charged. Nevertheless, there are often plenty of legit reasons to initiate huge downloads.

In these cases, it makes sense to be smart about when I initiate these downloads. Being something of a UNIX-head myself, I wanted to use the age-old at command to download a Linux ISO during off-peak hours, which my ISP says starts at 2 AM. Much to my chagrin, I found that at doesn’t work by default on Mac OS X and, worse, the Leopard man page leads to a dead end (though it didn’t back in Tiger…).

Turns out that the system daemon that is responsible for checking up on at jobs has been wrapped with a launchd job. This makes enabling at on your system really easy:

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist

Once you’ve done this, you can now use at as you normally have done. For instance, I could now schedule my downloads to happen during the off-peak hours:

Perseus:Fedora maymay$ at 2:15am tomorrow # now press return 
curl -LO http://download.fedoraproject.org/pub/fedora/linux/releases/9/Fedora/x86_64/iso/Fedora-9-x86_64-DVD.iso
# now press CTRL-D.
job 1 at Tue Jul 15 02:15:00 2008
Perseus:Fedora maymay$ atq
1	Tue Jul 15 02:15:00 2008

This is also incredibly handy for scheduling just about any resource-intensive task that you don’t have to do right now. To take it one step further, you can even let the computer itself choose when to run these resource-heavy tasks by using the batch command, which will execute commands much like at but will check the system load average instead of the system clock to determine if it should start the job.

Note that with the com.apple.atrun job loaded /usr/libexec/atrun is started every 30 seconds (unless you change the StartInterval key in the plist file). Since the atrun command checks a file on disk (that it places in the /usr/lib/cron/jobs directory) to see if there is any work to do, this will probably prevent your disks from ever sleeping, which could be a major concern for battery life on portables. Also, obviously, your computer needs to be turned on and awake for the job to actually launch.

For more information, check out the result of typing man at and man launchctl at a Terminal prompt. There’s also a really good Google Tech Talk about Launchd that will teach you a lot more about job scheduling on Mac OS X.

Quick ‘N’ Dirty Drupal Module SVN Tagging Script

In a (rather beastly) project at work today, I found myself needing to import a significant number of contributed Drupal modules into Subversion vendor branches to prepare for custom development. To do so manually would have been quite the hassle, so after downloading the appropriate tarballs and creating a module_name/current directory under my vendor/drupal/modules vendor branch directory, I concocted this little (relatively untested) script to handle the mass tagging operations I needed to perform.

for i in *; do
    v=`grep 'version = "' "$i/current/$i/"*.info |
      cut -d ':' -f 2 |
        sed -e 's/^version = "/v/' -e 's/"$//'`
    svn cp "$i/current" "$i/$v"
done;

It’s a bit buggy for some modules that have multiple .info files, but I’m sure a few more pipeline stages can fix that. (Which, because I’m done with this at the moment, I will leave as an exercise to the reader.)

Chalk this one up as another testament to the power of shell scripting and how it can help every developer get their job done faster.

One Minute Mac Tip: Use the command line to edit the content of your clipboard

Using the pbpaste and pbcopy commands, you can manipulate the contents of the Mac OS X clipboard (or more formally known as the pasteboard) right from the command line. As a brief example, just select the text of this first paragraph, copy it to your clipboard (with -c), and then type pbpaste in a Terminal prompt. You should see output similar to the following:

Perseus:~ meitar$ pbpaste
Using the pbpaste and pbcopy commands, you can manipulate the contents of the Mac OS X clipboard (or more formally known as the pasteboard) right from the command line. As a brief example, just select the text of this first paragraph, copy it to your clipboard (with ?-c), and then type pbpaste in a Terminal prompt. You should see output similar to the following:Perseus:~ meitar$ 

Pretty straightforward, right? The only thing to be aware of is that the  symbol showed up in the output as a ? symbol. This is because the Terminal doesn’t support Unicode, but that’s a topic for another time.

Anyway, what’s happening here is nothing more magical than simply reading the clipboard and pasting it into a command’s standard output stream. As a result, you can construct pipelines that read from or add content to the clipboard. Here’s an example in reverse, which takes a command’s standard output and replaces the contents of the clipboard with it:

echo "Hello world! I came from the command line, but now I'm in the clipboard." | pbcopy

This command produces no output, but if we examine the contents of the clipboard (by selecting Edit → Show Clipboard from the Finder’s menu bar) we can see that the text we echoed has indeed been copied there.

The clipboard now contains the text we echoed from the command line.

Another way we can verify that this worked as expected is to simply pbpaste again:

Perseus:~ meitar$ pbpaste
Hello world! I came from the command line, but now I'm in the clipboard.
Perseus:~ meitar$ 

Anyway, this is cool, but it isn’t very useful yet. For that, we need to add some more stages to our pipeline. Let’s take the simple case of trying to count how many words the selected text contains. We’ll use the clipboard contents shown above to do this:

Perseus:~ meitar$ pbpaste | wc -w
      14

Using the word count (wc) utility, we can count words (-w) very easily. Indeed, our previous example does have exactly 14 words in it. We can also count characters (-c) or lines (-l) of text in the clipboard this way. This is like adding Microsoft Word’s “Word Count” feature to every single piece of text you can copy!

As another example take, for instance, the simple case of copying and pasting a snippet of email from Mail. Instead of pasting it back into a text file verbatim, let’s prepend ‘> ‘ to the beginning of each line. This way, when we paste our email’s snippet, we’ll know where the snippet begins and where it ends. This is a simple three-stage pipeline that uses pbpaste to take our clipboard and put it into the pipeline and then reads back the result from the pipeline back to the clipboard using pbcopy. In the middle, we use sed to insert the desired text at the start of each line:

pbpaste | sed -e 's/^/> /' | pbcopy

Now, when you paste your clipboard, you’ll have a greater-than symbol at the start of each line. Naturally, check out the manual pages for all of these commands for more detailed information. For instance, type man pbpaste for more information about the pbpaste command.