f826d5ce64a9ee6fb6b558baec2eff5e2ae00154
[releng.git] / utils / opnfv-artifacts.py
1 #!/usr/bin/python
2 # SPDX-license-identifier: Apache-2.0
3 ##############################################################################
4 # Copyright (c) 2016 The Linux Foundation and others
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #  http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 ##############################################################################
17
18 """
19 Generate JSON listing of OPNFV Artifacts
20
21 This produces a slimmed down version of metadata provided by Google
22 Storage for each artifact. Also excludes a large number of uninteresting
23 files.
24 """
25
26 from apiclient import discovery
27 from apiclient.errors import HttpError
28
29 import argparse
30 import json
31 import os
32 import sys
33
34 api = {
35   'projects': {},
36   'docs': {},
37   'releases': {},
38 }
39
40 releases = [
41   'arno.2015.1.0',
42   'arno.2015.2.0',
43   'brahmaputra.1.0',
44 ]
45
46 # List of file extensions to filter out
47 ignore_extensions = [
48   '.buildinfo',
49   '.woff',
50   '.ttf',
51   '.svg',
52   '.eot',
53   '.pickle',
54   '.doctree',
55   '.js',
56   '.png',
57   '.css',
58   '.gif',
59   '.jpeg',
60   '.jpg',
61   '.bmp',
62 ]
63
64
65 parser = argparse.ArgumentParser(
66              description='OPNFV Artifacts JSON Generator')
67
68 parser.add_argument(
69         '-k',
70         dest='key',
71         default='',
72         help='API Key for Google Cloud Storage')
73
74 parser.add_argument(
75         '-p',
76         default=None,
77         dest='pretty',
78         action='store_const',
79         const=2,
80         help='pretty print the output')
81
82 # Parse and assign arguments
83 args = parser.parse_args()
84 key = args.key
85 pretty_print = args.pretty
86
87
88 def output(item, indent=2):
89     print(json.dumps(item, sort_keys=True, indent=indent))
90
91
92 def has_gerrit_review(dir_list):
93     """
94     If a directory contains an integer, it is assumed to be a gerrit
95     review number
96     """
97     for d in dir_list:
98         if d.isdigit():
99             return int(d)
100     return False
101
102
103 def has_release(dir_list):
104     """
105     Checks if any directory contains a release name
106     """
107     for d in dir_list:
108         if d in releases:
109             return d
110     return False
111
112
113 def has_documentation(dir_list):
114     """
115     Checks for a directory specifically named 'docs'
116     """
117     for d in dir_list:
118         if d == 'docs':
119             return True
120     return False
121
122
123 # Rename this or modify how gerrit review are handled
124 def has_logs(gerrit_review):
125     """
126     If a gerrit review exists, create a link to the review
127     """
128     if gerrit_review:
129         return "https://gerrit.opnfv.org/gerrit/#/c/%s" % gerrit_review
130     return False
131
132
133 def has_md5hash(item):
134     """
135     If a file has an md5hash available, grab it
136     """
137     if 'md5Hash' in item:
138         return item['md5Hash']
139     return False
140
141
142 def has_ignorable_extension(filename):
143     for extension in ignore_extensions:
144         if filename.lower().endswith(extension):
145             return True
146     return False
147
148
149 def get_results(key):
150     """
151     Pull down all metadata from artifacts.opnfv.org
152     and store it in projects as:
153     { 'PROJECT': [file ...], }
154     """
155     storage = discovery.build('storage', 'v1', developerKey=key)
156     files = storage.objects().list(bucket='artifacts.opnfv.org',
157                                    fields='nextPageToken,'
158                                           'items('
159                                               'name,'
160                                               'mediaLink,'
161                                               'md5Hash,'
162                                               'updated,'
163                                               'contentType,'
164                                               'size'
165                                           ')')
166     while (files is not None):
167         sites = files.execute()
168
169         for site in sites['items']:
170             # Filter out unneeded files (js, images, css, buildinfo, etc)
171             if has_ignorable_extension(site['name']):
172                 continue
173
174             # Split /foo/bar/ into ['foo', 'bar'] and remove any extra
175             # slashes (ex. /foo//bar/)
176             site_split = filter(None, site['name'].split('/'))
177
178             # Don't do anything if we aren't given files multiple
179             # directories deep
180             if len(site_split) < 2:
181                 continue
182
183             project = site_split[0]
184             name = '/'.join(site_split[1:])
185             proxy = "http://build.opnfv.org/artifacts.opnfv.org/%s" % site['name']
186             if name.endswith('.html'):
187                 href = "http://artifacts.opnfv.org/%s" % site['name']
188                 href_type = 'view'
189             else:
190                 href = site['mediaLink']
191                 href_type = 'download'
192             md5 = has_md5hash(site)
193
194             gerrit = has_gerrit_review(site_split)
195             logs = False  # has_logs(gerrit)
196             documentation = has_documentation(site_split)
197             release = has_release(site_split)
198
199             category = 'project'
200             if gerrit:
201                 category = 'gerrit'
202             elif release:
203                 category = 'release'
204             elif logs:
205                 category = 'logs'
206
207             metadata = {
208                 'category': category,
209                 'gerritreview': gerrit,
210                 'release': release,
211                 'name': name,
212                 'size': site['size'],
213                 'time': site['updated'],
214                 'contentType': site['contentType'],
215                 'href': href,
216                 'href_type': href_type,
217                 'proxy_href': proxy,
218                 'md5hash': md5,
219             }
220
221             if project in releases:
222                 if project not in api['releases']:
223                     api['releases'][project] = [metadata]
224                 else:
225                     api['releases'][project].append(metadata)
226             else:
227                 if project not in api['projects']:
228                     api['projects'][project] = [metadata]
229                 else:
230                     api['projects'][project].append(metadata)
231
232         files = storage.objects().list_next(files, sites)
233
234     return api
235
236
237 # Fail if there is an invalid response from GCE
238 try:
239     js = get_results(key)
240 except HttpError as e:
241     print >> sys.stderr, e
242     exit(1)
243
244 output(js, indent=pretty_print)