Index: gm/rebaseline_server/imagediffdb.py |
diff --git a/gm/rebaseline_server/imagediffdb.py b/gm/rebaseline_server/imagediffdb.py |
index 3a2ce63b954f6244454e76ddf085e4fca66ef643..936301e1cdef393e736ad852283768482037a63c 100644 |
--- a/gm/rebaseline_server/imagediffdb.py |
+++ b/gm/rebaseline_server/imagediffdb.py |
@@ -12,6 +12,7 @@ Calulate differences between image pairs, and store them in a database. |
import contextlib |
import logging |
import os |
+import re |
import shutil |
import urllib |
try: |
@@ -23,6 +24,8 @@ except ImportError: |
DEFAULT_IMAGE_SUFFIX = '.png' |
DEFAULT_IMAGES_SUBDIR = 'images' |
+DISALLOWED_FILEPATH_CHAR_REGEX = re.compile('[^\w\-]') |
+ |
DIFFS_SUBDIR = 'diffs' |
WHITEDIFFS_SUBDIR = 'whitediffs' |
@@ -61,6 +64,9 @@ class DiffRecord(object): |
actual_images_subdir: the subdirectory actual images are stored in. |
image_suffix: the suffix of images. |
""" |
+ expected_image_locator = _sanitize_locator(expected_image_locator) |
+ actual_image_locator = _sanitize_locator(actual_image_locator) |
+ |
# Download the expected/actual images, if we don't have them already. |
# TODO(rmistry): Add a parameter that makes _download_and_open_image raise |
# an exception if images are not found locally (instead of trying to |
@@ -132,6 +138,16 @@ class DiffRecord(object): |
for each R/G/B channel, as a list.""" |
return self._max_diff_per_channel |
+ def as_dict(self): |
+ """Returns a dictionary representation of this DiffRecord, as needed when |
+ constructing the JSON representation.""" |
+ return { |
+ 'numDifferingPixels': self._num_pixels_differing, |
+ 'percentDifferingPixels': self.get_percent_pixels_differing(), |
+ 'weightedDiffMeasure': self.get_weighted_diff_measure(), |
+ 'maxDiffPerChannel': self._max_diff_per_channel, |
+ } |
+ |
class ImageDiffDB(object): |
""" Calculates differences between image pairs, maintaining a database of |
@@ -174,6 +190,8 @@ class ImageDiffDB(object): |
actual image within storage_root (probably including a checksum to |
guarantee uniqueness) |
""" |
+ expected_image_locator = _sanitize_locator(expected_image_locator) |
+ actual_image_locator = _sanitize_locator(actual_image_locator) |
key = (expected_image_locator, actual_image_locator) |
if not key in self._diff_dict: |
try: |
@@ -193,7 +211,8 @@ class ImageDiffDB(object): |
Raises a KeyError if we don't have a DiffRecord for this image pair. |
""" |
- key = (expected_image_locator, actual_image_locator) |
+ key = (_sanitize_locator(expected_image_locator), |
+ _sanitize_locator(actual_image_locator)) |
return self._diff_dict[key] |
@@ -322,6 +341,15 @@ def _mkdir_unless_exists(path): |
if not os.path.isdir(path): |
os.makedirs(path) |
+def _sanitize_locator(locator): |
+ """Returns a sanitized version of a locator (one in which we know none of the |
+ characters will have special meaning in filenames). |
+ |
+ Args: |
+ locator: string, or something that can be represented as a string |
+ """ |
+ return DISALLOWED_FILEPATH_CHAR_REGEX.sub('_', str(locator)) |
+ |
def _get_difference_locator(expected_image_locator, actual_image_locator): |
"""Returns the locator string used to look up the diffs between expected_image |
and actual_image. |
@@ -330,7 +358,8 @@ def _get_difference_locator(expected_image_locator, actual_image_locator): |
expected_image_locator: locator string pointing at expected image |
actual_image_locator: locator string pointing at actual image |
- Returns: locator where the diffs between expected and actual images can be |
- found |
+ Returns: already-sanitized locator where the diffs between expected and |
+ actual images can be found |
""" |
- return "%s-vs-%s" % (expected_image_locator, actual_image_locator) |
+ return "%s-vs-%s" % (_sanitize_locator(expected_image_locator), |
+ _sanitize_locator(actual_image_locator)) |