mirror of
https://github.com/iluvcapra/ptulsconv.git
synced 2025-12-31 08:50:48 +00:00
More implementation
This commit is contained in:
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (ptulsconv)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
||||||
2
.idea/ptulsconv.iml
generated
2
.idea/ptulsconv.iml
generated
@@ -2,7 +2,7 @@
|
|||||||
<module type="PYTHON_MODULE" version="4">
|
<module type="PYTHON_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$" />
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="jdk" jdkName="Python 3.7" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="TestRunnerService">
|
<component name="TestRunnerService">
|
||||||
|
|||||||
@@ -1,99 +1,39 @@
|
|||||||
from parsimonious.grammar import Grammar
|
from .ptuls_grammar import protools_text_export_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 parsimonious.nodes import NodeVisitor
|
||||||
|
|
||||||
class PTTextVisitor(NodeVisitor):
|
class PTTextVisitor(NodeVisitor):
|
||||||
def visit_document(self, node, visited_children):
|
def visit_document(self, node, visited_children):
|
||||||
return {'header': visited_children[0],
|
files = None
|
||||||
'files': visited_children[1][0],
|
clips = None
|
||||||
'clips': visited_children[2][0],
|
plugins = None
|
||||||
'plugins': visited_children[3][0],
|
tracks = None
|
||||||
'tracks': visited_children[4][0]
|
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):
|
def visit_header(self, node, visited_children):
|
||||||
return {
|
return dict(session_name=visited_children[2],
|
||||||
'session_name': visited_children[2],
|
sample_rate=visited_children[6],
|
||||||
'sample_rate': visited_children[6],
|
bit_depth=visited_children[10],
|
||||||
'bit_depth': visited_children[10],
|
start_timecode=visited_children[15],
|
||||||
'start_timecode': visited_children[14],
|
timecode_format=visited_children[19],
|
||||||
'timecode_format': visited_children[18],
|
count_audio_tracks=visited_children[24],
|
||||||
'count_audio_tracks': visited_children[23],
|
count_clips=visited_children[28],
|
||||||
'count_clips': visited_children[27],
|
count_files=visited_children[32])
|
||||||
'count_files': visited_children[31]
|
|
||||||
}
|
|
||||||
|
|
||||||
def visit_files_section(self, node, visited_children):
|
def visit_files_section(self, node, visited_children):
|
||||||
return list(map(lambda child: {'filename': child[0], 'path': child[2]}, visited_children[2]))
|
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]},
|
'count_instances': child[10]},
|
||||||
visited_children[2]))
|
visited_children[2]))
|
||||||
|
|
||||||
def visit_track_listing(self, node, visited_children):
|
def visit_track_block(self, node, visited_children):
|
||||||
retval = []
|
clips = []
|
||||||
for child in visited_children[1]:
|
for clip in visited_children[1]:
|
||||||
state = list(map(lambda t: t.text, child[14]))
|
if clip[0] != None:
|
||||||
plugs = list(map(lambda t: t.text, child[17]))
|
clips.append(clip[0])
|
||||||
retval.append({'track_name': child[2],
|
|
||||||
'comments': child[6],
|
|
||||||
'samples_delay': child[10],
|
|
||||||
'state': state,
|
|
||||||
'clips': child[19]})
|
|
||||||
|
|
||||||
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):
|
def visit_track_listing(selfs, node, visited_children):
|
||||||
return visited_children[14]
|
return visited_children[1]
|
||||||
|
|
||||||
def visit_track_clip_entry(self, node, visited_children):
|
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],
|
return {'channel': visited_children[0],
|
||||||
'event': visited_children[3],
|
'event': visited_children[3],
|
||||||
'clip_name': visited_children[6],
|
'clip_name': visited_children[6],
|
||||||
'start_time': visited_children[8],
|
'start_time': visited_children[8],
|
||||||
'end_time': visited_children[10],
|
'end_time': visited_children[10],
|
||||||
'duration': visited_children[12],
|
'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):
|
def visit_track_clip_state(self, node, visited_children):
|
||||||
return node.text
|
return node.text
|
||||||
|
|
||||||
@@ -144,20 +97,20 @@ class PTTextVisitor(NodeVisitor):
|
|||||||
return visited_children[1].text
|
return visited_children[1].text
|
||||||
|
|
||||||
def visit_string_value(self, node, visited_children):
|
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):
|
def visit_integer_value(self, node, visited_children):
|
||||||
return int(node.text)
|
return int(node.text)
|
||||||
|
|
||||||
def visit_timecode_value(self, node, visited_children):
|
def visit_timecode_value(self, node, visited_children):
|
||||||
return visited_children[1].text + visited_children[2].text + \
|
return visited_children[1].text
|
||||||
visited_children[3].text + visited_children[4].text + \
|
|
||||||
visited_children[5].text + visited_children[6].text + \
|
|
||||||
visited_children[7].text
|
|
||||||
|
|
||||||
def visit_float_value(self, node, visited_children):
|
def visit_float_value(self, node, visited_children):
|
||||||
return float(node.text)
|
return float(node.text)
|
||||||
|
|
||||||
|
def visit_block_ending(self, node, visited_children):
|
||||||
|
pass
|
||||||
|
|
||||||
def generic_visit(self, node, visited_children):
|
def generic_visit(self, node, visited_children):
|
||||||
""" The generic visit method. """
|
""" The generic visit method. """
|
||||||
return visited_children or node
|
return visited_children or node
|
||||||
|
|||||||
74
ptulsconv/ptuls_grammar.py
Normal file
74
ptulsconv/ptuls_grammar.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
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 integer_value "-bit" 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 block_ending
|
||||||
|
|
||||||
|
files_section = files_header files_column_header file_record* block_ending
|
||||||
|
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* block_ending
|
||||||
|
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* block_ending
|
||||||
|
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_block*
|
||||||
|
track_block = track_list_top ( track_clip_entry / block_ending )*
|
||||||
|
|
||||||
|
track_listing_header = "T R A C K L I S T I N G" rs
|
||||||
|
track_list_top = "TRACK NAME:" fs string_value rs
|
||||||
|
"COMMENTS:" fs string_value rs
|
||||||
|
"USER DELAY:" fs integer_value " Samples" rs
|
||||||
|
"STATE: " track_state_list rs
|
||||||
|
"PLUG-INS: " ( fs string_value )* rs
|
||||||
|
"CHANNEL " fs "EVENT " fs "CLIP NAME " fs
|
||||||
|
"START TIME " fs "END TIME " fs "DURATION " fs
|
||||||
|
("TIMESTAMP " fs)? "STATE" rs
|
||||||
|
|
||||||
|
track_state_list = (track_state " ")*
|
||||||
|
|
||||||
|
track_state = "Solo" / "Muted" / "Inactive"
|
||||||
|
|
||||||
|
track_clip_entry = integer_value isp fs
|
||||||
|
integer_value isp fs
|
||||||
|
string_value fs
|
||||||
|
timecode_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"
|
||||||
|
block_ending = rs rs
|
||||||
|
string_value = ~"[^\t\n]*"
|
||||||
|
timecode_value = ~"[^\d\t\n]*" ~"\d\d:\d\d:\d\d:\d\d(\.\d+)?" ~"[^\d\t\n]*"
|
||||||
|
integer_value = ~"\d+"
|
||||||
|
float_value = ~"\d+(\.\d+)"
|
||||||
|
isp = ~"[^\d\t\n]*"
|
||||||
|
""")
|
||||||
79
tests/test_robinhood1.py
Normal file
79
tests/test_robinhood1.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import unittest
|
||||||
|
import ptulsconv
|
||||||
|
import pprint
|
||||||
|
|
||||||
|
class TestRobinHood1(unittest.TestCase):
|
||||||
|
path = 'tests/export_cases/Robin Hood Spotting.txt'
|
||||||
|
|
||||||
|
def test_header_export(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.PTTextVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed :dict = visitor.visit(result)
|
||||||
|
|
||||||
|
self.assertTrue('header' in parsed.keys())
|
||||||
|
self.assertEqual(parsed['header']['session_name'], 'Robin Hood Spotting')
|
||||||
|
self.assertEqual(parsed['header']['sample_rate'], 48000.0)
|
||||||
|
self.assertEqual(parsed['header']['bit_depth'], 24)
|
||||||
|
self.assertEqual(parsed['header']['timecode_format'], 29.97)
|
||||||
|
|
||||||
|
def test_all_sections(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.PTTextVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed :dict = visitor.visit(result)
|
||||||
|
|
||||||
|
self.assertIn('header', parsed.keys())
|
||||||
|
self.assertIn('files', parsed.keys())
|
||||||
|
self.assertIn('clips', parsed.keys())
|
||||||
|
self.assertIn('plugins', parsed.keys())
|
||||||
|
self.assertIn('tracks', parsed.keys())
|
||||||
|
self.assertIn('markers', parsed.keys())
|
||||||
|
|
||||||
|
def test_tracks(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.PTTextVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed :dict = visitor.visit(result)
|
||||||
|
self.assertEqual(len(parsed['tracks']), 14)
|
||||||
|
self.assertListEqual(["Scenes", "Robin", "Will", "Marian", "John",
|
||||||
|
"Guy", "Much", "Butcher", "Town Crier",
|
||||||
|
"Soldier 1", "Soldier 2", "Soldier 3",
|
||||||
|
"Priest", "Guest at Court"],
|
||||||
|
list(map(lambda n: n['name'], parsed['tracks'])))
|
||||||
|
self.assertListEqual(["", "[ADR] {Actor=Errol Flynn} $CN=1",
|
||||||
|
"[ADR] {Actor=Patrick Knowles} $CN=2",
|
||||||
|
"[ADR] {Actor=Olivia DeHavilland} $CN=3",
|
||||||
|
"[ADR] {Actor=Claude Raines} $CN=4",
|
||||||
|
"[ADR] {Actor=Basil Rathbone} $CN=5",
|
||||||
|
"[ADR] {Actor=Herbert Mundin} $CN=6",
|
||||||
|
"[ADR] {Actor=George Bunny} $CN=101",
|
||||||
|
"[ADR] {Actor=Leonard Mundie} $CN=102",
|
||||||
|
"[ADR] $CN=103",
|
||||||
|
"[ADR] $CN=104",
|
||||||
|
"[ADR] $CN=105",
|
||||||
|
"[ADR] {Actor=Thomas R. Mills} $CN=106",
|
||||||
|
"[ADR] $CN=107"],
|
||||||
|
list(map(lambda n: n['comments'], parsed['tracks'])))
|
||||||
|
|
||||||
|
def test_a_track(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.PTTextVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed :dict = visitor.visit(result)
|
||||||
|
guy_track = parsed['tracks'][5]
|
||||||
|
self.assertEqual(guy_track['name'], 'Guy')
|
||||||
|
self.assertEqual(guy_track['comments'], '[ADR] {Actor=Basil Rathbone} $CN=5')
|
||||||
|
self.assertEqual(guy_track['user_delay_samples'], 0)
|
||||||
|
self.assertListEqual(guy_track['state'], [])
|
||||||
|
self.assertEqual(len(guy_track['clips']), 16)
|
||||||
|
self.assertEqual(guy_track['clips'][5]['channel'], 1)
|
||||||
|
self.assertEqual(guy_track['clips'][5]['event'], 6)
|
||||||
|
self.assertEqual(guy_track['clips'][5]['clip_name'], "\"What's your name? You Saxon dog!\" $QN=GY106" )
|
||||||
|
self.assertEqual(guy_track['clips'][5]['start_time'], "01:04:19:15")
|
||||||
|
self.assertEqual(guy_track['clips'][5]['end_time'], "01:04:21:28")
|
||||||
|
self.assertEqual(guy_track['clips'][5]['duration'], "00:00:02:13")
|
||||||
|
self.assertEqual(guy_track['clips'][5]['state'], 'Unmuted')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
49
tests/test_robinhood5.py
Normal file
49
tests/test_robinhood5.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import unittest
|
||||||
|
import ptulsconv
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
class TestRobinHood5(unittest.TestCase):
|
||||||
|
path = 'tests/export_cases/Robin Hood Spotting5.txt'
|
||||||
|
|
||||||
|
def test_plugins(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.PTTextVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed: dict = visitor.visit(result)
|
||||||
|
self.assertEqual(len(parsed['plugins']), 2)
|
||||||
|
|
||||||
|
def test_stereo_track(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.PTTextVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed: dict = visitor.visit(result)
|
||||||
|
self.assertEqual(parsed['tracks'][1]['name'], 'MX WT (Stereo)')
|
||||||
|
self.assertEqual(len(parsed['tracks'][1]['clips']), 2)
|
||||||
|
self.assertEqual(parsed['tracks'][1]['clips'][0]['clip_name'], 'RobinHood.1-01.L')
|
||||||
|
self.assertEqual(parsed['tracks'][1]['clips'][1]['clip_name'], 'RobinHood.1-01.R')
|
||||||
|
|
||||||
|
def test_a_track(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.PTTextVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed :dict = visitor.visit(result)
|
||||||
|
|
||||||
|
guy_track = parsed['tracks'][8]
|
||||||
|
self.assertEqual(guy_track['name'], 'Guy')
|
||||||
|
self.assertEqual(guy_track['comments'], '[ADR] {Actor=Basil Rathbone} $CN=5')
|
||||||
|
self.assertEqual(guy_track['user_delay_samples'], 0)
|
||||||
|
self.assertListEqual(guy_track['state'], ['Solo'])
|
||||||
|
self.assertEqual(len(guy_track['clips']), 16)
|
||||||
|
self.assertEqual(guy_track['clips'][5]['channel'], 1)
|
||||||
|
self.assertEqual(guy_track['clips'][5]['event'], 6)
|
||||||
|
self.assertEqual(guy_track['clips'][5]['clip_name'], "\"What's your name? You Saxon dog!\" $QN=GY106" )
|
||||||
|
self.assertEqual(guy_track['clips'][5]['start_time'], "01:04:19:15.00")
|
||||||
|
self.assertEqual(guy_track['clips'][5]['end_time'], "01:04:21:28.00")
|
||||||
|
self.assertEqual(guy_track['clips'][5]['duration'], "00:00:02:13.00")
|
||||||
|
self.assertEqual(guy_track['clips'][5]['timestamp'], "01:04:19:09.70")
|
||||||
|
self.assertEqual(guy_track['clips'][5]['state'], 'Unmuted')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user