download_appveyor.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
  2. # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
  3. """Use the Appveyor API to download Windows artifacts."""
  4. import os
  5. import os.path
  6. import sys
  7. import zipfile
  8. import requests
  9. def make_auth_headers():
  10. """Make the authentication headers needed to use the Appveyor API."""
  11. with open("ci/appveyor.token") as f:
  12. token = f.read().strip()
  13. headers = {
  14. 'Authorization': 'Bearer {0}'.format(token),
  15. }
  16. return headers
  17. def make_url(url, **kwargs):
  18. """Build an Appveyor API url."""
  19. return "https://ci.appveyor.com/api" + url.format(**kwargs)
  20. def get_project_build(account_project):
  21. """Get the details of the latest Appveyor build."""
  22. url = make_url("/projects/{account_project}", account_project=account_project)
  23. response = requests.get(url, headers=make_auth_headers())
  24. return response.json()
  25. def download_latest_artifacts(account_project):
  26. """Download all the artifacts from the latest build."""
  27. build = get_project_build(account_project)
  28. jobs = build['build']['jobs']
  29. print "Build {0[build][version]}, {1} jobs: {0[build][message]}".format(build, len(jobs))
  30. for job in jobs:
  31. name = job['name'].partition(':')[2].split(',')[0].strip()
  32. print " {0}: {1[status]}, {1[artifactsCount]} artifacts".format(name, job)
  33. url = make_url("/buildjobs/{jobid}/artifacts", jobid=job['jobId'])
  34. response = requests.get(url, headers=make_auth_headers())
  35. artifacts = response.json()
  36. for artifact in artifacts:
  37. is_zip = artifact['type'] == "Zip"
  38. filename = artifact['fileName']
  39. print " {0}, {1} bytes".format(filename, artifact['size'])
  40. url = make_url(
  41. "/buildjobs/{jobid}/artifacts/{filename}",
  42. jobid=job['jobId'],
  43. filename=filename
  44. )
  45. download_url(url, filename, make_auth_headers())
  46. if is_zip:
  47. unpack_zipfile(filename)
  48. os.remove(filename)
  49. def ensure_dirs(filename):
  50. """Make sure the directories exist for `filename`."""
  51. dirname, _ = os.path.split(filename)
  52. if dirname and not os.path.exists(dirname):
  53. os.makedirs(dirname)
  54. def download_url(url, filename, headers):
  55. """Download a file from `url` to `filename`."""
  56. ensure_dirs(filename)
  57. response = requests.get(url, headers=headers, stream=True)
  58. if response.status_code == 200:
  59. with open(filename, 'wb') as f:
  60. for chunk in response.iter_content(16*1024):
  61. f.write(chunk)
  62. def unpack_zipfile(filename):
  63. """Unpack a zipfile, using the names in the zip."""
  64. with open(filename, 'rb') as fzip:
  65. z = zipfile.ZipFile(fzip)
  66. for name in z.namelist():
  67. print " extracting {0}".format(name)
  68. ensure_dirs(name)
  69. z.extract(name)
  70. if __name__ == "__main__":
  71. download_latest_artifacts(sys.argv[1])