Coverage for meta_tags_parser/snippets.py: 97%
29 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-21 00:51 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-21 00:51 +0000
1import dataclasses
2import types
3import typing
5from . import structs
6from .parse import parse_meta_tags_from_source
9def _parse_dimension(dimension_text: str) -> int:
10 cleaned_text: typing.Final[str] = dimension_text.strip()
11 if not cleaned_text:
12 return 0
13 if not cleaned_text.isascii() or not cleaned_text.isdigit():
14 return 0
15 return int(cleaned_text)
18_SNIPPET_RULES: typing.Final[
19 typing.Mapping[str, typing.Callable[[structs.SocialMediaSnippet, str], structs.SocialMediaSnippet]]
20] = types.MappingProxyType(
21 {
22 "title": lambda snippet_data, tag_value: dataclasses.replace(snippet_data, title=tag_value),
23 "description": lambda snippet_data, tag_value: dataclasses.replace(snippet_data, description=tag_value),
24 "url": lambda snippet_data, tag_value: dataclasses.replace(snippet_data, url=tag_value),
25 "image": lambda snippet_data, tag_value: dataclasses.replace(snippet_data, image=tag_value),
26 "image:width": lambda snippet_data, tag_value: dataclasses.replace(
27 snippet_data, image_width=_parse_dimension(tag_value)
28 ),
29 "image:height": lambda snippet_data, tag_value: dataclasses.replace(
30 snippet_data, image_height=_parse_dimension(tag_value)
31 ),
32 }
33)
36def _merge_snippet_tag(
37 snippet_object: structs.SocialMediaSnippet, one_meta_tag: structs.OneMetaTag
38) -> structs.SocialMediaSnippet:
39 rule: typing.Final[typing.Callable[[structs.SocialMediaSnippet, str], structs.SocialMediaSnippet] | None] = (
40 _SNIPPET_RULES.get(one_meta_tag.name)
41 )
42 if rule is None:
43 return snippet_object
44 return rule(snippet_object, one_meta_tag.value)
47def parse_snippets_from_source(source_code: str) -> structs.SnippetGroup:
48 parsed_group: typing.Final[structs.TagsGroup] = parse_meta_tags_from_source(
49 source_code, (structs.WhatToParse.OPEN_GRAPH, structs.WhatToParse.TWITTER)
50 )
51 result_group: structs.SnippetGroup = structs.SnippetGroup()
52 social_name: str
53 parsed_tags: list[structs.OneMetaTag]
54 for social_name, parsed_tags in (
55 ("twitter", parsed_group.twitter),
56 ("open_graph", parsed_group.open_graph),
57 ):
58 snippet_object: structs.SocialMediaSnippet = structs.SocialMediaSnippet()
59 one_meta_tag: structs.OneMetaTag
60 for one_meta_tag in parsed_tags:
61 snippet_object = _merge_snippet_tag(snippet_object, one_meta_tag)
62 if social_name == "twitter":
63 result_group = dataclasses.replace(result_group, twitter=snippet_object)
64 else:
65 result_group = dataclasses.replace(result_group, open_graph=snippet_object)
66 return result_group