def get_groups(self): response = self.make_request("channel_list", method="POST") is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) Kartina.raise_api_exception_on_error(response) groups = OrderedDict() for group_data in response["groups"]: if all(k in group_data for k in ("id", "name", "channels")) is False: continue channels = OrderedDict() for channel_data in group_data["channels"]: if bool(channel_data.get("is_video", 1)) is False: continue group_data["id"] = str(group_data["id"]) if self.adult is False and bool( channel_data.get("protected", False)) is True: continue channel = Channel( cid=str(channel_data["id"]), gid=group_data["id"], name=channel_data["name"], icon=self.base_icon_url % channel_data["id"], epg=True if int(channel_data.get("epg_start", 0)) > 0 else False, archive=bool(channel_data.get("have_archive", 0)), protected=bool(channel_data.get("protected", False))) channels[channel.cid] = channel groups[group_data["id"]] = Group(group_data["id"], group_data["name"], channels) return groups
def get_epg(self, cid): # type: (str) -> OrderedDict[int, Program] programs = self.get_epg_gh(self.channels[cid]) if len(programs): return programs settings = self.read_settings_file() if not settings: self.login() return self.get_epg(cid) start = int(time_now() - self.archive_ttl) end = int(time_now() + (DAY * 2)) uri = "api/api_v2.php?_resource=users/%s/tv-channels/%s/epg&from=%s&to=%s" % \ (settings.get("user_id"), cid, start, end) response = self.make_request(uri, headers=self.default_headers()) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) programs = OrderedDict() prev = None # type: Program for entry in response.get("results", []): program = Program(cid, self.channels[cid].gid, entry["start"], entry["end"], entry["name"], "", bool(entry["in_archive"])) program.data["id"] = entry["id"] if prev is not None: program.prev_program = prev prev.next_program = program programs[program.ut_start] = prev = program return programs
def get_epg(self, cid): # type: (str) -> OrderedDict[int, Program] programs = self.get_epg_gh(self.channels[cid]) if len(programs): return programs programs = OrderedDict() json_data = self.make_request("channel/%s" % cid) is_error, error = Api.is_error_response(json_data) if is_error: raise ApiException(error.get("message"), error.get("code")) response = json.loads(json_data) if not isinstance(json_data, dict) else json_data prev = None response = {int(k): v for k, v in response.items()} for k in sorted(response.iterkeys()): v = response[k] program = Program( cid, self.channels[cid].gid, v["time"], v["time_to"], v["name"], v["descr"], bool(v["rec"]) if v.has_key("rec") else self.channels[cid].archive) if prev is not None: program.prev_program = prev prev.next_program = program programs[program.ut_start] = prev = program return programs
def do_login(self, device_id=""): response = self.make_api_request( "login", [self.username, self.password, device_id]) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) Ottplayer.raise_api_exception_on_error(response["error"]) return response
def get_devices(self): # type: () -> list[dict] response = self.make_api_request("get_devices", ["unknown"], 1) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) Ottplayer.raise_api_exception_on_error(response["error"]) return response["result"]
def get_epg(self, cid): # type: (str) -> OrderedDict[int, Program] programs = self.get_epg_gh(self.channels[cid]) if len(programs): return programs requests = [] days = (self.archive_ttl / DAY) + 2 while days % 4: days += 1 start = int(time_now() - self.archive_ttl) for i in range(days): day = format_date(start + (i * DAY), custom_format="%d%m%y") request = self.prepare_request( "epg.php", self.auth_payload({ "cid": cid, "day": day })) requests.append(request) results = self.send_parallel_requests(requests, 0.40, 4) epg = dict() prev_ts = None for key in sorted(results.iterkeys()): response = results[key] is_error, error = Api.is_error_response(response) if not is_error: for entry in response["epg"]: title, descr = (HTMLParser().unescape(entry["progname"]) + "\n").split("\n", 1) ts = int(entry["ut_start"]) epg[ts] = dict({ "time": ts, "time_to": 0, "duration": 0, "name": title, "descr": descr }) if prev_ts is not None: epg[prev_ts]["time_to"] = ts prev_ts = ts else: log("error: %s" % error, xbmc.LOGDEBUG) programs = OrderedDict() prev = None # type: Program for key in sorted(epg.iterkeys()): val = epg[key] program = Program(cid, self.channels[cid].gid, val["time"], val["time_to"], val["name"], val["descr"], self.channels[cid].archive) if prev is not None: program.prev_program = prev prev.next_program = program programs[program.ut_start] = prev = program return programs
def get_stream_url(self, cid, ut_start=None): payload = {"cid": cid} if ut_start: payload["gmt"] = int(ut_start) response = self.make_request("get_url", payload) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) Kartina.raise_api_exception_on_error(response) url = response["url"] return url.replace("http/ts", "http").split()[0]
def get_random_token(self): payload = { "apiAction": "getRandomTokens", "cnt": "1", "fingerPrint": "%d" % self.device_id, "sessionId": self._session_id } response = self.make_request("", payload) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) return response.get("data").get("tokens")[0]
def register_device(self): # type: () -> str response = self.make_api_request("register_device", [self.DEVICE_TYPE, "unknown"], 2) is_error, error = Api.is_error_response(response) if is_error: raise ApiException( error.get("message", get_string(TEXT_HTTP_REQUEST_ERROR_ID)), error.get("code", Api.E_UNKNOW_ERROR)) if "error" in response and response["error"]: raise ApiException(response["error"], Api.E_API_ERROR) return response["result"]
def get_stream_url(self, cid, ut_start=None): payload = self.auth_payload({"zone_id": "1", "nohls": "0", "channel_id": cid}) response = self.make_request("translation_http.php", payload) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) self.raise_api_exception_on_error(response["error"]) url = response["source"] if ut_start is not None: url = "%s%sutc=%s&lutc=%s" % (url, "&" if "?" in url else "?", ut_start, int(time_now())) return url
def login(self): payload = { "username": self.username, "password": self.password, "typeresult": "json", "application": "xbmc", "guid": self._guid } response = self.make_request("auth.php", payload) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) self.raise_api_exception_on_error(response["error"]) self.auth_status = self.AUTH_STATUS_OK self.write_cookie_file("%s" % response["session"])
def get_groups(self): payload = self.auth_payload({ "type": "channel", }) response = self.make_request("translation_list.php", payload) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) self.raise_api_exception_on_error(response["error"]) groups = OrderedDict() channels = OrderedDict() for group_data in response.get("categories", []): if all(k in group_data for k in ("id", "name", "adult")) is False: continue gid = str(group_data["id"]) groups[gid] = Group(gid, group_data["name"], OrderedDict(), group_data["position"]) for channel_data in response.get("channels", []): gid = str(channel_data["group"]) if groups.has_key(gid) is False: continue group = groups[gid] if self.adult is False and bool(channel_data["adult"]): continue access = channel_data.get("ts_on_air", 0) and \ (channel_data.get("access_user", 0) or channel_data.get("access_free", 0)) if bool(access) is False: continue cid = str(channel_data["id"]) channel = Channel(cid=cid, gid=group.gid, name=channel_data["name"], icon=self.base_icon_url % channel_data["logo"], epg=channel_data["epg_id"] > 0, archive=bool( channel_data.get("access_archive", 0)), protected=bool(channel_data["adult"])) channel.data.update({"epg_id": channel_data["epg_id"]}) group.channels[cid] = channels[cid] = channel return groups
def login(self): passwd = hashlib.md5(self.password).hexdigest() response = self.make_request("", {"userLogin": self.username, "userPasswd": passwd}) if response.get("error") != "": raise ApiException( addon.getLocalizedString(TEXT_AUTHENTICATION_FAILED_ID), Api.E_API_ERROR ) else: is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) self._session_id = response.get("data").get("sessionId") self.auth_status = self.AUTH_STATUS_OK self._random_token = self.get_random_token() return response
def get_groups(self): if self._session_id is None: self.login() payload = { "apiAction": "getUserChannels", "resultType": "tree", "sessionId": self._session_id } response = self.make_api_request(payload) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) data = response.get("data") groups = OrderedDict() channels = OrderedDict() for group_data in data.get("userChannelsTree"): gid = group_data.get("groupId") if gid == 0: continue group = Group( gid=gid, name=group_data.get("groupName"), channels=OrderedDict(), number=int(group_data.get("sortOrder")) ) groups[gid] = group for channel_data in group_data.get("channelsList"): is_adult = bool(int(channel_data.get("isPorno"))) if self.adult is False and is_adult is True: continue cid = channel_data.get("channelId") has_epg = len(channel_data.get("curProgram").get("prTitle")) > 0 channel = Channel( cid=cid, gid=group.gid, name=channel_data.get("channelName"), icon=channel_data.get("channelLogo"), epg=has_epg, archive=has_epg, protected=is_adult ) channel.data.update({"stream_url": channel_data["liveLink"]}) group.channels[cid] = channels[cid] = channel return groups
def login(self): payload = { "login": self.username, "pass": self.password, "settings": "all" } response = self.make_request("login.php", payload=payload) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) Novoetv.raise_api_exception_on_error(response) self.auth_status = self.AUTH_STATUS_OK self.write_cookie_file("%s=%s" % (response["sid_name"], response["sid"])) self.write_settings_file(response) return response
def get_channels(self): # type: () -> list settings = self.read_settings_file() if not settings: self.login() return self.get_channels() uri = "api/api_v2.php?_resource=users/%s/tv-channels" % settings.get( "user_id") response = self.make_request(uri, headers=self.default_headers()) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) if "error" in response: raise ApiException( response.get("error_description", get_string(TEXT_SERVICE_ERROR_OCCURRED_ID)), Api.E_API_ERROR) return response.get("results")
def get_epg(self, cid): # type: (str) -> OrderedDict[int, Program] channel = self.channels[cid] programs = self.get_epg_gh(channel) if len(programs): return programs response = self.make_api_request( "get_epg2", [channel.epg_id, 2, int(self.archive_ttl / DAY)]) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) Ottplayer.raise_api_exception_on_error(response["error"]) epg = dict() for v in response["result"]: start = int( str_to_timestamp(v["start"], "%Y-%m-%d %H:%M:%S") + self._utc_local_offset) stop = int( str_to_timestamp(v["stop"], "%Y-%m-%d %H:%M:%S") + self._utc_local_offset) epg[start] = dict({ "time": start, "time_to": stop, "duration": stop - start, "name": v["title"], "descr": v["desc"] }) programs = OrderedDict() prev = None # type: Program for key in sorted(epg.iterkeys()): val = epg[key] program = Program(cid, channel.gid, val["time"], val["time_to"], val["name"], val["descr"], channel.archive) if prev is not None: if program.ut_start != prev.ut_end: continue program.prev_program = prev prev.next_program = program programs[program.ut_start] = prev = program return programs
def login(self): self._player_info = [] response = self.make_request("", { "action": "playerInfo", "ukey": self.key }) if isinstance(response, list) and len(response) and response[0].get( "response") == "No Token": raise ApiException( addon.getLocalizedString(self.TEXT_ERROR_WRONG_KEY_ID), Api.E_API_ERROR) else: is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) self._player_info = response self.auth_status = self.AUTH_STATUS_OK return response
def get_groups(self): settings = self.read_settings_file() if not settings: self.login() return self.get_groups() uri = "api/api_v2.php?_resource=users/%s/tv-genres" % settings.get( "user_id") response = self.make_request(uri, headers=self.default_headers()) is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) if "error" in response: raise ApiException( response.get("error_description", get_string(TEXT_SERVICE_ERROR_OCCURRED_ID)), Api.E_API_ERROR) groups = OrderedDict() for group_data in response.get("results"): if all(k in group_data for k in ("id", "title", "censored", "number")) is False: continue groups[str(group_data["id"])] = Group(str(group_data["id"]), group_data["title"], OrderedDict(), int(group_data["number"])) channels = self.get_channels() for channel_data in channels: if self.adult is False and bool(channel_data.get( "censored", False)) is True: continue channel = Channel(cid=str(channel_data["id"]), gid=str(channel_data["genre_id"]), name=channel_data["name"], icon=self.base_icon_url % channel_data["logo"], epg=True, archive=bool(channel_data.get("archive", 0)), protected=bool( channel_data.get("censored", False)), url=channel_data["url"]) groups[channel.gid].channels[channel.cid] = channel return groups
def get_epg(self, cid): # type: (str) -> OrderedDict[int, Program] obj = quote(json.dumps({"action": "epg", "chid": cid})) response = self.make_request("epg.php?obj=%s" % obj) # type: dict[str, list[dict]] is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) programs = OrderedDict() prev = None for v in response["res"]: program = Program(cid, self.channels[cid].gid, int(v["startTime"]), int(v["stopTime"]), v["title"], v["desc"], self.channels[cid].archive) if prev is not None: program.prev_program = prev prev.next_program = program programs[program.ut_start] = prev = program return programs
def login(self): payload = { "grant_type": "password", "username": self.username, "password": self.password } response = self.make_request("auth/token.php", payload, method="POST") is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) if "error" in response: raise ApiException( response.get("error_description", get_string(TEXT_SERVICE_ERROR_OCCURRED_ID)), Api.E_API_ERROR) self.auth_status = self.AUTH_STATUS_OK token_type = self.get_token_type(response) self.write_cookie_file( "%s %s" % (token_type, response.get("access_token", "Unknown"))) self.write_settings_file(response) return response
def get_epg(self, cid): # type: (str) -> OrderedDict[int, Program] programs = self.get_epg_gh(self.channels[cid]) if len(programs): return programs if self._session_id is None: self.login() payload = { "apiAction": "getTvProgram", "channelId": cid, "sessionId": self._session_id } response = self.make_api_request(payload) # type: dict[str, list[dict]] is_error, error = Api.is_error_response(response) if is_error: raise ApiException(error.get("message"), error.get("code")) programs = OrderedDict() prev = None for v in response.get("data").get("tvProgram"): program = Program( cid, self.channels[cid].gid, int(v.get("prStartSec")), int(v.get("prStopSec")), v.get("prTitle"), v.get("prSubTitle"), (v.get("streamLink") != "") ) program.data.update({"stream_url": v.get("streamLink")}) if prev is not None: program.prev_program = prev prev.next_program = program programs[program.ut_start] = prev = program return programs
def get_epg(self, cid): # type: (str) -> OrderedDict[int, Program] channel = self.channels[cid] if channel.epg is False or channel.epg_id == 0: return OrderedDict() requests = [] days = (self.archive_ttl / DAY) start = int(time_now() - self.archive_ttl) for i in range(days): day = format_date(start + (i * DAY), custom_format="%d-%m-%Y") payload = self.auth_payload({ "epg_id": channel.epg_id, "date": day }) request = self.prepare_request("arc_records.php", payload) requests.append(request) requests.append( self.prepare_request("translation_epg.php", self.auth_payload({"epg_id": channel.epg_id}))) results = self.send_parallel_requests(requests) epg = dict() prev_ts = None for key in sorted(results.iterkeys()): response = results[key] is_error, error = Api.is_error_response(response) if not is_error and "success" in response and response[ "success"] == 1: data = response[ "records"] if "records" in response else response[ "data"] if "data" in response else [] for entry in data: time = int(entry["time"]) if "time" in entry else int( entry["btime"]) if "btime" in entry else 0 time_to = int(entry["etime"]) if "etime" in entry else 0 epg[time] = dict({ "time": time, "time_to": time_to, "duration": 0, "name": entry["name"] }) if prev_ts is not None and epg[prev_ts]["time_to"] == 0: epg[prev_ts]["time_to"] = time prev_ts = time else: log("error: %s" % error if is_error else response, xbmc.LOGDEBUG) programs = OrderedDict() prev = None # type: Program for key in sorted(epg.iterkeys()): val = epg[key] program = Program(cid, self.channels[cid].gid, val["time"], val["time_to"], val["name"], "", self.channels[cid].archive) if prev is not None: program.prev_program = prev prev.next_program = program programs[program.ut_start] = prev = program return programs
def get_groups(self): if self.auth_status != self.AUTH_STATUS_OK: self.login() get_groups_request = self.prepare_api_request("get_groups", [], 0) get_playlists_request = self.prepare_api_request( "get_playlists", [], 0) requests = [get_groups_request, get_playlists_request] results = self.send_parallel_requests(requests) get_groups_response = results[get_groups_request.ident] is_error, error = Api.is_error_response(get_groups_response) if is_error: raise ApiException(error.get("message"), error.get("code")) Ottplayer.raise_api_exception_on_error(get_groups_response["error"]) groups = OrderedDict() number = 1 for group_data in get_groups_response["result"]: if all(k in group_data for k in ("id", "name", "title")) is False: continue gid = str(group_data["id"]) groups[gid] = Group(gid, group_data["title"], OrderedDict(), number) number += 1 get_playlists_response = results[get_playlists_request.ident] is_error, error = Api.is_error_response(get_playlists_response) if is_error: raise ApiException(error.get("message"), error.get("code")) Ottplayer.raise_api_exception_on_error(get_playlists_response["error"]) playlists = get_playlists_response.get("result") # type: list[dict] if len(playlists) == 0: raise ApiException( "%s\n%s" % (addon.getLocalizedString(self.TEXT_NO_PLAYLIST_BOUND_ID), addon.getLocalizedString(self.TEXT_YOU_CAN_BIND_DEVICE_ID)), Api.E_UNKNOW_ERROR) channels = OrderedDict() requests = [] for playlist in playlists: requests.append( self.prepare_api_request("get_channels", [playlist.get("id")], 0, playlist.get("id"))) results = self.send_parallel_requests(requests) for playlist_id, result in results.iteritems(): is_error, error = Api.is_error_response(result) if is_error: raise ApiException(error.get("message"), error.get("code")) Ottplayer.raise_api_exception_on_error(result["error"]) for channel_data in result["result"]: if self.adult is False and bool( channel_data.get("adult", False)) is True: continue playlist = next((playlist for playlist in playlists if playlist.get("id") == playlist_id), {}) cid = "%s-%s" % ( channel_data["group_id"], channel_data["id"], ) channel = Channel( cid=cid, gid=str(channel_data["group_id"]), name=channel_data["name"], icon=channel_data["pict"], epg=True if channel_data["epg_id"] > 0 else False, archive=playlist.get("have_archive", False), protected=bool(channel_data.get("adult", False)), url=channel_data["href"]) channel.data['epg_id'] = channel_data["epg_id"] groups[str(channel_data["group_id"])].channels[ channel.cid] = channels[channel.cid] = channel return groups
def get_epg(self, cid): # type: (str) -> OrderedDict[int, Program] programs = self.get_epg_gh(self.channels[cid]) if len(programs): return programs if self._open_epg_cids is None: try: url = "https://iptv.kartina.tv/api/json/open_epg?get=channels" request = self.prepare_request(url) response = self.send_parallel_requests([request])[url] is_error, error = Api.is_error_response(response) if not is_error: self._open_epg_cids = [] for entry in response["channels"]: self._open_epg_cids.append(entry["id"]) else: self._open_epg_cids = [] except: self._open_epg_cids = [] if cid not in self._open_epg_cids: return self.get_real_epg(cid) requests = [] days = (self.archive_ttl / DAY) + 2 while days % self.API_REQUESTS_NUM_THREADS: days += 1 start = int(time_now() - self.archive_ttl) for i in range(days): day = format_date(start + (i * DAY), custom_format="%d%m%y") request = self.prepare_request( "https://iptv.kartina.tv/api/json/open_epg", payload={ "period": "day", "cid": cid, "dt": day }) requests.append(request) results = self.send_parallel_requests(requests, 0.20, self.API_REQUESTS_NUM_THREADS) epg = dict() prev_ts = None for key in sorted(results.iterkeys()): response = results[key] is_error, error = Api.is_error_response(response) if not is_error: for entry in response["report"][0]["list"]: title, descr = (entry["progname"] + "\n").split("\n", 1) ts = int(entry["ts"]) epg[ts] = dict({ "time": ts, "time_to": 0, "duration": 0, "name": title, "descr": descr }) if prev_ts is not None: epg[prev_ts]["time_to"] = ts prev_ts = ts else: log("error: %s" % error, xbmc.LOGDEBUG) programs = OrderedDict() prev = None # type: Program for key in sorted(epg.iterkeys()): val = epg[key] program = Program(cid, self.channels[cid].gid, val["time"], val["time_to"], val["name"], val["descr"], self.channels[cid].archive) if prev is not None: program.prev_program = prev prev.next_program = program programs[program.ut_start] = prev = program return programs