예제 #1
0
def open_page(
        plugin,
        url,
        params={
            "box_mac": ''.join(re.findall('..', '%012x' % uuid.getnode())),
            "box_user": Settings.get_string("email")
        },
        search_query=None,
        base_url=None):
    items_m3u = None
    items_et = None
    if search_query:
        params.update({"search": search_query})
    else:
        params.update({"search": None})
    if Settings.get_string("mac") != "default":
        params.update({"box_mac": Settings.get_string("mac")})
    url_constructor = urljoin_partial(base_url)
    resp = urlquick.get(url_constructor(url),
                        params=params,
                        max_age=1,
                        headers={
                            "Accept": "text/xml"
                        }).text

    if '<?xml version="1.0"' in resp:
        return open_xml_page(page=resp, base_url=base_url)
    elif '"title":' in resp:
        return open_json_page(plugin, page=resp, base_url=base_url)
    elif '#EXTINF:' in resp:
        return open_m3u_playlist(playlist=resp, base_url=base_url)
예제 #2
0
def qualityFilter(config):
    return (config.get("resolution", "hd")
            == ["4k", "hd", "sd"][Settings.get_int("resolution")]
            and config.get("video_codec", "h265") == [
                "dvh265", "h265", "vp9", "h264"
            ][Settings.get_int("video_codec")]
            and config.get("dynamic_range", "sdr")
            == ["dv", "hdr10", "sdr"][Settings.get_int("dynamic_range")]
            and config.get("audio_channel", "stereo")
            == ["stereo", "dolby51"][Settings.get_int("audio_channel")]
            and config.get("audio_codec", "aac")
            == ["ec3", "aac"][Settings.get_int("audio_codec")])
예제 #3
0
 def doLogin(self):
     with PersistentDict("userdata.pickle") as db:
         try:
             username = Settings.get_string(
                 "username",
                 "plugin.video.jiotv") or db.get("username") or Dialog(
                 ).input("Username (MobileNo / Email)")
             password = Settings.get_string(
                 "password", "plugin.video.jiotv") or db.get(
                     "password") or Dialog().input("Password")
         except RuntimeError:
             username = Dialog().input("Username (MobileNo / Email)")
             password = Dialog().input("Password")
         if username and password:
             body = {
                 "identifier":
                 username if '@' in username else "+91" + username,
                 "password": password,
                 "rememberUser": "******",
                 "upgradeAuth": "Y",
                 "returnSessionDetails": "T",
                 "deviceInfo": {
                     "consumptionDeviceName": "Jio",
                     "info": {
                         "type": "android",
                         "platform": {
                             "name": "vbox86p",
                             "version": "8.0.0"
                         },
                         "androidId": "6fcadeb7b4b10d77"
                     }
                 }
             }
             resp = urlquick.post(
                 "https://api.jio.com/v3/dip/user/unpw/verify",
                 json=body,
                 headers={
                     "x-api-key": "l7xx75e822925f184370b2e25170c5d5820a"
                 },
                 verify=False,
                 raise_for_status=False).json()
             if resp.get("ssoToken"):
                 db["data"] = resp
                 Script.notify("Login Successful",
                               "You have been logged in successfully")
             else:
                 Script.notify(
                     "Login Failed",
                     "Double check you username and password and try again")
         else:
             Script.notify("Login Required",
                           "Please login with you Jio credentials")
예제 #4
0
def m3ugen(plugin):
    channels = urlquick.get(CHANNELS_SRC).json().get("result")
    m3ustr = "#EXTM3U x-tvg-url=\"%s\"" % EPG_SRC
    for i, channel in enumerate(channels):
        lang = LANG_MAP[channel.get("channelLanguageId")]
        genre = GENRE_MAP[channel.get("channelCategoryId")]
        if not Settings.get_boolean(lang):
            continue
        group = lang + ";" + genre
        _play_url = PLAY_URL + \
            "channel_id={0}".format(channel.get("channel_id"))
        catchup = ""
        if channel.get("isCatchupAvailable"):
            catchup = ' catchup="vod" catchup-source="{0}channel_id={1}&showtime={{H}}{{M}}{{S}}&srno={{Y}}{{m}}{{d}}" catchup-days="7"'.format(
                PLAY_URL, channel.get("channel_id"))
        m3ustr += M3U_CHANNEL.format(
            tvg_id=channel.get("channel_id"),
            channel_name=channel.get("channel_name"),
            group_title=group,
            tvg_chno=int(channel.get("channel_order", i)) + 1,
            tvg_logo=IMG_CATCHUP + channel.get("logoUrl", ""),
            catchup=catchup,
            play_url=_play_url,
        )
    with open(M3U_SRC, "w+") as f:
        f.write(m3ustr.replace(u'\xa0', ' ').encode('utf-8').decode('utf-8'))
    Script.notify("JioTV", "Playlist updated. Restart to apply.")
예제 #5
0
 def fltr(x):
     fby = by.lower()[:-1]
     if fby == "genre":
         return x.get(fby) == category_id and Settings.get_boolean(
             x.get("language"))
     else:
         return x.get(fby) == category_id
예제 #6
0
def play(plugin, channel_id, showtime=None, srno=None):
    if showtime is None and Settings.get_boolean("extra"):
        with open(EXTRA_CHANNELS, "r") as f:
            extra = json.load(f)
        if extra.get(str(channel_id)):
            if extra.get(str(channel_id)).get("ext"):
                return extra.get(str(channel_id)).get("ext")
            return PLAY_EX_URL + extra.get(str(channel_id)).get("data")

    rjson = {
        "channel_id": int(channel_id),
        "stream_type": "Seek"
    }
    if showtime and srno:
        rjson["showtime"] = showtime
        rjson["srno"] = srno
        rjson["stream_type"] = "Catchup"

    resp = urlquick.post(GET_CHANNEL_URL, json=rjson).json()
    art = {}
    art["thumb"] = art["icon"] = IMG_CATCHUP + \
        resp.get("result", "").split("/")[-1].replace(".m3u8", ".jpg")
    params = getTokenParams()
    return Listitem().from_dict(**{
        "label": plugin._title,
        "art": art,
        "callback": resp.get("result", "") + "?" + urlencode(params),
        "properties": {
            "IsPlayable": True,
            "inputstream": "inputstream.adaptive",
            "inputstream.adaptive.stream_headers": "User-Agent=KAIOS",
            "inputstream.adaptive.manifest_type": "hls",
            "inputstream.adaptive.license_key": urlencode(params) + "|" + urlencode(getHeaders()) + "|R{SSM}|",
        }
    })
예제 #7
0
def show_category(plugin, category_id, by):
    resp = urlquick.get(CHANNELS_SRC).json().get("result")

    def fltr(x):
        fby = by.lower()[:-1]
        if fby == "genre":
            return GENRE_MAP[x.get("channelCategoryId")] == category_id and Settings.get_boolean(LANG_MAP[x.get("channelLanguageId")])
        else:
            return LANG_MAP[x.get("channelLanguageId")] == category_id

    for each in filter(fltr, resp):
        if each.get("channelIdForRedirect") and not Settings.get_boolean("extra"):
            continue
        litm = Listitem.from_dict(**{
            "label": each.get("channel_name"),
            "art": {
                "thumb": IMG_CATCHUP + each.get("logoUrl"),
                "icon": IMG_CATCHUP + each.get("logoUrl"),
                "fanart": IMG_CATCHUP + each.get("logoUrl"),
                "clearlogo": IMG_CATCHUP + each.get("logoUrl"),
                "clearart": IMG_CATCHUP + each.get("logoUrl"),
            },
            "callback": play,
            "params": {
                "channel_id": each.get("channel_id")
            }
        })
        if each.get("isCatchupAvailable"):
            litm.context.container(show_epg, "Catchup",
                                   0, each.get("channel_id"))
        yield litm
예제 #8
0
    def __init__(self, proxy):
        self.proxy = proxy
        p = urlparse(proxy.path)
        self.path = p.path
        self.params = parse_qs(p.query)
        play_url = self.path.endswith('master.m3u8')
        m3u8_url = self.path.endswith('.m3u8')
        ts_url = self.path.endswith('.ts')
        key_url = self.path.endswith('.key')

        self.ishls = 'packagerx' in self.path
        self.channel_name = self.path.split(
            '/')[3] if self.ishls else self.path.split('/')[2]
        self.maxq = 'maxq' in self.params and int(self.params['maxq'][0])
        self.hlsrx = '' if not self.ishls else "/"+self.path.split('/')[2]
        self.quality = qmap[Settings.get_string('quality')]

        try:
            if play_url:
                self.getMaster()
            elif m3u8_url:
                self.getM3U8()
            elif key_url:
                self.resolveKey()
            elif ts_url:
                self.resolveTS()
            else:
                Script.log("Resource not found by proxy", lvl=Script.INFO)
                self.proxy.send_error(404, "Not Found")
        except Exception, e:
            Script.log(e, lvl=Script.INFO)
            if(self.proxy):
                self.proxy.send_error(500, "Internal Server Error")
                self.proxy.wfile.write(str(e).encode("utf-8"))
예제 #9
0
 def fltr(x):
     fby = by.lower()[:-1]
     if fby == "genre":
         return GENRE_MAP[x.get(
             "channelCategoryId")] == category_id and Settings.get_boolean(
                 LANG_MAP[x.get("channelLanguageId")])
     else:
         return LANG_MAP[x.get("channelLanguageId")] == category_id
예제 #10
0
 def doLogin(self):
     try:
         username = Settings.get_string(
             "username", "plugin.video.jiotvx") or Dialog().input(
                 "Username (MobileNo / Email)")
         password = Settings.get_string(
             "password",
             "plugin.video.jiotvx") or Dialog().input("Password")
     except RuntimeError:
         username = Dialog().input("Username (MobileNo / Email)")
         password = Dialog().input("Password")
     if username and password:
         body = {
             "identifier":
             username if "@" in username else "+91" + username,
             "password": password,
             "rememberUser": "******",
             "upgradeAuth": "Y",
             "returnSessionDetails": "T",
             "deviceInfo": {
                 "consumptionDeviceName": "unknown sdk_google_atv_x86",
                 "info": {
                     "type": "android",
                     "platform": {
                         "name": "generic_x86",
                         "version": "8.1.0"
                     },
                     "androidId": str(uuid4())
                 }
             }
         }
         resp = self.post(
             "https://api.jio.com/v3/dip/user/unpw/verify",
             json=body,
             headers={"x-api-key": "l7xx75e822925f184370b2e25170c5d5820a"})
         if resp.get("ssoToken"):
             with PersistentDict("userdata.pickle") as db:
                 db["data"] = resp
         else:
             Script.notify(
                 "Login Failed",
                 "Double check you username and password and try again")
     else:
         Script.notify("Login Required",
                       "Please login with you Jio credentials")
예제 #11
0
def m3ugen(plugin):
    channels = urlquick.get(CHANNELS_SRC).json().get("result")
    m3ustr = "#EXTM3U x-tvg-url=\"%s\"\n" % EPG_SRC
    for i, channel in enumerate(channels):
        lang = LANG_MAP[channel.get("channelLanguageId")]
        genre = GENRE_MAP[channel.get("channelCategoryId")]
        if not Settings.get_boolean(lang) and Settings.get_boolean("uselang"):
            continue
        group = lang + ";" + genre
        _play_url = PLAY_URL + \
            hexlify(dumps({"channel_id": channel.get("channel_id")}))
        m3ustr += "\n\n#EXTINF:0 tvg-id=\"%d\" tvg-name=\"%s\" group-title=\"%s\" tvg-chno=\"%d\" tvg-logo=\"%s\",%s\n%s" % (
            channel.get("channel_id"), channel.get("channel_name"), group,
            int(channel.get("channel_order", i)) + 1, IMG_CATCHUP +
            channel.get("logoUrl", ""), channel.get("channel_name"), _play_url)
    with open(M3U_SRC, "w+") as f:
        f.write(m3ustr.replace(u'\xa0', ' ').encode('utf-8'))
    Script.notify("JioTV", "Playlist updated. Restart to apply.")
예제 #12
0
def serveForever(handler):
    try:
        handler.serve_forever()
    except Exception as e:
        Script.log(e, lvl=Script.DEBUG)
        pass


ThreadingTCPServer.allow_reuse_address = True
_PORT = 48996
handler = ThreadingTCPServer(("", _PORT), proxy.JioTVProxy)
t = threading.Thread(target=serveForever, args=(handler, ))
t.setDaemon(True)
t.start()

if not Settings.get_boolean("popup"):
    xbmcgui.Dialog().ok(
        "JioTV Notification",
        "Now you can create your custom playlist from BotAllen Dashboard. [CR]Find out more at [B]https://botallen.com/#dashboard[/B] [CR][CR]If you like this add-on then consider donating from [B]https://botallen.com/#donate[/B] [CR][CR]Github: [B]https://github.com/botallen/repository.botallen[/B] [CR]Discord: [B]https://botallen.com/discord[/B] [CR][CR][I]You can disable this popup from settings[/I]"
    )

if Settings.get_boolean("m3ugen"):
    executebuiltin(
        "RunPlugin(plugin://plugin.video.jiotv/resources/lib/main/m3ugen/?notify=no)"
    )

monitor = Monitor()
while not monitor.abortRequested():
    if monitor.waitForAbort(10):
        handler.shutdown()
        handler.server_close()
예제 #13
0
import SocketServer
import threading
from xbmc import Monitor
from kodi_six import xbmcgui


def serveForever(handler):
    try:
        handler.serve_forever()
    except Exception as e:
        Script.log(e, lvl=Script.DEBUG)
        pass


SocketServer.ThreadingTCPServer.allow_reuse_address = True
_PORT = 48996
handler = SocketServer.ThreadingTCPServer(("", _PORT), proxy.JioTVProxy)
t = threading.Thread(target=serveForever, args=(handler,))
t.setDaemon(True)
t.start()

if not Settings.get_boolean("popup"):
    xbmcgui.Dialog().ok("JioTV Notification", "Now you can create your custom playlist from BotAllen Dashboard. [CR]Find out more at [B]https://botallen.com/#dashboard[/B] [CR][CR]If you like this add-on then consider donating from [B]https://botallen.com/#donate[/B] [CR][CR]Github: [B]https://github.com/botallen/repository.botallen[/B] [CR]Discord: [B]https://botallen.com/discord[/B] [CR][CR][I]You can disable this popup from settings[/I]")

monitor = Monitor()
while not monitor.abortRequested():
    if monitor.waitForAbort(10):
        handler.shutdown()
        handler.server_close()
        break
예제 #14
0
def login(plugin):
    username = Settings.get_string("username") or keyboard(
        "Username (MobileNo / Email)")
    password = Settings.get_string("password") or keyboard("Password",
                                                           hidden=True)
    ULogin(username, password)
예제 #15
0
 def _findPlayback(playBackSets, lang=None, ask=False):
     selected = None
     index = -1
     options = []
     quality = {"4k": 0, "hd": 1, "sd": 2}
     for each in playBackSets:
         config = {
             k: v
             for d in map(lambda x: dict([x.split(":")]),
                          each.get("tagsCombination", "a:b").split(";"))
             for k, v in d.items()
         }
         Script.log(f"Checking combination {config} with language {lang}",
                    lvl=Script.DEBUG)
         if config.get("encryption",
                       "") in ["plain", "widevine"] and config.get(
                           "package", "") in ["hls", "dash"]:
             if lang and config.get("language") and config.get(
                     "language", "") != lang:
                 continue
             config["playback"] = (each.get("playbackUrl"),
                                   each.get("licenceUrl"),
                                   "mpd" if config.get("package") == "dash"
                                   else "hls")
             if selected is None:
                 selected = config["playback"]
             if config.get("ladder"):
                 del config["ladder"]
             if config not in options:
                 options.append(config)
     options.sort(
         key=lambda x: str(quality.get(x.get("resolution", "sd")) or ""))
     if len(options) > 0:
         if Settings.get_string("playback_select") == "Ask" or ask:
             index = Dialog().select(
                 "Playback Quality",
                 list(
                     map(
                         lambda x:
                         "Video: {0} - {1} - {2} - {3} | Audio: {4} - {5} | {6}"
                         .format(
                             x.get("resolution", "").upper(),
                             x.get("dynamic_range", "").upper(),
                             x.get("video_codec", "").upper(),
                             x.get("container", "").upper(),
                             x.get("audio_channel", "").upper(),
                             x.get("audio_codec", "").upper(), "Non-DRM"
                             if x.get("encryption", "plain") == "plain" else
                             "DRM"), options)))
             if index == -1:
                 return (None, None, None)
         else:
             options = list(filter(qualityFilter, options))
             if len(options) > 0:
                 index = 0
     if len(options) > 0:
         Script.log("Selected Config {0}".format(options[index]))
         selected = options[index].get("playback")
     if selected is None:
         selected = (playBackSets[0].get("playbackUrl"),
                     playBackSets[0].get("licenceUrl"), "hls" if ".m3u8"
                     in playBackSets[0].get("playbackUrl") else "mpd")
         Script.log("No stream found for desired config. Using %s" %
                    playBackSets[0].get("playbackUrl"),
                    lvl=Script.INFO)
     return selected