ssc_codegen 0.9.6__tar.gz → 0.9.8__tar.gz

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 (56) hide show
  1. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/PKG-INFO +1 -1
  2. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/pyproject.toml +1 -1
  3. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/__init__.py +1 -1
  4. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/__init__.py +1 -1
  5. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_selectors.py +14 -0
  6. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/go_goquery.py +1 -0
  7. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/js_pure.py +16 -8
  8. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/py_bs4.py +25 -0
  9. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/py_parsel.py +19 -0
  10. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/py_selectolax.py +19 -0
  11. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/document.py +23 -0
  12. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/tokens.py +2 -0
  13. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/.gitignore +0 -0
  14. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/LICENSE +0 -0
  15. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/README.md +0 -0
  16. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/_compat.py +0 -0
  17. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/base.py +0 -0
  18. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_array.py +0 -0
  19. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_cast.py +0 -0
  20. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_core.py +0 -0
  21. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_filter.py +0 -0
  22. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_string.py +0 -0
  23. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_validate.py +0 -0
  24. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_build/__init__.py +0 -0
  25. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_build/main.py +0 -0
  26. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_build/utils.py +0 -0
  27. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_grep_rules/js_rules.yml +0 -0
  28. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_grep_rules/py_rules.yml +0 -0
  29. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/__init__.py +0 -0
  30. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/ast_grep.py +0 -0
  31. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/cli_callbacks.py +0 -0
  32. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/cli_utils.py +0 -0
  33. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/code_callbacks.py +0 -0
  34. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/consts.py +0 -0
  35. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/main.py +0 -0
  36. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/runtime_parse_runners.py +0 -0
  37. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/compiler.py +0 -0
  38. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/consts.py +0 -0
  39. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/__init__.py +0 -0
  40. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/base.py +0 -0
  41. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/helpers.py +0 -0
  42. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/py_base.py +0 -0
  43. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/templates/__init__.py +0 -0
  44. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/templates/go_goquery.py +0 -0
  45. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/templates/js_pure.py +0 -0
  46. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/document_utlis.py +0 -0
  47. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/json_struct.py +0 -0
  48. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/json_to_scc.py +0 -0
  49. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/logs.py +0 -0
  50. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/pseudo_selectors.py +0 -0
  51. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/schema.py +0 -0
  52. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/selector_utils.py +0 -0
  53. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/static_checker/__init__.py +0 -0
  54. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/static_checker/base.py +0 -0
  55. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/static_checker/callbacks.py +0 -0
  56. {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/str_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ssc_codegen
3
- Version: 0.9.6
3
+ Version: 0.9.8
4
4
  Summary: Python-dsl code converter to html parser for web scraping
5
5
  Project-URL: Documentation, https://github.com/vypivshiy/selector_schema_codegen#readme
6
6
  Project-URL: Issues, https://github.com/vypivshiy/selector_schema_codegen/issues
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ssc_codegen"
3
- version = "0.9.6"
3
+ version = "0.9.8"
4
4
  description = "Python-dsl code converter to html parser for web scraping "
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -7,7 +7,7 @@ from ssc_codegen.schema import ItemSchema, DictSchema, ListSchema, FlatListSchem
7
7
 
8
8
  setup_logger()
9
9
 
10
- VERSION = "0.9.6"
10
+ VERSION = "0.9.8"
11
11
 
12
12
 
13
13
  class __MISSING(object):
@@ -25,7 +25,7 @@ from .nodes_filter import FilterOr, FilterAnd, FilterNot, FilterNotEqual, Filter
25
25
  FilterStrLenLe, FilterStrLenGt, FilterStrLenGe
26
26
 
27
27
  from .nodes_selectors import ExprCss, ExprCssAll, ExprXpathAll, ExprXpath, ExprGetHtmlText, ExprGetHtmlRaw, \
28
- ExprGetHtmlAttr, ExprGetHtmlAttrAll, ExprGetHtmlRawAll, ExprGetHtmlTextAll
28
+ ExprGetHtmlAttr, ExprGetHtmlAttrAll, ExprGetHtmlRawAll, ExprGetHtmlTextAll, ExprMapAttrs, ExprMapAttrsAll
29
29
  from .nodes_string import ExprStringTrim, ExprStringRegex, ExprStringSplit, ExprStringReplace, ExprStringLeftTrim, \
30
30
  ExprStringFormat, ExprListStringTrim, ExprStringRegexAll, ExprStringRegexSub, ExprStringRightTrim, \
31
31
  ExprListStringFormat, ExprListStringReplace, ExprListStringRightTrim, ExprListStringLeftTrim, \
@@ -80,3 +80,17 @@ class ExprGetHtmlRawAll(BaseAstNode[T_EMPTY_KWARGS, tuple]):
80
80
  kind: ClassVar[TokenType] = TokenType.EXPR_RAW_ALL
81
81
  accept_type: VariableType = VariableType.LIST_DOCUMENT
82
82
  ret_type: VariableType = VariableType.LIST_STRING
83
+
84
+
85
+ @dataclass(kw_only=True)
86
+ class ExprMapAttrs(BaseAstNode[T_EMPTY_KWARGS, tuple]):
87
+ kind: ClassVar[TokenType] = TokenType.EXPR_MAP_ATTRS
88
+ accept_type: VariableType = VariableType.DOCUMENT
89
+ ret_type: VariableType = VariableType.LIST_STRING
90
+
91
+
92
+ @dataclass(kw_only=True)
93
+ class ExprMapAttrsAll(BaseAstNode[T_EMPTY_KWARGS, tuple]):
94
+ kind: ClassVar[TokenType] = TokenType.EXPR_MAP_ATTRS_ALL
95
+ accept_type: VariableType = VariableType.LIST_DOCUMENT
96
+ ret_type: VariableType = VariableType.LIST_STRING
@@ -1267,3 +1267,4 @@ def pre_list_str_rm_prefix_and_suffix(
1267
1267
  # TODO: impl ExprStringMapReplace, ExprListStringMapReplace
1268
1268
  # TODO: impl ExprAttr, ExprListAttr for multiple extract keys
1269
1269
  # TODO impl unescape
1270
+ # TODO: impl ExprHasAttr, ExprHasAttrAll
@@ -106,6 +106,7 @@ from ssc_codegen.ast_ import (
106
106
  ExprListStringMapReplace,
107
107
  )
108
108
  from ssc_codegen.ast_.nodes_core import ModuleImports
109
+ from ssc_codegen.ast_.nodes_selectors import ExprMapAttrs, ExprMapAttrsAll
109
110
  from ssc_codegen.ast_.nodes_string import (
110
111
  ExprListStringUnescape,
111
112
  ExprStringUnescape,
@@ -161,8 +162,9 @@ def to_js_regexp(
161
162
  pattern: str, ignore_case: bool = False, is_global: bool = True
162
163
  ) -> str:
163
164
  """helper function for convert string pattern to js"""
164
- pattern = pattern.replace("<\\/", "</")
165
- pattern = pattern.replace("/", "\\/")
165
+ # fix backslashes translate
166
+ pattern = pattern.replace("/", r"\/").replace(r"\\/", r"\/")
167
+
166
168
  pattern = f"/{pattern}/"
167
169
  if is_global:
168
170
  pattern += "g"
@@ -186,12 +188,6 @@ def py_sequence_to_js_array(values: tuple[str, ...] | list[str]) -> str:
186
188
  return "[" + val_arr[1:-1] + "]"
187
189
 
188
190
 
189
- @CONVERTER(ModuleImports.kind)
190
- def pre_imports(_node: ModuleImports) -> str:
191
- # HACK: used imports node for provide helpers scripts
192
- pass
193
-
194
-
195
191
  @CONVERTER(Docstring.kind)
196
192
  def pre_docstring(node: Docstring) -> str:
197
193
  value = node.kwargs["value"]
@@ -1012,3 +1008,15 @@ def pre_list_str_unescape(node: ExprListStringUnescape) -> str:
1012
1008
  + r".replace(/\\([bfnrt])/g, (_, ch) => ({b:'\b',f:'\f',n:'\n',r:'\r',t:'\\t'})[ch])"
1013
1009
  + ");"
1014
1010
  )
1011
+
1012
+
1013
+ @CONVERTER(ExprMapAttrs.kind)
1014
+ def pre_map_attrs(node: ExprMapAttrs) -> str:
1015
+ prv, nxt = prev_next_var(node)
1016
+ return f"let {nxt} = Array.from({prv}.attributes).map(a => a.value); "
1017
+
1018
+
1019
+ @CONVERTER(ExprMapAttrsAll.kind)
1020
+ def pre_map_attrs_all(node: ExprMapAttrsAll) -> str:
1021
+ prv, nxt = prev_next_var(node)
1022
+ return f"let {nxt} = [].concat(...{prv}.map(e => Array.from(e.attributes).map(a => a.value))); "
@@ -19,6 +19,7 @@ from ssc_codegen.ast_ import (
19
19
  ExprHasAttr,
20
20
  ExprListHasAttr,
21
21
  )
22
+ from ssc_codegen.ast_.nodes_selectors import ExprMapAttrs, ExprMapAttrsAll
22
23
  from ssc_codegen.converters.helpers import (
23
24
  prev_next_var,
24
25
  have_default_expr,
@@ -211,6 +212,30 @@ def pre_list_has_attr(node: ExprListHasAttr) -> str:
211
212
  return expr + "\n" + indent + f"{nxt} = {prv}"
212
213
 
213
214
 
215
+ @CONVERTER(ExprMapAttrs.kind)
216
+ def pre_map_attrs(node: ExprMapAttrs) -> str:
217
+ indent = (
218
+ INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
219
+ )
220
+ prv, nxt = prev_next_var(node)
221
+ return (
222
+ indent
223
+ + f"{nxt} = [' '.join(i) if isinstance(i, list) else i for i in {prv}.attrs.values()]"
224
+ )
225
+
226
+
227
+ @CONVERTER(ExprMapAttrsAll.kind)
228
+ def pre_map_attrs_all(node: ExprMapAttrsAll) -> str:
229
+ indent = (
230
+ INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
231
+ )
232
+ prv, nxt = prev_next_var(node)
233
+ return (
234
+ indent
235
+ + f"{nxt} = [' '.join(i) if isinstance(i, list) else i for e in {prv} for i in e.attrs.values()]"
236
+ )
237
+
238
+
214
239
  # NOT SUPPORT
215
240
  @CONVERTER(ExprXpath.kind)
216
241
  def pre_xpath(_: ExprXpath) -> str:
@@ -19,6 +19,7 @@ from ssc_codegen.ast_ import (
19
19
  ExprListHasAttr,
20
20
  ExprHasAttr,
21
21
  )
22
+ from ssc_codegen.ast_.nodes_selectors import ExprMapAttrs, ExprMapAttrsAll
22
23
  from ssc_codegen.converters.helpers import (
23
24
  prev_next_var,
24
25
  have_default_expr,
@@ -239,3 +240,21 @@ def pre_list_has_attr(node: ExprListHasAttr) -> str:
239
240
  if is_last_var_no_ret(node):
240
241
  return expr
241
242
  return expr + "\n" + indent + f"{nxt} = {prv}"
243
+
244
+
245
+ @CONVERTER(ExprMapAttrs.kind)
246
+ def pre_map_attrs(node: ExprMapAttrs) -> str:
247
+ indent = (
248
+ INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
249
+ )
250
+ prv, nxt = prev_next_var(node)
251
+ return indent + f"{nxt} = list({prv}.attrib.values())"
252
+
253
+
254
+ @CONVERTER(ExprMapAttrsAll.kind)
255
+ def pre_map_attrs_all(node: ExprMapAttrsAll) -> str:
256
+ indent = (
257
+ INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
258
+ )
259
+ prv, nxt = prev_next_var(node)
260
+ return indent + f"{nxt} = [i for e in {prv} for i in e.attrib.values()]"
@@ -19,6 +19,7 @@ from ssc_codegen.ast_ import (
19
19
  ExprListHasAttr,
20
20
  ExprHasAttr,
21
21
  )
22
+ from ssc_codegen.ast_.nodes_selectors import ExprMapAttrs, ExprMapAttrsAll
22
23
  from ssc_codegen.converters.helpers import (
23
24
  prev_next_var,
24
25
  have_default_expr,
@@ -214,6 +215,24 @@ def pre_list_has_attr(node: ExprListHasAttr) -> str:
214
215
  return expr + "\n" + indent + f"{nxt} = {prv}"
215
216
 
216
217
 
218
+ @CONVERTER(ExprMapAttrs.kind)
219
+ def pre_map_attrs(node: ExprMapAttrs) -> str:
220
+ indent = (
221
+ INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
222
+ )
223
+ prv, nxt = prev_next_var(node)
224
+ return indent + f"{nxt} = list({prv}.attributes.values())"
225
+
226
+
227
+ @CONVERTER(ExprMapAttrsAll.kind)
228
+ def pre_map_attrs_all(node: ExprMapAttrsAll) -> str:
229
+ indent = (
230
+ INDENT_DEFAULT_BODY if have_default_expr(node) else INDENT_METHOD_BODY
231
+ )
232
+ prv, nxt = prev_next_var(node)
233
+ return indent + f"{nxt} = [i for e in {prv} for i in e.attributes.values()]"
234
+
235
+
217
236
  # NOT SUPPORT
218
237
  @CONVERTER(ExprXpath.kind)
219
238
  def pre_xpath(_: ExprXpath) -> str:
@@ -79,6 +79,7 @@ from ssc_codegen.ast_ import (
79
79
  ExprListStringMapReplace,
80
80
  ExprStringMapReplace,
81
81
  )
82
+ from ssc_codegen.ast_.nodes_selectors import ExprMapAttrs, ExprMapAttrsAll
82
83
  from ssc_codegen.ast_.nodes_string import (
83
84
  ExprListStringUnescape,
84
85
  ExprStringUnescape,
@@ -338,6 +339,28 @@ class HTMLDocument(BaseDocument):
338
339
  self._add(ExprGetHtmlRaw())
339
340
  return self
340
341
 
342
+ def attrs_map(self) -> Self:
343
+ """extract all attributes from current tag or list of tags
344
+ - accept DOCUMENT, return LIST_STRING
345
+ - accept LIST_DOCUMENT, return LIST_STRING
346
+ """
347
+ match self.stack_last_ret:
348
+ case VariableType.DOCUMENT:
349
+ self._add(ExprMapAttrs())
350
+ case VariableType.LIST_DOCUMENT:
351
+ self._add(ExprMapAttrsAll())
352
+ case _:
353
+ LOGGER.warning(
354
+ "attrs_list(): Expected type(s) %s got %s",
355
+ (
356
+ VariableType.DOCUMENT.name,
357
+ VariableType.LIST_DOCUMENT.name,
358
+ ),
359
+ self.stack_last_ret.name,
360
+ )
361
+ self._add(ExprMapAttrs())
362
+ return self
363
+
341
364
 
342
365
  class ArrayDocument(BaseDocument):
343
366
  def first(self) -> Self:
@@ -111,6 +111,7 @@ class TokenType(IntEnum):
111
111
  EXPR_ATTR = auto()
112
112
  EXPR_TEXT = auto()
113
113
  EXPR_RAW = auto()
114
+ EXPR_MAP_ATTRS = auto()
114
115
 
115
116
  # LIST_DOCUMENT
116
117
  EXPR_CSS_ALL = auto()
@@ -118,6 +119,7 @@ class TokenType(IntEnum):
118
119
  EXPR_ATTR_ALL = auto()
119
120
  EXPR_TEXT_ALL = auto()
120
121
  EXPR_RAW_ALL = auto()
122
+ EXPR_MAP_ATTRS_ALL = auto()
121
123
 
122
124
  # STRING
123
125
  EXPR_REGEX = auto()
File without changes
File without changes
File without changes