def action_add_custom_filter(self, remove=False):
        if SC.ITEM_PAGE in self.args:
            st = List(SC.TXT_CUSTOM_FORMAT.format(self.args[SC.ITEM_PAGE]))
        else:
            st = List(SC.TXT_CUSTOM_FORMAT.format(self.url))

        cfg = {
            SC.ITEM_URL: '',
            SC.ITEM_TITLE: '',
        }
        if remove is False:
            label = dinput('Zadaj nazov polozky')
            if label == '':
                label = self.args[SC.ITEM_ID]
            cfg[SC.ITEM_TITLE] = label

            url = dinput(
                'Zadaj url pre [B]plugin[/B] z https://stream-cinema.online/filter',
                '')
            if url == '':
                return False
            cfg[SC.ITEM_URL] = url
        else:
            cfg.update({
                SC.ITEM_URL: self.args[SC.ITEM_URL],
                SC.ITEM_TITLE: self.args[SC.ITEM_TITLE],
            })

        st.add(cfg, remove_only=remove)
        if remove is True:
            container_refresh()
 def action_csearch(self):
     self.succeeded = True
     self.end_of_directory()
     _id = self.args.get(SC.ITEM_ID)
     home_win.setProperty('SC.search', '{}'.format(_id))
     search = dinput('', '', xbmcgui.INPUT_TYPE_TEXT)
     home_win.clearProperty('SC.search')
     info('search string: {}'.format(search))
     if search == '':
         exec_build_in('Action(Back)')
         return
     query = {'search': search, SC.ITEM_ID: _id}
     if _id.startswith('search-people'):
         query.update({'ms': '1'})
     st = List(_id)
     st.add(search)
     debug('SEARCH: _ID "{}" search for "{}" people "{}"'.format(
         _id, search, 1 if 'ms' in query else 0))
     url = '/Search/{}?{}'.format(_id, urlencode(query))
     info('search url: {}'.format(url))
     self.url = url
     self.call_url()
     if 'msgERROR' in self.response.get('system', {}):
         self.msg_error()
         exec_build_in('Action(Back)')
         return
     plugin_url = create_plugin_url({'url': url})
     container_update(plugin_url)
     return
 def action_last(self):
     lid = get_history_item_name(self.args.get(SC.ITEM_ID))
     st = List(lid)
     if len(st.get()) > 0:
         self.url = '/Last'
         self.payload = {"ids": dumps(st.get())}
         self.call_url_and_response()
     else:
         if SC.ITEM_WIDGET not in self.args:
             dok(Strings.txt(Strings.EMPTY_HISTORY_H1),
                 Strings.txt(Strings.EMPTY_HISTORY_L1))
Exemple #4
0
def translate_cond_visibility(text):
    m = re.search(
        'sc://(?P<typ>[^\(]+)\((?P<param1>[^\s,\)]+),(?P<param2>[^\s,\)]+)\)',
        text)
    debug('najdene: {} / {} ({}, {})'.format(m.group(0), m.group('typ'),
                                             m.group('param1'),
                                             m.group('param2')))
    ret = text
    if m.group('typ') == 'config':
        debug('{} vs {}'.format(get_setting(m.group('param1')),
                                m.group('param2')))
        p1 = m.group('param1')
        p2 = m.group('param2')
        val = get_setting(p1)
        if p2 == 'notempty':
            ret = val is not None and val != ''
        elif p2 == 'empty':
            ret = val is None or val == ''
        else:
            ret = '{}'.format(val) == '{}'.format(p2)
    elif m.group('typ') == 'history':
        from resources.lib.gui.item import get_history_item_name
        name = get_history_item_name(m.group('param1'))
        st = List(name)
        ret = len(st.get()) > int(m.group('param2'))
    elif m.group('typ') == 'listlen':
        st = List(m.group('param1'))
        p1 = len(st.get())
        p2 = int(m.group('param2'))
        debug('p1 {} p2 {}'.format(p1, p2))
        return p1 > p2
    elif m.group('typ') == 'storagelen':
        st = Storage(m.group('param1'))
        p1 = len(st._data)
        p2 = int(m.group('param2'))
        debug('p1 {} p2 {}'.format(p1, p2))
        return p1 > p2

    debug('{} -> {}'.format(text, ret))
    return ret
    def __init__(self, data):
        SCBaseItem.__init__(self, data)
        self.lib = List(SC.ITEM_LIBRARY)
        item_id = self.data.get(SC.ITEM_ID)
        if item_id and item_id in self.lib.get():
            label = "[COLOR red]*[/COLOR] {0}".format(self.item.getLabel())
            self.item.setLabel(label)

        if SC.ITEM_URL in data:
            url = create_plugin_url(data)
            self.item.setPath(url)
        if self.build_ctx:
            self.make_ctx()
 def pinned_custom(self):
     st = List(SC.TXT_CUSTOM_FORMAT.format(self.url))
     for itm in st.get():
         debug('custom item: {}'.format(itm))
         cfg = {
             SC.ITEM_TYPE: SC.ITEM_CUSTOM_FILTER,
             SC.ITEM_TITLE: itm.get(SC.ITEM_TITLE),
             SC.ITEM_URL: itm.get(SC.ITEM_URL),
             'self_url': self.url,
         }
         item = SCItem(cfg)
         if item.visible:
             item.li().setProperty('SpecialSort', GUI.TOP)
             self.items_pinned.append(item.get())
    def action(self):
        action = self.args.get(SC.ITEM_ACTION)
        if action == SC.ACTION_PLAY_URL:
            self.play_url(self.args.get(SC.ITEM_URL))
            self.succeeded = True
        elif action == SC.ACTION_CMD:
            self.action_cmd()
        elif action == 'intro':
            intro(2, True)
        elif action == SC.ACTION_PIN:
            self.action_pin()
        elif action == SC.ACTION_CSEARCH:
            self.action_csearch()
        elif action == SC.ACTION_LAST:
            self.action_last()
        elif action == 'nextep':
            self.action_next_ep()
        elif action == 'update_nextep':
            self.action_update_next_ep()
            return True
        elif action == 'search_next_episodes':
            self.action_search_next_episodes()
        elif action == SC.ACTION_DEBUG:
            from resources.lib.kodiutils import check_set_debug

            check_set_debug(True)
        elif action == SC.ACTION_DOWNLOAD:
            self.url = self.args.get(SC.ITEM_DOWNLOAD)
            self.call_url_and_response()
        elif action == SC.ACTION_BUFFER:
            set_kodi_cache_size()
        elif action == SC.ACTION_ANDROID:
            self.action_android()
        elif action == SC.ACTION_ADD2HP:
            self.action_add2hp()
        elif action == SC.ACTION_DEL2HP:
            self.action_add2hp(True)
        elif action == SC.ACTION_ADD_CUSTOM_FILTER:
            self.action_add_custom_filter()
        elif action == SC.ACTION_DEL_CUSTOM_FILTER:
            self.action_add_custom_filter(True)
        elif action == SC.ACTION_REMOVE_FROM_LIST:
            self.action_remove_from_list()
        elif action == SC.ACTION_UPDATE_ADDON:
            update_addon()
        elif 'trakt.' in action:
            from resources.lib.trakt.Trakt import trakt
            trakt.action(action, self)
            return True
        elif action in ['add_to_library', 'add_to_library_sub']:
            lib = List(SC.ITEM_LIBRARY)
            lib.add(self.args.get(SC.ITEM_ID))
            if action == 'add_to_library_sub':
                sub = List(SC.ITEM_LIBRARY_SUB)
                sub.add(self.args.get(SC.ITEM_ID))
            container_refresh()
        elif action == 'remove_from_sub':
            lib = List(SC.ITEM_LIBRARY)
            lib.add(self.args.get(SC.ITEM_ID), True)
            if action == 'remove_from_sub':
                sub = List(SC.ITEM_LIBRARY_SUB)
                sub.add(self.args.get(SC.ITEM_ID), True)
            container_refresh()
        elif action == 'autocomplet':
            from resources.lib.services.autocomplete import Autocomplete
            Autocomplete(self.args)
            return True
        elif action == SC.ACTION_DEL_PREFERRED_LANGUAGE:
            del preferred_lang_list[self.args.get(SC.ITEM_ID)]
            container_refresh()
            return
        elif action == SC.ACTION_SET_PREFERRED_LANGUAGE:
            lang_list = Sc.get('/Lang/{}'.format(self.args.get(SC.ITEM_ID)))
            debug('parametre: {} / langs: {}'.format(self.args, lang_list))
            ret = dselect(lang_list,
                          Strings.txt(Strings.CONTEXT_ADD_PREF_LANG))
            if ret > -1:
                st = preferred_lang_list
                st[self.args.get(SC.ITEM_ID)] = lang_list[ret]
                debug('znovelene: {} / {}'.format(
                    ret, st[self.args.get(SC.ITEM_ID)]))
                container_refresh()
            return
        else:
            info('Neznama akcia: {}'.format(action))
        return False
 def action_android(self):
     st = List('android')
     st.add(self.args)
 def action_remove_from_list(self):
     st = List(self.args[SC.ITEM_PAGE])
     st.add(self.args[SC.ITEM_ID], True)
     container_refresh()
     pass
class TraktAPI(object):
    __client_id = "bb21f3665cf0fa07f2a1a420ec6990317c49dee91af8e012cb836d66674e75c4"
    __client_secret = "fcc25d240d560326147cfb32fc0554868333dc954dc150ea2519f0a2a259f6e2"
    authDialog = None
    authPollProgress = None
    storage = {
        'sync.movies': Storage('trakt.sync.movies'),
        'sync.episodes': Storage('trakt.sync.episodes'),
        'watched.movies': List('trakt.watched.movies', sorted=False),
        'watched.shows': List('trakt.watched.shows', sorted=False),
    }
    authorization = {}
    initialized = False

    def __init__(self, force=False):
        debug("TRAKT Initializing.")

        Trakt.configuration.defaults.client(id=self.__client_id,
                                            secret=self.__client_secret)

        Trakt.on('oauth.token_refreshed', self.on_token_refreshed)

        Trakt.configuration.defaults.oauth(refresh=True)
        Trakt.configuration.defaults.http(retry=True, timeout=90)

        from resources.lib.services.Monitor import monitor
        self.monitor = monitor

        if not get_setting_as_bool('trakt.enabled'):
            debug('Trak nieje zapnuty')
            return

        self.initialize(force=force)

    def initialize(self, force=False):
        self.initialized = True

        if settings.get_setting('trakt.authorization') and not force:
            self.authorization = loads(
                settings.get_setting('trakt.authorization'))
            Trakt.configuration.defaults.oauth.from_response(
                self.authorization, refresh=True)
        else:
            self.login()

    def login(self):
        with Trakt.configuration.http(timeout=90):
            code = Trakt['oauth/device'].code()

            if not code:
                debug('TRAKT Error can not reach trakt')
                dok('ERROR', 'Trakt.tv error')
            else:
                # Construct device authentication poller
                poller = Trakt['oauth/device'].poll(**code) \
                    .on('aborted', self.on_aborted) \
                    .on('authenticated', self.on_authenticated) \
                    .on('expired', self.on_expired) \
                    .on('poll', self.on_poll)

                debug(
                    'TRAKT Enter the code "%s" at %s to authenticate your account'
                    % (code.get('user_code'), code.get('verification_url')))

                self.authDialog = dprogress()
                self.authDialog.create(
                    'Trakt', '{} -> {}'.format(code.get('verification_url'),
                                               code.get('user_code')))

                self.authPollProgress = [
                    float(code.get('expires_in')),
                    float(code.get('interval')), 0
                ]

                # Start polling for authentication token
                poller.start(daemon=False)

    def on_aborted(self):
        debug('TRAKT Authentication aborted')
        self.authDialog.close()

    def on_authenticated(self, token):
        self.authorization = token
        set_setting('trakt.authorization', dumps(self.authorization))
        debug('TRAKT Authentication complete: %r' % token)
        self.authDialog.close()
        dok('Trakt', 'Autorizacia uspesna')
        self.update_user()

    def on_expired(self):
        debug('TRAKT Authentication expired')
        self.authDialog.close()

    def on_poll(self, callback):
        debug('TRAKT poll')
        if self.authDialog.iscanceled():
            callback(False)
        else:
            self.authPollProgress[2] += self.authPollProgress[1]
            exp, _, current = self.authPollProgress
            self.authDialog.update(int(current / exp * 100))
            callback(True)

    def on_token_refreshed(self, response):
        # OAuth token refreshed, save token for future calls
        self.authorization = response
        set_setting('trakt.authorization', dumps(self.authorization))

    # ##################################################################################################################

    def update_user(self):
        data = self.get_user()
        debug('trakt user: {}'.format(dumps(data)))
        user = data['user']['username'] if 'username' in data.get(
            'user', {}) else data['user']['name']
        set_setting('trakt.user', user)

    def get_user(self):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['users/settings'].get()
                return result

    def get_playback_movies(self, movies):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                movies = Trakt['sync/playback'].movies(parse=False).json()
        return movies

    def get_shows_watched(self, ids={}):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                shows = Trakt['sync/watched'].shows(extended='full',
                                                    parse=False).json()
                ids = [(i['show']['ids']['trakt'], i['show']['aired_episodes'],
                        sum([[(s['number'], e['number'], e['last_watched_at'])
                              for e in s['episodes']]
                             for s in i['seasons']], [])) for i in shows]

        return ids

    def get_shows_history(self, start_at, end_at=None):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                shows = Trakt['sync/history'].shows(start_at=start_at,
                                                    page=1,
                                                    per_page=100000,
                                                    parse=False).json()
                shows_data = {}
                for i in shows:
                    if i['action'] == 'watch' and i['type'] == 'episode':
                        id = i['show']['ids']['trakt']
                        if id not in shows_data:
                            shows_data.update({id: []})
                        shows_data[id].append(
                            (i['episode']['season'], i['episode']['number'],
                             i['watched_at']))
                ids = [(key, 1, sorted(items, key=lambda x:
                                       (x[2], x[0], x[1])))
                       for key, items in shows_data.items()]
        return ids

    def get_movies_watched(self, movies):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                Trakt['sync/watched'].movies(movies, exceptions=True)
        return movies

    def get_episode_info(self, id, season, episode, extended=None):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                try:
                    res = Trakt['shows'].episode(id,
                                                 season,
                                                 episode,
                                                 extended,
                                                 parse=False).json()
                except:
                    res = None
        return res

    def get_last_activities(self):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['sync'].last_activities()
                return result

    def add_to_history(self, item):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['sync/history'].add(item)
                return result

    def remove_from_history(self, item):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['sync/history'].remove(item)
                return result

    def get_lists(self, user='******'):
        return Trakt['users/*/lists'].get(username=user)

    def get_list_items(self, id, user='******'):
        return Trakt['users/*/lists/*'].get(username=user, id=id)

    def get_watchlist(self, user='******'):
        return Trakt['users/*/watchlist'].get(username=user, parse=False)

    @staticmethod
    def script_trakt():
        return Addon('script.trakt')

    @staticmethod
    def is_enabled():
        return settings.get_setting_as_bool(
            'trakt.enabled') and settings.get_setting('trakt.authorization')

    @staticmethod
    def can_check():
        return home_win.getProperty(
            'check_trakt') == '' and TraktAPI.is_enabled(
            ) and not player.isPlaying()

    @staticmethod
    def clean_prop():
        home_win.clearProperty('check_trakt')

    def check_trakt(self, force=False):
        if TraktAPI.can_check() or force:
            home_win.setProperty('check_trakt', '1')
            if self.initialized is False:
                self.initialize()
            # debug('check trakt')
            data = self.get_last_activities()
            if data is None:
                debug('trakt data is NONE')
                self.clean_prop()
                return None

            for check in CHECK_SYNC.items():
                synced = False
                item = data.get(check[0])
                for a, i in enumerate(item):
                    if i in check[1]:
                        key = 'sync.{}'.format(check[0])
                        if self.storage[key].get(i) != item.get(i):
                            debug('zmena {}[{}] z {} na {}'.format(
                                key, i, self.storage[key].get(i), item.get(i)))
                            if not synced:
                                synced = True
                                try:
                                    if self.sync_local(
                                            check[0],
                                            self.storage[key].get(i),
                                            force=force):
                                        self.storage[key].update(
                                            {i: item.get(i)})
                                except:
                                    debug('TRAKT ERR: {}'.format(
                                        traceback.format_exc()))
                                    pass
            self.clean_prop()

    def sync_playback_movies(self, last=0):
        last_at = TraktAPI.utc2timestamp(last)
        playback = self.get_playback_movies({})
        debug('paused at {}'.format(len(playback)))
        sync = {}
        tr = []
        for m in playback:
            paused_at = TraktAPI.utc2timestamp(m['paused_at'])
            if paused_at is None or last_at is None or paused_at >= last_at:
                sync.update({m['movie']['ids']['trakt']: m})
                tr.append(m['movie']['ids']['trakt'])
        if len(sync):
            res = Sc.post('/Ftrakt2sc', data={'trakt': dumps(tr), 't': 1})
            debug('sync {} / {}     {}'.format(len(sync), len(res), res))
            max = len(res)
            dialog = dprogressgb()
            dialog.create('sync_playback_movies Trakt.Movies')
            for pos, scid in enumerate(res):
                if self.monitor.abortRequested():
                    return

                debug('trakt {}%'.format(int(pos / max * 100)))
                dialog.update(int(pos / max * 100))
                itm = res.get(scid)
                item = SCKODIItem(scid, trakt=itm['trakt'])
                tr = sync.get(int(itm['trakt']))
                progress = float(sync.get(int(itm['trakt']))['progress'])
                try:
                    watched = int(
                        float(itm['duration']) * float(progress / 100))
                except:
                    watched = 0
                debug('itm {} {} {} {} {} {}'.format(scid, itm,
                                                     itm['duration'], watched,
                                                     progress, tr))
                item.set_watched(watched)
                d = datetime.fromtimestamp(
                    self.utc2timestamp(tr.get('paused_at')))
                item.set_last_played(d.strftime('%Y-%m-%d %H:%M:%S'))
            dialog.close()
        pass

    def sync_local(self, type, last, force=False):
        if type == 'movies':
            return self.sync_local_movies(last)
        else:
            return self.sync_local_episodes(last, force=force)

    def scroble(self, id, season=None, episode=None, percent=0, action='stop'):
        data = {
            "action": action,
            "progress": float(percent),
            "parse": False,
        }
        if season is not None:
            # ep_info = self.get_episode_info(id, season, episode)
            data.update({
                "show": {
                    "ids": {
                        "trakt": id
                    }
                },
                "episode": {
                    "season": season,
                    "number": episode
                }
            })
        else:
            data.update({"movie": {"ids": {"trakt": id}}})
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                debug('scrobble obj: {}'.format(data))
                try:
                    result = Trakt['scrobble'].action(**data).json()
                except:
                    result = None
                return result
        pass

    def sync_get_list(self, data, typ):
        data = list(data.items())
        items = {}
        for _, item in data:
            item = item.to_dict()
            # debug("------ film\n{}".format(movie))
            tr = item['ids']['trakt']
            items.update({tr: item})
        return self.trakt2sc(items, typ)

    def trakt2sc(self, items, typ):
        debug('items {}'.format(len(items)))
        res = Sc.post('/Ftrakt2sc',
                      data={
                          'trakt': dumps(list(items.keys())),
                          't': typ
                      })
        debug('res: {}'.format(len(res)))
        return res, items

    def sync_local_episodes(self, last=0, force=False):
        last_at = TraktAPI.utc2timestamp(last)
        dialog = dprogressgb()
        dialog.create('sync_local_episodes Trakt.TVShow')
        debug('sync local episodes {} / {}'.format(last, last_at))
        if force:
            data = self.get_shows_watched({})
        else:
            data = self.get_shows_history(datetime.utcfromtimestamp(last_at))
        if data == []:
            dialog.close()
            return True
        items = {}
        for trid, num, eps in data:
            if self.abortRequested():
                dialog.close()
                return False
            items.update({trid: eps})
        res, items = self.trakt2sc(items, 3)
        pos = 0
        total = len(res)
        for scid, trid in res.items():
            if self.abortRequested():
                dialog.close()
                return False
            pos += 1
            max_time = 0
            last_ep = None
            debug('episodes: {}%'.format(int(pos / total * 100)))
            dialog.update(int(pos / total * 100))
            item = SCKODIItem(scid)
            debug('ITEM: {}'.format(item.data))
            for s, e, watched_at in items[int(trid['trakt'])]:
                item.series = s
                item.episode = e
                if self.abortRequested():
                    dialog.close()
                    return False
                wa = TraktAPI.utc2timestamp(watched_at)

                if int(wa) >= int(max_time):
                    ''' ak su epizody vsetky oznacene ako videne v rovnaky cas alebo novsie '''
                    max_time = wa
                    last_ep = (s, e)

                old = item.get_play_count()
                if force or old is None or last_at is None or wa >= last_at:
                    debug('SCID ADD {} {}x{}'.format(scid, s, e))
                    item.set_play_count('1')

            if item and last_ep is not None:
                item.set_last_ep(last_ep[0], last_ep[1], max_time)
        dialog.close()
        return True

    def abortRequested(self):
        return self.monitor.abortRequested() or player.isPlayback()

    def sync_local_movies(self, last):
        self.sync_playback_movies(last)
        data = self.get_movies_watched({})
        res, movies = self.sync_get_list(data, 1)
        debug('res: {}'.format(len(res)))
        all_items = self.storage['watched.movies'].get()[:]
        # debug('na zaciatku {}'.format(all_items))
        dialog = dprogressgb()
        dialog.create('sync_local_movies Trakt.Movies 1')
        pos = 0
        max = len(res)
        for scid, trid in res.items():
            if self.monitor.abortRequested():
                return False
            pos += 1
            dialog.update(int(pos / max * 100))
            # debug('SCID: {}'.format(scid))
            # debug('w {}'.format(self.storage['watched.{}'.format(type)]))
            item = SCKODIItem(scid)
            if scid not in all_items:
                debug('pridavam do zoznamu {}'.format(scid))
                self.storage['watched.movies'].add(scid)
                item.set_play_count('1')
            else:
                all_items.remove(scid)
            pass
            # debug('{} -> {}'.format(scid, movies.get(trid)))
        dialog.close()
        dialog.create('sync_local_movies Trakt.Movies 2')
        # debug('Zostali nam po synchre: {}'.format(all_items))
        if len(all_items) > 0:
            max = len(all_items)
            pos = 0
            for scid in all_items:
                if self.monitor.abortRequested():
                    return False
                pos += 1
                dialog.update(int(pos / max * 100))
                # debug('mazem {}'.format(scid))
                self.storage['watched.movies'].add(scid, remove_only=True)
                item = SCKODIItem(scid)
                item.set_play_count(None)
        dialog.close()
        return True
        # debug('res: {}/{}'.format(len(res), res))

    @staticmethod
    def utc2timestamp(to_convert):
        if to_convert:
            date_format = "%s"
            try:
                naive = dateutil.parser.parse(to_convert)
                utc = naive.replace(tzinfo=tzutc())
            except ValueError:
                debug('utc2timestamp() problem, nastavujem aktualny cas')
                utc = datetime.now()
            try:
                to_convert = int(utc.strftime(date_format))
            except:
                to_convert = int(utc.timestamp())

        return to_convert

    def set_watched(self, trid, times=None, season=None, episode=None):
        if season is None:
            if 'trakt' in trid:
                obj = {"movies": [{"ids": {"trakt": int(trid.get('trakt'))}}]}
            else:
                obj = {"movies": [{"ids": {"trakt": int(trid)}}]}
        else:
            ep_info = self.get_episode_info(int(trid), season, episode)
            debug('EP INFO: {}'.format(ep_info))
            if ep_info:
                obj = {"episodes": [{"ids": ep_info.get('ids', {})}]}
            else:
                obj = {
                    "shows": [{
                        "ids": {
                            "trakt": int(trid)
                        },
                        "seasons": {
                            "number": season,
                            "episodes": [{
                                "number": episode
                            }]
                        }
                    }]
                }
        debug('posielam obj: {}'.format(dumps(obj)))
        if times is not None and int(times) > 0:
            ret = self.add_to_history(obj)
        else:
            ret = self.remove_from_history(obj)
        debug('Hotovo trakt history.... {}'.format(ret))

    def show_items(self, items, sc):
        sc.url = '/Search/getTrakt'
        sc.payload = {'ids': dumps(items)}
        sc.call_url_and_response()

    def action(self, action, sc):
        from resources.lib.params import params
        debug('trakt action: {} / {}'.format(action, params.args))
        if action == 'trakt.login':
            set_setting_as_bool('trakt.enabled', True)
            self.login()
        elif action == 'trakt.logout':
            set_setting('trakt.authorization', '')
            set_setting('trakt.user', '')
        elif action == 'trakt.list':
            u = 'me' if not params.args.get('user',
                                            None) else params.args.get('user')
            if u == 'me':
                for i in ['watchlist']:
                    itm = {
                        'type': 'action',
                        'title': i,
                        'action': 'trakt.list.items',
                        'id': i,
                        'user': u
                    }
                    item = SCItem(itm)
                    if item.visible:
                        sc.items.append(item.get())

            for l in self.get_lists(user=u):
                # l.name = l.name.encode('utf-8')
                itm = {
                    'type': 'action',
                    'title': l.name,
                    'action': 'trakt.list.items',
                    'id': l.id,
                    'user': u
                }
                item = SCItem(itm)
                if item.visible:
                    sc.items.append(item.get())
        elif action == 'trakt.sync.shows':
            self.sync_local_episodes(last=0, force=True)
        elif action == 'trakt.list.items':
            u = 'me' if not params.args.get('user',
                                            None) else params.args.get('user')
            name = params.args.get('id')
            if name == 'watchlist':
                data = self.get_watchlist(u).json()
            else:
                data = self.get_list_items(name, u).items(parse=False).json()
            items = []
            for i in data:
                t = i.get('type')
                debug('item: {} {}'.format(t, i))
                if t not in ['movie', 'tvshow', 'show']:
                    continue
                sc_type = 1 if t == 'movie' else 3
                data = i.get(t, {})
                ids = data.get('ids')
                tr = ids.get('trakt')
                itm = "{},{}".format(sc_type, tr)
                items.append(itm)
            debug('items: {}'.format(items))
            self.show_items(items, sc)
        else:
            debug('Neznama akcia trakt.tv {}'.format(action))
        sc.succeeded = True
        sc.end()
    def resolve(self):
        data = self.data
        del (data[SC.ITEM_URL])
        self.streams = self.input.get(SC.ITEM_STRMS)
        self.filter()

        items = []
        matrix = []
        for s in self.streams:
            debug('ideme vytvorit listItems zo streamov')
            s.update(data)
            itm = SCStreamSelect(s)
            x = itm.get()
            title_items = [
                '[B]{}[/B] - '.format(s.get(SC.ITEM_LANG)),
                '[B]{}[/B] '.format(s.get(SC.ITEM_QUALITY)),
                '{} '.format(s.get(SC.ITEM_SIZE)),
                '{}{}'.format(s.get(SC.ITEM_VIDEO_INFO),
                              s.get(SC.ITEM_AUDIO_INFO)),
            ]
            matrix.append(title_items)
            items.append(x[1])
        # matrix = make_table(matrix)
        # info('matrix: {}'.format(matrix))
        for i, itm in enumerate(items):
            itm.setProperty('old_title', itm.getLabel())
            itm.setLabel(' '.join(matrix[i]))

        if len(
                items
        ) > 1 or SC.ACTION_SELECT_STREAM in self.params or SC.ACTION_DOWNLOAD in self.params:
            pos = dselect(items,
                          heading=items[0].getProperty('old_title'),
                          use_details=True)
            # info('post: {} | {}'.format(pos, json.dumps(self.data)))
            if pos is False or pos == -1:
                raise BaseException
            res = items[pos]
            self.selected = self.streams[pos]
        elif len(items) == 1:
            res = items[0]
            self.selected = self.streams[
                0] if self.selected is None else self.selected
        else:
            raise BaseException

        url = res.getPath()
        # info('vybrany stream: {} / {}'.format(res.getPath(), self.selected))
        if res.getProperty(SC.ITEM_PROVIDER) == SC.PROVIDER:
            resp = Sc.get(res.getPath())
            kr = Kraska()
            try:
                ident = resp.get(SC.ITEM_IDENT)
                debug('ideme resolvovat ident {} na kra.sk'.format(ident))
                url = kr.resolve(ident)
            except ResolveException as e:
                dok(Strings.txt(Strings.RESOLVE_ERROR_H1),
                    Strings.txt(Strings.RESOLVE_ERROR_L1))
                raise BaseException
            except:
                raise BaseException
            if res.getProperty(SC.ITEM_SUBS):
                debug('subor ma titulky, tak ich natahujem')
                part = res.getProperty(SC.ITEM_SUBS).split('/file/')
                self.item.setSubtitles([kr.resolve(part[1])])
            else:
                info('nemame titulky')

        info('resolve: {}'.format(url))
        if 'lid' in data:
            lid = 'p-{}'.format(
                data.get('lid')) if parental_history() else data.get('lid')
            st = List(lid, max_items=20)
            st.add(res.getProperty(SC.ITEM_ID))
        self.item.setPath(url)
        self.item.setLabel(res.getProperty('original_title'))
        # home_win.setProperty('SC-lite-item', '{}'.format(res.getProperty(SC.ITEM_ID)))

        if 'unique_ids' in self.input.get(SC.ITEM_INFO):
            unique_ids = self.input.get(SC.ITEM_INFO).get('unique_ids')
            home_win.setProperty('script.trakt.ids',
                                 '{}'.format(dumps(unique_ids)))
            home_win.setProperty('{}.ids'.format(ADDON_ID),
                                 '{}'.format(dumps(unique_ids)))
from resources.lib.common.logger import info, debug
from resources.lib.common.storage import preferred_lang_list
from resources.lib.constants import ADDON_ID, SC, GUI
from resources.lib.debug import try_catch
from resources.lib.gui import get_cond_visibility as gcv, home_win
from resources.lib.gui.dialog import dselect, dok
from resources.lib.kodiutils import create_plugin_url, convert_bitrate, get_setting_as_bool, get_setting_as_int, \
    get_setting, get_info_label, get_system_platform, decode, make_nfo_content, translate_path, make_legal_filename, \
    microtime, get_isp
from resources.lib.language import Strings
from resources.lib.params import params
from resources.lib.services.Settings import settings
from resources.lib.system import SYSTEM_LANG_CODE

list_item = ListItem
list_hp = List('HP')


def parental_history():
    return get_setting_as_bool(
        'parental.control.enabled'
    )  # and get_setting_as_bool('parental.control.history')


def get_history_item_name(item):
    return 'p-{}'.format(item) if parental_history() else item


class SCItem:
    def __init__(self, data):
        self.item = None
 def __init__(self):
     KodiDb.__init__(self)
     self.list = List('android')
     self.last_run = 0