Intelerad has developed something called “nuage Patient Portal”, which is used by many clinics to let patients download their scans. It’s an excellent service, especially if you want to have backups of all of your own health records. But it (or at least the version used by my clinic) does have a flaw: it’s cumbersome to download all the images.

It is possible to download an image set as a video, but the resulting file seems to be broken. Popular video software like MPV and VLC were unable to play the files smoothly, and using FFmpeg to extract frames from the video resulted in an incomplete set, so I’m pretty sure the video files are not standards compliant. It is also possible to download each image of a set individually, but this requires two mouse clicks and then scrolling or pressing the down button to get to the next image. Doing this for more than 1,000 images would be a massive chore, not to mention error prone. So I looked around for a way to easily automate this (ideally) one-off process. I tried a few solutions, but none of them seemed to work well, so I won’t mention them here.

After a few hours I learned about ydotool, a generic desktop automation tool for Linux. It did the trick, by providing simple commands like ydotool click 0xC0 to left click and release, ydotool mousemove --xpos 0 --ypos -50 to move the mouse pointer down, and ydotool key 108:1 108:0 to press and immediately release the down arrow.

Prerequisites

  • Bash
  • ydotool

Code

#!/usr/bin/env bash

set -o errexit -o nounset

if [[ $# -ne 1 ]]; then
    cat >&2 << EOF
$0: Download nuage image series, since they don't provide a convenient way of doing that.

Usage:

1. Log into your clinic's nuage patient portal.
2. Go to the first image in the series you want to download.
3. Open up a terminal side by side with the browser.
4. \`cd\` into your browser download directory, for example \`~/download\`. This directory should ideally be empty to help with validation at the end of this script.
5. Move the mouse pointer so it hovers above the middle of the download icon, but don't click it.
6. Run \`$0 IMAGE_COUNT\`. For example, \`$0 100\` will try to download 100 images.
EOF
    exit 2
fi

image_count="$1"

readonly pixels_from_download_button_to_link=40

image_index=0
while [[ "$image_index" -lt "$image_count" ]]; do
    ydotool click 0xC0                                                        # Left mouse button on download icon
    sleep 0.3s                                                                # Wait for menu to appear
    ydotool mousemove --xpos 0 --ypos "$pixels_from_download_button_to_link"  # Move down to "Download current image"
    ydotool click 0xC0                                                        # Left mouse button on "Download current image"
    sleep 0.3s                                                                # Wait for menu to disappear
    ydotool mousemove --xpos 0 --ypos -"$pixels_from_download_button_to_link" # Move back up to download icon
    ydotool key 108:1 108:0                                                   # Press and release down arrow
    ((++image_index))
done

# Check for missing files
for file_index in $(seq 1 "$image_count"); do
    if ! test -f ./*" ${file_index}.png"; then
        echo "Missing image #${file_index}" >&2
        exit_code=3
    fi
done

exit "${exit_code-0}"

Use

  1. Put the code above into a file such as download.bash.
  2. Make the file executable.
  3. Run the file and follow the instructions printed on screen.