Explode Yer Gifs
October 6th, 2011

I noticed last night that gifexplode.com is no longer a real site (some domain squatter took it, it looks like), so last night / this morning I recreated the service at gif-explode.com.  It’s a simple concept, basically it takes in as input a URL to an animated gif and then spits out each frame of the animated gif.  There’s a demo on the site if you want to see it but don’t feel like finding an animated gif.

On the tech side, I decided I wanted to try out Flask, which is a micro-webframework for Python.  I’ve never used it but it’s pretty similar to a lot of other small web frameworks.  From what I’ve garnered by using it and the examples, I don’t think it’s suited for medium to large websites, but for something as small as this it’s perfect.  Using Python allowed me to use PIL for the image processing, and while PIL usually manages to piss me off, it did a decent job here.

For hosting I tried out Heroku.  I used Heroku about 2 years ago for a Ruby on Rails project back when it was kind of a novel thing, but since then they’ve added support for a few other languages and have added a lot of new “add-on” features.  Things went pretty smoothly, deployment-wise, though it didn’t like my id_rsa.pub file and I accidentally deployed to the wrong stack, but total time from signup to completion was probably less than an hour.  Their docs are pretty good.  I have mixed feelings though about Heroku in general, because it’s very expensive for things that can be free or cheap on an EC2 instance.  I understand paying for convenience which is probably why Heroku is so popular, but I have a hard time imagining using it for anything bigger than a project like this, cost-wise.

One cool thing about this app is that it doesn’t actually save images anywhere.  Each frame is base64 encoded and then embedded in an img tag.  This makes the result page larger, but prevents the need for storage altogether and reduces HTTP requests substantially.  As a side-effect it also prevents a malicious or ignorant user from using this service as an image host.

For the last step I think I’m going to make an “Animated GIF -> base64 encoded frames” API that other people can use, perhaps move my encoding code into it’s own module.  We’ll see.

In the meantime, the site is at gif-explode.com and the source it on github.

Tweets Per Day – Chrome Extension
September 19th, 2011

One of the key factors I look at when deciding to follow someone on twitter is how often that user tweets.  If I’m not careful, it’s easy to add someone who will overwhelm my stream.  To that end I created an extension for Chrome that adds an info box (next to the other info items, such as follower count, following count, etc) with the rate at which they post new tweets.  With this add on it’s now very easy to see if someone is a “once per day” user, once per week, or “28.2 tweets per day” type.

It won’t change your life, but it only takes about 5 seconds to install and you can forget it after that.

download (Chrome Store): http://bit.ly/tweetsperday

source: https://github.com/trg/Tweets-Per-Day

 

 

 

 

 

 

 

MathJax – Pure Clientside Javascript TeX Equation Renderer
July 8th, 2011

I implimented MathJax on mathproblems.us today and so far I’m pretty impressed.  It’s worked beautifully so far and the documentation, while not the easiest to navigate, is very useful and complete.  It makes good use of hooks which were useful because it allowed me to hide the raw equation text until after it’s rendered (otherwise it flickers).

Birthday Blob – View all your Facebook Friend’s Birthdays
April 19th, 2011

Just launched BirthdayBlob.com, a silly little app.

URL: BirthdayBlob.com

From idea to minimum viable product in about 5 hours.  Have a few more ideas for it (better charts, more stats).

Cocoaism Redesign
April 24th, 2010

Just implemented the new design for for Cocoaism. Check it out if you’re so inclined. The name of the designer Nick hired escapes me at the moment but I’ll update this post when I find out.  WordPress themes turned out to be easier to write than I thought.

The New TomGraft.com
February 7th, 2010

Just wrapped up a redesign of tomgraft.com.

GreaseMonkey Script – Reddit.com: Highlight Submitter’s Posts
December 6th, 2009

I’m a redditor and one thing that I’ve always wanted to do is have a way for the submitter’s posts to be more prominent.  So I whipped up a quick GM script to do just that.  This is the result:

Click to Enlarge

Submitter's posts are now in a light blue box.

Certainly nothing spectacular but it’s pretty trivial to change the CSS to your liking or extent this script to do other things to the submitter’s posts.

gm_reddit_submitter_css @ github

See the New Google.com
November 27th, 2009

1. Go to Google.

2. Copy/paste this in to your address bar and hit enter:

javascript:void(document.cookie="PREF=ID=20b6e4c2f44943bb:U=4bf292d46faad806:TM=1249677602:LM=1257919388:S=odm0Ys-53ZueXfZG;path=/; domain=.google.com");

3. Refresh the page.

Don’t forget to check around to other Google properties (Google News, Video, etc) as many of them also received significant updates as well.

Fix for: iPhone Safari Resizes Some Text But Not Others
November 18th, 2009

This is largely “for my own benefit” since I come across this problem every time I make a smartphone site:  iPhone Safari freaks out when you rotate the phone from portrait to landscape.  By that I mean it will make some text bigger but not others, throw some text off the screen, and generally make a formerly pretty page look like garbage.

The reason, it turns out, is that the iPhone Safari browser is trying to “help” users out by making the text bigger.

Without further ado, how to fix this. Add the following in your CSS:

body { -webkit-text-size-adjust: none; }

Of course, if you do want this functionality, you can add that CSS attribute to specific divs or whatever parts of your site you want.

Recent Incoming Searches:

  • make text bigger iphone safari
The Google Logo is a Barcode Today
October 7th, 2009

Google’s logo is a barcode today. Check out their other logos here.

Be your own DJ with Finetune Live
October 6th, 2009

Finetune has launched a new “streaming DJ” service, Finetune Live.  I’ll let the site speak for itself, but basically the service allows you to broadcast what you are currently listening to on iTunes, and anyone viewing your profile on Finetune Live can tune in to your stream.  It’s still in beta (I think?), but has worked for me with no problems.

In the past I’ve streamed music via running an icecast server, but Finetune Live brings the same basic streaming idea to a more user-friendly, high-discoverability medium.  It will be interesting to see where this goes, as I can imagine this sort of product would be very attractive to Facebook users, MySpace users, bloggers, and other self-promoters.

Automatically Respond to Twitter Messages in Python
August 6th, 2009

Matt Warren has come up with a very elegant script to automatically tweet back to anyone who mentions certain keywords.  Check it out here.

Google Map API (with a tiny tutorial)
April 22nd, 2009

The Google Map API is excellent, I’ve been using it on a recent project.

Google Map

To get something that looks like the above image, get a Google Map API key, include the relevant Google API Javascript files, and add:

map = new GMap2(document.getElementById('classroom_map'));
map.setUIToDefault();
map.setCenter(new GLatLng(42.3337872, -71.0958314), 10);
marker = new GMarker(new GLatLng(40.6101, -79.9669));
marker.bindInfoWindowHtml("HTML GOES HERE");
map.addOverlay(marker);

Breakdown:

map = new GMap2(document.getElementById('classroom_map'))

Creates a GMap2 object in the div with the id ‘classroom_map’.  Elsewhere on the page, we would have an empty div with the id ‘classroom_map’ and whatever CSS we want our Google Map to have.


map.setUIToDefault();

Sets the various default widgets (Zoom, Map Type) to their default positions.


map.setCenter(new GLatLng(42.3337872, -71.0958314), 10);

The GLatLng object is first created with the lat and lng values shown. The map.setCenter() method takes in this GLatLng object, along with a zoom level (10). So this step centers our GMap at the above coords and zoom level.


marker = new GMarker(new GLatLng(40.6101, -79.9669));

Using GLatLng again, we create a GMarker object called ‘marker’. GMarkers are the little red arrows that you can click on Google Maps. This step creates the marker object but does not display it. We won’t want to display it yet because first we’ll want to bind the tooltip shown in the example picture.


marker.bindInfoWindowHtml("HTML GOES HERE");

This step adds the HTML that is displayed in the tooltip. “bindInfoWindowHtml(the_html)” basically says “When the user clicks this marker, show a tooltip with ‘the_html’ as the content of the tooltip.”


map.addOverlay(marker);

This step adds the marker to the map.


And that’s pretty much it!  I didn’t show any of the advanced features of the Google Map API but with only a few lines you can have a functional map with tooltips.

Python Port Scanner in 3 Lines
April 17th, 2009

Just wanted to see how few lines I could do it in.  If you don’t include the ‘includes’ or the ‘except:pass’, it’s really only two lines.

#!/usr/bin/python
 
import sys
from socket import *
 
for port in range(int(sys.argv[2].split('-')[0]), int(sys.argv[2].split('-')[1])+1):
    try:socket(AF_INET, SOCK_STREAM).connect((sys.argv[1], port)); print "Able to connect to port:", port
    except: pass

Usage: <filename> <host> <ports>
So for example if you saved this as pyscanner.py, and chmod +x it, you could do:

./pyscanner.py localhost 1-1024

to scan the priviledged ports on your local box.

If it isn’t obvious from the code, it does not support IPv6 addresses and determines of a port is connectable via a standard TCP connect().

History of the Internet
April 17th, 2009