Skip to content

Instantly share code, notes, and snippets.

@chmouel
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chmouel/1db66bd76e7fcbc7a13e to your computer and use it in GitHub Desktop.
Save chmouel/1db66bd76e7fcbc7a13e to your computer and use it in GitHub Desktop.
Take a openstack spec review and convert the rst in HTML (default) or PDF
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Chmouel Boudjnah <chmouel@chmouel.com>
#
# 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.
# Take a review openstack spec and convert the rst in HTML (default) or PDF
import argparse
import json
import os
import subprocess
import sys
import tempfile
import gerritlib.gerrit
import requests
USER = "chmouel"
KEY = "~/.ssh/id_rsa"
GERRIT_HOST = "review.openstack.org"
GERRIT_PORT = 29418
GITWEB_URL = 'https://review.openstack.org/gitweb'
OUTPUT_DIR = '/tmp'
DEFAULT_OUTPUT = 'html'
def which(program):
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file
raise Exception("cannot find " + program)
class SpecReviewPDF(object):
def __init__(self):
self.gerrit = None
def connect(self):
self.gerrit = gerritlib.gerrit.Gerrit(
self.host, self.username, self.port, self.keyfile)
def query_patchsets(self, review):
cmd = 'gerrit query --format json --files --patch-sets %s' % review
out, err = self.gerrit._ssh(cmd)
if not out:
return False
lines = out.split('\n')
if not lines:
return False
data = json.loads(lines[0])
if not data:
return False
return data
def convert_url(self, fname, url):
tmpfile = tempfile.NamedTemporaryFile(delete=False)
response = requests.get(url)
response.raise_for_status()
tmpfile.write(response.content)
tmpfile.close()
output_file = "%s/%s" % (self.output_dir,
os.path.basename(
fname.replace('.rst',
"." + self.output)))
print("writing %s" % output_file)
if self.output == 'html':
with open(output_file, 'w') as output_file_writer:
output = subprocess.check_output([which("rst2html.py"),
tmpfile.name])
output_file_writer.write(output)
elif self.output == 'pdf':
from rst2pdf import createpdf
cmdline = '-o %s %s' % (output_file, tmpfile.name)
createpdf.main(cmdline.split())
os.remove(tmpfile.name)
launcher = None
if os.path.exists("/usr/bin/xdg-open"):
launcher = "/usr/bin/xdg-open"
elif os.path.exists("/usr/bin/open"):
launcher = "/usr/bin/open"
if launcher:
os.system("%s %s" % (launcher, output_file))
def get_rst_files(self):
json = self.query_patchsets(self.review)
highest = 0
for patchset in json['patchSets']:
if int(patchset['number']) > highest:
revision = patchset['revision']
files = [pfile['file'] for pfile in patchset['files']
if pfile['file'].endswith('rst')]
for rst_file in files:
url = ("%(gitweb)s?p=%(project)s.git;a=blob_plain;"
"f=%(file)s;hb=%(revision)s" %
{'gitweb': self.gitweb_url,
'project': json['project'],
'revision': revision,
'file': rst_file})
self.convert_url(rst_file, url)
def parse_args(self, argv):
parser = argparse.ArgumentParser(
description='Convert a spec patchset to pdf',
)
parser.add_argument('-u', '--user', default=USER)
parser.add_argument('-k', '--key-file', default=KEY)
parser.add_argument('-H', '--gerrit-host', default=GERRIT_HOST)
parser.add_argument('-p', '--gerrit-port', default=GERRIT_PORT)
parser.add_argument('-g', '--gitweb_url', default=GITWEB_URL)
parser.add_argument('-o', '--output_dir', default=OUTPUT_DIR)
parser.add_argument('-O', '--output_writer',
help='output writer can be html or pdf',
default=DEFAULT_OUTPUT)
parser.add_argument('review', metavar="REVIEW_NUMBER",
type=int, help='The review number')
args = parser.parse_args(argv)
self.username = args.user
self.port = args.gerrit_port
self.keyfile = os.path.expanduser(args.key_file)
self.host = args.gerrit_host
self.gitweb_url = args.gitweb_url
self.review = args.review
self.output_dir = args.output_dir
self.output = args.output_writer
def main():
spec_review_pdf = SpecReviewPDF()
spec_review_pdf.parse_args(sys.argv[1:])
spec_review_pdf.connect()
spec_review_pdf.get_rst_files()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment