Created
July 18, 2012 15:46
-
-
Save mpg/3137053 to your computer and use it in GitHub Desktop.
biglumber-sort - sort keys from a biglumber page by mean shortest distance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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