Skip to content

Commit

Permalink
Start of a rewrite to produce google slides.
Browse files Browse the repository at this point in the history
  • Loading branch information
ralphbean committed Sep 7, 2017
1 parent a6cd3c0 commit 16658bb
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 49 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
*.pyc
venv
foo.md
16 changes: 16 additions & 0 deletions Makefile.factory
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
install:
test -d ~/node_modules/md2gslides/bin/ || npm install md2gslides
test -d venv || virtualenv venv
venv/bin/pip install -Ur requirements.txt

build: install
venv/bin/python finishline.py \
--insecure \
--server https://projects.engineering.redhat.com \
--project FACTORY \
--title "Factory 2.0, Sprint Review" \
--subtitle "Sprint #39" \
--template threebean/slides.md > foo.md

upload: build
~/node_modules/md2gslides/bin/md2gslides.js foo.md -e -a 1Riz9-XeqElrXlnu_vB5JS0nV-FoDv_oTmTAcl3emyuw
115 changes: 66 additions & 49 deletions finishline.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@

import bs4
import docutils.examples
import requests
import jinja2

import jira

date_format = '%Y-%m-%d'

custom_filters = {
'slugify': lambda x: x.lower().replace(' ', '-'),
Expand All @@ -24,81 +26,93 @@


def scrape_links(session, args):
response = session.get(args.url)
response = session.get(args.server)
soup = bs4.BeautifulSoup(response.text, 'html5lib')
return [l.text for l in soup.find(id='content').findAll('a')[5:]]


def parse_arguments():
two_weeks = datetime.timedelta(days=14)
default_since = (datetime.date.today() - two_weeks).strftime(date_format)
parser = argparse.ArgumentParser()
parser.add_argument('--url', help='HTTP-accessible directory where sprint videos and descriptions are stored.')
parser.add_argument('--server', help='server to your JIRA instance.')
parser.add_argument('--insecure', help='Do not verify SSL certs.',
default=False, action='store_true')
parser.add_argument('--project', help='JIRA project to report on.')
parser.add_argument('--since', help='Past date from which to pull data.',
default=default_since)
parser.add_argument('--title', help='Title of the report.')
parser.add_argument('--subtitle', help='Subtitle of the report.')
parser.add_argument('--template', help='Path to a template for output.')
parser.add_argument('--epicfield', help='Epic customfield key.',
default='customfield_10006')
args = parser.parse_args()
if not args.url:
raise ValueError('--url is required')
if not args.server:
raise ValueError('--server is required')
if not args.project:
raise ValueError('--project is required')
if not args.title:
raise ValueError('--title is required')
if not args.template:
raise ValueError('--template is required')
return args


def prepare(session, args, links):
get = lambda filename: session.get(args.url + '/' + filename).text
def render(args, data):
env = jinja2.Environment(
loader=jinja2.FileSystemLoader('templates'),
)
env.filters.update(custom_filters)
template = env.get_template(args.template)

try:
links.remove('readme.rst')
summary = get('readme.rst')
except ValueError:
summary = ''
data = data.copy()

collated = collections.defaultdict(dict)
for link in links:
key, extension = link.rsplit('.')
collated[key][extension] = link
data['today'] = datetime.datetime.utcnow().strftime(date_format)

entries = []
for key, items in collated.items():
try:
username, rest = key.split('-', 1)
except ValueError:
username, rest = key.split('_', 1)
data.update(args._get_kwargs())

heading = "%s, by %s" % (rest, username)
return template.render(**data)

extensions = items.keys()
try:
extensions.remove('rst')
body = get(items['rst'])
except ValueError:
body = None
def pull_issues(client, args):
tmpl = (
'project = %s'
' AND resolution is not EMPTY'
' AND resolutiondate >= %s'
' AND status != Dropped'
)
query = tmpl % (args.project, args.since)
issues = client.search_issues(query)
for issue in issues:
yield issue

assert(len(extensions) == 1)
link = items[extensions[0]]

entries.append((heading, body, args.url + '/' + link,))
def get_epic_details(client, key):
if not key:
return None
epic = client.issue(key)

entries.sort()
epic.image_url = 'https://placekitten.com/1600/900'

return dict(summary=summary, entries=entries)
epic.status_update = 'foo bar'
epic.status_update_date = '2017-01-01'

return epic

def render(args, data):
env = jinja2.Environment(
loader=jinja2.FileSystemLoader('templates'),
)
env.filters.update(custom_filters)
template = env.get_template(args.template)

data = data.copy()
def collate_issues(client, args, issues):
epics = {}
by_epic = collections.defaultdict(set)
for issue in issues:
epic = issue.raw['fields'][args.epicfield]

fmt = "%Y/%m/%d %H:%M:%S"
data['current_date'] = datetime.datetime.now().strftime(fmt)
# Enrich with details
if not epic in epics:
epics[epic] = get_epic_details(client, epic)

data.update(args._get_kwargs())
# Associate the issue with the enriched epic.
by_epic[epic].add(issue)

return template.render(**data)
return dict(epics=epics, by_epic=by_epic)


if __name__ == '__main__':
Expand All @@ -107,11 +121,14 @@ def render(args, data):

args = parse_arguments()

session = requests.session()

links = scrape_links(session, args)
client = jira.client.JIRA(
server=args.server,
options=dict(verify=not args.insecure),
kerberos=True,
)

data = prepare(session, args, links)
issues = pull_issues(client, args)
data = collate_issues(client, args, issues)

output = render(args, data)
print output.encode('utf-8')
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ docutils
html5lib
requests
jinja2
jira
requests_kerberos
22 changes: 22 additions & 0 deletions templates/threebean/slides.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# {{title}}
{% if subtitle %}
## {{subtitle}}
## {{today}}
### PnT DevOps
{% endif %}
---
{% for key, epic in epics.items() if epic %}
# [{{ epic.raw['fields']['customfield_10007'] }}]({{ server }}/browse/{{ key }})

{{ epic.raw['fields']['summary'] }}

{% if epic.status_update %}**Status**: (*{{epic.status_update_date}}*) {{epic.status_update}} {% endif %}
{% for issue in by_epic[key] %}
* {{ issue.raw['fields']['summary'].replace('[', '').replace(']', ':') }}
[{{ issue.key }}]({{ server }}/browse/{{ issue.key }})
{% endfor %}
{% if epic.image_url %}![]({{epic.image_url}}){.background}
{% endif %}
---
{% endfor %}
# Thank you

0 comments on commit 16658bb

Please sign in to comment.