Entries in category "Web Development"

It's amazing how quickly you can bootstrap projects. I remember when I first build Lightbox7, it took weeks to get it into a testable stage. 

With the toolsets that are available to me, I might have a demoable product within a week. 

Over the past two days, I got individual image views (with easy arrow navigation) as well as the workflow for user login/registrations to view private albums done. 

I started working on the comments data model tonight, but I need to sleep. 

Originally, I wanted collections (curated albums within an album) to be in the v1, but I think I'm going to punt that to a v2. Tomorrow, I'm going to wrap up commenting (editing, deleting), and do a quick blog post on the status for the features I want in a v1 beta test. 

. . .

This project is great, cause it's also giving me ideas on how to revamp Tabulas' featureset. What I may end up doing is just bringing in a simpler version of this codebase into Tabulas! Yay! 

. . .

Been playing around with pricing - I originally was thinking $50/year for 10,000 images... but that seems really expensive. I'm actually leaning towards offering a monthly plan - $4.99/month for 5,000 images after reading this post

And to those of you who help me beta test, free 10,000 image accounts for life! 

Posted by roy on October 25, 2012 at 03:43 AM in Miyaki, Web Development | 1 Comments

It was about 9 years ago when I started Lightbox7, a very early photo-sharing site. I sold it so I could get more cash, but it's always been on my list of "projects to start again when I have time."

Of course, for a long time, Flickr dominated photo sharing, so there was really no reason to kick start another project. Then, FB, Smugmug, (and now Google+) have done a "good-enough" job of photo sharing (actually, G+ is pretty good). But I feel we're at a crossroads again with photo sharing, where a really useful product can be built and supported. 

Here's my idea: an anti-social photo sharing site. Here's the specific use case: 

People who go to shared events (like weddings or Vegas parties) oftentimes want to share photos with other people there. Now, with FB's advanced privacy controls, it's actually pretty hard to do this effectively without friending every person you met. 

This site would allow an event creator to create a shared album. He can either make it a "shared-link album," which grants access to the album to everybody who has the private URL, or will explicitly invite users to the album (via FB friends list). Every album can only be access by registered users (be it via FB or G+ or local registration) and has a max number of users (150 users).  

Every user who can see the album can contribute to it by adding photos, adding comments, or creating a "collection." A collection simply would be a curated view of the album (since it would conceivably hold a lot of photos from lots of users). 

Why do I think this would work?

Try to answer this question right now: "How do I share my photos to somebody w/o FB or Google+ easily?" 

You'd be surprised at the answer: besides SmugMug (which doesn't really approach the social aspect of photos), it's hard to find a solid answer. Everybody requires social logins lately. And a lot of people (like my parents) don't have G+ or FB accounts. 

I've noticed anecdotally that the number of friends who have been sharing photos on FB have been dropping - I actually think FB has gotten ubiquitous enough that it actually feels like a really public space. With this project, you wouldn't worry about figuring out permissions based on your friends - you make the decision on an event-by-event basis. You would have to opt-in every person to your albums. 

The anti-social photosharing site. 

Random Technological/Implementation ideas: 

I really like G+'s approach to a mixed-grid view of images; I definitely think the "unfiltered" view of each album would look like that, and users would create collections by simply clicking images. 

Also, one way to get a leg-up? A Retina-friendly site. Actually, could that be a marketing push all to itself? We'll have to find out. 

There'd be no import features (and exporting only for archival purposes - I'm thinking it'd integrate to Dropbox so you could just select an album to be exported into your Dropbox account). 

Costs are a big problem - Amazon S3 is not very cost effective. I'd imagine at some point I'd end up running my own DC (once I get into a few terabytes, I guess). Glacier looks promising to store the original uploads, and then I'd keep lighter versions on S3 and on the servers as well. 


In keeping with my recent motto to only build for-pay products, I think $49.99/year is a solid price point (or $4.99/month). This would give you a quota of 10,000 images (by my math, each image is about 3MB, so on S3 pricing, that's about $38/year in costs). 

And to solve the "how do you make it social if everybody has to pay?" problem - your usage would be calculated based on the albums you created, so other users would also eat your quota. That also means that not every participating user needs to be a paid member.

In my experience with Tabulas, there were a few members who would actually pay for other members - I think this phenomenom would extend well here - not everybody would want to pay, but those who feel comfortable might end up "paying" for their whole families by being the sole album creator for each event. 

When creating an event/album, you'd set a "target size" for your album (in # of images) - and everybody can upload until that image quota is hit. Other users can donate their # of images to make the album size bigger. 


In honor of Pinboard.in, my favorite anti-social bookmarketing site, I also adopted the .in domain name extension. When picking a name, I wanted to pick something vague but with some cultural pulls - so I picked miyaki.in. I'm not sure what it means - to me, it sounds like a cool chick who is "over" Facebook but is super artsy with photographs, and thus wants to share them. I don't know. It sounds recognizable and full of character without meaning anything. Just my type of name. 

Unfortunately, my workload is rather full this month, so I'll have to start tackling this slowly (maybe only 1 or 2 hours a day). Fortunately, it's a pretty easy product to build, and most of the UIs are built in my head already (I've been ruminating on a photo sharing site for a while now). 

Posted by roy on October 15, 2012 at 03:34 AM in Miyaki, Ramblings, Web Development | 1 Comments

Been on a plane all day, so a bit tired. But I got to spend a lot of time thinking about App.net on the plane, and it's got my quite excited. So in keeping with my old writing style, here comes a lot of disconnected thoughts. 

. . .

It's been quite some time since I've written in this thing with any regularity. In the years I've been away, I've immersed myself in the Twitter, Facebook, Flickr, Pinterest, and the Instagram world. The mobile world is exciting, and clearly it's helping the growth of products which thrive on stealing your attention for 10 minutes at a time (information consumption, games, etc.). I worked in a product in the enterprise space and left, never vowing to do it again, before finding myself in midst of starting another enterprise SaaS service. But you (old) readers should know that my love has always been in building sites for people to share their stories. That's what led to me building Tabulas *9* years ago. I never stopped thinking about Tabulas and how to improve it. (Now, having time + resources to address it is something else altogether). 

Let's face it: Tabulas suffered because it got much easier to share stories on other sites. And it wasn't even the creation of the stories that was important - it was the feedback you got. It was much easier to build and maintain a community on those other sites. 

. . .

But I sense that this is fading. As pressure mounts on the Twitter and Facebooks of the world to monetize, the feature sets aren't as enticing. I've seen a dropoff from my friends' activity across a lot of these sites, and I'm beginning to re-thinking my metric for  measuring "success" of a social network - I no longer think it's the size of the network that matters, but more the quality. Svbtle has been doing a great job of proving this point. 

Tabulas did pretty damn good in the early days (of course, this was really pre-FB) in picking up $28/year subscriptions from its users, with no real difference between the premium and free versions. But then came the flood of ad-driven sites that caused the price to drop to $0, which really destroyed the ability for Tabulas to continue product development. We tried ads for a bit, found out they didn't work, and basically let the site flounder. We were living in an ad-driven product world, when what we really wanted was the users to pay for our product. 

. . .

But now I'm starting to believe that there could be a world where people would pay to join a site like Tabulas, and it could support itself immensely well. The Apple iOS community proves people will pay for software again, as long as it is high quality

Now, I don't think ad-driven sites like Twitter/Facebook/Google+ will ever fail - I simply believe they will be the commoditized products of the world. The lowest common denominator. Like McDonald's with food - everybody has been there, they fill you up... but do you really want to eat all your meals there? 

I think the next generation of social networks will provide polished, hand-crafted apps that people *love* to use and pay for. This is already happening on the iOS platform, but hasn't made its way to the web yet (the technial reasons for this deserve its own blog post). 

. . .

In my mind, Tabulas goes back to its roots as a journaling-driven social network. We strive, once again, to build a high-quality journaling product that allows people to easily and freely share their stories. But I can't provide the social graph - creating great writing tools and allowing people to connect is too hard. 

And that's where the problem lies. I won't delve into the issues with FB Connect, but I'm not convinced that Tabulas could survive in a world where the social graph lies with FB. (It mostly has to do with the fact that users who use FB expect free, and also the ability to gain traction via FB has largely been limited due to their throttling of viral social growth after abuses in the past). 

. . .

So imagine my joy to hear about App.net. Right now, it's nothing more than an idea; a call to arms. The gist is the following: it's a social network that is not driven by advertisers, but by its users. You pay for a great social networking services, and you get an awesome product in return. It's a great idea. Social networking is the killer app of the Internet, and I see no reason why people wouldn't pay for it. 

The price? A measly $50/year. Given that FB only generates $5/user per year, the business model seems - at first glance - decent. 

What gets me excited about this? 

Well, App.net will focus on providing the base tools to build data (posts, images, etc.) and the name brand should be enough to start building the social graph. Tabulas can focus on building a great product for sharing stories. 

IF App.net (a big if) can position itself as a high-quality exclusive social network, it should have NO problem drawing in people to pay for it. And IF those people are in App.net, and they get access to a series of high-quality apps on TOP of App.net, there should be no reason why app builders on top cannot make a good income building high-quality products that people love to use. 

To me, that'd be the perfect world. The commoditization of social networking tools has really hurt the user experience across the board (with the exception of mobile Twitter), and I think people are starting to get bored. There's an army of developer craftsmen who want to pursue perfection, but need a market to do so. So far, the Apple iOS ecosystem is the only one - but one doesn't exist for the web. 

If App.net can change this by creating a marketplace on the web for developers on top of a solid social graph, *that* is a game changer for developers. 

. . .

So far, the API is non-existent. The core decisions seem good, though. I do agree that the data needs to be centralized - I've long dreamed of a decentralized world, but it won't work. JSON (implicitly REST) for the API is great for a lightweight transport format. The fear with API design is always you abstract too much - hopefully they set a deadline and work against that with real use cases for the API. (And of course, don't be afraid to make breaking changes to the API). 

In any case, they are soliciting donations for App.net - only when they get $500K pledged will this start to become a reality. And I hope they get there, cause I do feel this is a game changer. (And that should mean something, I've only really used that phrase when Amazon S3 launched). 

Posted by roy on July 20, 2012 at 11:45 PM in Ramblings, Web Development | 6 Comments

I'm so glad I had a chance to work at MT, where I really understood why a SOA rocked. Reading posts like this also drilled into me the value of a platform. 

Of course, applying this concept into the type of clients I work for is difficult. The cost to building out a platform is high, and the returns are negligible in the early days. 

With most of my projects, the idea is to get quickly to market, which means our toolset differs a lot from the ones you'd use to build something more solid. That's not to say that what we build is crap - it's not. It's just not geared to be the basis of a platform. 

However, the great thing about building an API is eventually you can swap out the underlying technology for something more robust, as long as the endpoints stay the same. Love it. 

In any case, we're building an iPhone app, which requires a data transit mechanism. Thought this would be an excellent place to start building out the beginnings of an API. 

And boy, did we rush through the v1 - we got it build over a span of about 3 weeks with CakePHP, and here are some lessons learned:

(1) CakePHP has all the inner workings to support a REST-based API. If you want clean URLs, use Routes to do so. Our routes config looks something like this:

	Router::connect('/api/users/authtoken', array('controller' => 'api', 'action' => 'users_authtoken', '[method]' => 'GET'));
	Router::connect('/api/users/current/challenges', array('controller' => 'api', 'action' => 'users_challenges', '[method]' => 'GET'));
	Router::connect('/api/users/current', array('controller' => 'api', 'action' => 'users_current', '[method]' => 'GET'));
	Router::connect('/api/users/current/picks', array('controller' => 'api', 'action' => 'users_current_picks', '[method]' => 'GET'));
	Router::connect('/api/users/challenges', array('controller' => 'api', 'action' => 'users_challenges', '[method]' => 'GET'));
	Router::connect('/api/challenges/:id/users', array('controller' => 'api', 'action' => 'challenges_users', '[method]' => 'GET'), array('pass' => array('id'), 'id' => '[0-9]+', 'users' => null));

(2) In the early iterations of the API, we got super ambitious and decided to support both XML and JSON. Don't bother. JSON works awesome by itself. Although we eventually abandoned support for XML, we were stuck with API endpoints which had to end in .json to render JSON. The v2 of the API (which we're working on), puts this into the API's beforeFilter() method:

		$this->RequestHandler->setContent('json', 'application/json');
		$this->layout = 'ajax';
		$this->header('Content-Type: application/json');

Everything is returned in JSON - yay!

(3) We were REALLY lazy in the first iteration of the site... so much so that we decided basically to emit the raw data structures coming from the ORM out to the user. That means our views were all the same: json_encode($json), but that means that we weren't able to manipulate a lot of the data before hitting the iPhone layer, which meant we were duplicating a lot of the view-logic in both places. 

One example of this: our user model contains a single field: avatar. This contains the filename of the the usericon for that user. However, instead of storing an absolute path, we simply store the filename. A view helper takes that filename and generates/returns a valid usericon string. 

By passing the data from the model directly out to the views, we weren't able to catch this. 

Not only this, but unless you wrote data suppression methods (which we stupidly had to do), you end up emitting the whole data models to the API. Talk about overkill. 

The v2 of the API development has been focused on cleaning up the outputs, so the primary thing we did was write serializers for each data model. This time we relied less on magic: we are writing a serializer helper object that'll handle each data object type and modify the values accordingly and be sure the data models are consistent. (Depending on how you use containers, you'll emit different data structures out as well). 

I can't stress the importance of documentation - we didn't do very good documentation first time around, and although the APIs were mostly self-explanatory, the lack of having to write through the documentation created a lot of inconsistencies throughout a lot of the endpoints. This time, I sat down and wrote the documentation in parallel with the views for the JSON objects, and they are a LOT more consistent (much to the delight of the iPhone dev team). 

Leaky abstractions occur everywhere - but I'm convinced writing your documentation before (or in parallel) with your code helps nail down the abstractions that are prevalent in user stories. 

One area that I'm struggling with - the API is SLOW. Even after cutting down the size of most API calls in half (in terms of data sent), we're still seeing response times in the 600 - 700ms range. That's CakePHP's magical autoassociation of models. I've done my best to only load models on-demand for each API call, but we will need to eventually dive into our models and start unbinding a lot of them (or only binding them when necessary). 

What's great about the API is that it's a great investment - if the killer app (the website) does well, these guys are gonna get the beginning of a great technical platform to boot. Of course, at some point we want to move the front-end on top of the API, but I reckon we can do that incrementally over time...

Posted by roy on November 2, 2011 at 11:57 PM in Web Development | Add a comment

Saw this at Focus, but wanted to share it here:

If we look at SalesKB, we see:

  • founded by 2 people
  • supported by work/consulting
  • spending about $300/month on hardware (outside the range)
  • spending WAY more on resources than $500/month
  • we are 4 months old (from the moment we started building the version 1)
  • we are ready to start selling the product
  • and i do guess we'll be break-even in 3-12 months

Although that number is weird: most startups spend $500/month but can't break-even? This shows the flaw: startup founders don't count what they need to pay themselves with the startup as a cost. I mean, if I took out all the money I pay myself from rykorp, it'd be hugely profitable!

As for problems? I feel with SalesKB (and I'm normally a pessimist!), things are going remarkably well. We delivered the v1 prototype (only cut out two "major" features, which turns out weren't major features at all) on budget (and relatively on-time), we have an excellent go-to-marketing plan, and we don't struggle much with time issues. 

It's actually been a really smooth ride so far (no drama, no unsurmountable roadblocks). Me and the other half of SalesKB have trusted each other with decisions, we've focused on the important part of the product, and we've had fun doing it. When SalesKB becomes super successful and they ask about the hardships of starting a company, I'm not sure I'll have a good story. Our hardest problem is usually deciding where to eat when we meet up. 

Posted by roy on May 16, 2011 at 11:12 PM in rykorp, Web Development | 1 Comments
« Newer · »