Skip to content

Commit

Permalink
make Snippet s dataclass
Browse files Browse the repository at this point in the history
  • Loading branch information
cleder committed Nov 23, 2023
1 parent 262050a commit 2b64050
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 60 deletions.
72 changes: 21 additions & 51 deletions fastkml/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""

import logging
from dataclasses import dataclass
from typing import Any
from typing import Dict
from typing import Iterator
Expand Down Expand Up @@ -50,6 +51,12 @@
]


@dataclass(frozen=True)
class Snippet:
text: str
max_lines: Optional[int] = None


class _Feature(TimeMixin, _BaseObject):
"""
abstract element; do not create
Expand Down Expand Up @@ -95,7 +102,7 @@ class _Feature(TimeMixin, _BaseObject):
# A string value representing a telephone number.
# This element is used by Google Maps Mobile only.

_snippet: Optional[Union[str, Dict[str, Any]]]
_snippet: Optional[Snippet]
# _snippet is either a tuple of a string Snippet.text and an integer
# Snippet.maxLines or a string
#
Expand Down Expand Up @@ -163,7 +170,7 @@ def __init__(
atom_author: Optional[atom.Author] = None,
address: Optional[str] = None,
phone_number: Optional[str] = None,
snippet: Optional[Union[str, Dict[str, Any]]] = None,
snippet: Optional[Snippet] = None,
description: Optional[str] = None,
view: Optional[Union[Camera, LookAt]] = None,
times: Optional[Union[TimeSpan, TimeStamp]] = None,
Expand Down Expand Up @@ -274,46 +281,12 @@ def styles(self) -> Iterator[Union[Style, StyleMap]]:
raise TypeError

@property
def snippet(self) -> Optional[Dict[str, Any]]:
if not self._snippet:
return None
if isinstance(self._snippet, dict):
text = self._snippet.get("text")
if text:
assert isinstance(text, str)
max_lines = self._snippet.get("maxLines", None)
if max_lines is None:
return {"text": text}
elif int(max_lines) > 0:
# if maxLines <=0 ignore it
return {"text": text, "maxLines": max_lines}
return None
return None
elif isinstance(self._snippet, str):
return self._snippet
else:
msg = "Snippet must be dict of {'text':t, 'maxLines':i} or string"
raise ValueError(
msg,
)
def snippet(self) -> Optional[Snippet]:
return self._snippet

@snippet.setter
def snippet(self, snip=None) -> None:
self._snippet = {}
if isinstance(snip, dict):
self._snippet["text"] = snip.get("text")
max_lines = snip.get("maxLines")
if max_lines is not None:
self._snippet["maxLines"] = int(snip["maxLines"])
elif isinstance(snip, str):
self._snippet["text"] = snip
elif snip is None:
self._snippet = None
else:
msg = "Snippet must be dict of {'text':t, 'maxLines':i} or string"
raise ValueError(
msg,
)
def snippet(self, snippet: Optional[Snippet]) -> None:
self._snippet = snippet

@property
def address(self) -> Optional[str]:
Expand Down Expand Up @@ -357,13 +330,9 @@ def etree_element(
element.append(style.etree_element())
if self.snippet:
snippet = config.etree.SubElement(element, f"{self.ns}Snippet")
if isinstance(self.snippet, str):
snippet.text = self.snippet
else:
assert isinstance(self.snippet["text"], str)
snippet.text = self.snippet["text"]
if self.snippet.get("maxLines"):
snippet.set("maxLines", str(self.snippet["maxLines"]))
snippet.text = self.snippet.text
if self.snippet.max_lines:
snippet.set("maxLines", str(self.snippet.max_lines))
elif self._times is not None:
element.append(self._times.etree_element())
if self._atom_link is not None:
Expand Down Expand Up @@ -422,10 +391,11 @@ def from_element(self, element: Element, strict: bool = False) -> None:
)
snippet = element.find(f"{self.ns}Snippet")
if snippet is not None:
_snippet = {"text": snippet.text}
if snippet.get("maxLines"):
_snippet["maxLines"] = int(snippet.get("maxLines"))
self.snippet = _snippet
max_lines = snippet.get("maxLines")
if max_lines is not None:
self.snippet = Snippet(text=snippet.text, max_lines=int(max_lines))
else:
self.snippet = Snippet(text=snippet.text)
timespan = element.find(f"{self.ns}TimeSpan")
if timespan is not None:
self._timespan = TimeSpan.class_from_element(
Expand Down
2 changes: 1 addition & 1 deletion fastkml/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Element(Protocol):
tag: str
text: str

def set(self, tag: str, value: str) -> None:
def set(self, tag: str, value: str) -> None: # noqa: A003
"""Set the value of the tag."""

def get(self, tag: str) -> str:
Expand Down
18 changes: 10 additions & 8 deletions tests/oldunit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from fastkml import atom
from fastkml import base
from fastkml import config
from fastkml import features
from fastkml import kml
from fastkml import styles
from fastkml.enums import ColorMode
Expand Down Expand Up @@ -534,17 +535,18 @@ def test_snippet(self) -> None:

k = kml.KML()
k.from_string(doc)
assert next(iter(k.features())).snippet["text"] == "Short Desc"
assert next(iter(k.features())).snippet["maxLines"] == 2
next(iter(k.features()))._snippet["maxLines"] = 3
assert next(iter(k.features())).snippet["maxLines"] == 3
assert next(iter(k.features())).snippet.text == "Short Desc"
assert next(iter(k.features())).snippet.max_lines == 2
next(iter(k.features()))._snippet = features.Snippet(
text="Another Snippet", max_lines=3
)
assert 'maxLines="3"' in k.to_string()
next(iter(k.features())).snippet = {"text": "Annother Snippet"}
next(iter(k.features())).snippet = features.Snippet(text="Another Snippet")
assert "maxLines" not in k.to_string()
assert "Annother Snippet" in k.to_string()
next(iter(k.features())).snippet = "Diffrent Snippet"
assert "Another Snippet" in k.to_string()
next(iter(k.features())).snippet = features.Snippet("Different Snippet")
assert "maxLines" not in k.to_string()
assert "Diffrent Snippet" in k.to_string()
assert "Different Snippet" in k.to_string()

def test_from_wrong_string(self) -> None:
doc = kml.KML()
Expand Down

0 comments on commit 2b64050

Please sign in to comment.