diff --git a/ptulsconv/pdf/common.py b/ptulsconv/pdf/common.py index d4f9473..dc3d446 100644 --- a/ptulsconv/pdf/common.py +++ b/ptulsconv/pdf/common.py @@ -52,7 +52,7 @@ class GRect: return (GRect(self.min_x, self.min_y, at, self.height), GRect(self.min_x + at, self.y, self.width - at, self.height)) - def split_y(self, at, direction='u'): + def split_y(self, at, direction='u') : if at >= self.height: return None, self elif at <= 0: diff --git a/ptulsconv/pdf/line_count.py b/ptulsconv/pdf/line_count.py index 9cc0848..129b4a7 100644 --- a/ptulsconv/pdf/line_count.py +++ b/ptulsconv/pdf/line_count.py @@ -15,8 +15,149 @@ from .common import GRect import datetime -def output_report(records): +def build_columns(records, show_priorities = False): + columns = list() + reel_numbers = sorted(set([x.get('Reel', None) for x in records['events'] if 'Reel' in x.keys()])) + def blank_len(iter): + l = len(iter) + if l == 0: + return "" + else: + return str(l) + + def time_format(mins): + if mins < 60.: + return "%im" % round(mins) + else: + m = round(mins) + hh, mm = divmod(m, 60) + return "%ih%im" % (hh, mm) + + columns.append({ + 'heading': '#', + 'value_getter': lambda recs: recs[0]['Character Number'], + 'style_getter': lambda col_index: [], + 'width': 0.75 * inch + }) + + columns.append({ + 'heading': 'Role', + 'value_getter': lambda recs: recs[0]['Character Name'], + 'style_getter': lambda col_index: [], + 'width': 1.75 * inch + }) + + columns.append({ + 'heading': 'Actor', + 'value_getter': lambda recs: recs[0].get('Actor Name', ''), + 'style_getter': lambda col_index: [(('LINEAFTER'), (col_index, 0), (col_index, -1), 1.0, colors.black)], + 'width': 1.75 * inch + }) + + if len(reel_numbers) > 0: + columns.append({ + 'heading': 'RX', + 'value_getter': lambda recs: blank_len([r for r in recs if r.get('Reel', None) in ("", None)]), + 'style_getter': lambda col_index: [], + 'width': 0.5 * inch + }) + + for n in reel_numbers: + columns.append({ + 'heading': n, + 'value_getter': lambda recs: blank_len([r for r in recs if r['Reel'] == n]), + 'style_getter': lambda col_index: [], + 'width': 0.5 * inch + }) + + if show_priorities: + for n in range(1, 6,): + columns.append({ + 'heading': 'P%i' % n, + 'value_getter': lambda recs: blank_len([r for r in recs if r.get('Priority', None) == n]), + 'style_getter': lambda col_index: [], + 'width': 0.375 * inch + }) + + columns.append({ + 'heading': '>P5', + 'value_getter': lambda recs: blank_len([r for r in recs if r.get('Priority', 5) > 5]), + 'style_getter': lambda col_index: [], + 'width': 0.5 * inch + }) + + columns.append({ + 'heading': 'TV', + 'value_getter': lambda recs: blank_len([r for r in recs if 'TV' in r.keys()]), + 'style_getter': lambda col_index: [], + 'width': 0.5 * inch + }) + + columns.append({ + 'heading': 'OPT', + 'value_getter': lambda recs: blank_len([r for r in recs if 'Optional' in r.keys()]), + 'style_getter': lambda col_index: [], + 'width': 0.5 * inch + }) + + columns.append({ + 'heading': 'EFF', + 'value_getter': lambda recs: blank_len([r for r in recs if 'Effort' in r.keys()]), + 'style_getter': lambda col_index: [], + 'width': 0.5 * inch + }) + + columns.append({ + 'heading': 'Total', + 'value_getter': lambda recs: len([r for r in recs]), + 'style_getter': lambda col_index: [(('LINEBEFORE'), (col_index, 0), (col_index, -1), 1.0, colors.black), + ('ALIGN', (col_index, 0), (col_index, -1), 'RIGHT')], + 'width': inch + }) + + columns.append({ + 'heading': 'Studio Time', + 'value_getter': lambda recs: time_format(sum([r.get('Time Budget Mins', 0.) for r in recs])), + 'style_getter': lambda col_index: [('ALIGN', (col_index, 0), (col_index, -1), 'RIGHT')], + 'width': inch + }) + + return columns + + +def populate_columns(records, columns): + data = list() + styles = list() + columns_widths = list() + + sorted_character_numbers = sorted(set([x['CN'] for x in records['events']]), + key=lambda x: int(x)) + + # construct column styles + + for i, c in enumerate(columns): + styles.extend(c['style_getter'](i)) + columns_widths.append(c['width']) + + # construct data table + # headers + data.append(list(map(lambda x: x['heading'], columns))) + + # values + for n in sorted_character_numbers: + char_records = sorted([x for x in records['events'] if x['Character Number'] == n], + key=lambda x: x['PT.Clip.Start_Seconds']) + row_data = list() + for col in columns: + row_data.append(col['value_getter'](char_records)) + + data.append(row_data) + + return data, styles, columns_widths + + +def output_report(records): # CN # Role # Actor @@ -26,65 +167,29 @@ def output_report(records): # EFF # Total - reel_numbers = sorted(set([x.get('Reel', None) for x in records['events'] if 'Reel' in x.keys()])) - - aux_columns = [{'heading': 'OPT', 'key': 'Optional'}, - {'heading': 'TV', 'key': 'TV'}, - {'heading': 'EFF', 'key': 'Effort'}] - - sorted_character_numbers = sorted(set([x['CN'] for x in records['events']]), - key=lambda x: int(x)) + columns = build_columns(records) + data, style, columns_widths = populate_columns(records, columns) + style.append(('FONTNAME', [0, 0], (-1, -1), "Futura")) + style.append(('FONTSIZE', (0, 0), (-1, -1), 11)) + style.append(('LINEBELOW', (0, 0), (-1, 0), 1.0, colors.black)) + style.append(('LINEBELOW', (0, 1), (-1, -1), 0.25, colors.gray)) pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc')) page: GRect = GRect(0, 0, letter[1], letter[0]) page = page.inset(inch * 0.5) - - headers = ['#', 'Role', 'Actor'] - - if len(reel_numbers) > 0: - for n in reel_numbers: - headers.append(n) - - headers.append("Total") - - for m in aux_columns: - headers.append(m['heading']) - - line_count_data = [headers] - - - for cn in sorted_character_numbers: - this_row = [cn] - this_character_cues = [x for x in records['events'] if x['Character Number'] == cn] - this_row.append(this_character_cues[0].get('Character Name', "")) - this_row.append(this_character_cues[0].get('Actor Name', "")) - - if len(reel_numbers) > 0: - for _ in reel_numbers: - this_row.append("X") - - this_row.append(len([x for x in this_character_cues if 'Omit' not in x.keys()])) - for m in aux_columns: - this_row.append(0) - - line_count_data.append(this_row) - pass - - style = TableStyle([('FONTNAME', (0, 0), (-1, -1), 'Futura'), - ('FONTSIZE', (0, 0), (-1, -1), 11), - ('LINEBELOW', (0, 0), (-1, 0), 1.0, colors.black), - ('ALIGN', (3, 1), (-1, -1), 'RIGHT') - ] - ) - - table = Table(data=line_count_data, style=style, colWidths=[0.5 * inch, 1.25 * inch, 2. * inch, 0.5 * inch, - 0.5 * inch, 0.5 * inch, 0.5 * inch, 0.5 * inch]) + title_box, table_box = page.split_y(inch, 'd') c = Canvas('Line Count.pdf', pagesize=(letter[1], letter[0])) + c.setFont('Futura', 18.) + c.drawCentredString(title_box.center_x, title_box.center_y, "Line Count") - w, h = table.wrap(page.width, page.height) - table.drawOn(canvas=c, x=page.min_x, y=page.max_y - h) + table = Table(data=data, style=style, colWidths=columns_widths) + + w, h = table.wrap(table_box.width, table_box.height) + table.drawOn(canvas=c, + x=table_box.min_x + table_box.width / 2. - w / 2., + y=table_box.max_y - h) c.showPage() c.save()