download_url()   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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