In February, I decided I would get rid of my side project of the last two years, blaster.fm. I listed it on Flippa and hoped that someone would buy it, but if not, I would just shut it down.
I wrote a blog post about the experience that had led to this point and submitted it to Hacker News, hoping that it would give the listing more exposure.
It hit the front page.
Over those three days the post garnered 24,000 hits, with 8,000 clicking through to the Flippa listing. That's a lot of exposure. Friends saw the post and sympathised. Oh, are you sad? It must be really hard. Not at all! I was elated that HN loved the blog post. I felt redeemed.
Ophélie, Flippa's Community Manager, had also seen the post and helped me tweak the listing while upgrading me to premium for free. Throughout the auction she kept in contact with advice and support.
Fame has its perks.
Over the two weeks that the auction was open, I received half a dozen enquiries. One bidder, who I skyped a few times, seemed particularly keen and asked me if I'd stay on to help build his future plans for the site. I was excited. We seemed to be on the same page in terms of goals and vision, and not only could I stick around to help guide future plans, but I would be getting paid to work on my baby. It felt like a great way to keep blaster.fm alive.
In the end it came down to just two bidders. I hit my reserve the day before the auction ended, and in the last hour bidding between the two parties drove the price up a couple of thousand dollars more. It wasn't a lot, but it was still a sizeable amount for someone to spend on a niche website that had zero revenue. Again, I was happy to be validated.
Jon, the bidder I had skyped, had ended up the winner.
Handover proceeded smoothly. Jon and I discussed my plans. I would be able to commit a small amount of time weekly, at a significant discount to my normal rate, to maintain and develop the site.
I transferred it to its new server. It was officially someone else's.
A few weeks after the auction, I was still happy to have sold the site, but I worried that I had been naive to think I could keep working on it.
I've made a huge mistake
By this stage I had finally grasped the reality that Jon and I were not actually the same person. Where things were unclear, I had assumed a lot, and projected my own plans and values onto Jon's. As a perfectionist, any tiny aesthetic change that didn't fit my values hurt me. As the person who had managed everything until this point, not being included or consulted on any decision, no matter how minor, felt like a tiny affront.
I knew I was being precious about it. I didn't own it any more. Jon had bought the right to do whatever he wanted with it when he won the auction.
Still, I couldn't do it.
I was like an overly attached builder who had sold the house he built and stayed on to renovate it. I can't knock down this wall, it has emotional significance to me! What do you mean, you want to put a spa in there? That doesn't fit the bathroom's minimal aesthetic!
I would make a terrible builder.
Thankfully, Jon was understanding and let me out of our agreement. It also benefits him to now have a developer who can make changes without grumbling.
I watch the new developments with interest, but as a user only.
We've all learned something here today
I've learned a lot from the process. I'm still proud of blaster.fm and all my work on it. I'm still glad to have sold it.
When working with clients, there's always a compromise to be made between their vision and your values. Compromise can be difficult if you hold those values strongly, and it only gets harder when there's an emotional attachment.
So I've learned that if you are attached to something – don't sell it.
Or sell it, then walk away.
I started blaster.fm in late 2010 with only a vague idea of what I wanted to do with it. Over the next two years I would work on it for at least a few hours every week; tweaking, refining, all-out rewriting, trying to get it as close as I could to the image in my head of what it could be. It was a one-man project and I was the only developer, though I had the support of friends and early users (with a large amount of the former making up the latter) to keep me going.
I speak in the past tense because I’ve decided to let it go. I’d like to sell it, but if it has no value, then I’ll just shut it down.
It seems like a good time to look back on the journey that led me to this point.
Basically, I wanted somewhere to post a song and be able to link to it and discuss it.
As a long-term user of both Twitter and last.fm, I had a vision of a beautiful Venn diagram in which these two services overlapped, and that overlap was my site. I was frustrated that you could do very little in the way of “social” on last.fm, and thought I’d have a go at addressing the issue with a service of my own. My other side project, Twitterscribe, was running happily without needing any maintenance, so I had plenty of time. Using last.fm’s API for most things, including user authentication, I would essentially wrap last.fm’s functionality with a social layer on top (I even picked a name with “last.fm” within it). I started a new Django project and got to work.
I launched to the public in February 2011. This is what it looked like.
A small group of friends had been privately testing for a few months prior, so I was fairly confident that most of the bugs were ironed out.
I tweeted a link. I posted to Facebook. I submitted a “Show HN” post.
Very little happened.
My Hacker News post did not make it to the front page, but one or two people signed up. Most of the other signups were from friends of friends, or twitter followers. The site had constant activity, but mostly from a core group of 20-30 people.
Still, I was optimistic.
I submitted a link and a pitch to TechCrunch, to The Next Web, to Lifehacker, to others I can’t remember. Martin from The Next Web signed up, but didn’t contact me further. After I pushed for some feedback, he told me it wasn’t big enough to warrant a story.
“It needs a mobile app to be interesting.”
He was probably right. It wasn’t much to look at. It was vaguely responsive and worked on mobile, but it was clunky. It needed to be better.
I got back to work.
From the start, my unrealistic-but-vaguely-possible best-case scenario was that “last.fm will see the value in social and acquire it”. The developer page encouraged developers to “show us the cool things you’ve made”. I emailed last.fm several times and submitted blaster.fm to the app gallery. I never heard back.
I decided that was okay, it could be its own thing. If last.fm doesn’t need me, then I don’t need last.fm. I would try to build as much of a platform as I could and achieve popularity without relying on integration with other services. I would appeal to indie artists, or indie labels, or create an API of my own so that developers could build cool things with its data.
Partly this attitude came from the limitations of the last.fm API. I had limited write access to user accounts. I couldn’t create new friendships, or allow users to message each other. Early on, I had thought that using last.fm as a foundation would enable me to build quickly, and would increase popularity as last.fm users could signup without creating a separate profile. In reality, it created confusion for everyone who came to it without having heard of last.fm. And it took away my ability to control the entire experience.
Meanwhile, it still needed to provide a more enjoyable, prettier experience.
I created a new RESTful API, and a new front-end using backbone.js. The front-end would talk directly to the API and allow users to navigate the site without losing what they were listening to. I redesigned the site. I only required users to link their last.fm account on signup, instead of using it to login. I started creating an Android app which would use the same API. Once I had a mobile app, I reasoned, I would have an entire platform which users and bloggers would take seriously. Then I could get some real traction.
Finally, by May 2012, over a year later, I launched the new design. I was pretty proud of it.
A trickle of users jumped ship from blip.fm to blaster.fm. Some hung around, but the majority signed up once and never returned. Of those who did post tracks and interact, most only lasted a month or so before drifting away. I don’t blame them. I wasn’t doing much to actively attempt to keep them around.
Meanwhile I still had to finish the Android app, which was only my first native Android app, and seemed to be an ever-growing task. I grew resentful of working on it. And I was still reluctant to seek more publicity until it was done. Once the platform was “complete”, I reasoned, then there was something to be proud of, something that would be featured on tech and music blogs alike. That’s when I would go into marketing mode.
But that time never came. I had pretty much abandoned the site. It ran itself. I checked in weekly to post a track, but no longer considered it in active development.
Ironically it was at this point that I was approached by the guys at Melbourne Geek Night to give a talk about what I’d learned from building the site, and what I hoped to get from it. I gave my talk, which wasn’t entirely terrible. I went on to pick up some work from people who saw me talk, and to be offered another job later on. But only maybe one or two people in the crowd actually signed up.
Shutting it down
Choosing to let it go wasn’t easy. “Why can’t you just let it sit there and keep running?” I have been asked several times. But even though it doesn’t require active maintenance, it still exerts a mental toll. It weighs on me, the site-that-could’ve-been. The site that missed its opportunity to get big.
I still consider it an excellent demonstration of what I can do, and I’ve learned a lot of lessons from it, both technical and otherwise. But I can’t do anything more for it.
I’m hoping someone else can, though, which is why I chose to put it up on Flippa. It works well, it was refined over a long period, and it does still have active users. Maybe someone else with more “hustle” can make something of it.
Please check out the listing if you’re interested. I’ve compiled some more stats on there as well.
I finally updated the site to reflect current standards. It was starting to get a little long in the tooth.
The results are not aesthetically amazing, but it's now HTML5 and fully responsive, so I'm happy. For now.
I have been trying to find a basic proof-of-concept for twitter user streams. I couldn't find a complete example, so I rolled my own.
I wanted to avoid the external pyCurl dependency (which means curl needs to be installed separarely on Windows) so I switched the pyCurl callback method you might have come across with some rather naive urllib2 buffering.
It works, though, and that's the important part.
Note: This has been tested on Python 2.6.5 and up. Problems have been reported with older versions.
If you use Firefox 5, 6, 7, 8, or greater in Windows, without ClearType, you've probably noticed how abysmal the font rendering is.
However, there's an easy fix. In about:config, find the preference gfx.direct2d.disabled and toggle this to true. Restart and your fonts will now look as they used to, which is to say, not nearly as horrible.
I don't consider myself a designer at all, but I do enjoy pushing pixels. So recently I've done a tiny bit of work designing icons for various projects other than my own.
On the left is the icon for MahTunes, from The League of Paul. I think only the source is available at this stage.
On the right is the icon for Convertor, a webOS app by Coding Bees.
While not incredibly awesome, they're a start and hopefully something I can look back on in twelve months and laugh at scornfully because I'll be so much better.
...unless it can show you all of your open app windows and let you switch between them with a swipe and a tap.
This is by far my favourite feature of webOS.
I recently signed up as to the Android Market as a developer so I could buy a "Google Dev Phone 1" which is an unlocked HTC Dream/G1. I've been interested in Android as an open-source competitor to the iPhone for a while, and given that the Dream has officially launched in Australia, and Australian developers are now able to submit (free only) apps to the Market, I thought I'd get a device to evaluate and maybe hack some apps on.
I'm quite interested in Palm's Pre OS too so I hope I don't end up with a Pre as well, "just to play with" :\
When the G1 was first announced I was very underwhelmed. It looked decidedly average. I maintained this opinion for a long time until I had a play with one in person a little while back. It's actually not a bad device. It fits comfortably in your hand (at least when held vertically) and though it's a bit bulky the rubberised finish is nice to hold. Specs-wise it has all the nice things — wifi, GPS, compass, QWERTY keyboard and of course a touch screen.
Update: Twitterscribe is now public. Anyone can sign up, so why not give it a go?
One of my resolutions this year was to deliver more of my side projects. Currently a lot of them are half-formed, either in idea or in function, and I wanted to change that by attempting to actually finish and make available whatever I start. So it is with a certain amount of glee that I announce my latest effort, Twitterscribe.
So recently I've been having a play with Python. I like it a lot, and it's started to affect how I code in PHP — all of my freelance work still uses PHP, so it's still my 'primary' coding language. However, this means that all the little things I can do faster in Python come back to haunt me in PHP. It was bound to happen. Unfortunately, though, I can't just switch all my work to Python (and it has a number of shortcomings that make it harder to support, anyway) so to resolve this I've been attempting to replicate, in my PHP framework Rex, some of the things which in Python make my life easier.
The first of these is the syntactic sugar of SQLAlchemy's (and AppEngine's, Django's, and others) data selection syntax. With some nifty method chaining, SQL queries can be abstracted to such pretty code (yes, in PHP) as
$user = User->all()->filter('Admin = 0')->order('FirstName','ASC')->go()->get(0);. I might follow up this post with another explaining how to achieve this method chaining, and it's really quite easy, but in the meantime I want to draw your attention to something else.
Older posts >