Selecting Child Entities with GQL Queries

In Google App Engine, you can create owned one-to-many relationships between entities. The classic example you were taught at uni is that a Book owns a Chapter, which in turn, owns a Paragraph. For my site, stolencamerafinder, the example is that a camera Make owns a set of Models.

If you want to query for the model directly in GQL (from the app engine dashboard for example) you can create the key by specifying the full parent chain:

SELECT * FROM Model where __key__ = KEY('Make', 'canon', 'Model', 'canon eos 5d')

Google’s GQL reference was a little sparse on this syntax so I’m posting it here in the hope you find this faster than I worked it out.

For completeness, this is the difference it makes in JDO. My old code looked something like this:

PersistenceManager pm = PMF.get().getPersistenceManager();
Key makeKey = KeyFactory.createKey(Make.class.getSimpleName(), makeName);
Make make = pm.getObjectById(Make.class, key);
List<Model> models = make.getModels();

for (Model model : models) {
    if (model.getName().equals(modelName)) {
        return model;
    }
}

It doesn’t take much imagination to realise this doesn’t scale very nicely as the number of models increases. The new code looks like this:

PersistenceManager pm = PMF.get().getPersistenceManager();
Key makeKey = KeyFactory.createKey(Make.class.getSimpleName(), makeName);
// Can create the Model key by specifying parent key...
Key modelKey = KeyFactory.createKey(makeKey, Model.class.getSimpleName(), name);
// Bam! Get the child entity in a single query
Model model = pm.getObjectById(Model.class, modelKey);

I wouldn’t have noticed this performance bottle neck if it wasn’t for appwrench. It looks a little dead to be honest, but works well.

Tips for better low-light wedding photos with an Canon DSLR.

I just got this in an email:

A friend has asked me to take some of their wedding photos with their Canon 1000D. Had a play with it yesterday and I’m finding the flash a bit harsh. Is there a top tip to minimise this?

Firstly, if you’re using the camera in the day near natural light, the camera will be fine and it’s all down to your artistic flair.

For evening shots, I’ve written a bunch of tips, but really, there is only one:

  • Borrow a Canon Speedlite that supports ETTL. (eg, the 430EXii or 580EXii).

Seriously. If you know someone into their photography that may have one you can borrow, give them a ring. Slap it on the camera, press “mode” until it says “ETTL” on the screen, aim the flash so the light bounces of a wall/ceiling to your subject (pool skills handy here) and snap away. The rest of the tips may help prevent you taking a load of unusable shots, but if you get a speedlite, you will take the best shots of the whole day (perhaps including the photographer’s).

If you can’t get a speedlite, my next-best advice is to wait for the sun to come up or get your subject under some other light source. On-camera flash is ugly, and unflattering. I have a top-end Canon and I never use the on-camera flash on people because they’ll just look sweaty and wrinkly. If you can get people next to a lamp or something, you’ll have much more luck.

If neither of those tips will help you, here are what I consider to be “last resort” tips:

  • Prop camera against wall or on table for a steadier shot.
  • Try self timer with camera on table.
  • Form triangles with your body (tuck elbows in to sides) to become human tripod. Remember to look like a pro by cupping the lens with left hand palm upwards.

Anti-tips! Don’t do this:

  • Raise the ISO above 800. Ideally, keep the ISO at 400 or lower unless you like grainy photos.
  • Stick a Rizla to the flash. It will not soften the light, it just drinks the battery.

Keeping the camera steady will mean sharper shots, but if your subjects move, you’ll still get blurry shots. But I say go with it. Asking people to stay still means awkward faces. A blurry shot of someone laughing / dancing is a good thing if it’s deliberate.

My favourite wedding photos are always in the evening when people are relaxed (read: drunk). I’m sure you’ll capture some gems.

How to update the lastmod date in your sitemap xml with Ant

Hmm, you want to add the “lastmod” node, but you’re too lazy to ever keep that up to date so you decide to update it with your Ant script whenever you deploy. Easy.

So you’ve just written a valid sitemap.xml file for your website because Google said it was a good idea. Great.

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url>
      <loc>http://www.stolencamerafinder.com/</loc>
      <lastmod>2011-04-21</lastmod>
      <changefreq>weekly</changefreq>
   </url>
</urlset>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url>
      <loc>http://www.stolencamerafinder.com/</loc>
      <lastmod>2011-04-21</lastmod>
      <changefreq>weekly</changefreq>
   </url>
</urlset>

First, you’ll need the jar for a third-party Ant task called XMLTask. Once you have that, the ant target you’ll need is simply:

1
2
3
4
5
6
7
8
9
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask" classpath="test-lib/xmltask.jar"/>
<target name="update-sitemap" description="update the update date">
    <tstamp>
        <format property="today" pattern="yyyy-MM-dd" locale="en,UK"/>
    </tstamp>
    <xmltask source="war/sitemap.xml" dest="war/sitemap.xml" standalone="yes" report="true">
        <replace path="/:urlset/:url/:lastmod/text()" withText="${today}"/>
    </xmltask>
</target>
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask" classpath="test-lib/xmltask.jar"/>
<target name="update-sitemap" description="update the update date">
	<tstamp>
	    <format property="today" pattern="yyyy-MM-dd" locale="en,UK"/>
	</tstamp>
    <xmltask source="war/sitemap.xml" dest="war/sitemap.xml" standalone="yes" report="true">
        <replace path="/:urlset/:url/:lastmod/text()" withText="${today}"/>
    </xmltask>
</target>

Yeah yeah, this is kid’s stuff, why blog about it? Well, embarrassingly, it took me 3 hours of messing around to get it working. If I don’t write it down somewhere, I’ll only forget the next time I need to do this. Sigh.

How to detect browser support for File Api and drag and drop with javascript

Here’s a bit of info for you crazy HTML5 kids. You’ll need to include the handy Modernizr script for it to work.

var browserIsSupported = !!window.FileReader && Modernizr.draganddrop;
If you want see it in action, just visit stolencamerafinder ;)
I’ve tested this in Firefox 3.6, Chrome 10, IE8, Safari 5 and Opera 11. The only browsers from that list to support FileReader from the File API and the drag and drop events are FF and Chrome.
Let’s hope the other catch up soon…

How to stop Google Chrome using your location when searching

When you use Chrome’s omnibar to search, Chrome will redirect you to search results based on when you are geographically. This is great when I’m at home because I see (more relevant) results from google.co.uk and not google.com.

However, I’m travelling at the moment and getting my results from google.co.th is painful since most of the results are not in english.

  1. Close Chrome.
  2. Open the file “Local State” in notepad. Mine was in: C:\Users\matt\AppData\Local\Google\Chrome\User Data\Local State. Linux users may find it in ~/.config/google-chrome/ or ~/.config/chromium/, and OS X users can try ~/Library/Application Support/Google/Chrome.
  3. Look for “last_known_google_url” and “last_prompted_google_url” and change their values to the local Google page of your choice.
  4. Save and close.
  5. Done.
You may find other pages telling you to hardcode the url in the Chrome options page when you “manage search engines”. This works to an extent but breaks other things like suggest.

Thanks to Siavash for originally posting this.

Challenge Conclusion…

Back in April I challenged myself to run 5km in under 19 minutes and gain 1.5 stone by the last Bridge Inn 5km of the summer.

Tonight was the night.

Being too busy disorganised, I didn’t realise that tonight was the deadline until today. If I had realised I would probably have prepared a little better. Two days ago I ran my first Kymin Dash, a ~7 mile run but includes a decent hill. Four days ago I ran in a 10km race between local clubs and broke 40 minutes for the first time.

Unsurprisingly, I didn’t have the highest hopes before tonights race, my legs were tight and still a bit sore. I got chatting with another runner at the start line and we exchanged excuses as to why we weren’t going to do very well (an unwritten custom). I was mid-sentence when the whistle blew.

Woah! Quick! Start the watch and run!

Maybe it was being caught off-guard, but I shot off without any time to get nervous and build thoughts of self-doubt. I reached the half-way point, and glanced at my watch. I was on target. I was better than on target, I was going too fast. It didn’t matter though, I felt good. I dug in for the return to the finished line. Although the course is a simple 2.5km out, then 2.5km back, I’m pretty sure that the return leg is longer ;)

I can see the finish in the distance now, another look at my watch, 17 minutes. 2 minutes left if I’m to hit my target. The finish looks far away and although I’m running as fast as I can, I know I’ve slowed down. I pick out a road sign ahead that I think is half way between me and the end. I tell myself, “If I can reach that in 1 minute, then I can do it”. 1 minute and 15 seconds later I run past the sign. Damn. “Forget that, it probably wasn’t half way”, my legs are burning, “it’s only another 45 seconds, just sprint like mad!” I fly over the finish line and tap my watch. It takes me a second or two before I’m physically able to look at the watch because my arms are still flailing around trying to slow down. 18:58. Whoop! I punch the air like I’ve just won the thing as other runners who finished earlier clap slowly and politely.

So, I hit my target with 2 seconds to spare. Well done me. That’s that then. Thanks for reading. Bye.

Ahem. Oh. You’re still here. “What about the weight thing?”. Erm, yeah, well, I kinda focussed more on the running. I just weighed myself and I’m exactly the same as when I started.

Yeah, I failed the challenge really, but I don’t care. It was great fun and with my fresh personal bests I’m buzzing!

Challenge Update

At the end of April I set myself the challenge of gaining a stone in weight and running a 5km race 2.5 minutes faster.

I ran the same race on Tuesday in 19:15, painfully close to my speed target of 19 minutes. However, I also weighed myself again but have actually lost a pound.

Gah!

Must try harder…

Solved: How to rotate with GWTCanvas

Having trouble rotating something you’ve drawn with GWTCanvas?

It took me a little while to work out, but GWTCanvas works slightly differently to Graphic2D in Java. It’s important to realise that with GWTCanvas, when you invoke “rotate(r)” you’re actually transforming the coordinate space that will be used for subsequent drawing.

canvas.moveTo(50, 50);
canvas.lineTo(50, 10);

canvas.stroke();

Produces:

In order to rotate it, you must invoke rotate before you start any drawing.
canvas.translate(50, 50);
canvas.rotate(Math.toRadians(45));
canvas.translate(-50, -50);

canvas.moveTo(50, 50);
canvas.lineTo(50, 10);

canvas.stroke();

Tadaa!

The same is also true for other transformation methods such as “scale” and “translate”.

Inspired

My First Stranger.

Yesterday, I attended a workshop hosted by the talented Lou O’Bedlam. Although I wasn’t fully aware of it at the time, I was getting inspired. Not only was I getting inspired to take more picutres, I was getting inspired to focus on stepping out of my comfort zone and going after my dreams.

Lou talked about recently teaching his nephew how to ask a girl out. His advice was simple: “Just ask her”. His nephew replied, “But then what would I say?”. “Woah!, that’s phase 2, don’t worry about that. Focus on phase 1: Asking her”.

The analogy was straight forward enough and was advice for us as photographers if we want to take pictures of the strangers we meet in the street. The worst that can happen is they can say no.

I took my camera to work today determined I would simply take pictures of all the interesting people I met. Throughout the day I saw several ideal candidates. But I can’t ask her, she has headphones on. She’s walking too fast, must be in a rush. The light’s not right. He doesn’t look friendly. She’s too tall, I’d have to climb something to get the right angle, but she’ll think I’m just trying to take a picture of her boobs… My brain found an excuse in an instant for all of them. The truth was that I was a big scared wimp.

I went out again, on my own this evening to walk around the harbour specifically to see if I could pluck up the courage to ask someone if I could take their portrait. All too soon, my opportunities were missed and the sun had set so I headed home dragging my heels. On the way however I saw a girl with an amazing look and I went for it so spontaneously that I surprised myself.

“Hi!”

She looks startled. I mean, very startled. It’s quite late and there are only one or two other people around. I panic a little and start to blurt out my words at record pace (the opposite of Lou’s advice):

“Erm, I know this is a bit random, but you have a really pretty and interesting face, do you mind if  take your picture?”

She’s still startled, perhaps so much so she can’t think of a better answer:

“Um, yeah, ok”

What? She said yes. Christ, now I’m gonna have to take this thing, where’s the light? It’s about 9:45pm and getting dark. I don’t want to use flash. I slap the camera on aperture priority to f/1.8 and cross my fingers.

-Click-

Blurry, damn.

I glance up and can see she wants to leave. She heard a click and I only asked for a photo. I can’t remember what I then said, some mumbling nonsense about grain and ISO settings probably. I quickly knock the ISO up to 800.

-Click-

I eyeball the screen, blurry? Probably. Good enough? Yes!

“Thanks so much for letting me take them. I can see I’m freaking you out a bit so I’m just gonna go the long way home over this way so you don’t think I’m following you. Er.. thanks again.”

I start to scuttle off, feeling awful for scaring the poor girl then hear a feint “Cheers”. Maybe she’s just a little shocked, but flattered. I wanted to give her my card so she could at least choose to email me if she wanted to see the photos but I forgot. I didn’t even tell her my name, or ask her hers. The whole thing was a nightmare display of clumsy social awkwardness that would make any observer cringe. Did I step out of my comfort zone? Yes. Did I learn about 50 things in as many seconds? Yes. None of that matters, that’s just perfecting phase 2. I’ll work on that tomorrow…