def to_model(scc_content: str): """Converts a SCC document to the data model""" context = _SccContext() document = ContentDocument() # Safe area must be a 32x15 grid, that represents 80% of the root area root_cell_resolution = CellResolutionType(rows=19, columns=40) document.set_cell_resolution(root_cell_resolution) context.set_safe_area(int((root_cell_resolution.columns - 32) / 2), int((root_cell_resolution.rows - 15) / 2)) body = Body() body.set_doc(document) document.set_body(body) context.div = Div() context.div.set_doc(document) body.push_child(context.div) time_code = None for line in scc_content.splitlines(): LOGGER.debug(line) scc_line = SccLine.from_str(line) if scc_line is None: continue time_code = scc_line.to_model(context) context.flush(time_code) return document
def _get_filled_body(isd: ISD, text: str) -> Body: body = Body(isd) text = Text(isd, text) span = Span(isd) span.push_child(text) p = P(isd) p.push_child(span) div = Div(isd) div.push_child(p) body.push_child(div) return body
def _get_filled_body(isd: ISD, *text_contents: List[str]) -> Body: body = Body(isd) for text_content in text_contents: div = Div(isd) body.push_child(div) for content in text_content: text = Text(isd, content) span = Span(isd) span.push_child(text) p = P(isd) p.push_child(span) div.push_child(p) return body
def to_model(scc_content: str): """Converts a SCC document to the data model""" context = _SccContext() document = Document() body = Body() body.set_doc(document) document.set_body(body) context.div = Div() context.div.set_doc(document) body.push_child(context.div) for line in scc_content.splitlines(): _read_line(context, line) return document
def process(self, isd: ISD): """Merges the ISD document regions""" LOGGER.debug("Apply regions merging filter to ISD.") original_regions = list(isd.iter_regions()) not_empty_regions = 0 for region in original_regions: not_empty_regions += len(region) if len(original_regions) <= 1 or not_empty_regions <= 1: return LOGGER.warning("Merging ISD regions.") target_body = Body(isd) region_ids = [] for region in original_regions: region_id = region.get_id() for body in region: for child in body: # Remove child from its parent body child.remove() # Add it to the target body target_body.push_child(child) region_ids.append(region_id) isd.remove_region(region_id) target_region = ISD.Region("_".join(region_ids), isd) target_region.push_child(target_body) isd.put_region(target_region)
def to_model(scc_content: str, config: Optional[SccReaderConfiguration] = None, progress_callback=lambda _: None): """Converts a SCC document to the data model""" context = _SccContext(config) document = ContentDocument() # Safe area must be a 32x15 grid, that represents 80% of the root area root_cell_resolution = CellResolutionType( rows=SCC_ROOT_CELL_RESOLUTION_ROWS, columns=SCC_ROOT_CELL_RESOLUTION_COLUMNS) document.set_cell_resolution(root_cell_resolution) context.set_safe_area( int((root_cell_resolution.columns - SCC_SAFE_AREA_CELL_RESOLUTION_COLUMNS) / 2), int((root_cell_resolution.rows - SCC_SAFE_AREA_CELL_RESOLUTION_ROWS) / 2)) # The active area is equivalent to the safe area active_area = ActiveAreaType( left_offset=context.safe_area_x_offset / root_cell_resolution.columns, top_offset=context.safe_area_y_offset / root_cell_resolution.rows, width=(root_cell_resolution.columns - (context.safe_area_x_offset * 2)) / root_cell_resolution.columns, height=(root_cell_resolution.rows - (context.safe_area_y_offset * 2)) / root_cell_resolution.rows, ) document.set_active_area(active_area) body = Body() body.set_doc(document) document.set_body(body) # the default value of LineHeight ("normal") typically translates to 125% of the font size, which causes regions to overflow. body.set_style(StyleProperties.LineHeight, LengthType(value=100, units=LengthType.Units.pct)) # use a more readable font than the default Courier body.set_style(StyleProperties.FontFamily, ("Consolas", "Monaco", GenericFontFamilyType.monospace)) # add line padding body.set_style(StyleProperties.LinePadding, LengthType(value=0.25, units=LengthType.Units.c)) context.div = Div() context.div.set_doc(document) body.push_child(context.div) lines = scc_content.splitlines() nb_lines = len(lines) for (index, line) in enumerate(lines): LOGGER.debug(line) scc_line = SccLine.from_str(line) progress_callback((index + 1) / nb_lines) if scc_line is None: continue context.process_line(scc_line) context.flush() return document
def test_srt_writer(self): doc = ContentDocument() r1 = Region("r1", doc) doc.put_region(r1) r2 = Region("r2", doc) r2.set_begin(Fraction(2)) r2.set_end(Fraction(4)) doc.put_region(r2) body = Body(doc) doc.set_body(body) div = Div(doc) body.push_child(div) p = P(doc) p.set_region(r1) p.set_end(Fraction(2)) div.push_child(p) span = Span(doc) span.push_child(Text(doc, "Lorem ipsum dolor sit amet,")) p.push_child(span) p = P(doc) p.set_region(r2) div.push_child(p) span = Span(doc) span.push_child(Text(doc, "consectetur adipiscing elit.")) p.push_child(span) p = P(doc) p.set_region(r1) p.set_begin(Fraction(4)) p.set_end(Fraction(6)) div.push_child(p) span = Span(doc) span.push_child( Text(doc, "Pellentesque interdum lacinia sollicitudin.")) p.push_child(span) expected_srt = """1 00:00:00,000 --> 00:00:02,000 Lorem ipsum dolor sit amet, 2 00:00:02,000 --> 00:00:04,000 consectetur adipiscing elit. 3 00:00:04,000 --> 00:00:06,000 Pellentesque interdum lacinia sollicitudin. """ srt_from_model = srt_writer.from_model(doc) self.assertEqual(expected_srt, srt_from_model)
def test_process_isd(self): supported_style_properties = SupportedStylePropertiesFilter({ StyleProperties.BackgroundColor: [NamedColors.red.value], StyleProperties.Extent: [] }) doc = ContentDocument() r1 = Region("r1", doc) r1.set_style(StyleProperties.BackgroundColor, NamedColors.red.value) r1.set_style(StyleProperties.LuminanceGain, 2.0) doc.put_region(r1) b = Body(doc) b.set_begin(Fraction(1)) b.set_end(Fraction(10)) doc.set_body(b) div1 = Div(doc) div1.set_region(r1) b.push_child(div1) p1 = P(doc) p1.set_style(StyleProperties.BackgroundColor, NamedColors.white.value) p1.set_style(StyleProperties.Direction, DirectionType.rtl) div1.push_child(p1) span1 = Span(doc) span1.set_style(StyleProperties.BackgroundColor, NamedColors.red.value) span1.set_style(StyleProperties.FontStyle, FontStyleType.italic) span1.set_style(StyleProperties.Direction, DirectionType.ltr) p1.push_child(span1) t1 = Text(doc, "hello") span1.push_child(t1) significant_times = sorted(ISD.significant_times(doc)) self.assertEqual(3, len(significant_times)) isd = ISD.from_model(doc, significant_times[1]) r1 = isd.get_region("r1") self.assertEqual(len(Region._applicableStyles), len(r1._styles)) self.assertEqual(NamedColors.red.value, r1.get_style(StyleProperties.BackgroundColor)) self.assertEqual(2.0, r1.get_style(StyleProperties.LuminanceGain)) body1 = list(r1)[0] div1 = list(body1)[0] p1 = list(div1)[0] span1 = list(p1)[0] self.assertEqual(len(P._applicableStyles), len(p1._styles)) self.assertEqual(NamedColors.white.value, p1.get_style(StyleProperties.BackgroundColor)) self.assertEqual(DirectionType.rtl, p1.get_style(StyleProperties.Direction)) self.assertEqual(len(Span._applicableStyles), len(span1._styles)) self.assertEqual(NamedColors.red.value, span1.get_style(StyleProperties.BackgroundColor)) self.assertEqual(FontStyleType.italic, span1.get_style(StyleProperties.FontStyle)) self.assertEqual(DirectionType.ltr, span1.get_style(StyleProperties.Direction)) supported_style_properties.process(isd) self.assertEqual(2, len(r1._styles)) self.assertEqual(NamedColors.red.value, r1.get_style(StyleProperties.BackgroundColor)) self.assertEqual( ExtentType(height=LengthType(value=0.0, units=LengthType.Units.rh), width=LengthType(value=0.0, units=LengthType.Units.rw)), r1.get_style(StyleProperties.Extent)) self.assertEqual(0, len(p1._styles)) self.assertIsNone(p1.get_style(StyleProperties.BackgroundColor)) self.assertIsNone(p1.get_style(StyleProperties.Direction)) self.assertEqual(1, len(span1._styles)) self.assertEqual(NamedColors.red.value, span1.get_style(StyleProperties.BackgroundColor)) self.assertIsNone(span1.get_style(StyleProperties.FontStyle)) self.assertIsNone(span1.get_style(StyleProperties.Direction))
def test_process_isd(self): default_style_value_filter = DefaultStylePropertyValuesFilter({ StyleProperties.BackgroundColor: NamedColors.red.value, StyleProperties.Direction: DirectionType.ltr }) doc = ContentDocument() r1 = Region("r1", doc) r1.set_style(StyleProperties.BackgroundColor, NamedColors.red.value) r1.set_style(StyleProperties.LuminanceGain, 2.0) doc.put_region(r1) b = Body(doc) b.set_begin(Fraction(1)) b.set_end(Fraction(10)) doc.set_body(b) div1 = Div(doc) div1.set_region(r1) b.push_child(div1) p1 = P(doc) p1.set_style(StyleProperties.BackgroundColor, NamedColors.white.value) p1.set_style(StyleProperties.Direction, DirectionType.rtl) div1.push_child(p1) span1 = Span(doc) span1.set_style(StyleProperties.BackgroundColor, NamedColors.red.value) span1.set_style(StyleProperties.FontStyle, FontStyleType.italic) span1.set_style(StyleProperties.Direction, DirectionType.ltr) p1.push_child(span1) t1 = Text(doc, "hello") span1.push_child(t1) significant_times = sorted(ISD.significant_times(doc)) self.assertEqual(3, len(significant_times)) isd = ISD.from_model(doc, significant_times[1]) r1 = isd.get_region("r1") self.assertEqual(len(Region._applicableStyles), len(r1._styles)) self.assertEqual(NamedColors.red.value, r1.get_style(StyleProperties.BackgroundColor)) self.assertEqual(2.0, r1.get_style(StyleProperties.LuminanceGain)) body1 = list(r1)[0] div1 = list(body1)[0] p1 = list(div1)[0] span1 = list(p1)[0] self.assertEqual(len(P._applicableStyles), len(p1._styles)) self.assertEqual(NamedColors.white.value, p1.get_style(StyleProperties.BackgroundColor)) self.assertEqual(DirectionType.rtl, p1.get_style(StyleProperties.Direction)) self.assertEqual(len(Span._applicableStyles), len(span1._styles)) self.assertEqual(NamedColors.red.value, span1.get_style(StyleProperties.BackgroundColor)) self.assertEqual(FontStyleType.italic, span1.get_style(StyleProperties.FontStyle)) self.assertEqual(DirectionType.ltr, span1.get_style(StyleProperties.Direction)) default_style_value_filter.process(isd) self.assertEqual(len(Region._applicableStyles) - 1, len(r1._styles)) self.assertIsNone(r1.get_style(StyleProperties.BackgroundColor)) self.assertEqual(len(P._applicableStyles), len(p1._styles)) self.assertEqual(NamedColors.white.value, p1.get_style(StyleProperties.BackgroundColor)) self.assertEqual(DirectionType.rtl, p1.get_style(StyleProperties.Direction)) self.assertEqual(len(Span._applicableStyles) - 1, len(span1._styles)) self.assertIsNone(span1.get_style(StyleProperties.BackgroundColor)) self.assertEqual(FontStyleType.italic, span1.get_style(StyleProperties.FontStyle)) self.assertEqual(DirectionType.ltr, span1.get_style(StyleProperties.Direction))