Compare commits

..

8 Commits

Author SHA1 Message Date
Jamie Hardt 9349f4ba1e Add Python 3.14 support (#21)
* Update pyproject.toml

Nudged version again

* Update python-package.yml

* Delete toot.yml

* Update pyproject.toml

Added verion 3.14 to classifiers

---------

Co-authored-by: Jamie Hardt <jamie@squad51.us>
2026-09-19 16:42:06 -07:00
Jamie Hardt e0e3024280 Bug ruff 2026 (#19)
* Updated Ruff to v0.16 and fixed for default checks 

* Nudge version and removed license classifier

---------

Co-authored-by: Jamie Hardt <jamie@squad51.us>
2026-09-19 16:35:56 -07:00
Jamie Hardt 2fc8a653cd Update .readthedocs.yaml
Removing dead lines
2026-09-17 21:07:26 -07:00
Jamie Hardt 183a7ef687 Update .readthedocs.yaml 2026-09-17 21:06:06 -07:00
Jamie Hardt e0fe946455 Update .readthedocs.yaml 2026-09-17 21:02:20 -07:00
Jamie Hardt 12ecb86bdf Docs update (#20)
* Update .readthedocs.yaml

Updated RTD version to `ubuntu-lts-latest`

* Update .readthedocs.yaml

RTD config fix
2026-09-17 20:57:00 -07:00
Jamie Hardt 6f2367c9fd Update pyproject.toml 2026-09-17 20:52:45 -07:00
jamie 8a23d7c702 Merge branch 'master' of https://github.com/iluvcapra/ptulsconv 2026-09-17 20:46:57 -07:00
18 changed files with 139 additions and 198 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v2.5.0
-22
View File
@@ -1,22 +0,0 @@
name: Test Toot
on:
workflow_dispatch:
jobs:
print-tag:
runs-on: ubuntu-latest
steps:
- name: Report to Mastodon
uses: cbrgm/mastodon-github-action@v1.0.1
env:
MASTODON_URL: ${{ secrets.MASTODON_URL }}
MASTODON_ACCESS_TOKEN: ${{ secrets.MASTODON_ACCESS_TOKEN }}
with:
message: |
This is a test toot, automatically posted by a github action.
${{ github.server_url }}/${{ github.repository }}
${{ github.ref }}
-16
View File
@@ -14,9 +14,6 @@ build:
pre_install:
- pip install --upgrade pip
- pip install --upgrade --upgrade-strategy only-if-needed --group doc .
# build:
# html:
# - python -m sphinx -T -b html -d _build/doctrees -D language=en . $READTHEDOCS_OUTPUT/html
post_build:
- echo "Command run at 'post_build' step"
- echo `date`
@@ -29,16 +26,3 @@ sphinx:
#If using Sphinx, optionally build your docs in additional formats such as PDF
formats:
- pdf
# FIXME: We should be installing the `doc` dependency group and not the `doc`
# extra.
#Optionally declare the Python requirements required to build your docs
python:
install:
- method: pip
path: .
extra_requirements:
- doc
+2 -2
View File
@@ -1,6 +1,6 @@
[project]
name = "ptulsconv"
version = "4.0.0"
version = "4.0.2"
description = "Read Pro Tools Text exports and generate PDF ADR Reports, JSON"
readme = "README.md"
requires-python = ">=3.9"
@@ -9,7 +9,6 @@ license-files = ["LICENSE"]
keywords = ["text-processing", "parsers", "film",
"broadcast", "editing", "editorial"]
classifiers = [
'License :: OSI Approved :: MIT License',
'Topic :: Multimedia',
'Topic :: Multimedia :: Sound/Audio',
"Programming Language :: Python :: 3.9",
@@ -17,6 +16,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Development Status :: 5 - Production/Stable",
"Topic :: Text Processing :: Filters"
]
+2 -5
View File
@@ -9,7 +9,6 @@ from ptulsconv.commands import convert
from ptulsconv.docparser.adr_entity import ADR_TAG_MAPPING, GENERIC_TAG_MAPPING
from ptulsconv.reporting import (
print_banner_style,
print_fatal_error,
print_section_header_style,
print_status_style,
)
@@ -111,7 +110,7 @@ def main():
elif options.show_formats:
dump_formats()
sys.exit(0)
try:
major_mode = options.output_format
if len(args) < 2:
@@ -120,9 +119,7 @@ def main():
)
convert(major_mode=major_mode, warnings=options.warnings)
else:
convert(
input_file=args[1], major_mode=major_mode, warnings=options.warnings
)
convert(input_file=args[1], major_mode=major_mode, warnings=options.warnings)
if __name__ == "__main__":
+7 -6
View File
@@ -6,18 +6,19 @@ from __future__ import annotations
import math
import re
from collections import namedtuple
from fractions import Fraction
from typing import SupportsFloat
from typing import NamedTuple
class TimecodeFormat(
namedtuple("_TimecodeFormat", "frame_duration logical_fps drop_frame")
):
class TimecodeFormat(NamedTuple):
"""
A struct reperesenting a timecode datum.
"""
frame_duration: Fraction
logical_fps: int
drop_frame: bool
def smpte_to_seconds(self, smpte: str) -> Fraction | None:
frame_count = smpte_to_frame_count(
smpte, self.logical_fps, drop_frame_hint=self.drop_frame
@@ -27,7 +28,7 @@ class TimecodeFormat(
else:
return frame_count * self.frame_duration
def seconds_to_smpte(self, seconds: SupportsFloat) -> str:
def seconds_to_smpte(self, seconds: Fraction) -> str:
frame_count = int(seconds / self.frame_duration)
return frame_count_to_smpte(frame_count, self.logical_fps, self.drop_frame)
-1
View File
@@ -13,7 +13,6 @@ from collections.abc import Iterator
from fractions import Fraction
from itertools import chain
from json import JSONEncoder
from zoneinfo import ZoneInfo
import ptsl
+1 -4
View File
@@ -2,7 +2,4 @@
Docparser module
"""
from .pt_doc_parser import parse_document
__all__ = [parse_document]
from .pt_doc_parser import parse_document # pyright: ignore[reportUnusedImport, reportUnusedImport] # noqa: F401, I001
+11 -9
View File
@@ -1,10 +1,9 @@
from __future__ import annotations
from collections import namedtuple
from collections.abc import Generator, Iterator
from dataclasses import dataclass
from fractions import Fraction
from typing import Callable
from typing import Callable, NamedTuple
from ptulsconv.docparser import doc_entity
@@ -27,12 +26,15 @@ class TagCompiler:
items.
"""
Intermediate = namedtuple(
"Intermediate",
"track_content track_tags track_comment_tags "
"clip_content clip_tags clip_tag_mode start "
"finish",
)
class Intermediate(NamedTuple):
track_content: str
clip_content: str
track_tags: dict[str, str]
track_comment_tags: dict[str, str]
clip_tags: dict[str, str]
clip_tag_mode: TagPreModes
start: Fraction
finish: Fraction
session: doc_entity.SessionDescriptor
@@ -181,7 +183,7 @@ class TagCompiler:
if item.clip_tag_mode == TagPreModes.TIMESPAN:
time_spans.append((item.clip_tags, item.start, item.finish))
else:
yield item, list(time_spans)
yield item, tuple(time_spans)
@staticmethod
def _time_span_tags(at_time: Fraction, applicable_spans) -> dict:
@@ -1,5 +1,4 @@
from enum import Enum
from typing import Dict
from parsimonious import Grammar, NodeVisitor
@@ -37,7 +36,7 @@ def parse_tags(prompt: str) -> "TaggedStringResult":
class TaggedStringResult:
content: str
tag_dict: Dict[str, str]
tag_dict: dict[str, str]
mode: TagPreModes
def __init__(self, content, tag_dict, mode):
@@ -53,7 +52,7 @@ class TagListVisitor(NodeVisitor):
return TaggedStringResult(
content=next(iter(line_opt), None),
tag_dict=next(iter(tag_list_opt), dict()),
tag_dict=next(iter(tag_list_opt), {}),
mode=TagPreModes(next(iter(modifier_opt), "Normal")),
)
@@ -74,7 +73,7 @@ class TagListVisitor(NodeVisitor):
@staticmethod
def visit_tag_list(_, visited_children):
retdict = dict()
retdict = {}
for child in visited_children:
if child[0] is not None:
k, v = child[0]
+1
View File
@@ -1,6 +1,7 @@
"""
Methods for converting string reprentations of film footage.
"""
from __future__ import annotations
import re
+21 -16
View File
@@ -26,7 +26,7 @@ class ReportCanvas(canvas.Canvas):
def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
self._startPage()
self._startPage() # pyright: ignore[reportAttributeAccessIssue]
def save(self):
"""add page info to each page (page x of y)"""
@@ -41,9 +41,11 @@ class ReportCanvas(canvas.Canvas):
self.saveState()
self.setFont("Helvetica", 10) # FIXME make this customizable
self.drawString(
0.5 * inch, 0.5 * inch, "Page %d of %d" % (self._pageNumber, page_count)
0.5 * inch,
0.5 * inch,
f"Page {self._pageNumber} of {page_count}", # pyright: ignore[reportAttributeAccessIssue]
)
right_edge = self._pagesize[0] - 0.5 * inch
right_edge = self._pagesize[0] - 0.5 * inch # pyright: ignore[reportAttributeAccessIssue]
self.drawRightString(
right_edge, 0.5 * inch, self._report_date.strftime("%m/%d/%Y %H:%M")
)
@@ -62,7 +64,7 @@ class ADRDocTemplate(BaseDocTemplate):
def make_doc_template(
page_size,
page_size: tuple[float, float],
filename,
document_title,
title: str,
@@ -71,18 +73,22 @@ def make_doc_template(
client: str,
document_subheader: str,
left_margin=0.5 * inch,
fonts: list[TTFont] = [],
fonts: list[TTFont] | None = None,
) -> ADRDocTemplate:
if fonts is None:
fonts = []
right_margin = top_margin = bottom_margin = 0.5 * inch
page_box: GRect = GRect(0.0, 0.0, page_size[0], page_size[1])
_, page_box = page_box.split_x(left_margin, direction="l")
_, page_box = page_box.split_x(right_margin, direction="r")
_, page_box = page_box.split_y(bottom_margin, direction="u")
_, page_box = page_box.split_y(top_margin, direction="d")
_, page_box = page_box.split_x(left_margin, direction="l") # pyright: ignore[reportAssignmentType]
_, page_box = page_box.split_x(right_margin, direction="r") # pyright: ignore[reportAssignmentType]
_, page_box = page_box.split_y(bottom_margin, direction="u") # pyright: ignore[reportAssignmentType]
_, page_box = page_box.split_y(top_margin, direction="d") # pyright: ignore[reportAssignmentType]
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")
footer_box, page_box = page_box.split_y(0.25 * inch, direction="u") # pyright: ignore[reportAssignmentType]
header_box, page_box = page_box.split_y(0.75 * inch, direction="d") # pyright: ignore[reportAssignmentType]
title_box, report_box = header_box.split_x(3.5 * inch, direction="r") # pyright: ignore[reportOptionalMemberAccess]
def on_page_lambda(c, _):
draw_header_footer(
@@ -97,7 +103,6 @@ def make_doc_template(
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=frames, onPage=on_page_lambda)
@@ -292,7 +297,7 @@ class GRect:
rem = self
for item in x_list:
s, rem = rem.split_x(item, direction)
s, rem = rem.split_x(item, direction) # pyright: ignore[reportOptionalMemberAccess]
ret_list.append(s)
return ret_list, rem
@@ -302,7 +307,7 @@ class GRect:
rem = self
for item in y_list:
s, rem = rem.split_y(item, direction)
s, rem = rem.split_y(item, direction) # pyright: ignore[reportOptionalMemberAccess]
ret_list.append(s)
return ret_list, rem
@@ -399,7 +404,7 @@ class GRect:
cp.rect(self.min_x, self.min_y, self.width, self.height)
a_canvas.clipPath(cp, stroke=0, fill=0)
w, h = flowable.wrap(inset_rect.width, inset_rect.height)
_w, h = flowable.wrap(inset_rect.width, inset_rect.height)
flowable.drawOn(a_canvas, inset_rect.x, inset_rect.max_y - h)
+33 -38
View File
@@ -1,11 +1,8 @@
from typing import List, Optional
from __future__ import annotations
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, portrait
from reportlab.lib.styles import getSampleStyleSheet
# from reportlab.pdfbase import pdfmetrics
# from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.units import inch
from reportlab.platypus import Paragraph, Spacer, Table
@@ -14,15 +11,13 @@ from .__init__ import make_doc_template, time_format
def build_columns(
lines: List[ADRLine],
reel_list: Optional[List[str]],
lines: list[ADRLine],
reel_list: list[str] | None,
show_priorities=False,
include_omitted=False,
):
columns = list()
reel_numbers = reel_list or sorted(
set([x.reel for x in lines if x.reel is not None])
)
columns = []
reel_numbers = reel_list or sorted({x.reel for x in lines if x.reel is not None})
num_column_width = 15.0 / 32.0 * inch
@@ -160,17 +155,17 @@ def build_columns(
):
columns.append(
{
"heading": "P%i" % n,
"value_getter": lambda recs: len(
[r for r in recs if r.priority == n]
"heading": f"P{n}",
"value_getter": lambda recs, N=n: len(
[r for r in recs if r.priority == N]
),
"value_getter2": (
lambda recs: time_format(
lambda recs, N=n: time_format(
sum(
[
r.time_budget_mins or 0.0
for r in recs
if r.priority == n
if r.priority == N
]
)
)
@@ -243,22 +238,20 @@ def build_columns(
return columns
def populate_columns(lines: List[ADRLine], columns, include_omitted, _page_size):
data = list()
styles = list()
columns_widths = list()
def populate_columns(lines: list[ADRLine], columns, include_omitted, _page_size):
data = []
styles = []
columns_widths = []
sorted_character_numbers: List[str] = sorted(
set([x.character_id for x in lines]), key=lambda x: str(x)
sorted_character_numbers: list[str | None] = sorted(
{x.character_id for x in lines}, key=lambda x: str(x)
)
# construct column styles
for i, c in enumerate(columns):
styles.extend(c["style_getter"](i))
columns_widths.append(c["width"])
data.append(list(map(lambda x: x["heading"], columns)))
data.append([x["heading"] for x in columns])
if not include_omitted:
lines = [x for x in lines if not x.omitted]
@@ -266,8 +259,8 @@ def populate_columns(lines: List[ADRLine], columns, include_omitted, _page_size)
for n in sorted_character_numbers:
char_records = [x for x in lines if x.character_id == n]
if len(char_records) > 0:
row_data = list()
row_data2 = list()
row_data = []
row_data2 = []
for col in columns:
row1_index = len(data)
@@ -291,8 +284,8 @@ def populate_columns(lines: List[ADRLine], columns, include_omitted, _page_size)
data.append(row_data)
data.append(row_data2)
summary_row1 = list()
summary_row2 = list()
summary_row1 = []
summary_row2 = []
row1_index = len(data)
for col in columns:
@@ -316,12 +309,15 @@ def populate_columns(lines: List[ADRLine], columns, include_omitted, _page_size)
def output_report(
lines: List[ADRLine],
reel_list: List[str],
lines: list[ADRLine],
reel_list: list[str],
page_size: tuple[float, float] | None = None,
include_omitted=False,
page_size=portrait(letter),
font_name="Helvetica",
):
if page_size is None:
page_size = portrait(letter)
columns = build_columns(lines, include_omitted=include_omitted, reel_list=reel_list)
data, style, columns_widths = populate_columns(
lines, columns, include_omitted, page_size
@@ -334,16 +330,17 @@ def output_report(
# pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc'))
title = "%s Line Count" % lines[0].title
title = f"{lines[0].title} Line Count"
filename = title + ".pdf"
doc = make_doc_template(
page_size=page_size,
filename=filename,
document_title=title,
title=lines[0].title,
document_subheader=lines[0].spot,
client=lines[0].client,
supervisor=lines[0].supervisor,
document_subheader=lines[0].spot or "",
client=lines[0].client or "",
supervisor=lines[0].supervisor or "",
document_header="Line Count",
)
@@ -364,8 +361,6 @@ def output_report(
omitted_count = len([x for x in lines if x.omitted])
if not include_omitted and omitted_count > 0:
story.append(
Paragraph("* %i Omitted lines are excluded." % omitted_count, style)
)
story.append(Paragraph(f"* {omitted_count} Omitted lines are excluded.", style))
doc.build(story)
+32 -41
View File
@@ -1,5 +1,4 @@
from typing import List
from __future__ import annotations
from reportlab.lib.pagesizes import letter, portrait
from reportlab.lib.styles import getSampleStyleSheet
@@ -13,7 +12,7 @@ from .__init__ import make_doc_template, time_format
def build_aux_data_field(line: ADRLine):
entries = list()
entries = []
if line.reason is not None:
entries.append("Reason: " + line.reason)
if line.note is not None:
@@ -27,40 +26,30 @@ def build_aux_data_field(line: ADRLine):
tag_field = ""
if line.effort:
bg_color = "red"
tag_field += "<font backColor=%s textColor=%s fontSize=11>%s</font> " % (
bg_color,
fg_color,
"EFF",
tag_field += (
f"<font backColor={bg_color} textColor={fg_color} fontSize=11>EFF</font> "
)
elif line.tv:
bg_color = "blue"
tag_field += "<font backColor=%s textColor=%s fontSize=11>%s</font> " % (
bg_color,
fg_color,
"TV",
tag_field += (
f"<font backColor={bg_color} textColor={fg_color} fontSize=11>TV</font> "
)
elif line.adlib:
bg_color = "purple"
tag_field += "<font backColor=%s textColor=%s fontSize=11>%s</font> " % (
bg_color,
fg_color,
"ADLIB",
tag_field += (
f"<font backColor={bg_color} textColor={fg_color} fontSize=11>ADLIB</font> "
)
elif line.optional:
bg_color = "green"
tag_field += "<font backColor=%s textColor=%s fontSize=11>%s</font>" % (
bg_color,
fg_color,
"OPTIONAL",
)
tag_field += f"font backColor={bg_color} textColor={fg_color} fontSize=11>OPTIONAL</font>"
entries.append(tag_field)
return "<br />".join(entries)
def build_story(lines: List[ADRLine], tc_rate: TimecodeFormat, font_name="Helvetica"):
story = list()
def build_story(lines: list[ADRLine], tc_rate: TimecodeFormat, font_name="Helvetica"):
story = []
this_scene = None
scene_style = getSampleStyleSheet()["Normal"]
@@ -78,15 +67,14 @@ def build_story(lines: List[ADRLine], tc_rate: TimecodeFormat, font_name="Helvet
("BOTTOMPADDING", (0, 0), (-1, -1), 24.0),
]
cue_number_field = "%s<br /><font fontSize=7>%s</font>" % (
line.cue_number,
line.character_name,
cue_number_field = (
f"{line.cue_number}<br /><font fontSize=7>{line.character_name}</font>"
)
time_data = time_format(line.time_budget_mins)
if line.priority is not None:
time_data = time_data + "<br />" + "P: " + line.priority
time_data = time_data + "<br />" + "P: " + str(line.priority)
aux_data_field = build_aux_data_field(line)
@@ -96,7 +84,7 @@ def build_story(lines: List[ADRLine], tc_rate: TimecodeFormat, font_name="Helvet
[
Paragraph(cue_number_field, line_style),
Paragraph(tc_data, line_style),
Paragraph(line.prompt, line_style),
Paragraph(line.prompt or "[No Prompt]", line_style),
Paragraph(time_data, line_style),
Paragraph(aux_data_field, line_style),
]
@@ -135,11 +123,11 @@ def build_tc_data(line: ADRLine, tc_format: TimecodeFormat):
third_line = []
if line.reel is not None:
if line.reel[0:1] == "R":
third_line.append("%s" % line.reel)
third_line.append(f"{line.reel}")
else:
third_line.append("Reel %s" % line.reel)
third_line.append(f"Reel {line.reel}")
if line.version is not None:
third_line.append("(%s)" % line.version)
third_line.append(f"({line.version})")
if len(third_line) > 0:
tc_data = tc_data + "<br/>" + " ".join(third_line)
return tc_data
@@ -147,17 +135,17 @@ def build_tc_data(line: ADRLine, tc_format: TimecodeFormat):
def generate_report(
page_size,
lines: List[ADRLine],
lines: list[ADRLine],
tc_rate: TimecodeFormat,
character_number=None,
include_omitted=True,
):
if character_number is not None:
lines = [r for r in lines if r.character_id == character_number]
title = "%s ADR Report (%s)" % (lines[0].title, lines[0].character_name)
document_header = "%s ADR Report" % lines[0].character_name
title = f"{lines[0].title} ADR Report ({lines[0].character_name})"
document_header = f"{lines[0].character_name} ADR Report"
else:
title = "%s ADR Report" % lines[0].title
title = f"{lines[0].title} ADR Report"
document_header = "ADR Report"
if not include_omitted:
@@ -172,9 +160,9 @@ def generate_report(
document_title=title,
document_header=document_header,
title=lines[0].title,
supervisor=lines[0].supervisor,
client=lines[0].client,
document_subheader=lines[0].spot,
supervisor=lines[0].supervisor or "",
client=lines[0].client or "",
document_subheader=lines[0].spot or "",
left_margin=0.75 * inch,
)
story = build_story(lines, tc_rate)
@@ -182,13 +170,16 @@ def generate_report(
def output_report(
lines: List[ADRLine],
lines: list[ADRLine],
tc_display_format: TimecodeFormat,
page_size=portrait(letter),
by_character=False,
page_size: tuple[float, float] | None = None,
by_character: bool = False,
):
if page_size is None:
page_size = portrait(letter)
if by_character:
character_numbers = set(r.character_id for r in lines)
character_numbers = {r.character_id for r in lines}
for n in character_numbers:
generate_report(page_size, lines, tc_display_format, n)
else:
+10 -14
View File
@@ -24,7 +24,7 @@ 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", font_name, 10, force_baseline=9.0)
line = "%s / %s" % (record.character_id, record.character_name)
line = f"{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, font_name, 12, force_baseline=9.0)
@@ -61,9 +61,9 @@ def draw_cue_number_block(canvas, rect, record: ADRLine):
"omitted": "OMIT",
}
tag_field = ""
for key in tags:
for key, value in tags.items():
if getattr(record, key):
tag_field = tag_field + tags[key] + " "
tag_field = tag_field + value + " "
aux_frame.draw_text_cell(
canvas, tag_field, font_name, 10, inset_x=10.0, inset_y=2.0, vertical_align="t"
@@ -221,7 +221,7 @@ def draw_aux_block(canvas, rect, recording_time_sec_this_line, recording_time_se
rect.draw_border(canvas, "min_x")
content_rect = rect.inset_xy(10.0, 10.0)
lines, last_line = content_rect.divide_y(
lines, _ = content_rect.divide_y(
[12.0, 12.0, 24.0, 24.0, 24.0, 24.0], direction="d"
)
@@ -255,7 +255,7 @@ def draw_footer(canvas, rect, record: ADRLine, report_date, line_no, total_lines
rect.draw_border(canvas, "max_y")
report_date_s = [report_date.strftime("%c")]
spotting_name = [record.spot] if record.spot is not None else []
pages_s = ["Line %i of %i" % (line_no, total_lines)]
pages_s = [f"Line {line_no} of {total_lines}"]
footer_s = " - ".join(report_date_s + spotting_name + pages_s)
rect.draw_text_cell(
canvas, footer_s, font_name=font_name, font_size=10.0, inset_y=2.0
@@ -266,11 +266,8 @@ def create_report_for_character(
records, report_date, tc_display_format: TimecodeFormat
):
outfile = "%s_%s_%s_Log.pdf" % (
records[0].title,
records[0].character_id,
records[0].character_name,
)
outfile = f"{records[0].title}_{records[0].character_id}_{records[0].character_name}_Log.pdf"
assert outfile is not None
assert outfile[-4:] == ".pdf", "Output file must have 'pdf' extension!"
@@ -285,7 +282,7 @@ def create_report_for_character(
)
)
cue_header_block, title_header_block = header_row.split_x(4.0 * inch)
cue_header_block, _title_header_block = header_row.split_x(4.0 * inch)
(cue_number_block, timecode_block), reason_block = data_row.divide_x(
[1.5 * inch, 1.5 * inch]
)
@@ -297,8 +294,7 @@ def create_report_for_character(
)
c.setTitle(
"%s %s (%s) Supervisor's Log"
% (records[0].title, records[0].character_name, records[0].character_id)
f"{records[0].title} {records[0].character_name} ({records[0].character_id}) Supervisor's Log"
)
c.setAuthor(records[0].supervisor)
@@ -339,7 +335,7 @@ def create_report_for_character(
def output_report(lines, tc_display_format: TimecodeFormat):
report_date = datetime.datetime.now()
events = sorted(lines, key=lambda x: x.start)
character_numbers = set([x.character_id for x in lines])
character_numbers = {x.character_id for x in lines}
for n in character_numbers:
create_report_for_character(
+6 -8
View File
@@ -1,5 +1,3 @@
from typing import List
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
@@ -14,9 +12,9 @@ from .__init__ import make_doc_template
def output_report(
lines: List[ADRLine], tc_display_format: TimecodeFormat, font_name="Helvetica"
lines: list[ADRLine], tc_display_format: TimecodeFormat, font_name="Helvetica"
):
character_numbers = set([n.character_id for n in lines])
character_numbers = {n.character_id for n in lines}
# pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc'))
for n in character_numbers:
@@ -27,8 +25,8 @@ def output_report(
char_lines = sorted(char_lines, key=lambda line: line.start)
title = "%s (%s) %s ADR Script" % (char_lines[0].title, character_name, n)
filename = "%s_%s_%s_ADR Script.pdf" % (char_lines[0].title, n, character_name)
title = f"{char_lines[0].title} ({character_name}) {n} ADR Script"
filename = f"{char_lines[0].title}_{n}_{character_name}_ADR Script.pdf"
doc = make_doc_template(
page_size=letter,
@@ -64,7 +62,7 @@ def output_report(
finish_tc = tc_display_format.seconds_to_smpte(line.finish)
data_block = [
[
Paragraph(line.cue_number, number_style),
Paragraph(line.cue_number or "[No QN]", number_style),
Paragraph(start_tc + " - " + finish_tc, number_style),
]
]
@@ -80,7 +78,7 @@ def output_report(
colWidths=[1.5 * inch, 6.0 * inch],
style=[("LEFTPADDING", (0, 0), (-1, -1), 0.0)],
),
Paragraph(line.prompt, prompt_style),
Paragraph(line.prompt or "[No Prompt]", prompt_style),
Spacer(1.0, inch * 1.5),
]
)
+1 -3
View File
@@ -43,9 +43,7 @@ def print_advisory_tagging_error(
sys.stderr.write(" ! \033[33;1mTagging error: \033[0m")
ok_string = failed_string[:position]
not_ok_string = failed_string[position:]
sys.stderr.write(
f'\033[32m"{ok_string}\033[31;1m{not_ok_string}"\033[0m\n'
)
sys.stderr.write(f'\033[32m"{ok_string}\033[31;1m{not_ok_string}"\033[0m\n')
if parent_track_name is not None:
sys.stderr.write(f' ! > On track "{parent_track_name}"\n')