3d9852221a2f — Carsten Grohmann 9 months ago
Separated from SMM to an own repository
6 files changed, 220 insertions(+), 0 deletions(-)

A => .build.yml
A => .hgignore
A => JsonDottedReadAccess.py
A => LICENSE
A => README.md
A => test.py
A => .build.yml +34 -0
@@ 0,0 1,34 @@ 
+# Build file for JsonDottedReadAccess
+#
+# This software is covered by the MIT License.
+#
+# Copyright (c) 2017-2020 Carsten Grohmann <mail@carsten-grohmann.de>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+image: archlinux
+arch:  x86_64
+packages:
+  - python2
+sources:
+  - hg+https://hg.sr.ht/~carstengrohmann/JsonDottedReadAccess
+shell: null
+tasks:
+  - unittests: |
+      cd JsonDottedReadAccess
+      python2 ./test.py
+triggers:
+  - action: email
+    condition: failure
+    to: Carsten Grohmann <mail@carstengrohmann.de>
  No newline at end of file

          
A => .hgignore +10 -0
@@ 0,0 1,10 @@ 
+# use glob syntax.
+syntax: glob
+
+# IntelliJ IDEA / PyCharm IDE
+.idea
+
+# Misc
+**.pyc
+**.pyo
+**.swp
  No newline at end of file

          
A => JsonDottedReadAccess.py +60 -0
@@ 0,0 1,60 @@ 
+# -*- coding: ASCII -*-
+#
+# This software is covered by the MIT License.
+#
+# Copyright (c) 2017-2020 Carsten Grohmann <mail@carsten-grohmann.de>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+import UserDict
+
+
+class JsonDottedReadAccess(UserDict.UserDict):
+    """
+    Extended dictionary implementation to simplify access nested elements
+    by a single key. Nested items separated by a dot "." in the key.
+
+    Elements of an embedded list can accessed by a digit string.
+
+    Example:
+    >>> d = {u'level1': {u'level2-a': None,
+    ...                  u'level2-b': [{'level3-b': 1}],
+    ...                  u'level2-c': {'level3-c': 1},
+    ...                  u'level2-d': 'level3-d'}}
+    >>> j = JsonDottedReadAccess(d)
+    >>> j.get('level1')
+    {u'level2-c': {'level3-c': 1}, u'level2-b': [{'level3-b': 1}], u'level2-a': None, u'level2-d': 'level3-d'}
+    >>> j.get('level1.level2-d')
+    'level3-d'
+    >>> j.get('level1.level2-b')
+    [{'level3-b': 1}]
+    """
+
+    def __getitem__(self, key):
+        keys = key.split('.')
+        val = self.data
+        for key in keys:
+            if isinstance(val, list):
+                if key.isdigit():
+                    key = int(key)
+                else:
+                    raise KeyError('Use a numeric key instead of %s to access list elements.' % key)
+            val = val[key]
+        return val
+
+    def get(self, key, failobj=None):
+        try:
+            return self.__getitem__(key)
+        except KeyError:
+            return failobj

          
A => LICENSE +7 -0
@@ 0,0 1,7 @@ 
+Copyright (c) 2014-2020 Carsten Grohmann <mail@carsten-grohmann.de>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

          
A => README.md +53 -0
@@ 0,0 1,53 @@ 
+Json Dotted Read Access
+=======================
+
+[![builds.sr.ht status](https://builds.sr.ht/~carstengrohmann/JsonDottedReadAccess.svg)](https://builds.sr.ht/~carstengrohmann/JsonDottedReadAccess)
+
+Simplify deep access to JSON structures by introduce a dotted access notation. 
+
+## Supported and tested Python versions
+ * Python 2.7
+ 
+## Requirements
+There are no additional requirements. All you need is Python2.
+
+## Installation
+Add the file `JsonDottedReadAccess.py` to your project and activate it like described in the "Usage" section.
+
+## Usage
+```python
+>>> from JsonDottedReadAccess import JsonDottedReadAccess
+>>> d = {u'level1': {u'level2-a': None,
+...                  u'level2-b': [{'level3-b': 1}],
+...                  u'level2-c': {'level3-c': 1},
+...                  u'level2-d': 'level3-d'}}
+>>> j = JsonDottedReadAccess(d)
+>>> j.get('level1')
+{u'level2-c': {'level3-c': 1}, u'level2-b': [{'level3-b': 1}], u'level2-a': None, u'level2-d': 'level3-d'}
+>>> j.get('level1.level2-d')
+'level3-d'
+>>> j.get('level1.level2-b')
+[{'level3-b': 1}]
+```
+
+## Project page and feedback
+* [Mercurial Repository](https://hg.sr.ht/~carstengrohmann/JsonDottedReadAccess)
+
+## License
+
+This software is covered by the MIT License.
+
+Copyright (c) 2017-2020 Carsten Grohmann <mail@carsten-grohmann.de>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

          
A => test.py +56 -0
@@ 0,0 1,56 @@ 
+# -*- coding: ASCII -*-
+#
+# This software is covered by the MIT License.
+#
+# Copyright (c) 2017-2020 Carsten Grohmann <mail@carsten-grohmann.de>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+import unittest
+from JsonDottedReadAccess import JsonDottedReadAccess
+
+
+class MyTestCase(unittest.TestCase):
+
+    def test_JsonDottedReadAccess(self):
+        simple_dict = {u'level1': {u'level21': None,
+                                   u'level22': [{'level3': 1}, ],
+                                   u'level23': {'level3': 1},
+                                   u'level24': 'level24',
+                                   }}
+        json_access = JsonDottedReadAccess(simple_dict)
+
+        # simple access
+        self.failUnlessEqual(json_access['level1.level21'], None)
+        self.failUnlessEqual(json_access['level1.level24'], 'level24')
+
+        # check if ValueError is raised for access with non-numeric value to a list
+        def raiseKeyError1():
+            json_access['level1.level22.A']
+        self.failUnlessRaises(KeyError, raiseKeyError1)
+
+        def raiseKeyError2():
+            json_access['non-existing']
+        self.failUnlessRaises(KeyError, raiseKeyError2)
+        self.failUnlessEqual(json_access.get('non-existing'), None)
+
+        def raiseKeyError3():
+            json_access['level1.non-existing.level3']
+        self.failUnlessRaises(KeyError, raiseKeyError3)
+        self.failUnlessEqual(json_access.get('level1.non-existing.level3'), None)
+
+
+if __name__ == '__main__':
+    unittest.main()