Beispiel #1
0
 def getSetting(self, key):
     if key   == 'poster_tmdb'     : return 'w342' 
     elif key == 'poster_tmdb'     : return 'w1280'
     elif key == 'api_tmdb'        : return 'b7cf9324cbeb6f4fb811144aa9397093'    
     elif key == 'tmdb_session'    : return ''
     elif key == 'history-view'    : return 'true'       
     elif key == 'home_update'     : return 'false'
     elif key == 'deco_color'      : return 'lightcoral'
     elif key == 'deco_color'      : return 'lightcoral'
     elif key == 'ZT'              :
         if os.path.exists(GetCacheSubDir('Tsiplayer')+'zt.url'):
             f = open(GetCacheSubDir('Tsiplayer')+'zt.url', "r")
             out = f.read()
             f.close() 
             printDBG('print_url='+out.strip())
             return out.strip()
         else:
             out = 'https://www.zt-za.net/index.php'
             return out.strip()
     elif '_nbItemParPage' in key  : return '25' 
     elif '_cacheDuration' in key  : return '12' 
     elif ('search' in key) and ('_type' in key)  : return False 
     elif key.startswith('plugin_'):
         if '__init__' not in key:
             return 'true' 
     return 'false'  
Beispiel #2
0
    def __init__(self):
        TSCBaseHostClass.__init__(self, {'cookie': 'tsiplayer.cookie'})
        self.USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'
        self.MAIN_URL = '/usr/lib/enigma2/python/Plugins/Extensions/IPTVPlayer/tsiplayer/addons/vstream'
        self.MAIN_URL0 = MAIN_URL0
        self.fncs_search = fncs_search
        self.MAIN_IMP = 'from ' + self.MAIN_URL0.replace(
            '/usr/lib/enigma2/python/', '').replace('/', '.')
        self.HTTP_HEADER = {'User-Agent': self.USER_AGENT}
        self.defaultParams = {'header': self.HTTP_HEADER}
        self.getPage = self.cm.getPage
        self.MyPath = GetCacheSubDir('Tsiplayer')
        printDBG('------------ MyPath= ' + self.MyPath)
        self.path_listing = self.MyPath + 'VStream_listing'
        self.DB_path = self.MyPath + 'VStream_DB'
        if config.plugins.iptvplayer.tsi_resolver.value == 'tsiplayer':
            self.ts_up = ts_urlparser()
        else:
            self.ts_up = urlparser()

        if not os.path.exists(self.MyPath + 'tmdb'):
            os.makedirs(self.MyPath + 'tmdb')
        files = glob.glob(self.MyPath + 'tmdb/*')
        for f in files:
            os.remove(f)
Beispiel #3
0
def showSearch():
    VSlog('showSearch global0')
    oGui = cGui()
    addons = addon()
    VSlog('showSearch global1')
    oInputParameterHandler = cInputParameterHandler()
    VSlog('showSearch global2')
    sSearchText = oInputParameterHandler.getValue('searchtext')
    VSlog('showSearch global3')
    sCat = oInputParameterHandler.getValue('sCat')
    VSlog('showSearch global4')
    VSlog('sText=' + str(sSearchText))
    oHandler = cRechercheHandler()
    oHandler.setText(sSearchText)
    oHandler.setCat(sCat)
    aPlugins = oHandler.getAvailablePlugins()
    if not aPlugins:
        return True
    VSlog('aPlugins=' + str(len(aPlugins)))
    total = len(aPlugins)
    progress_ = progress().VScreate(large=True)

    # kodi 17 vire la fenetre busy qui se pose au dessus de la barre de Progress
    try:
        xbmc.executebuiltin('Dialog.Close(busydialog)')
    except:
        pass

    oGui.addText('globalSearch',
                 addons.VSlang(30081) % sSearchText, 'search.png')
    sSearchText = Quote(sSearchText)

    count = 1
    for plugin in aPlugins:
        if not os.path.exists(
                GetCacheSubDir('Tsiplayer') + 'VStream_listing.search'):
            break
        progress_.VSupdate(progress_, total, plugin['name'], True)
        if progress_.iscanceled():
            break
        oGui.addText(plugin['identifier'],
                     '%s. [COLOR olive]%s[/COLOR]' % (count, plugin['name']),
                     'sites/%s.png' % (plugin['identifier']))
        oGui.searchResults[:] = [
        ]  # vider le tableau de résultats pour les récupérer par source

        _pluginSearch(plugin, sSearchText)
        count += 1

    if not count:  # aucune source ne retourne de résultats
        oGui.addText('globalSearch')  # "Aucune information"

    progress_.VSclose(progress_)

    cGui.CONTENT = 'files'

    oGui.setEndOfDirectory()
    return True
Beispiel #4
0
def _pluginSearch(plugin, sSearchText):

    # Appeler la source en mode Recherche globale
    window(10101).setProperty('search', 'true')

    try:
        plugins = __import__(
            'Plugins.Extensions.IPTVPlayer.tsiplayer.addons.resources.sites.%s'
            % plugin['identifier'],
            fromlist=[plugin['identifier']])
        function = getattr(plugins, plugin['search'][1])
        sUrl = plugin['search'][0] + str(sSearchText)
        if os.path.exists(
                GetCacheSubDir('Tsiplayer') + 'VStream_listing.search'):
            function(sUrl)

        VSlog('Load Search: ' + str(plugin['identifier']))
    except:
        VSlog(plugin['identifier'] + ': search failed')

    window(10101).setProperty('search', 'false')
Beispiel #5
0
 def MyPath(self):
     return GetCacheSubDir('Tsiplayer')
Beispiel #6
0
    def getVideoLinks(self, videoUrl):
        printDBG("BSTO.getVideoLinks [%s]" % videoUrl)
        urlTab = []

        key = strwithmeta(videoUrl).meta.get('links_key', '')
        if key in self.cacheLinks:
            for idx in range(len(self.cacheLinks[key])):
                if self.cacheLinks[key][idx][
                        'url'] == videoUrl and not self.cacheLinks[key][idx][
                            'name'].startswith('*'):
                    self.cacheLinks[key][idx][
                        'name'] = '*' + self.cacheLinks[key][idx]['name']

        sts, data = self.getPage(videoUrl)
        if not sts:
            return []

        errorMsgTab = []

        baseUrl = self.cm.ph.getSearchGroups(
            data, '''href=['"][^'^"]*?(/out/[^'^"]+?)['"]''')[0]
        url = self.getFullUrl(baseUrl)
        prevUrl = url

        linkId = self.cm.ph.getSearchGroups(url, '''/out/([0-9]+)''')[0]
        hostUrl = BSTO.LINKS_CACHE.get(linkId, '')
        if hostUrl == '' and config.plugins.iptvplayer.bsto_linkcache.value:
            hostUrl = ReadTextFile(GetCacheSubDir('bs.to', linkId))[1]

        if hostUrl == '':
            sts, data = self.cm.getPage(prevUrl, self.defaultParams)
            if not sts:
                return []
            url = data.meta['url']

            if url == prevUrl:
                query = {}
                tmp = self.cm.ph.getDataBeetwenNodes(data, ('<form', '>'),
                                                     ('</form', '>'), False)[1]
                tmp = self.cm.ph.getAllItemsBeetwenMarkers(
                    tmp, '<input', '>', False)
                for item in tmp:
                    name = self.cm.ph.getSearchGroups(
                        item, '''name=['"]([^'^"]+?)['"]''')[0]
                    value = self.cm.ph.getSearchGroups(
                        item, '''value=['"]([^'^"]+?)['"]''')[0]
                    if name != '':
                        query[name] = value

                sitekey = self.cm.ph.getSearchGroups(
                    data, '''['"]sitekey['"]\s*?:\s*?['"]([^'^"]+?)['"]''')[0]
                if sitekey != '' and 'bitte das Captcha' in data:
                    token, errorMsgTab = self.processCaptcha(
                        sitekey, self.cm.meta['url'],
                        config.plugins.iptvplayer.bsto_bypassrecaptcha.value)
                    if token != '':
                        sts, data = self.cm.getPage(
                            url + '?t=%s&s=%s' % (token, query.get('s', '')),
                            self.defaultParams)
                        if not sts:
                            return []
                        url = data.meta['url']

            if 1 != self.up.checkHostSupport(url):
                url = baseUrl.replace('/out/', '/watch/')[1:]

                hostUrl = ''
                try:
                    sts, data = self.cm.getPage(self.getFullUrl('/api/' + url),
                                                self.getHeaders(url))
                    if not sts:
                        return []

                    data = byteify(json.loads(data))
                    printDBG(data)

                    hostUrl = data['fullurl']
                except Exception:
                    printExc()
            else:
                hostUrl = url

        if 1 != self.up.checkHostSupport(hostUrl):
            SetIPTVPlayerLastHostError('\n'.join(errorMsgTab))
        elif self.cm.isValidUrl(hostUrl):
            BSTO.LINKS_CACHE[linkId] = hostUrl
            if config.plugins.iptvplayer.bsto_linkcache.value:
                WriteTextFile(GetCacheSubDir('bs.to', linkId), hostUrl)
            urlTab = self.up.getVideoLinkExt(hostUrl)

        return urlTab
Beispiel #7
0
class cDb:
    #On chercher le profil courant.
    request = {
        "jsonrpc": "2.0",
        "method": "Profiles.GetCurrentProfile",
        "params": {
            "properties": ["thumbnail", "lockmode"]
        },
        "id": 1
    }

    req = json.dumps(request)

    #On recupere le nom.
    name = 'TSIPlayer'

    #Le cas par defaut.
    if name == 'Master user':
        from Plugins.Extensions.IPTVPlayer.tools.iptvtools import GetCacheSubDir
        DB = GetCacheSubDir('Tsiplayer') + 'vstream.db'
    else:
        from Plugins.Extensions.IPTVPlayer.tools.iptvtools import GetCacheSubDir
        DB = GetCacheSubDir('Tsiplayer') + 'vstream.db'

    try:
        REALDB = VSPath(DB).decode('utf-8')
    except AttributeError:
        REALDB = VSPath(DB)

    del request, req, name  # delete des objets temporaires

    def __init__(self):

        VSlog('DB engine for db : ' + sqlite.__name__)

        try:
            if not xbmcvfs.exists(self.DB):
                self.db = sqlite.connect(self.REALDB)
                self.db.row_factory = sqlite.Row
                self.dbcur = self.db.cursor()
                self._create_tables()
                return
        except:
            VSlog('Error: Unable to write to %s' % self.REALDB)
            pass

        try:
            self.db = sqlite.connect(self.REALDB)
            self.db.row_factory = sqlite.Row
            self.dbcur = self.db.cursor()
        except:
            VSlog('Error: Unable to access to %s' % self.REALDB)
            pass

    def __del__(self):
        ''' Cleanup db when object destroyed '''
        try:
            self.dbcur.close()
            self.db.close()
        except Exception:
            pass

    def _create_tables(self):

        # sql_create2 = 'DROP TABLE history'
        ''' Create table '''
        sql_create = "CREATE TABLE IF NOT EXISTS history ("\
                        "addon_id integer PRIMARY KEY AUTOINCREMENT, "\
                        "title TEXT, "\
                        "disp TEXT, "\
                        "icone TEXT, "\
                        "isfolder TEXT, "\
                        "level TEXT, "\
                        "lastwatched TIMESTAMP "", "\
                        "UNIQUE(title)"\
                        ");"
        self.dbcur.execute(sql_create)

        sql_create = "CREATE TABLE IF NOT EXISTS resume ("\
                        "addon_id integer PRIMARY KEY AUTOINCREMENT, "\
                        "title TEXT, "\
                        "hoster TEXT, "\
                        "point TEXT, "\
                        "UNIQUE(title, hoster)"\
                        ");"
        self.dbcur.execute(sql_create)

        sql_create = "CREATE TABLE IF NOT EXISTS watched ("\
                        "addon_id integer PRIMARY KEY AUTOINCREMENT, "\
                        "title TEXT, "\
                        "site TEXT, "\
                        "UNIQUE(title, site)"\
                        ");"
        self.dbcur.execute(sql_create)

        sql_create = "CREATE TABLE IF NOT EXISTS favorite ("\
                        "addon_id integer PRIMARY KEY AUTOINCREMENT, "\
                        "title TEXT, "\
                        "siteurl TEXT, "\
                        "site TEXT, "\
                        "fav TEXT, "\
                        "cat TEXT, "\
                        "icon TEXT, "\
                        "fanart TEXT, "\
                        "UNIQUE(title, site)"\
                        ");"
        self.dbcur.execute(sql_create)

        sql_create = "CREATE TABLE IF NOT EXISTS download ("\
                        "addon_id integer PRIMARY KEY AUTOINCREMENT, "\
                        "title TEXT, "\
                        "url TEXT, "\
                        "path TEXT, "\
                        "cat TEXT, "\
                        "icon TEXT, "\
                        "size TEXT,"\
                        "totalsize TEXT, "\
                        "status TEXT, "\
                        "UNIQUE(title, path)"\
                        ");"
        self.dbcur.execute(sql_create)

        VSlog('Table initialized')

    # Ne pas utiliser cette fonction pour les chemins
    def str_conv(self, data):
        if not isMatrix():
            if isinstance(data, str):
                # Must be encoded in UTF-8
                try:
                    data = data.decode('utf8')
                except AttributeError:
                    pass
            import unicodedata
            data = unicodedata.normalize('NFKD',
                                         data).encode('ascii', 'ignore')

            try:
                data = data.decode(
                    'string-escape'
                )  # ATTENTION: provoque des bugs pour les chemins a cause du caractere '/'
            except:
                pass

        else:
            data = data.encode().decode()

        return data

    # ***********************************
    #   History fonctions
    # ***********************************

    def insert_history(self, meta):

        # title = Unquote(meta['title']).decode('ascii', 'ignore')
        title = self.str_conv(Unquote(meta['title']))
        disp = meta['disp']
        icon = 'icon.png'

        try:
            ex = 'INSERT INTO history (title, disp, icone) VALUES (?, ?, ?)'
            self.dbcur.execute(ex, (title, disp, icon))
            self.db.commit()
            VSlog('SQL INSERT history Successfully')
        except Exception as e:
            if 'UNIQUE constraint failed' in e.message:
                ex = "UPDATE history set title = '%s', disp = '%s', icone= '%s' WHERE title = '%s'" % (
                    title, disp, icon, title)
                self.dbcur.execute(ex)
                self.db.commit()
                VSlog('SQL UPDATE history Successfully')
            VSlog('SQL ERROR INSERT, title = %s, %s' % (title, e))
            pass

    def get_history(self):
        sql_select = 'SELECT * FROM history'

        try:
            self.dbcur.execute(sql_select)
            # matchedrow = self.dbcur.fetchone()
            matchedrow = self.dbcur.fetchall()
            return matchedrow
        except Exception as e:
            VSlog('SQL ERROR EXECUTE, %s' % e)
            return None

    def del_history(self):
        from Plugins.Extensions.IPTVPlayer.tsiplayer.addons.resources.lib.gui.gui import cGui
        oGui = cGui()
        oInputParameterHandler = cInputParameterHandler()
        if oInputParameterHandler.exist('searchtext'):
            sql_delete = "DELETE FROM history WHERE title = '%s'" % (
                oInputParameterHandler.getValue('searchtext'))
        else:
            sql_delete = 'DELETE FROM history;'

        try:
            self.dbcur.execute(sql_delete)
            self.db.commit()
            dialog().VSinfo(addon().VSlang(30041))
            oGui.updateDirectory()
            return False, False
        except Exception:
            VSlog('SQL ERROR DELETE : %s' % sql_delete)
            return False, False

    # ***********************************
    #   Watched fonctions
    # ***********************************

    def insert_watched(self, meta):
        title = meta['title']
        if not title:
            return

        site = QuotePlus(meta['site'])
        ex = 'INSERT INTO watched (title, site) VALUES (?, ?)'
        try:
            self.dbcur.execute(ex, (title, site))
            self.db.commit()
            VSlog('SQL INSERT watched Successfully')
        except Exception:
            VSlog('SQL ERROR INSERT watched : title = %s, site = %s' %
                  (title, site))
            pass

    def get_watched(self, meta):
        title = meta['title']
        if not title:
            return None

        sql_select = "SELECT * FROM watched WHERE title = '%s'" % title

        try:
            self.dbcur.execute(sql_select)
            # matchedrow = self.dbcur.fetchone()
            matchedrow = self.dbcur.fetchall()

            if matchedrow:
                return 1
            return 0
        except Exception as e:
            VSlog('SQL ERROR %s' % sql_select)
            return None

    def del_watched(self, meta):
        title = meta['title']
        if not title:
            return

        sql_select = "DELETE FROM watched WHERE title = '%s'" % title
        try:
            self.dbcur.execute(sql_select)
            self.db.commit()
            return False, False
        except Exception:
            VSlog('SQL ERROR %s' % sql_select)
            return False, False

    # ***********************************
    #   Resume fonctions
    # ***********************************

    def insert_resume(self, meta):
        title = self.str_conv(meta['title'])
        site = QuotePlus(meta['site'])
        # hoster = meta['hoster']
        point = meta['point']
        ex = "DELETE FROM resume WHERE title = '%s'" % title
        try:
            self.dbcur.execute(ex)
        except Exception:
            VSlog('SQL ERROR - ' + ex)
            pass

        try:
            ex = 'INSERT INTO resume (title, hoster, point) VALUES (?, ?, ?)'
            self.dbcur.execute(ex, (title, site, point))
            self.db.commit()
        except Exception:
            VSlog('SQL ERROR INSERT resume, title = %s' % title)
            pass

    def get_resume(self, meta):
        title = self.str_conv(meta['title'])
        # site = QuotePlus(meta['site'])

        sql_select = "SELECT point FROM resume WHERE title = '%s'" % title
        # sql_select = "SELECT * FROM resume WHERE hoster = '%s'" % site

        try:
            self.dbcur.execute(sql_select)
            matchedrow = self.dbcur.fetchone()
            # matchedrow = self.dbcur.fetchall()
            if not matchedrow:
                return 0
            return float(matchedrow[0])

        except Exception as e:
            VSlog('SQL ERROR : %s' % sql_select)
            return None

    def del_resume(self, meta):
        title = QuotePlus(meta['title'])

        sql_select = "DELETE FROM resume WHERE title = '%s'" % title

        try:
            self.dbcur.execute(sql_select)
            self.db.commit()
            return False, False
        except Exception:
            VSlog('SQL ERROR %s' % sql_select)
            return False, False

    # ***********************************
    #   Bookmark fonctions
    # ***********************************

    def insert_bookmark(self, meta):

        title = self.str_conv(meta['title'])
        siteurl = QuotePlus(meta['siteurl'])

        try:
            sIcon = meta['icon'].decode('UTF-8')
        except:
            sIcon = meta['icon']

        try:
            ex = 'INSERT INTO favorite (title, siteurl, site, fav, cat, icon, fanart) VALUES (?, ?, ?, ?, ?, ?, ?)'
            self.dbcur.execute(ex, (title, siteurl, meta['site'], meta['fav'],
                                    meta['cat'], sIcon, meta['fanart']))

            self.db.commit()

            dialog().VSinfo(addon().VSlang(30042), meta['title'])
            VSlog('SQL INSERT favorite Successfully')
        except Exception as e:
            if 'UNIQUE constraint failed' in e.message:
                dialog().VSinfo(addon().VSlang(30043), meta['title'])
            VSlog('SQL ERROR INSERT : %s' % e)
            pass

    def get_bookmark(self):

        sql_select = 'SELECT * FROM favorite'

        try:
            self.dbcur.execute(sql_select)
            # matchedrow = self.dbcur.fetchone()
            matchedrow = self.dbcur.fetchall()
            return matchedrow
        except Exception:
            VSlog('SQL ERROR EXECUTE')
            return None

    def del_bookmark(self, sSiteUrl='', sMovieTitle='', sCat='', sAll=False):

        sql_delete = None

        # Tous supprimer
        if sAll:
            sql_delete = 'DELETE FROM favorite;'

        # Supprimer un bookmark selon son titre
        elif sMovieTitle:
            siteUrl = QuotePlus(sSiteUrl)
            title = self.str_conv(sMovieTitle)
            title = title.replace("'", r"''")
            sql_delete = "DELETE FROM favorite WHERE siteurl = '%s' AND title = '%s'" % (
                siteUrl, title)

        # Supprimer un bookmark selon son url
        elif sSiteUrl:
            siteUrl = QuotePlus(sSiteUrl)
            sql_delete = "DELETE FROM favorite WHERE siteurl = '%s'" % siteUrl

        # Supprimer toute une catégorie
        elif sCat:
            catList = ('1', '7')  # films, saga
            if sCat not in catList:
                catList = ('2', '3', '4', '8')
                if sCat not in catList:
                    catList = ('0', sCat)
            sql_delete = "DELETE FROM favorite WHERE cat in %s" % str(catList)

        if sql_delete:
            from Plugins.Extensions.IPTVPlayer.tsiplayer.addons.resources.lib.gui.gui import cGui
            try:
                self.dbcur.execute(sql_delete)
                self.db.commit()
                update = self.db.total_changes

                if not update and sSiteUrl and sMovieTitle:
                    # si pas trouvé, on essaie sans le titre, seulement l'URL
                    return self.del_bookmark(sSiteUrl)

                dialog().VSinfo(addon().VSlang(30044))
                cGui().updateDirectory()
                return True
            except Exception:
                VSlog('SQL ERROR %s' % sql_delete)
        return False

    # ***********************************
    #   Download fonctions
    # ***********************************

    def insert_download(self, meta):

        title = self.str_conv(meta['title'])
        url = QuotePlus(meta['url'])
        sIcon = QuotePlus(meta['icon'])
        sPath = meta['path']
        ex = 'INSERT INTO download (title, url, path, cat, icon, size, totalsize, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'

        try:
            self.dbcur.execute(
                ex, (title, url, sPath, meta['cat'], sIcon, '', '', 0))
            self.db.commit()
            VSlog('SQL INSERT download Successfully')
            dialog().VSinfo(addon().VSlang(30042), meta['title'])
        except Exception:
            VSlog('SQL ERROR INSERT into download')
            pass

    def get_download(self, meta=''):

        if meta == '':
            sql_select = 'SELECT * FROM download'
        else:
            url = QuotePlus(meta['url'])
            sql_select = "SELECT * FROM download WHERE url = '%s' AND status = '0'" % url

        try:
            self.dbcur.execute(sql_select)
            matchedrow = self.dbcur.fetchall()
            return matchedrow
        except Exception:
            VSlog('SQL ERROR %s' % sql_select)
            return None

    def clean_download(self):

        sql_select = "DELETE FROM download WHERE status = '2'"

        try:
            self.dbcur.execute(sql_select)
            self.db.commit()
            return False, False
        except Exception:
            VSlog('SQL ERROR %s' % sql_select)
            return False, False

    def reset_download(self, meta):

        url = QuotePlus(meta['url'])
        sql_select = "UPDATE download SET status = '0' WHERE status = '2' AND url = '%s'" % url

        try:
            self.dbcur.execute(sql_select)
            self.db.commit()
            return False, False
        except Exception:
            VSlog('SQL ERROR %s' % sql_select)
            return False, False

    def del_download(self, meta):

        if len(meta['url']) > 1:
            url = QuotePlus(meta['url'])
            sql_select = "DELETE FROM download WHERE url = '%s'" % url
        elif len(meta['path']) > 1:
            path = meta['path']
            sql_select = "DELETE FROM download WHERE path = '%s'" % path
        else:
            return

        try:
            self.dbcur.execute(sql_select)
            self.db.commit()
            return False, False
        except Exception:
            VSlog('SQL ERROR %s' % sql_select)
            return False, False

    def cancel_download(self):
        sql_select = "UPDATE download SET status = '0' WHERE status = '1'"
        try:
            self.dbcur.execute(sql_select)
            self.db.commit()
            return False, False
        except Exception:
            VSlog('SQL ERROR %s' % sql_select)
            return False, False

    def update_download(self, meta):

        path = meta['path']
        size = meta['size']
        totalsize = meta['totalsize']
        status = meta['status']

        sql_select = "UPDATE download set size = '%s', totalsize = '%s', status= '%s' WHERE path = '%s'" % (
            size, totalsize, status, path)

        try:
            self.dbcur.execute(sql_select)
            self.db.commit()
            return False, False
        except Exception:
            VSlog('SQL ERROR %s' % sql_select)
            return False, False
Beispiel #8
0
    def getVideoLinks(self, videoUrl):
        printDBG("MRPiracyGQ.getVideoLinks [%s]" % videoUrl)
        errorMsgTab = []
        urlTab = []

        # mark requested link as used one
        if len(self.cacheLinks.keys()):
            for key in self.cacheLinks:
                for idx in range(len(self.cacheLinks[key])):
                    if videoUrl in self.cacheLinks[key][idx]['url']:
                        if not self.cacheLinks[key][idx]['name'].startswith(
                                '*'):
                            self.cacheLinks[key][idx][
                                'name'] = '*' + self.cacheLinks[key][idx][
                                    'name']
                        break

        if self.cm.isValidUrl(videoUrl):
            return self.up.getVideoLinkExt(videoUrl)

        playerData = strwithmeta(videoUrl).meta
        linkId = ''
        imdbId = ''
        try:
            tmp = []
            for it in ['playertype', 'episodio', 'id']:
                tmp.append(playerData.get(it, ''))
            imdbId = self.cm.ph.getSearchGroups(playerData['ref_url'],
                                                '''imdb=(tt[0-9]+)''')[0]
            tmp.insert(0, imdbId)
            linkId = '_'.join(tmp)
        except Exception:
            printExc()

        printDBG(">>> linkId[%s]" % linkId)
        hostUrl = MRPiracyGQ.LINKS_CACHE.get(linkId, '')
        if hostUrl == '' and config.plugins.iptvplayer.mrpiracy_linkcache.value:
            hostUrl = ReadTextFile(GetCacheSubDir('mrpiracy', linkId))[1]

        if hostUrl == '':
            try:
                jscode = playerData.pop('jscode', '')
                jscode += '''var iptv_fake_element={hide:function(){},show:function(){},addClass:function(){},removeClass:function(){}};playertype="iptv_player_data";var iptv_player_data=''' + json.dumps(
                    playerData
                ) + ''';$=function(){return 1==arguments.length&&arguments[0].endsWith(playertype)?{data:function(a){return iptv_player_data[a]}}:iptv_fake_element},$.ajax=function(){print(JSON.stringify(arguments[0]))},''' + playerData[
                    'callback'] + '''(iptv_player_data.sitekey);'''
                ret = js_execute(jscode)
                data = ret['data'].strip()
                data = byteify(json.loads(data))

                url = self.getFullUrl(data['url'])
                post_data = data['data']
                urlParams = dict(self.defaultParams)
                urlParams['header'] = dict(self.AJAX_HEADER)
                urlParams['header']['Referer'] = playerData['ref_url']

                if 'sitekey' in playerData:
                    token, errorMsgTab = self.processCaptcha(
                        playerData['sitekey'], playerData['ref_url'], config.
                        plugins.iptvplayer.mrpiracy_bypassrecaptcha.value)
                    printDBG('> token "%s" ' % token)
                    post_data['token'] = token

                sts, data = self.getPage(url, urlParams, post_data)
                printDBG("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
                printDBG(data)
                printDBG("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
                tmp = re.compile('''['"](https?://[^'^"]+?)['"]''').findall(
                    data)
                for item in tmp:
                    if 1 == self.up.checkHostSupport(item):
                        hostUrl = item

                if hostUrl == '':
                    url = self.getFullUrl(
                        self.cm.ph.getSearchGroups(
                            data,
                            '<iframe[^>]+?src="([^"]+?)"',
                            1,
                            ignoreCase=True)[0])
                    if url != '':
                        urlParams = dict(self.defaultParams)
                        urlParams['header'] = dict(urlParams['header'])
                        urlParams['header']['Referer'] = playerData['ref_url']
                        sts, data = self.getPage(url, urlParams)
                        hostUrl = self.cm.ph.getSearchGroups(
                            data, '''location\.href=['"]([^'^"]+?)['"]''')[0]
            except Exception:
                printExc()

        if self.cm.isValidUrl(hostUrl):
            if linkId != '':
                if config.plugins.iptvplayer.mrpiracy_linkcache.value and linkId not in MRPiracyGQ.LINKS_CACHE:
                    WriteTextFile(GetCacheSubDir('mrpiracy', linkId), hostUrl)
                MRPiracyGQ.LINKS_CACHE[linkId] = hostUrl

            urlTab = self.up.getVideoLinkExt(hostUrl)

        if 0 == len(urlTab):
            SetIPTVPlayerLastHostError('\n'.join(errorMsgTab))
        else:
            subUrl = 'https://cdn.mrpiracy.xyz/subs/%s.srt' % imdbId
            sts, data = self.getPage(subUrl)
            if sts and '00:' in data:
                for idx in range(len(urlTab)):
                    urlTab[idx]['url'] = strwithmeta(urlTab[idx]['url'])
                    if 'external_sub_tracks' not in urlTab[idx]['url'].meta:
                        urlTab[idx]['url'].meta['external_sub_tracks'] = []
                    urlTab[idx]['url'].meta['external_sub_tracks'].append({
                        'title':
                        '',
                        'url':
                        subUrl,
                        'lang':
                        'pt',
                        'format':
                        'srt'
                    })
        return urlTab
Beispiel #9
0
 def setSetting(self, key, value):
     if key == 'ZT':
         f = open(GetCacheSubDir('Tsiplayer')+'zt.url', "w")
         f.write(value)
         f.close()
     return None
Beispiel #10
0
def VSPath(path):
    path = path.replace('special://temp/',GetCacheSubDir('Tsiplayer'))
    path = path.replace('special://home/userdata/addon_data/plugin.video.vstream/',GetCacheSubDir('Tsiplayer'))
    return path
Beispiel #11
0
class GestionCookie():
    #PathCache = 'special://userdata/addon_data/plugin.video.vstream'
    PathCache = GetCacheSubDir('Tsiplayer')[:-1]

    def MakeListwithCookies(self, c):
        t = {}
        c = c.split(';')
        for i in c:
            j = i.split('=', 1)
            if len(j) > 1:
                t[j[0]] = j[1]

        return t

    def DeleteCookie(self, Domain):
        Name = '/'.join([self.PathCache, 'cookie_%s.txt']) % (Domain)
        xbmcvfs.delete(Name)

    def SaveCookie(self, Domain, data):
        Name = '/'.join([self.PathCache, 'cookie_%s.txt']) % (Domain)

        # save it
        # file = open(Name, 'w')
        # file.write(data)
        # file.close()

        f = xbmcvfs.File(Name, 'w')
        f.write(data)
        f.close()

    def Readcookie(self, Domain):
        Name = '/'.join([self.PathCache, 'cookie_%s.txt']) % (Domain)

        # try:
        #     file = open(Name,'r')
        #     data = file.read()
        #     file.close()
        # except:
        #     return ''

        try:
            f = xbmcvfs.File(Name)
            data = f.read()
            f.close()
        except:
            return ''

        return data

    def AddCookies(self):
        cookies = self.Readcookie(self.__sHosterIdentifier)
        return 'Cookie=' + cookies

    def MixCookie(self, ancien_cookies, new_cookies):
        t1 = self.MakeListwithCookies(ancien_cookies)
        t2 = self.MakeListwithCookies(new_cookies)
        #Les nouveaux doivent ecraser les anciens
        for i in t2:
            t1[i] = t2[i]

        cookies = ''
        for c in t1:
            cookies = cookies + c + '=' + t1[c] + ';'
        cookies = cookies[:-1]
        return cookies
Beispiel #12
0
class cTMDb:

    # https://developers.themoviedb.org/3/genres/get-movie-list
    # https://developers.themoviedb.org/3/genres/get-tv-list
    TMDB_GENRES = {
        12: 'Aventure',
        14: 'Fantastique',
        16: 'Animation',
        18: 'Drame',
        27: 'Horreur',
        28: 'Action',
        35: 'Comédie',
        36: 'Histoire',
        37: 'Western',
        53: 'Thriller',
        80: 'Crime',
        99: 'Documentaire',
        878: 'Science-Fiction',
        9648: 'Mystère',
        10402: 'Musique',
        10749: 'Romance',
        10751: 'Familial',
        10752: 'Guerre',
        10759: 'Action & Aventure',
        10762: 'Kids',
        10763: 'News',
        10764: 'Realité',
        10765: 'Science-Fiction & Fantastique',
        10766: 'Feuilleton',
        10767: 'Talk',
        10768: 'Guerre & Politique',
        10769: 'Etranger',
        10770: 'Téléfilm'
    }

    URL = 'https://api.themoviedb.org/3/'
    URL_TRAILER = 'plugin://plugin.video.youtube/play/?video_id=%s'  # ancien : 'plugin://plugin.video.youtube/?action=play_video&videoid=%s'
    from Plugins.Extensions.IPTVPlayer.tools.iptvtools import GetCacheSubDir
    CACHE = GetCacheSubDir('Tsiplayer') + 'video_cache.db'

    # important seul xbmcvfs peux lire le special
    if not isMatrix():
        REALCACHE = VSPath(CACHE).decode('utf-8')
    else:
        REALCACHE = VSPath(CACHE)

    def __init__(self, api_key='', debug=False, lang='fr'):

        self.ADDON = addon()

        self.api_key = self.ADDON.getSetting('api_tmdb')
        self.debug = debug
        self.lang = lang
        self.poster = 'https://image.tmdb.org/t/p/%s' % self.ADDON.getSetting(
            'poster_tmdb')
        self.fanart = 'https://image.tmdb.org/t/p/%s' % self.ADDON.getSetting(
            'backdrop_tmdb')

        try:
            if not xbmcvfs.exists(self.CACHE):
                # f = open(self.cache, 'w')
                # f.close()
                self.db = sqlite.connect(self.REALCACHE)
                self.db.row_factory = sqlite.Row
                self.dbcur = self.db.cursor()
                self.__createdb()
                return
        except:
            VSlog('Error: Unable to write on %s' % self.REALCACHE)
            pass

        try:
            self.db = sqlite.connect(self.REALCACHE)
            self.db.row_factory = sqlite.Row
            self.dbcur = self.db.cursor()
        except:
            VSlog('Error: Unable to connect to %s' % self.REALCACHE)
            pass

    def __createdb(self, dropTable=''):
        #Permets de detruire une table pour la recreer de zero.
        if dropTable != '':
            self.dbcur.execute("DROP TABLE " + dropTable)
            self.db.commit()

        sql_create = "CREATE TABLE IF NOT EXISTS movie ("\
                     "imdb_id TEXT, "\
                     "tmdb_id TEXT, "\
                     "title TEXT, "\
                     "year INTEGER,"\
                     "director TEXT, "\
                     "writer TEXT, "\
                     "tagline TEXT, "\
                     "credits TEXT,"\
                     "vote_average FLOAT, "\
                     "vote_count TEXT, "\
                     "runtime TEXT, "\
                     "overview TEXT,"\
                     "mpaa TEXT, "\
                     "premiered TEXT, "\
                     "genre TEXT, "\
                     "studio TEXT,"\
                     "status TEXT,"\
                     "poster_path TEXT, "\
                     "trailer TEXT, "\
                     "backdrop_path TEXT,"\
                     "playcount INTEGER,"\
                     "UNIQUE(imdb_id, tmdb_id, title, year)"\
                     ");"
        try:
            self.dbcur.execute(sql_create)
        except:
            VSlog('Error: Cannot create table movie')

        sql_create = "CREATE TABLE IF NOT EXISTS tvshow ("\
                     "imdb_id TEXT, "\
                     "tmdb_id TEXT, "\
                     "title TEXT, "\
                     "year INTEGER,"\
                     "director TEXT, "\
                     "writer TEXT, "\
                     "credits TEXT,"\
                     "vote_average FLOAT, "\
                     "vote_count TEXT, "\
                     "runtime TEXT, "\
                     "overview TEXT,"\
                     "mpaa TEXT, "\
                     "premiered TEXT, "\
                     "genre TEXT, "\
                     "studio TEXT,"\
                     "status TEXT,"\
                     "poster_path TEXT,"\
                     "trailer TEXT, "\
                     "backdrop_path TEXT,"\
                     "playcount INTEGER,"\
                     "season INTEGER,"\
                     "UNIQUE(imdb_id, tmdb_id, title)"\
                     ");"

        self.dbcur.execute(sql_create)

        sql_create = "CREATE TABLE IF NOT EXISTS season ("\
                     "imdb_id TEXT, "\
                     "tmdb_id TEXT, " \
                     "season INTEGER, "\
                     "year INTEGER,"\
                     "premiered TEXT, "\
                     "poster_path TEXT,"\
                     "playcount INTEGER,"\
                     "overview TEXT,"\
                     "UNIQUE(imdb_id, tmdb_id, season)"\
                     ");"

        self.dbcur.execute(sql_create)

        sql_create = "CREATE TABLE IF NOT EXISTS episode ("\
                     "imdb_id TEXT, "\
                     "tmdb_id TEXT, "\
                     "episode_id TEXT, "\
                     "season INTEGER, "\
                     "episode INTEGER, "\
                     "title TEXT, "\
                     "director TEXT, "\
                     "writer TEXT, "\
                     "overview TEXT, "\
                     "vote_average FLOAT, "\
                     "premiered TEXT, "\
                     "poster_path TEXT, "\
                     "playcount INTEGER, "\
                     "UNIQUE(imdb_id, tmdb_id, episode_id, title)"\
                     ");"

        self.dbcur.execute(sql_create)
        VSlog('table movie creee')

    def __del__(self):
        """ Cleanup db when object destroyed """
        try:
            self.dbcur.close()
            self.db.close()
        except:
            pass

    def getToken(self):

        result = self._call('authentication/token/new', '')

        total = len(result)

        if (total > 0):
            url = 'https://www.themoviedb.org/authenticate/'
            if not xbmc.getCondVisibility('system.platform.android'):
                #Si possible on ouvre la page automatiquement dans un navigateur internet.
                webbrowser.open(url + result['request_token'])
                sText = (self.ADDON.VSlang(30421)) % (url,
                                                      result['request_token'])
                DIALOG = dialog()
                if not DIALOG.VSyesno(sText):
                    return False
            else:
                from resources.lib import pyqrcode
                qr = pyqrcode.create(url + result['request_token'])
                qr.png(
                    'special://home/userdata/addon_data/plugin.video.vstream/qrcode.png',
                    scale=5)
                oSolver = cInputWindowYesNo(
                    captcha=
                    'special://home/userdata/addon_data/plugin.video.vstream/qrcode.png',
                    msg="Scanner le QRCode pour acceder au lien d'autorisation",
                    roundnum=1)
                retArg = oSolver.get()
                DIALOG = dialog()
                if retArg == "N":
                    return False

            result = self._call('authentication/session/new',
                                'request_token=' + result['request_token'])

            if 'success' in result and result['success']:
                self.ADDON.setSetting('tmdb_session',
                                      str(result['session_id']))
                DIALOG.VSinfo(self.ADDON.VSlang(30000))
                return
            else:
                DIALOG.VSerror('Erreur' + self.ADDON.VSlang(30000))
                return

            # xbmc.executebuiltin('Container.Refresh')
            return
        return

    # cherche dans les films ou serie l'id par le nom, return ID ou FALSE
    def get_idbyname(self, name, year='', mediaType='movie', page=1):
        #Pour les series il faut enlever le numero de l episode et la saison.
        if mediaType == "tv":
            m = re.search(
                '(?i)(?:^|[^a-z])((?:E|(?:\wpisode\s?))([0-9]+(?:[\-\.][0-9\?]+)*))',
                name)
            m1 = re.search('(?i)( s(?:aison +)*([0-9]+(?:\-[0-9\?]+)*))', name)

            name = name.replace(m.group(1), '').replace(m1.group(1),
                                                        '').replace('+', ' ')

        #On enleve le contenu entre paranthese.
        try:
            name = name.split('(')[0]
        except:
            pass

        if year:
            term = QuotePlus(name) + '&year=' + year
        else:
            term = QuotePlus(name)

        meta = self._call('search/' + str(mediaType),
                          'query=' + term + '&page=' + str(page))

        # si pas de résultat avec l'année, on teste sans l'année
        if 'total_results' in meta and meta['total_results'] == 0 and year:
            meta = self.search_movie_name(name, '')

        # cherche 1 seul resultat
        if 'total_results' in meta and meta['total_results'] != 0:
            if meta['total_results'] > 1:
                listitems = []

                listitem = xbmcgui.ListItem()
                # boucle commit
                for i in meta['results']:
                    icon = self.fanart + str(i['backdrop_path'])
                    login = i["name"]
                    desc = i["overview"]
                    listitem = xbmcgui.ListItem(label=login, label2=desc)
                    listitem.setArt({'icon': icon, 'thumb': icon})
                    listitem.setUniqueIDs({'tmdb': i['id']}, "tmdb")
                    listitems.append(listitem)

                tmdb_id = self.Box(listitems)

            else:
                tmdb_id = meta['results'][0]['id']
            return tmdb_id

        else:
            return False

        return False

    # Search for movies by title.
    def search_movie_name(self, name, year='', page=1):

        name = re.sub(" +", " ", name)  # nettoyage du titre

        if year:
            term = QuotePlus(name) + '&year=' + year
        else:
            term = QuotePlus(name)

        meta = self._call('search/movie',
                          'query=' + term + '&page=' + str(page))

        if 'errors' not in meta and 'status_code' not in meta:

            # si pas de résultat avec l'année, on teste sans l'année
            if 'total_results' in meta and meta['total_results'] == 0 and year:
                meta = self.search_movie_name(name, '')

            # cherche 1 seul resultat
            if 'total_results' in meta and meta['total_results'] != 0:

                movie = ''

                # s'il n'y en a qu'un, c'est le bon
                if meta['total_results'] == 1:
                    movie = meta['results'][0]

                else:
                    # premiere boucle, recherche la correspondance parfaite sur le nom
                    for searchMovie in meta['results']:
                        if searchMovie['genre_ids'] and 99 not in searchMovie[
                                'genre_ids']:
                            if self._clean_title(
                                    searchMovie['title']) == self._clean_title(
                                        name):
                                movie = searchMovie
                                break
                    # sinon, hors documentaire et année proche
                    if not movie:
                        for searchMovie in meta['results']:
                            if searchMovie[
                                    'genre_ids'] and 99 not in searchMovie[
                                        'genre_ids']:

                                # controle supplémentaire sur l'année meme si déjà dans la requete
                                if year:
                                    if 'release_date' in searchMovie and searchMovie[
                                            'release_date']:
                                        release_date = searchMovie[
                                            'release_date']
                                        yy = release_date[:4]
                                        if int(year) - int(yy) > 1:
                                            continue  # plus de deux ans d'écart, c'est pas bon
                                movie = searchMovie
                                break

                    # Rien d'interessant, on prend le premier
                    if not movie:
                        movie = meta['results'][0]

                # recherche de toutes les infos
                tmdb_id = movie['id']
                meta = self.search_movie_id(tmdb_id)
        else:
            meta = {}

        return meta

    # Search for collections by title.
    def search_collection_name(self, name):

        name = re.sub(" +", " ", name)  # nettoyage du titre

        term = QuotePlus(name)

        meta = self._call('search/collection', 'query=' + term)

        if 'errors' not in meta and 'status_code' not in meta:

            # cherche 1 seul resultat
            if 'total_results' in meta and meta['total_results'] != 0:

                collection = ''

                # s'il n'y en a qu'un, c'est le bon
                if meta['total_results'] == 1:
                    collection = meta['results'][0]

                else:
                    # premiere boucle, recherche la correspondance parfaite sur le nom
                    for searchCollec in meta['results']:
                        cleanTitleTMDB = self._clean_title(
                            searchCollec['name'])
                        cleanTitleSearch = self._clean_title(name)
                        if not cleanTitleSearch.endswith('saga'):
                            cleanTitleSearch += 'saga'
                        if cleanTitleTMDB == cleanTitleSearch:
                            collection = searchCollec
                            break
                        elif (cleanTitleSearch + 'saga') == cleanTitleTMDB:
                            collection = searchCollec
                            break
                    # sinon, le premier qui n'est pas du genre animation
                    if not collection:
                        for searchCollec in meta['results']:
                            if 'animation' not in searchCollec['name']:
                                collection = searchCollec
                                break

                    # Rien d'interessant, on prend le premier
                    if not collection:
                        collection = meta['results'][0]

                meta = collection
                tmdb_id = collection['id']
                meta['tmdb_id'] = tmdb_id

                # recherche de toutes les infos
                meta = self.search_collection_id(tmdb_id)
        else:
            meta = {}

        return meta

    # Search for TV shows by title.
    def search_tvshow_name(self, name, year='', page=1, genre=''):

        if year:
            term = QuotePlus(name) + '&year=' + year
        else:
            term = QuotePlus(name)

        meta = self._call('search/tv', 'query=' + term + '&page=' + str(page))
        if 'errors' not in meta and 'status_code' not in meta:

            # si pas de résultat avec l'année, on teste sans l'année
            if 'total_results' in meta and meta['total_results'] == 0 and year:
                meta = self.search_tvshow_name(name, '')

            # cherche 1 seul resultat
            if 'total_results' in meta and meta['total_results'] != 0:
                movie = ''

                # s'il n'y en a qu'un, c'est le bon
                if meta['total_results'] == 1:
                    movie = meta['results'][0]

                else:
                    # premiere boucle, recherche la correspondance parfaite sur le nom
                    for searchMovie in meta['results']:
                        if genre == '' or genre in searchMovie['genre_ids']:
                            movieName = searchMovie['name']
                            if self._clean_title(
                                    movieName) == self._clean_title(name):
                                movie = searchMovie
                                break
                    # sinon, hors documentaire et année proche
                    if not movie:
                        for searchMovie in meta['results']:
                            if genre and genre in searchMovie['genre_ids']:

                                # controle supplémentaire sur l'année meme si déjà dans la requete
                                if year:
                                    if 'release_date' in searchMovie and searchMovie[
                                            'release_date']:
                                        release_date = searchMovie[
                                            'release_date']
                                        yy = release_date[:4]
                                        if int(year) - int(yy) > 1:
                                            continue  # plus de deux ans d'écart, c'est pas bon
                                movie = searchMovie
                                break

                    # Rien d'interessant, on prend le premier
                    if not movie:
                        movie = meta['results'][0]

                # recherche de toutes les infos
                tmdb_id = movie['id']
                meta = self.search_tvshow_id(tmdb_id)
        else:
            meta = {}

        return meta

    # Search for person by name.
    def search_person_name(self, name):
        name = re.sub(" +", " ", name)  # nettoyage du titre
        term = QuotePlus(name)

        meta = self._call('search/person', 'query=' + term)

        # si pas d'erreur
        if 'errors' not in meta and 'status_code' not in meta:

            # on prend le premier resultat
            if 'total_results' in meta and meta['total_results'] != 0:
                meta = meta['results'][0]

                # recherche de toutes les infos
                person_id = meta['id']
                meta = self.search_person_id(person_id)
        else:
            meta = {}

        return meta

    # Get the basic movie information for a specific movie id.
    def search_movie_id(
            self,
            movie_id,
            append_to_response='append_to_response=trailers,credits'):
        result = self._call('movie/' + str(movie_id), append_to_response)
        result['tmdb_id'] = movie_id
        return result  # obj(**self._call('movie/' + str(movie_id), append_to_response))

    # Get the primary information about a TV series by id.
    def search_tvshow_id(
            self,
            show_id,
            append_to_response='append_to_response=external_ids,videos,credits'
    ):
        result = self._call('tv/' + str(show_id), append_to_response)
        result['tmdb_id'] = show_id
        return result

    # Get the basic informations for a specific collection id.
    def search_collection_id(self, collection_id):
        result = self._call('collection/' + str(collection_id))
        result['tmdb_id'] = collection_id
        return result

    # Get the basic person informations for a specific person id.
    def search_person_id(self, person_id):
        result = self._call('person/' + str(person_id))
        result['tmdb_id'] = person_id
        return result

    # Get the informations for a specific network.
    def search_network_id(self, network_id):
        result = self._call('network/%s/images' % str(network_id))
        if 'status_code' not in result and 'logos' in result:
            network = result['logos'][0]
            vote = -1

            # On prend le logo qui a la meilleure note
            for logo in result['logos']:
                logoVote = float(logo['vote_average'])
                if logoVote > vote:
                    network = logo
                    vote = logoVote
            network['tmdb_id'] = network_id
            network.pop('vote_average')
            return network
        return {}

    def _format(self, meta, name):
        _meta = {}
        _meta['imdb_id'] = ''
        _meta['tmdb_id'] = ''
        _meta['tvdb_id'] = ''
        _meta['title'] = name
        _meta['media_type'] = ''
        _meta['rating'] = 0
        _meta['votes'] = 0
        _meta['duration'] = 0
        _meta['plot'] = ''
        _meta['mpaa'] = ''
        _meta['premiered'] = ''
        _meta['year'] = ''
        _meta['trailer'] = ''
        _meta['tagline'] = ''
        _meta['genre'] = ''
        _meta['studio'] = ''
        _meta['status'] = ''
        _meta['credits'] = ''
        _meta['cast'] = []
        _meta['director'] = ''
        _meta['writer'] = ''
        _meta['poster_path'] = ''
        _meta['cover_url'] = ''
        _meta['backdrop_path'] = ''
        _meta['backdrop_url'] = ''
        _meta['episode'] = 0
        _meta['playcount'] = 0
        _meta['season'] = []

        if 'title' in meta and meta['title']:
            _meta['title'] = meta['title']
        elif 'name' in meta and meta['name']:
            _meta['title'] = meta['name']

        if 'id' in meta:
            _meta['tmdb_id'] = meta['id']
        if 'tmdb_id' in meta:
            _meta['tmdb_id'] = meta['tmdb_id']
        if 'imdb_id' in meta:
            _meta['imdb_id'] = meta['imdb_id']
        elif 'external_ids' in meta:
            _meta['imdb_id'] = meta['external_ids']['imdb_id']
        if 'mpaa' in meta:
            _meta['mpaa'] = meta['mpaa']
        if 'media_type' in meta:
            _meta['media_type'] = meta['media_type']

        if 'release_date' in meta:
            _meta['premiered'] = meta['release_date']
        elif 'first_air_date' in meta:
            _meta['premiered'] = meta['first_air_date']
        elif 's_premiered' in meta and meta['s_premiered']:
            _meta['premiered'] = meta['s_premiered']
        elif 'premiered' in meta and meta['premiered']:
            _meta['premiered'] = meta['premiered']
        elif 'air_date' in meta and meta['air_date']:
            _meta['premiered'] = meta['air_date']

        if 's_year' in meta and meta['s_year']:
            _meta['year'] = meta['s_year']
        elif 'year' in meta and meta['year']:
            _meta['year'] = meta['year']
        else:
            try:
                if 'premiered' in _meta and _meta['premiered']:
                    _meta['year'] = int(_meta['premiered'][:4])
            except:
                pass

        if 'rating' in meta:
            _meta['rating'] = meta['rating']
        elif 'vote_average' in meta:
            _meta['rating'] = meta['vote_average']
        if 'votes' in meta:
            _meta['votes'] = meta['votes']
        elif 'vote_count' in meta:
            _meta['votes'] = meta['vote_count']

        try:
            duration = 0
            if 'runtime' in meta and meta['runtime']:
                duration = float(meta['runtime'])
            elif 'episode_run_time' in meta and meta['episode_run_time']:
                duration = float(meta['episode_run_time'][0])

            if duration < 300:  # en minutes
                duration *= 60  # Convertir les minutes TMDB en secondes pour KODI
            _meta['duration'] = duration
        except:
            _meta['duration'] = 0

        if 's_overview' in meta and meta['s_overview']:  # saison
            _meta['plot'] = meta['s_overview']
        elif 'overview' in meta and meta['overview']:  # film ou série
            _meta['plot'] = meta['overview']
        elif 'parts' in meta:  # Il s'agit d'une collection, on récupere le plot du premier film
            _meta['plot'] = meta['parts'][0]['overview']
        elif 'biography' in meta:  # Il s'agit d'une personne, on récupere sa bio
            _meta['plot'] = meta['biography']

        if 'studio' in meta:
            _meta['studio'] = meta['studio']
        elif 'production_companies' in meta:
            _meta['studio'] = ''
            for studio in meta['production_companies']:
                if _meta['studio'] == '':
                    _meta['studio'] += studio['name']
                else:
                    _meta['studio'] += ' / ' + studio['name']

        if 'genre' in meta:
            listeGenre = meta['genre']
            if '{' in listeGenre:
                meta['genres'] = eval(listeGenre)
            else:
                _meta['genre'] = listeGenre
        if 'genres' in meta:
            # _meta['genre'] = ''
            for genre in meta['genres']:
                if _meta['genre'] == '':
                    _meta['genre'] += genre['name']
                else:
                    _meta['genre'] += ' / ' + genre['name']

        elif 'genre_ids' in meta:
            genres = self.getGenresFromIDs(meta['genre_ids'])
            _meta['genre'] = ''
            for genre in genres:
                if _meta['genre'] == '':
                    _meta['genre'] += genre
                else:
                    _meta['genre'] += ' / ' + genre

            if not isMatrix():
                _meta['genre'] = unicode(_meta['genre'], 'utf-8')

        elif 'parts' in meta:  # Il s'agit d'une collection, on récupere le genre du premier film
            genres = self.getGenresFromIDs(meta['parts'][0]['genre_ids'])
            _meta['genre'] = ''
            for genre in genres:
                if _meta['genre'] == '':
                    _meta['genre'] += genre
                else:
                    _meta['genre'] += ' / ' + genre

            if not isMatrix():
                _meta['genre'] = unicode(_meta['genre'], 'utf-8')

        trailer_id = ''
        if 'trailer' in meta and meta['trailer']:  # Lecture du cache
            _meta['trailer'] = meta['trailer']
        elif 'trailers' in meta:  # Trailer d'un film retourné par TMDB
            try:  # Recherche de la BA en français
                trailers = meta['trailers']['youtube']
                for trailer in trailers:
                    if trailer['type'] == 'Trailer':
                        if 'VF' in trailer['name']:
                            trailer_id = trailer['source']
                            break
                # pas de trailer français, on prend le premier
                if not trailer_id:
                    trailer_id = meta['trailers']['youtube'][0]['source']
                _meta['trailer'] = self.URL_TRAILER % trailer_id
            except:
                pass
        elif 'videos' in meta and meta[
                'videos']:  # Trailer d'une série retourné par TMDB
            try:  # Recherche de la BA en français
                trailers = meta['videos']
                if len(trailers['results']) > 0:
                    for trailer in trailers['results']:
                        if trailer['type'] == 'Trailer' and trailer[
                                'site'] == 'YouTube':
                            trailer_id = trailer[
                                'key']  # Au moins c'est un trailer, pas forcement français
                            if 'fr' in trailer['iso_639_1']:
                                trailer_id = trailer['key']
                                break
                    # pas de trailer, on prend la premiere vidéo disponible
                    if not trailer_id:
                        trailer_id = meta['videos'][0]['key']
                    _meta['trailer'] = self.URL_TRAILER % trailer_id
            except:
                pass

        if 'backdrop_path' in meta and meta['backdrop_path']:
            _meta['backdrop_path'] = meta['backdrop_path']
            _meta['backdrop_url'] = self.fanart + str(_meta['backdrop_path'])
        elif 'parts' in meta:  # Il s'agit d'une collection, on récupere le backdrop du dernier film
            nbFilm = len(meta['parts'])
            _meta['backdrop_path'] = meta['parts'][nbFilm - 1]['backdrop_path']
            _meta['backdrop_url'] = self.fanart + str(_meta['backdrop_path'])

        if 'poster_path' in meta and meta['poster_path']:
            _meta['poster_path'] = meta['poster_path']
            _meta['cover_url'] = self.poster + str(_meta['poster_path'])
        elif 'parts' in meta:  # Il s'agit d'une collection, on récupere le poster du dernier film
            nbFilm = len(meta['parts'])
            _meta['poster_path'] = meta['parts'][nbFilm - 1]['poster_path']
            _meta['cover_url'] = self.fanart + str(_meta['poster_path'])
        elif 'profile_path' in meta:  # il s'agit d'une personne
            _meta['poster_path'] = meta['profile_path']
            _meta['cover_url'] = self.poster + str(_meta['poster_path'])
        elif 'file_path' in meta:  # il s'agit d'un network
            _meta['poster_path'] = meta['file_path']
            _meta['cover_url'] = self.poster + str(_meta['poster_path'])
            _meta['backdrop_path'] = _meta['poster_path']
            _meta['backdrop_url'] = self.fanart + str(_meta['backdrop_path'])

        # special saisons
        if 's_poster_path' in meta and meta['s_poster_path']:
            _meta['poster_path'] = meta['s_poster_path']
            _meta['cover_url'] = self.poster + str(meta['s_poster_path'])

        if 'playcount' in meta:
            _meta['playcount'] = meta['playcount']
            if _meta['playcount'] == 6:  # Anciennement 6 = unwatched
                _meta['playcount'] = 0
        else:
            _meta['playcount'] = 0

        if 'tagline' in meta and meta['tagline']:
            _meta['tagline'] = meta['tagline']

        if 'status' in meta:
            _meta['status'] = meta['status']

        if 'writer' in meta and meta['writer']:
            _meta['writer'] = meta['writer']

        if 'director' in meta and meta['director']:
            _meta['director'] = meta['director']

        if 'credits' in meta and meta['credits']:

            # Transformation compatible pour lecture depuis le cache et retour de TMDB
            strmeta = str(meta['credits'])
            listCredits = eval(strmeta)

            casts = listCredits['cast']
            crews = []

            if len(casts) > 0:
                licast = []
                if 'crew' in listCredits:
                    crews = listCredits['crew']
                if len(crews) > 0:
                    _meta['credits'] = "{u'cast': " + str(
                        casts) + ", u'crew': " + str(crews) + "}"
                else:
                    _meta['credits'] = "{u'cast': " + str(casts) + '}'
#                 _meta['credits'] = "{u'cast': " + str(casts) + ", u'crew': "+str(crews) + "}"
#                 _meta['credits'] = 'u\'cast\': ' + str(casts) + ''
                for cast in casts:
                    licast.append((cast['name'], cast['character']))
                _meta['cast'] = licast

            #if 'crew' in listCredits:
            if len(crews) > 0:
                for crew in crews:
                    if crew['job'] == 'Director':
                        _meta['director'] = crew['name']
                    elif crew['department'] == 'Writing':
                        if _meta['writer'] != '':
                            _meta['writer'] += ' / '
                        _meta['writer'] += '%s (%s)' % (crew['job'],
                                                        crew['name'])
                    elif crew[
                            'department'] == 'Production' and 'Producer' in crew[
                                'job']:
                        if _meta['writer'] != '':
                            _meta['writer'] += ' / '
                        _meta['writer'] += '%s (%s)' % (crew['job'],
                                                        crew['name'])

        if 'season' in meta and meta['season']:
            _meta['season'] = meta['season']

        if 'seasons' in meta and meta['seasons']:
            _meta['season'] = meta['seasons']

        return _meta

    def _clean_title(self, title):
        title = re.sub('[^%s]' % (string.ascii_lowercase + string.digits), '',
                       title.lower())
        return title

    def _cache_search(self,
                      media_type,
                      name,
                      tmdb_id='',
                      year='',
                      season='',
                      episode=''):
        if media_type == 'movie':
            sql_select = 'SELECT * FROM movie'
            if tmdb_id:
                sql_select = sql_select + ' WHERE tmdb_id = \'%s\'' % tmdb_id
            else:
                sql_select = sql_select + ' WHERE title = \'%s\'' % name

            if year:
                sql_select = sql_select + ' AND year = %s' % year

        elif media_type == 'collection':
            sql_select = 'SELECT * FROM movie'
            if tmdb_id:
                sql_select = sql_select + ' WHERE tmdb_id = \'%s\'' % tmdb_id
            else:
                if not name.endswith('saga'):
                    name += 'saga'
                sql_select = sql_select + ' WHERE title = \'%s\'' % name

        elif media_type == 'tvshow' or media_type == 'anime' or media_type == 'season':

            sql_select = 'SELECT * FROM tvshow'
            if season:
                sql_select = 'SELECT *, season.poster_path as s_poster_path, season.premiered as s_premiered, ' \
                             'season.year as s_year, season.overview as s_overview FROM tvshow LEFT JOIN season ON tvshow.imdb_id = season.imdb_id '
            if tmdb_id:
                sql_select = sql_select + ' WHERE tvshow.tmdb_id = \'%s\'' % tmdb_id
            else:
                sql_select = sql_select + ' WHERE tvshow.title = \'%s\'' % name

            if year:
                sql_select = sql_select + ' AND tvshow.year = %s' % year

            if season:
                sql_select = sql_select + ' AND season.season = \'%s\'' % season
        else:
            return None

        try:
            self.dbcur.execute(sql_select)
            matchedrow = self.dbcur.fetchone()
        except Exception as e:
            if 'no such column' in str(e) or 'no column named' in str(e):
                #Pour les serie il faut drop les deux tables.
                if media_type == "tvshow":
                    self.dbcur.execute("DROP TABLE tvshow")
                    self.dbcur.execute("DROP TABLE season")
                    self.__createdb()
                else:
                    self.__createdb(media_type)
                VSlog('Table recreated')

                self.dbcur.execute(sql_select)
                matchedrow = self.dbcur.fetchone()
            else:
                VSlog('************* Error selecting from cache db: %s' % e, 4)
                return None

        if matchedrow:
            #             VSlog('Found meta information by name in cache table')
            return dict(matchedrow)
        else:
            #             VSlog('No match in local DB')
            return None

    def _cache_save(self, meta, name, media_type, season, year):

        # Pas de cache pour les personnes ou les distributeurs
        if media_type in ('person', 'network'):
            return

        # cache des séries et animes
        if media_type == 'tvshow' or media_type == 'anime':
            return self._cache_save_tvshow(meta, name, 'tvshow', season, year)

        # cache des collections
        if media_type == 'collection':
            media_type = 'movie'  # On utilise la même table que pour les films
            if not name.endswith('saga'):
                name += 'saga'

        # sauvegarde de la durée en minutes, pour le retrouver en minutes comme le fait TMDB
        runtime = 0
        if 'duration' in meta and meta['duration']:
            runtime = int(meta['duration']) / 60

        if not year and 'year' in meta:
            year = meta['year']

        # sauvegarde movie dans la BDD
        # year n'est pas forcement l'année du film mais l'année utilisée pour la recherche
        try:
            sql = 'INSERT or IGNORE INTO %s (imdb_id, tmdb_id, title, year, credits, writer, director, tagline, vote_average, vote_count, runtime, ' \
                  'overview, mpaa, premiered, genre, studio, status, poster_path, trailer, backdrop_path, playcount) ' \
                  'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' % media_type
            self.dbcur.execute(
                sql,
                (meta['imdb_id'], meta['tmdb_id'], name, year, meta['credits'],
                 meta['writer'], meta['director'], meta['tagline'],
                 meta['rating'], meta['votes'], str(runtime), meta['plot'],
                 meta['mpaa'], meta['premiered'], meta['genre'],
                 meta['studio'], meta['status'], meta['poster_path'],
                 meta['trailer'], meta['backdrop_path'], 0))
            self.db.commit()
#             VSlog('SQL INSERT Successfully')
        except Exception as e:
            if 'no such column' in str(e) or 'no column named' in str(e):
                self.__createdb(media_type)
                VSlog('Table recreated')

                self.dbcur.execute(sql_select)
                matchedrow = self.dbcur.fetchone()
            else:
                VSlog('SQL ERROR INSERT into table ' + media_type)
            pass

    # Cache pour les séries (et animes)
    def _cache_save_tvshow(self, meta, name, media_type, season, year):
        # ecrit les saisons dans la BDD
        if 'season' in meta:
            self._cache_save_season(meta, season)
            #Petite manipulation pour les skin qui affiche le nombre total de saison.
            meta['season'] = len(meta['season'])

        if not year and 'year' in meta:
            year = meta['year']

        # sauvegarde de la durée en minutes, pour le retrouver en minutes comme le fait TMDB
        runtime = 0
        if 'duration' in meta and meta['duration']:
            runtime = int(meta['duration']) / 60

        # sauvegarde tvshow dans la BDD
        try:
            sql = 'INSERT or IGNORE INTO %s (imdb_id, tmdb_id, title, year, credits, writer, director, vote_average, vote_count, runtime, ' \
                  'overview, mpaa, premiered, genre, studio, status, poster_path, trailer, backdrop_path, playcount, season) ' \
                  'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' % media_type
            self.dbcur.execute(
                sql,
                (meta['imdb_id'], meta['tmdb_id'], name, year, meta['credits'],
                 meta['writer'], meta['director'], meta['rating'],
                 meta['votes'], runtime, meta['plot'], meta['mpaa'],
                 meta['premiered'], meta['genre'], meta['studio'],
                 meta['status'], meta['poster_path'], meta['trailer'],
                 meta['backdrop_path'], 0, meta['season']))
            self.db.commit()
#             VSlog('SQL INSERT Successfully')
        except Exception as e:
            if 'no such column' in str(e) or 'no column named' in str(e):
                self.__createdb('tvshow')
                VSlog('Table recreated')

                self.dbcur.execute(sql_select)
                matchedrow = self.dbcur.fetchone()
            else:
                VSlog('SQL ERROR INSERT into table tvshow')
            pass

    def _cache_save_season(self, meta, season):
        for s in meta['season']:
            if s['season_number'] != None and (
                    '%02d' % int(s['season_number'])) == season:
                meta['s_poster_path'] = s['poster_path']
                meta['s_overview'] = s['overview']
                meta['s_premiered'] = s['air_date']
                meta['s_year'] = s['air_date']
                try:
                    if 's_premiered' in meta and meta['s_premiered']:
                        meta['s_year'] = int(meta['s_premiered'][:4])
                except:
                    pass

            try:
                sql = 'INSERT or IGNORE INTO season (imdb_id, tmdb_id, season, year, premiered, poster_path, playcount, overview) VALUES ' \
                      '(?, ?, ?, ?, ?, ?, ?, ?)'
                self.dbcur.execute(
                    sql, (meta['imdb_id'], s['id'], s['season_number'],
                          s['air_date'], s['air_date'], s['poster_path'], 6,
                          s['overview']))

                self.db.commit()
#                 VSlog('SQL INSERT Successfully')
            except Exception as e:
                if 'no such column' in str(e) or 'no column named' in str(e):
                    self.__createdb('season')
                    VSlog('Table recreated')

                    self.dbcur.execute(sql_select)
                    matchedrow = self.dbcur.fetchone()
                else:
                    VSlog('SQL ERROR INSERT into table season')
                pass

    def get_meta(self,
                 media_type,
                 name,
                 imdb_id='',
                 tmdb_id='',
                 year='',
                 season='',
                 episode='',
                 update=False):
        """
        Main method to get meta data for movie or tvshow. Will lookup by name/year
        if no IMDB ID supplied.

        Args:
            media_type (str): 'movie' or 'tvshow'
            name (str): full name of movie/tvshow you are searching
        Kwargs:
            imdb_id (str): IMDB ID
            tmdb_id (str): TMDB ID
            year (str): 4 digit year of video, recommended to include the year whenever possible
                        to maximize correct search results.
            season (int)
            episode (int)

        Returns:
            DICT of meta data or None if cannot be found.
        """

        name = re.sub(" +", " ", name)  # nettoyage du titre

        #         VSlog('Attempting to retrieve meta data for %s: %s %s %s %s' % (media_type, name, year, imdb_id, tmdb_id))

        # recherche dans la base de données
        if not update:
            #Obligatoire pour pointer vers les bonnes infos dans la base de données
            if media_type in ("season", "tvshow", "anime"):
                name = re.sub(
                    '(?i)( s(?:aison +)*([0-9]+(?:\-[0-9\?]+)*))(?:([^"]+)|)',
                    '', name)
            meta = self._cache_search(media_type, self._clean_title(name),
                                      tmdb_id, year, season, episode)
            if meta:
                meta = self._format(meta, name)
                return meta

        # recherche online
        meta = {}
        if media_type == 'movie':
            if tmdb_id:
                meta = self.search_movie_id(tmdb_id)
            elif name:
                meta = self.search_movie_name(name, year)
        elif media_type == 'tvshow':
            if tmdb_id:
                meta = self.search_tvshow_id(tmdb_id)
            elif name:
                meta = self.search_tvshow_name(name, year)
        elif media_type == 'anime':
            if tmdb_id:
                meta = self.search_tvshow_id(tmdb_id)
            elif name:
                meta = self.search_tvshow_name(name, year, genre=16)
        elif media_type == 'collection':
            if tmdb_id:
                meta = self.search_collection_id(tmdb_id)
            elif name:
                meta = self.search_collection_name(name)
        elif media_type == 'person':
            if tmdb_id:
                meta = self.search_person_id(tmdb_id)
            elif name:
                meta = self.search_person_name(name)
        elif media_type == 'network':
            if tmdb_id:
                meta = self.search_network_id(tmdb_id)

        # Mise en forme des metas si trouvé
        if meta and 'tmdb_id' in meta:
            meta = self._format(meta, name)
            # sauvegarde dans un cache
            self._cache_save(meta, self._clean_title(name), media_type, season,
                             year)
        else:  # initialise un meta vide
            meta = self._format(meta, name)

        return meta

    def getUrl(self, url, page=1, term=''):
        # return url api exemple 'movie/popular' page en cours
        try:
            if term:
                term = term + '&page=' + str(page)
            else:
                term = 'page=' + str(page)
            result = self._call(url, term)
        except:
            return False
        return result

    def _call(self, action, append_to_response=''):
        url = '%s%s?language=%s&api_key=%s' % (self.URL, action, self.lang,
                                               self.api_key)
        if append_to_response:
            url += '&%s' % append_to_response

        #On utilise requests car urllib n'arrive pas a certain moment a ouvrir le json.
        import requests
        data = requests.get(url).json()

        return data

    def getPostUrl(self, action, post):

        tmdb_session = self.ADDON.getSetting('tmdb_session')
        if not tmdb_session:
            return

        sUrl = '%s%s?api_key=%s&session_id=%s' % (self.URL, action,
                                                  self.api_key, tmdb_session)
        try:
            sPost = json.dumps(post).encode('utf-8')
        except:
            sPost = json.dumps(post)

        headers = {'Content-Type': 'application/json'}
        req = urllib2.Request(sUrl, sPost, headers)
        response = urllib2.urlopen(req)
        data = json.loads(response.read())
        return data

    # retourne la liste des genres en Texte, à partir des IDs
    def getGenresFromIDs(self, genresID):
        sGenres = []
        for gid in genresID:
            genre = self.TMDB_GENRES.get(gid)
            if genre:
                sGenres.append(genre)
        return sGenres

    # Retourne le genre en Texte, à partir d'un ID
    def getGenreFromID(self, genreID):
        if not str(genreID).isdigit():
            return genreID

        genre = self.TMDB_GENRES.get(genreID)
        if genre:
            return genre
        return genreID

    def Box(self, listitems):
        addons = addon()

        class XMLDialog(xbmcgui.WindowXMLDialog):
            def __init__(self, *args, **kwargs):
                self.tmdb_id = ""

            def onInit(self):
                self.container = self.getControl(6)
                self.button = self.getControl(5)
                self.getControl(3).setVisible(False)
                self.getControl(1).setLabel("Choisissez le bon contenu")
                self.list = self.container.addItems(listitems)
                self.setFocus(self.container)

            def onClick(self, controlId):
                self.tmdb_id = self.getControl(
                    controlId).getSelectedItem().getUniqueID('tmdb')
                self.close()

        path = 'special://home/addons/plugin.video.vstream'
        wd = XMLDialog('DialogSelect.xml', path, 'Default')
        wd.doModal()
        tmdb_id = wd.tmdb_id
        del wd

        return tmdb_id
Beispiel #13
0
    def getVideoLinks(self, videoUrl):
        printDBG("BSTO.getVideoLinks [%s]" % videoUrl)
        urlTab = []
        
        key = strwithmeta(videoUrl).meta.get('links_key', '')
        if key in self.cacheLinks:
            for idx in range(len(self.cacheLinks[key])):
                if self.cacheLinks[key][idx]['url'] == videoUrl and not self.cacheLinks[key][idx]['name'].startswith('*'):
                    self.cacheLinks[key][idx]['name'] = '*' + self.cacheLinks[key][idx]['name']
        
        sts, data = self.getPage(videoUrl)
        if not sts: 
            return []
        
        #printDBG("---------------------------")
        #printDBG(data)
        #printDBG("---------------------------")
        
        errorMsgTab = []
        
        # LID
        #<div class="hoster-player" data-lid="4778534">
        # token
        #<meta name="security_token" content="edfafd7a9fa9a7d005f88c96" />
        # ticket <- token from recaptcha
        # recaptcha sitekey
        #series.init (1, 1, '6LeiZSYUAAAAAI3JZXrRnrsBzAdrZ40PmD57v_fs')
        
        lid = self.cm.ph.getSearchGroups(data, "data-lid=['\"]([^'^\"]+?)['\"]")[0]
        printDBG("Data LID : %s " % lid)
        
        token = self.cm.ph.getSearchGroups(data, "<meta.*security_token.*content=\"(.*?)\"")[0]
        printDBG("Security token : %s " % token)
        
        if not lid or not token:
            return []
        
        sitekey = self.cm.ph.getSearchGroups(data, "'([0-9a-zA-Z_]{38,}?)'\)")[0]
        
        if sitekey != '':
            ticket, errorMsgTab = self.processCaptcha(sitekey,  self.cm.meta['url'], bypassCaptchaService=config.plugins.iptvplayer.bsto_bypassrecaptcha.value)
            if not ticket :
                SetIPTVPlayerLastHostError(errorMsgTab)
                return []
        
        printDBG("ticket: %s" % ticket)
                
        # post data
        postData = {'token': token, 'LID': lid, 'ticket': ticket}
        ajaxUrl = self.MAIN_URL + "ajax/embed.php"
        ajaxParams = self.defaultParams
        ajaxParams['header']= self.AJAX_HEADER
        ajaxParams['header']['Referer'] = videoUrl
         
        sts, ajaxData = self.cm.getPage(ajaxUrl, ajaxParams, post_data=postData)
        if not sts: 
            return []

        printDBG("----------- ajax data ----------")
        printDBG(ajaxData)
        printDBG("--------------------------------")
        # {"success":true,"link":"https:\/\/vivo.sx\/2eaf981402","embed":"0"}
        
        jsonData = json_loads(ajaxData) 
        
        hostUrl = jsonData.get('link','')
        
        if hostUrl:
            if 1 != self.up.checkHostSupport(hostUrl):
                SetIPTVPlayerLastHostError('\n'.join(errorMsgTab)) 
            elif self.cm.isValidUrl(hostUrl):
                BSTO.LINKS_CACHE[lid] = hostUrl
                if config.plugins.iptvplayer.bsto_linkcache.value:
                    WriteTextFile(GetCacheSubDir('bs.to', lid), hostUrl)
                urlTab = self.up.getVideoLinkExt(hostUrl)
        
        return urlTab
Beispiel #14
0
def get_response(img, cookie):
    # on telecharge l'image
    from Plugins.Extensions.IPTVPlayer.tsiplayer.addons.resources.lib import xbmcvfs

    dialogs = dialog()

    from Plugins.Extensions.IPTVPlayer.tools.iptvtools import GetCacheSubDir
    filename = GetCacheSubDir('Tsiplayer')+'Captcha.raw'
    # PathCache = xbmc.translatePath(xbmcaddon.Addon('plugin.video.vstream').getAddonInfo("profile"))
    # filename  = os.path.join(PathCache, 'Captcha.raw')

    # hostComplet = re.sub(r'(https*:\/\/[^/]+)(\/*.*)', '\\1', img)
    # host = re.sub(r'https*:\/\/', '', hostComplet)
    url = img

    oRequestHandler = cRequestHandler(url)
    oRequestHandler.addHeaderEntry('User-Agent', UA)
    # oRequestHandler.addHeaderEntry('Referer', url)
    oRequestHandler.addHeaderEntry('Cookie', cookie)

    htmlcontent = oRequestHandler.request()

    NewCookie = oRequestHandler.GetCookies()

    downloaded_image = xbmcvfs.File(filename, 'wb')
    # downloaded_image = file(filename, "wb")
    downloaded_image.write(htmlcontent)
    downloaded_image.close()

    # on affiche le dialogue
    solution = ''

    if True:
        # nouveau captcha
        try:
            # affichage du dialog perso
            class XMLDialog(xbmcgui.WindowXMLDialog):
                # """
                # Dialog class for captcha
                # """
                def __init__(self, *args, **kwargs):
                    xbmcgui.WindowXMLDialog.__init__(self)
                    pass

                def onInit(self):
                    # image background captcha
                    self.getControl(1).setImage(filename.encode("utf-8"), False)
                    # image petit captcha memory fail
                    self.getControl(2).setImage(filename.encode("utf-8"), False)
                    self.getControl(2).setVisible(False)
                    # Focus clavier
                    self.setFocus(self.getControl(21))

                def onClick(self, controlId):
                    if controlId == 20:
                        # button Valider
                        solution = self.getControl(5000).getLabel()
                        xbmcgui.Window(10101).setProperty('captcha', solution)
                        self.close()
                        return

                    elif controlId == 30:
                        # button fermer
                        self.close()
                        return

                    elif controlId == 21:
                        # button clavier
                        self.getControl(2).setVisible(True)
                        kb = xbmc.Keyboard(self.getControl(5000).getLabel(), '', False)
                        kb.doModal()

                        if (kb.isConfirmed()):
                            self.getControl(5000).setLabel(kb.getText())
                            self.getControl(2).setVisible(False)
                        else:
                            self.getControl(2).setVisible(False)

                def onFocus(self, controlId):
                    self.controlId = controlId

                def _close_dialog(self):
                    self.close()

                def onAction(self, action):
                    # touche return 61448
                    if action.getId() in (9, 10, 11, 30, 92, 216, 247, 257, 275, 61467, 61448):
                        self.close()

            path = "special://home/addons/plugin.video.vstream"
            wd = XMLDialog('DialogCaptcha.xml', path, 'default', '720p')
            wd.doModal()
            del wd
        finally:

            solution = xbmcgui.Window(10101).getProperty('captcha')
            if solution == '':
                dialogs.VSinfo("Vous devez taper le captcha")

    else:
        # ancien Captcha
        try:
            img = xbmcgui.ControlImage(450, 0, 400, 130, filename.encode("utf-8"))
            wdlg = xbmcgui.WindowDialog()
            wdlg.addControl(img)
            wdlg.show()
            # xbmc.sleep(3000)
            kb = xbmc.Keyboard("", "Tapez les Lettres/chiffres de l'image", False)
            kb.doModal()
            if kb.isConfirmed():
                solution = kb.getText()
                if solution == '':
                    dialogs.VSinfo("Vous devez taper le captcha")
            else:
                dialogs.VSinfo("Vous devez taper le captcha")
        finally:
            wdlg.removeControl(img)
            wdlg.close()

    return solution, NewCookie
Beispiel #15
0
class cTMDb:
    # https://developers.themoviedb.org/3/genres/get-movie-list
    # https://developers.themoviedb.org/3/genres/get-tv-list
    TMDB_GENRES = {
        12: 'Aventure',
        14: 'Fantastique',
        16: 'Animation',
        18: 'Drame',
        27: 'Horreur',
        28: 'Action',
        35: 'Comédie',
        36: 'Histoire',
        37: 'Western',
        53: 'Thriller',
        80: 'Crime',
        99: 'Documentaire',
        878: 'Science-Fiction',
        9648: 'Mystère',
        10402: 'Musique',
        10749: 'Romance',
        10751: 'Familial',
        10752: 'Guerre',
        10759: 'Action & Aventure',
        10762: 'Kids',
        10763: 'News',
        10764: 'Realité',
        10765: 'Science-Fiction & Fantastique',
        10766: 'Feuilleton',
        10767: 'Talk',
        10768: 'Guerre & Politique',
        10769: 'Etranger',
        10770: 'Téléfilm'
    }

    URL = 'https://api.themoviedb.org/3/'
    URL_TRAILER = 'plugin://plugin.video.youtube/play/?video_id=%s'  # ancien : 'plugin://plugin.video.youtube/?action=play_video&videoid=%s'
    from Plugins.Extensions.IPTVPlayer.tools.iptvtools import GetCacheSubDir
    CACHE = GetCacheSubDir('Tsiplayer') + 'video_cache.db'

    # important seul xbmcvfs peux lire le special
    if not isMatrix():
        REALCACHE = VSPath(CACHE).decode('utf-8')
    else:
        REALCACHE = VSPath(CACHE)

    def __init__(self, api_key='', debug=False, lang='fr'):

        self.ADDON = addon()

        self.api_key = self.ADDON.getSetting('api_tmdb')
        self.debug = debug
        self.lang = lang
        self.poster = 'https://image.tmdb.org/t/p/%s' % self.ADDON.getSetting(
            'poster_tmdb')
        self.fanart = 'https://image.tmdb.org/t/p/%s' % self.ADDON.getSetting(
            'backdrop_tmdb')

        try:
            if not xbmcvfs.exists(self.CACHE):
                self.db = sqlite.connect(self.REALCACHE)
                self.db.row_factory = sqlite.Row
                self.dbcur = self.db.cursor()
                self.__createdb()
                return
        except:
            VSlog('Error: Unable to write on %s' % self.REALCACHE)
            pass

        try:
            self.db = sqlite.connect(self.REALCACHE)
            self.db.row_factory = sqlite.Row
            self.dbcur = self.db.cursor()
        except:
            VSlog('Error: Unable to connect to %s' % self.REALCACHE)
            pass

    def __createdb(self, dropTable=''):
        try:
            # Permets de detruire une table pour la recreer de zero.
            if dropTable != '':
                self.dbcur.execute("DROP TABLE " + dropTable)
                self.db.commit()
        except:
            pass

        sql_create = "CREATE TABLE IF NOT EXISTS movie ("\
                     "imdb_id TEXT, "\
                     "tmdb_id TEXT, "\
                     "title TEXT, "\
                     "year INTEGER, "\
                     "director TEXT, "\
                     "writer TEXT, "\
                     "tagline TEXT, "\
                     "cast TEXT, "\
                     "crew TEXT, "\
                     "rating FLOAT, "\
                     "votes TEXT, "\
                     "duration INTEGER, "\
                     "plot TEXT, "\
                     "mpaa TEXT, "\
                     "premiered TEXT, "\
                     "genre TEXT, "\
                     "studio TEXT, "\
                     "status TEXT, "\
                     "poster_path TEXT, "\
                     "trailer TEXT, "\
                     "backdrop_path TEXT, "\
                     "UNIQUE(tmdb_id)"\
                     ");"
        try:
            self.dbcur.execute(sql_create)
            VSlog('table movie creee')
        except:
            VSlog('Error: Cannot create table movie')

        sql_create = "CREATE TABLE IF NOT EXISTS saga ("\
                     "tmdb_id TEXT, "\
                     "title TEXT, "\
                     "plot TEXT, "\
                     "genre TEXT, "\
                     "poster_path TEXT, "\
                     "backdrop_path TEXT, "\
                     "UNIQUE(tmdb_id)"\
                     ");"
        try:
            self.dbcur.execute(sql_create)
            VSlog('table saga creee')
        except:
            VSlog('Error: Cannot create table saga')

        sql_create = "CREATE TABLE IF NOT EXISTS tvshow ("\
                     "imdb_id TEXT, "\
                     "tmdb_id TEXT, "\
                     "title TEXT, "\
                     "year INTEGER, "\
                     "director TEXT, "\
                     "writer TEXT, "\
                     "cast TEXT, "\
                     "crew TEXT, "\
                     "rating FLOAT, "\
                     "votes TEXT, "\
                     "duration INTEGER, "\
                     "plot TEXT, "\
                     "mpaa TEXT, "\
                     "premiered TEXT, "\
                     "genre TEXT, "\
                     "studio TEXT, "\
                     "status TEXT, "\
                     "poster_path TEXT, "\
                     "trailer TEXT, "\
                     "backdrop_path TEXT, "\
                     "nbseasons INTEGER, "\
                     "UNIQUE(tmdb_id)"\
                     ");"
        try:
            self.dbcur.execute(sql_create)
            VSlog('table tvshow creee')
        except:
            VSlog('Error: Cannot create table tvshow')

        sql_create = "CREATE TABLE IF NOT EXISTS season ("\
                     "tmdb_id TEXT, " \
                     "season INTEGER, "\
                     "year INTEGER, "\
                     "premiered TEXT, "\
                     "poster_path TEXT, "\
                     "plot TEXT, "\
                     "episode INTEGER, "\
                     "UNIQUE(tmdb_id, season)"\
                     ");"
        try:
            self.dbcur.execute(sql_create)
            VSlog('table season creee')
        except:
            VSlog('Error: Cannot create table season')

        sql_create = "CREATE TABLE IF NOT EXISTS episode ("\
                     "tmdb_id TEXT, "\
                     "season INTEGER, "\
                     "episode INTEGER, "\
                     "year INTEGER, "\
                     "title TEXT, "\
                     "director TEXT, "\
                     "writer TEXT, "\
                     "guest_stars TEXT, "\
                     "plot TEXT, "\
                     "rating FLOAT, "\
                     "votes TEXT, "\
                     "premiered TEXT, "\
                     "tagline TEXT, "\
                     "poster_path TEXT, "\
                     "UNIQUE(tmdb_id, season, episode)"\
                     ");"

        try:
            self.dbcur.execute(sql_create)
            VSlog('table episode creee')
        except:
            VSlog('Error: Cannot create table episode')

    def __del__(self):
        """ Cleanup db when object destroyed """
        try:
            self.dbcur.close()
            self.db.close()
        except:
            pass

    def getToken(self):
        result = self._call('authentication/token/new', '')
        total = len(result)

        if (total > 0):
            url = 'https://www.themoviedb.org/authenticate/'
            if not xbmc.getCondVisibility('system.platform.android'):
                # Si possible on ouvre la page automatiquement dans un navigateur internet.
                #import webbrowser
                webbrowser.open(url + result['request_token'])
                sText = (self.ADDON.VSlang(30421)) % (url,
                                                      result['request_token'])
                DIALOG = dialog()
                if not DIALOG.VSyesno(sText):
                    return False
            else:
                from resources.lib import pyqrcode

                qr = pyqrcode.create(url + result['request_token'])
                qr.png(
                    'special://home/userdata/addon_data/plugin.video.vstream/qrcode.png',
                    scale=5)
                oSolver = cInputWindowYesNo(
                    captcha=
                    'special://home/userdata/addon_data/plugin.video.vstream/qrcode.png',
                    msg="Scanner le QRCode pour acceder au lien d'autorisation",
                    roundnum=1)
                retArg = oSolver.get()
                DIALOG = dialog()
                if retArg == "N":
                    return False

            result = self._call('authentication/session/new',
                                'request_token=' + result['request_token'])

            if 'success' in result and result['success']:
                self.ADDON.setSetting('tmdb_session',
                                      str(result['session_id']))
                DIALOG.VSinfo(self.ADDON.VSlang(30000))
                return
            else:
                DIALOG.VSerror('Erreur' + self.ADDON.VSlang(30000))
                return

            # xbmc.executebuiltin('Container.Refresh')
            return
        return

    # cherche dans les films ou serie l'id par le nom, return ID ou FALSE
    def get_idbyname(self, name, year='', mediaType='movie', page=1):

        # On enleve le contenu entre paranthese.
        try:
            name = name.split('(')[0]
        except:
            pass

        if year:
            term = QuotePlus(name) + '&year=' + year
        else:
            term = QuotePlus(name)

        meta = self._call('search/' + str(mediaType),
                          'query=' + term + '&page=' + str(page))

        # si pas de résultat avec l'année, on teste sans l'année
        if 'total_results' in meta and meta['total_results'] == 0 and year:
            meta = self.search_movie_name(name, '')

            # cherche 1 seul resultat
            if 'total_results' in meta and meta['total_results'] != 0:
                tmdb_id = meta['results'][0]['id']
                return tmdb_id
        else:
            return False

        return False

    # Search for movies by title.
    def search_movie_name(self, name, year='', page=1):

        name = re.sub(" +", " ", name)  # nettoyage du titre

        if year:
            term = QuotePlus(name) + '&year=' + year
        else:
            term = QuotePlus(name)

        meta = self._call('search/movie',
                          'query=' + term + '&page=' + str(page))

        if 'errors' not in meta and 'status_code' not in meta:

            # si pas de résultat avec l'année, on teste sans l'année
            if 'total_results' in meta and meta['total_results'] == 0 and year:
                meta = self.search_movie_name(name, '')

            # cherche 1 seul resultat
            if 'total_results' in meta and meta['total_results'] != 0:
                movie = ''

                # s'il n'y en a qu'un, c'est le bon
                if meta['total_results'] == 1:
                    movie = meta['results'][0]

                else:
                    # premiere boucle, recherche la correspondance parfaite sur le nom
                    for searchMovie in meta['results']:
                        if searchMovie['genre_ids'] and 99 not in searchMovie[
                                'genre_ids']:
                            if self._clean_title(
                                    searchMovie['title']) == self._clean_title(
                                        name):
                                movie = searchMovie
                                break
                    # sinon, hors documentaire et année proche
                    if not movie:
                        for searchMovie in meta['results']:
                            if searchMovie[
                                    'genre_ids'] and 99 not in searchMovie[
                                        'genre_ids']:

                                # controle supplémentaire sur l'année meme si déjà dans la requete
                                if year:
                                    if 'release_date' in searchMovie and searchMovie[
                                            'release_date']:
                                        release_date = searchMovie[
                                            'release_date']
                                        yy = release_date[:4]
                                        if int(year) - int(yy) > 1:
                                            continue  # plus de deux ans d'écart, c'est pas bon
                                movie = searchMovie
                                break

                    # Rien d'interessant, on prend le premier
                    if not movie:
                        movie = meta['results'][0]

                # recherche de toutes les infos
                tmdb_id = movie['id']
                meta = self.search_movie_id(tmdb_id)
        else:
            meta = {}

        return meta

    # Search for collections by title.
    def search_collection_name(self, name):
        name = re.sub(" +", " ", name)  # nettoyage du titre
        term = QuotePlus(name)
        meta = self._call('search/collection', 'query=' + term)

        if 'errors' not in meta and 'status_code' not in meta:

            # cherche 1 seul resultat
            if 'total_results' in meta and meta['total_results'] != 0:

                collection = ''

                # s'il n'y en a qu'un, c'est le bon
                if meta['total_results'] == 1:
                    collection = meta['results'][0]

                else:
                    # premiere boucle, recherche la correspondance parfaite sur le nom
                    for searchCollec in meta['results']:
                        cleanTitleTMDB = self._clean_title(
                            searchCollec['name'])
                        cleanTitleSearch = self._clean_title(name)
                        if cleanTitleTMDB == cleanTitleSearch:
                            collection = searchCollec
                            break
                    # sinon, le premier qui n'est pas du genre animation
                    if not collection:
                        for searchCollec in meta['results']:
                            if 'animation' not in searchCollec['name']:
                                collection = searchCollec
                                break

                    # Rien d'interessant, on prend le premier
                    if not collection:
                        collection = meta['results'][0]

                meta = collection
                tmdb_id = collection['id']
                meta['tmdb_id'] = tmdb_id

                # recherche de toutes les infos
                meta = self.search_collection_id(tmdb_id)
        else:
            meta = {}

        return meta

    # Search for TV shows by title.
    def search_tvshow_name(self, name, year='', page=1, genre=''):

        if year:
            term = QuotePlus(name) + '&year=' + year
        else:
            term = QuotePlus(name)

        meta = self._call('search/tv', 'query=' + term + '&page=' + str(page))
        if 'errors' not in meta and 'status_code' not in meta:

            # si pas de résultat avec l'année, on teste sans l'année
            if 'total_results' in meta and meta['total_results'] == 0 and year:
                meta = self.search_tvshow_name(name, '')

            # cherche 1 seul resultat
            if 'total_results' in meta and meta['total_results'] != 0:
                movie = ''

                # s'il n'y en a qu'un, c'est le bon
                if meta['total_results'] == 1:
                    movie = meta['results'][0]

                else:
                    # premiere boucle, recherche la correspondance parfaite sur le nom
                    for searchMovie in meta['results']:
                        if genre == '' or genre in searchMovie['genre_ids']:
                            movieName = searchMovie['name']
                            if self._clean_title(
                                    movieName) == self._clean_title(name):
                                movie = searchMovie
                                break
                    # sinon, hors documentaire et année proche
                    if not movie:
                        for searchMovie in meta['results']:
                            if genre and genre in searchMovie['genre_ids']:

                                # controle supplémentaire sur l'année meme si déjà dans la requete
                                if year:
                                    if 'release_date' in searchMovie and searchMovie[
                                            'release_date']:
                                        release_date = searchMovie[
                                            'release_date']
                                        yy = release_date[:4]
                                        if int(year) - int(yy) > 1:
                                            continue  # plus de deux ans d'écart, c'est pas bon
                                movie = searchMovie
                                break

                    # Rien d'interessant, on prend le premier
                    if not movie:
                        movie = meta['results'][0]

                # recherche de toutes les infos
                tmdb_id = movie['id']
                meta = self.search_tvshow_id(tmdb_id)
        else:
            meta = {}

        return meta

    # Search for person by name.
    def search_person_name(self, name):
        name = re.sub(" +", " ", name)  # nettoyage du titre
        term = QuotePlus(name)

        meta = self._call('search/person', 'query=' + term)

        # si pas d'erreur
        if 'errors' not in meta and 'status_code' not in meta:

            # on prend le premier resultat
            if 'total_results' in meta and meta['total_results'] != 0:
                meta = meta['results'][0]

                # recherche de toutes les infos
                person_id = meta['id']
                meta = self.search_person_id(person_id)
        else:
            meta = {}

        return meta

    # Get the basic movie information for a specific movie id.
    def search_movie_id(
        self,
        movie_id,
        append_to_response='append_to_response=trailers,credits,release_dates'
    ):
        result = self._call('movie/' + str(movie_id), append_to_response)
        result['tmdb_id'] = movie_id
        return result  # obj(**self._call('movie/' + str(movie_id), append_to_response))

    # Get the primary information about a TV series by id.
    def search_tvshow_id(
        self,
        show_id,
        append_to_response='append_to_response=external_ids,videos,credits,release_dates'
    ):
        result = self._call('tv/' + str(show_id), append_to_response)
        result['tmdb_id'] = show_id
        return result

    # Get the primary information about a TV series by id.
    def search_season_id(self, show_id, season):
        result = self._call('tv/' + str(show_id) + '/season/' + str(season))
        result['tmdb_id'] = show_id
        return result

    # Get the primary information about a episode.
    def search_episode_id(self, show_id, season, episode):
        if season:
            result = self._call('tv/' + str(show_id) + '/season/' +
                                str(season) + '/episode/' + str(episode))
            result['tmdb_id'] = show_id
            return result
        else:
            return False

    # Get the basic informations for a specific collection id.
    def search_collection_id(self, collection_id):
        result = self._call('collection/' + str(collection_id))
        result['tmdb_id'] = collection_id
        return result

    # Get the basic person informations for a specific person id.
    def search_person_id(self, person_id):
        result = self._call('person/' + str(person_id))
        result['tmdb_id'] = person_id
        return result

    # Get the informations for a specific network.
    def search_network_id(self, network_id):
        result = self._call('network/%s/images' % str(network_id))
        if 'status_code' not in result and 'logos' in result:
            network = result['logos'][0]
            vote = -1

            # On prend le logo qui a la meilleure note
            for logo in result['logos']:
                logoVote = float(logo['vote_average'])
                if logoVote > vote:
                    network = logo
                    vote = logoVote
            network['tmdb_id'] = network_id
            network.pop('vote_average')
            return network
        return {}

    def _format(self, meta, name, media_type=""):
        _meta = {
            'imdb_id':
            meta.get('imdb_id', ""),
            'tmdb_id':
            meta.get('tmdb_id', "") if meta.get('tmdb_id') else meta.get('id'),
            'tvdb_id':
            "",
            "title":
            meta.get('title') if meta.get('title') else meta.get('name', ""),
            'media_type':
            meta.get('media_type', "") if media_type == "" else media_type,
            'rating':
            meta.get('s_vote_average', 0.0)
            if meta.get('s_vote_average') else meta.get('vote_average', 0.0),
            'votes':
            meta.get('s_vote_count', 0)
            if meta.get('s_vote_count') else meta.get('vote_count', 0),
            'duration': (int(meta.get('episode_run_time', 0)[0]) if meta.get(
                'episode_run_time', 0) else meta.get('runtime', 0)) * 60,
            'plot':
            ''.join([
                meta.get(key, "")
                for key in ['s_overview', 'overview', 'biography']
                if meta.get(key) != None
            ]),
            'mpaa':
            meta.get('mpaa', ""),
            'premiered':
            meta.get('s_premiered', "")
            if meta.get('s_premiered') else meta.get('release_date', "")
            if meta.get('release_date') else meta.get('first_air_date', "")
            if meta.get('first_air_date') else meta.get('air_date', ""),
            'year':
            meta.get('s_year', 0) if meta.get('s_year') else meta.get(
                'year', 0),
            'trailer':
            '',
            'tagline':
            meta.get('name')
            if media_type == "episode" else meta.get('tagline'),
            'genre':
            '',
            'studio':
            "",
            'status':
            meta.get('status', ""),
            'cast':
            '',
            'crew':
            '',
            'director':
            meta.get('s_director', "") if meta.get('s_director') else meta.get(
                'director', ""),
            'writer':
            meta.get('s_writer', "") if meta.get('s_writer') else meta.get(
                'writer', ""),
            'poster_path':
            ''.join([
                meta.get(key, "") for key in
                ['poster_path', 'still_path', 'file_path', 'profile_path']
                if meta.get(key) != None
            ]),
            'backdrop_path':
            ''.join([
                meta.get(key, "") for key in
                ['backdrop_path', 'still_path', 'file_path', 'profile_path']
                if meta.get(key) != None
            ]),
            'episode':
            meta.get('episode_number', 0),
            'season':
            meta.get('season_number', 0)
            if meta.get('season_number') else meta.get('seasons', []),
            'nbseasons':
            meta.get('number_of_seasons', ""),
            'guest_stars':
            str(meta.get('guest_stars', [])),
        }

        try:
            if _meta['year'] == 0:
                _meta['year'] = int(_meta['premiered'][:4])
        except:
            pass

        if 'production_companies' in meta:
            for studio in meta['production_companies']:
                if _meta['studio'] == '':
                    _meta['studio'] += studio['name']
                else:
                    _meta['studio'] += ' / ' + studio['name']

        if 'genre' in meta:
            listeGenre = meta['genre']
            if '{' in listeGenre:
                meta['genres'] = eval(listeGenre)
            else:
                _meta['genre'] = listeGenre
        elif 'genres' in meta:
            for genre in meta['genres']:
                if _meta['genre'] == '':
                    _meta['genre'] += genre['name']
                else:
                    _meta['genre'] += ' / ' + genre['name']

        elif 'genre_ids' in meta:
            genres = self.getGenresFromIDs(meta['genre_ids'])
            _meta['genre'] = ''
            for genre in genres:
                if _meta['genre'] == '':
                    _meta['genre'] += genre
                else:
                    _meta['genre'] += ' / ' + genre

            if not isMatrix():
                _meta['genre'] = unicode(_meta['genre'], 'utf-8')

        elif 'parts' in meta:  # Il s'agit d'une collection, on récupere le genre du premier film
            genres = self.getGenresFromIDs(meta['parts'][0]['genre_ids'])
            _meta['genre'] = ''
            for genre in genres:
                if _meta['genre'] == '':
                    _meta['genre'] += genre
                else:
                    _meta['genre'] += ' / ' + genre

            if not isMatrix():
                _meta['genre'] = unicode(_meta['genre'], 'utf-8')

        trailer_id = ''
        if 'trailer' in meta and meta['trailer']:  # Lecture du cache
            _meta['trailer'] = meta['trailer']
        elif 'trailers' in meta:  # Trailer d'un film retourné par TMDB
            try:  # Recherche de la BA en français
                trailers = meta['trailers']['youtube']
                for trailer in trailers:
                    if trailer['type'] == 'Trailer':
                        if 'VF' in trailer['name']:
                            trailer_id = trailer['source']
                            break
                # pas de trailer français, on prend le premier
                if not trailer_id:
                    trailer_id = meta['trailers']['youtube'][0]['source']
                _meta['trailer'] = self.URL_TRAILER % trailer_id
            except:
                pass
        elif 'videos' in meta and meta[
                'videos']:  # Trailer d'une série retourné par TMDB
            try:  # Recherche de la BA en français
                trailers = meta['videos']
                if len(trailers['results']) > 0:
                    for trailer in trailers['results']:
                        if trailer['type'] == 'Trailer' and trailer[
                                'site'] == 'YouTube':
                            trailer_id = trailer[
                                'key']  # Au moins c'est un trailer, pas forcement français
                            if 'fr' in trailer['iso_639_1']:
                                trailer_id = trailer['key']
                                break
                    # pas de trailer, on prend la premiere vidéo disponible
                    if not trailer_id:
                        trailer_id = meta['videos'][0]['key']
                    _meta['trailer'] = self.URL_TRAILER % trailer_id
            except:
                pass

        if 'credits' in meta and meta['credits']:
            # Code from https://github.com/jurialmunkey/plugin.video.themoviedb.helper/blob/matrix/resources/lib/tmdb/mapping.py
            cast_list = []
            if meta.get('credits', {}).get('cast'):
                cast_list += meta['credits']['cast']
            cast = []
            cast_item = None
            for i in sorted(cast_list, key=lambda k: k.get('order', 0)):
                if cast_item:
                    if cast_item.get('name') != i.get('name'):
                        cast.append(cast_item)
                        cast_item = None
                    elif i.get('character'):
                        if 'role' in cast_item:
                            cast_item['role'] = u'{} / {}'.format(
                                cast_item['role'], i['character'])
                        else:
                            cast_item = None
                if not cast_item:
                    cast_item = {
                        'id': i.get('id'),
                        'name': i.get('name'),
                        'character': i.get('character'),
                        'order': i.get('order')
                    }
                    if i.get('profile_path'):
                        cast_item[
                            'thumbnail'] = self.poster + i['profile_path']
            if cast_item:
                cast.append(cast_item)
            _meta['cast'] = json.dumps(cast)

        # Pas dans le cache, à récupérer depuis TMDB
        if not _meta['director'] and not _meta['writer']:
            crews = []
            if "credits" in meta:
                crews = eval(str(meta['credits']['crew']))
                _meta['crew'] = json.dumps(crews)
            elif "crew" in meta:  # cas des épisodes
                crews = eval(str(meta['crew']))

            if len(crews) > 0:
                for crew in crews:
                    if crew['job'] == 'Director':
                        _meta['director'] = crew['name']
                    elif crew['department'] == 'Writing':
                        if _meta['writer'] != '':
                            _meta['writer'] += ' / '
                        _meta['writer'] += '%s (%s)' % (crew['job'],
                                                        crew['name'])
                    elif crew[
                            'department'] == 'Production' and 'Producer' in crew[
                                'job']:
                        if _meta['writer'] != '':
                            _meta['writer'] += ' / '
                        _meta['writer'] += '%s (%s)' % (crew['job'],
                                                        crew['name'])

        if _meta["mpaa"] == "":
            try:
                cert = meta['release_dates']
                if len(cert['results']) > 0:
                    for data in cert['results']:
                        if 'fr' in data['iso_3166_1']:
                            _meta['mpaa'] = data['release_dates'][0][
                                'certification']
                            break
                    if not _meta['mpaa']:
                        _meta['mpaa'] = cert['results'][0]['release_dates'][0][
                            'certification']
            except:
                pass

        if _meta['poster_path']:
            _meta['poster_path'] = self.poster + _meta['poster_path']

        if _meta['backdrop_path']:
            _meta['backdrop_path'] = self.fanart + _meta['backdrop_path']
        return _meta

    def _clean_title(self, title):
        title = re.sub('[^%s]' % (string.ascii_lowercase + string.digits), '',
                       title.lower())
        return title

    def _cache_search(self,
                      media_type,
                      name,
                      tmdb_id='',
                      year='',
                      season='',
                      episode=''):
        if media_type == 'movie':
            sql_select = 'SELECT * FROM movie'
            if tmdb_id:
                sql_select = sql_select + ' WHERE tmdb_id = \'%s\'' % tmdb_id
            else:
                sql_select = sql_select + ' WHERE title = \'%s\'' % name
                if year:
                    sql_select = sql_select + ' AND year = %s' % year

        elif media_type == 'collection':
            sql_select = 'SELECT * FROM saga'
            if tmdb_id:
                sql_select = sql_select + ' WHERE tmdb_id = \'%s\'' % tmdb_id
            else:
                sql_select = sql_select + ' WHERE title = \'%s\'' % name

        elif media_type == 'tvshow' or media_type == 'anime':
            sql_select = 'SELECT * FROM tvshow'
            if tmdb_id:
                sql_select = sql_select + ' WHERE tvshow.tmdb_id = \'%s\'' % tmdb_id
            else:
                sql_select = sql_select + ' WHERE tvshow.title = \'%s\'' % name
                if year:
                    sql_select = sql_select + ' AND tvshow.year = %s' % year

        elif media_type == 'season':
            sql_select = 'SELECT *, season.poster_path, season.premiered, ' \
                             'season.year, season.plot FROM season LEFT JOIN tvshow ON season.tmdb_id = tvshow.tmdb_id'
            if tmdb_id:
                sql_select = sql_select + ' WHERE tvshow.tmdb_id = \'%s\'' % tmdb_id
            else:
                sql_select = sql_select + ' WHERE tvshow.title = \'%s\'' % name

            sql_select = sql_select + ' AND season.season = \'%s\'' % season

        elif media_type == 'episode':
            sql_select = 'SELECT *, episode.title, episode.poster_path, episode.premiered, '\
                'episode.guest_stars, episode.year, episode.plot, '\
                'episode.director, episode.writer, episode.rating, episode.votes '\
                'FROM episode LEFT JOIN tvshow ON episode.tmdb_id = tvshow.tmdb_id'
            if tmdb_id:
                sql_select += ' WHERE tvshow.tmdb_id = \'%s\'' % tmdb_id
            else:
                sql_select += ' WHERE tvshow.title = \'%s\'' % name
            sql_select += ' AND episode.season = \'%s\' AND episode.episode = \'%s\'' % (
                season, episode)
        else:
            return None

        try:
            self.dbcur.execute(sql_select)
            matchedrow = self.dbcur.fetchone()
        except Exception as e:
            if 'no such column' in str(e) or 'no column named' in str(e):
                # Pour les series il faut reconstruire les deux tables.
                if media_type == "tvshow":
                    self.__createdb('tvshow')
                    self.__createdb('season')
                else:
                    self.__createdb(media_type)
                VSlog('Table recreated')

                # Deuxieme tentative
                self.dbcur.execute(sql_select)
                matchedrow = self.dbcur.fetchone()
            else:
                VSlog('************* Error selecting from cache db: %s' % e, 4)
                return None

        if matchedrow:
            # VSlog('Found meta information by name in cache table')
            return dict(matchedrow)
        else:
            # VSlog('No match in local DB')
            return None

    def _cache_save(self, meta, name, media_type, season, episode, year):
        # Pas de cache pour les personnes ou les distributeurs
        if media_type in ('person', 'network'):
            return

        # cache des films
        if media_type == 'movie':
            return self._cache_save_movie(meta, name, year)

        # cache des séries et animes
        elif media_type == 'tvshow' or media_type == 'anime':
            return self._cache_save_tvshow(meta, name, season, year)

        # cache des saisons
        if media_type == "season":
            return self._cache_save_season(meta, season)

        # cache des épisodes
        elif media_type == "episode":
            return self._cache_save_episode(meta, season, episode)

        # cache des collections
        elif media_type == 'collection':
            return self._cache_save_collection(meta, name)

    # sauvegarde movie dans la BDD
    def _cache_save_movie(self, meta, name, year):
        # year n'est pas forcement l'année du film mais l'année utilisée pour la recherche
        if not year and 'year' in meta:
            year = meta['year']

        try:
            sql = 'INSERT or IGNORE INTO movie (imdb_id, tmdb_id, title, year, cast, crew, writer, director, tagline, rating, votes, duration, ' \
                  'plot, mpaa, premiered, genre, studio, status, poster_path, trailer, backdrop_path) ' \
                  'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
            self.dbcur.execute(
                sql,
                (meta['imdb_id'], meta['tmdb_id'], name, year, meta['cast'],
                 meta['crew'], meta['writer'], meta['director'],
                 meta['tagline'], meta['rating'], meta['votes'],
                 str(meta['duration']), meta['plot'], meta['mpaa'],
                 meta['premiered'], meta['genre'], meta['studio'],
                 meta['status'], meta['poster_path'], meta['trailer'],
                 meta['backdrop_path']))
            self.db.commit()
            # VSlog('SQL INSERT Successfully')
        except Exception as e:
            VSlog(str(e))
            if 'no such column' in str(e) or 'no column named' in str(
                    e) or "no such table" in str(e):
                self.__createdb('movie')
                VSlog('Table recreated')

                # Deuxieme tentative
                self.dbcur.execute(
                    sql, (meta['imdb_id'], meta['tmdb_id'], name, year,
                          meta['cast'], meta['crew'], meta['writer'],
                          meta['director'], meta['tagline'], meta['rating'],
                          meta['votes'], str(meta['duration']), meta['plot'],
                          meta['mpaa'], meta['premiered'], meta['genre'],
                          meta['studio'], meta['status'], meta['poster_path'],
                          meta['trailer'], meta['backdrop_path']))
                self.db.commit()
            else:
                VSlog('SQL ERROR INSERT into table movie')
            pass

    # Cache pour les séries (et animes)
    def _cache_save_tvshow(self, meta, name, season, year):
        # Ecrit les saisons dans le cache
        for s_meta in meta['season']:
            s_meta['tmdb_id'] = meta['tmdb_id']
            self._cache_save_season(s_meta, season)

        if not year and 'year' in meta:
            year = meta['year']

        # sauvegarde tvshow dans la BDD
        try:
            sql = 'INSERT or IGNORE INTO tvshow (imdb_id, tmdb_id, title, year, cast, crew, writer, director, rating, votes, duration, ' \
                  'plot, mpaa, premiered, genre, studio, status, poster_path, trailer, backdrop_path, nbseasons) ' \
                  'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
            self.dbcur.execute(
                sql,
                (meta['imdb_id'], meta['tmdb_id'], name, year, meta['cast'],
                 meta['crew'], meta['writer'], meta['director'],
                 meta['rating'], meta['votes'], meta['duration'], meta['plot'],
                 meta['mpaa'], meta['premiered'], meta['genre'],
                 meta['studio'], meta['status'], meta['poster_path'],
                 meta['trailer'], meta['backdrop_path'], meta['nbseasons']))
            self.db.commit()
        except Exception as e:
            VSlog(str(e))
            if 'no such column' in str(e) or 'no column named' in str(e):
                self.__createdb('tvshow')
                VSlog('Table recreated')

                # Deuxieme tentative
                self.dbcur.execute(
                    sql, (meta['imdb_id'], meta['tmdb_id'], name, year,
                          meta['cast'], meta['crew'], meta['writer'],
                          meta['director'], meta['rating'], meta['votes'],
                          meta['duration'], meta['plot'], meta['mpaa'],
                          meta['premiered'], meta['genre'], meta['studio'],
                          meta['status'], meta['poster_path'], meta['trailer'],
                          meta['backdrop_path'], meta['nbseasons']))
                self.db.commit()
            else:
                VSlog('SQL ERROR INSERT into table tvshow')
            pass

    # Cache pour les saisons
    def _cache_save_season(self, meta, season):
        if 'air_date' in meta and meta['air_date']:
            premiered = meta['air_date']
        elif 'premiered' in meta and meta['premiered']:
            premiered = meta['premiered']
        else:
            premiered = 0

        s_year = 0
        if 'year' in meta and meta['year']:
            s_year = meta['year']
        else:
            try:
                if premiered:
                    s_year = int(premiered[:4])
            except:
                pass

        if 'season_number' in meta:
            season = meta['season_number']
        elif 'season' in meta:
            season = meta['season']

        if 'overview' in meta:
            plot = meta.get('overview', "")
        else:
            plot = ""

        if meta['poster_path']:
            fanart = self.poster + meta['poster_path']
        else:
            fanart = ""

        try:
            sql = 'INSERT or IGNORE INTO season (tmdb_id, season, year, premiered, poster_path, plot, episode) VALUES '\
                  '(?, ?, ?, ?, ?, ?, ?)'
            self.dbcur.execute(sql,
                               (meta['tmdb_id'], season, s_year, premiered,
                                fanart, plot, meta.get('episode_count', 0)))
            self.db.commit()
        except Exception as e:
            VSlog(str(e))
            if 'no such column' in str(e) or 'no column named' in str(e):
                self.__createdb('season')
                VSlog('Table recreated')

                # Deuxieme tentative
                self.dbcur.execute(
                    sql, (meta['tmdb_id'], season, s_year, premiered, fanart,
                          plot, meta.get('episode_count', 0)))
                self.db.commit()
            else:
                VSlog('SQL ERROR INSERT into table season')
            pass

    # Cache pour les épisodes
    def _cache_save_episode(self, meta, season, episode):
        try:
            sql = 'INSERT or IGNORE INTO episode (tmdb_id, season, episode, year, title, premiered, poster_path, plot, rating, votes, director, writer, guest_stars, tagline) VALUES ' \
                  '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
            self.dbcur.execute(
                sql, (meta['tmdb_id'], season, episode, meta['year'],
                      meta['title'], meta['premiered'], meta['poster_path'],
                      meta['plot'], meta['rating'], meta['votes'],
                      meta['director'], meta['writer'], ''.join(
                          meta.get('guest_stars', "")), meta["tagline"]))
            self.db.commit()
        except Exception as e:
            VSlog(str(e))
            if 'no such column' in str(e) or 'no column named' in str(e):
                self.__createdb('episode')
                VSlog('Table recreated')

                # Deuxieme tentative
                self.dbcur.execute(
                    sql,
                    (meta['tmdb_id'], season, episode, meta['year'],
                     meta['title'], meta['premiered'], meta['poster_path'],
                     meta['plot'], meta['rating'], meta['votes'],
                     meta['director'], meta['writer'], ''.join(
                         meta.get('guest_stars', "")), meta.get("tagline",
                                                                "")))
                self.db.commit()
            else:
                VSlog('SQL ERROR INSERT into table episode')
            pass

    # Cache pour les sagas
    def _cache_save_collection(self, meta, name):
        try:
            sql = 'INSERT or IGNORE INTO saga (tmdb_id, title, plot, genre, poster_path, backdrop_path) VALUES ' \
                  '(?, ?, ?, ?, ?, ?)'
            self.dbcur.execute(
                sql, (meta['tmdb_id'], name, meta['plot'], meta['genre'],
                      meta['poster_path'], meta["backdrop_path"]))
            self.db.commit()
        except Exception as e:
            VSlog(str(e))
            if 'no such column' in str(e) or 'no column named' in str(
                    e) or "no such table" in str(e):
                self.__createdb('saga')
                VSlog('Table recreated')

                # Deuxieme tentative
                self.dbcur.execute(
                    sql, (meta['tmdb_id'], name, meta['plot'], meta['genre'],
                          meta['poster_path'], meta["backdrop_path"]))
                self.db.commit()
            else:
                VSlog('SQL ERROR INSERT into table saga')
            pass

    def get_meta(self,
                 media_type,
                 name,
                 imdb_id='',
                 tmdb_id='',
                 year='',
                 season='',
                 episode='',
                 update=False):
        """
        Main method to get meta data for movie or tvshow. Will lookup by name/year
        if no IMDB ID supplied.

        Args:
            media_type (str): 'movie' or 'tvshow'
            name (str): full name of movie/tvshow you are searching
        Kwargs:
            imdb_id (str): IMDB ID
            tmdb_id (str): TMDB ID
            year (str): 4 digit year of video, recommended to include the year whenever possible
                        to maximize correct search results.
            season (int)
            episode (int)

        Returns:
            DICT of meta data or None if cannot be found.
        """

        name = re.sub(" +", " ", name)  # nettoyage du titre

        # VSlog('Attempting to retrieve meta data for %s: %s %s %s %s' % (media_type, name, year, imdb_id, tmdb_id))

        # recherche dans la base de données
        if not update:
            # Obligatoire pour pointer vers les bonnes infos dans la base de données
            if not tmdb_id:
                if media_type in ("season", "tvshow", "anime", "episode"):
                    name = re.sub(
                        '(?i)( s(?:aison +)*([0-9]+(?:\-[0-9\?]+)*))(?:([^"]+)|)',
                        '', name)

            meta = self._cache_search(media_type, self._clean_title(name),
                                      tmdb_id, year, season, episode)

            if meta:
                return meta

        # recherche online
        meta = {}
        if media_type == 'movie':
            if tmdb_id:
                meta = self.search_movie_id(tmdb_id)
            elif name:
                meta = self.search_movie_name(name, year)
        elif media_type == 'tvshow':
            if tmdb_id:
                meta = self.search_tvshow_id(tmdb_id)
            elif name:
                meta = self.search_tvshow_name(name, year)
        elif media_type == 'season':
            if not tmdb_id:
                tmdb_id = self.get_idbyname(name, year, 'tv')
            if tmdb_id:
                meta = self.search_season_id(tmdb_id, season)
        elif media_type == 'episode':
            if tmdb_id:  # pas de recherche par nom si pas de tmdb_id, car il y aurait déjà un tmdb_id si on connaissait la série
                meta = self.search_episode_id(tmdb_id, season, episode)
        elif media_type == 'anime':
            if tmdb_id:
                meta = self.search_tvshow_id(tmdb_id)
            elif name:
                meta = self.search_tvshow_name(name, year, genre=16)
        elif media_type == 'collection':
            if tmdb_id:
                meta = self.search_collection_id(tmdb_id)
            elif name:
                meta = self.search_collection_name(name)
        elif media_type == 'person':
            if tmdb_id:
                meta = self.search_person_id(tmdb_id)
            elif name:
                meta = self.search_person_name(name)
        elif media_type == 'network':
            if tmdb_id:
                meta = self.search_network_id(tmdb_id)

        # Mise en forme des metas si trouvé
        if meta and 'tmdb_id' in meta:
            meta = self._format(meta, name, media_type)
            # sauvegarde dans un cache
            self._cache_save(meta, self._clean_title(name), media_type, season,
                             episode, year)
        elif meta != False:  # initialise un meta vide
            meta = self._format(meta, name)
        else:
            meta = {}
        return meta

    def getUrl(self, url, page=1, term=''):
        # return url api exemple 'movie/popular' page en cours
        try:
            if term:
                term = term + '&page=' + str(page)
            else:
                term = 'page=' + str(page)
            result = self._call(url, term)
        except:
            return False
        return result

    def _call(self, action, append_to_response=''):
        url = '%s%s?language=%s&api_key=%s' % (self.URL, action, self.lang,
                                               self.api_key)
        if append_to_response:
            url += '&%s' % append_to_response

        # On utilise requests car urllib n'arrive pas a certain moment a ouvrir le json.
        oRequestHandler = cRequestHandler(url)
        data = oRequestHandler.request(jsonDecode=True)

        return data

    # retourne la liste des genres en Texte, à partir des IDs
    def getGenresFromIDs(self, genresID):
        sGenres = []
        for gid in genresID:
            genre = self.TMDB_GENRES.get(gid)
            if genre:
                sGenres.append(genre)
        return sGenres

    # Retourne le genre en Texte, à partir d'un ID
    def getGenreFromID(self, genreID):
        if not str(genreID).isdigit():
            return genreID

        genre = self.TMDB_GENRES.get(genreID)
        if genre:
            return genre
        return genreID
Beispiel #16
0
 def __init__(self, sDefaultText):
     self.MyPath = GetCacheSubDir('Tsiplayer')
     pass