Skip to content

Commit

Permalink
Merge pull request #8 from iluvcapra/bug-flake8
Browse files Browse the repository at this point in the history
Add Flake8 to build tests, clean up code style
  • Loading branch information
iluvcapra authored Jul 21, 2023
2 parents 4318946 + 82f07b1 commit 5f29e95
Show file tree
Hide file tree
Showing 26 changed files with 656 additions and 401 deletions.
4 changes: 4 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[flake8]
per-file-ignores =
ptulsconv/__init__.py: F401
ptulsconv/docparser/__init__.py: F401
1 change: 1 addition & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ jobs:
- name: Test with pytest
run: |
pytest
flake8 ptulsconv
5 changes: 3 additions & 2 deletions ptulsconv/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

__version__ = '2.0.0'
__author__ = 'Jamie Hardt'
__author__ = 'Jamie Hardt'
__license__ = 'MIT'
__copyright__ = "%s %s (c) 2023 %s. All rights reserved." % (__name__, __version__, __author__)
__copyright__ = "%s %s (c) 2023 %s. All rights reserved." \
% (__name__, __version__, __author__)
73 changes: 41 additions & 32 deletions ptulsconv/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
import datetime
import sys

from ptulsconv import __name__, __version__, __author__, __copyright__
from ptulsconv import __name__, __copyright__
from ptulsconv.commands import convert
from ptulsconv.reporting import print_status_style, print_banner_style, print_section_header_style, print_fatal_error
from ptulsconv.reporting import print_status_style, \
print_banner_style, print_section_header_style, \
print_fatal_error


def dump_field_map(output=sys.stdout):
from ptulsconv.docparser.tag_mapping import TagMapping
from ptulsconv.docparser.adr_entity import ADRLine, GenericEvent

TagMapping.print_rules(GenericEvent, output=output)
TagMapping.print_rules(ADRLine, output=output)

Expand All @@ -19,12 +21,12 @@ def dump_formats():
print_section_header_style("`raw` format:")
sys.stderr.write("A JSON document of the parsed Pro Tools export.\n")
print_section_header_style("`tagged` Format:")
sys.stderr.write("A JSON document containing one record for each clip, with\n"
"all tags parsed and all tagging rules applied. \n")
sys.stderr.write(
"A JSON document containing one record for each clip, with\n"
"all tags parsed and all tagging rules applied. \n")
print_section_header_style("`doc` format:")
sys.stderr.write("Creates a directory with folders for different types\n"
"of ADR reports.\n\n")

"of ADR reports.\n\n")


def main():
Expand All @@ -45,38 +47,43 @@ def main():
warn_options.add_option('-W', action='store_false',
dest='warnings',
default=True,
help='Suppress warnings for common errors (missing code numbers etc.)')
help='Suppress warnings for common '
'errors (missing code numbers etc.)')

parser.add_option_group(warn_options)

informational_options = OptionGroup(title="Informational Options",
parser=parser,
description='Print useful information and exit without processing '
'input files.')

informational_options.add_option('--show-formats',
dest='show_formats',
action='store_true',
default=False,
help='Display helpful information about the '
'available output formats.')

informational_options.add_option('--show-available-tags',
dest='show_tags',
action='store_true',
default=False,
help='Display tag mappings for the FMP XML '
'output style and exit.')
description='Print useful '
'information '
'and exit without processing '
'input files.')

informational_options.add_option(
'--show-formats',
dest='show_formats',
action='store_true',
default=False,
help='Display helpful information about the available '
'output formats.')

informational_options.add_option(
'--show-available-tags',
dest='show_tags',
action='store_true',
default=False,
help='Display tag mappings for the FMP XML output style '
'and exit.')

parser.add_option_group(informational_options)

print_banner_style(__copyright__)

(options, args) = parser.parse_args(sys.argv)

(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("This run started %s" %
(datetime.datetime.now().isoformat()))

if options.show_tags:
dump_field_map()
Expand All @@ -87,14 +94,16 @@ def main():
sys.exit(0)
try:
major_mode = options.output_format

if len(args) < 2:
print_status_style("No input file provided, will connect to Pro Tools with PTSL...")
convert(major_mode=major_mode,
print_status_style(
"No input file provided, will connect to Pro Tools "
"with PTSL...")
convert(major_mode=major_mode,
warnings=options.warnings)
else:
convert(input_file=args[1],
major_mode=major_mode,
convert(input_file=args[1],
major_mode=major_mode,
warnings=options.warnings)

except FileNotFoundError as e:
Expand Down
45 changes: 27 additions & 18 deletions ptulsconv/broadcast_timecode.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,50 @@
from typing import Optional, SupportsFloat


class TimecodeFormat(namedtuple("_TimecodeFormat", "frame_duration logical_fps drop_frame")):
class TimecodeFormat(namedtuple("_TimecodeFormat",
"frame_duration logical_fps drop_frame")):
"""
A struct reperesenting a timecode datum.
"""

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)
frame_count = smpte_to_frame_count(
smpte, self.logical_fps, drop_frame_hint=self.drop_frame)
if frame_count is None:
return None
else:
return frame_count * self.frame_duration

def seconds_to_smpte(self, seconds: SupportsFloat) -> str:
frame_count = int(seconds / self.frame_duration)
return frame_count_to_smpte(frame_count, self.logical_fps, self.drop_frame)
return frame_count_to_smpte(frame_count, self.logical_fps,
self.drop_frame)


def smpte_to_frame_count(smpte_rep_string: str, frames_per_logical_second: int, drop_frame_hint=False) -> Optional[int]:
def smpte_to_frame_count(smpte_rep_string: str, frames_per_logical_second: int,
drop_frame_hint=False) -> Optional[int]:
"""
Convert a string with a SMPTE timecode representation into a frame count.
:param smpte_rep_string: The timecode string
:param frames_per_logical_second: Num of frames in a logical second. This is asserted to be
in one of `[24,25,30,48,50,60]`
:param drop_frame_hint: `True` if the timecode rep is drop frame. This is ignored (and implied `True`) if
the last separator in the timecode string is a semicolon. This is ignored (and implied `False`) if
`frames_per_logical_second` is not 30 or 60.
:param frames_per_logical_second: Num of frames in a logical second. This
is asserted to be in one of `[24,25,30,48,50,60]`
:param drop_frame_hint: `True` if the timecode rep is drop frame. This is
ignored (and implied `True`) if the last separator in the timecode
string is a semicolon. This is ignored (and implied `False`) if
`frames_per_logical_second` is not 30 or 60.
"""
assert frames_per_logical_second in [24, 25, 30, 48, 50, 60]

m = re.search(r'(\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)
hh, mm, ss, ff, frac = int(hh), int(
mm), int(ss), int(ff), float(frac or 0.0)

drop_frame = drop_frame_hint
if sep == ";":
Expand All @@ -54,8 +61,8 @@ def smpte_to_frame_count(smpte_rep_string: str, frames_per_logical_second: int,
if frames_per_logical_second not in [30, 60]:
drop_frame = False

raw_frames = hh * 3600 * frames_per_logical_second + mm * 60 * frames_per_logical_second + \
ss * frames_per_logical_second + ff
raw_frames = hh * 3600 * frames_per_logical_second + mm * 60 * \
frames_per_logical_second + ss * frames_per_logical_second + ff

frames = raw_frames
if drop_frame is True:
Expand All @@ -68,7 +75,8 @@ def smpte_to_frame_count(smpte_rep_string: str, frames_per_logical_second: int,
return frames


def frame_count_to_smpte(frame_count: int, frames_per_logical_second: int, drop_frame: bool = False,
def frame_count_to_smpte(frame_count: int, frames_per_logical_second: int,
drop_frame: bool = False,
fractional_frame: Optional[float] = None) -> str:
assert frames_per_logical_second in [24, 25, 30, 48, 50, 60]
assert fractional_frame is None or fractional_frame < 1.0
Expand All @@ -90,7 +98,8 @@ def frame_count_to_smpte(frame_count: int, frames_per_logical_second: int, drop_

hh = hh % 24
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:])
return "%02i:%02i:%02i%s%02i%s" % (hh, mm, ss, separator, ff,
("%.3f" % fractional_frame)[1:])
else:
return "%02i:%02i:%02i%s%02i" % (hh, mm, ss, separator, ff)

Expand Down
Loading

0 comments on commit 5f29e95

Please sign in to comment.