import operator import re from collections import namedtuple import requests base_url = 'https://download.docker.com/linux/static/{0}/x86_64/' categories = [ 'edge', 'stable', 'test' ] class Version(namedtuple('_Version', 'major minor patch rc edition')): @classmethod def parse(cls, version): edition = None version = version.lstrip('v') version, _, rc = version.partition('-') if rc: if 'rc' not in rc: edition = rc rc = None elif '-' in rc: edition, rc = rc.split('-') major, minor, patch = version.split('.', 3) return cls(major, minor, patch, rc, edition) @property def major_minor(self): return self.major, self.minor @property def order(self): """Return a representation that allows this object to be sorted correctly with the default comparator. """ # rc releases should appear before official releases rc = (0, self.rc) if self.rc else (1, ) return (int(self.major), int(self.minor), int(self.patch)) + rc def __str__(self): rc = '-{}'.format(self.rc) if self.rc else '' edition = '-{}'.format(self.edition) if self.edition else '' return '.'.join(map(str, self[:3])) + edition + rc def main(): results = set() for url in [base_url.format(cat) for cat in categories]: res = requests.get(url) content = res.text versions = [ Version.parse( v.strip('"').lstrip('docker-').rstrip('.tgz').rstrip('-x86_64') ) for v in re.findall( r'"docker-[0-9]+\.[0-9]+\.[0-9]+-.*tgz"', content ) ] sorted_versions = sorted( versions, reverse=True, key=operator.attrgetter('order') ) latest = sorted_versions[0] results.add(str(latest)) print(' '.join(results)) if __name__ == '__main__': main()