Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 228 lines (187 sloc) 9.15 KB
#!/usr/bin/env python
#!/usr/bin/env python
"""%prog [-o|--output-dir] [-c|--channels] [--aurora-suffix] [--beta-suffix] [--esr-suffix]
"""
from argparse import ArgumentParser
import sys
import psycopg2
import os
from datetime import datetime
import jinja2
from secrets import *
DEFAULT_CHANNELS = "Aurora,Beta,Release"
PRODUCTS = ['Firefox', 'Firefox for mobile']
ESR_PRODUCTS = ['Firefox ESR']
conn_string = "host='%s' dbname='%s' user='%s' password='%s'" % (DB_HOST, DB_NAME, DB_USER, DB_PASSWORD)
conn = psycopg2.connect(conn_string)
c = conn.cursor()
channel_info = {}
def cache_channels(aurora_suffix, beta_suffix, esr_suffix):
c.execute('SELECT r.version, r.sub_version, c.channel_name, p.product_name FROM "Releases" r '
'LEFT JOIN "Channels" c ON c.id = r.channel '
'LEFT JOIN "Products" p ON p.id = r.product '
'ORDER BY r.release_date DESC')
data = c.fetchall()
for record in data:
(version, sub_version, channel, product) = record
if channel not in channel_info:
channel_info[channel] = {'version': version,
'sub_version': sub_version}
if ('desktop-url' not in channel_info[channel] or
'mobile-url' not in channel_info[channel]) :
relname = 'releasenotes'
version_text = '%s.0' % version
if sub_version != 0:
version_text += '.%s' % sub_version
if channel == 'Aurora':
version_text = version_text + aurora_suffix
relname = 'auroranotes'
elif channel == 'Beta':
version_text = version_text + beta_suffix
elif channel == 'ESR':
version_text = version_text + esr_suffix
if product == 'Firefox ESR':
channel_info[channel]['desktop-url'] = 'en-US/firefox/%s/%s' % (version_text, relname)
else:
channel_info[channel]['mobile-url'] = 'en-US/mobile/%s/%s' % (version_text, relname)
if product == 'Firefox':
channel_info[channel]['desktop-url'] = 'en-US/firefox/%s/%s' % (version_text, relname)
else:
channel_info[channel]['mobile-url'] = 'en-US/mobile/%s/%s' % (version_text, relname)
def publish_channel(product_name, channel_name, out_base, aurora_suffix, beta_suffix, esr_suffix):
c.execute('SELECT id, product_text FROM "Products" WHERE product_name=%s LIMIT 1', (product_name,))
(product_id, product_text) = c.fetchone()
c.execute('SELECT id FROM "Channels" WHERE channel_name=%s LIMIT 1',
(channel_name,))
(channel_id,) = c.fetchone() or (None,)
c.execute('SELECT version, sub_version, release_date, release_text FROM "Releases" '
'WHERE product=%s AND channel=%s '
'ORDER BY release_date DESC LIMIT 1',
(product_id, channel_id))
(version, sub_version, release_date, release_text) = c.fetchone() or (None, None, None, None)
# for esr we just want the security fixes per subversion
if channel_name == 'ESR':
c.execute('SELECT n.description, t.tag_text FROM "Notes" n '
'LEFT OUTER JOIN "Tags" t ON n.tag=t.id '
'WHERE bug_num IS NULL AND '
'(product IS NULL OR product=%s) AND '
'fixed_in_subversion=%s AND '
'(fixed_in_channel=%s) '
'ORDER BY t.sort_num ASC, n.sort_num DESC',
(product_id, sub_version, channel_id))
else:
c.execute('SELECT n.description, t.tag_text FROM "Notes" n '
'LEFT OUTER JOIN "Tags" t ON n.tag=t.id '
'WHERE bug_num IS NULL AND '
'(product IS NULL OR product=%s) AND '
'fixed_in_version=%s AND '
'(fixed_in_channel IS NULL OR fixed_in_channel<=%s) '
'ORDER BY t.sort_num ASC, n.sort_num DESC',
(product_id, version, channel_id))
whats_new = c.fetchall()
# TODO to fix this for being able to create release notes earlier
# TODO get "Fixed" based on tag, not on bug num so we can put more bug num in db
c.execute('SELECT bug_num,description FROM "Notes" '
'WHERE bug_num IS NOT NULL AND '
'(product IS NULL OR product=%s) AND '
'fixed_in_version=%s AND '
'(fixed_in_channel IS NULL OR fixed_in_channel<=%s) '
'ORDER BY sort_num DESC',
(product_id, version, channel_id))
fixed = c.fetchall()
c.execute('SELECT n.bug_num, n.description, n.fixed_in_version, '
' n.fixed_in_channel, n.first_version, c.channel_name FROM "Notes" n '
'LEFT OUTER JOIN "Channels" c ON n.fixed_in_channel=c.id '
'WHERE bug_num IS NOT NULL AND '
'(product IS NULL OR product=%s) AND '
'(first_version<%s OR '
' (first_version=%s AND '
' (first_channel IS NULL OR first_channel<=%s))) AND '
'(fixed_in_version IS NULL OR fixed_in_version>%s OR '
' (fixed_in_version=%s AND fixed_in_channel>%s)) '
'ORDER BY sort_num DESC',
(product_id, version, version, channel_id, version, version, channel_id))
known_issues = c.fetchall()
# TODO - Integrating the different release's WN and FR pages into the output
is_mobile = (product_name == 'Firefox for mobile')
relname = 'releasenotes'
version_text = '%s.0' % version
if sub_version != 0:
version_text += '.%s' % sub_version
real_version_text = version_text
if channel == 'Aurora':
version_text = version_text + aurora_suffix
real_version_text = version_text
relname = 'auroranotes'
elif channel == 'Beta':
version_text = version_text + beta_suffix
real_version_text = version_text
elif channel == 'ESR':
version_text = version_text + esr_suffix
real_version_text = version_text
relname = 'releasenotes'
is_mobile = False
if is_mobile:
out_dir = 'en-US/mobile/%s/%s' % (real_version_text, relname)
else:
out_dir = 'en-US/firefox/%s/%s' % (real_version_text, relname)
out_file = '%s/index.html' % out_dir
try:
os.makedirs(os.path.join(out_base, out_dir));
except OSError: pass
env = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'))
tmpl = env.get_template(channel_name + '.html')
versions = dict([(i['version'],i) for (ch,i) in channel_info.iteritems()])
release_date = release_date.strftime("%B %d, %Y").replace(" 0", " ")
with file(os.path.join(out_base, out_file), 'w') as f:
f.write(tmpl.render({'is_mobile': is_mobile,
'release_date': release_date,
'version_text': version_text,
'version': version,
'whats_new': whats_new,
'fixed': fixed,
'known_issues': known_issues,
'release_text': release_text,
'product_text': product_text,
'versions': versions}).encode('utf-8'))
print 'Done: %s' % os.path.join(out_base, out_file)
if __name__ == '__main__':
parser = ArgumentParser(__doc__)
parser.set_defaults(
output_dir=None,
channels=DEFAULT_CHANNELS,
aurora_suffix='a2',
beta_suffix='beta',
esr_suffix='',
)
parser.add_argument("-o", "--output-dir", dest="output_dir",
help="specify a location for the generated files to be written to")
parser.add_argument("-c", "--channels", dest="channels",
help="comma-separated string of channels to create notes for")
parser.add_argument("--aurora-suffix", dest="aurora_suffix",
help="specify a specific suffix for aurora release")
parser.add_argument("--beta-suffix", dest="beta_suffix",
help="specify a specific suffix for beta release")
parser.add_argument("--esr-suffix", dest="esr_suffix",
help="specify a specific suffix for esr releases")
options, args = parser.parse_known_args()
if options.output_dir == None:
parser.error("Need to provide an output location")
channels = options.channels.split(',')
for channel in channels:
if channel not in DEFAULT_CHANNELS and channel != 'ESR':
channels.remove(channel)
if channel == 'Aurora' and options.aurora_suffix == None:
parser.error("Need to provide an Aurora suffix")
cache_channels(options.aurora_suffix, options.beta_suffix, options.esr_suffix)
for channel in channels:
if channel == 'ESR':
for product in ESR_PRODUCTS:
publish_channel(product, channel,
options.output_dir, options.aurora_suffix,
options.beta_suffix, options.esr_suffix)
else:
for product in PRODUCTS:
publish_channel(product, channel,
options.output_dir, options.aurora_suffix,
options.beta_suffix, options.esr_suffix)