I wrote this a while ago, recently ported it to run on GitHub Pages: http://mustpax.github.com/Truth-Table-Generator/
I'm Mustafa Paksoy and I write code for a living. I post assorted items of interest here. You can contact me via email.
I also take pictures, dabble in Twitter and occasionally put projects on GitHub.
Netflix just announced that they are spinning off their DVD-rental-by-mail service under a new brand Qwikster while the streaming service retains the Netflix name. Many commentators have duly noted Netflix’s boldness in leaving its cash cow behind and looking to the future, a true example of a company facing up to the Innovator’s Dilemma.
However, this latest change serves a purpose beyond merely signaling Netflix’s future direction to customers and investors. Namely, Netflix is setting itself up to offer premium pricing options for its streaming product. The company has already been burnt by customer confusion stemming from its most recent pricing changes. Netflix knows it needs to clearly delineate the two product offerings to be able to say “pay another $10 a month to watch all Fox shows” without customers wondering they will still be able to rent Family Guy Season 3 DVDs by mail.
At $10 a month unlimited streaming is a great deal. The cable plans that that Netflix’s service replaces run around $40-50 which means there’s a lot of consumer surplus Netflix can absorb to widens its product offering. As evidenced by the latest Starz loss, Netflix needs to make more compelling bids for streaming rights and offering premium streaming packages is the key to that. I for one can’t wait.
— Joshua Schachter on Hacker News
Not everything runs the same on production as it does on localhost so you need a staging environment to vet changes before making them public.
When developing Piazza (on GitHub) we put together a simple workflow to manage production and staging deployments. Our app is built on the Heroku Cedar stack with Java and the Play framework but this workflow should be applicable to all other apps on Heroku.
Git branches
We need Git branches to track what we have on Heroku. We will be pushing these back to our central repository origin (GitHub in our case) to facilitate easier collaboration.
git checkout -b prod
git checkout -b staging
git push origin prod
git push origin staging
Heroku setup
You will need two different Heroku applications, one for staging and one for production. If you’re starting from scratch you can create these applications and attach them to the right Git remote repository.
heroku create --stack cedar --remote prod
heroku create --stack cedar --remote staging
If you already have a Heroku app under the Git remote heroku you can rename it and create a new app for staging.
git remote rename heroku prod
heroku create --stack cedar --remote staging
make me a sandwich
Create a file in your project root named makefile (with the lowercase m). We will create two make targets in this file which are basically project specific shortcuts. There’s a lot more you can do with make but we’re sticking to basics. Our two make targets look like this:
make stage will now deploy the contents of the staging branch to the appropriate Heroku app followed by GitHub. make deploy will do the same with the prod branch. You will have to merge changes from master into these branches yourself like so:
git checkout staging
git merge master
make stage
Bonus: Keeping branches clean
Since you have to update the staging and prod branches manually it is good to put in some safety measures to prevent bad deployments. For our part, we require the Git branch to be clean. A simple Bash script can check Git to see if there are any uncommitted changes and abort the make target
The new make targets should look like
Now if you try to make stage with a dirty repo the deployment will be aborted.
$ git checkout prod
Switched to branch 'prod'
$ touch newfile
$ make deploy
There are uncommitted changes.
make: *** [deploy] Error 1
Appendix
From “Go the F*** to Sleep not funny”
“She has good reason to be concerned about the message behind such a parody. Demarest was the prosecuting attorney in one of Oregon’s most high-profile child murder cases. […] Nobody is suggesting that there’s a connection between Adam Mansbach’s book and child abuse or child neglect.”
Dear CNN op-ed author, I believe you’ve made that very suggestion.
Just today I was thinking about how annoying it is that Facebook redirects all outgoing links to an internal page. They do this to mitigate the spread of clickjacking worms and whatnot but I like to think I’m smart enough to not click a post titled “I can’t believe she isnt werring a bra LOL WORM!!” So I figured I’d write a quick greasmonkey script to switch the links back to their pristine form. Well, I didn’t exactly get around to writing the script but I discovered something nifty instead.
Take the following innocuous link to a humorous imgur image a friend posted on my wall:
<a href="http://i.imgur.com/7XSdO.jpg" target="_blank" rel="nofollow"
onmousedown="UntrustedLink.bootstrap($(this), "SNIP", event, bagof(null));">
http://i.imgur.com/7XSdO.jpg
</a>
The link target (href) is not rewritten on the server so the click must be getting intercepted via JavaScript. But you can’t preventDefault for a click via onmousedown, you have to catch the onclick event instead. Here’s what UntrustedLink looks like once beautified:
function UntrustedLink(a, d, b, c) {
this.dom = a;
this.url = a.href;
this.hash = d;
this.func_get_params = c ||
function () {
return {};
};
Event.listen(this.dom, 'click', this.onclick.bind(this));
Event.listen(this.dom, 'mousedown', this.onmousedown.bind(this));
Event.listen(this.dom, 'mouseup', this.onmouseup.bind(this));
Event.listen(this.dom, 'mouseout', this.onmouseout.bind(this));
this.onmousedown($E(b));
}
Facebook is adding onclick handlers to links right before the click happens. No wasting time with pesky onload initializations, links are self-initializing! Pretty neat.
-
Using Dropbox as a Git repository
So last month I wrote a bit about setting up your own personal Git repositories on a Linux box, and how to use...
-
Me: “Alright, I want you to go ahead and drag that file to your desktop.”
Client: “Pff. I don’t have a desktop, I have a laptop!” -
“If a worker labors under the threat of force or of need, or a student produces on demand, we may admire what they do, but despise what they are.”
-
How To Tell if Different Kinds Of Fruit Are Ripe
It seems like everyone these days has some kind of quick tip for gauging the ripeness of fruit.
Still, billions of shoppers every day find themselves in the produce aisle, ears pressed to cassava melons, grinning like idiots.
-
Client: “I need your agency to develop a robust morale-boosting program for the top 100 ‘leaders’ in our region during our annual team building...
-
EZ-Laminator450 Users Manual: Frequently Asked Questions
FAQ
Is this the same type of laminator they have at high schools?
Yes! Your I.D. card...
-
What’s this? Oh, just some stuff my bank thinks I should put on my checks.
-
“For this invention will encourage forgetfulness in the minds that use it because they will not practice their memory. Their trust in writing,...”
