contentstack-utils 1.2.3__py3-none-any.whl → 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. contentstack_utils/__init__.py +36 -0
  2. contentstack_utils/automate.py +176 -0
  3. contentstack_utils/embedded/__init__.py +1 -0
  4. contentstack_utils/embedded/item_type.py +15 -0
  5. contentstack_utils/embedded/styletype.py +20 -0
  6. contentstack_utils/gql.py +37 -0
  7. contentstack_utils/helper/__init__.py +1 -0
  8. contentstack_utils/helper/converter.py +14 -0
  9. contentstack_utils/helper/metadata.py +65 -0
  10. contentstack_utils/helper/node_to_html.py +28 -0
  11. contentstack_utils/render/__init__.py +1 -0
  12. contentstack_utils/render/options.py +126 -0
  13. contentstack_utils/utils.py +94 -0
  14. {contentstack_utils-1.2.3.dist-info → contentstack_utils-1.3.0.dist-info}/METADATA +1 -1
  15. contentstack_utils-1.3.0.dist-info/RECORD +31 -0
  16. {contentstack_utils-1.2.3.dist-info → contentstack_utils-1.3.0.dist-info}/WHEEL +1 -1
  17. contentstack_utils-1.3.0.dist-info/top_level.txt +2 -0
  18. tests/__init__.py +52 -0
  19. tests/convert_style.py +29 -0
  20. tests/test_default_opt_others.py +44 -0
  21. tests/test_gql_to_html_func.py +37 -0
  22. tests/test_helper_node_to_html.py +61 -0
  23. tests/test_item_types.py +13 -0
  24. tests/test_metadata.py +53 -0
  25. tests/test_option_render_mark.py +52 -0
  26. tests/test_render_default_options.py +82 -0
  27. tests/test_render_options.py +36 -0
  28. tests/test_style_type.py +26 -0
  29. tests/test_util_srte.py +135 -0
  30. tests/test_utils.py +80 -0
  31. contentstack_utils-1.2.3.dist-info/RECORD +0 -5
  32. contentstack_utils-1.2.3.dist-info/top_level.txt +0 -1
  33. {contentstack_utils-1.2.3.dist-info → contentstack_utils-1.3.0.dist-info}/LICENSE +0 -0
@@ -0,0 +1,36 @@
1
+ # pip install -r requirements.txt
2
+ # pytest --html=tests/report/test-report.html
3
+ # coverage report -m
4
+ # coverage html -d coveragereport
5
+ """
6
+ __author__, __status__, __version__, __endpoint__ and __email__
7
+
8
+ `Your code has been rated at 10.00/10`
9
+ """
10
+
11
+ from contentstack_utils.embedded.item_type import ItemType
12
+ from contentstack_utils.embedded.styletype import StyleType
13
+ from contentstack_utils.helper.metadata import Metadata
14
+ from contentstack_utils.helper.node_to_html import NodeToHtml
15
+ from contentstack_utils.render.options import Options
16
+ from contentstack_utils.utils import Utils
17
+ from contentstack_utils.gql import GQL
18
+ from contentstack_utils.automate import Automate
19
+
20
+ __all__ = (
21
+ "Utils",
22
+ "Options",
23
+ "Metadata",
24
+ "GQL",
25
+ "Automate",
26
+ "StyleType",
27
+ "ItemType",
28
+ "NodeToHtml"
29
+ )
30
+
31
+ __title__ = 'contentstack_utils'
32
+ __author__ = 'contentstack'
33
+ __status__ = 'debug'
34
+ __version__ = '1.3.0'
35
+ __endpoint__ = 'cdn.contentstack.io'
36
+ __contact__ = 'support@contentstack.com'
@@ -0,0 +1,176 @@
1
+ import json
2
+ from contentstack_utils.helper.converter import convert_style
3
+ from contentstack_utils.helper.metadata import Metadata
4
+ from contentstack_utils.helper.node_to_html import NodeToHtml
5
+ from contentstack_utils.render.options import Options
6
+
7
+
8
+ class Automate:
9
+
10
+ @staticmethod
11
+ def _str_from_embed_items(metadata, entry, option):
12
+ if isinstance(entry, list):
13
+ for node in entry:
14
+ uid = node['node']['uid']
15
+ if uid == metadata.get_item_uid:
16
+ return option.render_options(node['node'], metadata)
17
+ elif isinstance(entry, dict) and '_embedded_items' in entry:
18
+ items = entry['_embedded_items'].keys()
19
+ for item in items:
20
+ items_array = entry['_embedded_items'][item]
21
+ content = Automate._find_embedded_entry(items_array, metadata)
22
+ if content is not None:
23
+ return option.render_options(content, metadata)
24
+ else:
25
+ node_style = entry['type']
26
+ def call(children):
27
+ return Automate._raw_processing(children, entry, option)
28
+
29
+ return option.render_node(node_style, entry, callback=call)
30
+ return ''
31
+
32
+ @staticmethod
33
+ def _get_embedded_keys(entry, key_path, option: Options, render_callback):
34
+ if '_embedded_items' in entry:
35
+ if key_path is not None:
36
+ for path in key_path:
37
+ Automate._find_embed_keys(entry, path, option, render_callback)
38
+ else:
39
+ _embedded_items = entry['_embedded_items']
40
+ available_keys: list = _embedded_items.keys()
41
+ for path in available_keys:
42
+ Automate._find_embed_keys(entry, path, option, render_callback)
43
+
44
+ @staticmethod
45
+ def _find_embed_keys(entry, path, option: Options, render_callback):
46
+ keys = path.split('.')
47
+ Automate._get_content(keys, entry, option, render_callback)
48
+
49
+ @staticmethod
50
+ def _get_content(keys_array, entry, option: Options, render_callback):
51
+ if keys_array is not None and len(keys_array) > 0:
52
+ key = keys_array[0]
53
+ if len(keys_array) == 1 and keys_array[0] in entry:
54
+ var_content = entry[key]
55
+ if isinstance(var_content, (list, str, dict)):
56
+ entry[key] = render_callback(var_content, entry, option)
57
+ else:
58
+ keys_array.remove(key)
59
+ if key in entry and isinstance(entry[key], dict):
60
+ Automate._get_content(keys_array, entry[key], option, render_callback)
61
+ elif key in entry and isinstance(entry[key], list):
62
+ list_json = entry[key]
63
+ for node in list_json:
64
+ Automate._get_content(keys_array, node, option, render_callback)
65
+
66
+ @staticmethod
67
+ def is_json(self: object) -> bool:
68
+ try:
69
+ json.dumps(self)
70
+ return True
71
+ except ValueError:
72
+ return False
73
+
74
+ @staticmethod
75
+ def find_embed_keys(entry, paths, option: Options, render_callback):
76
+ Automate.get_content(paths, entry, option, render_callback)
77
+
78
+ @staticmethod
79
+ def get_content(keys_array, entry, option: Options, render_callback):
80
+ if keys_array is not None and len(keys_array) > 0:
81
+ key = keys_array[0]
82
+ if len(keys_array) == 1 and keys_array[0] in entry:
83
+ var_content = entry[key]
84
+ if isinstance(var_content, (list, str, dict)):
85
+ entry[key] = render_callback(var_content, entry, option)
86
+ else:
87
+ keys_array.remove(key)
88
+ if key in entry and isinstance(entry[key], dict):
89
+ Automate.get_content(keys_array, entry[key], option, render_callback)
90
+ elif key in entry and isinstance(entry[key], list):
91
+ list_json = entry[key]
92
+ for node in list_json:
93
+ Automate.get_content(keys_array, node, option, render_callback)
94
+
95
+ @staticmethod
96
+ def _enumerate_content(content, entry, option):
97
+ if len(content) > 0:
98
+ if isinstance(content, list):
99
+ array_content = []
100
+ for item in content:
101
+ result = Automate._enumerate_content(item, entry, option)
102
+ array_content.append(result)
103
+ return array_content
104
+ if isinstance(content, dict):
105
+ content_entry = content[entry]
106
+ if isinstance(content_entry, dict):
107
+ if 'type' and 'children' in content_entry:
108
+ if content_entry['type']:
109
+ return Automate._raw_processing(content_entry['children'], entry, option)
110
+ elif isinstance(content_entry, list):
111
+ for entry_item in content_entry:
112
+ if 'type' and 'children' in entry_item:
113
+ if entry_item['type']:
114
+ return Automate._raw_processing(entry_item['children'], entry, option)
115
+
116
+ return ''
117
+
118
+ @staticmethod
119
+ def _raw_processing(children, entry, option):
120
+ array_container = []
121
+ for item in children:
122
+ if isinstance(item, dict):
123
+ array_container.append(Automate._extract_keys(item, entry, option))
124
+ temp = ''.join(array_container)
125
+ return temp
126
+
127
+ @staticmethod
128
+ def _extract_keys(item, entry, option: Options):
129
+ if 'type' not in item.keys() and 'text' in item.keys():
130
+ return NodeToHtml.text_node_to_html(item, option)
131
+
132
+ elif 'type' in item.keys():
133
+ node_style = item['type']
134
+ if node_style == 'reference':
135
+ metadata = Automate._return_metadata(item, node_style)
136
+ return Automate._str_from_embed_items(metadata=metadata, entry=item, option=option)
137
+ else:
138
+ def call(children):
139
+ return Automate._raw_processing(children, entry, option)
140
+
141
+ return option.render_node(node_style, item, callback=call)
142
+ return ''
143
+
144
+ @staticmethod
145
+ def _find_embedded_entry(list_json: list, metadata: Metadata):
146
+ for obj in list_json:
147
+ if obj['uid'] == metadata.get_item_uid:
148
+ return obj
149
+ return None
150
+
151
+ @staticmethod
152
+ def _return_metadata(item, node_style):
153
+ attr = item['attrs']
154
+ text = Automate._get_child_text(item)
155
+ style = convert_style(attr['display-type'])
156
+ if attr['type'] == 'asset':
157
+ return Metadata(text, node_style,
158
+ attr['asset-uid'],
159
+ 'sys-asset',
160
+ style, '', '')
161
+ else:
162
+ return Metadata(text, node_style,
163
+ attr['entry-uid'],
164
+ attr['content-type-uid'],
165
+ style, '', '')
166
+
167
+ @staticmethod
168
+ def _get_child_text(item):
169
+ text = ''
170
+ if 'children' in item.keys() and len(item['children']) > 0:
171
+ children = item['children']
172
+ for child in children:
173
+ if text in child.keys():
174
+ text = child['text']
175
+ break
176
+ return text
@@ -0,0 +1 @@
1
+ import contentstack_utils
@@ -0,0 +1,15 @@
1
+ """
2
+ ItemType is Enumeration class that conatains two options for ItemType:
3
+
4
+ ASSET
5
+
6
+ ENTRY
7
+ """
8
+
9
+ import enum
10
+
11
+
12
+ class ItemType(enum.Enum):
13
+ """Contains Two option for ItemsType => ENTRY and ASSET """
14
+ ENTRY = 'entry'
15
+ ASSET = 'asset'
@@ -0,0 +1,20 @@
1
+ """"
2
+ There are two types StyleType ENTRY and ASSETS
3
+ For `Entry`: StyleType.BLOCK, StyleType.INLINE, StyleType.LINKED,
4
+ For `Assets`: StyleType.DISPLAY, StyleType.DOWNLOADABLE
5
+ """
6
+ import enum
7
+
8
+
9
+ class StyleType(enum.Enum):
10
+
11
+ """
12
+ This StyleType contains four options like below.
13
+ BLOCK ,INLINE ,LINK,DISPLAY,DOWNLOAD
14
+ """
15
+
16
+ BLOCK = 'block'
17
+ INLINE = 'inline'
18
+ LINK = 'link'
19
+ DISPLAY = 'display'
20
+ DOWNLOAD = 'download'
@@ -0,0 +1,37 @@
1
+ from contentstack_utils import Utils
2
+ from contentstack_utils.automate import Automate
3
+ from contentstack_utils.render.options import Options
4
+
5
+
6
+ class GQL(Automate):
7
+
8
+ @staticmethod
9
+ def json_to_html(gql_entry: dict, paths: list, option: Options):
10
+ if not Automate.is_json(gql_entry):
11
+ raise FileNotFoundError("Can't process invalid object")
12
+ if len(paths) > 0:
13
+ for path in paths:
14
+ Automate.find_embed_keys(gql_entry, path, option, render_callback=GQL._json_matcher)
15
+ return Automate._enumerate_content(gql_entry, path, option)
16
+
17
+ @staticmethod
18
+ def __filter_content(content_dict):
19
+ embedded_items = None
20
+ if content_dict is not None and 'embedded_itemsConnection' in content_dict:
21
+ embedded_connection = content_dict['embedded_itemsConnection']
22
+ if 'edges' in embedded_connection:
23
+ embedded_items = embedded_connection['edges']
24
+ return embedded_items
25
+
26
+ @staticmethod
27
+ def _json_matcher(content_dict, entry, option):
28
+ embedded_items = GQL.__filter_content(content_dict)
29
+ if 'json' in content_dict:
30
+ json = content_dict['json']
31
+ if isinstance(json, dict):
32
+ return Automate._enumerate_content(json, entry=embedded_items, option=option)
33
+ elif isinstance(json, list):
34
+ json_container = []
35
+ for item in json:
36
+ json_container.append(Automate._enumerate_content(item, entry=embedded_items, option=option))
37
+ return json_container
@@ -0,0 +1 @@
1
+ import contentstack_utils
@@ -0,0 +1,14 @@
1
+ from contentstack_utils.embedded.styletype import StyleType
2
+
3
+
4
+ def convert_style(style) -> StyleType:
5
+ if style == 'block':
6
+ return StyleType.BLOCK
7
+ if style == 'inline':
8
+ return StyleType.INLINE
9
+ if style == 'link':
10
+ return StyleType.LINK
11
+ if style == 'display':
12
+ return StyleType.DISPLAY
13
+ if style == 'download':
14
+ return StyleType.DOWNLOAD
@@ -0,0 +1,65 @@
1
+ """
2
+ Metadata is the model class for embedded objects
3
+
4
+ Returns:
5
+ str: text, item_type, item_uid, type_uid, style_type, outer_html and attributes
6
+ """
7
+
8
+ from contentstack_utils.embedded.styletype import StyleType
9
+
10
+
11
+ class Metadata:
12
+ """
13
+ model helper class to set and get value
14
+ """
15
+
16
+ def __init__(self, text: str, item_type: str, item_uid: str,
17
+ content_type_uid: str, style_type: StyleType,
18
+ outer_html: str, attributes: str):
19
+ """
20
+ Used to set the value to the variables
21
+
22
+ Args:
23
+ text (str): text for embedded objects
24
+ item_type (str): item_type for embedded objects
25
+ item_uid (str): item_uid for embedded objects
26
+ content_type_uid (str): content_type_uid for embedded objects
27
+ style_type (StyleType): style_type for embedded objects
28
+ outer_html (str): outer_html for embedded objects
29
+ attributes (str): attributes for embedded objects
30
+ """
31
+ self.text = text
32
+ self.item_type = item_type
33
+ self.item_uid = item_uid
34
+ self.content_type_uid = content_type_uid
35
+ self.style_type = style_type
36
+ self.outer_html = outer_html
37
+ self.attributes = attributes
38
+
39
+ @property
40
+ def get_text(self):
41
+ return self.text
42
+
43
+ @property
44
+ def get_item_type(self):
45
+ return self.item_type
46
+
47
+ @property
48
+ def get_item_uid(self):
49
+ return self.item_uid
50
+
51
+ @property
52
+ def get_content_type_uid(self):
53
+ return self.content_type_uid
54
+
55
+ @property
56
+ def get_style_type(self) -> StyleType:
57
+ return self.style_type
58
+
59
+ @property
60
+ def get_outer_html(self):
61
+ return self.outer_html
62
+
63
+ @property
64
+ def get_attributes(self):
65
+ return self.attributes
@@ -0,0 +1,28 @@
1
+ from contentstack_utils.render.options import Options
2
+
3
+
4
+ class NodeToHtml:
5
+
6
+ @staticmethod
7
+ def text_node_to_html(node, option: Options):
8
+ """
9
+ accepts node type,
10
+ on the basis of the node type, generates string
11
+ :rtype: str
12
+ """
13
+ node_text = node['text']
14
+ if 'superscript' in node:
15
+ node_text = option.render_mark('superscript', node_text)
16
+ if 'subscript' in node:
17
+ node_text = option.render_mark('subscript', node_text)
18
+ if 'inlineCode' in node:
19
+ node_text = option.render_mark('inlineCode', node_text)
20
+ if 'strikethrough' in node:
21
+ node_text = option.render_mark('strikethrough', node_text)
22
+ if 'underline' in node:
23
+ node_text = option.render_mark('underline', node_text)
24
+ if 'italic' in node:
25
+ node_text = option.render_mark('italic', node_text)
26
+ if 'bold' in node:
27
+ node_text = option.render_mark('bold', node_text)
28
+ return node_text
@@ -0,0 +1 @@
1
+ import contentstack_utils
@@ -0,0 +1,126 @@
1
+ from contentstack_utils.helper.metadata import Metadata
2
+
3
+
4
+ def _title_or_uid(_obj: dict) -> str:
5
+ _title = ""
6
+ if _obj is not None:
7
+ if 'title' in _obj and len(_obj['title']) != 0:
8
+ _title = _obj['title']
9
+ elif 'uid' in _obj:
10
+ _title = _obj['uid']
11
+ return _title
12
+
13
+
14
+ def _asset_title_or_uid(_obj: dict) -> str:
15
+ _title = ""
16
+ if _obj is not None:
17
+ if 'title' in _obj and len(_obj['title']) != 0:
18
+ _title = _obj['title']
19
+ elif 'filename' in _obj:
20
+ _title = _obj['filename']
21
+ elif 'uid' in _obj:
22
+ _title = _obj['uid']
23
+ return _title
24
+
25
+
26
+ class Options:
27
+
28
+ @staticmethod
29
+ def render_options(_obj: dict, metadata: Metadata):
30
+ if metadata.style_type.value == 'block':
31
+ _content_type_uid = ''
32
+ if '_content_type_uid' in _obj:
33
+ _content_type_uid = _obj['_content_type_uid']
34
+ return '<div><p>' + _title_or_uid(_obj) \
35
+ + '</p><div><p>Content type: <span>' + _content_type_uid \
36
+ + '</span></p></div>'
37
+ if metadata.style_type.value == 'inline':
38
+ return '<span>' + _title_or_uid(_obj) + '</span>'
39
+ if metadata.style_type.value == 'link':
40
+ return '<a href=' + _obj['url'] + '>' + _title_or_uid(_obj) + '</a>'
41
+ if metadata.style_type.value == 'display':
42
+ return '<img src=' + _obj['url'] + ' alt=' \
43
+ + _asset_title_or_uid(_obj) + '/>'
44
+ if metadata.style_type.value == 'download':
45
+ return '<a href=' + _obj['url'] + '>' + _asset_title_or_uid(_obj) + '</a>'
46
+
47
+ @staticmethod
48
+ def render_mark(mark_type: str, render_text: str):
49
+ if mark_type == 'superscript':
50
+ return "<sup>" + render_text + "</sup>"
51
+ if mark_type == 'subscript':
52
+ return "<sub>" + render_text + "</sub>"
53
+ if mark_type == 'inlineCode':
54
+ return "<span>" + render_text + "</span>"
55
+ if mark_type == 'strikethrough':
56
+ return "<strike>" + render_text + "</strike>"
57
+ if mark_type == 'underline':
58
+ return "<u>" + render_text + "</u>"
59
+ if mark_type == 'italic':
60
+ return "<em>" + render_text + "</em>"
61
+ if mark_type == 'bold':
62
+ return "<strong>" + render_text + "</strong>"
63
+ else:
64
+ return render_text
65
+ pass
66
+
67
+ @staticmethod
68
+ def render_node(node_type, node_obj: dict, callback):
69
+ inner_html = callback(node_obj['children'])
70
+ if node_type == 'p':
71
+ return "<p>" + inner_html + "</p>"
72
+ if node_type == 'a':
73
+ return "<a href=\"{}\">{}</a>".format(node_obj["attrs"]["href"], inner_html)
74
+ if node_type == 'img':
75
+ return "<img src=\"{}\" />{}".format(node_obj["attrs"]["src"], inner_html)
76
+ if node_type == 'embed':
77
+ return "<iframe src={}>{}</iframe>".format(node_obj["attrs"]["src"], inner_html)
78
+ if node_type == 'h1':
79
+ return "<h1>" + inner_html + "</h1>"
80
+ if node_type == 'h2':
81
+ return "<h2>" + inner_html + "</h2>"
82
+ if node_type == 'h3':
83
+ return "<h3>" + inner_html + "</h3>"
84
+ if node_type == 'h4':
85
+ return "<h4>" + inner_html + "</h4>"
86
+ if node_type == 'h5':
87
+ return "<h5>" + inner_html + "</h5>"
88
+ if node_type == 'h6':
89
+ return "<h6>" + inner_html + "</h6>"
90
+ if node_type == 'ol':
91
+ return "<ol>" + inner_html + "</ol>"
92
+ if node_type == 'ul':
93
+ return "<ul>" + inner_html + "</ul>"
94
+ if node_type == 'li':
95
+ return "<li>" + inner_html + "</li>"
96
+ if node_type == 'hr':
97
+ return "<hr />"
98
+ if node_type == 'table':
99
+ return "<table>" + inner_html + "</table>"
100
+ if node_type == 'thead':
101
+ return "<thead>" + inner_html + "</thead>"
102
+ if node_type == 'tbody':
103
+ return "<tbody>" + inner_html + "</tbody>"
104
+ if node_type == 'tfoot':
105
+ return "<tfoot>" + inner_html + "</tfoot>"
106
+ if node_type == 'tr':
107
+ return "<tr>" + inner_html + "</tr>"
108
+ if node_type == 'th':
109
+ return "<th>" + inner_html + "</th>"
110
+ if node_type == 'td':
111
+ return "<td>" + inner_html + "</td>"
112
+ if node_type == 'blockquote':
113
+ return "<blockquote>" + inner_html + "</blockquote>"
114
+ if node_type == 'code':
115
+ return "<code>" + inner_html + "</code>"
116
+ if node_type == 'fragment':
117
+ return "<fragment>" + inner_html + "</fragment>"
118
+ if node_type == 'reference':
119
+ if node_obj['attrs']['type'] == 'asset':
120
+ return "<img src=\"{}\" alt=\"{}\" class=\"{}\" />{}".format(node_obj["attrs"]["asset-link"], node_obj["attrs"]["alt"], node_obj["attrs"]["class-name"], inner_html)
121
+ else:
122
+ return inner_html
123
+ if node_type == 'doc':
124
+ return inner_html
125
+ else:
126
+ return inner_html
@@ -0,0 +1,94 @@
1
+ # pylint: disable=missing-function-docstring
2
+
3
+ from lxml import etree
4
+
5
+ from contentstack_utils.automate import Automate
6
+ from contentstack_utils.helper.converter import convert_style
7
+ from contentstack_utils.helper.metadata import Metadata
8
+ from contentstack_utils.render.options import Options
9
+
10
+
11
+ class Utils(Automate):
12
+
13
+ @staticmethod
14
+ def render(entry_obj, key_path: list, option: Options):
15
+ valid = Automate.is_json(entry_obj)
16
+ if not valid:
17
+ raise FileNotFoundError('Invalid file found')
18
+
19
+ if isinstance(entry_obj, list):
20
+ for entry in entry_obj:
21
+ Utils.render(entry, key_path, option)
22
+
23
+ if isinstance(entry_obj, dict):
24
+ Automate._get_embedded_keys(entry_obj, key_path, option, render_callback=Utils.render_content)
25
+
26
+ @staticmethod
27
+ def render_content(rte_content, embed_obj: dict, option: Options) -> object:
28
+ if isinstance(rte_content, str):
29
+ return Utils.__get_embedded_objects(rte_content, embed_obj, option)
30
+ elif isinstance(rte_content, list):
31
+ render_callback = []
32
+ for rte in rte_content:
33
+ render_callback.append(Utils.render_content(rte, embed_obj, option))
34
+ return render_callback
35
+ return rte_content
36
+
37
+ @staticmethod
38
+ def __get_embedded_objects(html_doc, entry, option):
39
+ import re
40
+ document = f"<items>{html_doc}</items>"
41
+ tag = etree.fromstring(document)
42
+ html_doc = etree.tostring(tag).decode('utf-8')
43
+ html_doc = re.sub('(?ms)<%s[^>]*>(.*)</%s>' % (tag.tag, tag.tag), '\\1', html_doc)
44
+ elements = tag.xpath("//*[contains(@class, 'embedded-asset') or contains(@class, 'embedded-entry')]")
45
+ metadata = Utils.__get_metadata(elements)
46
+ string_content = Utils._str_from_embed_items(metadata=metadata, entry=entry, option=option)
47
+ html_doc = html_doc.replace(metadata.outer_html, string_content)
48
+ return html_doc
49
+
50
+ @staticmethod
51
+ def _str_from_embed_items(metadata, entry, option):
52
+ if '_embedded_items' in entry:
53
+ items = entry['_embedded_items'].keys()
54
+ for item in items:
55
+ items_array = entry['_embedded_items'][item]
56
+ content = Automate._find_embedded_entry(items_array, metadata)
57
+ if content is not None:
58
+ return option.render_options(content, metadata)
59
+ return ''
60
+
61
+ @staticmethod
62
+ def __get_metadata(elements):
63
+ for element in elements:
64
+ content_type = None
65
+ typeof = element.attrib['type']
66
+ if typeof == 'asset':
67
+ uid = element.attrib['data-sys-asset-uid']
68
+ else:
69
+ uid = element.attrib['data-sys-entry-uid']
70
+ content_type = element.attrib['data-sys-content-type-uid']
71
+ style = element.attrib['sys-style-type']
72
+ outer_html = etree.tostring(element).decode('utf-8')
73
+ attributes = element.attrib
74
+ style = convert_style(style)
75
+ metadata = Metadata(element.text, typeof, uid, content_type, style, outer_html, attributes)
76
+ return metadata
77
+
78
+ ####################################################
79
+ # SUPERCHARGED #
80
+ ####################################################
81
+
82
+ @staticmethod
83
+ def json_to_html(entry_obj, key_path: list, option: Options):
84
+ if not Automate.is_json(entry_obj):
85
+ raise FileNotFoundError('Could not process invalid content')
86
+ if isinstance(entry_obj, list):
87
+ for entry in entry_obj:
88
+ return Utils.json_to_html(entry, key_path, option)
89
+ if isinstance(entry_obj, dict):
90
+ if key_path is not None:
91
+ for path in key_path:
92
+ render_callback = Automate._enumerate_content(entry_obj, path, option)
93
+ # Automate._find_embed_keys(entry_obj, path, option, render_callback) This method used in GQL class.
94
+ return render_callback
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: contentstack_utils
3
- Version: 1.2.3
3
+ Version: 1.3.0
4
4
  Summary: contentstack_utils is a Utility package for Contentstack headless CMS with an API-first approach.
5
5
  Home-page: https://github.com/contentstack/contentstack-utils-python
6
6
  Author: contentstack
@@ -0,0 +1,31 @@
1
+ contentstack_utils/__init__.py,sha256=CfbGkFGBS_v7mfYxOo1QU35LLUUhX8muQ650EjzDisU,957
2
+ contentstack_utils/automate.py,sha256=3tm43Y12dWZrJy6DR9tkAl4Dmph9-hNMXK94UWSKYso,7389
3
+ contentstack_utils/gql.py,sha256=_r1K8pBduin_STrIo9IqdD3ftH0_3Ii6RSnTcrqwJlY,1587
4
+ contentstack_utils/utils.py,sha256=4oIy_JBhpLW0CkxyZJ39ubj9u7Lw4sKRhOyg3cCStdM,4045
5
+ contentstack_utils/embedded/__init__.py,sha256=0Ni3R_ia-HuTDFYQvoLURdeRkRD8HiyteiEEJ3O4V14,25
6
+ contentstack_utils/embedded/item_type.py,sha256=yoB3ZTJ0IdwhL5E61zrxLXZSvcLMnnUiI6vi6jhR3Ww,239
7
+ contentstack_utils/embedded/styletype.py,sha256=lwRV-tn1be3DPqeW3YnZPsWCXns9Xd0ml_hC5M87zow,443
8
+ contentstack_utils/helper/__init__.py,sha256=0Ni3R_ia-HuTDFYQvoLURdeRkRD8HiyteiEEJ3O4V14,25
9
+ contentstack_utils/helper/converter.py,sha256=2tZ6paPnWCCW0aoaQiMFGAhAdx4Bh2LsCnlCm3Q7yVw,391
10
+ contentstack_utils/helper/metadata.py,sha256=YrNVhvkv4n_nR0nrJR2x2eqYE3-P1jT7ctVSklvnSgc,1795
11
+ contentstack_utils/helper/node_to_html.py,sha256=himweM9ID4tQb7GNQP49XYTkN0KWWPy_LzBi-f6eS2E,1019
12
+ contentstack_utils/render/__init__.py,sha256=0Ni3R_ia-HuTDFYQvoLURdeRkRD8HiyteiEEJ3O4V14,25
13
+ contentstack_utils/render/options.py,sha256=hbqgPxCksgQlV5hK_6Flb2HEHaXk5JpMNc7z5yMxgCI,5033
14
+ tests/__init__.py,sha256=stlQRdpO_kQoRExPLd-q80RCzHd-F4t1Rs6tZ0ObP2o,2336
15
+ tests/convert_style.py,sha256=gXHQjSnxCZ7kQBG6TjKIYk-tvKhzdpeOBCA88YTcDC8,983
16
+ tests/test_default_opt_others.py,sha256=H-xhmyGMJNET0kkhXGcyepWUTE0Vqd1DpzPCI6hKaro,2138
17
+ tests/test_gql_to_html_func.py,sha256=oh7YpNay9GBBnVXbJhbh5e0r5eMYcrXhrzaiwuAQTOg,1180
18
+ tests/test_helper_node_to_html.py,sha256=S3JSRv5FXyBnBXM23J7v9rtrIvODii0J9AEBMO4gve4,2497
19
+ tests/test_item_types.py,sha256=lHKquAgitHEPquAR9Qyvcl2aWhXYaHJe9F1anCloYh0,350
20
+ tests/test_metadata.py,sha256=B5SY50S7-bdzgSs5UDupcRWThzm3weyTNu4WqUBr3OY,1837
21
+ tests/test_option_render_mark.py,sha256=NU7TOTJgljZyO5cnrphX-XyhJXUYqaZIbTzMJX0HOvY,2582
22
+ tests/test_render_default_options.py,sha256=JNx_gA11Af-hPRoSd5MG59Cy5xjyUrpr8WXpVzqk6FY,3993
23
+ tests/test_render_options.py,sha256=BFuf9nkh1c9BJ-UTFVBkmjBTf31pSeWJ2jTZY7XgVaY,1701
24
+ tests/test_style_type.py,sha256=6Wz_UR5ZQcaUlB-Tfeqp6Dcu85AE7pHbtg6V1Sh7A9k,723
25
+ tests/test_util_srte.py,sha256=vNb2xsrmGmGSonW_EzpItcqoQmnSWUmOlzybIo5fzik,5951
26
+ tests/test_utils.py,sha256=2rvZZcT6m3QJZeyqzyp9ydsTX34w5tAkQOCKqXso3xw,3614
27
+ contentstack_utils-1.3.0.dist-info/LICENSE,sha256=lNqz95ic6VWhDILAlbV_KgjGfl7GM1QQd6LKZq__zx4,1051
28
+ contentstack_utils-1.3.0.dist-info/METADATA,sha256=3J3TPvQlfE0wmBcz1EweJYGRt6wzYdIH5jpWRI3UhgY,4906
29
+ contentstack_utils-1.3.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
30
+ contentstack_utils-1.3.0.dist-info/top_level.txt,sha256=4b5I6taLW2KGOy1931_UZDIcML7HJEfjpzIDpz5MmTU,25
31
+ contentstack_utils-1.3.0.dist-info/RECORD,,