package.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #!/usr/bin/env 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. """Utility to package and upload the USB gadget framework.
  6. """
  7. import argparse
  8. import hashlib
  9. import io
  10. import os
  11. import zipfile
  12. try:
  13. from urllib.request import Request, urlopen
  14. except ImportError: # For Py2 compatibility
  15. from urllib2 import Request, urlopen
  16. def MakeZip(directory=None, files=None):
  17. """Construct a zip file.
  18. Args:
  19. directory: Include Python source files from this directory
  20. files: Include these files
  21. Returns:
  22. A tuple of the buffer containing the zip file and its MD5 hash.
  23. """
  24. buf = io.BytesIO()
  25. archive = zipfile.PyZipFile(buf, 'w')
  26. if directory is not None:
  27. archive.writepy(directory)
  28. if files is not None:
  29. for f in files:
  30. archive.write(f, os.path.basename(f))
  31. archive.close()
  32. content = buf.getvalue()
  33. buf.close()
  34. md5 = hashlib.md5(content).hexdigest()
  35. return content, md5
  36. def EncodeBody(filename, buf):
  37. return b'\r\n'.join([
  38. b'--foo',
  39. b'Content-Disposition: form-data; name="file"; filename="%s"' %
  40. filename,
  41. b'Content-Type: application/octet-stream',
  42. b'',
  43. buf,
  44. b'--foo--',
  45. b''
  46. ])
  47. def UploadZip(content, md5, host):
  48. filename = b'usb_gadget-%s.zip' % md5.encode('utf-8')
  49. req = Request(url='http://{}/update'.format(host),
  50. data=EncodeBody(filename, content))
  51. req.add_header('Content-Type', 'multipart/form-data; boundary=foo')
  52. urlopen(req)
  53. def main():
  54. parser = argparse.ArgumentParser(
  55. description='Package (and upload) the USB gadget framework.')
  56. parser.add_argument(
  57. '--dir', type=str, metavar='DIR',
  58. help='package all Python files from DIR')
  59. parser.add_argument(
  60. '--zip-file', type=str, metavar='FILE',
  61. help='save package as FILE')
  62. parser.add_argument(
  63. '--hash-file', type=str, metavar='FILE',
  64. help='save package hash as FILE')
  65. parser.add_argument(
  66. '--upload', type=str, metavar='HOST[:PORT]',
  67. help='upload package to target system')
  68. parser.add_argument(
  69. 'files', metavar='FILE', type=str, nargs='*',
  70. help='source files')
  71. args = parser.parse_args()
  72. content, md5 = MakeZip(directory=args.dir, files=args.files)
  73. if args.zip_file:
  74. with open(args.zip_file, 'wb') as zip_file:
  75. zip_file.write(content)
  76. if args.hash_file:
  77. with open(args.hash_file, 'w') as hash_file:
  78. hash_file.write(md5)
  79. if args.upload:
  80. UploadZip(content, md5, args.upload)
  81. if __name__ == '__main__':
  82. main()