コード例 #1
0
ファイル: operations.py プロジェクト: opendesk/winnow
def merge(source_a, source_b, target, doc, validation=True):

    doc_a = source_a.get_doc()
    doc_b = source_b.get_doc()

    # get the options from bothe sources
    options_a = deepcopy(source_a.get_options_dict())
    options_b = deepcopy(source_b.get_options_dict())

    errors = []

    # carry any errors through
    errors_a = doc_a.get("errors")
    if errors_a:
        errors += errors_a

    errors_b = doc_b.get("errors")
    if errors_b:
        errors += errors_b

    merged_options = inline._merge_option_dicts(source_a, options_a, options_b, doc_a, doc_b, errors=errors)

    # put this merged options into a copy of the doc
    new_doc = deepcopy(doc)
    new_doc[OPTIONS_KEY] = merged_options
    if errors:
        new_doc["errors"] = errors

    target.clone_history_from(source_a)
    _add_start_if_needed(source_a, target)
    _set_doc(target, new_doc, validation=validation)

    target.add_history_action(action=HISTORY_ACTION_MERGE,
                              input=source_b,
                              output_type=doc.get("type"))
コード例 #2
0
ファイル: base_tests.py プロジェクト: paulharter/winnow
    def test_allows_subset(self):

        configured_option = deepcopy(BASE_PRODUCT)
        configured_option[u"options"][u"color"] = u"red"

        configured_version = WinnowVersion.add_doc(self.db, configured_option,
                                                   {})
        self.assertTrue(winnow.allows(self.base_version, configured_version))

        configured_option = deepcopy(BASE_PRODUCT)
        configured_option[u"options"][u"color"] = [u"red", u"green"]

        # the values for given keys are a subset
        configured_version = WinnowVersion.add_doc(self.db, configured_option,
                                                   {})
        self.assertTrue(winnow.allows(self.base_version, configured_version))
        self.assertFalse(winnow.allows(configured_version, self.base_version))

        self.assertFalse(
            winnow.is_allowed_by(self.base_version, configured_version))
        self.assertTrue(
            winnow.is_allowed_by(configured_version, self.base_version))

        configured_option = deepcopy(BASE_PRODUCT)
        configured_option[u"options"][u"color"] = [u"red", u"green"]
        configured_option[u"options"][u"tool"] = [u"cnc"]

        configured_version = WinnowVersion.add_doc(self.db, configured_option,
                                                   {})
        self.assertTrue(winnow.allows(self.base_version, configured_version))
コード例 #3
0
ファイル: base_tests.py プロジェクト: opendesk/winnow
    def test_allows_subset(self):

        configured_option = deepcopy(BASE_PRODUCT)
        configured_option[u"options"][u"color"] = u"red"

        configured_version = WinnowVersion.add_doc(self.db, configured_option, {})
        self.assertTrue(winnow.allows(self.base_version, configured_version))

        configured_option = deepcopy(BASE_PRODUCT)
        configured_option[u"options"][u"color"] = [u"red", u"green"]

        # the values for given keys are a subset
        configured_version = WinnowVersion.add_doc(self.db, configured_option, {})
        self.assertTrue(winnow.allows(self.base_version, configured_version))
        self.assertFalse(winnow.allows(configured_version, self.base_version))

        self.assertFalse(winnow.is_allowed_by(self.base_version, configured_version))
        self.assertTrue(winnow.is_allowed_by(configured_version, self.base_version))


        configured_option = deepcopy(BASE_PRODUCT)
        configured_option[u"options"][u"color"] = [u"red", u"green"]
        configured_option[u"options"][u"tool"] = [u"cnc"]

        configured_version = WinnowVersion.add_doc(self.db, configured_option, {})
        self.assertTrue(winnow.allows(self.base_version, configured_version))
コード例 #4
0
    def munge_values(self, this_value, other_value):
        #WTF is this really meant to do!!!!!

        from winnow.options import OptionsSet

        try:
            new_value = deepcopy(other_value)
            new_value.update(deepcopy(this_value))
        except Exception, e:
            print "this_value", this_value
            print "other_value", other_value
            raise e
コード例 #5
0
ファイル: option_values.py プロジェクト: opendesk/winnow
    def munge_values(self, this_value, other_value):
        #WTF is this really meant to do!!!!!

        from winnow.options import OptionsSet

        try:
            new_value = deepcopy(other_value)
            new_value.update(deepcopy(this_value))
        except Exception, e:
            print "this_value", this_value
            print "other_value", other_value
            raise e
コード例 #6
0
ファイル: options.py プロジェクト: paulharter/winnow
    def mega_store(self, other):

        #
        # print "****STORES****"
        # print self.store
        # print other.store
        #

        expanded = deepcopy(self.store)
        for k in self.store.keys():
            if "*" in k:
                matching = other.matcher.get_matching_paths(k)
                for match in matching:
                    expanded[match] = self.store[k]
                # this consumes matched wildcards values
                if matching:
                    del expanded[k]
        mega_store = {}

        for k, v in expanded.iteritems():
            new_key, real_value = value_path_factory(k, v)
            if real_value is not None:
                if not new_key in mega_store.keys():
                    mega_store[new_key] = []
                mega_store[new_key].append(real_value)

        return mega_store
コード例 #7
0
ファイル: numeric_values.py プロジェクト: opendesk/winnow
    def __new__(cls, value):


        if isinstance(value, list) or isinstance(value, set):
            as_list = value
            if len(as_list) > MAX_VALUE_SET_SIZE:
                raise OptionsExceptionNotAllowed("maximum value set size exceeded")
            elif len(as_list) == 0:
                return None
            elif len(as_list) == 1:
                return NumericNumberWinnowValue(list(as_list)[0])
            else:
                return NumericWinnowValue.__new__(cls)
        else:
            as_list = value[u"value"]
            if not (isinstance(as_list, list) or isinstance(as_list, set)):
                raise OptionsExceptionFailedValidation("NumericNumberSieveValue must be a Decimal")
            if len(as_list) > MAX_VALUE_SET_SIZE:
                raise OptionsExceptionNotAllowed("maximum value set size exceeded")
            elif len(as_list) == 0:
                return None
            elif len(as_list) == 1:
                v = deepcopy(value)
                v[u"value"] = list(as_list)[0]
                return NumericNumberWinnowValue(v)
            else:
                return NumericWinnowValue.__new__(cls)
コード例 #8
0
ファイル: numeric_values.py プロジェクト: paulharter/winnow
    def __new__(cls, value):

        if isinstance(value, list) or isinstance(value, set):
            as_list = value
            if len(as_list) > MAX_VALUE_SET_SIZE:
                raise OptionsExceptionNotAllowed(
                    "maximum value set size exceeded")
            elif len(as_list) == 0:
                return None
            elif len(as_list) == 1:
                return NumericNumberWinnowValue(list(as_list)[0])
            else:
                return NumericWinnowValue.__new__(cls)
        else:
            as_list = value[u"value"]
            if not (isinstance(as_list, list) or isinstance(as_list, set)):
                raise OptionsExceptionFailedValidation(
                    "NumericNumberSieveValue must be a Decimal")
            if len(as_list) > MAX_VALUE_SET_SIZE:
                raise OptionsExceptionNotAllowed(
                    "maximum value set size exceeded")
            elif len(as_list) == 0:
                return None
            elif len(as_list) == 1:
                v = deepcopy(value)
                v[u"value"] = list(as_list)[0]
                return NumericNumberWinnowValue(v)
            else:
                return NumericWinnowValue.__new__(cls)
コード例 #9
0
ファイル: base_tests.py プロジェクト: paulharter/winnow
 def test_allows_fails(self):
     configured_option = deepcopy(BASE_PRODUCT)
     configured_option[u"options"][u"color"] = u"purple"
     configured_version = WinnowVersion.add_doc(self.db, configured_option,
                                                {})
     self.assertFalse(winnow.allows(self.base_version, configured_version))
     self.assertFalse(self.base_version.allows(configured_version))
コード例 #10
0
def get_quantified_configuration(db, product_path, choices):

    doc = {
        "schema": "https://opendesk.cc/schemata/options.json",
        "type": "choice",
        "name": "paul's choices",
        "options": choices
    }

    choice_document = WinnowVersion.add_doc(db, doc)

    product = WinnowProduct.get_from_path(db, product_path)

    qc_doc = deepcopy(product.get_doc())
    product_doc = product.get_doc()

    version = product_doc["version"]

    qc_doc[u"type"] = "quantified_configuration"
    qc_doc[u"schema"] = "https://opendesk.cc/schemata/options.json"
    qc_doc[u"product"] = "%s@%s.%s.%s" % (product_doc["path"], version[0],
                                          version[1], version[2])

    return WinnowQuantifiedConfiguration.merged(db, qc_doc, {}, product,
                                                choice_document)
コード例 #11
0
ファイル: base_tests.py プロジェクト: paulharter/winnow
    def test_allows_subset_without_a_key(self):

        configured_option = deepcopy(BASE_PRODUCT)
        del configured_option[u"options"][u"color"]
        configured_version = WinnowVersion.add_doc(self.db, configured_option,
                                                   {})
        self.assertTrue(winnow.allows(configured_version, self.base_version))
コード例 #12
0
ファイル: options.py プロジェクト: opendesk/winnow
    def mega_store(self, other):

        #
        # print "****STORES****"
        # print self.store
        # print other.store
        #

        expanded = deepcopy(self.store)
        for k in self.store.keys():
            if "*" in k:
                matching = other.matcher.get_matching_paths(k)
                for match in matching:
                    expanded[match] = self.store[k]
                # this consumes matched wildcards values
                if matching:
                    del expanded[k]
        mega_store = {}

        for k, v in expanded.iteritems():
            new_key, real_value = value_path_factory(k, v)
            if real_value is not None:
                if not new_key in mega_store.keys():
                    mega_store[new_key] = []
                mega_store[new_key].append(real_value)

        return mega_store
コード例 #13
0
ファイル: inline.py プロジェクト: opendesk/winnow
def get_inlined_options(source):

    ref_doc = source.get_doc()
    # expand all the refs
    ref_hashes = {}
    inlined = deepcopy(ref_doc["options"])
    inline_refs(inlined, ref_doc, source, ref_hashes)
    return inlined
コード例 #14
0
ファイル: operations.py プロジェクト: opendesk/winnow
def expand(source, target, validation=True):
    new_doc = deepcopy(source.get_doc())
    target.clone_history_from(source)
    ## inline references
    ref_hashes = {}
    inline.inline_refs(new_doc, new_doc, source, ref_hashes)
    _set_doc(target, new_doc, validation=validation)
    return ref_hashes
コード例 #15
0
ファイル: inline.py プロジェクト: paulharter/winnow
def get_inlined_options(source):

    ref_doc = source.get_doc()
    # expand all the refs
    ref_hashes = {}
    inlined = deepcopy(ref_doc["options"])
    inline_refs(inlined, ref_doc, source, ref_hashes)
    return inlined
コード例 #16
0
def expand(source, target, validation=True):
    new_doc = deepcopy(source.get_doc())
    target.clone_history_from(source)
    ## inline references
    ref_hashes = {}
    inline.inline_refs(new_doc, new_doc, source, ref_hashes)
    _set_doc(target, new_doc, validation=validation)
    return ref_hashes
コード例 #17
0
ファイル: base_tests.py プロジェクト: opendesk/winnow
    def test_allows_subset_with_an_extra_key(self):

        configured_option = deepcopy(BASE_PRODUCT)
        configured_option[u"options"][u"wheels"] = [u"big", u"small"]
        configured_version = WinnowVersion.add_doc(self.db, configured_option, {})


        self.assertTrue(winnow.allows(self.base_version, configured_version))
        self.assertTrue(self.base_version.allows(configured_version))
コード例 #18
0
ファイル: base_tests.py プロジェクト: paulharter/winnow
    def test_allows_subset_with_an_extra_key(self):

        configured_option = deepcopy(BASE_PRODUCT)
        configured_option[u"options"][u"wheels"] = [u"big", u"small"]
        configured_version = WinnowVersion.add_doc(self.db, configured_option,
                                                   {})

        self.assertTrue(winnow.allows(self.base_version, configured_version))
        self.assertTrue(self.base_version.allows(configured_version))
コード例 #19
0
ファイル: inline.py プロジェクト: opendesk/winnow
def _extract_internal_path(doc, path):
    walker = doc
    parts = [p for p in path.split("/") if p]
    for part in parts:
        if not isinstance(walker, dict):
            raise OptionsExceptionReferenceError("internal_path reference couldn't find %s in %s" % (path, doc))
        walker = walker.get(part)
        if walker is None:
            raise OptionsExceptionReferenceError("internal_path reference couldn't find %s in %s" % (path, doc))
    return deepcopy(walker)
コード例 #20
0
ファイル: inline.py プロジェクト: paulharter/winnow
def _find_expanded_ref(reference,
                       doc,
                       source,
                       options,
                       ref_hashes,
                       default_scopes=None):

    # looks up the contents of a reference

    if u"~" in reference:
        ref, internal_path = reference.split(u"~")
    elif u"#" in reference:
        ref, internal_path = reference.split(u"#")
    else:
        ref = reference
        internal_path = None
    if ref == "":
        referenced_doc = doc
    else:
        wv = source.lookup(ref)
        if wv is None:
            raise OptionsExceptionReferenceError(
                "Winnow Reference Error: Failed to find resource %s" % ref)
        existing_doc = wv.get_doc()
        referenced_doc = deepcopy(existing_doc)
    if referenced_doc is None:
        raise OptionsExceptionReferenceError(
            "Winnow Reference Error: Cannot find reference %s as ref doc is None"
            % ref)
    else:
        if options is not None:
            # if the ref also has some options then pre merge them into the reference
            referenced_options = referenced_doc.get(u"options")
            if referenced_options is None:
                referenced_doc[u"options"] = options
            else:
                options_a = OptionsSet(referenced_options)
                options_b = OptionsSet(options)
                referenced_doc[u"options"] = _merge_option_dicts(
                    source, options_a.store, options_b.store, referenced_doc,
                    doc)

            ## TODO look again at the the default scopes thing
            # if default_scopes is not None:
            #     for k, v in referenced_doc[u"options"].iteritems():
            #         print v
            #         if v.get("scopes") is None:
            #             v["scopes"] = default_scopes

        new_doc = _extract_internal_path(
            referenced_doc, internal_path) if internal_path else referenced_doc
        # TODO revisit this use of doc as the reference doc to use
        new_doc = inline_refs(new_doc, doc, source, ref_hashes)
        return new_doc
コード例 #21
0
ファイル: inline.py プロジェクト: paulharter/winnow
def _extract_internal_path(doc, path):
    walker = doc
    parts = [p for p in path.split("/") if p]
    for part in parts:
        if not isinstance(walker, dict):
            raise OptionsExceptionReferenceError(
                "internal_path reference couldn't find %s in %s" % (path, doc))
        walker = walker.get(part)
        if walker is None:
            raise OptionsExceptionReferenceError(
                "internal_path reference couldn't find %s in %s" % (path, doc))
    return deepcopy(walker)
コード例 #22
0
def merge(source_a, source_b, target, doc, validation=True):

    doc_a = source_a.get_doc()
    doc_b = source_b.get_doc()

    # get the options from bothe sources
    options_a = deepcopy(source_a.get_options_dict())
    options_b = deepcopy(source_b.get_options_dict())

    errors = []

    # carry any errors through
    errors_a = doc_a.get("errors")
    if errors_a:
        errors += errors_a

    errors_b = doc_b.get("errors")
    if errors_b:
        errors += errors_b

    merged_options = inline._merge_option_dicts(source_a,
                                                options_a,
                                                options_b,
                                                doc_a,
                                                doc_b,
                                                errors=errors)

    # put this merged options into a copy of the doc
    new_doc = deepcopy(doc)
    new_doc[OPTIONS_KEY] = merged_options
    if errors:
        new_doc["errors"] = errors

    target.clone_history_from(source_a)
    _add_start_if_needed(source_a, target)
    _set_doc(target, new_doc, validation=validation)

    target.add_history_action(action=HISTORY_ACTION_MERGE,
                              input=source_b,
                              output_type=doc.get("type"))
コード例 #23
0
ファイル: munge.py プロジェクト: paulharter/winnow
def find_key_named(node, key_name, collecting_node=None):

    if isinstance(node, dict):
        if key_name in node.keys():
            if collecting_node is not None:
                collecting_node[key_name] = deepcopy(node[key_name])
        for key in node.keys():
            child = node[key]
            find_key_named(child, key_name, collecting_node)

    if isinstance(node, list):
        for i, child in enumerate(node[:]):
            find_key_named(child, key_name, collecting_node)
コード例 #24
0
ファイル: munge.py プロジェクト: opendesk/winnow
def find_key_named(node, key_name, collecting_node=None):

    if isinstance(node, dict):
        if key_name in node.keys():
            if collecting_node is not None:
                collecting_node[key_name] = deepcopy(node[key_name])
        for key in node.keys():
            child = node[key]
            find_key_named(child, key_name, collecting_node)


    if isinstance(node, list):
        for i, child in enumerate(node[:]):
            find_key_named(child, key_name, collecting_node)
コード例 #25
0
ファイル: unexpand_tests.py プロジェクト: paulharter/winnow
    def test_unexpand(self):

        breed1 = WinnowVersion.get_from_path(self.db, "/breeds/collie")

        ref_hashes = {}
        expanded_doc = deepcopy(breed1.get_doc())

        winnow.inline.inline_refs(expanded_doc, expanded_doc, breed1, ref_hashes)

        ref_value = u"$ref:/choices/dog_choices#/options/colours"
        colour_options = self.dog_base_choices["options"]["colours"]
        hash = winnow.utils.get_doc_hash(winnow.utils.json_dumps(colour_options))
        self.assertEqual(ref_hashes.get(hash), ref_value)
        self.assertEqual(expanded_doc["options"]["colours"], ["brown", "red", "white"])
        winnow.inline.restore_unchanged_refs(expanded_doc, ref_hashes)
        self.assertEqual(expanded_doc["options"]["colours"], ref_value)
コード例 #26
0
ファイル: inline.py プロジェクト: opendesk/winnow
def _find_expanded_ref(reference, doc, source, options, ref_hashes, default_scopes=None):


    # looks up the contents of a reference


    if u"~" in reference:
        ref, internal_path = reference.split(u"~")
    elif u"#" in reference:
        ref, internal_path = reference.split(u"#")
    else:
        ref = reference
        internal_path = None
    if ref == "":
        referenced_doc = doc
    else:
        wv = source.lookup(ref)
        if wv is None:
            raise OptionsExceptionReferenceError("Winnow Reference Error: Failed to find resource %s" % ref)
        existing_doc = wv.get_doc()
        referenced_doc = deepcopy(existing_doc)
    if referenced_doc is None:
        raise OptionsExceptionReferenceError("Winnow Reference Error: Cannot find reference %s as ref doc is None" % ref)
    else:
        if options is not None:
            # if the ref also has some options then pre merge them into the reference
            referenced_options = referenced_doc.get(u"options")
            if referenced_options is None:
                referenced_doc[u"options"] = options
            else:
                options_a = OptionsSet(referenced_options)
                options_b = OptionsSet(options)
                referenced_doc[u"options"] = _merge_option_dicts(source, options_a.store, options_b.store, referenced_doc, doc)

            ## TODO look again at the the default scopes thing
            # if default_scopes is not None:
            #     for k, v in referenced_doc[u"options"].iteritems():
            #         print v
            #         if v.get("scopes") is None:
            #             v["scopes"] = default_scopes

        new_doc = _extract_internal_path(referenced_doc, internal_path) if internal_path else referenced_doc
        # TODO revisit this use of doc as the reference doc to use
        new_doc = inline_refs(new_doc, doc, source, ref_hashes)
        return new_doc
コード例 #27
0
def default_choices(source, scopes):

    #take a copy of the options
    doc = source.get_doc()
    options_dict = deepcopy(source.get_options_dict())

    #expand it
    ref_hashes = {}
    inline.inline_refs(options_dict, doc, source, ref_hashes)

    #scope it
    _trim_out_off_scope(options_dict, set(scopes))

    # wrap it in an options set
    options_set = OptionsSet(options_dict)

    #get default options set
    default = options_set.default()

    return default.store
コード例 #28
0
ファイル: operations.py プロジェクト: opendesk/winnow
def default_choices(source, scopes):

    #take a copy of the options
    doc = source.get_doc()
    options_dict = deepcopy(source.get_options_dict())

    #expand it
    ref_hashes = {}
    inline.inline_refs(options_dict, doc, source, ref_hashes)

    #scope it
    _trim_out_off_scope(options_dict, set(scopes))

    # wrap it in an options set
    options_set = OptionsSet(options_dict)

    #get default options set
    default = options_set.default()

    return default.store
コード例 #29
0
ファイル: operations.py プロジェクト: opendesk/winnow
def quantify(source, target, doc, validation=True):

    default_quantity = {
        u"type": u"numeric::range",
        u"name": u"Quantity",
        u"default": Decimal("1"),
        u"max": Decimal("100"),
        u"min": Decimal("1"),
    }

    options_dict = source.get_options_dict()
    options_dict.setdefault(u'quantity', default_quantity)

    new_doc = deepcopy(doc)
    new_doc[OPTIONS_KEY] = options_dict

    target.clone_history_from(source)

    _add_start_if_needed(source, target)
    _set_doc(target, new_doc, validation=validation)

    target.add_history_action(action=HISTORY_ACTION_QUANTIFY,
                              output_type=doc.get("type"))
コード例 #30
0
ファイル: flow.py プロジェクト: opendesk/winnow
def get_quantified_configuration(db, product_path, choices):

    doc = {
        "schema": "https://opendesk.cc/schemata/options.json",
        "type": "choice",
        "name": "paul's choices",
        "options":choices
    }

    choice_document = WinnowVersion.add_doc(db, doc)

    product = WinnowProduct.get_from_path(db, product_path)

    qc_doc = deepcopy(product.get_doc())
    product_doc = product.get_doc()

    version = product_doc["version"]

    qc_doc[u"type"] = "quantified_configuration"
    qc_doc[u"schema"] = "https://opendesk.cc/schemata/options.json"
    qc_doc[u"product"] = "%s@%s.%s.%s" % (product_doc["path"], version[0], version[1], version[2])

    return WinnowQuantifiedConfiguration.merged(db, qc_doc, {}, product, choice_document)
コード例 #31
0
def quantify(source, target, doc, validation=True):

    default_quantity = {
        u"type": u"numeric::range",
        u"name": u"Quantity",
        u"default": Decimal("1"),
        u"max": Decimal("100"),
        u"min": Decimal("1"),
    }

    options_dict = source.get_options_dict()
    options_dict.setdefault(u'quantity', default_quantity)

    new_doc = deepcopy(doc)
    new_doc[OPTIONS_KEY] = options_dict

    target.clone_history_from(source)

    _add_start_if_needed(source, target)
    _set_doc(target, new_doc, validation=validation)

    target.add_history_action(action=HISTORY_ACTION_QUANTIFY,
                              output_type=doc.get("type"))
コード例 #32
0
ファイル: base_tests.py プロジェクト: opendesk/winnow
 def test_allows_fails(self):
     configured_option = deepcopy(BASE_PRODUCT)
     configured_option[u"options"][u"color"] = u"purple"
     configured_version = WinnowVersion.add_doc(self.db, configured_option, {})
     self.assertFalse(winnow.allows(self.base_version, configured_version))
     self.assertFalse(self.base_version.allows(configured_version))
コード例 #33
0
def scope(source, scopes, target, doc):
    new_doc = deepcopy(doc)
    _trim_out_off_scope(new_doc[OPTIONS_KEY], set(scopes))
    target.clone_history_from(source)
    _add_start_if_needed(source, target)
    _set_doc(target, new_doc)
コード例 #34
0
ファイル: operations.py プロジェクト: opendesk/winnow
def scope(source, scopes, target, doc):
    new_doc = deepcopy(doc)
    _trim_out_off_scope(new_doc[OPTIONS_KEY], set(scopes))
    target.clone_history_from(source)
    _add_start_if_needed(source, target)
    _set_doc(target, new_doc)
コード例 #35
0
    def intersection(self, other):
        #
        #
        # print "++++++++++++++++++++++++++++++++++++++  me  +++++++++++++++++++++++++++++++++++++++++++"
        # print self.values_lookup.keys()
        #

        from winnow.options import OptionsSet

        self.check_class(other)

        values = []

        default = None

        if type(other) == OptionResourceWinnowValue:
            msg = "You cannot merge a string with a resource: self: %s\n other: %s" % (
                self, other)
            raise OptionsExceptionIncompatibleTypes(msg)

        elif isinstance(other, OptionNullWinnowValue):

            other_options = other._get_options()
            if other_options is None:
                return self

            self_keys = list(self.values_lookup.keys())

            for value_id in self_keys:
                this_value = self.values_lookup.get(value_id)
                if isinstance(this_value, dict):
                    new_value = deepcopy(this_value)
                    this_options = self.get_value_options(value_id)
                elif isinstance(this_value, unicode):
                    new_value = {"type": u"string", "value": this_value}
                    this_options = None
                else:
                    raise Exception("This shouldn't ever happen")

                if this_options is not None:
                    try:
                        new_value[u"options"] = OptionsSet(this_options).merge(
                            OptionsSet(other_options)).store
                    except OptionsExceptionSetWithException as e:
                        new_value = None

                default = self._default
                if new_value is not None:
                    values.append(new_value)

        else:
            other_keys = list(other.values_lookup.keys())
            # self_keys = list(self.values_lookup.keys())
            other_keys.sort()

            this_default_allowed = False
            that_default_allowed = False

            # find matching values

            # get the one to use

            # add them to the list

            ## when putting together the intersecting values perform a merge on their nested options
            for value_id in other_keys:

                this_value = self.values_lookup.get(value_id)
                if this_value is None:
                    continue
                other_value = other.values_lookup[value_id]

                if self._default == value_id:
                    this_default_allowed = True

                if other._default == value_id:
                    that_default_allowed = True

                ## if they are both unicode just add the value
                if isinstance(other_value, unicode) and isinstance(
                        this_value, unicode):
                    values.append(this_value)
                elif isinstance(other_value, unicode) and isinstance(
                        this_value, dict):
                    values.append(deepcopy(this_value))
                elif isinstance(other_value, dict) and isinstance(
                        this_value, unicode):
                    values.append(deepcopy(other_value))
                elif isinstance(other_value, dict) and isinstance(
                        this_value, dict):
                    new_value = self.munge_values(this_value, other_value)
                    values.append(new_value)
                else:
                    raise Exception("this should never happen")

                if this_default_allowed and that_default_allowed:
                    default = self._default
                elif this_default_allowed:
                    default = self._default
                elif that_default_allowed:
                    default = other._default
                else:
                    default = None

        ## if there is no intersection return None
        if len(values) == 0:
            return None

        info = self.get_merged_info(other)
        info[u"type"] = self.type,
        info[VALUES_KEY_NAME] = values
        if default is not None:
            info[u"default"] = default

        return self.__class__(info)
コード例 #36
0
def add_doc(target, doc, validation=True):
    _set_doc(target, deepcopy(doc), validation=validation)
コード例 #37
0
    def intersection(self, other):

        # print " "
        # print "****************  resource intersection ******************"
        # print "self keys", self.values_lookup.keys()

        from winnow.options import OptionsSet

        self.check_class(other)

        values = []

        if type(other) == OptionNullWinnowValue:

            # print "a null resource"

            other_options = other._get_options()
            if other_options is None:
                return self

            self_keys = list(self.values_lookup.keys())

            for value_id in self_keys:
                this_value = self.values_lookup.get(value_id)
                if isinstance(this_value, dict):
                    new_value = deepcopy(this_value)
                    this_options = self.get_value_options(value_id)
                else:
                    raise Exception("This shouldn't ever happen")

                # if this_options is not None:
                #
                #     new_value[u"options"] = OptionsSet(this_options).merge(OptionsSet(other_options)).store
                #
                # values.append(new_value)
                #
                #
                #
                #

                if this_options is not None:
                    try:
                        new_value[u"options"] = OptionsSet(this_options).merge(
                            OptionsSet(other_options)).store
                    except OptionsExceptionSetWithException as e:
                        new_value = None

                if new_value is not None:
                    values.append(new_value)

        elif type(other) == OptionStringWinnowValue:
            raise OptionsExceptionIncompatibleTypes(
                "You cannot merge and resource with a string: %s" % other)

        else:

            # take a cope of the the possible values in a lookup table keyed by path
            all_values = deepcopy(self.values_lookup)

            all_values.update(deepcopy(other.values_lookup))

            # prune and child nodes from each set

            other_paths = list(other.values_lookup.keys())
            self_paths = list(self.values_lookup.keys())

            other_paths_pruned = self._prune_child_nodes(other_paths)
            self_paths_pruned = self._prune_child_nodes(self_paths)

            # then add values if it or parent is in other
            intersecting_paths = self._intersection_of_path_sets(
                other_paths_pruned, self_paths_pruned)

            # for each intersecting path find the most specific option set on each side and merge them
            values = []

            for path in intersecting_paths:
                # find best fit values to get merged options
                this_value = self.values_lookup[self._nearest_match(
                    path, self_paths)]
                other_value = other.values_lookup[self._nearest_match(
                    path, other_paths)]

                merged_value = self.munge_values(this_value, other_value)

                # and then add these options to a copy of the origional value from all_values
                new_value = all_values[path]
                if "options" in merged_value:
                    new_value["options"] = merged_value["options"]

                values.append(new_value)

        ## if there is no intersection return None
        if len(values) == 0:
            return None

        info = self.get_merged_info(other)
        info[u"type"] = self.type,
        info[VALUES_KEY_NAME] = values

        return self.__class__(info)
コード例 #38
0
ファイル: option_values.py プロジェクト: opendesk/winnow
    def intersection(self, other):

        # print " "
        # print "****************  resource intersection ******************"
        # print "self keys", self.values_lookup.keys()

        from winnow.options import OptionsSet

        self.check_class(other)

        values = []

        if type(other) == OptionNullWinnowValue:

            # print "a null resource"

            other_options = other._get_options()
            if other_options is None:
                return self

            self_keys = list(self.values_lookup.keys())

            for value_id in self_keys:
                this_value = self.values_lookup.get(value_id)
                if isinstance(this_value, dict):
                    new_value = deepcopy(this_value)
                    this_options = self.get_value_options(value_id)
                else:
                    raise Exception("This shouldn't ever happen")

                # if this_options is not None:
                #
                #     new_value[u"options"] = OptionsSet(this_options).merge(OptionsSet(other_options)).store
                #
                # values.append(new_value)
                #
                #
                #
                #

                if this_options is not None:
                    try:
                        new_value[u"options"] = OptionsSet(this_options).merge(OptionsSet(other_options)).store
                    except OptionsExceptionSetWithException as e:
                        new_value = None


                if new_value is not None:
                    values.append(new_value)

        elif type(other) == OptionStringWinnowValue:
            raise OptionsExceptionIncompatibleTypes("You cannot merge and resource with a string: %s" % other)

        else:

            # take a cope of the the possible values in a lookup table keyed by path
            all_values = deepcopy(self.values_lookup)

            all_values.update(deepcopy(other.values_lookup))

            # prune and child nodes from each set

            other_paths = list(other.values_lookup.keys())
            self_paths = list(self.values_lookup.keys())

            other_paths_pruned = self._prune_child_nodes(other_paths)
            self_paths_pruned = self._prune_child_nodes(self_paths)

            # then add values if it or parent is in other
            intersecting_paths = self._intersection_of_path_sets(other_paths_pruned, self_paths_pruned)

            # for each intersecting path find the most specific option set on each side and merge them
            values = []

            for path in intersecting_paths:
                # find best fit values to get merged options
                this_value = self.values_lookup[self._nearest_match(path, self_paths)]
                other_value = other.values_lookup[self._nearest_match(path, other_paths)]

                merged_value = self.munge_values(this_value, other_value)

                # and then add these options to a copy of the origional value from all_values
                new_value = all_values[path]
                if "options" in merged_value:
                    new_value["options"] = merged_value["options"]

                values.append(new_value)

        ## if there is no intersection return None
        if len(values) == 0:
            return None

        info = self.get_merged_info(other)
        info[u"type"] = self.type,
        info[VALUES_KEY_NAME] = values

        return self.__class__(info)
コード例 #39
0
ファイル: option_values.py プロジェクト: opendesk/winnow
    def intersection(self, other):
        #
        #
        # print "++++++++++++++++++++++++++++++++++++++  me  +++++++++++++++++++++++++++++++++++++++++++"
        # print self.values_lookup.keys()
        #


        from winnow.options import OptionsSet

        self.check_class(other)

        values = []

        default = None

        if type(other) == OptionResourceWinnowValue:
            msg = "You cannot merge a string with a resource: self: %s\n other: %s" % (self, other)
            raise OptionsExceptionIncompatibleTypes(msg)

        elif isinstance(other, OptionNullWinnowValue):

            other_options = other._get_options()
            if other_options is None:
                return self

            self_keys = list(self.values_lookup.keys())

            for value_id in self_keys:
                this_value = self.values_lookup.get(value_id)
                if isinstance(this_value, dict):
                    new_value = deepcopy(this_value)
                    this_options = self.get_value_options(value_id)
                elif isinstance(this_value, unicode):
                    new_value = {
                        "type": u"string",
                        "value": this_value
                    }
                    this_options = None
                else:
                    raise Exception("This shouldn't ever happen")

                if this_options is not None:
                    try:
                        new_value[u"options"] = OptionsSet(this_options).merge(OptionsSet(other_options)).store
                    except OptionsExceptionSetWithException as e:
                        new_value = None

                default = self._default
                if new_value is not None:
                    values.append(new_value)

        else:
            other_keys = list(other.values_lookup.keys())
            # self_keys = list(self.values_lookup.keys())
            other_keys.sort()

            this_default_allowed = False
            that_default_allowed = False

            # find matching values

            # get the one to use

            # add them to the list

            ## when putting together the intersecting values perform a merge on their nested options
            for value_id in other_keys:

                this_value = self.values_lookup.get(value_id)
                if this_value is None:
                    continue
                other_value = other.values_lookup[value_id]

                if self._default == value_id:
                    this_default_allowed = True

                if other._default == value_id:
                    that_default_allowed = True

                ## if they are both unicode just add the value
                if isinstance(other_value, unicode) and isinstance(this_value, unicode):
                    values.append(this_value)
                elif isinstance(other_value, unicode) and isinstance(this_value, dict):
                    values.append(deepcopy(this_value))
                elif isinstance(other_value, dict) and isinstance(this_value, unicode):
                    values.append(deepcopy(other_value))
                elif isinstance(other_value, dict) and isinstance(this_value, dict):
                    new_value = self.munge_values(this_value, other_value)
                    values.append(new_value)
                else:
                    raise Exception("this should never happen")


                if this_default_allowed and that_default_allowed:
                    default = self._default
                elif this_default_allowed:
                    default = self._default
                elif that_default_allowed:
                    default = other._default
                else:
                    default = None

        ## if there is no intersection return None
        if len(values) == 0:
            return None

        info = self.get_merged_info(other)
        info[u"type"] = self.type,
        info[VALUES_KEY_NAME] = values
        if default is not None:
            info[u"default"] = default


        return self.__class__(info)
コード例 #40
0
ファイル: base_tests.py プロジェクト: opendesk/winnow
    def test_allows_subset_without_a_key(self):

        configured_option = deepcopy(BASE_PRODUCT)
        del configured_option[u"options"][u"color"]
        configured_version = WinnowVersion.add_doc(self.db, configured_option, {})
        self.assertTrue(winnow.allows(configured_version, self.base_version))
コード例 #41
0
ファイル: operations.py プロジェクト: opendesk/winnow
def add_doc(target, doc, validation=True):
    _set_doc(target,  deepcopy(doc), validation=validation)
コード例 #42
0
ファイル: base.py プロジェクト: paulharter/winnow
 def __init__(self, db=None, kwargs={}):
     self.kwargs = deepcopy(kwargs)
     self.db = db if db else self.cls_db
     if self.kwargs.get("uuid") is None:
         self.kwargs["uuid"] = unicode(uuid.uuid4())
コード例 #43
0
ファイル: base.py プロジェクト: paulharter/winnow
 def clone_history_from(self, options_interface):
     history = options_interface.kwargs.get(u"history")
     if history is not None:
         self.kwargs[u"history"] = deepcopy(history)
コード例 #44
0
ファイル: base.py プロジェクト: opendesk/winnow
 def __init__(self, db=None, kwargs={}):
     self.kwargs = deepcopy(kwargs)
     self.db = db if db else self.cls_db
     if self.kwargs.get("uuid") is None:
         self.kwargs["uuid"] = unicode(uuid.uuid4())
コード例 #45
0
ファイル: base.py プロジェクト: opendesk/winnow
 def clone_history_from(self, options_interface):
     history = options_interface.kwargs.get(u"history")
     if history is not None:
         self.kwargs[u"history"] = deepcopy(history)