Automating the next-episode button in Netflix
6 of January2012
I’ve long since been frustrated by the inability to queue Netflix episodes. A few weeks ago came the final straw: My 2yr old woke up at 3am and refused to go back to bed. The kid requested Shaun the Sheep, which happens to be 20 minutes long.
So I can either stay up with the kid, or go to bed and risk getting woken up every 20 minutes to fulfill my duty as the next-episode-button-pushing-man. I’ve been going with option 2, which is no way to live (or sleep).
So I’d had it, from 3-5am, with my kid on my lap, I resolved to find some sort of solution. Certainly SOMEBODY has written an app to solve my problem. Turns our there was only 1 could find, and it was Windows only, so it wasn’t a viable option for our iMac in the loft.
My solution:
I found a neat program called Sikuli (Open Source and written by MIT students) which handles GUI automation. I wrote a python script for it, which now looks for the “next episode” button and clicks it (for as many times as I specify). Works like a charm.
Here is the project on Github:
Autoplay-net
Here is the source of the script:
#setThrowException(False)
#function exit the script
def exitScript(event):
popup("You've managed to close Autoplay. Script will abort.")
#kill the program (this is native python)
import sys
sys.exit()
#how often has next button been pressed?
counter = 0
#prompt user with input
numEpisodes = input("How many more episodes should this run for? \nexample: 4 | Press Ctrl + F1 to cancel.")
#default success message that will play after script ends successfully
popMessage = "Done auto-playing episodes!\n" + str(counter) + " played."
#select a region
region = Screen().selectRegion("Where should the mouse-pointer go after autoplaying?")
#take a screenshot, then click that one
#scrnShot = Screen(0).capture("take a screenshot")
#add key listener. Listen for this key combo to exit the script.
Env.addHotkey(Key.F1, KeyModifier.ALT+KeyModifier.CTRL, exitScript)
#loop through looking for the next for the # of times specified by user through input above
for x in range(int(numEpisodes)):
#look for the button every 5 seconds (easier on CPU)
while not ("PlayNextEpis.png"):
wait(5)
#Check for button existence (for 1 hr)
if exists("PlayNextEpis.png", 60 * 60 ):
click(exists("PlayNextEpis.png")) #(first click for focus)
wait(2) #wait for load
click(exists("PlayNextEpis.png")) #click again if still there (since we now certainly have focus)
#increment the counter to show how many were played
counter += 1
#update play count here for how many episodes have played
popMessage = "Done auto-playing episodes!\n" + str(counter) + " episodes auto-played."
try:
#move moouse to rest after clicking next episode. This was user selected earlier.
mouseMove(region.getTopLeft()) #move to place selected
#popup("found")
except:
#upon failure to find a valid region specified, pop this up, before terminating the script.
popMessage = "Region selected earlier was invalid. So mouse move didn't work.\n" + str(counter) + " episodes autoplayed."
#pass # we miss it
#pass is just a placeholder.
else:
popMessage = "Auto-play aborted! Next button wasn't found for 1 hour. \n"
break #terminate the loop
#popup before script ends with success or failure message.
popup(popMessage)
Enjoy. Bear in mind I’m a total Python newb. If you have any improvements / suggestions please let me know.
Posted in Projects
Lessons learned from Apple's Design Process
2 of July2009
Some time ago I ran across a BusinessWeek article about Apple’s design process:
Every week, the teams have two meetings. One in which to brainstorm, to forget about constraints and think freely. As Lopp put it: to “go crazy”. Then they also hold a production meeting, an entirely separate but equally regular meeting which is the other’s antithesis. Here, the designers and engineers are required to nail everything down, to work out how this crazy idea might actually work.
This really struck me as quite profound. I’ve participated in brainstorming sessions, creative sessions, (or whatever else you want to call them) where the goal of the meeting was to come up with creative ways to solve problems and restrictions. The most successful of these meetings followed something similar to Apple’s process.
Why is this?
There seems to be something intensely paralyzing about trying to find creative solutions while at the same time trying to remember all of the constraints of the tiny square you’ve painted around yourself. Trying to find solutions that solve all of the problems while staying inside of the constraints of the box is an unproductive ritual of self-guessing. You end up shooting yourself down on every idea you come up with. “This won’t work. That won’t either…”
A lesson to be learned from authors
Authors write a rough draft. They just kind of vomit everything out, and then write and write until they run dry. Then they go back and refine parts that need refining. Many authors will do 9 or 10 rewrites until the finished book ends up being very different from the original draft. The rough draft gets their ideas out on paper. They can improve it. They can show it to others who can critique it.
Designer’s Block
Just like writers have “writer’s block” so do designers. I find the best remedy to this (after sketching and doing the normal research) is to simply open up photoshop and start pushing pixels. Overwhelmingly, after 10 minutes or so of this, I can see a solution and am excited to finish the piece.
Summary & Conclusion
Have 1 meeting where anything goes. Everybody’s idea is appreciated. There are no dumb ideas. This is a meeting for trying to find ways an idea could work.
Have a 2nd half or separate meeting where you shoot holes in those ideas. You then usually end up with the really good ones.
A word of caution before I end. There is such a thing as getting input from too many people. With most brilliant ideas, many people don’t recognize them as such. There will often be opposition. Show it to the right people you trust. Not too many. Design by committee is useless. Now go forth and be brilliant.
Tags: Creativity, Interaction Design
Posted in Design, Interaction Design
On why I started another Redesign when I had just finished one.
18 of May2009
Tired. That about sums up how I feel. The many hours I’ve spent in the wee of the morning before work. The weekends spent doing nothing but crafting this puppy, taming the beast we call WordPress.
I’m finally happy enough to launch it. So here it is. Of course I’ll be polishing the site some more over the coming months, but I’m itching to move on to other projects that have been kept waiting.
My previous design
Why a new site?
I had just finished my previous design, and was very proud of it. I showed it to my brother who just threw up all over it. At first I was just going to ignore his comments, but then I really thought deeply about what he’d said, sifted through his comments, and extrapolated what he really meant when he said certain things.
It made me realize that I had gone about the entire design process for that site completely wrong. I needed to seriously rethink my methodology. So I pondered and looked to where I could make improvements.
Goals
I thought about what the purpose of the site was and what I was trying to accomplish. Once I set my goals, I realized my current design wasn’t achieving them, primarily because I hadn’t thought very hard about what the site should do. I had just sat down and started running. I think I still came up with something pretty, but pretty isn’t always meaningful. I want design that is meaningful. That will make an impact. That will achieve results.
I don’t like it when people tell me that I’m here to “paint pretty pictures”. I solve problems. I solve business needs. I bring results. It often happens to be pretty. But pretty isn’t the goal. Effective is.
A time to think
I appreciate these times because I get to reflect on my design process and really think about what is working and what isn’t. I looked around the web. I thought hard. I tried to see what other designers were doing, and meditated some.
So I came up with a new process. It seemed to me that the designers I really respect seem to spend a lot more time thinking about their Design before they start and along the way. They can explain why made their choices. So I tried the same thing. I thought. It thought a lot more at each step of the way. I tried to have good design rationale for everything I did. Some things of course, I just did because I wanted to, but that’s part of the fun of it. I think it worked better for me. You be the judge.
In the next few weeks I’ll be talking about my new design process. I’ll be taking a look under the hood of thise and talk about what went into building it. Starting at custom built RSS feeds, Image Replacement, Grid based design and CSS etc.
Until then…
Why I chose Bluehost for cheap, reliable hosting (review)
26 of September2008
I am a web designer/developer. I need a reliable host. About 6 months ago I got fed up with my old host because of the excessive down-time I was experiencing. So I decided to look around.
I finally settled on Bluehost. Fast forward 6 months later, and I couldn’t be happier. I haven’t had a single entire day of downtime. I remember having minutes of downtime maybe once. It’s been a great experience. I’m very pleased with the additional control I get over the server too. Besides that I have access to PHP, Ruby on Rails, SSH, and lots of stuff that usually doesn’t come standard.
A list of their features (from their site):
- UNLIMITED Hosting Space (NEW!)
- UNLIMITED File Transfer (NEW!)
- web hostingHost UNLIMITED Domains!!!
- 2,500 POP/Imap Email Accounts
- SSH (Secure Shell), SSL, FTP, Stats
- CGI, Ruby (RoR), Perl, PHP, MySQL
- 2000/2002 Front Page Extensions
- Free Domain Forever!
- Free Site Builder (NEW)
- 24/7 Superb/Responsive Sales/Support
They only have 1 price. It’s not the cheapest plan, but I thought the added value was definitely worth it. Give it a try.
Tags: Hosting
Posted in Uncategorized
Break; and continue; in javascript loops
1 of July2008
Break; and continue; statements are essential when working with complex loops. They can be very useful. You can use them to end a loop prematurely, or skip the rest of the loop to start over at the beginning. Here is how you implement it:
<script type="text/javascript">
//build our array
var array1 = new Array();
array1[0] = 0;
array1[1] = 1;
array1[2] = 2;
array1[3] = 3;
array1[4] = 4;
var numArray = array1.length;
for(var i=0; i<numarray ; i++){
if (array1[i] == 2){
continue; //skip to the end of the for loop, then start over after incrementing by 1
}else if (array1[i] == 3){
break; //end the for loop, and execute code after the loop
}
alert("still in for loop: " + i);
}
alert("after for loop: " + i);
</script>
The above code should have created popups for the numbers “0″, “1″, and “3″. This is because the “continue;” statement makes the code skip to the end of the loop, not executing any of the rest of the loop code, then starts over at the beginning of the loop after incrementing i by 1.
The “break;” statement causes the loop to end and the code after the loop to be executed. i is NOT incremented anymore and thus remains at 3.
You can also use “return;” to just end a function prematurely.
Tags: JavaScript
Posted in JavaScript, Photoshop