Skip to content

Instantly share code, notes, and snippets.

@MicahElliott
Created September 6, 2011 00:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save MicahElliott/1196269 to your computer and use it in GitHub Desktop.
Save MicahElliott/1196269 to your computer and use it in GitHub Desktop.
flickpapr — Succeeded by https://github.com/MicahElliott/flickpapr

flickpapr — Randomly choose an “interesting” flickr photo for desktop wallpaper.

AUTHOR: Micah Elliott LICENSE: WTFPL

About Flickr Interestingness

Flickr’s interestingness heuristics generate some lovely images. People visit every day and just click “Refresh” to see page after page of these. BUT… it’s much better just have these delivered right to your desktop as a wallpaper. Well, maybe you should just have pics of your cats going there, but these can be a little more inspirational. The cats shouldn’t get too jealous; they’ll love all the bugs!

There’s a danger in coming to flickr every day to peruse interesting pics. And anyway, they’re too small there. So this little script recipe just puts one at random on your desktop every so often. It also puts a desktop notification describing the photo and location.

Some key information is part of each pic. You’ll want to know its original URL, who took it, and sometimes you’ll be able to find geo-location info. This is displayed and stowed away in extended filesystem attributes, which can later be queried.

I recommend going through these once a month or so to select some faves for future desktops BGs.

Dependencies

  • GNOME (but adaptable to whatever scriptable desktop manipulator).
  • Ruby
  • Nokogiri gem (just made it too easy to not depend on flickr API).
  • ffi-xattr, ffi gems (for creating xattrs database)

Usage

Note that there’s a new-ish limitation in Ubuntu that disables updating desktop things via cron. The cronX wrapper script (included) works around this, so use it to call flickpapr.

Put something like these (choose one) in your crontab for rotation (crontab -e):

MAILTO = you@example.com

@hourly .../cronX.zsh .../flickpapr.rb

# Pomodoro productivity!
0,30 * * * * ...

# Firehose of distraction.
0-55/5 * * * * ...

Later on, you can visit your local collection to query and browse them.

% cd ~/tmp/flickr
% getfattr -n user.location *.jpg
# file: 6667763073_e3271a96e6_o.jpg
user.location="Velence, Fejér, HU"
# file: 6672593991_b0cf581e34_o.jpg
user.location="Kijkduin, The Hague, ZH, NL"
...
% nautilus .
% mv {x,y,z}.jpg ~/Photos/wallpapers

BTW, You’ll probably want to have semi-transparent terminals to get the most out your wallpapers.

Present shortcomings and areas for improvement

  • Just dumps a file into $TMPDIR with no cleanup.
  • Should discard images that are too big so as not to fill your disk!
  • Image gets stretched to desktop width, so top/bottom often cut off.
  • Assumes JPG (99% safe).
  • Only works for GNOME (gconftool).
  • Doesn’t use Flickr API, so DOM/CDNs susceptible to change.
  • So simple it might not be worth turning into an installable gem.
  • Could use Daemons to avoid cron klugery.
  • Haven’t researched what “screensaver” apps (cf. “wallpapers”) are out there that could also use these images.
  • No way to “like” a pic in real time; have to visit dir to select faves.

Surprises

Why not just use the flickr API? Just wanted to minimize dependencies, and the scraping a la nokogiri is really simple.

Why not just use EXIF metadata for storing pic info? EXIF data is noisy, mostly not wanted, and difficult to query. Flickr doesn’t do much (anything?) with storing the real geolocation data there anyway.

#! /bin/bash
# If you're doing system ruby.
export RUBYOPT="rubygems"
export GEM_HOME=$HOME/.gem
export GEM_PATH=$GEM_PATH:$HOME/.gem/ruby/1.8.7
# Stupid hack to be able to run gconftool/notify from cron.
# http://ubuntuforums.org/showpost.php?p=7210276
# Get the pid of nautilus
nautilus_pid=$(pgrep -u $LOGNAME -n nautilus)
# If nautilus isn't running, just exit silently
if [ -z "$nautilus_pid" ]; then
exit 0
fi
# Grab the DBUS_SESSION_BUS_ADDRESS variable from nautilus's environment
eval $(tr '\0' '\n' < /proc/$nautilus_pid/environ | grep '^DBUS_SESSION_BUS_ADDRESS=')
# Check that we actually found it
if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then
echo "Failed to find bus address" >&2
exit 1
fi
# export it so that child processes will inherit it
export DBUS_SESSION_BUS_ADDRESS
#echo "$@"
$@
#! /usr/bin/env ruby
# flickpapr — Randomly choose an “interesting” flickr photo for desktop wallpaper.
#
# AUTHOR: Micah Elliott http://MicahElliott.com
# LICENSE: WTFPL http://sam.zoy.org/wtfpl/
#
# Any output from this script will go to cron, and subsequently into
# email. So you probably want to keep it silent.
require 'nokogiri'
require 'open-uri'
require 'ffi-xattr'
# Debug cron here if you have issues.
##puts $LOAD_PATH
int_table = 'http://www.flickr.com/explore/interesting/7days/'
doc = Nokogiri::HTML( open(int_table) )
orig = '/sizes/o/in/photostream/' # o => original
# Get the first pic in the page’s table.
# /photos/micke33/6108863245/
base = doc.css('.TwentyFour td.Photo a').first.attributes['href'].value
# http://www.flickr.com/photos/superpepelu/6097194845/sizes/o/in/photostream/
largest_uri = 'http://flickr.com' + base + orig
doc2 = Nokogiri::HTML( open(largest_uri) )
# e.g. http://farm7.static.flickr.com/6074/6116492734_36e7ec6efc_b.jpg
pic = doc2.css('#allsizes-photo img').first.attributes['src'].value
title = doc2.title.split(' | ')[1]
# About info.
about_uri = 'http://flickr.com' + base
# Uncomment to have each URL show up in your cron email (as thumbnail in gmail).
##puts about_uri
about_doc = Nokogiri::HTML( open(about_uri) )
# Keep the string `dump`-safe, avoiding nil.
location = ""
location_tree = about_doc.css('a#photoGeolocation-storylink')
if ! location_tree.empty?
location = location_tree.first.children.first.content.strip
# NOTE: this replaced whitespace is non-ascii (nbsp?)!
location.gsub! / /, " "
# e.g. "Little Stoke, Bristol, England, GB"
end
jpg = File.split(pic).last
# You do set TMPDIR, don’t you? Hmm, let's not rely on TMPDIR being set.
archive = "#{ENV['HOME']}/tmp/flickr"
# Not going to attempt to sensibly name the photo file.
jpg_path = "#{archive}/#{jpg}"
FileUtils.mkdir_p archive
`wget --quiet '#{pic}' -O #{jpg_path}`
# Set the extended filesystem attributes.
attrs = Xattr.new(jpg_path)
attrs['user.location'] = location if ! location.empty?
attrs['user.title'] = title
attrs['user.url'] = about_uri
#puts about_uri
#puts jpg_path
#puts title, location
# Using `dump` to avoid extra quotes (punctuation) going to shell.
`notify-send #{title.dump} #{location.dump}`
# GConfTool is the programmatic means to control GNOME’s wallpaper.
# Substitute with your OS’s equivalent.
`/usr/bin/gconftool -t str -s /desktop/gnome/background/picture_filename #{jpg_path}`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment