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 9import argparse 10import hashlib 11import os 12import StringIO 13import urllib2 14import zipfile 15 16 17def 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 41def 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 54def 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 62def 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 94if __name__ == '__main__': 95 main() 96