File: models.py

package info (click to toggle)
python-directv 0.4.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 324 kB
  • sloc: python: 1,067; sh: 5; makefile: 3
file content (155 lines) | stat: -rw-r--r-- 4,559 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"""Models for DirecTV."""

from dataclasses import dataclass
from datetime import datetime, timezone
from typing import List, Optional

from .exceptions import DIRECTVError
from .utils import combine_channel_number


@dataclass(frozen=True)
class Info:
    """Object holding information from DirecTV."""

    brand: str
    receiver_id: str
    version: str

    @staticmethod
    def from_dict(data: dict):
        """Return Info object from DirecTV API response."""
        receiver_id = data.get("receiverId", "")

        return Info(
            brand="DirecTV",
            receiver_id="".join(receiver_id.split()),
            version=data.get("stbSoftwareVersion", "Unknown"),
        )


@dataclass(frozen=True)
class Location:
    """Object holding all information of receiver client location."""

    client: bool
    name: str
    address: str

    @staticmethod
    def from_dict(data: dict):
        """Return Info object from DirecTV API response."""
        address = data.get("clientAddr", "")

        return Location(
            client=address != "0",
            name=data.get("locationName", "Receiver"),
            address=address,
        )


@dataclass(frozen=True)
class Program:
    """Object holding all information of playing program."""

    channel: str
    channel_name: str
    ondemand: bool
    recorded: bool
    recording: bool
    viewed: bool
    program_id: int
    program_type: str
    duration: int
    title: str
    episode_title: str
    music_title: str
    music_album: str
    music_artist: str
    partial: bool
    payperview: bool
    position: int
    purchased: bool
    rating: str
    start_time: datetime
    unique_id: int

    @staticmethod
    def from_dict(data: dict):
        """Return Info object from DirecTV API response."""
        major = data.get("major", 0)
        minor = data.get("minor", 65535)
        episode_title = data.get("episodeTitle", None)
        music = data.get("music", {})
        music_title = music.get("title", None)
        program_type = "movie"
        if episode_title is not None:
            program_type = "tvshow"
        elif music_title is not None:
            program_type = "music"
        start_time = data.get("startTime", None)
        if start_time:
            start_time = datetime.fromtimestamp(start_time, timezone.utc)
        unique_id = data.get("uniqueId", None)

        return Program(
            channel=combine_channel_number(major, minor),
            channel_name=data.get("callsign", None),
            program_id=data.get("programId", None),
            program_type=program_type,
            duration=data.get("duration", 0),
            title=data.get("title", None),
            episode_title=episode_title,
            music_title=music_title,
            music_album=music.get("cd", None),
            music_artist=music.get("by", None),
            ondemand=data.get("isVod", False),
            partial=data.get("isPartial", False),
            payperview=data.get("isPpv", False),
            position=data.get("offset", 0),
            purchased=data.get("isPurchased", False),
            rating=data.get("rating", None),
            recorded=(unique_id is not None),
            recording=data.get("isRecording", False),
            start_time=start_time,
            unique_id=unique_id,
            viewed=data.get("isViewed", False),
        )


@dataclass(frozen=True)
class State:
    """Object holding all information of a single receiver client state."""

    authorized: bool
    available: bool
    standby: bool
    program: Optional[Program]
    at: datetime = datetime.utcnow()


class Device:
    """Object holding all information of receiver."""

    info: Info
    locations: List[Location] = []

    def __init__(self, data: dict):
        """Initialize an empty DirecTV device class."""
        # Check if all elements are in the passed dict, else raise an Error
        if any(k not in data for k in ["locations", "info"]):
            raise DIRECTVError(
                "DirecTV data is incomplete, cannot construct device object"
            )
        self.update_from_dict(data)

    def update_from_dict(self, data: dict) -> "Device":
        """Return Device object from DirecTV API response."""
        if "info" in data and data["info"]:
            self.info = Info.from_dict(data["info"])

        if "locations" in data and data["locations"]:
            locations = [Location.from_dict(location) for location in data["locations"]]
            self.locations = locations

        return self