Skip to content

Instantly share code, notes, and snippets.

@xeonchen
Forked from anonymous/nightly_win_updater.py
Created January 19, 2017 13:43
Show Gist options
  • Save xeonchen/2bc2dc5194db76327b862b8c2dfd09c1 to your computer and use it in GitHub Desktop.
Save xeonchen/2bc2dc5194db76327b862b8c2dfd09c1 to your computer and use it in GitHub Desktop.
Update Firefox Nightly on Windows platform
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import hashlib
import os
import re
import stat
import tempfile
import urllib2
class WinNightlyDownloader:
CONFIG = {
'protocol': 'https',
'host': 'archive.mozilla.org',
'path': '/pub/firefox/nightly/latest-mozilla-central',
}
def __init__(self, platform):
self.config = self.CONFIG.copy()
self.config['platform'] = platform
self.config['lang'] = 'en-US'
self.config['version'] = self._check_version()
self.config['installer'] = 'firefox-%(version)s.%(lang)s.%(platform)s.installer.exe' % (self.config)
self.checksums = {}
self.digests = {}
self.path = ''
self.filesize = 0
def __del__(self):
self.reset()
def _check_version(self):
url = '%(protocol)s://%(host)s%(path)s/' % (self.config)
req = urllib2.urlopen(url)
for line in req.read().split('\n'):
pat = 'firefox-(\d+.\w+).%(lang)s.%(platform)s.installer.exe' % self.config
m = re.search(pat, line)
if m:
return m.group(1)
return None
def _prepare_checksums(self):
url = '%(protocol)s://%(host)s%(path)s/firefox-%(version)s.%(lang)s.%(platform)s.checksums' % (self.config)
req = urllib2.urlopen(url)
checksums = {}
for line in req.read().split('\r\n'):
if not line: continue
checksum, name, size, filename = line.split()
checksum = checksum.lower()
name = name.lower()
size = int(size, 10)
filename = filename.split('/')[-1]
if filename != self.config['installer']: continue
checksums[name] = {
'checksum': checksum.lower(),
'size': int(size),
}
self.checksums = checksums
def fetch(self):
self._prepare_checksums()
url = '%(protocol)s://%(host)s%(path)s/%(installer)s' % (self.config)
req = urllib2.urlopen(url)
fd, path = tempfile.mkstemp(prefix='nightly-', suffix='.exe')
filesize = 0
hashes = dict((m, hashlib.new(m)) for m in self.checksums)
with os.fdopen(fd, 'w', 65536) as f:
while True:
buf = req.read(65536)
if not buf: break;
filesize += len(buf)
for m in hashes.itervalues():
m.update(buf)
f.write(buf)
print 'downloading: %d bytes\r' % filesize,
print ''
for k, v in hashes.iteritems():
self.digests[k] = v.hexdigest().lower()
self.path = path
self.filesize = filesize
return True
def check(self):
for k, v in self.digests.iteritems():
if self.checksums[k]['checksum'] != v:
print 'checksum %s mismatch' % k
return False
if self.checksums[k]['size'] != self.filesize:
print 'size %s mismatch' % k
return False
return True
def reset(self):
if os.path.exists(self.path):
os.remove(self.path)
def main():
for platform in ('win32', 'win64'):
f = WinNightlyDownloader(platform)
if f.fetch() and f.check():
print 'installing...'
os.system(f.path + ' -ms')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment