It's been some time, since my last serious python code, so excuse the mess ;) This will take any key fingerprint, for e.g. from ssh, in a hexadicaml format and show an image from commons.wikimedia.org which represents the key. The script will hash the key and does some sort of table lookup. I still need to implement some double hashing, when the matching image has a too high time offset, to eliminate some collisions. The current implementation also can't really deal with deleted images, tho I came up with some workarounds to that already.
#!/usr/bin/python
# convert ssh key figerprint to wikimedia commons image
import os
import sys
import commands
from datetime import datetime
from datetime import timedelta
import re
from xml.sax import saxutils
from xml.sax import make_parser
from xml.sax.handler import feature_namespaces
def convertMonth(ds):
""" Replaces all written out months in a string with a xx number."""
# don't depend on locals
ds = ds.replace("January", "01")
ds = ds.replace("February", "02")
ds = ds.replace("March", "03")
ds = ds.replace("April", "04")
ds = ds.replace("May", "05")
ds = ds.replace("June", "06")
ds = ds.replace("July", "07")
ds = ds.replace("August", "08")
ds = ds.replace("September", "09")
ds = ds.replace("October", "10")
ds = ds.replace("November", "11")
ds = ds.replace("December", "12")
return ds
class ImageParser(saxutils.DefaultHandler):
def __init__(self):
self.inThumb = False
self.dateElement = False
self.thumbs = []
def startElement(self, name, attrs):
if self.dateElement:
self.dateElement = False
if name == 'div':
if attrs.get('class', None) == 'thumb':
self.inThumb = True
if self.inThumb:
if name == 'img':
self.thumbs.append([attrs.get('src', None)])
if name == 'i':
self.dateElement = True
self.inThumb = False
def characters(self, content):
if self.dateElement:
date = datetime.strptime(convertMonth(content), "%H:%M, %d %m %Y")
self.thumbs[len(self.thumbs)-1].append(date)
def endDocument(self):
self.thumbList = []
for l in self.thumbs:
if l[0].find('http') != -1:
if len(l) == 2:
self.thumbList.append(l)
class HashFunction:
def __init__(self, startDate, duration, ticSize):
""" Provides a Hash function, which takes any integer
and returns a date within a given interval.
Keyword Arguments:
startDate -- the maximum date in the time interval, a datetime object
duration -- the positiv length of the timer interval, a deltatime object
ticSize -- the tic size in seconds is the unit in which the interval is divided
"""
self.startDate = startDate
self.duration = duration
self.ticSize = ticSize
seconds = duration.days*24*60*60 + duration.seconds
self.numHashes = seconds / ticSize
def h(self, x):
""" Converts an Integer to a date in the configured period,
based on a hashfunction.
"""
h1 = x%self.numHashes
second = h1 * self.ticSize
return self.startDate - timedelta(0, second)
def hFormat(self, x):
""" Converts an Integer to a date in the configured period,
based on a hashfunction. The date is formated string.
"""
dt = self.h(x)
return dt.strftime("%Y%m%d%H%M%S")
class KeyImage:
def __init__(self):
self.hf = HashFunction(startDate, duration, resolution)
def __init__(self, startDate=datetime(2010, 2, 1, 12, 00, 00), duration=timedelta(days=365*4), resolution=60):
self.hf = HashFunction(startDate, duration, resolution)
def getImage(self, x, size=-1):
""" Converts an Integer value to an image url from wikimedia commons."""
# hasing
imageDate = self.hf.hFormat(x)
# download html file
url = "'http://commons.wikimedia.org/w/index.php?title=Special:NewFiles&from=" + imageDate + "'"
htmlFilename = "/tmp/commons_thumbs.html"
commands.getstatusoutput("wget -E " + url + " -O " + htmlFilename)
# parse xml file
parser = make_parser()
ip = ImageParser()
parser.setFeature(feature_namespaces, 0)
parser.setContentHandler(ip)
file = open(htmlFilename)
parser.parse(file)
# remove temporary html file
commands.getstatusoutput("rm " + htmlFilename)
imageUrl = ip.thumbList[0][0]
if (size > -1):
imageUrl = re.sub("[0-9]{2,3}px", str(size) + "px", imageUrl)
return imageUrl
def main():
skey = sys.argv[1].replace(".","").replace(":","")
try:
key = int(skey, 16)
except:
sys.stderr.write("[ERROR] Invalid Key")
sys.exit(1)
thumbSize = -1
if len(sys.argv) >= 3:
try:
thumbSize = int(sys.argv[2])
except:
sys.stderr.write("[ERROR] Invalid Size")
sys.exit(1)
ki = KeyImage()
print ki.getImage(key, thumbSize)
main()
Here is a short wrapper script, which downloads the image and displays it with feh.
#!/bin/bash
IMAGEURL=`key_to_thumb.py $1 $2|tail -1`
echo $IMAGEURL
TMPFILE="/tmp/kthumb.img"
wget "$IMAGEURL" -O$TMPFILE &> /dev/null
feh $TMPFILE
rm $TMPFILE