-
Notifications
You must be signed in to change notification settings - Fork 6
Fix for ALEs with too few or too many blank lines between sections #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
48e9202
a2b2a90
3a88cf8
bee0789
5381849
7d31fd3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
|
|
||
| DEFAULT_VIDEO_FORMAT = '1080' | ||
| ASC_SOP_REGEX = re.compile(r'(-*\d+\.\d+)') | ||
| ALE_SECTION_DESIGNATORS = {"Heading", "Column", "Data"} | ||
|
|
||
|
|
||
| def AVID_VIDEO_FORMAT_FROM_WIDTH_HEIGHT(width, height): | ||
|
|
@@ -182,6 +183,70 @@ def _video_format_from_metadata(clips): | |
| return AVID_VIDEO_FORMAT_FROM_WIDTH_HEIGHT(max_width, max_height) | ||
|
|
||
|
|
||
| def _read_heading_lines(lines): | ||
| """ | ||
| Consumes all the Header information from lines returning a dictionary | ||
| mapping header keys to header values. | ||
| """ | ||
| header = {} | ||
| # read until we run out of lines or the next section starts, not consuming | ||
| # the next section designator | ||
| while len(lines) and lines[0] not in ALE_SECTION_DESIGNATORS: | ||
| line = lines.pop(0) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a huge fan of mutating input arguments, but it's a private func, we're fine.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I don't love that either - I've renamed it to |
||
| if line.strip() == "": | ||
| continue | ||
|
|
||
| if "\t" not in line: | ||
| raise ALEParseError("Invalid Heading line: " + line) | ||
|
|
||
| segments = line.split("\t") | ||
| while len(segments) >= 2: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Segments beyond the 2nd are lost here. Should that be an error condition, or should those be part of
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the check on line 206 handles that behavior, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It only gets to line 207 and raises an ALEParseError if there's an odd number of values in the row. Otherwise it handles even pairs fine and they all get added to the header dictionary, no key value pairs lost. WACK_HEADER = "FIELD_DELIM\tTABS\n\nVIDEO_FORMAT\t108\tBANANA\tAPPLE\tGRAPE\tJUICE\n\nAUDIO_FORMAT\t48kh\tCESSNA\tDIAMOND\n\nFPS\t25\tWRONGFPS\t23"
lines = WACK_HEADER.splitlines()
header = _read_heading_lines(lines)
header
>>> {'FIELD_DELIM': 'TABS', 'VIDEO_FORMAT': '108', 'BANANA': 'APPLE', 'GRAPE': 'JUICE', 'AUDIO_FORMAT': '48kh', 'CESSNA': 'DIAMOND', 'FPS': '25', 'WRONGFPS': '23'} |
||
| key, val = segments.pop(0), segments.pop(0) | ||
| header[key] = val | ||
| if len(segments) != 0: | ||
| raise ALEParseError("Invalid Heading line: " + line) | ||
|
|
||
| return header | ||
|
|
||
|
|
||
| def _pop_columns(lines): | ||
| """ | ||
| Consumes the Column information from the ALE and returns the list of | ||
| columns. | ||
| """ | ||
| try: | ||
| line = lines.pop(0) | ||
| # skip blank lines | ||
| while not line.strip(): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a "skip blank lines" comment here for readability. |
||
| line = lines.pop(0) | ||
| except IndexError: | ||
| raise ALEParseError("Unexpected end of file after 'Column'") | ||
|
|
||
| columns = line.split("\t") | ||
|
|
||
| return columns | ||
|
|
||
|
|
||
| def _read_data(lines, columns, fps, ale_name_column_key): | ||
| """ | ||
| Generator consuming the Data section of the ALE yielding Clips. | ||
| """ | ||
| while len(lines): | ||
| line = lines.pop(0) | ||
|
|
||
| if line.strip() == "": | ||
| continue | ||
|
|
||
| clip = _parse_data_line( | ||
| line, | ||
| columns, | ||
| fps, | ||
| ale_name_column_key=ale_name_column_key | ||
| ) | ||
|
|
||
| yield clip | ||
|
|
||
|
|
||
| def read_from_string(input_str, fps=24, **adapter_argument_map): | ||
| ale_name_column_key = adapter_argument_map.get( | ||
| "ale_name_column_key", "Name" | ||
|
|
@@ -203,21 +268,7 @@ def nextline(lines): | |
| continue | ||
|
|
||
| if line.strip() == "Heading": | ||
| while len(lines): | ||
| line = nextline(lines) | ||
|
|
||
| if line.strip() == "": | ||
| break | ||
|
|
||
| if "\t" not in line: | ||
| raise ALEParseError("Invalid Heading line: " + line) | ||
|
|
||
| segments = line.split("\t") | ||
| while len(segments) >= 2: | ||
| key, val = segments.pop(0), segments.pop(0) | ||
| header[key] = val | ||
| if len(segments) != 0: | ||
| raise ALEParseError("Invalid Heading line: " + line) | ||
| header.update(_read_heading_lines(lines)) | ||
|
|
||
| if "FPS" in header: | ||
| read_fps = float(header["FPS"]) | ||
|
|
@@ -234,24 +285,13 @@ def nextline(lines): | |
| if len(lines) == 0: | ||
| raise ALEParseError("Unexpected end of file after: " + line) | ||
|
|
||
| line = nextline(lines) | ||
| columns = line.split("\t") | ||
| columns = _pop_columns(lines) | ||
|
|
||
| if line.strip() == "Data": | ||
| while len(lines): | ||
| line = nextline(lines) | ||
|
|
||
| if line.strip() == "": | ||
| continue | ||
|
|
||
| clip = _parse_data_line( | ||
| line, | ||
| columns, | ||
| fps, | ||
| ale_name_column_key=ale_name_column_key | ||
| ) | ||
|
|
||
| collection.append(clip) | ||
| clip_generator = _read_data( | ||
| lines, columns, fps, ale_name_column_key | ||
| ) | ||
| collection.extend(clip_generator) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't actually need to create the Collection until here, since we're no longer appending to it. Do we even need to extend it or can we just generate it in one line?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did it above because if, for some reason, there's no data, we still can populate any other parsed header and columns. |
||
|
|
||
| collection.metadata["ALE"] = { | ||
| "header": header, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| Heading | ||
|
|
||
| FIELD_DELIM TABS | ||
|
|
||
| VIDEO_FORMAT 1080 | ||
|
|
||
| AUDIO_FORMAT 48khz | ||
|
|
||
| FPS 25 | ||
|
|
||
|
|
||
|
|
||
| Column | ||
|
|
||
| Name Tracks Start End Take Tape UNC FPS Reel Scene Shoot date Manufacturer Source Resolution Source Bit Depth DESCRIPT Comments Audio SR Audio Bit Depth Auxiliary TC1 KN Start Source File Path Filter Camera ID ISO Lens Number Camera Serial # Camera Type White Point (Kelvin) Angle Camera Clip Number Stereoscopic Eye Gamma Space LUT 1 ASC_SOP ASC_SAT RESOLVE_SIZING | ||
|
|
||
|
|
||
|
|
||
| Data | ||
|
|
||
| A020C003_150905_E2XZ.mov V 05:42:12:20 05:42:30:12 A020E2XZ Y:\Pennrand_CompWorkflow_XXXXXX\04_Compositing\11_Render_Compositing\PennComp_Za250\PennComp_Za250_Raw\A020C003_150905_E2XZ.mov 25 A020E2XZ 20150905 DaVinci Resolve 2048x1152 16 Y:\Pennrand_CompWorkflow_XXXXXX\04_Compositing\11_Render_Compositing\PennComp_Za250\PennComp_Za250_Raw\A020C003_150905_E2XZ.mov 0 E2XZ 800 0 3120 Alexa Plus 4700 1800 A A020C003_150905_E2XZ SINGLE LOG-C None (1.1822 1.2183 1.2284)(-0.2429 -0.2823 -0.2849)(0.7283 0.7096 0.7054) 1.0680 (0.0000 0.0000 1.0000 0.0000 0.0000 0 0) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good, this means we skip over as many blank lines at the end as we need.