Netflix Feature Request: Multiple Account Profiles

I purchased Apple TV and Netflix over a year ago. Been very happy with both. So much so that I recently bought an Apple TV for my parents and included them on my Netflix account. From an subscription perspective, I see no problem with this as Netflix allows your account on up to 6 devices. But after about a week I noticed my Recommendations were skewed and some odd items in my Queue. And of course they were. My viewing habits are different than my parents. I though my Netflix account should have more than one Profile. To my knowledge, such feature does not exist.

The following is a letter to Netflix requesting this feature. Although I have submitted this request to Netflix, I’m posting it here in hopes the feature might gain some traction. Let me know your thoughts.

Dear Netflix,

I have a feature request. As your streaming plans currently support up to 6 devices, it’s common for a single account to be shared. Say for example, between family members. However, currently all aspects of the account are shared. Most notably Recommendations and Queues.

This really degrades the Netflix experience. So I’m recommending the concept of Profiles. Profiles inject themselves between the account and it’s features. Further encapsulating Netflix features. A Netflix account can then have multiple Profiles. As such a user would toggle their Profile to receive their personalized Recommendations and Queues.

Incorporating this feature into the UI would be simple. For the web and mobile app UI, a user could toggle from a drop down menu in the upper right. For Apple TV, add another option button above Logout. As far as usability, it is in the users best interest to toggle their Profile.

The application of Profiles extend beyond this use case. For example, Parental Controls could be built around Profiles. The concept of Profiles is widely used by Satellite TV. Netflix should incorporate its own version of Profiles.

Customer,

Jason McCreary

Installing, Configuring, and Deploying I/O Docs

I heard about I/O Docs in a tweet from @Mashery last August. One of their evangelist developed I/O Docs with node.js and released the project on Github. I’ve wanted to check it out for two reasons. First, I have an undocumented private API – PocketBracket – that, well, I said it already, was undocumented. Second, I wanted a reason to develop with node.js.

From the I/O Docs synopsis:

I/O Docs is a live interactive documentation system for RESTful APIs

Some of the highlights of I/O Docs:

  • live and interactive
  • Promotes RESTful APIs
  • Documentation is done in JSON

Installing I/O Docs

The README within the project provides pretty good instruction for getting started with I/O Docs. It notes the changes you need to make to each file as well as full detail on how to begin documenting your API using their JSON format.

Unfortunately they gloss over the prerequisites for node.js and redis. If you’re running Mac OS X, check out my previous post on installing node.js, npm, and redis on Mac OS X. Otherwise, the links they provide should get you started.

Configuring I/O Docs

Out of the box some of the sample APIs did not run. After setting "debug": true; in config.json, I noticed these were the API requests only passing an API key. After revisiting GitHub, this was a known issue which lead me to a fork by ezarko.

I applied ezarko’s patches to app.js and config.json. This got me most of the way there. I also had to add the following to unsecuredCall() (~ line 504):

options.headers["Content-Length"] = Buffer.byteLength(options.body);

Unfortunately the DELETE requests still failed for my PocketBracket API. I realized I was expecting the API key as part of the request body. I/O Docs still appended it to the query params. For a minute I questioned my API architecture. However, using the request body for a DELETE did not violate the constraints of REST or the HTTP spec. In fact, to me, it seems more intuitive. In my opinion, only a GET request should explicitly utilize the query params.

I made a few changes to ensure DELETE requests utilized request body properly. I provide my app.js file below. So in summary, I audited the code for DELETE requests and ensured they behaved like PUT/POST (2 places). I also had to modify the if statement to ensure the request body was sent with the request (~ line 600).

Deploying I/O Docs to Heroku

While running I/O Docs locally worked, I needed to share the documentation with my team. Heroku to the rescue. Heroku is a cloud hosting service that plays nicely with git, node.js and redis. In this case, all were free add-ons. The sign up process for Heroku was simple and I was ready to deploy an app in minutes.

I started following a post about deploying I/O Docs to Heroku by Princess Ploymath. Unfortunately as noted in my comment on her post, it didn’t get me all the way. Although it ran fine locally, I received an error regarding the redis configuration when running on Heroku.

Heroku required some configuration changes in more spots than Princess Polymath noted. I added the following updates to app.js while to be minimally invasive (I hate hacking core code).

Modify the config object before creating the redis connection (~ line 60).

if (process.env.REDISTOGOURL) {
  // use production (Heroku) redis configuration
  // overwrite config to keep it simple
  var rtg = require(‘url’).parse(process.env.REDISTOGOURL);
  config.redis.port = rtg.port;
  config.redis.host = rtg.hostname;
  config.redis.password = rtg.auth.split(“:”)[1];
}

Modify the port (end of file)

//  use production (Heroku) port if set

var port = process.env.PORT || config.port;

app.listen(port, config.address);

Closing

I plan to start contributing to the I/O Docs project once I become more familiar with git/GitHub (I know). I’d like to add some additional configuration options, like passing parameters (such as the API key) in the request headers.

In the meantime, you’re welcome to download my app.js. All other changes should be configuration specific to your environment.

Unexpected behavior with drop-down option order using minYear, maxYear in CakePHP

I noticed something interesting when testing a checkout form today build in CakePHP. The options for the drop-down were in descending order. The options were for the credit card expiration date field. The range was set with minYear and maxYear attributes.

The code in my view (CakePHP version 1.3.7).

echo $this->Form->input('cc_expires', array('type' => 'date',
  'label' => 'Expiration Date',
  'dateFormat' => 'MY',
  'empty' => true,
  'separator' => ' ',
  'minYear' => date('Y'),
  'maxYear' => date('Y', strtotime('+7 years')));

Although the options range is correct, this seemed unintuitive. In addition, I felt it was slightly poor usability. So I wanted to fix the order.

CakePHP default option order

CakePHP default option order

I dug around in The Book. Nothing. I was about to submit a ticket. But before I do, I typically check my version and the core. Upon searching for minYear I found the function in question – year(). Apparently an undocumented attribute exists – orderYear. After adding 'orderYear' => 'asc' to the options array I got the desired output.

Two notes here. First, CakePHP has many undocumented features. It never hurts to dig around the core. Second, the orderYear attribute is completely unnecessary in this case. In fact, it is only used for the *year* drop-down. It could be easily determined from comparing minYear and maxYear. In this case, minYear is 2012 which is less than maxYear is 2019. Display in ascending order.

Control option order using orderYear for year in CakePHP

CakePHP option order with orderYear

Maybe orderYear has uses. But today it wasted my time.

</rant>

Installing node.js, npm, and redis on Mac OS X

I’ve been wanting to mess with I/O Docs for some time now. I/O Docs requires node.js, npm, and redis. I hear the buzz around these technologies, but I have yet to use them. Although I found several posts and a package for installing node.js and npm on Mac OS X, each had issues. Mac OS X runs atop BSD Unix. So, while potentially intimidating, you can install all these yourself by running commands within Terminal.

Installing node.js

After much Googling I discovered an overwhelming set of node.js installation instructions. In a nutshell (no pun), this installs node.js under a newly created local folder in the current user folder and adds that folder to your PATH so you can run node.js simply by typing node.

echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bash_profile
source ~/.bash_profile
mkdir ~/local
mkdir ~/node-js
cd ~/node-js
curl http://nodejs.org/dist/node-v0.4.7.tar.gz | tar xz --strip-components=1
./configure --prefix=~/local
make install

A few notes.

First, this installs node.js version 0.4.7. From what I read, this is currently the most compatible version. If you require a different version, I’ll assume you know more about installing node.js than me.

Second, bash on Max OS X uses .bash_profile not .bashrc. I’ve modified the original script to reflect these changes.

Installing npm

Once you have installed node.js, you can install npm with just one command.

curl http://npmjs.org/install.sh | sh

I should pass along the warning that this runs commands streamed from the internet. If you’re paranoid about that kind of stuff, you should download and verify install.sh first.

Installing redis

Redis was a straightforward install. For the most part I followed the redis quickstart guide. I modified the script below slightly to use curl as Mac OS X does not include wget.

curl -O http://redis.googlecode.com/files/redis-2.4.4.tar.gz
tar -xzf redis-2.4.4.tar.gz
cd redis-2.4.4
make
rm redis-2.4.4.tar.gz

In closing

In time, you may need to update the versions for node.js and redis. Both offer a latest download. Feel free to substitute these into your script. The commands above should still work. Nonetheless, I tried to provide links to the original documentation when available.

Check out my recent post if you are interested in getting started with I/O Docs.

Tough Mudder Challenge

In two weeks I, as part of team #tigerblood, will accept the Tough Mudder Challenge. This course, located in northern Indiana, will consist of 21 obstacles over 12 miles. The course is over rough terrain with elevation changes, water, and mud. I expect to be wet the whole time. Since winter is coming the cold will be a factor.

Each Tough Mudder course is different. But the following video demonstrates the most common obstacles. You also see the fine line between toughness and craziness.

Why?

A man should measure himself against a strong force at least once in his life to see if he can handle it.

Tough Mudder is as much about physical endurance as it is mental will. In addition, several of the obstacles are designed to require a group effort. Many races or events are about the individual. I like the camaraderie Tough Mudder adds. You have to band together to complete it. Finally, Tough Mudder isn’t about results. There are no times, no scores, no places. It’s about finishing.

Preparation for Tough Mudder

I trained for 5k races in the summer. So I had a base to start Tough Mudder training. I added weight lifting and the Tough Mudder workout to the weekly routine.

Any opportunity to add grit to the training was taken. My parents had an uprooted tree that needed removal. Instead of a chainsaw and trailer, we used axes and carried the logs. Before our long weekend runs we dump buckets of water on ourselves. I’ve started running home from work once a week. Particularly on the days that it rains.

Goals

I have no idea how difficult Tough Mudder will be. My goal is to finish – run the course and complete all the obstacles. I hope to have fun and stick together as a team.