mirror of
https://github.com/iluvcapra/ptulsconv.git
synced 2026-10-01 17:27:27 +00:00
ruffage
This commit is contained in:
@@ -42,6 +42,11 @@ doc = [
|
||||
"sphinx-rtd-theme>=3.0.2",
|
||||
]
|
||||
|
||||
[tool.ruff.lint]
|
||||
ignore = [
|
||||
"DTZ005" # datetime created without a tz
|
||||
]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"reaper/Export Items as Text.py" = ["F821"]
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
import datetime
|
||||
import json
|
||||
import time
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
item_records = []
|
||||
|
||||
@@ -66,7 +66,7 @@ output["project_frame_rate"], _, output["project_drop_frame"] = (
|
||||
|
||||
output_path, _ = RPR_GetProjectPath("", 1024)
|
||||
|
||||
now = datetime.datetime.now(tz=time.tzname)
|
||||
now = datetime.datetime.now()
|
||||
output_title = output["project_title"]
|
||||
|
||||
if output_title == "":
|
||||
|
||||
@@ -102,7 +102,7 @@ def main():
|
||||
(options, args) = parser.parse_args(sys.argv)
|
||||
|
||||
print_section_header_style("Startup")
|
||||
print_status_style("This run started %s" % (datetime.datetime.now().isoformat()))
|
||||
print_status_style(f"This run started {datetime.datetime.now().isoformat()}")
|
||||
|
||||
if options.show_tags:
|
||||
dump_field_map()
|
||||
@@ -124,17 +124,6 @@ def main():
|
||||
input_file=args[1], major_mode=major_mode, warnings=options.warnings
|
||||
)
|
||||
|
||||
except FileNotFoundError as e:
|
||||
print_fatal_error("Error trying to read input file")
|
||||
raise e
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
|
||||
print_fatal_error("Error trying to convert file")
|
||||
print("\033[31m" + e.__repr__() + "\033[0m", file=sys.stderr)
|
||||
print(traceback.format_exc())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
Useful functions for parsing and working with timecode.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
import re
|
||||
from collections import namedtuple
|
||||
from fractions import Fraction
|
||||
from typing import Optional, SupportsFloat
|
||||
from typing import SupportsFloat
|
||||
|
||||
|
||||
class TimecodeFormat(
|
||||
@@ -16,7 +18,7 @@ class TimecodeFormat(
|
||||
A struct reperesenting a timecode datum.
|
||||
"""
|
||||
|
||||
def smpte_to_seconds(self, smpte: str) -> Optional[Fraction]:
|
||||
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
|
||||
)
|
||||
@@ -32,7 +34,7 @@ class TimecodeFormat(
|
||||
|
||||
def smpte_to_frame_count(
|
||||
smpte_rep_string: str, frames_per_logical_second: int, drop_frame_hint=False
|
||||
) -> Optional[int]:
|
||||
) -> int | None:
|
||||
"""
|
||||
Convert a string with a SMPTE timecode representation into a frame count.
|
||||
|
||||
@@ -83,7 +85,7 @@ def frame_count_to_smpte(
|
||||
frame_count: int,
|
||||
frames_per_logical_second: int,
|
||||
drop_frame: bool = False,
|
||||
fractional_frame: Optional[float] = None,
|
||||
fractional_frame: float | None = None,
|
||||
) -> str:
|
||||
assert frames_per_logical_second in [24, 25, 30, 48, 50, 60]
|
||||
assert fractional_frame is None or fractional_frame < 1.0
|
||||
@@ -104,20 +106,21 @@ def frame_count_to_smpte(
|
||||
ss, ff = divmod(rem, frames_per_logical_second)
|
||||
|
||||
hh = hh % 24
|
||||
|
||||
hh = int(hh)
|
||||
mm = int(mm)
|
||||
ss = int(ss)
|
||||
ff = int(ff)
|
||||
|
||||
if fractional_frame is not None and fractional_frame > 0:
|
||||
return "%02i:%02i:%02i%s%02i%s" % (
|
||||
hh,
|
||||
mm,
|
||||
ss,
|
||||
separator,
|
||||
ff,
|
||||
("%.3f" % fractional_frame)[1:],
|
||||
)
|
||||
fpart = "{fractional_frame:.3f}"[1:]
|
||||
return f"{hh:02}:{mm:02}:{ss:02}{separator}{ff:02}{fpart}"
|
||||
else:
|
||||
return "%02i:%02i:%02i%s%02i" % (hh, mm, ss, separator, ff)
|
||||
return f"{hh:02}:{mm:02}:{ss:02}{separator}{ff:02}"
|
||||
# "%02i:%02i:%02i%s%02i" % (hh, mm, ss, separator, ff)
|
||||
|
||||
|
||||
def footage_to_frame_count(footage_string) -> Optional[int]:
|
||||
def footage_to_frame_count(footage_string) -> int | None:
|
||||
m = re.search(r"(\d+)\+(\d+)(\.\d+)?", footage_string)
|
||||
if m is None:
|
||||
return None
|
||||
@@ -131,4 +134,4 @@ def footage_to_frame_count(footage_string) -> Optional[int]:
|
||||
|
||||
def frame_count_to_footage(frame_count):
|
||||
feet, frm = divmod(frame_count, 16)
|
||||
return "%i+%02i" % (feet, frm)
|
||||
return f"{feet}+{frm:02}"
|
||||
|
||||
+19
-21
@@ -3,6 +3,8 @@ This module provides the main input document parsing and transform
|
||||
implementation.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import datetime
|
||||
import os
|
||||
@@ -11,7 +13,7 @@ from collections.abc import Iterator
|
||||
from fractions import Fraction
|
||||
from itertools import chain
|
||||
from json import JSONEncoder
|
||||
from typing import List, Optional
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
import ptsl
|
||||
|
||||
@@ -39,26 +41,25 @@ class FractionEncoder(JSONEncoder):
|
||||
as a dict.
|
||||
"""
|
||||
|
||||
force_denominator: Optional[int]
|
||||
force_denominator: int | None
|
||||
|
||||
def default(self, o):
|
||||
""" """
|
||||
if isinstance(o, Fraction):
|
||||
return dict(numerator=o.numerator, denominator=o.denominator)
|
||||
return {"numerator": o.numerator, "denominator": o.denominator}
|
||||
else:
|
||||
return o.__dict__
|
||||
|
||||
|
||||
def output_adr_csv(lines: List[ADRLine], time_format: TimecodeFormat):
|
||||
def output_adr_csv(lines: list[ADRLine], time_format: TimecodeFormat):
|
||||
"""
|
||||
Writes ADR lines as CSV to the current working directory. Creates
|
||||
directories for each character number and name pair, and within that
|
||||
directory, creates a CSV file for each reel.
|
||||
"""
|
||||
|
||||
reels: set[str | None] = set([ln.reel for ln in lines])
|
||||
reels: set[str | None] = {ln.reel for ln in lines}
|
||||
for n, name in [(n.character_id, n.character_name) for n in lines]:
|
||||
dir_name = "%s_%s" % (n, name)
|
||||
dir_name = f"{n}_{name}"
|
||||
os.makedirs(dir_name, exist_ok=True)
|
||||
os.chdir(dir_name)
|
||||
for reel in reels:
|
||||
@@ -69,11 +70,8 @@ def output_adr_csv(lines: List[ADRLine], time_format: TimecodeFormat):
|
||||
if len(these_lines) == 0:
|
||||
continue
|
||||
|
||||
outfile_name = "%s_%s_%s_%s.csv" % (
|
||||
these_lines[0].title,
|
||||
n,
|
||||
these_lines[0].character_name,
|
||||
reel,
|
||||
outfile_name = (
|
||||
f"{these_lines[0].title}_{n}_{these_lines[0].character_name}_{reel}.csv"
|
||||
)
|
||||
|
||||
with open(outfile_name, mode="w", newline="") as outfile:
|
||||
@@ -119,13 +117,13 @@ def output_adr_csv(lines: List[ADRLine], time_format: TimecodeFormat):
|
||||
os.chdir("..")
|
||||
|
||||
|
||||
def generate_documents(session_tc_format, scenes, adr_lines: List[ADRLine], title):
|
||||
def generate_documents(session_tc_format, scenes, adr_lines: list[ADRLine], title):
|
||||
"""
|
||||
Create PDF output.
|
||||
"""
|
||||
print_section_header_style("Creating PDF Reports")
|
||||
report_date = datetime.datetime.now()
|
||||
reports_dir = "%s_%s" % (title, report_date.strftime("%Y-%m-%d_%H%M%S"))
|
||||
reports_dir = f"{title}_{report_date.strftime('%Y-%m-%d_%H%M%S')}"
|
||||
os.makedirs(reports_dir, exist_ok=False)
|
||||
os.chdir(reports_dir)
|
||||
|
||||
@@ -155,7 +153,7 @@ def generate_documents(session_tc_format, scenes, adr_lines: List[ADRLine], titl
|
||||
|
||||
|
||||
def create_adr_reports(
|
||||
lines: List[ADRLine], tc_display_format: TimecodeFormat, reel_list: List[str]
|
||||
lines: list[ADRLine], tc_display_format: TimecodeFormat, reel_list: list[str]
|
||||
):
|
||||
"""
|
||||
Creates a directory heirarchy and a respective set of ADR reports,
|
||||
@@ -240,18 +238,18 @@ def convert(major_mode, input_file=None, output=sys.stdout, warnings=True):
|
||||
)
|
||||
|
||||
# TODO: Breakdown by titles
|
||||
titles = set([x.title for x in (generic_events + adr_lines)])
|
||||
titles = {x.title for x in (generic_events + adr_lines)}
|
||||
if len(titles) != 1:
|
||||
print_warning(
|
||||
"Multiple titles per export is not supported, "
|
||||
"found multiple titles: %s Exiting." % titles
|
||||
f"found multiple titles: {titles} Exiting."
|
||||
)
|
||||
exit(-1)
|
||||
sys.exit(-1)
|
||||
|
||||
title = list(titles)[0]
|
||||
title = next(iter(titles))
|
||||
|
||||
print_status_style("%i generic events found." % len(generic_events))
|
||||
print_status_style("%i ADR events found." % len(adr_lines))
|
||||
print_status_style(f"{len(generic_events)} generic events found.")
|
||||
print_status_style(f"{len(adr_lines)} ADR events found.")
|
||||
|
||||
if warnings:
|
||||
perform_adr_validations(iter(adr_lines))
|
||||
|
||||
Reference in New Issue
Block a user