Windows XP Sleep Criteria

Posted on 01 February 2013 by Joseph

Working today to debug a problem with Granola that had been reported by a couple of different users, I got the opportunity yet again to get down and dirty with Windows XP power management.aspx#pmfunctionsxpandearlier). Windows APIs in general can range from robust and well-documented to quirky and confusing. Power management definitely falls into the latter category. It is a less-used API, which means that there are few forums online discussing anything but the most straightforward uses. Add to that the fact that most of the functionality was brand new in XP and was completely rewritten for Vista and you have a set of functions that can be difficult to use and understand, top to bottom. It’s almost as if Microsoft never intended for this API to be used.

The problem I tackled today (and attempted to tackle several other times this week) seemed straightforward: some users were reporting that running Granola disabled or made erratic their screensaver coming on, monitor powering down, and computer going to sleep. My first thought was that Granola wasn’t updating the internal view of the power scheme as the user changed it, but no, that worked fine. My second thought was that perhaps the I/O of logging and communicating over named pipes was causing the machine to stay awake, but that wasn’t it either. I tried one thing after another, only to be shut down again and again.

Windows uses a fairly sophisticated set of criteria.aspx) for determining an appropriate time to put the monitor and system to sleep. According to the documentation, “[a]s long as the system determines that there is user or application activity, it will not enter sleep.” That encompasses the obvious: user interaction is keyboard and mouse activity, application activity is processor utilization, memory activity, or I/O such as network activity. I checked all of these things in turn, only to find that none of them applied. I was obviously not touching the mouse or keyboard; the application itself uses almost no processor, memory, disk, or network. So what was going on?

I’ll cut the story short here. Calls to the power management API were being considered user interaction. The issue causing my confusion was actually twofold: first, these sleep criteria are not really as clear as they seem; second, the power management API was never really intended to be used like Granola uses it. I’ll speak to the first issue later, but as to the second, clearly the developers of Windows XP thought that only users would be changing the power settings. How they thought the user could be changing them without using the keyboard or mouse is an even more interesting question; perhaps these settings are intrinsically linked to the same structures that monitor user interaction with the console.

Finally, I’d reached the end of the road. I uploaded a new version of the software that eliminated the power management functionality and indeed the monitor shut down. I waited 2 minutes more for the system to sleep, but no luck. I continued to wait, and the system never slept. Exit the application, and the system sleeps. Start it up again and the system becomes the computer version of New York. Oh noes! Not again!!

To cut the story short again: the system would not sleep while running unvetted software. “Unvetted software” in this instance meant software that hadn’t been installed by the Windows installer. In Windows XP and later versions of Windows, running software that wasn’t put on the system by an installer produces a UI alert asking the user if it is OK to run the software even if the software was signed by a valid signature. Allowing the software to run apparently puts the system into such a state that it cannot sleep, even though it CAN power down the monitor. This is well outside of the documented interface.

And this is the murkiness of the criteria that I was speaking of earlier. Again, “[a]s long as the system determines that there is user or application activity, it will not enter sleep.” HOW the system determines this is what is unclear. With a closed-source system like Windows, this statement isn’t really helpful from an API-specification standpoint. It may as well say “the system makes an arbitrary decisions that you as an application developer can’t know about.” Ultimately, the power management API as it existed in XP was never intended to be used beyond its basic functionality. Why else would the specification be so unclear and sparse in detail?

SSH Tunneling and Apache vhosts

Posted on 03 January 2013 by Joseph

For better or worse, our web development workflow begins on in-house servers that are the same software stack as our development webservers, particularly for new features that may change the data model. I’m currently working on a new feature for the new-and-improved Granola Enterprise that adds interesting and actionable aggregate data at the group and installation level, a perfect feature to work on in our cloistered environment. Each developer maintains their own Apache name-based virtual host to track their feature branch and any different data they need to track.

Today, I’m taking a cross-country flight to California to set up a case study of the new energy footprint generation capabilities of Granola Enterprise. The flight is long (>5 hours) and has the double advantage of both plenty of room (seat next to me is empty) and in-flight Internets, so I figured I’d get some work done. Getting to the development environment is a piece of cake: we have an Internet-facing ssh server. Setting things up so I can load my vhost in a browser is slightly more complicated, but is ultimately pretty easy using ssh port forwarding.

For a single-host Apache instance, it is really, really easy. Just ssh into your server and forward a local port to port 80 on the internal development machine. If your ssh server is ssh.example.com, your username is example, and your internal development machine is developmentmachine, you could forward local port 8800 like this:

ssh -L 8800:developmentmachine:80 example@ssh.example.com

To get to your webpage, then, just go to http://localhost:8800 in your browser. Simple. It can be even simpler if you forward local port 80 instead of a non-privileged port, but in that case you need to run the command as root (or with sudo).

With virtual hosts, it’s only a bit tricker. Name-based virtual hosts work by looking at the hostname in the HTTP headers, so that information must be right to wind up in the right place. The solution is to give your own machine the same name as your target vhost in your /etc/hosts file. Using the example above, you’d add this line:

127.0.0.1   developmentmachine

Now, instead of going to localhost in your browser, go to the normal name of your development vhost (http://developmentmachine:8800), and tada! you’re in. Bonus points: if you use port 80 (again as root) all your bookmarks work.

Now to do some real work instead of writing blog posts! :)

Select discontinuous items or ranges from a Python list

Posted on 02 January 2013 by Joseph

If you need to select several discontinuous items (and/or ranges) from a Python list, you can use the operator module’s itemgetter second-order function. In the realm of lists, it accepts arguments as either integers or slice objects and returns a function object that when called on a list returns the elements specified.

What? Like this:

>>> from operator import itemgetter
>>> get_items = itemgetter(1, 4, 6, slice(8, 12))
>>> get_items
<operator.itemgetter object at 0x02160D70>
>>> get_items(range(20))
(1, 4, 6, [8, 9, 10, 11])

I’ll leave it as an exercise to the reader to figure out how to flatten the resulting tuple. If it proves challenging, I’d suggest trying some or all of the 99 Prolog Problems (but a list ain’t one?), in Python of course :)

Recipe: Tag Photos With Facebook Graph API

Posted on 01 January 2013 by Joseph

The Facebook Graph API presents a powerful, unified view of the myriad resources made available by Facebook. There is only one problem: documentation, particularly for accessing resources from the different SDKs, is lacking. In designing my little Facebook new-profile-creating toy, PRO!(de)file, I came across several fuzzy places in the documentation that I had to clear up with Google, some time spent reading the SDK code, and good ol’ trial and error. Of particular difficulty was tagging uploaded photos, which is a core requirement of PRO!(de)file.

Uploading from the Facebook PHP SDK

There is a published SDK for PHP made available (or at least linked to!) by Facebook. It is basically a handy wrapper for libcurl. Browsing through the source for the SDK and the Graph API documentation for Photos, I managed to work out how to upload photos. Naturally, the photos must first be on the server side, since it wouldn’t do to have PHP magicking them straight off of your hard drive. How to get them there is left as an exercise for the reader. Also left to the reader is how to register your Facebook application and get an application ID (hint: it’s very easy).

All Facebook transactions, whether client-side or server-side, begin with one of the several methods for application authentication. The documentation on auth is pretty good on the Facebook site, though it is spread out over several unlinked pages. After auth, the user has a cookie containing information about the session and the available permissions requested at auth time. Note that in order to publish anything, including photos, you must request the publish_stream permission when authenticating. Creating the Facebook PHP object and getting the session is then very simple:

$fb = new Facebook(array(
    'appId' => 'YOUR_APP_ID',
    'secret' => 'YOUR_APP_SECRET',
    'cookie' => true,
    ));
$session = $fb->getSession();

With these objects, you have everything you need to upload a photo to Facebook:

function post_image($fb, $session, $image_path){
    try{
        $image = array(
            'access_token' => $session['access_token'],
        );
        $fb->setFileUploadSupport(true);
        $image['image'] = '@'.realpath($image_path);
        $fb->api('/me/photos', 'POST', $image);
        echo "Success!";
        return true;
    }catch(FacebookApiException $e){
        echo $e;
        return false;
    }
}

Super easy. And there are all kinds of neat properties you can include in the image array, explained at the Graph API Photo documentation. Of particular interest to me was the “tags” property, described as returning “An array of JSON objects, the x and y coordinates are percentages from the left and top edges of the photo, respectively” when requested in a GET request. But how does one tag users when posting a photo?

Tagging a photo with the Graph API

The trick, it turns out, is to include a “tags” property as it suggests, with the following format: “tags” is an array of associative arrays, each of which contains the fields ‘x’ (x-coordinate of the tag as a percentage), ‘y’ (y-coordinate of the tag as a percentage), and ‘tag_uid’, a user UID. I never did any testing to see if there was any limit to how many tags, but it definitely works for one at least. Here is the updated post_image function from above, now including a tag of the logged-in user in the center of the image:

function post_image($fb, $session, $image_path){
    try{
        $tag = array(
            'tag_uid' => $fb->getUser(),
            'x' => 0,
            'y' => 0
        );
        $tags[] = $tag;
        $image = array(
            'access_token' => $session['access_token'],
            'tags' => $tags,
        );
        $fb->setFileUploadSupport(true);
        $image['image'] = '@'.realpath($image_path);
        $fb->api('/me/photos', 'POST', $image);
        echo "Success!";
        return true;
    }catch(FacebookApiException $e){
        echo $e;
        return false;
    }
}

As the name implies, the get_user method of the Facebook object retrieves the user ID (actually the Graph ID) of the logged-in user.

In conclusion, having just scratched the surface of the possibilities of the Graph API, I am very excited by its breadth and depth. Though lacking in complete documentation, when wrapped up in some of the reasonably well-done SDKs, it is both straightforward and indeed easy to include powerful Facebook functionality in web applications.

Country Selection Splash Pages Are Stupid

Posted on 20 June 2012 by Joseph

I love the Microplane kitchen tools (and would probably love the woodworking tools too if ever I had used them). What I don’t love is the unnecessary step of choosing my country upon arriving at their website. In a world where tools like visitor.js exist, much less the vast array of server-side techniques for doing just this, why am I ever forced to click ‘Microplane USA’ again?

And it’s not just kitchen tools either. I commonly see technology providers doing this same thing. In my opinion, it’s always better to make a best guess then let the user correct if they need to. This is what high-traffic projects like Firefox do to get people to the correct download. If their assumptions about your language or operating system are incorrect, you’re just a click away from the correct page, but most people never have to click anything to get to their final destination.


Copyright © 2018 Joseph Turner