def test_get_value_or_attachment_uri(self): path = os.path.join( os.path.dirname(__file__), 'fixtures', 'photo_type_in_repeat_group.xlsx') self._publish_xls_file_and_set_xform(path) filename = u'bob/attachments/123.jpg' download_url = u'/api/v1/files/1?filename=%s' % filename # used a smaller version of row because we only using _attachmets key row = { u'_attachments': [{ u'mimetype': u'image/jpeg', u'medium_download_url': u'%s&suffix=medium' % download_url, u'download_url': download_url, u'filename': filename, u'name': '123.jpg', u'instance': 1, u'small_download_url': u'%s&suffix=small' % download_url, u'id': 1, u'xform': 1 }] } # yapf: disable # when include_images is True, you get the attachment url media_xpaths = ['photo'] attachment_list = None key = 'photo' value = u'123.jpg' val_or_url = get_value_or_attachment_uri(key, value, row, self.xform, media_xpaths, attachment_list) self.assertTrue(val_or_url) current_site = Site.objects.get_current() url = 'http://%s%s' % (current_site.domain, download_url) self.assertEqual(url, val_or_url) # when include_images is False, you get the value media_xpaths = [] val_or_url = get_value_or_attachment_uri(key, value, row, self.xform, media_xpaths, attachment_list) self.assertTrue(val_or_url) self.assertEqual(value, val_or_url) # test that when row is an empty dict, the function still returns a # value row.pop('_attachments', None) self.assertEqual(row, {}) media_xpaths = ['photo'] val_or_url = get_value_or_attachment_uri(key, value, row, self.xform, media_xpaths, attachment_list) self.assertTrue(val_or_url) self.assertEqual(value, val_or_url)
def _reindex(cls, key, value, ordered_columns, row, data_dictionary, parent_prefix=None, include_images=True): """ Flatten list columns by appending an index, otherwise return as is """ def get_ordered_repeat_value(xpath, repeat_value): children = data_dictionary.get_child_elements(xpath) item = OrderedDict() for elem in children: xp = elem.get_abbreviated_xpath() if xp in repeat_value: item[xp] = repeat_value[xp] return item d = {} # check for lists if type(value) is list and len(value) > 0 \ and key not in [ATTACHMENTS, NOTES]: for index, item in enumerate(value): # start at 1 index += 1 # for each list check for dict, we want to transform the key of # this dict if type(item) is dict: # order repeat according to xform order item = get_ordered_repeat_value(key, item) for nested_key, nested_val in item.iteritems(): # given the key "children/details" and nested_key/ # abbreviated xpath # "children/details/immunization/polio_1", # generate ["children", index, "immunization/polio_1"] xpaths = [ "%s[%s]" % ( nested_key[:nested_key.index(key) + len(key)], index), nested_key[nested_key.index(key) + len(key) + 1:]] # re-create xpath the split on / xpaths = "/".join(xpaths).split("/") new_prefix = xpaths[:-1] if type(nested_val) is list: # if nested_value is a list, rinse and repeat d.update(cls._reindex( nested_key, nested_val, ordered_columns, row, data_dictionary, new_prefix, include_images=include_images)) else: # it can only be a scalar # collapse xpath if parent_prefix: xpaths[0:len(parent_prefix)] = parent_prefix new_xpath = u"/".join(xpaths) # check if this key exists in our ordered columns if key in ordered_columns.keys(): if new_xpath not in ordered_columns[key]: ordered_columns[key].append(new_xpath) d[new_xpath] = get_value_or_attachment_uri( nested_key, nested_val, row, data_dictionary, include_images ) else: d[key] = get_value_or_attachment_uri( key, value, row, data_dictionary, include_images ) else: # anything that's not a list will be in the top level dict so its # safe to simply assign if key == NOTES: # Do not include notes d[key] = u"" else: d[key] = get_value_or_attachment_uri( key, value, row, data_dictionary, include_images ) return d
def _reindex(cls, key, value, ordered_columns, row, data_dictionary, parent_prefix=None, include_images=True, split_select_multiples=True, index_tags=DEFAULT_INDEX_TAGS, show_choice_labels=False, language=None): """ Flatten list columns by appending an index, otherwise return as is """ def get_ordered_repeat_value(xpath, repeat_value): """ Return OrderedDict of repeats in the order in which they appear in the XForm. """ children = data_dictionary.get_child_elements( xpath, split_select_multiples) item = OrderedDict() for elem in children: if not question_types_to_exclude(elem.type): xp = elem.get_abbreviated_xpath() item[xp] = repeat_value.get(xp, DEFAULT_NA_REP) return item d = {} # check for lists if isinstance(value, list) and len(value) > 0 \ and key not in [ATTACHMENTS, NOTES]: for index, item in enumerate(value): # start at 1 index += 1 # for each list check for dict, we want to transform the key of # this dict if isinstance(item, dict): # order repeat according to xform order item = get_ordered_repeat_value(key, item) for (nested_key, nested_val) in iteritems(item): # given the key "children/details" and nested_key/ # abbreviated xpath # "children/details/immunization/polio_1", # generate ["children", index, "immunization/polio_1"] if parent_prefix is not None: _key = '/'.join( parent_prefix + key.split('/')[len(parent_prefix):]) xpaths = ['{key}{open_tag}{index}{close_tag}' .format(key=_key, open_tag=index_tags[0], index=index, close_tag=index_tags[1])] + \ nested_key.split('/')[len(_key.split('/')):] else: xpaths = ['{key}{open_tag}{index}{close_tag}' .format(key=key, open_tag=index_tags[0], index=index, close_tag=index_tags[1])] + \ nested_key.split('/')[len(key.split('/')):] # re-create xpath the split on / xpaths = "/".join(xpaths).split("/") new_prefix = xpaths[:-1] if isinstance(nested_val, list): # if nested_value is a list, rinse and repeat d.update( cls._reindex( nested_key, nested_val, ordered_columns, row, data_dictionary, new_prefix, include_images=include_images, split_select_multiples= split_select_multiples, index_tags=index_tags, show_choice_labels=show_choice_labels, language=language)) else: # it can only be a scalar # collapse xpath new_xpath = u"/".join(xpaths) # check if this key exists in our ordered columns if key in list(ordered_columns): if new_xpath not in ordered_columns[key]: ordered_columns[key].append(new_xpath) d[new_xpath] = get_value_or_attachment_uri( nested_key, nested_val, row, data_dictionary, include_images, show_choice_labels=show_choice_labels, language=language) else: d[key] = get_value_or_attachment_uri( key, value, row, data_dictionary, include_images, show_choice_labels=show_choice_labels, language=language) else: # anything that's not a list will be in the top level dict so its # safe to simply assign if key == NOTES: # Do not include notes d[key] = u"" else: d[key] = get_value_or_attachment_uri( key, value, row, data_dictionary, include_images, show_choice_labels=show_choice_labels, language=language) return d
def _reindex(cls, key, value, ordered_columns, row, data_dictionary, parent_prefix=None, include_images=True, split_select_multiples=True, index_tags=DEFAULT_INDEX_TAGS, show_choice_labels=False, language=None): """ Flatten list columns by appending an index, otherwise return as is """ def get_ordered_repeat_value(xpath, repeat_value): """ Return OrderedDict of repeats in the order in which they appear in the XForm. """ children = data_dictionary.get_child_elements( xpath, split_select_multiples) item = OrderedDict() for elem in children: if not question_types_to_exclude(elem.type): xp = elem.get_abbreviated_xpath() item[xp] = repeat_value.get(xp, DEFAULT_NA_REP) return item d = {} # check for lists if isinstance(value, list) and len(value) > 0 \ and key not in [ATTACHMENTS, NOTES]: for index, item in enumerate(value): # start at 1 index += 1 # for each list check for dict, we want to transform the key of # this dict if isinstance(item, dict): # order repeat according to xform order item = get_ordered_repeat_value(key, item) for (nested_key, nested_val) in iteritems(item): # given the key "children/details" and nested_key/ # abbreviated xpath # "children/details/immunization/polio_1", # generate ["children", index, "immunization/polio_1"] if parent_prefix is not None: _key = '/'.join( parent_prefix + key.split('/')[len(parent_prefix):]) xpaths = ['{key}{open_tag}{index}{close_tag}' .format(key=_key, open_tag=index_tags[0], index=index, close_tag=index_tags[1])] + \ nested_key.split('/')[len(_key.split('/')):] else: xpaths = ['{key}{open_tag}{index}{close_tag}' .format(key=key, open_tag=index_tags[0], index=index, close_tag=index_tags[1])] + \ nested_key.split('/')[len(key.split('/')):] # re-create xpath the split on / xpaths = "/".join(xpaths).split("/") new_prefix = xpaths[:-1] if isinstance(nested_val, list): # if nested_value is a list, rinse and repeat d.update(cls._reindex( nested_key, nested_val, ordered_columns, row, data_dictionary, new_prefix, include_images=include_images, split_select_multiples=split_select_multiples, index_tags=index_tags, show_choice_labels=show_choice_labels, language=language)) else: # it can only be a scalar # collapse xpath new_xpath = u"/".join(xpaths) # check if this key exists in our ordered columns if key in list(ordered_columns): if new_xpath not in ordered_columns[key]: ordered_columns[key].append(new_xpath) d[new_xpath] = get_value_or_attachment_uri( nested_key, nested_val, row, data_dictionary, include_images, show_choice_labels=show_choice_labels, language=language) else: d[key] = get_value_or_attachment_uri( key, value, row, data_dictionary, include_images, show_choice_labels=show_choice_labels, language=language) else: # anything that's not a list will be in the top level dict so its # safe to simply assign if key == NOTES: # Do not include notes d[key] = u"" else: d[key] = get_value_or_attachment_uri( key, value, row, data_dictionary, include_images, show_choice_labels=show_choice_labels, language=language) return d