Skip to content

Commit

Permalink
Merge pull request #28 from elupus/channellists
Browse files Browse the repository at this point in the history
Expose active channel list based on active favorites
  • Loading branch information
elupus authored Jan 23, 2023
2 parents f40827d + 50715c6 commit db3ab27
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9]
python-version: ["3.10", "3.11"]

steps:
- uses: actions/checkout@v2
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ dist
.vscode
.coverage
coverage.xml
test-results.xml
test-results.xml
venv
build
96 changes: 77 additions & 19 deletions haphilipsjs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
ChannelListType,
ChannelsCurrentType,
ChannelsType,
ChannelType,
ContextType,
FavoriteListType,
RecordingsListed,
Expand Down Expand Up @@ -186,17 +187,20 @@ def __init__(self, data):


class NoneJsonData(GeneralFailure):
"""API Returned non json data when json was expected."""
def __init__(self, data):
super().__init__(f"Non json data received: {data}")
self.data = data

"""API Returned non json data when json was expected."""


T = TypeVar("T")


class PhilipsTV(object):

channels: ChannelsType
"""All available channels, with ccid as key."""

def __init__(
self,
host=None,
Expand All @@ -218,7 +222,7 @@ def __init__(
self.sources = {}
self.source_id = None
self.audio_volume = None
self.channels: ChannelsType = {}
self.channels = {}
self.channel: Optional[Union[ActivitesTVType, ChannelsCurrentType]] = None
self.channel_lists: Dict[str, ChannelListType] = {}
self.favorite_lists: Dict[str, FavoriteListType] = {}
Expand Down Expand Up @@ -456,6 +460,44 @@ def channel_id(self):
return r["id"][pos + 1 :]
return r["id"]

@property
def channel_list_id(self) -> str:
if self.api_version >= 5:
if not self.channel:
return "all"
r = cast(ActivitesTVType, self.channel)
channel_list = r.get("channelList")
if not channel_list:
return "all"
return channel_list.get("id", "all")

return "all"

@property
def channels_current(self) -> List[ChannelType]:
"""All channels in the current favorite list."""
if self.api_version >= 5:
favorite_list = self.favorite_lists.get(self.channel_list_id)
if not favorite_list:
return list(self.channels.values())

return [
{
**channel,
"preset": favorite.get("preset", "")
}
for favorite in favorite_list.get("channels", [])
if (channel := self.channels.get(str(favorite.get("ccid"))))
]
else:
return [
{
**channel,
"ccid": key
}
for key, channel in self.channels.items()
]

@property
def ambilight_modes(self):
modes = ["internal", "manual", "expert"]
Expand Down Expand Up @@ -724,13 +766,10 @@ async def getAudiodata(self):
async def getChannels(self):
if self.api_version >= 5:
self.channels = {}
for list_id in self.channel_lists:
r = await self.getChannelList(list_id)
if r:
for channel in r:
if "ccid" in channel:
self.channels[str(channel["ccid"])] = channel
return r
for channel_list in self.channel_lists.values():
for channel in channel_list.get("Channel", []):
self.channels[str(channel.get("ccid"))] = channel
return self.channels
else:
r = cast(Optional[ChannelsType], await self.getReq("channels"))
if r:
Expand Down Expand Up @@ -775,15 +814,15 @@ async def getContext(self) -> Optional[ContextType]:
self.context = r
return r

async def setChannel(self, ccid, list_id: str = "alltv"):
async def setChannel(self, ccid: Union[str, int], list_id: Optional[str] = None):
channel: Union[ActivitesTVType, ChannelsCurrentType]
if self.api_version >= 5:
channel = {"channelList": {"id": list_id}, "channel": {"ccid": ccid}}
channel = {"channelList": {"id": list_id or "all"}, "channel": {"ccid": int(ccid)}}
if await self.postReq("activities/tv", cast(Dict, channel)) is not None:
self.channel = channel
return True
else:
channel = {"id": ccid}
channel = {"id": str(ccid)}
if await self.postReq("channels/current", cast(Dict, channel)) is not None:
self.channel = channel
return True
Expand All @@ -793,15 +832,34 @@ async def getChannelLists(self):
if self.api_version >= 5:
r = cast(ChannelDbTv, await self.getReq("channeldb/tv"))
if r:
self.channel_lists = {
data["id"]: data for data in r.get("channelLists", {})
}
self.favorite_lists = {
data["id"]: data for data in r.get("favoriteLists", {})
}
channel_lists = {}
favorite_lists = {}

for data in r.get("channelLists", []):
list_id = data["id"]
channel_list = cast(
Optional[ChannelListType],
await self.getReq(f"channeldb/tv/channelLists/{list_id}"),
)
if channel_list:
channel_lists[list_id] = channel_list


for data in r.get("favoriteLists", []):
list_id = data["id"]
favorite_list = cast(
Optional[FavoriteListType],
await self.getReq(f"channeldb/tv/favoriteLists/{list_id}"),
)
if favorite_list:
favorite_lists[list_id] = favorite_list

self.channel_lists = channel_lists
self.favorite_lists = favorite_lists
else:
self.channel_lists = {}
self.favorite_lists = {}

return r

async def getFavoriteList(self, list_id: str):
Expand Down
7 changes: 6 additions & 1 deletion haphilipsjs/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import json
import sys

from setuptools import find_namespace_packages
from . import PhilipsTV
import asyncio
from ast import literal_eval
Expand Down Expand Up @@ -52,6 +51,12 @@ def get_application_name():
stdscr.addstr(3, 45, tv.context.get("level3", ""))
stdscr.addstr(4, 45, tv.context.get("data", ""))


stdscr.addstr(0, 70, "Channels")
for idx, channel in enumerate(tv.channels_current):
stdscr.addstr(1+idx, 70, channel.get("name", channel.get("ccid")))


def print_pixels(side, offset_y, offset_x):
stdscr.addstr(offset_y, offset_x, "{}".format(side))
stdscr.addstr(offset_y + 1, offset_x, "-----------")
Expand Down
68 changes: 60 additions & 8 deletions haphilipsjs/data/v6.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,34 +322,78 @@
}
}

ACTIVITIES_TV: ActivitesTVType = {"channel": {"ccid": 1648}}
ACTIVITIES_TV_ANDROID: ActivitesTVType = {
"channel": {"ccid": 1648},
"channelList": {
"id": "1",
"version": "10"
}
}

ACTIVITIES_TV_SAPHI: ActivitesTVType = {
"channel": {"ccid": 1648},
}

ACTIVITIES_TV = {
"android": ACTIVITIES_TV_ANDROID,
"saphi": ACTIVITIES_TV_SAPHI
}

CHANNELDB_TV_CHANNELLISTS_ALL: ChannelListType = {
"id": "all",
"version": 10,
"listType": "MixedSources",
"medium": "mixed",
"active": True,
"virtual": True,
"modifiable": False,
"Channel": [
{"ccid": 1648, "preset": "1", "name": "Irdeto scrambled"},
{"ccid": 1649, "preset": "2"},
],
}


CHANNELDB_TV_FAVORITELISTS_ALLTER: FavoriteListType = {
"id": "allter",
"version": 10,
"listType": "MixedSources",
"medium": "mixed",
"channels": [
{"ccid": 1648, "preset": "1"},
{"ccid": 1649, "preset": "2"},
],
}


CHANNELDB_TV_FAVORITELISTS_1: FavoriteListType = {
"id": "1",
"version": 10,
"listType": "MixedSources",
"medium": "mixed",
"channels": [
{"ccid": 1649, "preset": "1"},
],
}

CHANNELDB_TV_ANDROID: ChannelDbTv = {
"channelLists": [CHANNELDB_TV_CHANNELLISTS_ALL],
"channelLists": [ {
"id": "all",
"version": 10,
"listType": "MixedSources",
"medium": "mixed",
"active": True,
"virtual": True,
"modifiable": False,
}
],
"favoriteLists": [
{
"id": "com.google.android.videos%2F.tv.usecase.tvinput.playback.TvInputService",
"id": "allter",
"version": 1545826184134,
"parentId": "all",
"listType": "MixedSources",
"medium": "mixed",
"virtual": False,
"modifiable": False,
"name": "Google Play Movies & TV",
"name": "All teresterial",
},
{
"id": "1",
Expand All @@ -366,7 +410,15 @@


CHANNELDB_TV_SAPHI: ChannelDbTv = {
"channelLists": [CHANNELDB_TV_CHANNELLISTS_ALL],
"channelLists": [{
"id": "all",
"version": 10,
"listType": "MixedSources",
"medium": "mixed",
"active": True,
"virtual": True,
"modifiable": False,
}],
}


Expand Down
44 changes: 33 additions & 11 deletions haphilipsjs/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ActivitiesChannelType(TypedDict, total=False):

class ActivitiesChannelListType(TypedDict, total=False):
id: str
version: str
version: Union[int, str]


class ActivitesTVType(TypedDict, total=False):
Expand Down Expand Up @@ -51,46 +51,68 @@ class ApplicationsType(TypedDict):
applications: List[ApplicationType]


class FavoriteChannelType(TypedDict):
class FavoriteChannelType(TypedDict, total=False):
ccid: int
preset: str


class FavoriteListType(TypedDict, total=False):
id: str
version: Union[int, str]
parentId: str
listType: str
medium: str
virtual: bool
modifiable: bool
name: str
channels: List[FavoriteChannelType]


class ChannelType(TypedDict, total=False):
ccid: int
ccid: Union[int, str]
preset: str
name: str
onid: int
tsid: int
sid: int
serviceType: str
type: str
logoVersion: Union[int, str]


class ChannelListType(TypedDict, total=False):
id: str
version: Union[int, str]
listType: str
medium: str
active: bool
virtual: bool
modifiable: bool
operator: str
installCountry: str
Channel: List[ChannelType]


ChannelsType = Dict[str, ChannelType]


class ChannelDbTvListBase(TypedDict):
id: str
version: Union[int, str]
listType: str


class ChannelDbTvList(ChannelDbTvListBase, total=False):
medium: str
active: bool
virtual: bool
modifiable: bool

class ChannelDbTvListFavorite(ChannelDbTvListBase, total=False):
medium: str
active: bool
virtual: bool
modifiable: bool
parentId: str
name: str

class ChannelDbTv(TypedDict, total=False):
channelLists: List[ChannelListType]
favoriteLists: List[FavoriteListType]
channelLists: List[ChannelDbTvList]
favoriteLists: List[ChannelDbTvListFavorite]


class JsonFeaturesType(TypedDict, total=False):
Expand Down
Loading

0 comments on commit db3ab27

Please sign in to comment.