gerrit-dash-creator/gerrit_dash_creator/cmd/creator.py

173 lines
5.4 KiB
Python
Executable File

#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import argparse
import os
import os.path
import sys
import urllib
import jinja2
import pkg_resources
import six
from six.moves import configparser
def escape_comma(buff):
"""Because otherwise Firefox is a sad panda."""
return buff.replace(',', '%2c')
def generate_dashboard_url(dashboard):
"""Generate a dashboard URL from a given definition."""
try:
title = dashboard.get('dashboard', 'title')
except configparser.NoOptionError:
raise ValueError("option 'title' in section 'dashboard' not set")
try:
foreach = escape_comma(dashboard.get('dashboard', 'foreach'))
except configparser.NoOptionError:
raise ValueError("option 'foreach' in section 'dashboard' not set")
try:
baseurl = dashboard.get('dashboard', 'baseurl')
except configparser.NoOptionError:
baseurl = 'https://review.openstack.org/#/dashboard/?'
url = baseurl
url += urllib.urlencode({'title': title, 'foreach': foreach})
url += '&'
for section in dashboard.sections():
if not section.startswith('section'):
continue
try:
query = dashboard.get(section, 'query')
except configparser.NoOptionError:
raise ValueError("option 'query' in '%s' not set" % section)
title = section[9:-1]
encoded = urllib.urlencode({title: query})
url += "&%s" % encoded
return url
def get_options():
"""Parse command line arguments and options."""
parser = argparse.ArgumentParser(
description='Create a Gerrit dashboard URL from specified dashboard '
'definition files')
parser.add_argument('dashboard_files', nargs='+',
metavar='dashboard_file',
help='Dashboard definition file to create URL from')
parser.add_argument('--template', default='single.txt',
help='Name of template')
parser.add_argument('--template-directory',
default=pkg_resources.resource_filename(
__name__, "templates"
), help='Directory to scan for template files')
parser.add_argument('--template-file', default=None,
help='Location of a specific template file')
return parser.parse_args()
def read_dashboard_file(fname):
"""Read and parse a dashboard definition from a specified file."""
dashboard = configparser.ConfigParser()
dashboard.readfp(open(fname))
return dashboard
def load_template(template_file=None, template_directory=None,
template_name=None):
"""Load the specified template."""
if template_file:
template_name = os.path.basename(template_file)
template_directory = os.path.dirname(os.path.abspath(template_file))
try:
loader = jinja2.FileSystemLoader(template_directory)
environment = jinja2.Environment(loader=loader)
template = environment.get_template(template_name)
except (jinja2.exceptions.TemplateError, IOError) as e:
print("error: opening template '%s' failed: %s" %
(template_name, e.__class__.__name__))
return
return template
def get_configuration(dashboard):
"""Returns the configuration of a dashboard as string."""
configuration = six.StringIO()
dashboard.write(configuration)
result = configuration.getvalue()
configuration.close()
return result
def main():
"""Entrypoint."""
result = 0
opts = get_options()
template = load_template(
template_file=opts.template_file,
template_directory=opts.template_directory,
template_name=opts.template
)
if not template:
return 1
for dashboard_file in opts.dashboard_files:
if (not os.path.isfile(dashboard_file) or
not os.access(dashboard_file, os.R_OK)):
print("\nerror: dashboard file '%s' is missing or is not "
"readable" % dashboard_file)
result = 1
continue
try:
dashboard = read_dashboard_file(dashboard_file)
except configparser.Error as e:
print("\nerror: dashboard file '%s' cannot be parsed\n\n%s" %
(dashboard_file, e))
return 1
continue
try:
url = generate_dashboard_url(dashboard)
except ValueError as e:
print("\nerror:\tgenerating dashboard '%s' failed\n\t%s" %
(dashboard_file, e))
result = 1
continue
variables = {
'title': dashboard.get('dashboard', 'title') or None,
'description': dashboard.get('dashboard', 'description') or None,
'url': url,
'filename': dashboard_file,
'configuration': get_configuration(dashboard)
}
print(template.render(variables))
return result
if __name__ == '__main__':
sys.exit(main())