diff --git a/.travis.yml b/.travis.yml
index b978a6a..9c59367 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,17 +2,19 @@ language: python
python:
- "2.6"
- "2.7"
- - "3.2"
- "3.3"
- "3.4"
+ - "3.5"
- "pypy"
+ - "pypy3"
# command to install dependencies
install:
- pip install argparse
- pip install mock
- pip install coveralls
+ - pip install setuptools
# command to run tests, e.g. python setup.py test
-script: coverage run --source=cdl_convert tests/__init__.py
+script: coverage run --source cdl_convert setup.py test
# command to run after tests have completed
after_success:
- coveralls
\ No newline at end of file
+ coveralls
diff --git a/MANIFEST.in b/MANIFEST.in
index 4e40322..1109124 100755
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,4 @@
include README.rst
include LICENSE
-recursive-include docs_html *
\ No newline at end of file
+include cdl_convert.py
+recursive-include docs_html *
diff --git a/README.rst b/README.rst
index 334718d..5ca5004 100644
--- a/README.rst
+++ b/README.rst
@@ -11,7 +11,7 @@ CDL Convert
- **Docs:** http://cdl-convert.readthedocs.org/
- **GitHub:** https://github.com/shidarin/cdl_convert
- **PyPI:** https://pypi.python.org/pypi/cdl_convert
-- **Python Versions:** 2.6-3.4, PyPy
+- **Python Versions:** 2.6-3.5, PyPy & PyPy3
Introduction
------------
@@ -40,8 +40,8 @@ It is the purpose of ``cdl_convert`` to convert ASC CDL information between
these basic formats to further facilitate the ease of exchange of color
data within the Film and TV industries.
-``cdl_convert`` supports parsing ALE, FLEx, CC, CCC, CDL and RCDL. We can write
-out CC, CCC, CDL and RCDL.
+``cdl_convert`` supports parsing ALE, FLEx, CC, CCC, CDL CMX EDL and RCDL.
+We can write out CC, CCC, CDL and RCDL.
**cdl_convert is not associated with the American Society of
Cinematographers**
@@ -71,6 +71,21 @@ the ``-o`` flag.::
Changelog
---------
+*New in version 0.9.2:*
+
+- Fixed a bug where ALE's with blank lines would not convert correctly.
+- Fixed a bug that was preventing ``cdl_convert`` from being correctly installed in Python 2.6
+- Fixed continuous integration testing.
+- No longer officially supporting Python 3.2, as I've had to remove it from our CI builds. It should still work just fine though, but we won't be running CI against it.
+
+*New in version 0.9:*
+
+- Added ability to parse CMX EDLs
+- Fixed a script bug where a collection format containing color decisions will not have those color decisions exported as individual color corrections.
+- Fixed a bug where we weren't reading line endings correctly in certain situations.
+- Added a cdl_convert.py stub file to the package root level, which will allow running of the cdl_convert script without installation. Due to relative imports in the python code, it was no longer possible to call cdl_convert/cdl_convert.py directly.
+- The script, when run directly from cdl_convert.py, will now write errors to stderror correctly, and exit with a status of 1.
+
*New in version 0.8:*
- Added ``--single`` flag. When provided with an output collection format, each color correction in the input will be exported to it's own collection.
diff --git a/cdl_convert.py b/cdl_convert.py
new file mode 100644
index 0000000..9f717d1
--- /dev/null
+++ b/cdl_convert.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+"""
+
+CDL Convert
+=======================
+
+Stub file for script execution of cdl_convert without installing.
+
+## License
+
+The MIT License (MIT)
+
+cdl_convert
+Copyright (c) 2015 Sean Wallitsch
+http://github.com/shidarin/cdl_convert/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+"""
+
+# ==============================================================================
+# IMPORTS
+# ==============================================================================
+
+from __future__ import print_function
+
+# Standard Imports
+
+import sys
+
+# cdl_convert imports
+
+from cdl_convert.cdl_convert import main
+
+# ==============================================================================
+# PRIVATE FUNCTIONS
+# ==============================================================================
+
+
+def _print_error(*objs):
+ print(*objs, file=sys.stderr)
+
+# ==============================================================================
+# EXECUTION
+# ==============================================================================
+
+if __name__ == '__main__': # pragma: no cover
+ try:
+ main()
+ except Exception as err: # pylint: disable=W0703
+ import traceback
+ _print_error('Unexpected error encountered:')
+ _print_error(err)
+ _print_error(traceback.format_exc())
+ exit(1)
diff --git a/cdl_convert/__init__.py b/cdl_convert/__init__.py
index 70e3b3e..a14aec4 100755
--- a/cdl_convert/__init__.py
+++ b/cdl_convert/__init__.py
@@ -94,7 +94,7 @@
__copyright__ = "Copyright 2015, Sean Wallitsch"
__credits__ = ["Sean Wallitsch", ]
__license__ = "MIT"
-__version__ = "0.8"
+__version__ = "0.9.2"
__maintainer__ = "Sean Wallitsch"
__email__ = "shidarin@alphamatte.com"
__status__ = "Development"
diff --git a/cdl_convert/cdl_convert.py b/cdl_convert/cdl_convert.py
index ddf5236..e6a3380 100755
--- a/cdl_convert/cdl_convert.py
+++ b/cdl_convert/cdl_convert.py
@@ -251,6 +251,9 @@ def write_collection_file(col, ext):
if filetype_in in config.COLLECTION_FORMATS:
for color_correct in color_decisions.color_corrections:
sanity_check(color_correct)
+ for decision in color_decisions.color_decisions:
+ if not decision.is_ref:
+ sanity_check(decision.cc)
else:
sanity_check(color_decisions)
@@ -260,6 +263,9 @@ def write_collection_file(col, ext):
if filetype_in in config.COLLECTION_FORMATS:
for color_correct in color_decisions.color_corrections:
write_single_file(color_correct, ext)
+ for decision in color_decisions.color_decisions:
+ if not decision.is_ref:
+ write_single_file(decision.cc, ext)
else:
write_single_file(color_decisions, ext)
else:
@@ -279,13 +285,3 @@ def write_collection_file(col, ext):
collection = ColorCollection(input_file=filepath)
collection.append_child(color_decisions)
write_collection_file(collection, ext)
-
-if __name__ == '__main__': # pragma: no cover
- try:
- main()
- except Exception as err: # pylint: disable=W0703
- import traceback
- print('Unexpected error encountered:')
- print(err)
- print(traceback.format_exc())
- raw_input('Press enter key to exit')
diff --git a/cdl_convert/config.py b/cdl_convert/config.py
index cca8e7b..1d5277d 100644
--- a/cdl_convert/config.py
+++ b/cdl_convert/config.py
@@ -72,6 +72,7 @@
# id doesn't exist. (Other than first creation)
# If a ColorCorrection is given a duplicate ID
HALT_ON_ERROR = False
+MISSING_ID_FROM_DESC_IF_AVAILABLE = True
COLLECTION_FORMATS = ['ale', 'ccc', 'cdl', 'edl', 'flex']
SINGLE_FORMATS = ['cc', 'rcdl']
diff --git a/cdl_convert/correction.py b/cdl_convert/correction.py
index 59e0688..d08d9ae 100644
--- a/cdl_convert/correction.py
+++ b/cdl_convert/correction.py
@@ -537,7 +537,7 @@ def sat(self, value):
def build_element(self):
"""Builds an ElementTree XML Element representing this SatNode"""
- sat = ElementTree.Element('SATNode')
+ sat = ElementTree.Element('SatNode')
for description in self.desc:
desc = ElementTree.SubElement(sat, 'Description')
desc.text = description
diff --git a/cdl_convert/parse.py b/cdl_convert/parse.py
index 1c59e86..0f10f9a 100644
--- a/cdl_convert/parse.py
+++ b/cdl_convert/parse.py
@@ -75,12 +75,13 @@
from ast import literal_eval
import os
+import sys
import re
from xml.etree import ElementTree
# cdl_convert imports
-from . import collection, correction
+from . import config, collection, correction
# ==============================================================================
# EXPORTS
@@ -138,10 +139,13 @@ def parse_ale(input_file): # pylint: disable=R0914
cdls = []
- with open(input_file, 'r') as edl:
+ with open(input_file, 'rU') as edl:
lines = edl.readlines()
for line in lines:
- if line.startswith('Column'):
+ if not line.strip():
+ # Skip entirely blank lines
+ continue
+ elif line.startswith('Column'):
section['column'] = True
continue
elif line.startswith('Data'):
@@ -247,7 +251,10 @@ def parse_cc(input_file): # pylint: disable=R0912
try:
cc_id = root.attrib['id']
except KeyError:
- raise ValueError('No id found on ColorCorrection')
+ if config.HALT_ON_ERROR:
+ raise ValueError('No id found on ColorCorrection')
+ else:
+ cc_id = None
cdl = correction.ColorCorrection(cc_id)
if file_in:
@@ -296,6 +303,10 @@ def find_required(elem, names):
else:
return found_element
+ try:
+ desc_xml = find_required(root, ['Description'])
+ except ValueError:
+ desc_xml = None
try:
sop_xml = find_required(root, correction.SopNode.element_names)
except ValueError:
@@ -305,6 +316,14 @@ def find_required(elem, names):
except ValueError:
sat_xml = None
+ if cc_id is None:
+ if config.MISSING_ID_FROM_DESC_IF_AVAILABLE:
+ if desc_xml is not None:
+ try:
+ cdl.id = '_'.join(desc_xml.text.split())
+ except ValueError, v:
+ raise(ValueError, "Description based naming collided. Please fix cc's to have unique ids or descriptions")
+
if sop_xml is None and sat_xml is None:
raise ValueError(
'The ColorCorrection element requires either a Sop node or a Sat '
@@ -468,20 +487,23 @@ def parse_cmx(input_file): # pylint: disable=R0912,R0914
"""
cdls = []
- with open(input_file, 'rb') as edl:
- lines = edl.readlines()
+ with open(input_file, 'rU') as edl:
+
+ lines = '\n'.join(edl.readlines())
+ lines = lines.replace('\n\n', '\n')
filename = os.path.basename(input_file).split('.')[0]
def parse_cmx_clip(cmx_tuple):
+
"""Parses a three line cmx clip tuple."""
if len(cmx_tuple) != 3:
print(cmx_tuple)
return
- title = cmx_tuple[0].split()[1]
+ title = cmx_tuple[0].split(': ')[1]
sop = re.match(
- r'^\*ASC_SOP \(([\d\. -]+)\)\(([\d\. -]+)\)\(([\d\. -]+)\)',
+ r'^ASC_SOP \(([\d\. -]+)\)\(([\d\. -]+)\)\(([\d\. -]+)\)',
cmx_tuple[1]
)
if not sop:
@@ -500,18 +522,124 @@ def parse_cmx_clip(cmx_tuple):
return cc
- for i, line in enumerate(lines):
- if line != '\r\n':
- # We only care about newlines when reading CMX, because
- # we use those to kick off parsing the next take.
- continue
- if i + 3 <= len(lines):
- cc = parse_cmx_clip(lines[i + 1:i + 4])
+
+ '''
+ Trailing whitespace can be a sneaky devil in cleanup operations
+ '''
+ whitespace_cleaner = re.compile(r'([\s\S]*?)[\t ]*\n')
+ lines = whitespace_cleaner.sub(r'\1\n', lines)
+ lines = lines + '\n'
+
+ '''
+ We'll try to pre-clean an EDL away from several of the standard types of aberrations between
+ the various EDL formatting types because no one cares to follow a standard.
+ Some EDL's have ASC_SOP lines split by a new-line and asterisk, so we're hoping to rescue those,
+ and remove other types of lines that are useless to us as well increase the possibility of hitting
+ a regex-malforming problem (like the word LOC appearing in a VFX note for example)
+ '''
+ def replace_newline(match):
+ if '\n' in match.group(0):
+ return (match.group(0).replace('\n', '')+'\n')
+ else:
+ return match.group(0)
+
+ split_ascsop_finder = re.compile(r'(ASC_SOP[\s\S]*?)[ ]*?\([\s\S]*?\)[\s\S]*?\([\s\S]*?\)[\s\S]*?\([\s\S]*?\)')
+ lines = split_ascsop_finder.sub(replace_newline, lines)
+
+ '''
+ An empty ASC_SOP or ASC_SAT line doesnt parse well and should be replaced with a null op so that
+ we retain the event even if the data is useless
+ '''
+ print(lines)
+ print("cleaning")
+ null_ascsop = 'ASC_SOP (1.0000 1.0000 1.0000)(1.0000 1.0000 1.0000)(1.0000 1.0000 1.0000)\n'
+ null_ascsat = 'ASC_SAT 1\n'
+ null_ascsop_finder = re.compile(r'ASC_SOP *?\n')
+ null_ascsat_finder = re.compile(r'ASC_SAT *?\n')
+ lines = null_ascsop_finder.sub(null_ascsop , lines)
+ lines = null_ascsat_finder.sub(null_ascsat , lines)
+
+ print("cleaned")
+ print(lines)
+ edl_block_finder = re.compile(r'(?<=\n)(\d+?[ ][\s\S]*?)(?=(([\n]\d+?[ ])|(\Z)))')
+ edl_blocks = edl_block_finder.findall(lines)
+ new_edl_blocks = []
+ for block in edl_blocks:
+ print(block)
+ block = block[0]
+ reordered_block = []
+ block_lines = block.split('\n')
+ reordered_block.append(block_lines[0])
+ if 'FROM CLIP NAME:' or 'LOC:' in block:
+ for block_line in block_lines:
+ if 'FROM CLIP NAME:' in block_line or 'LOC:' in block_line:
+ reordered_block.append(block_line)
+ else:
+ clip_namer = re.compile(r'\d*\s*(\S*)(?=\s*)')
+ clip_name = clip_namer.findall(block_lines[0])[0]
+ block_line = 'FROM CLIP NAME: %s\n' % clip_name
+ reordered_block.append(block_line)
+ if 'ASC_SOP' in block:
+ for block_line in block_lines:
+ if 'ASC_SOP' in block_line:
+ reordered_block.append(block_line)
+ else:
+ asc_sop_default = 'ASC_SOP (1.0 1.0 1.0)(0.0 0.0 0.0)(1.0 1.0 1.0)'
+ reordered_block.append(asc_sop_default)
+ if 'ASC_SAT' in block:
+ for block_line in block_lines:
+ if 'ASC_SAT' in block_line:
+ reordered_block.append(block_line)
+ else:
+ asc_sat_default = 'ASC_SAT 1.0'
+ reordered_block.append(asc_sat_default)
+ for block_line in block_lines:
+ if block_line not in reordered_block:
+ reordered_block.append(block_line)
+ new_block = '\n'.join(reordered_block)
+ new_edl_blocks.append(new_block)
+ lines = '\n'.join(new_edl_blocks)
+
+ lines = lines.replace('* ', '').replace('*', '')
+ lines = re.sub('\nSOURCE FILE:.*', '', lines)
+ lines = re.sub('\nSOURCE.*', '', lines)
+ lines = re.sub('\nREEL:.*', '', lines)
+ lines = re.sub('\nDescript:.*', '', lines)
+ lines = re.sub('\n.*[=].*', '', lines)
+
+
+ '''
+ We sort of need to fail if we don't have any information; That is, if the number of
+ clip naming type entries does not correspond with the number of ASC type entries.
+ '''
+ declaration_matcher = re.compile(r'((FROM CLIP NAME:[\s\S]*?)|(LOC: [\s\S]*?))((?!ASC)[\s\S])*')
+ if len(declaration_matcher.findall(lines) * 2) != len(re.findall(r'ASC', lines)):
+ sys.exit("Inequal amounts of 'FROM CLIP NAME'|'LOC', 'ASC', 'SAT' lines - Exiting")
+
+ '''This regex will avoid caring about extra stuff between
+ the important lines we care about as long as the important
+ lines we care about are in the right order'''
+ cc_matcher = re.compile(r'((\A)|(\n+\d+.*))([\s\S]+?)(((FROM CLIP NAME:.*[\s\S]*?)|(LOC:.*[\s\S]*?)))((?!ASC)[\s\S]*?)(((ASC_(SOP|SAT).+)))([\s\S]+?)(((ASC_(SOP|SAT).+)))')
+ clip_entries = cc_matcher.findall(lines)
+ for entry in clip_entries:
+ clip = None
+ sop = None
+ sat = None
+ i = 0
+ for group in entry:
+ if ('FROM' in group or 'LOC' in group) and clip is None:
+ clip = group
+ if group == 'SOP':
+ sop = entry[i - 1]
+ if group == 'SAT':
+ sat = entry[i - 1]
+ i += 1
+ if clip is not None and sop is not None and sat is not None:
+ colorCorrect = parse_cmx_clip((clip, sop, sat))
+ cdls.append(colorCorrect)
else:
continue
- cdls.append(cc)
-
ccc = collection.ColorCollection()
ccc.file_in = input_file
ccc.append_children(cdls)
@@ -575,7 +703,7 @@ def parse_flex(input_file): # pylint: disable=R0912,R0914
cdls = []
- with open(input_file, 'r') as edl:
+ with open(input_file, 'rU') as edl:
lines = edl.readlines()
filename = os.path.basename(input_file).split('.')[0]
@@ -700,7 +828,7 @@ def parse_rnh_cdl(input_file):
"""
- with open(input_file, 'r') as cdl_f:
+ with open(input_file, 'rU') as cdl_f:
# We only need to read the first line
line = cdl_f.readline()
line = line.split()
diff --git a/cdl_convert/utils.py b/cdl_convert/utils.py
index bf07cd4..a4b37ec 100644
--- a/cdl_convert/utils.py
+++ b/cdl_convert/utils.py
@@ -173,7 +173,10 @@ def to_decimal(value, name='Value'):
elif type(value) is Decimal:
return value
elif type(value) is str:
- if '.' not in value:
+ if 'e' in value:
+ value = str(float(value))
+ elif '.' not in value:
+ value = value.strip()
value += '.0'
try:
diff --git a/dev-requirements.txt b/dev-requirements.txt
index a24e95c..1672d7b 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,2 +1,4 @@
# Used for running the test suite
mock>=1.0.1
+nose>=1.3
+sphinx>=1.3
diff --git a/docs/cdl_convert.rst b/docs/cdl_convert.rst
index 943e381..63c9f8d 100644
--- a/docs/cdl_convert.rst
+++ b/docs/cdl_convert.rst
@@ -2,10 +2,6 @@
API Reference
#############
-.. note::
- All code for the following lives under cdl_convert.cdl_convert, and is
- imported into the local space of cdl_convert.
-
Classes
=======
@@ -239,6 +235,11 @@ Parse cdl
.. autofunction:: cdl_convert.parse.parse_cdl
+Parse cmx
+---------
+
+.. autofunction:: cdl_convert.parse.parse_cmx
+
Parse file
----------
diff --git a/docs/changelog.rst b/docs/changelog.rst
index c882946..6a70c0c 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -2,6 +2,23 @@
Changelog
#########
+Version 0.9.2
+=============
+
+- Fixed a bug where ALE's with blank lines would not convert correctly.
+- Fixed a bug that was preventing ``cdl_convert`` from being correctly installed in Python 2.6
+- Fixed continuous integration testing.
+- No longer officially supporting Python 3.2, as I've had to remove it from our CI builds. It should still work just fine though, but we won't be running CI against it.
+
+Version 0.9
+===========
+
+- Added ability to parse CMX EDLs
+- Fixed a script bug where a collection format containing color decisions will not have those color decisions exported as individual color corrections.
+- Fixed a bug where we weren't reading line endings correctly in certain situations.
+- Added a cdl_convert.py stub file to the package root level, which will allow running of the cdl_convert script without installation. Due to relative imports in the python code, it was no longer possible to call cdl_convert/cdl_convert.py directly.
+- The script, when run directly from cdl_convert.py, will now write errors to stderror correctly, and exit with a status of 1.
+
Version 0.8
===========
diff --git a/docs/index.rst b/docs/index.rst
index f04ad89..0054f28 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -58,6 +58,20 @@ Cinematographers**
Changelog
=========
+*New in version 0.9.2:*
+
+- Fixed a bug where ALE's with blank lines would not convert correctly.
+- Fixed a bug that was preventing ``cdl_convert`` from being correctly installed in Python 2.6
+- Fixed continuous integration testing.
+- No longer officially supporting Python 3.2, as I've had to remove it from our CI builds. It should still work just fine though, but we won't be running CI against it.
+
+*New in version 0.9:*
+
+- Added ability to parse CMX EDLs
+- Fixed a script bug where a collection format containing color decisions will not have those color decisions exported as individual color corrections.
+- Fixed a bug where we weren't reading line endings correctly in certain situations.
+- Added a cdl_convert.py stub file to the package root level, which will allow running of the cdl_convert script without installation. Due to relative imports in the python code, it was no longer possible to call cdl_convert/cdl_convert.py directly.
+- The script, when run directly from cdl_convert.py, will now write errors to stderror correctly, and exit with a status of 1.
*New in version 0.8:*
diff --git a/setup.py b/setup.py
index 13e994d..515f6a6 100755
--- a/setup.py
+++ b/setup.py
@@ -2,6 +2,17 @@
import codecs
import os
import re
+import sys
+
+if sys.hexversion >= 0x20700f0: # 2.7.0 (final release)
+ install_requires = []
+elif 0x20600f0 <= sys.hexversion < 0x20700f0: # 2.6.0 (final release)
+ install_requires = ['argparse']
+else:
+ raise RuntimeError(
+ "cdl_convert requires python 2.6 or greater. Current python version "
+ "is '%s'" % sys.version
+ )
# Instructions for setting up a dist of cdl_convert
#
@@ -149,11 +160,11 @@ def find_metadata(filepath):
# List run-time dependencies here. These will be installed by pip when your
# project is installed.
- install_requires=['argparse'],
+ install_requires=install_requires,
# Testing
test_suite='nose.collector',
- tests_require=['nose'],
+ tests_require=['nose', 'mock'],
# If there are data files included in your packages that need to be
# installed, specify them here. If using Python 2.6 or less, then these
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100755
index e5cadb3..0000000
--- a/tests/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python
-"""Collects all the various tests into one big test suite"""
-
-from test_cdl_convert import *
-from test_classes import *
-from test_ale import *
-from test_cc import *
-from test_ccc import *
-from test_cdl import *
-from test_flex import *
-from test_rnh_cdl import *
-
-
-if __name__ == '__main__':
- unittest.main()
-
diff --git a/tests/test_ale.py b/tests/test_ale.py
index fed707a..db2067b 100644
--- a/tests/test_ale.py
+++ b/tests/test_ale.py
@@ -31,7 +31,7 @@
sys.path.append('/'.join(os.path.realpath(__file__).split('/')[:-2]))
import cdl_convert
-from tests.test_cdl_convert import TimeCodeSegment
+from test_cdl_convert import TimeCodeSegment
#==============================================================================
# GLOBALS
@@ -319,6 +319,54 @@ def setUp(self):
self.cdl2 = self.cdls.color_corrections[1]
self.cdl3 = self.cdls.color_corrections[2]
+
+class TestParseALEShortAndBlankLines(TestParseALEBasic):
+ """Tests basic parsing of a shortened ALE with line breaks"""
+
+ #==========================================================================
+ # SETUP & TEARDOWN
+ #==========================================================================
+
+ def setUp(self):
+ self.slope1 = decimalize(1.329, 0.9833, 1.003)
+ self.offset1 = decimalize(0.011, 0.013, 0.11)
+ self.power1 = decimalize(.993, .998, 1.0113)
+ self.sat1 = Decimal('1.01')
+
+ line1 = buildALELine(self.slope1, self.offset1, self.power1, self.sat1,
+ 'bb94_x103_line1', short=True)
+
+ # Note that there are limits to the floating point precision here.
+ # Python will not parse numbers exactly with numbers with more
+ # significant whole and decimal digits
+ self.slope2 = decimalize(137829.329, 4327890.9833, 3489031.003)
+ self.offset2 = decimalize(-3424.011, -342789423.013, -4238923.11)
+ self.power2 = decimalize(3271893.993, .0000998, 0.0000000000000000113)
+ self.sat2 = Decimal('1798787.01')
+
+ line2 = buildALELine(self.slope2, self.offset2, self.power2, self.sat2,
+ 'bb94_x104_line2', short=True)
+
+ self.slope3 = decimalize(1.2, 2.32, 10.82)
+ self.offset3 = decimalize(-1.3782, 278.32, 0.738378233782)
+ self.power3 = decimalize(1.329, 0.9833, 1.003)
+ self.sat3 = Decimal('0.99')
+
+ line3 = buildALELine(self.slope3, self.offset3, self.power3, self.sat3,
+ 'bb94_x105_line3', short=True)
+
+ self.file = ALE_HEADER_SHORT.replace('Column', 'Column\n\n').replace('Data', 'Data\n\n') + line1 + line2 + line3
+
+ # Build our ale
+ with tempfile.NamedTemporaryFile(mode='wb', delete=False) as f:
+ f.write(enc(self.file))
+ self.filename = f.name
+
+ self.cdls = cdl_convert.parse_ale(self.filename)
+ self.cdl1 = self.cdls.color_corrections[0]
+ self.cdl2 = self.cdls.color_corrections[1]
+ self.cdl3 = self.cdls.color_corrections[2]
+
#==============================================================================
# FUNCTIONS
#==============================================================================
diff --git a/tests/test_cc.py b/tests/test_cc.py
index f32293d..af6c17c 100644
--- a/tests/test_cc.py
+++ b/tests/test_cc.py
@@ -215,11 +215,11 @@
-0.00315 -0.00124 0.3103
1.0 0.9983 1.0
-
+
Sat description 1
Sat description 2
1.09
-
+
"""
@@ -236,18 +236,18 @@
-3424.011 -342789423.013 -4238923.11
3271893.993 0.0000998 0.0000000000000000113
-
+
1798787.01
-
+
"""
CC_NO_SOP_WRITE = """
-
+
I am a lovely sat node
1.0128109381
-
+
"""
@@ -635,17 +635,17 @@ def tearDown(self):
#==========================================================================
def testNoId(self):
- """Tests that not finding an id attrib raises ValueError"""
+ """Tests that not finding an id attrib works"""
# Build our cc
with tempfile.NamedTemporaryFile(mode='wb', delete=False) as f:
f.write(enc(CC_NO_ID))
self.file = f.name
- self.assertRaises(
- ValueError,
- cdl_convert.parse_cc,
- self.file
+ cc = cdl_convert.parse_cc(self.file)
+ self.assertEqual(
+ '001',
+ cc.id
)
#==========================================================================
diff --git a/tests/test_ccc.py b/tests/test_ccc.py
index 024c542..edd0894 100644
--- a/tests/test_ccc.py
+++ b/tests/test_ccc.py
@@ -213,11 +213,11 @@
-0.00315 -0.00124 0.3103
1.0 0.9983 1.0
-
+
Sat description 1
Sat description 2
1.09
-
+
@@ -225,9 +225,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
METAL VIEWER!!! \/\/
@@ -240,9 +240,9 @@
-3424.011 -342789423.013 -4238923.11
3271893.993 0.0000998 0.0000000000000000113
-
+
1798787.01
-
+
@@ -250,9 +250,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
@@ -260,15 +260,15 @@
-0.00315 -0.00124 0.3103
1.0 0.9983 1.0
-
+
1.09
-
+
-
+
I am a lovely sat node
1.01
-
+
@@ -305,11 +305,11 @@
-0.00315 -0.00124 0.3103
1.0 0.9983 1.0
-
+
Sat description 1
Sat description 2
1.09
-
+
@@ -319,9 +319,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
@@ -336,9 +336,9 @@
-3424.011 -342789423.013 -4238923.11
3271893.993 0.0000998 0.0000000000000000113
-
+
1798787.01
-
+
@@ -348,9 +348,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
@@ -360,17 +360,17 @@
-0.00315 -0.00124 0.3103
1.0 0.9983 1.0
-
+
1.09
-
+
-
+
I am a lovely sat node
1.01
-
+
@@ -408,20 +408,20 @@
-
+
1798787.01
-
+
-
+
1.01
-
+
-
+
I am a lovely sat node
1.01
-
+
"""
@@ -454,24 +454,24 @@
-
+
1798787.01
-
+
-
+
1.01
-
+
-
+
I am a lovely sat node
1.01
-
+
diff --git a/tests/test_cdl.py b/tests/test_cdl.py
index 3801f4a..23ba624 100644
--- a/tests/test_cdl.py
+++ b/tests/test_cdl.py
@@ -260,11 +260,11 @@
-0.00315 -0.00124 0.3103
1.0 0.9983 1.0
-
+
Sat description 1
Sat description 2
1.09
-
+
@@ -274,9 +274,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
@@ -295,9 +295,9 @@
-3424.011 -342789423.013 -4238923.11
3271893.993 0.0000998 0.0000000000000000113
-
+
1798787.01
-
+
@@ -310,9 +310,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
@@ -322,9 +322,9 @@
-0.00315 -0.00124 0.3103
1.0 0.9983 1.0
-
+
1.09
-
+
@@ -359,11 +359,11 @@
-0.00315 -0.00124 0.3103
1.0 0.9983 1.0
-
+
Sat description 1
Sat description 2
1.09
-
+
@@ -371,9 +371,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
@@ -381,9 +381,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
METAL VIEWER!!! \/\/
@@ -396,9 +396,9 @@
-3424.011 -342789423.013 -4238923.11
3271893.993 0.0000998 0.0000000000000000113
-
+
1798787.01
-
+
@@ -406,9 +406,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
@@ -416,9 +416,9 @@
-0.00315 -0.00124 0.3103
1.0 0.9983 1.0
-
+
1.09
-
+
@@ -426,9 +426,9 @@
0.031 0.128 -0.096
1.8 0.97 0.961
-
+
1.01
-
+
"""
@@ -477,10 +477,10 @@
-
+
I am a lovely sat node
1.01
-
+
@@ -541,10 +541,10 @@
-
+
I am a lovely sat node
1.01
-
+
@@ -588,10 +588,10 @@
-
+
I am a lovely sat node
1.01
-
+
diff --git a/tests/test_cdl_convert.py b/tests/test_cdl_convert.py
index cbcfdea..c08ca5d 100644
--- a/tests/test_cdl_convert.py
+++ b/tests/test_cdl_convert.py
@@ -1606,6 +1606,16 @@ def testStringInt(self):
result
)
+ def testStringIntWithSpaces(self):
+ """Tests string conversions"""
+ value = ' 1 '
+
+ result = utils.to_decimal(value)
+ self.assertEqual(
+ Decimal('1.0'),
+ result
+ )
+
def testStringAdvanced(self):
"""Tests string conversions"""
value = '1237891273.23162178368123787214849017132897'