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.
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/PKG-INFO +1 -1
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/pyproject.toml +1 -1
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/__init__.py +1 -1
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/__init__.py +1 -1
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_selectors.py +14 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/go_goquery.py +1 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/js_pure.py +16 -8
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/py_bs4.py +25 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/py_parsel.py +19 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/py_selectolax.py +19 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/document.py +23 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/tokens.py +2 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/.gitignore +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/LICENSE +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/README.md +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/_compat.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/base.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_array.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_cast.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_core.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_filter.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_string.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_/nodes_validate.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_build/__init__.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_build/main.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_build/utils.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_grep_rules/js_rules.yml +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/ast_grep_rules/py_rules.yml +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/__init__.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/ast_grep.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/cli_callbacks.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/cli_utils.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/code_callbacks.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/consts.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/main.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/cli/runtime_parse_runners.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/compiler.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/consts.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/__init__.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/base.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/helpers.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/py_base.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/templates/__init__.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/templates/go_goquery.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/converters/templates/js_pure.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/document_utlis.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/json_struct.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/json_to_scc.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/logs.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/pseudo_selectors.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/schema.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/selector_utils.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/static_checker/__init__.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/static_checker/base.py +0 -0
- {ssc_codegen-0.9.6 → ssc_codegen-0.9.8}/ssc_codegen/static_checker/callbacks.py +0 -0
- {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.
|
|
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
|
|
@@ -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
|
|
@@ -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
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|