diff --git a/ptulsconv/docparser/tag_compiler.py b/ptulsconv/docparser/tag_compiler.py index 4f285c9..5449db7 100644 --- a/ptulsconv/docparser/tag_compiler.py +++ b/ptulsconv/docparser/tag_compiler.py @@ -1,6 +1,7 @@ +import sys from collections import namedtuple from fractions import Fraction -from typing import Iterator, Tuple, Callable, Generator, Dict +from typing import Iterator, Tuple, Callable, Generator, Dict, List import ptulsconv.docparser.doc_entity as doc_entity from .tagged_string_parser_visitor import parse_tags, TagPreModes @@ -25,6 +26,40 @@ class TagCompiler: session: doc_entity.SessionDescriptor + def compile_all_timespans(self) -> List[Tuple[str, str, Fraction, Fraction]]: + ret_list = list() + for element in self.parse_data(): + if element.clip_tag_mode == TagPreModes.TIMESPAN: + for k in element.clip_tags.keys(): + ret_list.append((k, element.clip_tags[k], element.start, element.finish)) + + return ret_list + + def compile_tag_list(self) -> Dict[str, List[str]]: + tags_dict = dict() + + def update_tags_dict(other_dict: dict): + for k in other_dict.keys(): + if k not in tags_dict.keys(): + tags_dict[k] = set() + tags_dict[k].add(other_dict[k]) + + for parsed in self.parse_data(): + update_tags_dict(parsed.clip_tags) + update_tags_dict(parsed.track_tags) + update_tags_dict(parsed.track_comment_tags) + + session_tags = parse_tags(self.session.header.session_name).tag_dict + update_tags_dict(session_tags) + + for m in self.session.markers: + marker_tags = parse_tags(m.name).tag_dict + marker_comment_tags = parse_tags(m.comments).tag_dict + update_tags_dict(marker_tags) + update_tags_dict(marker_comment_tags) + + return tags_dict + def compile_events(self) -> Iterator[Event]: step0 = self.parse_data() step1 = self.apply_appends(step0) @@ -108,7 +143,7 @@ class TagCompiler: @staticmethod def _time_span_tags(at_time: Fraction, applicable_spans) -> dict: retval = dict() - for tags in [a[0] for a in applicable_spans if a[1] <= at_time <= a[2]]: + for tags in reversed([a[0] for a in applicable_spans if a[1] <= at_time <= a[2]]): retval.update(tags) return retval diff --git a/tests/test_tag_compiler.py b/tests/test_tag_compiler.py index 03a210f..7355248 100644 --- a/tests/test_tag_compiler.py +++ b/tests/test_tag_compiler.py @@ -12,6 +12,50 @@ class TestTagCompiler(unittest.TestCase): def test_one_track(self): c = ptulsconv.docparser.tag_compiler.TagCompiler() + test_session = self.make_test_session() + + c.session = test_session + + events = c.compile_events() + event1 = next(events) + self.assertEqual('This is clip 1', event1.clip_name) + self.assertEqual('Track 1', event1.track_name) + self.assertEqual('Test Session', event1.session_name) + self.assertEqual(dict(A='A', + Color='Blue', + Ver='1.1', + Mode='2', + Comment='This is some text in the comments', + Part='1'), event1.tags) + self.assertEqual(Fraction(3600, 1), event1.start) + + event2 = next(events) + self.assertEqual("This is the second clip ...and this is the last clip", event2.clip_name) + self.assertEqual('Track 1', event2.track_name) + self.assertEqual('Test Session', event2.session_name) + self.assertEqual(dict(R='Noise', A='A', B='B', + Color='Red', + Comment='This is some text in the comments', + N='1', Mode='2', + Ver='1.1', + Part='2'), event2.tags) + + self.assertEqual(c.session.header.convert_timecode('01:00:01:10'), event2.start) + self.assertEqual(c.session.header.convert_timecode('01:00:03:00'), event2.finish) + + self.assertIsNone(next(events, None)) + + def test_tag_list(self): + session = self.make_test_session() + c = ptulsconv.docparser.tag_compiler.TagCompiler() + c.session = session + + all_tags = c.compile_tag_list() + + self.assertTrue(all_tags['Mode'] == {'2', '1'}) + + @staticmethod + def make_test_session(): test_header = doc_entity.HeaderDescriptor(session_name="Test Session $Ver=1.1", sample_rate=48000, timecode_format="24", @@ -22,71 +66,59 @@ class TestTagCompiler(unittest.TestCase): count_clips=3, count_files=0 ) - test_clips = [ doc_entity.TrackClipDescriptor(channel=1, event=1, - clip_name='This is clip 1 {Color=Blue}', + clip_name='This is clip 1 {Color=Blue} $Mode=2', start_time='01:00:00:00', finish_time='01:00:01:03', duration='00:00:01:03', state='Unmuted', timestamp=None), doc_entity.TrackClipDescriptor(channel=1, event=2, - clip_name='This is the second clip {R=Noise} [B]', + clip_name='This is the second clip {R=Noise} [B] $Mode=2', start_time='01:00:01:10', finish_time='01:00:02:00', duration='00:00:00:14', state='Unmuted', timestamp=None), doc_entity.TrackClipDescriptor(channel=1, event=3, - clip_name='& ...and this is the last clip $N=1', + clip_name='& ...and this is the last clip $N=1 $Mode=2', start_time='01:00:02:00', finish_time='01:00:03:00', duration='00:00:01:00', state='Unmuted', timestamp=None), ] - - test_track = doc_entity.TrackDescriptor(name="Track 1 [A] {Color=Red}", + test_track = doc_entity.TrackDescriptor(name="Track 1 [A] {Color=Red} $Mode=1", comments="{Comment=This is some text in the comments}", user_delay_samples=0, plugins=[], state=[], - clips=test_clips) - c.session = doc_entity.SessionDescriptor(header=test_header, - tracks=[test_track], - clips=[], - files=[], - markers=[], - plugins=[]) + markers = [doc_entity.MarkerDescriptor(number=1, + location="01:00:00:00", + time_reference=48000 * 60, + units="Samples", + name="Marker 1 {Part=1}", + comments="" + ), + doc_entity.MarkerDescriptor(number=2, + location="01:00:01:00", + time_reference=48000 * 61, + units="Samples", + name="Marker 2 {Part=2}", + comments="" + ), + ] - events = c.compile_events() - event1 = next(events) - self.assertEqual('This is clip 1', event1.clip_name) - self.assertEqual('Track 1', event1.track_name) - self.assertEqual('Test Session', event1.session_name) - self.assertEqual(dict(A='A', - Color='Blue', - Ver='1.1', - Comment='This is some text in the comments'), event1.tags) - self.assertEqual(Fraction(3600, 1), event1.start) - - event2 = next(events) - self.assertEqual("This is the second clip ...and this is the last clip", event2.clip_name) - self.assertEqual('Track 1', event2.track_name) - self.assertEqual('Test Session', event2.session_name) - self.assertEqual(dict(R='Noise', A='A', B='B', - Color='Red', - Comment='This is some text in the comments', - N='1', - Ver='1.1'), event2.tags) - - self.assertEqual(c.session.header.convert_timecode('01:00:01:10'), event2.start) - self.assertEqual(c.session.header.convert_timecode('01:00:03:00'), event2.finish) - - self.assertIsNone(next(events, None)) + test_session = doc_entity.SessionDescriptor(header=test_header, + tracks=[test_track], + clips=[], + files=[], + markers=markers, + plugins=[]) + return test_session if __name__ == '__main__':