Skip to content

Commit

Permalink
add_entry() source support. #276
Browse files Browse the repository at this point in the history
  • Loading branch information
lemon24 committed Nov 22, 2024
1 parent 3cd7daa commit 34ac5f1
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 5 deletions.
15 changes: 15 additions & 0 deletions src/reader/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ def entry_data_from_obj(obj: object) -> EntryData:
"""
if isinstance(obj, Mapping):
obj = SimpleNamespace(**obj)
source_obj = getattr(obj, 'source', None)
return EntryData(
feed_url=_getattr(obj, 'feed_url', str),
id=_getattr(obj, 'id', str),
Expand All @@ -191,6 +192,7 @@ def entry_data_from_obj(obj: object) -> EntryData:
summary=_getattr_optional(obj, 'summary', str),
content=tuple(content_from_obj(o) for o in getattr(obj, 'content', ())),
enclosures=tuple(enclosure_from_obj(o) for o in getattr(obj, 'enclosures', ())),
source=source_from_obj(source_obj) if source_obj else None,
)


Expand All @@ -214,6 +216,19 @@ def enclosure_from_obj(obj: object) -> Enclosure:
)


def source_from_obj(obj: object) -> EntrySource:
if isinstance(obj, Mapping):
obj = SimpleNamespace(**obj)
return EntrySource(
url=_getattr_optional(obj, 'url', str),
updated=_getattr_optional_datetime(obj, 'updated'),
title=_getattr_optional(obj, 'title', str),
link=_getattr_optional(obj, 'link', str),
author=_getattr_optional(obj, 'author', str),
subtitle=_getattr_optional(obj, 'subtitle', str),
)


def _getattr(obj: object, name: str, type: type[_T]) -> _T:
# will raise AttributeError implicitly
value = getattr(obj, name)
Expand Down
4 changes: 4 additions & 0 deletions src/reader/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1513,6 +1513,7 @@ def add_entry(self, entry: Any, /) -> None:
* :attr:`~Entry.summary`
* :attr:`~Entry.content`
* :attr:`~Entry.enclosures`
* :attr:`~Entry.source`
Naive datetimes are normalized by passing them to
:meth:`~datetime.datetime.astimezone`.
Expand All @@ -1532,6 +1533,9 @@ def add_entry(self, entry: Any, /) -> None:
.. versionchanged:: 3.0
The ``entry`` argument is now positional-only.
.. versionchanged:: 3.16
Allow setting :attr:`~Entry.source`.
"""

# `entry` is of type Union[EntryDataLikeProtocol, EntryDataTypedDict],
Expand Down
10 changes: 5 additions & 5 deletions tests/test__types.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,22 @@ def test_tristate_filter_argument_error(input):
assert 'name' in str(excinfo.value)


@pytest.mark.parametrize('feed_type', ['rss', 'atom'])
@pytest.mark.parametrize('data_file', ['full', 'empty'])
def test_entry_data_from_obj(data_dir, data_file):
def test_entry_data_from_obj(data_dir, feed_type, data_file):
expected = {'url_base': '', 'rel_base': ''}
exec(data_dir.joinpath(f'{data_file}.rss.py').read_bytes(), expected)
exec(data_dir.joinpath(f'{data_file}.{feed_type}.py').read_bytes(), expected)

for i, entry in enumerate(expected['entries']):
# FIXME: temporary during #276 development
entry = entry._replace(source=None)

assert entry == entry_data_from_obj(entry), i

entry_dict = entry._asdict()
if 'content' in entry_dict:
entry_dict['content'] = [c._asdict() for c in entry_dict['content']]
if 'enclosures' in entry_dict:
entry_dict['enclosures'] = [e._asdict() for e in entry_dict['enclosures']]
if entry_dict.get('source'):
entry_dict['source'] = entry_dict['source']._asdict()

assert entry == entry_data_from_obj(entry_dict), i

Expand Down

0 comments on commit 34ac5f1

Please sign in to comment.