예제 #1
0
class O2TVGO:
    def __init__(self,
                 device_id,
                 username,
                 password,
                 _logs_=None,
                 scriptname=None,
                 logId="O2TVGO/IPTVSimple"):
        self.username = username
        self.password = password
        self._live_channels = {}
        self.access_token = None
        self.subscription_code = None
        self.locality = None
        self.offer = None
        self.device_id = device_id
        ######## ADDED ########
        self.channel_key = None
        self.epg_id = None
        self.forceFromTimestamp = None
        self.hoursToLoadFrom = None
        self.hoursToLoad = None
        self.logIdSuffix = "/o2tvgo.py/O2TVGO"
        self.scriptname = scriptname
        self.logId = logId
        if _logs_:
            self._logs_ = _logs_
        else:
            from logs import Logs
            self._logs_ = Logs(scriptname, logId)

    def log(self, msg):
        return self._logs_.log(msg=msg, idSuffix=self.logIdSuffix)

    def logDbg(self, msg):
        return self._logs_.logDbg(msg=msg, idSuffix=self.logIdSuffix)

    def logNtc(self, msg):
        return self._logs_.logNtc(msg=msg, idSuffix=self.logIdSuffix)

    def logWarn(self, msg):
        return self._logs_.logWarn(msg=msg, idSuffix=self.logIdSuffix)

    def logErr(self, msg):
        return self._logs_.logErr(msg=msg, idSuffix=self.logIdSuffix)

    def refresh_access_token(self):
        if not self.username or not self.password:
            raise AuthenticationError()
        headers = _COMMON_HEADERS
        headers[
            "Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8"
        data = {
            'grant_type': 'password',
            'client_id': 'tef-production-mobile',
            'client_secret': '627a4f43b2eea512702127e09c3921fc',
            'username': self.username,
            'password': self.password,
            'platform_id': '231a7d6678d00c65f6f3b2aaa699a0d0',
            'language': 'sk'
        }
        req = requests.post('https://oauth.o2tv.cz/oauth/token',
                            data=data,
                            headers=headers,
                            verify=False)
        j = req.json()
        if 'error' in j:
            error = j['error']
            if error == 'authentication-failed':
                self.logErr(j)
                raise AuthenticationError()
            else:
                self.logErr(j)
                raise Exception(error)
        self.access_token = j["access_token"]
        self.expires_in = j["expires_in"]
        return self.access_token

    def refresh_configuration(self):
        if not self.access_token:
            self.refresh_access_token()
        access_token = self.access_token
        headers = _COMMON_HEADERS
        cookies = {"access_token": access_token, "deviceId": self.device_id}
        try:
            req = requests.get(
                'http://app.o2tv.cz/sws/subscription/settings/subscription-configuration.json',
                headers=headers,
                cookies=cookies)
        except Exception as e:
            self.logErr("Exception was thrown in requests.get(): " + str(e))
            raise RequestError()
        j = req.json()
        if 'errorMessage' in j:
            errorMessage = j['errorMessage']
            statusMessage = j['statusMessage']
            if statusMessage == 'unauthorized-device':
                raise TooManyDevicesError()
            else:
                self.logErr(j)
                raise Exception(errorMessage)
        self.subscription_code = self._logs_._toString(j["subscription"])
        self.offer = j["billingParams"]["offers"]
        self.tariff = j["billingParams"]["tariff"]
        self.locality = j["locality"]

    def live_channels(self):
        if not self.access_token:
            self.refresh_access_token()
        access_token = self.access_token
        if not self.offer:
            self.refresh_configuration()
        offer = self.offer
        if not self.tariff:
            self.refresh_configuration()
        tariff = self.tariff
        if not self.locality:
            self.refresh_configuration()
        locality = self.locality
        if len(self._live_channels) == 0:
            headers = _COMMON_HEADERS
            cookies = {
                "access_token": access_token,
                "deviceId": self.device_id
            }
            params = {
                "locality": locality,
                "tariff": tariff,
                "isp": "3",
                "language": "slo",
                "deviceType": "MOBILE",
                "liveTvStreamingProtocol": "HLS",
                "offer": offer
            }
            try:
                req = requests.get(
                    'http://app.o2tv.cz/sws/server/tv/channels.json',
                    params=params,
                    headers=headers,
                    cookies=cookies)
            except Exception as e:
                self.logErr("Exception was thrown in requests.get(): " +
                            str(e))
                raise RequestError()
            j = req.json()
            if 'error' in j:
                self.logErr(j)
            purchased_channels = j['purchasedChannels']
            items = j['channels']
            for channel_id, item in items.iteritems():
                if channel_id in purchased_channels:
                    live = item['liveTvPlayable']
                    if live:
                        channel_key = self._logs_._toString(item['channelKey'])
                        logoUrl = self._logs_._toString(item['logo'])
                        if logoUrl.startswith("http://") or logoUrl.startswith(
                                "https://"):
                            logo = logoUrl
                        else:
                            logo = "http://www.o2tv.cz" + logoUrl

                        name = self._logs_._toString(item['channelName'])
                        weight = item['weight']
                        self._live_channels[channel_key] = LiveChannel(
                            self, channel_key, name, logo, weight, self._logs_,
                            self.scriptname, self.logId)
            done = False
            offset = 0
            while not done:
                headers = _COMMON_HEADERS
                params = {
                    "language": "slo",
                    "audience": "over_18",
                    "channelKey": self._live_channels.keys(),
                    "limit": 30,
                    "offset": offset
                }
                try:
                    req = requests.get(
                        'http://www.o2tv.cz/mobile/tv/channels.json',
                        params=params,
                        headers=headers)
                except Exception as e:
                    self.logErr("Exception was thrown in requests.get(): " +
                                str(e))
                    raise RequestError()
                j = req.json()
                items = j['channels']['items']
                for item in items:
                    item = item['channel']
                    channel_key = self._logs_._toString(item['channelKey'])
                    if 'logoUrl' in item.keys():
                        logoUrl = item['logoUrl']
                        if logoUrl.startswith("http://") or logoUrl.startswith(
                                "https://"):
                            logo_url = logoUrl
                        else:
                            logo_url = "http://www.o2tv.cz" + logoUrl
                        self._live_channels[channel_key].logo_url = logo_url
                offset += 30
                total_count = j['channels']['totalCount']
                if offset >= total_count:
                    done = True
        return self._live_channels

    ######## ADDED ########
    def channel_epg(self):
        if not self.access_token:
            self.refresh_access_token()
        access_token = self.access_token
        if not self.channel_key:
            return
        headers = _COMMON_HEADERS
        cookies = {"access_token": access_token, "deviceId": self.device_id}
        timestampNow = int(time.time())
        if self.forceFromTimestamp:
            fromTimestamp = int(self.forceFromTimestamp) * 1000
        else:
            if self.hoursToLoadFrom:
                secondsToLoadFrom = self.hoursToLoadFrom * 3600
            else:
                secondsToLoadFrom = 5 * 60
            fromTimestamp = (timestampNow - secondsToLoadFrom) * 1000

        if self.hoursToLoad:
            hoursToLoad = self.hoursToLoad
        else:
            hoursToLoad = 24
        toTimestamp = (timestampNow + 3600 * hoursToLoad) * 1000
        if fromTimestamp >= toTimestamp:
            self.logErr(
                "O2TVGO.channel_epg(): fromTimestamp >= toTimestamp (" +
                str(fromTimestamp) + " >= " + str(toTimestamp) + ")")
            return False
        params = {
            "language": "slo",
            "channelKey": self.channel_key,
            "fromTimestamp": fromTimestamp,
            "toTimestamp": toTimestamp
        }
        #logDbg(_toString(params))
        try:
            req = requests.get(
                'http://app.o2tv.cz/sws/server/tv/channel-programs.json',
                params=params,
                headers=headers,
                cookies=cookies)
        except Exception as e:
            self.logErr("Exception was thrown in requests.get(): " + str(e))
            raise RequestError()
        j = req.json()
        return j

    def current_programme(self):
        if not self.channel_key:
            return
        epg = self.channel_epg()
        epg[0].items()
        return epg[0]

    def epg_detail(self):
        if not self.epg_id:
            return
        if not self.access_token:
            self.refresh_access_token()
        access_token = self.access_token
        headers = _COMMON_HEADERS
        cookies = {"access_token": access_token, "deviceId": self.device_id}
        params = {"language": "slo", "epgId": self.epg_id}
        try:
            req = requests.get(
                'http://app.o2tv.cz/sws/server/tv/epg-detail.json',
                params=params,
                headers=headers,
                cookies=cookies)
        except Exception as e:
            self.logErr("Exception was thrown in requests.get(): " + str(e))
            raise RequestError()
        j = req.json()
        j.items()
        return j

    def setWatchPosition(self, epgId, watchPosition):
        #_origin=http://www.o2tv.sk
        #contentDataType=EPG
        #contentId=17322228
        #watchPosition=4650.983208

        if not self.access_token:
            self.refresh_access_token()
        access_token = self.access_token
        if not self.channel_key:
            return
        headers = _COMMON_HEADERS
        cookies = {"access_token": access_token, "deviceId": self.device_id}
        params = {
            "_origin": "http://www.o2tv.sk",
            "contentDataType": "EPG",
            "contentId": epgId,
            "watchPosition": watchPosition
        }
        try:
            req = requests.get(
                'http://app.o2tv.cz/sws/subscription/content/add-visited.json',
                params=params,
                headers=headers,
                cookies=cookies)
        except Exception as e:
            self.logErr("Exception was thrown in requests.get(): " + str(e))
            raise RequestError()
        j = req.json()
        return j
예제 #2
0
class JsonRPC:
    def __init__(self,  _logs_ = None,  scriptname="O2TVGO/IPTVSimple", logId="O2TVGO/IPTVSimple"):
        if _logs_:
            self._logs_ = _logs_
        else:
            from logs import Logs
            self._logs_ = Logs(scriptname, logId)
        self.logIdSuffix = "/jsonrpc.py/JsonRPC"
        self.scriptname = scriptname
        self.logId = logId

    def log(self, msg):
        return self._logs_.log(msg=msg, idSuffix=self.logIdSuffix)
    def logDbg(self, msg):
        return self._logs_.logDbg(msg=msg, idSuffix=self.logIdSuffix)
    def logNtc(self, msg):
        return self._logs_.logNtc(msg=msg, idSuffix=self.logIdSuffix)
    def logWarn(self, msg):
        return self._logs_.logWarn(msg=msg, idSuffix=self.logIdSuffix)
    def logErr(self, msg):
        return self._logs_.logErr(msg=msg, idSuffix=self.logIdSuffix)

    def _getAddons(self):
        payloadGetAddons = {
          "jsonrpc": "2.0",
          "id": "1",
          "method": "Addons.GetAddons",
        }
        payloadGetAddonsJson = json.dumps(payloadGetAddons)
        jsonGetAddonsResponse = xbmc.executeJSONRPC(payloadGetAddonsJson)
        if jsonGetAddonsResponse:
            try:
                responseGetAddons = json.loads(jsonGetAddonsResponse)
                if "result" in responseGetAddons and responseGetAddons["result"] and "addons" in responseGetAddons["result"] and responseGetAddons["result"]["addons"]:
                    return responseGetAddons["result"]["addons"]
                else:
                    self.logErr("Invalid response from 'Addons.GetAddonDetails': "+self._logs_._toString(responseGetAddons))
                    return False
            except:
                self.logErr("An exception was raised by 'Addons.GetAddonDetails': "+self._logs_._toString(sys.exc_info()[0]))
                return False
        else:
            self.logErr("No response from 'Addons.GetAddonDetails'")
            return False

    def _getAddonDetails(self, addonId):
        payloadGetDetails = {
          "jsonrpc": "2.0",
          "id": "1",
          "method": "Addons.GetAddonDetails",
          "params": {
            "addonid": addonId,
            "properties": ["enabled","name"]
          }
        }
        payloadGetDetailsJson = json.dumps(payloadGetDetails)
        jsonGetDetailsResponse = xbmc.executeJSONRPC(payloadGetDetailsJson)
        if jsonGetDetailsResponse:
            try:
                responseGetDetails = json.loads(jsonGetDetailsResponse)
                if "result" in responseGetDetails and responseGetDetails["result"] and "addon" in responseGetDetails["result"] and responseGetDetails["result"]["addon"] and "enabled" in responseGetDetails["result"]["addon"]:
                    return responseGetDetails["result"]["addon"]
                else:
                    self.logErr("Invalid response from 'Addons.GetAddonDetails' for "+addonId+": "+self._logs_._toString(responseGetDetails))
                    return False
            except:
                self.logErr("An exception was raised by 'Addons.GetAddonDetails' for "+addonId+": "+self._logs_._toString(sys.exc_info()[0]))
                return False
        else:
            self.logErr("No response from 'Addons.GetAddonDetails' for "+addonId)
            return False

    def _setAddonEnabled(self, addonId, enabled = True):
        if enabled:
            strAction = "enabling"
        else:
            strAction = "disabling"
        payloadSetEnabled = {
          "jsonrpc": "2.0",
          "id":"1",
          "method": "Addons.SetAddonEnabled",
          "params": {
            "addonid": addonId,
            "enabled": enabled
          }
        }
        payloadSetEnabledJson = json.dumps(payloadSetEnabled)
        jsonSetEnabledResponse = xbmc.executeJSONRPC(payloadSetEnabledJson)
        if jsonSetEnabledResponse:
            try:
                responseSetEnabled = json.loads(jsonSetEnabledResponse)
                if "result" in responseSetEnabled and self._logs_._toString(responseSetEnabled["result"]).lower() == "ok":
                    return True
                else:
                    self.logErr("Invalid response from 'Addons.SetAddonEnabled' for "+strAction+" "+addonId+": "+self._logs_._toString(responseSetEnabled))
                    if "result" in responseSetEnabled:
                        self.logNtc(self._logs_._toString(responseSetEnabled["result"]))
                    return False
            except:
                self.logErr("An exception was raised by 'Addons.SetAddonEnabled' for "+strAction+" "+addonId+": "+self._logs_._toString(sys.exc_info()[0]))
                return False
        else:
            self.logErr("No response from 'Addons.SetAddonEnabled' for "+strAction+" "+addonId)
            return False

    def _getPVRChannels(self):
        payload = {
          "jsonrpc": "2.0",
          "id":"1",
          "method": "PVR.GetChannels",
          "params": {
            "channelgroupid": "alltv"
          }
        }
        payloadJson = json.dumps(payload)
        jsonResponse = xbmc.executeJSONRPC(payloadJson)
        if jsonResponse:
            response = json.loads(jsonResponse)

        if "result" in response and "channels" in response["result"]:
            return response["result"]["channels"]
        return False

    def _switchToChannel(self, channelID):
        payload = {
          "jsonrpc": "2.0",
          "id":"1",
          "method": "Player.Open",
          "params": {
            "item":{
              "channelid": channelID
            }
          }
        }
        payloadJson = json.dumps(payload)
        jsonResponse = xbmc.executeJSONRPC(payloadJson)
        if jsonResponse:
            responseDecoded = json.loads(jsonResponse)
            if "error" in responseDecoded:
                if "message" in responseDecoded["error"]:
                    self.logErr("Could not channel ID "+str(channelID)+": "+responseDecoded["error"]["message"])
                else:
                    self.logErr("Could not play channel ID "+str(channelID))
                self.logDbg('payloadJson: '+payloadJson)
                self.logDbg('jsonResponse: '+jsonResponse)
        else:
            self.logErr("Could not channel ID "+str(channelID)+": No response from JSONRPC")
            self.logDbg('payloadJson: '+payloadJson)
            self.logDbg('jsonResponse: '+jsonResponse)
    
    def getNowPlayed(self):
        payload = {
            'jsonrpc': '2.0',
            'method': 'Player.GetItem',
            'params': {
                'playerid': 1,
                'properties': ['file', 'showtitle', 'season', 'episode']
            },
            'id': '1'
        }
        payloadJson = json.dumps(payload)
        jsonResponse = xbmc.executeJSONRPC(payloadJson)
        if jsonResponse:
            respponseDecoded = json.loads(jsonResponse)
            
        if "result" in respponseDecoded and "item" in respponseDecoded["result"]:
            return respponseDecoded["result"]["item"]
        return False