Home | History | Annotate | Download | only in usb_gadget
      1 #!/usr/bin/python
      2 # Copyright 2014 The Chromium Authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 """Utility to package and upload the USB gadget framework.
      7 """
      8 
      9 import argparse
     10 import hashlib
     11 import os
     12 import StringIO
     13 import urllib2
     14 import zipfile
     15 
     16 
     17 def MakeZip(directory=None, files=None):
     18   """Construct a zip file.
     19 
     20   Args:
     21     directory: Include Python source files from this directory
     22     files: Include these files
     23 
     24   Returns:
     25     A tuple of the buffer containing the zip file and its MD5 hash.
     26   """
     27   buf = StringIO.StringIO()
     28   archive = zipfile.PyZipFile(buf, 'w')
     29   if directory is not None:
     30     archive.writepy(directory)
     31   if files is not None:
     32     for f in files:
     33       archive.write(f, os.path.basename(f))
     34   archive.close()
     35   content = buf.getvalue()
     36   buf.close()
     37   md5 = hashlib.md5(content).hexdigest()
     38   return content, md5
     39 
     40 
     41 def EncodeBody(filename, buf):
     42   return '\r\n'.join([
     43       '--foo',
     44       'Content-Disposition: form-data; name="file"; filename="{}"'
     45       .format(filename),
     46       'Content-Type: application/octet-stream',
     47       '',
     48       buf,
     49       '--foo--',
     50       ''
     51   ])
     52 
     53 
     54 def UploadZip(content, md5, host):
     55   filename = 'usb_gadget-{}.zip'.format(md5)
     56   req = urllib2.Request(url='http://{}/update'.format(host),
     57                         data=EncodeBody(filename, content))
     58   req.add_header('Content-Type', 'multipart/form-data; boundary=foo')
     59   urllib2.urlopen(req)
     60 
     61 
     62 def main():
     63   parser = argparse.ArgumentParser(
     64       description='Package (and upload) the USB gadget framework.')
     65   parser.add_argument(
     66       '--dir', type=str, metavar='DIR',
     67       help='package all Python files from DIR')
     68   parser.add_argument(
     69       '--zip-file', type=str, metavar='FILE',
     70       help='save package as FILE')
     71   parser.add_argument(
     72       '--hash-file', type=str, metavar='FILE',
     73       help='save package hash as FILE')
     74   parser.add_argument(
     75       '--upload', type=str, metavar='HOST[:PORT]',
     76       help='upload package to target system')
     77   parser.add_argument(
     78       'files', metavar='FILE', type=str, nargs='*',
     79       help='source files')
     80 
     81   args = parser.parse_args()
     82 
     83   content, md5 = MakeZip(directory=args.dir, files=args.files)
     84   if args.zip_file:
     85     with open(args.zip_file, 'w') as zip_file:
     86       zip_file.write(content)
     87   if args.hash_file:
     88     with open(args.hash_file, 'w') as hash_file:
     89       hash_file.write(md5)
     90   if args.upload:
     91     UploadZip(content, md5, args.upload)
     92 
     93 
     94 if __name__ == '__main__':
     95   main()
     96