[Patchew-devel] [PATCH 7/7] mods: refactor extraction of properties into a dictionary

Paolo Bonzini pbonzini at redhat.com
Wed Apr 17 10:09:48 UTC 2019


Both the email and testing modules have code to extract the
configuration from project properties into a dictionary.
Generalize that code, using the project_property_schema to
drive the conversion.

This will be useful in order to support YAML-based configuration
and also to de-JSONify project properties.
---
 mod.py          | 34 ++++++++++++++++++++++++++++++++++
 mods/email.py   | 14 +-------------
 mods/testing.py | 13 +------------
 3 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/mod.py b/mod.py
index 696dda1..3481a73 100644
--- a/mod.py
+++ b/mod.py
@@ -152,6 +152,40 @@ class PatchewModule(object):
         tmpl += self._render_template(request, project, TMPL_END)
         return tmpl
 
+    def _get_map_scm(self, project, prop_name, scm):
+        prefix = prop_name + "."
+        result = {}
+        for p, v in project.get_properties().items():
+            if not p.startswith(prefix):
+                continue
+            name = p[len(prefix):]
+            name = name[:name.rfind(".")]
+            if name in result:
+                continue
+            assert scm.item.name == '{name}'
+            value = self._get_one(project, prefix + name, scm.item)
+            if isinstance(value, dict):
+                value["name"] = name
+            result[name] = value
+        return result
+
+    def _get_one(self, project, prop_name, scm):
+        if type(scm) == MapSchema:
+            return self._get_map_scm(project, prop_name, scm)
+        elif type(scm) == ArraySchema:
+            prefix = prop_name + "."
+            result = {}
+            for i in scm.members:
+                assert i.name != '{name}'
+                result[i.name] = self._get_one(project, prefix + i.name, i)
+            return result
+        else:
+            return project.get_property(prop_name)
+
+    def get_module_properties(self, project):
+        scm = self.project_property_schema
+        return self._get_one(project, scm.name, scm)
+
 _loaded_modules = {}
 
 def _module_init_config(cls):
diff --git a/mods/email.py b/mods/email.py
index 91c7d28..7ee7724 100644
--- a/mods/email.py
+++ b/mods/email.py
@@ -188,19 +188,7 @@ Email information is configured in "INI" style:
         return "<%s at patchew.org>" % uuid.uuid1()
 
     def get_notifications(self, project):
-        ret = {}
-        for k, v in project.get_properties().items():
-            if not k.startswith("email.notifications."):
-                continue
-            tn = k[len("email.notifications."):]
-            if "." not in tn:
-                continue
-            an = tn[tn.find(".") + 1:]
-            tn = tn[:tn.find(".")]
-            ret.setdefault(tn, {})
-            ret[tn][an] = v
-            ret[tn]["name"] = tn
-        return ret
+        return self.get_module_properties(project)["notifications"]
 
     def on_event(self, event, **params):
         class EmailCancelled(Exception):
diff --git a/mods/testing.py b/mods/testing.py
index e390e30..05493f0 100644
--- a/mods/testing.py
+++ b/mods/testing.py
@@ -298,18 +298,7 @@ class TestingModule(PatchewModule):
         ret = {}
         if isinstance(obj, Message):
             obj = obj.project
-        for k, v in obj.get_properties().items():
-            if not k.startswith("testing.tests."):
-                continue
-            tn = k[len("testing.tests."):]
-            if "." not in tn:
-                continue
-            an = tn[tn.find(".") + 1:]
-            tn = tn[:tn.find(".")]
-            ret.setdefault(tn, {})
-            ret[tn][an] = v
-            ret[tn]["name"] = tn
-        return ret
+        return self.get_module_properties(obj)["tests"]
 
     def _build_reset_ops(self, obj):
         if isinstance(obj, Message):
-- 
2.21.0




More information about the Patchew-devel mailing list