Skip to content

Commit

Permalink
feat: Add iTunes Store Identifier to metadata
Browse files Browse the repository at this point in the history
- Added `iTunesStoreIdentifier` to `FeatureName` in `pyatv/const.py`.
- Updated `Playing` class in `pyatv/interface.py` to include `itunes_store_identifier`.
- Enhanced the `metadata_field` function in `pyatv/protocols/mrp/__init__.py` to support `itunes_store_identifier`.
- Adjusted fake device implementation in `tests/fake_device/mrp.py` to handle `itunes_store_identifier`.
- Updated functional tests in `tests/protocols/mrp/test_mrp_functional.py` to verify `itunes_store_identifier`.
- Modified documentation to include `itunes_store_identifier`.
  • Loading branch information
JarekToro authored and postlund committed Nov 2, 2024
1 parent 0f35403 commit 5f0515e
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 31 deletions.
13 changes: 9 additions & 4 deletions docs/api/pyatv.const.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ <h4><code><a title="pyatv.const.DeviceState" href="#pyatv.const.DeviceState">Dev
</li>
<li>
<h4><code><a title="pyatv.const.FeatureName" href="#pyatv.const.FeatureName">FeatureName</a></code></h4>
<ul class="two-column">
<ul class="">
<li><code><a title="pyatv.const.FeatureName.AccountList" href="#pyatv.const.FeatureName.AccountList">AccountList</a></code></li>
<li><code><a title="pyatv.const.FeatureName.Action" href="#pyatv.const.FeatureName.Action">Action</a></code></li>
<li><code><a title="pyatv.const.FeatureName.AddOutputDevices" href="#pyatv.const.FeatureName.AddOutputDevices">AddOutputDevices</a></code></li>
Expand Down Expand Up @@ -114,6 +114,7 @@ <h4><code><a title="pyatv.const.FeatureName" href="#pyatv.const.FeatureName">Fea
<li><code><a title="pyatv.const.FeatureName.VolumeDown" href="#pyatv.const.FeatureName.VolumeDown">VolumeDown</a></code></li>
<li><code><a title="pyatv.const.FeatureName.VolumeUp" href="#pyatv.const.FeatureName.VolumeUp">VolumeUp</a></code></li>
<li><code><a title="pyatv.const.FeatureName.WakeUp" href="#pyatv.const.FeatureName.WakeUp">WakeUp</a></code></li>
<li><code><a title="pyatv.const.FeatureName.iTunesStoreIdentifier" href="#pyatv.const.FeatureName.iTunesStoreIdentifier">iTunesStoreIdentifier</a></code></li>
</ul>
</li>
<li>
Expand Down Expand Up @@ -223,7 +224,7 @@ <h1 class="title">Module <code>pyatv.const</code></h1>
</header>
<section id="section-intro">
<p>Constants used in the public API.</p>
<div class="git-link-div"><a href="https://github.com/postlund/pyatv/blob/master/pyatv/const.py#L1-L454" class="git-link">Browse git</a></div>
<div class="git-link-div"><a href="https://github.com/postlund/pyatv/blob/master/pyatv/const.py#L1-L457" class="git-link">Browse git</a></div>
</section>
<section>
</section>
Expand Down Expand Up @@ -348,7 +349,7 @@ <h3>Class variables</h3>
</code></dt>
<dd>
<section class="desc"><p>All supported features.</p></section>
<div class="git-link-div"><a href="https://github.com/postlund/pyatv/blob/master/pyatv/const.py#L249-L445" class="git-link">Browse git</a></div>
<div class="git-link-div"><a href="https://github.com/postlund/pyatv/blob/master/pyatv/const.py#L249-L448" class="git-link">Browse git</a></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>enum.Enum</li>
Expand Down Expand Up @@ -615,6 +616,10 @@ <h3>Class variables</h3>
<dd>
<section class="desc"><p>Wake up device (deprecated; use Power.turn_on).</p></section>
</dd>
<dt id="pyatv.const.FeatureName.iTunesStoreIdentifier"><code class="name">var <span class="ident">iTunesStoreIdentifier</span> = 50</code></dt>
<dd>
<section class="desc"><p>iTunes Store Identifier for Content</p></section>
</dd>
</dl>
</dd>
<dt id="pyatv.const.FeatureState"><code class="flex name class">
Expand Down Expand Up @@ -931,7 +936,7 @@ <h3>Class variables</h3>
</code></dt>
<dd>
<section class="desc"><p>Touch action constants.</p></section>
<div class="git-link-div"><a href="https://github.com/postlund/pyatv/blob/master/pyatv/const.py#L448-L454" class="git-link">Browse git</a></div>
<div class="git-link-div"><a href="https://github.com/postlund/pyatv/blob/master/pyatv/const.py#L451-L457" class="git-link">Browse git</a></div>
<h3>Ancestors</h3>
<ul class="hlist">
<li>enum.Enum</li>
Expand Down
57 changes: 31 additions & 26 deletions docs/api/pyatv.interface.html

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions pyatv/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,9 @@ class FeatureName(Enum):
ContentIdentifier = 47
"""Identifier for Content"""

iTunesStoreIdentifier = 50
"""iTunes Store Identifier for Content"""

AppList = 38
"""List of launchable apps."""

Expand Down
13 changes: 13 additions & 0 deletions pyatv/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ class Playing(ABC):
"season_number",
"episode_number",
"content_identifier",
"itunes_store_identifier",
]

def __init__( # pylint: disable=too-many-locals
Expand All @@ -494,8 +495,10 @@ def __init__( # pylint: disable=too-many-locals
season_number: Optional[int] = None,
episode_number: Optional[int] = None,
content_identifier: Optional[str] = None,
itunes_store_identifier: Optional[int] = None,
) -> None:
"""Initialize a new Playing instance."""
self._itunes_store_identifier = None
self._media_type = media_type
self._device_state = device_state
self._title = title
Expand All @@ -511,6 +514,8 @@ def __init__( # pylint: disable=too-many-locals
self._season_number = season_number
self._episode_number = episode_number
self._content_identifier = content_identifier
self._itunes_store_identifier = itunes_store_identifier

self._post_process()

def _post_process(self) -> None:
Expand Down Expand Up @@ -570,6 +575,8 @@ def __str__(self) -> str: # pylint: disable=too-many-branches
if self.shuffle is not None:
output.append(f" Shuffle: {convert.shuffle_str(self.shuffle)}")

if self._itunes_store_identifier is not None:
output.append(f"iTunes Store Identifier: {self._itunes_store_identifier}")
return "\n".join(output)

def __eq__(self, other) -> bool:
Expand Down Expand Up @@ -676,6 +683,12 @@ def content_identifier(self) -> Optional[str]:
"""Content identifier (app specific)."""
return self._content_identifier

@property # type: ignore
@feature(50, "iTunesStoreIdentifier", "iTunes Store identifier for Content")
def itunes_store_identifier(self) -> Optional[int]:
"""Itunes Store identifier."""
return self._itunes_store_identifier


class App:
"""Information about an app."""
Expand Down
6 changes: 6 additions & 0 deletions pyatv/protocols/mrp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
FeatureName.SeasonNumber: "seasonNumber",
FeatureName.EpisodeNumber: "episodeNumber",
FeatureName.ContentIdentifier: "contentIdentifier",
FeatureName.iTunesStoreIdentifier: "iTunesStoreIdentifier",
}

DELAY_BETWEEN_COMMANDS = 0.1
Expand Down Expand Up @@ -267,6 +268,10 @@ def content_identifier() -> str:
"""Content identifier."""
return state.metadata_field("contentIdentifier")

def itunes_store_identifier() -> int:
"""Itunes Store identifier."""
return state.metadata_field("iTunesStoreIdentifier")

return Playing(
media_type=media_type(),
device_state=device_state(),
Expand All @@ -283,6 +288,7 @@ def content_identifier() -> str:
season_number=season_number(),
episode_number=episode_number(),
content_identifier=content_identifier(),
itunes_store_identifier=itunes_store_identifier(),
)


Expand Down
3 changes: 3 additions & 0 deletions tests/fake_device/mrp.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ def _fill_item(item, metadata):
md.episodeNumber = metadata.episode_number
if metadata.content_identifier:
md.contentIdentifier = metadata.content_identifier
if metadata.itunes_store_identifier:
md.iTunesStoreIdentifier = metadata.itunes_store_identifier


def _set_state_message(metadata, identifier):
Expand Down Expand Up @@ -194,6 +196,7 @@ def __init__(self, **kwargs):
self.skip_time = kwargs.get("skip_time")
self.app_name = kwargs.get("app_name")
self.content_identifier = kwargs.get("content_identifier")
self.itunes_store_identifier = kwargs.get("itunes_store_identifier")


class FakeMrpState:
Expand Down
2 changes: 2 additions & 0 deletions tests/protocols/mrp/test_mrp_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ async def test_metadata_tv_playing(self):
season_number=12,
episode_number=4,
content_identifier="identifier",
itunes_store_identifier=123456789,
)

with faketime("pyatv", 0):
Expand All @@ -554,6 +555,7 @@ async def test_metadata_tv_playing(self):
self.assertEqual(playing.season_number, 12)
self.assertEqual(playing.episode_number, 4)
self.assertEqual(playing.content_identifier, "identifier")
self.assertEqual(playing.itunes_store_identifier, 123456789)

self.assertFeatures(
FeatureState.Available,
Expand Down
1 change: 1 addition & 0 deletions tests/scripts/test_atvscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ async def test_mrp_idle(scriptenv):
"season_number": None,
"episode_number": None,
"content_identifier": None,
"itunes_store_identifier": None,
},
)
assert exit_code == 0
4 changes: 3 additions & 1 deletion tests/test_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ def test_playing_basic_fields():
season_number=1245,
episode_number=2468,
content_identifier="content_id",
itunes_store_identifier=123456789,
)
)
assert "mytitle" in out
Expand All @@ -138,6 +139,7 @@ def test_playing_basic_fields():
assert "1245" in out
assert "2468" in out
assert "content_id" in out
assert "123456789" in out


@pytest.mark.parametrize(
Expand Down Expand Up @@ -197,7 +199,7 @@ def test_playing_custom_hash():
def test_playing_eq_ensure_member_count():
# Fail if a property is added or removed to interface, just as a reminder to
# update equality comparison
assert len(Playing().__dict__) == 15
assert len(Playing().__dict__) == 16


@pytest.mark.parametrize(
Expand Down

0 comments on commit 5f0515e

Please sign in to comment.