More implementation

This commit is contained in:
Jamie Hardt
2019-10-06 22:29:40 -07:00
parent 46f41a4b8f
commit b90045cc6b
6 changed files with 266 additions and 111 deletions

View File

@@ -1,99 +1,39 @@
from parsimonious.grammar import Grammar
protools_text_export_grammar = Grammar(
r"""
document = header files_section? clips_section? plugin_listing? track_listing? markers_listing?
header = "SESSION NAME:" fs string_value rs
"SAMPLE RATE:" fs float_value rs
"BIT DEPTH:" fs string_value rs
"SESSION START TIMECODE:" fs timecode_value rs
"TIMECODE FORMAT:" fs float_value " Frame" rs
"# OF AUDIO TRACKS:" fs integer_value rs
"# OF AUDIO CLIPS:" fs integer_value rs
"# OF AUDIO FILES:" fs integer_value rs rs rs
files_section = files_header files_column_header ( file_record )* rs rs
files_header = "F I L E S I N S E S S I O N" rs
files_column_header = "Filename " fs "Location" rs
file_record = string_value fs string_value rs
clips_section = clips_header clips_column_header ( clip_record )* rs rs
clips_header = "O N L I N E C L I P S I N S E S S I O N" rs
clips_column_header = string_value fs string_value rs
clip_record = string_value fs string_value fs "[" integer_value "]" rs
plugin_listing = plugin_header plugin_column_header ( plugin_record rs )* rs rs
plugin_header = "P L U G - I N S L I S T I N G" rs
plugin_column_header = "MANUFACTURER " fs "PLUG-IN NAME " fs
"VERSION " fs "FORMAT " fs "STEMS " fs
"NUMBER OF INSTANCES" rs
plugin_record = string_value fs string_value fs string_value fs
string_value fs string_value fs string_value rs
track_listing = track_listing_header ( track_list )*
track_listing_header = "T R A C K L I S T I N G" rs
track_list = "TRACK NAME:" fs string_value rs
"COMMENTS:" fs string_value rs
"USER DELAY:" fs integer_value " Samples" rs
"STATE: " ( fs string_value )* rs
"PLUG-INS: " ( fs string_value )* rs
track_clip_list rs rs
track_clip_list = "CHANNEL " fs "EVENT " fs "CLIP NAME " fs
"START TIME " fs "END TIME " fs "DURATION " fs "STATE" rs
(track_clip_entry)*
track_clip_entry = integer_value isp fs
integer_value isp fs
string_value fs
timecode_value fs timecode_value fs timecode_value fs
track_clip_state rs
track_clip_state = ("Muted" / "Unmuted")
markers_listing = markers_listing_header markers_column_header marker_record*
markers_listing_header = "M A R K E R S L I S T I N G" rs
markers_column_header = "# " fs "LOCATION " fs "TIME REFERENCE " fs
"UNITS " fs "NAME " fs "COMMENTS" rs
marker_record = string_value fs string_value fs string_value fs
string_value fs string_value fs string_value rs
fs = "\t"
rs = "\n"
string_value = ~"[^\S\t\n]*" ~"[^\t\n]*"
timecode_value = ~"[^\d\t\n]*" ~"\d\d" ":" ~"\d\d" ":" ~"\d\d" ":" ~"\d\d" ~"[^\d\t\n]*"
integer_value = ~"\d+"
float_value = ~"\d+(\.\d+)"
isp = ~"[^\d\t\n]*"
""")
from parsimonious.nodes import NodeVisitor, Node
from timecode import Timecode
from .ptuls_grammar import protools_text_export_grammar
from parsimonious.nodes import NodeVisitor
class PTTextVisitor(NodeVisitor):
def visit_document(self, node, visited_children):
return {'header': visited_children[0],
'files': visited_children[1][0],
'clips': visited_children[2][0],
'plugins': visited_children[3][0],
'tracks': visited_children[4][0]
}
files = None
clips = None
plugins = None
tracks = None
markers = None
if isinstance(visited_children[1] ,list):
files = visited_children[1][0]
if isinstance(visited_children[2], list):
clips = visited_children[2][0]
if isinstance(visited_children[3], list):
plugins = visited_children[3][0]
if isinstance(visited_children[4], list):
tracks = visited_children[4][0]
return dict(header=visited_children[0],
files=files,
clips=clips,
plugins=plugins,
tracks=tracks,
markers=markers)
def visit_header(self, node, visited_children):
return {
'session_name': visited_children[2],
'sample_rate': visited_children[6],
'bit_depth': visited_children[10],
'start_timecode': visited_children[14],
'timecode_format': visited_children[18],
'count_audio_tracks': visited_children[23],
'count_clips': visited_children[27],
'count_files': visited_children[31]
}
return dict(session_name=visited_children[2],
sample_rate=visited_children[6],
bit_depth=visited_children[10],
start_timecode=visited_children[15],
timecode_format=visited_children[19],
count_audio_tracks=visited_children[24],
count_clips=visited_children[28],
count_files=visited_children[32])
def visit_files_section(self, node, visited_children):
return list(map(lambda child: {'filename': child[0], 'path': child[2]}, visited_children[2]))
@@ -108,32 +48,45 @@ class PTTextVisitor(NodeVisitor):
'count_instances': child[10]},
visited_children[2]))
def visit_track_listing(self, node, visited_children):
retval = []
for child in visited_children[1]:
state = list(map(lambda t: t.text, child[14]))
plugs = list(map(lambda t: t.text, child[17]))
retval.append({'track_name': child[2],
'comments': child[6],
'samples_delay': child[10],
'state': state,
'clips': child[19]})
def visit_track_block(self, node, visited_children):
clips = []
for clip in visited_children[1]:
if clip[0] != None:
clips.append(clip[0])
return retval
return dict(
name=visited_children[0][2],
comments=visited_children[0][6],
user_delay_samples=visited_children[0][10],
state=visited_children[0][14],
clips=clips
)
def visit_track_clip_list(self, node, visited_children):
return visited_children[14]
def visit_track_listing(selfs, node, visited_children):
return visited_children[1]
def visit_track_clip_entry(self, node, visited_children):
timestamp = None
if isinstance(visited_children[14], list):
timestamp = visited_children[14][0][0]
return {'channel': visited_children[0],
'event': visited_children[3],
'clip_name': visited_children[6],
'start_time': visited_children[8],
'end_time': visited_children[10],
'duration': visited_children[12],
'state': visited_children[14]
'timestamp' : timestamp,
'state': visited_children[15]
}
def visit_track_state_list(self, node, visited_children):
states = []
for next_state in visited_children:
states.append(next_state[0][0].text)
return states
def visit_track_clip_state(self, node, visited_children):
return node.text
@@ -144,20 +97,20 @@ class PTTextVisitor(NodeVisitor):
return visited_children[1].text
def visit_string_value(self, node, visited_children):
return visited_children[1].text
return node.text.strip(" ")
def visit_integer_value(self, node, visited_children):
return int(node.text)
def visit_timecode_value(self, node, visited_children):
return visited_children[1].text + visited_children[2].text + \
visited_children[3].text + visited_children[4].text + \
visited_children[5].text + visited_children[6].text + \
visited_children[7].text
return visited_children[1].text
def visit_float_value(self, node, visited_children):
return float(node.text)
def visit_block_ending(self, node, visited_children):
pass
def generic_visit(self, node, visited_children):
""" The generic visit method. """
return visited_children or node