tools/update-packaging/generatesnippet.py

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 # This Source Code Form is subject to the terms of the Mozilla Public
     2 # License, v. 2.0. If a copy of the MPL was not distributed with this
     3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     5 """
     6 This script generates the complete snippet for a given locale or en-US
     7 Most of the parameters received are to generate the MAR's download URL
     8 and determine the MAR's filename
     9 """
    10 import sys, os, platform, sha
    11 from optparse import OptionParser
    12 from ConfigParser import ConfigParser
    13 from stat import ST_SIZE
    15 def main():
    16     error = False
    17     parser = OptionParser(
    18         usage="%prog [options]")
    19     parser.add_option("--mar-path",
    20                       action="store",
    21                       dest="marPath",
    22                       help="[Required] Specify the absolute path where the MAR file is found.")
    23     parser.add_option("--application-ini-file",
    24                       action="store",
    25                       dest="applicationIniFile",
    26                       help="[Required] Specify the absolute path to the application.ini file.")
    27     parser.add_option("-l",
    28                       "--locale",
    29                       action="store",
    30                       dest="locale",
    31                       help="[Required] Specify which locale we are generating the snippet for.")
    32     parser.add_option("-p",
    33                       "--product",
    34                       action="store",
    35                       dest="product",
    36                       help="[Required] This option is used to generate the URL to download the MAR file.")
    37     parser.add_option("--platform",
    38                       action="store",
    39                       dest="platform",
    40                       help="[Required] This option is used to indicate which target platform.")
    41     parser.add_option("--branch",
    42                       action="store",
    43                       dest="branch",
    44                       help="This option is used to indicate which branch name to use for FTP file names.")
    45     parser.add_option("--download-base-URL",
    46                       action="store",
    47                       dest="downloadBaseURL",
    48                       help="This option indicates under which.")
    49     parser.add_option("-v",
    50                       "--verbose",
    51                       action="store_true",
    52                       dest="verbose",
    53                       default=False,
    54                       help="This option increases the output of the script.")
    55     (options, args) = parser.parse_args()
    56     for req, msg in (('marPath', "the absolute path to the where the MAR file is"),
    57                      ('applicationIniFile', "the absolute path to the application.ini file."),
    58                      ('locale', "a locale."),
    59                      ('product', "specify a product."),
    60                      ('platform', "specify the platform.")):
    61         if not hasattr(options, req):
    62             parser.error('You must specify %s' % msg)
    64     if not options.downloadBaseURL or options.downloadBaseURL == '':
    65         options.downloadBaseURL = 'http://ftp.mozilla.org/pub/mozilla.org/%s/nightly' % options.product
    67     if not options.branch or options.branch == '':
    68         options.branch = None
    70     snippet = generateSnippet(options.marPath,
    71                               options.applicationIniFile,
    72                               options.locale,
    73                               options.downloadBaseURL,
    74                               options.product,
    75                               options.platform,
    76                               options.branch)
    77     f = open(os.path.join(options.marPath, 'complete.update.snippet'), 'wb')
    78     f.write(snippet)
    79     f.close()
    81     if options.verbose:
    82         # Show in our logs what the contents of the snippet are
    83         print snippet
    85 def generateSnippet(abstDistDir, applicationIniFile, locale,
    86                     downloadBaseURL, product, platform, branch):
    87     # Let's extract information from application.ini
    88     c = ConfigParser()
    89     try:
    90         c.readfp(open(applicationIniFile))
    91     except IOError, (stderror):
    92        sys.exit(stderror)
    93     buildid = c.get("App", "BuildID")
    94     appVersion = c.get("App", "Version")
    95     branchName = branch or c.get("App", "SourceRepository").split('/')[-1]
    97     marFileName = '%s-%s.%s.%s.complete.mar' % (
    98         product,
    99         appVersion,
   100         locale,
   101         platform)
   102     # Let's determine the hash and the size of the MAR file
   103     # This function exits the script if the file does not exist
   104     (completeMarHash, completeMarSize) = getFileHashAndSize(
   105         os.path.join(abstDistDir, marFileName))
   106     # Construct the URL to where the MAR file will exist
   107     interfix = ''
   108     if locale == 'en-US':
   109         interfix = ''
   110     else:
   111         interfix = '-l10n'
   112     marDownloadURL = "%s/%s%s/%s" % (downloadBaseURL,
   113                                      datedDirPath(buildid, branchName),
   114                                      interfix,
   115                                      marFileName)
   117     snippet = """complete
   118 %(marDownloadURL)s
   119 sha1
   120 %(completeMarHash)s
   121 %(completeMarSize)s
   122 %(buildid)s
   123 %(appVersion)s
   124 %(appVersion)s
   125 """ % dict( marDownloadURL=marDownloadURL,
   126             completeMarHash=completeMarHash,
   127             completeMarSize=completeMarSize,
   128             buildid=buildid,
   129             appVersion=appVersion)
   131     return snippet
   133 def getFileHashAndSize(filepath):
   134     sha1Hash = 'UNKNOWN'
   135     size = 'UNKNOWN'
   137     try:
   138         # open in binary mode to make sure we get consistent results
   139         # across all platforms
   140         f = open(filepath, "rb")
   141         shaObj = sha.new(f.read())
   142         sha1Hash = shaObj.hexdigest()
   143         size = os.stat(filepath)[ST_SIZE]
   144     except IOError, (stderror):
   145        sys.exit(stderror)
   147     return (sha1Hash, size)
   149 def datedDirPath(buildid, milestone):
   150     """
   151     Returns a string that will look like:
   152     2009/12/2009-12-31-09-mozilla-central
   153     """
   154     year  = buildid[0:4]
   155     month = buildid[4:6]
   156     day   = buildid[6:8]
   157     hour  = buildid[8:10]
   158     datedDir = "%s-%s-%s-%s-%s" % (year,
   159                                    month,
   160                                    day,
   161                                    hour,
   162                                    milestone)
   163     return "%s/%s/%s" % (year, month, datedDir)
   165 if __name__ == '__main__':
   166     main()

mercurial