michael@0: # This Source Code Form is subject to the terms of the Mozilla Public michael@0: # License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: # file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: michael@0: """ michael@0: This script generates the complete snippet for a given locale or en-US michael@0: Most of the parameters received are to generate the MAR's download URL michael@0: and determine the MAR's filename michael@0: """ michael@0: import sys, os, platform, sha michael@0: from optparse import OptionParser michael@0: from ConfigParser import ConfigParser michael@0: from stat import ST_SIZE michael@0: michael@0: def main(): michael@0: error = False michael@0: parser = OptionParser( michael@0: usage="%prog [options]") michael@0: parser.add_option("--mar-path", michael@0: action="store", michael@0: dest="marPath", michael@0: help="[Required] Specify the absolute path where the MAR file is found.") michael@0: parser.add_option("--application-ini-file", michael@0: action="store", michael@0: dest="applicationIniFile", michael@0: help="[Required] Specify the absolute path to the application.ini file.") michael@0: parser.add_option("-l", michael@0: "--locale", michael@0: action="store", michael@0: dest="locale", michael@0: help="[Required] Specify which locale we are generating the snippet for.") michael@0: parser.add_option("-p", michael@0: "--product", michael@0: action="store", michael@0: dest="product", michael@0: help="[Required] This option is used to generate the URL to download the MAR file.") michael@0: parser.add_option("--platform", michael@0: action="store", michael@0: dest="platform", michael@0: help="[Required] This option is used to indicate which target platform.") michael@0: parser.add_option("--branch", michael@0: action="store", michael@0: dest="branch", michael@0: help="This option is used to indicate which branch name to use for FTP file names.") michael@0: parser.add_option("--download-base-URL", michael@0: action="store", michael@0: dest="downloadBaseURL", michael@0: help="This option indicates under which.") michael@0: parser.add_option("-v", michael@0: "--verbose", michael@0: action="store_true", michael@0: dest="verbose", michael@0: default=False, michael@0: help="This option increases the output of the script.") michael@0: (options, args) = parser.parse_args() michael@0: for req, msg in (('marPath', "the absolute path to the where the MAR file is"), michael@0: ('applicationIniFile', "the absolute path to the application.ini file."), michael@0: ('locale', "a locale."), michael@0: ('product', "specify a product."), michael@0: ('platform', "specify the platform.")): michael@0: if not hasattr(options, req): michael@0: parser.error('You must specify %s' % msg) michael@0: michael@0: if not options.downloadBaseURL or options.downloadBaseURL == '': michael@0: options.downloadBaseURL = 'http://ftp.mozilla.org/pub/mozilla.org/%s/nightly' % options.product michael@0: michael@0: if not options.branch or options.branch == '': michael@0: options.branch = None michael@0: michael@0: snippet = generateSnippet(options.marPath, michael@0: options.applicationIniFile, michael@0: options.locale, michael@0: options.downloadBaseURL, michael@0: options.product, michael@0: options.platform, michael@0: options.branch) michael@0: f = open(os.path.join(options.marPath, 'complete.update.snippet'), 'wb') michael@0: f.write(snippet) michael@0: f.close() michael@0: michael@0: if options.verbose: michael@0: # Show in our logs what the contents of the snippet are michael@0: print snippet michael@0: michael@0: def generateSnippet(abstDistDir, applicationIniFile, locale, michael@0: downloadBaseURL, product, platform, branch): michael@0: # Let's extract information from application.ini michael@0: c = ConfigParser() michael@0: try: michael@0: c.readfp(open(applicationIniFile)) michael@0: except IOError, (stderror): michael@0: sys.exit(stderror) michael@0: buildid = c.get("App", "BuildID") michael@0: appVersion = c.get("App", "Version") michael@0: branchName = branch or c.get("App", "SourceRepository").split('/')[-1] michael@0: michael@0: marFileName = '%s-%s.%s.%s.complete.mar' % ( michael@0: product, michael@0: appVersion, michael@0: locale, michael@0: platform) michael@0: # Let's determine the hash and the size of the MAR file michael@0: # This function exits the script if the file does not exist michael@0: (completeMarHash, completeMarSize) = getFileHashAndSize( michael@0: os.path.join(abstDistDir, marFileName)) michael@0: # Construct the URL to where the MAR file will exist michael@0: interfix = '' michael@0: if locale == 'en-US': michael@0: interfix = '' michael@0: else: michael@0: interfix = '-l10n' michael@0: marDownloadURL = "%s/%s%s/%s" % (downloadBaseURL, michael@0: datedDirPath(buildid, branchName), michael@0: interfix, michael@0: marFileName) michael@0: michael@0: snippet = """complete michael@0: %(marDownloadURL)s michael@0: sha1 michael@0: %(completeMarHash)s michael@0: %(completeMarSize)s michael@0: %(buildid)s michael@0: %(appVersion)s michael@0: %(appVersion)s michael@0: """ % dict( marDownloadURL=marDownloadURL, michael@0: completeMarHash=completeMarHash, michael@0: completeMarSize=completeMarSize, michael@0: buildid=buildid, michael@0: appVersion=appVersion) michael@0: michael@0: return snippet michael@0: michael@0: def getFileHashAndSize(filepath): michael@0: sha1Hash = 'UNKNOWN' michael@0: size = 'UNKNOWN' michael@0: michael@0: try: michael@0: # open in binary mode to make sure we get consistent results michael@0: # across all platforms michael@0: f = open(filepath, "rb") michael@0: shaObj = sha.new(f.read()) michael@0: sha1Hash = shaObj.hexdigest() michael@0: size = os.stat(filepath)[ST_SIZE] michael@0: except IOError, (stderror): michael@0: sys.exit(stderror) michael@0: michael@0: return (sha1Hash, size) michael@0: michael@0: def datedDirPath(buildid, milestone): michael@0: """ michael@0: Returns a string that will look like: michael@0: 2009/12/2009-12-31-09-mozilla-central michael@0: """ michael@0: year = buildid[0:4] michael@0: month = buildid[4:6] michael@0: day = buildid[6:8] michael@0: hour = buildid[8:10] michael@0: datedDir = "%s-%s-%s-%s-%s" % (year, michael@0: month, michael@0: day, michael@0: hour, michael@0: milestone) michael@0: return "%s/%s/%s" % (year, month, datedDir) michael@0: michael@0: if __name__ == '__main__': michael@0: main()