Skip to content

Instantly share code, notes, and snippets.

@mpg
Created July 18, 2012 15:46
Show Gist options
  • Save mpg/3137053 to your computer and use it in GitHub Desktop.
Save mpg/3137053 to your computer and use it in GitHub Desktop.
biglumber-sort - sort keys from a biglumber page by mean shortest distance
#!/usr/bin/python -tt
# coding: utf-8
# Manuel Pégourié-Gonnard, 2012. WTFPL v2.
"""
biglumber-sort - sort keys from a biglumber page by mean shortest distance
Example:
biglumber-sort 'http://biglumber.com/x/web?sc=Paris'
Background:
- biglumber.com is a site that lists people willing to sign GPG keys
- the mean shortest distance of a key is defined here:
http://pgp.cs.uu.nl/plot/
"""
import re
import sys
import urllib
class Key(object):
"""A GPG key"""
def __init__(self, fingerprint):
self._fingerprint = fingerprint
self._msd = None
def fingerprint(self):
return self._fingerprint
def short_id(self):
return self._fingerprint[-8:]
def __str__(self):
return self.short_id()
def biglumber_url(self):
"""Biglumber key page with owner details"""
return 'http://biglumber.com/x/web?sf=' + self._fingerprint
def wotsap_url(self):
"""Plain-text statistics"""
return 'http://webware.lysator.liu.se/jc/wotsap/wots/latest/keystatistics/0x' + self.short_id() + '.txt'
def kpas_url(self):
"""More human-friendly statistics"""
return 'http://pgp.cs.uu.nl/stats/' + self.short_id() + '.html'
def msd(self):
"""Mean shortest distance as given by wotsap statistics.
+infinity if not listed by wotsap.
Cached to avoid repeated network access"""
if not self._msd:
handle = urllib.urlopen(self.wotsap_url())
data = handle.read()
handle.close()
m = re.search(r'Mean shortest distance:\s+([0-9.]+)', data)
self._msd = float(m.group(1) if m else 'inf')
return self._msd
def __cmp__(self, other):
return cmp(self.msd(), other.msd())
def get_keys(biglumber_url):
"""Get a list of keys from biglumber city/country url"""
fh = urllib.urlopen(biglumber_url)
text = fh.read()
fh.close()
fingerprints = re.findall(
r'>Fingerprint: <a href=".*?=(.*?)">', text)
return [ Key(fp) for fp in fingerprints ]
def main():
werr = sys.stderr.write
if len(sys.argv) != 2:
werr('Error: invalid number of arguments.\n' + __doc__)
sys.exit(1)
source_url = sys.argv[1]
werr("Acquiring key list... ")
keys = get_keys(source_url)
werr(str(len(keys)) + " keys found.\n")
werr("Acquiring msd data... ")
for k in keys:
k.msd()
werr('.')
werr(' done.\n')
for key in sorted(keys):
print str(key.msd()).ljust(8) + key.biglumber_url()
return
# Standard boilerplate to call the main() function.
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment