Skip to content

Commit

Permalink
Some documentation and autopep
Browse files Browse the repository at this point in the history
  • Loading branch information
iluvcapra committed Jan 5, 2025
1 parent 1e1331e commit 8bb6dad
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 73 deletions.
2 changes: 2 additions & 0 deletions pycmx/edit_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def format(self) -> str:
"""
The detected format of the EDL. Possible values are: "3600", "File32",
"File128", and "unknown".
Adobe EDLs with more than 999 events will be reported as "3600".
"""
first_event = next( (s for s in self.event_statements if type(s) is StmtEvent), None)

Expand Down
4 changes: 2 additions & 2 deletions pycmx/parse_cmx_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

from typing import TextIO

def parse_cmx3600(f: TextIO):
def parse_cmx3600(f: TextIO) -> EditList:
"""
Parse a CMX 3600 EDL.
:param TextIO f: a file-like object, anything that's readlines-able.
:param TextIO f: a file-like object, an opened CMX 3600 .EDL file.
:returns: An :class:`pycmx.edit_list.EditList`.
"""
statements = parse_cmx3600_statements(f)
Expand Down
162 changes: 91 additions & 71 deletions pycmx/parse_cmx_statements.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,83 @@
# (c) 2018 Jamie Hardt

import re
import sys
from collections import namedtuple
from itertools import count
from typing import TextIO, List


from .util import collimate

StmtTitle = namedtuple("Title",["title","line_number"])
StmtFCM = namedtuple("FCM",["drop","line_number"])
StmtEvent = namedtuple("Event",["event","source","channels","trans",\
"trans_op","source_in","source_out","record_in","record_out","format","line_number"])
StmtAudioExt = namedtuple("AudioExt",["audio3","audio4","line_number"])
StmtClipName = namedtuple("ClipName",["name","affect","line_number"])
StmtSourceFile = namedtuple("SourceFile",["filename","line_number"])
StmtRemark = namedtuple("Remark",["text","line_number"])
StmtEffectsName = namedtuple("EffectsName",["name","line_number"])
StmtSourceUMID = namedtuple("Source",["name","umid","line_number"])
StmtSplitEdit = namedtuple("SplitEdit",["video","magnitude", "line_number"])
StmtMotionMemory = namedtuple("MotionMemory",["source","fps"]) # FIXME needs more fields
StmtUnrecognized = namedtuple("Unrecognized",["content","line_number"])
StmtTitle = namedtuple("Title", ["title", "line_number"])
StmtFCM = namedtuple("FCM", ["drop", "line_number"])
StmtEvent = namedtuple("Event", ["event", "source", "channels", "trans",
"trans_op", "source_in", "source_out",
"record_in", "record_out", "format",
"line_number"])
StmtAudioExt = namedtuple("AudioExt", ["audio3", "audio4", "line_number"])
StmtClipName = namedtuple("ClipName", ["name", "affect", "line_number"])
StmtSourceFile = namedtuple("SourceFile", ["filename", "line_number"])
StmtRemark = namedtuple("Remark", ["text", "line_number"])
StmtEffectsName = namedtuple("EffectsName", ["name", "line_number"])
StmtSourceUMID = namedtuple("Source", ["name", "umid", "line_number"])
StmtSplitEdit = namedtuple("SplitEdit", ["video", "magnitude", "line_number"])
StmtMotionMemory = namedtuple(
"MotionMemory", ["source", "fps"]) # FIXME needs more fields
StmtUnrecognized = namedtuple("Unrecognized", ["content", "line_number"])


def parse_cmx3600_statements(file: TextIO) -> List[object]:
"""
Return a list of every statement in the file argument.
"""
lines = file.readlines()
line_numbers = count()
return [_parse_cmx3600_line(line.strip(), line_number) \
for (line, line_number) in zip(lines,line_numbers)]

def _edl_column_widths(event_field_length, source_field_length):
return [event_field_length,2, source_field_length,1,
4,2, # chans
4,1, # trans
3,1, # trans op
11,1,
11,1,
11,1,
11]

def _edl_m2_column_widths():
return [2, # "M2"
3,3, #
8,8,1,4,2,1,4,13,3,1,1]


def _parse_cmx3600_line(line, line_number):
long_event_num_p = re.compile("^[0-9]{6} ")
return [_parse_cmx3600_line(line.strip(), line_number)
for (line_number, line) in enumerate(lines)]


def _edl_column_widths(event_field_length, source_field_length) -> List[int]:
return [event_field_length, 2, source_field_length, 1,
4, 2, # chans
4, 1, # trans
3, 1, # trans op
11, 1,
11, 1,
11, 1,
11]

# def _edl_m2_column_widths():
# return [2, # "M2"
# 3,3, #
# 8,8,1,4,2,1,4,13,3,1,1]


def _parse_cmx3600_line(line: str, line_number: int) -> object:
"""
Parses a single CMX EDL line.
:param line: A single EDL line.
:param line_number: The index of this line in the file.
"""
long_event_num_p = re.compile("^[0-9]{6} ")
short_event_num_p = re.compile("^[0-9]{3} ")

if isinstance(line,str):

if isinstance(line, str):
if line.startswith("TITLE:"):
return _parse_title(line,line_number)
return _parse_title(line, line_number)
elif line.startswith("FCM:"):
return _parse_fcm(line, line_number)
elif long_event_num_p.match(line) != None:
length_file_128 = sum(_edl_column_widths(6,128))
length_file_128 = sum(_edl_column_widths(6, 128))
if len(line) < length_file_128:
return _parse_long_standard_form(line, 32, line_number)
else:
return _parse_long_standard_form(line, 128, line_number)
elif short_event_num_p.match(line) != None:
return _parse_standard_form(line, line_number)
elif line.startswith("AUD"):
return _parse_extended_audio_channels(line,line_number)
return _parse_extended_audio_channels(line, line_number)
elif line.startswith("*"):
return _parse_remark( line[1:].strip(), line_number)
return _parse_remark(line[1:].strip(), line_number)
elif line.startswith(">>> SOURCE"):
return _parse_source_umid_statement(line, line_number)
elif line.startswith("EFFECTS NAME IS"):
Expand All @@ -82,24 +90,29 @@ def _parse_cmx3600_line(line, line_number):
else:
return _parse_unrecognized(line, line_number)

def _parse_title(line, line_num):

def _parse_title(line, line_num) -> StmtTitle:
title = line[6:].strip()
return StmtTitle(title=title,line_number=line_num)
return StmtTitle(title=title, line_number=line_num)

def _parse_fcm(line, line_num):

def _parse_fcm(line, line_num) -> StmtFCM:
val = line[4:].strip()
if val == "DROP FRAME":
return StmtFCM(drop= True, line_number=line_num)
return StmtFCM(drop=True, line_number=line_num)
else:
return StmtFCM(drop= False, line_number=line_num)
return StmtFCM(drop=False, line_number=line_num)


def _parse_long_standard_form(line, source_field_length, line_number):
return _parse_columns_for_standard_form(line, 6, source_field_length,
line_number)


def _parse_long_standard_form(line,source_field_length, line_number):
return _parse_columns_for_standard_form(line, 6, source_field_length, line_number)

def _parse_standard_form(line, line_number):
return _parse_columns_for_standard_form(line, 3, 8, line_number)



def _parse_extended_audio_channels(line, line_number):
content = line.strip()
if content == "AUD 3":
Expand All @@ -110,60 +123,67 @@ def _parse_extended_audio_channels(line, line_number):
return StmtAudioExt(audio3=True, audio4=True, line_number=line_number)
else:
return StmtUnrecognized(content=line, line_number=line_number)



def _parse_remark(line, line_number) -> object:
if line.startswith("FROM CLIP NAME:"):
return StmtClipName(name=line[15:].strip() , affect="from", line_number=line_number)
return StmtClipName(name=line[15:].strip(), affect="from",
line_number=line_number)
elif line.startswith("TO CLIP NAME:"):
return StmtClipName(name=line[13:].strip(), affect="to", line_number=line_number)
return StmtClipName(name=line[13:].strip(), affect="to",
line_number=line_number)
elif line.startswith("SOURCE FILE:"):
return StmtSourceFile(filename=line[12:].strip() , line_number=line_number)
return StmtSourceFile(filename=line[12:].strip(),
line_number=line_number)
else:
return StmtRemark(text=line, line_number=line_number)


def _parse_effects_name(line, line_number) -> StmtEffectsName:
name = line[16:].strip()
return StmtEffectsName(name=name, line_number=line_number)


def _parse_split(line, line_number):
split_type = line[10:21]
is_video = False
if split_type.startswith("VIDEO"):
is_video = True

split_mag = line[24:35]
return StmtSplitEdit(video=is_video, magnitude=split_mag, line_number=line_number)
split_mag = line[24:35]
return StmtSplitEdit(video=is_video, magnitude=split_mag,
line_number=line_number)


def _parse_motion_memory(line, line_number):
return StmtMotionMemory(source = "", fps="")
return StmtMotionMemory(source="", fps="")


def _parse_unrecognized(line, line_number):
return StmtUnrecognized(content=line, line_number=line_number)

def _parse_columns_for_standard_form(line, event_field_length, source_field_length, line_number):

def _parse_columns_for_standard_form(line, event_field_length,
source_field_length, line_number):
col_widths = _edl_column_widths(event_field_length, source_field_length)

if sum(col_widths) > len(line):
return StmtUnrecognized(content=line, line_number=line_number)
column_strings = collimate(line,col_widths)
return StmtEvent(event=column_strings[0],
source=column_strings[2].strip(),
channels=column_strings[4].strip(),
trans=column_strings[6].strip(),

column_strings = collimate(line, col_widths)

return StmtEvent(event=column_strings[0],
source=column_strings[2].strip(),
channels=column_strings[4].strip(),
trans=column_strings[6].strip(),
trans_op=column_strings[8].strip(),
source_in=column_strings[10].strip(),
source_out=column_strings[12].strip(),
record_in=column_strings[14].strip(),
record_out=column_strings[16].strip(),
line_number=line_number,
format=source_field_length)
line_number=line_number, format=source_field_length)


def _parse_source_umid_statement(line, line_number):
trimmed = line[3:].strip()
return StmtSourceUMID(name=None, umid=None, line_number=line_number)

0 comments on commit 8bb6dad

Please sign in to comment.