diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
index abcf070..c8dded9 100644
--- a/.github/workflows/python-package.yml
+++ b/.github/workflows/python-package.yml
@@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- python-version: [3.7, 3.8, 3.9]
+ python-version: [3.7, 3.8, 3.9, "3.10"]
steps:
- uses: actions/checkout@v2
diff --git a/.gitignore b/.gitignore
index ac58e49..e7ef7c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -104,3 +104,4 @@ venv.bak/
.mypy_cache/
.DS_Store
/example/Charade/Session File Backups/
+lcov.info
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index a566bfe..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# Default ignored files
-/workspace.xml
-/tasks.xml
diff --git a/.idea/dictionaries/jamie.xml b/.idea/dictionaries/jamie.xml
deleted file mode 100644
index 07f35a2..0000000
--- a/.idea/dictionaries/jamie.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- adlib
- bottompadding
- fmpxml
- futura
- leftpadding
- lineafter
- linebefore
- ptulsconv
- retval
- smpte
- subheader
- timecode
- timespan
-
-
-
\ No newline at end of file
diff --git a/.idea/dictionaries/jamiehardt.xml b/.idea/dictionaries/jamiehardt.xml
deleted file mode 100644
index 8339c00..0000000
--- a/.idea/dictionaries/jamiehardt.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- fmpxmlresult
- frac
- mins
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 105ce2d..0000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index ce59ae2..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 922e7b3..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/ptulsconv.iml b/.idea/ptulsconv.iml
deleted file mode 100644
index cd0c393..0000000
--- a/.idea/ptulsconv.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/shelf/Uncommitted_changes_before_Update_at_5_20_21,_8_09_PM_[Default_Changelist]/Charade.ptx b/.idea/shelf/Uncommitted_changes_before_Update_at_5_20_21,_8_09_PM_[Default_Changelist]/Charade.ptx
deleted file mode 100644
index e3cb912..0000000
Binary files a/.idea/shelf/Uncommitted_changes_before_Update_at_5_20_21,_8_09_PM_[Default_Changelist]/Charade.ptx and /dev/null differ
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 94a25f7..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ptulsconv/__init__.py b/ptulsconv/__init__.py
index 8bb00ec..fc5dc5d 100644
--- a/ptulsconv/__init__.py
+++ b/ptulsconv/__init__.py
@@ -1,5 +1,5 @@
from ptulsconv.docparser.ptuls_grammar import protools_text_export_grammar
-__version__ = '0.8.2'
+__version__ = '0.8.3'
__author__ = 'Jamie Hardt'
__license__ = 'MIT'
diff --git a/ptulsconv/broadcast_timecode.py b/ptulsconv/broadcast_timecode.py
index 46bbc78..c0c6366 100644
--- a/ptulsconv/broadcast_timecode.py
+++ b/ptulsconv/broadcast_timecode.py
@@ -2,13 +2,16 @@ from fractions import Fraction
import re
import math
from collections import namedtuple
-
+from typing import Optional
class TimecodeFormat(namedtuple("_TimecodeFormat", "frame_duration logical_fps drop_frame")):
- def smpte_to_seconds(self, smpte: str) -> Fraction:
+ def smpte_to_seconds(self, smpte: str) -> Optional[Fraction]:
frame_count = smpte_to_frame_count(smpte, self.logical_fps, drop_frame_hint=self.drop_frame)
- return frame_count * self.frame_duration
+ if frame_count is None:
+ return None
+ else:
+ return frame_count * self.frame_duration
def seconds_to_smpte(self, seconds: Fraction) -> str:
frame_count = int(seconds / self.frame_duration)
@@ -28,7 +31,11 @@ def smpte_to_frame_count(smpte_rep_string: str, frames_per_logical_second: int,
"""
assert frames_per_logical_second in [24, 25, 30, 48, 50, 60]
- m = re.search("(\d?\d)[:;](\d\d)[:;](\d\d)([:;])(\d\d)(\.\d+)?", smpte_rep_string)
+ m = re.search(r'(\d?\d)[:;](\d\d)[:;](\d\d)([:;])(\d\d)(\.\d+)?', smpte_rep_string)
+
+ if m is None:
+ return None
+
hh, mm, ss, sep, ff, frac = m.groups()
hh, mm, ss, ff, frac = int(hh), int(mm), int(ss), int(ff), float(frac or 0.0)
@@ -81,7 +88,7 @@ def frame_count_to_smpte(frame_count: int, frames_per_logical_second: int, drop_
def footage_to_frame_count(footage_string):
- m = re.search("(\d+)\+(\d+)(\.\d+)?", footage_string)
+ m = re.search(r'(\d+)\+(\d+)(\.\d+)?', footage_string)
feet, frm, frac = m.groups()
feet, frm, frac = int(feet), int(frm), float(frac or 0.0)
diff --git a/ptulsconv/commands.py b/ptulsconv/commands.py
index cae642d..cc80979 100644
--- a/ptulsconv/commands.py
+++ b/ptulsconv/commands.py
@@ -126,7 +126,7 @@ def create_adr_reports(lines: List[ADRLine], tc_display_format: TimecodeFormat,
# return parsed
-def convert(input_file, major_mode='fmpxml', output=sys.stdout, warnings=True):
+def convert(input_file, major_mode, output=sys.stdout, warnings=True):
session = parse_document(input_file)
session_tc_format = session.header.timecode_format
diff --git a/ptulsconv/docparser/doc_entity.py b/ptulsconv/docparser/doc_entity.py
index 8fd1f76..04beb3e 100644
--- a/ptulsconv/docparser/doc_entity.py
+++ b/ptulsconv/docparser/doc_entity.py
@@ -21,7 +21,8 @@ class SessionDescriptor:
def markers_timed(self) -> Iterator[Tuple['MarkerDescriptor', Fraction]]:
for marker in self.markers:
- marker_time = self.header.convert_timecode(marker.location)
+ marker_time = Fraction(marker.time_reference, int(self.header.sample_rate))
+ #marker_time = self.header.convert_timecode(marker.location)
yield marker, marker_time
def tracks_clips(self) -> Iterator[Tuple['TrackDescriptor', 'TrackClipDescriptor']]:
diff --git a/ptulsconv/footage.py b/ptulsconv/footage.py
new file mode 100644
index 0000000..0d70bd0
--- /dev/null
+++ b/ptulsconv/footage.py
@@ -0,0 +1,20 @@
+from fractions import Fraction
+import re
+import math
+from collections import namedtuple
+from typing import Optional
+
+def footage_to_seconds(footage: str) -> Optional[Fraction]:
+ m = re.match(r'(\d+)\+(\d+)(\.\d+)?')
+ if m is None:
+ return None
+
+ feet, frames = m.groups()
+ feet, frames = int(feet), int(frames)
+
+ fps = 24
+ frames_per_foot = 16
+
+ total_frames = feet * 16 + frames
+
+ return Fraction(total_frames, fps)
\ No newline at end of file
diff --git a/ptulsconv/movie_export.py b/ptulsconv/movie_export.py
index c104ad6..c0f4fa3 100644
--- a/ptulsconv/movie_export.py
+++ b/ptulsconv/movie_export.py
@@ -1,4 +1,4 @@
-import ffmpeg # ffmpeg-python
+#import ffmpeg # ffmpeg-python
# TODO: Implement movie export
diff --git a/ptulsconv/pdf/__init__.py b/ptulsconv/pdf/__init__.py
index 3cd319c..cf17a3a 100644
--- a/ptulsconv/pdf/__init__.py
+++ b/ptulsconv/pdf/__init__.py
@@ -9,9 +9,11 @@ from reportlab.platypus.frames import Frame
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
+from typing import List
+
# TODO: A Generic report useful for spotting
# TODO: A report useful for M&E mixer's notes
-
+# TODO: Use a default font that doesn't need to be installed
# This is from https://code.activestate.com/recipes/576832/ for
# generating page count messages
@@ -36,7 +38,7 @@ class ReportCanvas(canvas.Canvas):
def draw_page_number(self, page_count):
self.saveState()
- self.setFont("Futura", 10)
+ self.setFont('Helvetica', 10) #FIXME make this customizable
self.drawString(0.5 * inch, 0.5 * inch, "Page %d of %d" % (self._pageNumber, page_count))
right_edge = self._pagesize[0] - 0.5 * inch
self.drawRightString(right_edge, 0.5 * inch, self._report_date.strftime("%m/%d/%Y %H:%M"))
@@ -60,7 +62,8 @@ def make_doc_template(page_size, filename, document_title,
document_header: str,
client: str,
document_subheader: str,
- left_margin=0.5 * inch) -> ADRDocTemplate:
+ left_margin=0.5 * inch,
+ fonts: List[TTFont] = []) -> ADRDocTemplate:
right_margin = top_margin = bottom_margin = 0.5 * inch
page_box = GRect(0., 0., page_size[0], page_size[1])
_, page_box = page_box.split_x(left_margin, direction='l')
@@ -71,16 +74,23 @@ def make_doc_template(page_size, filename, document_title,
footer_box, page_box = page_box.split_y(0.25 * inch, direction='u')
header_box, page_box = page_box.split_y(0.75 * inch, direction='d')
title_box, report_box = header_box.split_x(3.5 * inch, direction='r')
-
+
+ on_page_lambda = (lambda c, _:
+ draw_header_footer(c, report_box, title_box,
+ footer_box,title=title,
+ supervisor=supervisor,
+ document_subheader=document_subheader,
+ client=client, doc_title=document_header))
+
+ frames = [Frame(page_box.min_x, page_box.min_y, page_box.width, page_box.height)]
+
page_template = PageTemplate(id="Main",
- frames=[Frame(page_box.min_x, page_box.min_y, page_box.width, page_box.height)],
- onPage=lambda c, _: draw_header_footer(c, report_box, title_box, footer_box,
- title=title, supervisor=supervisor,
- document_subheader=document_subheader,
- client=client,
- doc_title=document_header))
+ frames=frames,
+ onPage=on_page_lambda)
+
+ for font in fonts:
+ pdfmetrics.registerFont(font)
- pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc'))
doc = ADRDocTemplate(filename,
title=document_title,
author=supervisor,
@@ -97,6 +107,8 @@ def time_format(mins, zero_str="-"):
"""
Formats a duration `mins` into a string
"""
+ if mins is None:
+ return zero_str
if mins == 0. and zero_str is not None:
return zero_str
elif mins < 60.:
@@ -108,11 +120,11 @@ def time_format(mins, zero_str="-"):
def draw_header_footer(a_canvas: ReportCanvas, left_box, right_box, footer_box, title: str, supervisor: str,
- document_subheader: str, client: str, doc_title=""):
+ document_subheader: str, client: str, doc_title="", font_name='Helvetica'):
(_supervisor_box, client_box,), title_box = right_box.divide_y([16., 16., ])
- title_box.draw_text_cell(a_canvas, title, "Futura", 18, inset_y=2., inset_x=5.)
- client_box.draw_text_cell(a_canvas, client, "Futura", 11, inset_y=2., inset_x=5.)
+ title_box.draw_text_cell(a_canvas, title, font_name, 18, inset_y=2., inset_x=5.)
+ client_box.draw_text_cell(a_canvas, client, font_name, 11, inset_y=2., inset_x=5.)
a_canvas.saveState()
a_canvas.setLineWidth(0.5)
@@ -129,13 +141,13 @@ def draw_header_footer(a_canvas: ReportCanvas, left_box, right_box, footer_box,
(doc_title_cell, spotting_version_cell,), _ = left_box.divide_y([18., 14], direction='d')
- doc_title_cell.draw_text_cell(a_canvas, doc_title, 'Futura', 14., inset_y=2.)
+ doc_title_cell.draw_text_cell(a_canvas, doc_title, font_name, 14., inset_y=2.)
if document_subheader is not None:
- spotting_version_cell.draw_text_cell(a_canvas, document_subheader, 'Futura', 12., inset_y=2.)
+ spotting_version_cell.draw_text_cell(a_canvas, document_subheader, font_name, 12., inset_y=2.)
if supervisor is not None:
- a_canvas.setFont('Futura', 11.)
+ a_canvas.setFont(font_name, 11.)
a_canvas.drawCentredString(footer_box.min_x + footer_box.width / 2., footer_box.min_y, supervisor)
diff --git a/ptulsconv/pdf/continuity.py b/ptulsconv/pdf/continuity.py
index 7e02d56..4cc4650 100644
--- a/ptulsconv/pdf/continuity.py
+++ b/ptulsconv/pdf/continuity.py
@@ -12,9 +12,9 @@ from ptulsconv.pdf import make_doc_template
# TODO: A Continuity
-def table_for_scene(scene, tc_format):
+def table_for_scene(scene, tc_format, font_name = 'Helvetica'):
scene_style = getSampleStyleSheet()['Normal']
- scene_style.fontName = 'Futura'
+ scene_style.fontName = font_name
scene_style.leftIndent = 0.
scene_style.leftPadding = 0.
scene_style.spaceAfter = 18.
@@ -29,7 +29,7 @@ def table_for_scene(scene, tc_format):
style = [('VALIGN', (0, 0), (-1, -1), 'TOP'),
('LEFTPADDING', (0, 0), (0, 0), 0.0),
('BOTTOMPADDING', (0, 0), (-1, -1), 12.),
- ('FONTNAME', (0, 0), (-1, -1), 'Futura')]
+ ('FONTNAME', (0, 0), (-1, -1), font_name)]
return Table(data=[row], style=style, colWidths=[1.0 * inch, 6.5 * inch])
diff --git a/ptulsconv/pdf/line_count.py b/ptulsconv/pdf/line_count.py
index 29bf4c8..d3f28a3 100644
--- a/ptulsconv/pdf/line_count.py
+++ b/ptulsconv/pdf/line_count.py
@@ -202,16 +202,16 @@ def populate_columns(lines: List[ADRLine], columns, include_omitted, _page_size)
def output_report(lines: List[ADRLine], reel_list: List[str], include_omitted=False,
- page_size=portrait(letter)):
+ page_size=portrait(letter), font_name='Helvetica'):
columns = build_columns(lines, include_omitted=include_omitted, reel_list=reel_list)
data, style, columns_widths = populate_columns(lines, columns, include_omitted, page_size)
- style.append(('FONTNAME', (0, 0), (-1, -1), "Futura"))
+ style.append(('FONTNAME', (0, 0), (-1, -1), font_name))
style.append(('FONTSIZE', (0, 0), (-1, -1), 9.))
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'))
+ #pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc'))
title = "%s Line Count" % lines[0].title
filename = title + '.pdf'
@@ -230,7 +230,7 @@ def output_report(lines: List[ADRLine], reel_list: List[str], include_omitted=Fa
story = [Spacer(height=0.5 * inch, width=1.), table]
style = getSampleStyleSheet()['Normal']
- style.fontName = 'Futura'
+ style.fontName = font_name
style.fontSize = 12.
style.spaceBefore = 16.
style.spaceAfter = 16.
diff --git a/ptulsconv/pdf/summary_log.py b/ptulsconv/pdf/summary_log.py
index 2c472d9..5d3fc2f 100644
--- a/ptulsconv/pdf/summary_log.py
+++ b/ptulsconv/pdf/summary_log.py
@@ -40,17 +40,17 @@ def build_aux_data_field(line: ADRLine):
return "
".join(entries)
-def build_story(lines: List[ADRLine], tc_rate: TimecodeFormat):
+def build_story(lines: List[ADRLine], tc_rate: TimecodeFormat, font_name='Helvetica'):
story = list()
this_scene = None
scene_style = getSampleStyleSheet()['Normal']
- scene_style.fontName = 'Futura'
+ scene_style.fontName = font_name
scene_style.leftIndent = 0.
scene_style.leftPadding = 0.
scene_style.spaceAfter = 18.
line_style = getSampleStyleSheet()['Normal']
- line_style.fontName = 'Futura'
+ line_style.fontName = font_name
for line in lines:
table_style = [('VALIGN', (0, 0), (-1, -1), 'TOP'),
diff --git a/ptulsconv/pdf/supervisor_1pg.py b/ptulsconv/pdf/supervisor_1pg.py
index 1b7e015..b3828c9 100644
--- a/ptulsconv/pdf/supervisor_1pg.py
+++ b/ptulsconv/pdf/supervisor_1pg.py
@@ -11,11 +11,12 @@ from reportlab.platypus import Paragraph
from .__init__ import GRect
-from ptulsconv.broadcast_timecode import TimecodeFormat
+from ptulsconv.broadcast_timecode import TimecodeFormat, footage_to_frame_count
from ptulsconv.docparser.adr_entity import ADRLine
import datetime
+font_name = 'Helvetica'
def draw_header_block(canvas, rect, record: ADRLine):
rect.draw_text_cell(canvas, record.cue_number, "Helvetica", 44, vertical_align='m')
@@ -23,19 +24,19 @@ def draw_header_block(canvas, rect, record: ADRLine):
def draw_character_row(canvas, rect, record: ADRLine):
label_frame, value_frame = rect.split_x(1.25 * inch)
- label_frame.draw_text_cell(canvas, "CHARACTER", "Futura", 10, force_baseline=9.)
+ label_frame.draw_text_cell(canvas, "CHARACTER", font_name, 10, force_baseline=9.)
line = "%s / %s" % (record.character_id, record.character_name)
if record.actor_name is not None:
line = line + " / " + record.actor_name
- value_frame.draw_text_cell(canvas, line, "Futura", 12, force_baseline=9.)
+ value_frame.draw_text_cell(canvas, line, font_name, 12, force_baseline=9.)
rect.draw_border(canvas, ['min_y', 'max_y'])
def draw_cue_number_block(canvas, rect, record: ADRLine):
(label_frame, number_frame,), aux_frame = rect.divide_y([0.20 * inch, 0.375 * inch], direction='d')
- label_frame.draw_text_cell(canvas, "CUE NUMBER", "Futura", 10,
+ label_frame.draw_text_cell(canvas, "CUE NUMBER", font_name, 10,
inset_y=5., vertical_align='t')
- number_frame.draw_text_cell(canvas, record.cue_number, "Futura", 14,
+ number_frame.draw_text_cell(canvas, record.cue_number, font_name, 14,
inset_x=10., inset_y=2., draw_baseline=True)
tags = {'tv': 'TV',
@@ -49,7 +50,7 @@ def draw_cue_number_block(canvas, rect, record: ADRLine):
if getattr(record, key):
tag_field = tag_field + tags[key] + " "
- aux_frame.draw_text_cell(canvas, tag_field, "Futura", 10,
+ aux_frame.draw_text_cell(canvas, tag_field, font_name, 10,
inset_x=10., inset_y=2., vertical_align='t')
rect.draw_border(canvas, 'max_x')
@@ -58,13 +59,13 @@ def draw_timecode_block(canvas, rect, record: ADRLine, tc_display_format: Timeco
(in_label_frame, in_frame, out_label_frame, out_frame), _ = rect.divide_y(
[0.20 * inch, 0.25 * inch, 0.20 * inch, 0.25 * inch], direction='d')
- in_label_frame.draw_text_cell(canvas, "IN", "Futura", 10,
+ in_label_frame.draw_text_cell(canvas, "IN", font_name, 10,
vertical_align='t', inset_y=5., inset_x=5.)
- in_frame.draw_text_cell(canvas, tc_display_format.seconds_to_smpte(record.start), "Futura", 14,
+ in_frame.draw_text_cell(canvas, tc_display_format.seconds_to_smpte(record.start), font_name, 14,
inset_x=10., inset_y=2., draw_baseline=True)
- out_label_frame.draw_text_cell(canvas, "OUT", "Futura", 10,
+ out_label_frame.draw_text_cell(canvas, "OUT", font_name, 10,
vertical_align='t', inset_y=5., inset_x=5.)
- out_frame.draw_text_cell(canvas, tc_display_format.seconds_to_smpte(record.finish), "Futura", 14,
+ out_frame.draw_text_cell(canvas, tc_display_format.seconds_to_smpte(record.finish), font_name, 14,
inset_x=10., inset_y=2., draw_baseline=True)
rect.draw_border(canvas, 'max_x')
@@ -75,16 +76,16 @@ def draw_reason_block(canvas, rect, record: ADRLine):
reason_label, reason_value = reason_cell.split_x(.75 * inch)
notes_label, notes_value = notes_cell.split_x(.75 * inch)
- reason_label.draw_text_cell(canvas, "Reason:", "Futura", 12,
+ reason_label.draw_text_cell(canvas, "Reason:", font_name, 12,
inset_x=5., inset_y=5., vertical_align='b')
- reason_value.draw_text_cell(canvas, record.reason or "", "Futura", 12,
+ reason_value.draw_text_cell(canvas, record.reason or "", font_name, 12,
inset_x=5., inset_y=5., draw_baseline=True,
vertical_align='b')
- notes_label.draw_text_cell(canvas, "Note:", "Futura", 12,
+ notes_label.draw_text_cell(canvas, "Note:", font_name, 12,
inset_x=5., inset_y=5., vertical_align='t')
style = getSampleStyleSheet()['BodyText']
- style.fontName = 'Futura'
+ style.fontName = font_name
style.fontSize = 12
style.leading = 14
@@ -96,10 +97,10 @@ def draw_reason_block(canvas, rect, record: ADRLine):
def draw_prompt(canvas, rect, prompt=""):
label, block = rect.split_y(0.20 * inch, direction='d')
- label.draw_text_cell(canvas, "PROMPT", "Futura", 10, vertical_align='t', inset_y=5., inset_x=0.)
+ label.draw_text_cell(canvas, "PROMPT", font_name, 10, vertical_align='t', inset_y=5., inset_x=0.)
style = getSampleStyleSheet()['BodyText']
- style.fontName = 'Futura'
+ style.fontName = font_name
style.fontSize = 14
style.leading = 24
@@ -116,10 +117,10 @@ def draw_prompt(canvas, rect, prompt=""):
def draw_notes(canvas, rect, note=""):
label, block = rect.split_y(0.20 * inch, direction='d')
- label.draw_text_cell(canvas, "NOTES", "Futura", 10, vertical_align='t', inset_y=5., inset_x=0.)
+ label.draw_text_cell(canvas, "NOTES", font_name, 10, vertical_align='t', inset_y=5., inset_x=0.)
style = getSampleStyleSheet()['BodyText']
- style.fontName = 'Futura'
+ style.fontName = font_name
style.fontSize = 14
style.leading = 24
@@ -175,12 +176,12 @@ def draw_aux_block(canvas, rect, recording_time_sec_this_line, recording_time_se
lines, last_line = content_rect.divide_y([12., 12., 24., 24., 24., 24.], direction='d')
lines[0].draw_text_cell(canvas,
- "Time for this line: %.1f mins" % (recording_time_sec_this_line / 60.), "Futura", 9.)
- lines[1].draw_text_cell(canvas, "Running time: %03.1f mins" % (recording_time_sec / 60.), "Futura", 9.)
- lines[2].draw_text_cell(canvas, "Actual Start: ______________", "Futura", 9., vertical_align='b')
- lines[3].draw_text_cell(canvas, "Record Date: ______________", "Futura", 9., vertical_align='b')
- lines[4].draw_text_cell(canvas, "Engineer: ______________", "Futura", 9., vertical_align='b')
- lines[5].draw_text_cell(canvas, "Location: ______________", "Futura", 9., vertical_align='b')
+ "Time for this line: %.1f mins" % (recording_time_sec_this_line / 60.), font_name, 9.)
+ lines[1].draw_text_cell(canvas, "Running time: %03.1f mins" % (recording_time_sec / 60.), font_name, 9.)
+ lines[2].draw_text_cell(canvas, "Actual Start: ______________", font_name, 9., vertical_align='b')
+ lines[3].draw_text_cell(canvas, "Record Date: ______________", font_name, 9., vertical_align='b')
+ lines[4].draw_text_cell(canvas, "Engineer: ______________", font_name, 9., vertical_align='b')
+ lines[5].draw_text_cell(canvas, "Location: ______________", font_name, 9., vertical_align='b')
def draw_footer(canvas, rect, record: ADRLine, report_date, line_no, total_lines):
@@ -189,7 +190,7 @@ def draw_footer(canvas, rect, record: ADRLine, report_date, line_no, total_lines
spotting_name = [record.spot] if record.spot is not None else []
pages_s = ["Line %i of %i" % (line_no, total_lines)]
footer_s = " - ".join(report_date_s + spotting_name + pages_s)
- rect.draw_text_cell(canvas, footer_s, font_name="Futura", font_size=10., inset_y=2.)
+ rect.draw_text_cell(canvas, footer_s, font_name=font_name, font_size=10., inset_y=2.)
def create_report_for_character(records, report_date, tc_display_format: TimecodeFormat):
@@ -200,7 +201,7 @@ def create_report_for_character(records, report_date, tc_display_format: Timecod
assert outfile is not None
assert outfile[-4:] == '.pdf', "Output file must have 'pdf' extension!"
- pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc'))
+ #pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc'))
page: GRect = GRect(0, 0, letter[0], letter[1])
page = page.inset(inch * 0.5)
diff --git a/ptulsconv/pdf/talent_sides.py b/ptulsconv/pdf/talent_sides.py
index e3b3e60..aed7933 100644
--- a/ptulsconv/pdf/talent_sides.py
+++ b/ptulsconv/pdf/talent_sides.py
@@ -16,9 +16,9 @@ from ..broadcast_timecode import TimecodeFormat
from ..docparser.adr_entity import ADRLine
-def output_report(lines: List[ADRLine], tc_display_format: TimecodeFormat):
+def output_report(lines: List[ADRLine], tc_display_format: TimecodeFormat, font_name="Helvetica"):
character_numbers = set([n.character_id for n in lines])
- pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc'))
+ #pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc'))
for n in character_numbers:
char_lines = [line for line in lines if not line.omitted and line.character_id == n]
@@ -39,7 +39,7 @@ def output_report(lines: List[ADRLine], tc_display_format: TimecodeFormat):
story = []
prompt_style = getSampleStyleSheet()['Normal']
- prompt_style.fontName = 'Futura'
+ prompt_style.fontName = font_name
prompt_style.fontSize = 18.
prompt_style.leading = 24.
@@ -47,7 +47,7 @@ def output_report(lines: List[ADRLine], tc_display_format: TimecodeFormat):
prompt_style.rightIndent = 1.5 * inch
number_style = getSampleStyleSheet()['Normal']
- number_style.fontName = 'Futura'
+ number_style.fontName = font_name
number_style.fontSize = 14
number_style.leading = 24
diff --git a/setup.py b/setup.py
index 4382a7c..a5220c7 100644
--- a/setup.py
+++ b/setup.py
@@ -26,6 +26,7 @@ setup(name='ptulsconv',
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
"Development Status :: 4 - Beta",
"Topic :: Text Processing :: Filters"],
packages=['ptulsconv'],
diff --git a/test-coverage.sh b/test-coverage.sh
new file mode 100755
index 0000000..5b7dca1
--- /dev/null
+++ b/test-coverage.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+coverage run -m pytest . ; coverage-lcov
+
diff --git a/tests/test_robinhood1.py b/tests/export_tests/test_robinhood1.py
similarity index 97%
rename from tests/test_robinhood1.py
rename to tests/export_tests/test_robinhood1.py
index cbe8ed1..38b128e 100644
--- a/tests/test_robinhood1.py
+++ b/tests/export_tests/test_robinhood1.py
@@ -4,7 +4,7 @@ import os.path
class TestRobinHood1(unittest.TestCase):
- path = os.path.dirname(__file__) + '/export_cases/Robin Hood Spotting.txt'
+ path = os.path.dirname(__file__) + '/../export_cases/Robin Hood Spotting.txt'
def test_header_export(self):
diff --git a/tests/test_robinhood5.py b/tests/export_tests/test_robinhood5.py
similarity index 95%
rename from tests/test_robinhood5.py
rename to tests/export_tests/test_robinhood5.py
index e38e040..99ebd4d 100644
--- a/tests/test_robinhood5.py
+++ b/tests/export_tests/test_robinhood5.py
@@ -4,7 +4,7 @@ import os.path
class TestRobinHood5(unittest.TestCase):
- path = os.path.dirname(__file__) + '/export_cases/Robin Hood Spotting5.txt'
+ path = os.path.dirname(__file__) + '/../export_cases/Robin Hood Spotting5.txt'
def test_skipped_segments(self):
session = parse_document(self.path)
diff --git a/tests/test_robinhood6.py b/tests/export_tests/test_robinhood6.py
similarity index 94%
rename from tests/test_robinhood6.py
rename to tests/export_tests/test_robinhood6.py
index 024f662..55e5373 100644
--- a/tests/test_robinhood6.py
+++ b/tests/export_tests/test_robinhood6.py
@@ -4,7 +4,7 @@ import os.path
class TestRobinHood6(unittest.TestCase):
- path = os.path.dirname(__file__) + '/export_cases/Robin Hood Spotting6.txt'
+ path = os.path.dirname(__file__) + '/../export_cases/Robin Hood Spotting6.txt'
def test_a_track(self):
session = parse_document(self.path)
diff --git a/tests/test_robinhooddf.py b/tests/export_tests/test_robinhooddf.py
similarity index 93%
rename from tests/test_robinhooddf.py
rename to tests/export_tests/test_robinhooddf.py
index d92a2d1..bb8070a 100644
--- a/tests/test_robinhooddf.py
+++ b/tests/export_tests/test_robinhooddf.py
@@ -4,7 +4,7 @@ import os.path
class TestRobinHoodDF(unittest.TestCase):
- path = os.path.dirname(__file__) + '/export_cases/Robin Hood SpottingDF.txt'
+ path = os.path.dirname(__file__) + '/../export_cases/Robin Hood SpottingDF.txt'
def test_header_export_df(self):
session = parse_document(self.path)
diff --git a/tests/functional/test_pdf_export.py b/tests/functional/test_pdf_export.py
new file mode 100644
index 0000000..1261f3d
--- /dev/null
+++ b/tests/functional/test_pdf_export.py
@@ -0,0 +1,34 @@
+import unittest
+
+import tempfile
+
+import os.path
+import os
+import glob
+
+from ptulsconv import commands
+
+class TestBroadcastTimecode(unittest.TestCase):
+ def test_report_generation(self):
+ """
+ Setp through every text file in export_cases and make sure it can
+ be converted into PDF docs without throwing an error
+ """
+ files = [os.path.dirname(__file__) + "/../export_cases/Robin Hood Spotting.txt"]
+ #files.append(os.path.dirname(__file__) + "/../export_cases/Robin Hood Spotting2.txt")
+ for path in files:
+ tempdir = tempfile.TemporaryDirectory()
+ os.chdir(tempdir.name)
+ try:
+ commands.convert(path, major_mode='doc')
+ except:
+ assert False, "Error processing file %s" % path
+ finally:
+ tempdir.cleanup()
+
+
+
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_adr_entity.py b/tests/unittests/test_adr_entity.py
similarity index 100%
rename from tests/test_adr_entity.py
rename to tests/unittests/test_adr_entity.py
diff --git a/tests/test_broadcast_timecode.py b/tests/unittests/test_broadcast_timecode.py
similarity index 100%
rename from tests/test_broadcast_timecode.py
rename to tests/unittests/test_broadcast_timecode.py
diff --git a/tests/test_doc_entities.py b/tests/unittests/test_doc_entities.py
similarity index 100%
rename from tests/test_doc_entities.py
rename to tests/unittests/test_doc_entities.py
diff --git a/tests/test_tag_compiler.py b/tests/unittests/test_tag_compiler.py
similarity index 99%
rename from tests/test_tag_compiler.py
rename to tests/unittests/test_tag_compiler.py
index 78c6b2e..db4e4fb 100644
--- a/tests/test_tag_compiler.py
+++ b/tests/unittests/test_tag_compiler.py
@@ -97,14 +97,14 @@ class TestTagCompiler(unittest.TestCase):
markers = [doc_entity.MarkerDescriptor(number=1,
location="01:00:00:00",
- time_reference=48000 * 60,
+ time_reference=48000 * 3600,
units="Samples",
name="Marker 1 {Part=1}",
comments=""
),
doc_entity.MarkerDescriptor(number=2,
location="01:00:01:00",
- time_reference=48000 * 61,
+ time_reference=48000 * 3601,
units="Samples",
name="Marker 2 {Part=2}",
comments="[M1]"
diff --git a/tests/test_tag_interpreter.py b/tests/unittests/test_tag_interpreter.py
similarity index 100%
rename from tests/test_tag_interpreter.py
rename to tests/unittests/test_tag_interpreter.py
diff --git a/tests/test_tagging.py b/tests/unittests/test_tagging.py
similarity index 97%
rename from tests/test_tagging.py
rename to tests/unittests/test_tagging.py
index b6ffc18..34fcc29 100644
--- a/tests/test_tagging.py
+++ b/tests/unittests/test_tagging.py
@@ -4,7 +4,7 @@ import os.path
class TaggingIntegratedTests(unittest.TestCase):
- path = os.path.dirname(__file__) + '/export_cases/Tag Tests/Tag Tests.txt'
+ path = os.path.dirname(__file__) + '/../export_cases/Tag Tests/Tag Tests.txt'
def test_event_list(self):
with open(self.path, 'r') as f:
diff --git a/tests/test_utils.py b/tests/unittests/test_utils.py
similarity index 100%
rename from tests/test_utils.py
rename to tests/unittests/test_utils.py