From 5cec50e9b5275afcf8d69d0d5e037401a4c07057 Mon Sep 17 00:00:00 2001 From: lemon24 <damian.adrian24@gmail.com> Date: Fri, 22 Oct 2021 11:38:57 +0300 Subject: [PATCH] Add Entry.source. For #239. --- src/reader/_storage.py | 11 +++++++++-- src/reader/_types.py | 5 +++++ src/reader/types.py | 10 ++++++++++ tests/test_reader.py | 6 ++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/reader/_storage.py b/src/reader/_storage.py index 1bb50fa6..bebfaec2 100644 --- a/src/reader/_storage.py +++ b/src/reader/_storage.py @@ -130,6 +130,7 @@ def create_entries(db: sqlite3.Connection, name: str = 'entries') -> None: read_modified TIMESTAMP, important INTEGER NOT NULL DEFAULT 0, important_modified TIMESTAMP, + source TEXT NOT NULL, last_updated TIMESTAMP NOT NULL, first_updated TIMESTAMP NOT NULL, first_updated_epoch TIMESTAMP NOT NULL, @@ -277,6 +278,7 @@ def update_from_33_to_34(db: sqlite3.Connection) -> None: # pragma: no cover read_modified, important, important_modified, + source, last_updated, first_updated, first_updated_epoch, @@ -300,6 +302,7 @@ def update_from_33_to_34(db: sqlite3.Connection) -> None: # pragma: no cover read_modified, important, important_modified, + 'feed', last_updated, first_updated_epoch, first_updated_epoch, @@ -925,7 +928,8 @@ def make_params() -> Iterable[Mapping[str, Any]]: feed_order, original_feed, data_hash, - data_hash_changed + data_hash_changed, + source ) VALUES ( :id, :feed_url, @@ -961,7 +965,8 @@ def make_params() -> Iterable[Mapping[str, Any]]: :feed_order, NULL, -- original_feed :data_hash, - :data_hash_changed + :data_hash_changed, + :source ); """, make_params(), @@ -1376,6 +1381,7 @@ def make_get_entries_query( entries.first_updated entries.last_updated entries.original_feed + entries.source """.split() ) .FROM("entries") @@ -1410,6 +1416,7 @@ def entry_factory(t: Tuple[Any, ...]) -> Entry: t[25], t[26], t[27] or feed.url, + t[28], feed, ) return Entry._make(entry) diff --git a/src/reader/_types.py b/src/reader/_types.py index ba2e3148..8f7b7ed4 100644 --- a/src/reader/_types.py +++ b/src/reader/_types.py @@ -22,6 +22,7 @@ from .types import Enclosure from .types import Entry from .types import EntryInput +from .types import EntrySource from .types import ExceptionInfo from .types import Feed from .types import FeedInput @@ -112,6 +113,7 @@ def as_entry(self, **kwargs: object) -> Entry: attrs.pop('hash', None) attrs.update(kwargs) attrs.setdefault('original_feed_url', feed_url) + attrs.setdefault('source', 'feed') return Entry(**attrs) @property @@ -223,6 +225,9 @@ class EntryUpdateIntent(NamedTuple): #: Same as EntryForUpdate.hash_changed. hash_changed: Optional[int] + #: Same as Entry.source. + source: EntrySource = 'feed' + @property def new(self) -> bool: """Whether the entry is new or not.""" diff --git a/src/reader/types.py b/src/reader/types.py index e6f9a9b5..87a3ff3b 100644 --- a/src/reader/types.py +++ b/src/reader/types.py @@ -186,6 +186,9 @@ def from_exception(cls: Type[_EI], exc: BaseException) -> _EI: ) +EntrySource = Literal['feed', 'user'] + + @dataclass(frozen=True) class Entry(_namedtuple_compat): @@ -294,6 +297,13 @@ def feed_url(self) -> str: # we don't check for it in __post_init__ because it's still useful # to have it None in tests. The cast is to please mypy. + #: The source of the entry. One of ``'feed'``, ``'user'``. + #: + #: Other values may be added in the future. + #: + #: .. versionadded:: 2.5 + source: EntrySource = cast(EntrySource, None) + #: The entry's feed. feed: Feed = cast(Feed, None) diff --git a/tests/test_reader.py b/tests/test_reader.py index 332af0d1..4cf2c825 100644 --- a/tests/test_reader.py +++ b/tests/test_reader.py @@ -3363,3 +3363,9 @@ def test_allow_invalid_url(make_reader, feed_root, url): assert excinfo.value.url == url reader.change_feed_url(old, url, allow_invalid_url=True) + + +@rename_argument('reader', 'reader_with_one_feed') +def test_entry_source(reader): + reader.update_feeds() + assert next(reader.get_entries()).source == 'feed'