Archive for December 2009

31

December 2009

Serving Different Ads/Content Based on a Users Location (Geo-Targeting)

You probably haven't noticed, but this blog serves up different ads depending on where you're visiting from. Or at least, it'll serve Amazon UK ads if you're near the UK, and Amazon US ads otherwise. Serving up US ads to UK visitors (and vice versa) is pretty pointless, and I've always tried to avoid showing any ads unless they're relevant and at least targeted to the right country.

There are a number of ways to determine where your visitors are coming from, so I spent some time yesterday trying to find the most reliable way (and preferably one that didn't involve having a huge IP database sat alongside my site!). After much hacking and testing, I found what I believe to be the best way. Google.

Google has a JavaScript loader API, which allows developers to load JavaScript libraries from Google with various benefits. That's not really what we're interested in though, it has something more exciting:

google.loader.ClientLocation

It appears that you do not need an API key to use the JavaScript loader, you can simply reference it at http://www.google.com/jsapi. If you look at the JavaScript served up (which is incredibly fast), you'll see something like this:

google.loader.ClientLocation = { "latitude":50.123, "longitude":-2.876, "address": { "city":"Liverpool", "region":"Merseyside", "country":"United Kingdom", "country_code":"GB" } };

Not only do you get the country, but you get the county, city and even lat/lon pair. For me, the location given was within 2-3 miles of where I live, so if you wanted, you could really localise your ads!

On this site, the country is just sent to a script that will serve up some ads based on keywords I've tagged against a post. You might wish to be a bit more exciting and show your users places or people nearby. This could be especially useful for mobile applications/sites, though be sure to read any associated terms and conditions before using it!

31

December 2009

Google Wave Notifier Now in 15 Languages!

When I started writing Google Wave Notifier last month, it was really only for my own use. I wouldn't use Google Wave if I had no way of knowing when I had messages (and keeping a browser open is not an acceptable solution!) so I hacked something together to login to Wave and parse the JavaScript objects.

A screenshot of Google Wave Notifier in action!

I decided others might benefit from the app, so I cleaned it up a little, gave it an icon and published it on the web. I had no idea that it would get close to 10,000 downloads in little over a month! Nor did I expect so many people to send in translations!

So here we are 6 weeks down the line, and the app has been translated into 15 different languages!

  • English
  • Czech
  • Danish
  • Dutch
  • French
  • German
  • Hungarian
  • Italian
  • Polish
  • Portuguese
  • Romanian
  • Russian
  • Spanish
  • Swedish
  • Turkish

So I'd like to say thanks to everyone that's helped; using, translating and finding bugs in the app. What was a small script written for personal use has turned into something quite useful!

For more information or to download, see the Google Wave Notifier website!

30

December 2009

Redirecting Requests from appid.appspot.com to a Custom Domain

If you're running your app engine project on a custom domain (like this blog), you're probably not so happy that people can still access your app at http://appid.appspot.com.

When I started working on my blog, I realised this might be an issue, and did some investigating into how I could stop it. I found solution on SackOverflow that seemed to do what I needed, so I set it up and got it working.

Not long after implementing this code, I found a few problems:

  • SSL is not supported on custom domains
  • Cron jobs fail when Google invokes them with an appspot.com address and you serve a 301

So with some tweaks, I've managed to get this working as required. The only annoyance is the hard-coded '/admin' check. This is to support cron jobs, task queues etc., which are all protected ("login: admin" in app.yaml). They must work with an appspot.com address, because Google doesn't seem to follow the redirect when invoking them. It's possible you could do an IP address check here, but I'm not sure how consistent cron/task queue IP addresses are.

The code is called like this:

def main():
    dantup.run_app([
        ("/\d*", RootHandler),
        ("/feed", FeedHandler),
        ("/tags/.*", TagHandler),
        ("/archive/.*", ArchiveHandler),
        ("/.*", PostHandler)
    ])

And dantup.py looks like this:

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

def run_app(url_mapping):
    application = webapp.WSGIApplication(url_mapping, debug=True)
    application = redirect_from_appspot(application)
    run_wsgi_app(application)

def redirect_from_appspot(wsgi_app):
    """Handle redirect to my domain if called from appspot (and not SSL)"""
    from_server = "dantup-blog.appspot.com"
    to_server = "blog.dantup.me.uk"

    def redirect_if_needed(env, start_response):
	
        # If we're calling on the appspot address, and we're not SSL (SSL only works on appspot)
        if env["HTTP_HOST"].endswith(from_server) and env["HTTPS"] == "off":
		
            # Parse the URL
            import webob, urlparse
            request = webob.Request(env)
            scheme, netloc, path, query, fragment = urlparse.urlsplit(request.url)
            url = urlparse.urlunsplit([scheme, to_server, path, query, fragment])
			
            # Exclude /admin calls, since they're used by Cron, TaskQueues and will fail if they return a redirect
            if not path.startswith('/admin'):
                # Send redirect
                start_response("301 Moved Permanently", [("Location", url)])
                return ["301 Moved Peramanently", "Click Here %s" % url]
	
        # Else, we return normally
        return wsgi_app(env, start_response)

    return redirect_if_needed

Hopefully you may find this useful. If you encounter any problems with it, please let me know!

29

December 2009

1-2-3-Testing. Is This Thing On? New Blog!

There's nothing like testing a system after it's gone live!

After lots of frantic hacking over the last few weeks, the blog engine I've been writing for Google App Engine is up and running. It's not complete, but the important things (frontend, feed, posting, etc.) are done so it's at least usable.

Apologies if you just got a flood of old messages in your feed reader. I did investigate keeping the Blogger IDs to avoid this, but it seemed more hassle than it was worth, so I'll forgive you for clicking "Mark All as Read" this one time ;-)

I'll post more info (and code) on the blog as I get time, but now I'm off to sort some food out after a hard day's hacking!

If you notice anything messed up in the transition, please do let me know!

24

December 2009

From .NET to Python on App Engine: Building a Blog on Google App Engine

Over the past few weeks I've been playing with Google App Engine. I find the best way to learn a new language/framework/platform is to just jump in and write something in/on it. So that's what I'm doing. I've decided to write my blog in Python for Google App Engine.

As I may have blogged about in the past, I wrote a blog engine in Microsoft ASP.NET MVC not so long ago with the aim of moving away from Blogger. It was around 90% complete when I abandoned it for a variety of reasons (one being Azure pricing).

It's entirely possible the Google App Engine blog engine will also be abandoned, but since the hosting is free it at least stands a good chance of seeing the light of day! It'll also make an interesting comparison to the ASP.NET MVC version.

I started writing code a few nights ago, and currently the blog stands at 159 non-blank lines. I'm actually quite impressed with how little code I've had to write to get up and running. Currently there's no back-end, but the displaying of posts, comments, tags and archives are all working. Here's a quick screenshot to prove it exists! :)

A screenshot of how the App Engine blog currently looks

Over the coming weeks I'll blog about how I've built it (including code), the pitfalls and the the experience of moving from .NET and C# to Python and App Engine!

« Older posts