Completed
Push — master ( 3c1059...41ee64 )
by Ionel Cristian
01:09
created

download_latest_artifacts()   B

Complexity

Conditions 5

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
c 2
b 0
f 0
dl 0
loc 29
rs 8.0894
1
#!/usr/bin/env python
2
"""
3
Use the AppVeyor API to download Windows artifacts.
4
5
Taken from: https://bitbucket.org/ned/coveragepy/src/tip/ci/download_appveyor.py
6
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
7
# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
8
"""
9
from __future__ import unicode_literals
10
11
import argparse
12
import os
13
import requests
14
import zipfile
15
16
17
def make_auth_headers():
18
    """Make the authentication headers needed to use the Appveyor API."""
19
    path = os.path.expanduser("~/.appveyor.token")
20
    if not os.path.exists(path):
21
        raise RuntimeError(
22
            "Please create a file named `.appveyor.token` in your home directory. "
23
            "You can get the token from https://ci.appveyor.com/api-token"
24
        )
25
    with open(path) as f:
26
        token = f.read().strip()
27
28
    headers = {
29
        'Authorization': 'Bearer {}'.format(token),
30
    }
31
    return headers
32
33
34
def download_latest_artifacts(account_project, build_id):
35
    """Download all the artifacts from the latest build."""
36
    if build_id is None:
37
        url = "https://ci.appveyor.com/api/projects/{}".format(account_project)
38
    else:
39
        url = "https://ci.appveyor.com/api/projects/{}/build/{}".format(account_project, build_id)
40
    build = requests.get(url, headers=make_auth_headers()).json()
41
    jobs = build['build']['jobs']
42
    print(u"Build {0[build][version]}, {1} jobs: {0[build][message]}".format(build, len(jobs)))
43
44
    for job in jobs:
45
        name = job['name']
46
        print(u"  {0}: {1[status]}, {1[artifactsCount]} artifacts".format(name, job))
47
48
        url = "https://ci.appveyor.com/api/buildjobs/{}/artifacts".format(job['jobId'])
49
        response = requests.get(url, headers=make_auth_headers())
50
        artifacts = response.json()
51
52
        for artifact in artifacts:
53
            is_zip = artifact['type'] == "Zip"
54
            filename = artifact['fileName']
55
            print(u"    {0}, {1} bytes".format(filename, artifact['size']))
56
57
            url = "https://ci.appveyor.com/api/buildjobs/{}/artifacts/{}".format(job['jobId'], filename)
58
            download_url(url, filename, make_auth_headers())
59
60
            if is_zip:
61
                unpack_zipfile(filename)
62
                os.remove(filename)
63
64
65
def ensure_dirs(filename):
66
    """Make sure the directories exist for `filename`."""
67
    dirname, _ = os.path.split(filename)
68
    if dirname and not os.path.exists(dirname):
69
        os.makedirs(dirname)
70
71
72
def download_url(url, filename, headers):
73
    """Download a file from `url` to `filename`."""
74
    ensure_dirs(filename)
75
    response = requests.get(url, headers=headers, stream=True)
76
    if response.status_code == 200:
77
        with open(filename, 'wb') as f:
78
            for chunk in response.iter_content(16 * 1024):
79
                f.write(chunk)
80
    else:
81
        print(u"    Error downloading {}: {}".format(url, response))
82
83
84
def unpack_zipfile(filename):
85
    """Unpack a zipfile, using the names in the zip."""
86
    with open(filename, 'rb') as fzip:
87
        z = zipfile.ZipFile(fzip)
88
        for name in z.namelist():
89
            print(u"      extracting {}".format(name))
90
            ensure_dirs(name)
91
            z.extract(name)
92
93
parser = argparse.ArgumentParser(description='Download artifacts from AppVeyor.')
94
parser.add_argument('--id',
95
                    metavar='PROJECT_ID',
96
                    default='ionelmc/python-tblib',
97
                    help='Project ID in AppVeyor.')
98
parser.add_argument('build',
99
                    nargs='?',
100
                    metavar='BUILD_ID',
101
                    help='Build ID in AppVeyor. Eg: master-123')
102
103
if __name__ == "__main__":
104
    # import logging
105
    # logging.basicConfig(level="DEBUG")
106
    args = parser.parse_args()
107
    download_latest_artifacts(args.id, args.build)
108