diff --git a/src/App/MetadataPy.xml b/src/App/MetadataPy.xml index 3b9f84417b..f1e41ad11a 100644 --- a/src/App/MetadataPy.xml +++ b/src/App/MetadataPy.xml @@ -1,162 +1,195 @@ - + - - - - Metadata - A Metadata object reads an XML-formatted package metadata file and provides read-only access to its contents. + + + + Metadata + A Metadata object reads an XML-formatted package metadata file and provides read-only access to its contents. - A single constructor is supported: - Metadata(file) -- Reads the XML file and provides access to the metadata it specifies. - - Metadata - + A single constructor is supported: + Metadata(file) -- Reads the XML file and provides access to the metadata it specifies. + + Metadata + - - - String: the name of this item - - - - - - String: the version of this item in semantic triplet format - - - - - - String: the description of this item (text only, no markup allowed) - - - - - - List of maintainer objects with 'name' and 'email' string attributes - - - - - - List of applicable licenses as objects with 'name' and 'file' string attributes - - - - - - - List of URLs as objects with 'location' and 'urltype' string attributes, where urltype is one of: - * website - * repository - * bugtracker - * readme - * documentation - - - - - - - List of author objects, each with a 'name' and a (potentially empty) 'email' string attribute - - - - - - - List of dependencies, as objects with the following attributes: - * package -- Required: must exactly match the contents of the 'name' element in the referenced package's package.xml file - * version_lt -- Optional: The dependency to the package is restricted to versions less than the stated version number - * version_lte -- Optional: The dependency to the package is restricted to versions less or equal than the stated version number - * version_eq -- Optional: The dependency to the package is restricted to a version equal than the stated version number - * version_gte -- Optional: The dependency to the package is restricted to versions greater or equal than the stated version number - * version_gt -- Optional: The dependency to the package is restricted to versions greater than the stated version number - * condition -- Optional: Conditional expression as documented in REP149 - - - - - - - List of conflicts, format identical to dependencies - - - - - - List of things this item is considered by its author to replace: format identical to dependencies - - - - - - List of strings - - - - - - Relative path to an icon file - - - - - - String: the name of the main Python class this item creates/represents - - - - - - String: the name of the subdirectory this content item is located in. If empty, the item is in a directory named the same as the content item. - - - - - - A list of files associated with this item -- the meaning of each file is implementation-defined - - - - - - A dictionary of lists of content items: defined recursively, each item is itself a Metadata object -- see package.xml file format documentation for details - - - + + + String: the name of this item + + + + + + String: the version of this item in semantic triplet format + + + + + + String: the description of this item (text only, no markup allowed) + + + + + + List of maintainer objects with 'name' and 'email' string attributes + + + + + + List of applicable licenses as objects with 'name' and 'file' string attributes + + + + + + + List of URLs as objects with 'location' and 'urltype' string attributes, where urltype is one of: + * website + * repository + * bugtracker + * readme + * documentation + + + + + + + List of author objects, each with a 'name' and a (potentially empty) 'email' string attribute + + + + + + + List of dependencies, as objects with the following attributes: + * package -- Required: must exactly match the contents of the 'name' element in the referenced package's package.xml file + * version_lt -- Optional: The dependency to the package is restricted to versions less than the stated version number + * version_lte -- Optional: The dependency to the package is restricted to versions less or equal than the stated version number + * version_eq -- Optional: The dependency to the package is restricted to a version equal than the stated version number + * version_gte -- Optional: The dependency to the package is restricted to versions greater or equal than the stated version number + * version_gt -- Optional: The dependency to the package is restricted to versions greater than the stated version number + * condition -- Optional: Conditional expression as documented in REP149 + + + + + + + List of conflicts, format identical to dependencies + + + + + + List of things this item is considered by its author to replace: format identical to dependencies + + + + + + List of strings + + + + + + Relative path to an icon file + + + + + + String: the name of the main Python class this item creates/represents + + + + + + String: the name of the subdirectory this content item is located in. If empty, the item is in a directory named the same as the content item. + + + + + + A list of files associated with this item -- the meaning of each file is implementation-defined + + + + + + A dictionary of lists of content items: defined recursively, each item is itself a Metadata object -- see package.xml file format documentation for details + + + + + + A string representing the minimum version of FreeCAD needed for this item. If unset it will be 0.0.0. + + + - - - - getGenericMetadata(name) - Get the list of GenericMetadata objects with key 'name'. Generic metadata objects are Python objects with - a string 'contents' and a dictionary of strings, 'attributes'. They represent unrecognized simple XML tags - in the metadata file. - - - + + + A string representing the maximum version of FreeCAD needed for this item. If unset it will be 0.0.0. + + + - - public: - MetadataPy(const Metadata & pla, PyTypeObject *T = &Type) - :PyObjectBase(new Metadata(pla),T){} - Metadata value() const - { return *(getMetadataPtr()); } - - + + + getLastSupportedFreeCADVersion() +Search through all content package items, and determine if a maximum supported version of FreeCAD +is set. Returns None if no maximum version is set, or if *any* content item fails to provide a +maximum version (implying that that content item will work with all known versions). + + + + + + + getFirstSupportedFreeCADVersion() +Search through all content package items, and determine if a minimum supported version of FreeCAD +is set. Returns 0.0 if no minimum version is set, or if *any* content item fails to provide a +minimum version (implying that that content item will work with all known versions -- technically +limited to 0.20 as the lowest known version since the metadata standard was added then). + + + + + + + getGenericMetadata(name) +Get the list of GenericMetadata objects with key 'name'. Generic metadata objects are Python objects with +a string 'contents' and a dictionary of strings, 'attributes'. They represent unrecognized simple XML tags +in the metadata file. + + + + + + public: + MetadataPy(const Metadata & pla, PyTypeObject *T = &Type) + :PyObjectBase(new Metadata(pla),T){} + Metadata value() const + { return *(getMetadataPtr()); } + + diff --git a/src/App/MetadataPyImp.cpp b/src/App/MetadataPyImp.cpp index 43e7ebd982..ec92416411 100644 --- a/src/App/MetadataPyImp.cpp +++ b/src/App/MetadataPyImp.cpp @@ -274,7 +274,7 @@ PyObject* MetadataPy::getGenericMetadata(PyObject* args) { const char* name; if (!PyArg_ParseTuple(args, "s!", &name)) - return NULL; + return nullptr; auto gm = (*getMetadataPtr())[name]; auto pyGenericMetadata = new Py::List; for (const auto& item : gm) { @@ -290,6 +290,77 @@ PyObject* MetadataPy::getGenericMetadata(PyObject* args) return pyGenericMetadata->ptr(); } +Py::Object MetadataPy::getFreeCADMin() const +{ + return Py::String(getMetadataPtr()->freecadmin().str()); +} + +void MetadataPy::setFreeCADMin(Py::Object args) +{ + char* version = nullptr; + PyObject* p = args.ptr(); + if (!PyArg_ParseTuple(p, "s", &version)) + return; + getMetadataPtr()->setFreeCADMin(App::Meta::Version(version)); +} + +Py::Object MetadataPy::getFreeCADMax() const +{ + return Py::String(getMetadataPtr()->freecadmax().str()); +} + +void MetadataPy::setFreeCADMax(Py::Object args) +{ + char* version = nullptr; + PyObject* p = args.ptr(); + if (!PyArg_ParseTuple(p, "s", &version)) + return; + getMetadataPtr()->setFreeCADMax(App::Meta::Version(version)); +} + +PyObject* MetadataPy::getFirstSupportedFreeCADVersion(PyObject* args) +{ + // Short-circuit: if the toplevel sets a version, then the lower-levels are overridden + if (getMetadataPtr()->freecadmin() != App::Meta::Version()) + return Py::new_reference_to(Py::String(getMetadataPtr()->freecadmin().str())); + + auto content = getMetadataPtr()->content(); + auto result = App::Meta::Version(); + for (const auto& item : content) { + auto minVersion = item.second.freecadmin(); + if (minVersion != App::Meta::Version()) + if (result == App::Meta::Version() || minVersion < result) + result = minVersion; + } + if (result != App::Meta::Version()) + return Py::new_reference_to(Py::String(result.str())); + else + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* MetadataPy::getLastSupportedFreeCADVersion(PyObject* args) +{ + // Short-circuit: if the toplevel sets a version, then the lower-levels are overridden + if (getMetadataPtr()->freecadmax() != App::Meta::Version()) + return Py::new_reference_to(Py::String(getMetadataPtr()->freecadmax().str())); + + auto content = getMetadataPtr()->content(); + auto result = App::Meta::Version(); + for (const auto& item : content) { + auto maxVersion = item.second.freecadmax(); + if (maxVersion != App::Meta::Version()) + if (result == App::Meta::Version() || maxVersion > result) + result = maxVersion; + } + if (result != App::Meta::Version()) + return Py::new_reference_to(Py::String(result.str())); + else + Py_INCREF(Py_None); + return Py_None; + +} + PyObject* MetadataPy::getCustomAttributes(const char* /*attr*/) const { return 0;