def play_external(self, **kwargs):
     kodi_log(['lib.container.router - Attempting to play item\n', kwargs],
              1)
     if not kwargs.get('tmdb_id'):
         kwargs['tmdb_id'] = self.tmdb_api.get_tmdb_id(**kwargs)
     Players(**kwargs).play(
         handle=self.handle if self.handle != -1 else None)
Esempio n. 2
0
def convert_timestamp(time_str,
                      time_fmt="%Y-%m-%dT%H:%M:%S",
                      time_lim=19,
                      utc_convert=False):
    if not time_str:
        return
    time_str = time_str[:time_lim] if time_lim else time_str
    utc_offset = 0
    if utc_convert:
        utc_offset = -time.timezone // 3600
        utc_offset += 1 if time.localtime().tm_isdst > 0 else 0
    try:
        time_obj = datetime.datetime.strptime(time_str, time_fmt)
        time_obj = time_obj + datetime.timedelta(hours=utc_offset)
        return time_obj
    except TypeError:
        try:
            time_obj = datetime.datetime(
                *(time.strptime(time_str, time_fmt)[0:6]))
            time_obj = time_obj + datetime.timedelta(hours=utc_offset)
            return time_obj
        except Exception as exc:
            kodi_log(exc, 1)
            return
    except Exception as exc:
        kodi_log(exc, 1)
        return
 def fivehundred_error(self, request):
     self.req_500_err[request] = set_timestamp()
     get_property(self.req_500_err_prop, dumps(self.req_500_err))
     kodi_log(u'ConnectionError: {}\nSuppressing retries for 1 minute'.format(dumps(self.req_500_err)), 1)
     xbmcgui.Dialog().notification(
         ADDON.getLocalizedString(32308).format(self.req_api_name),
         ADDON.getLocalizedString(32307))
    def refresh_token(self):
        # Check we haven't attempted too many refresh attempts
        refresh_attempts = try_int(get_property('TraktRefreshAttempts')) + 1
        if refresh_attempts > 5:
            kodi_log(
                'Trakt Unauthorised!\nExceeded refresh_token attempt limit\nSuppressing retries for 10 minutes',
                1)
            get_property('TraktRefreshTimeStamp', set_timestamp(600))
            get_property('TraktRefreshAttempts', 0)  # Reset refresh attempts
            return
        get_property('TraktRefreshAttempts', refresh_attempts)

        kodi_log('Attempting to refresh Trakt token', 2)
        if not self.authorization or not self.authorization.get(
                'refresh_token'):
            kodi_log('Trakt refresh token not found!', 1)
            return
        postdata = {
            'refresh_token': self.authorization.get('refresh_token'),
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob',
            'grant_type': 'refresh_token'
        }
        self.authorization = self.get_api_request_json(
            'https://api.trakt.tv/oauth/token', postdata=postdata)
        if not self.authorization or not self.authorization.get(
                'access_token'):
            kodi_log('Failed to refresh Trakt token!', 2)
            return
        self.on_authenticated(auth_dialog=False)
        kodi_log('Trakt token refreshed', 1)
        return self.authorization
 def connection_error(self, err):
     self.req_connect_err = set_timestamp()
     get_property(self.req_connect_err_prop, self.req_connect_err)
     kodi_log(u'ConnectionError: {}\nSuppressing retries for 1 minute'.format(err), 1)
     xbmcgui.Dialog().notification(
         ADDON.getLocalizedString(32308).format(self.req_api_name),
         ADDON.getLocalizedString(32307))
Esempio n. 6
0
 def on_authenticated(self, auth_dialog=True):
     """Triggered when device authentication has been completed"""
     kodi_log(u'Trakt authenticated successfully!', 1)
     ADDON.setSettingString('trakt_token', dumps(self.authorization))
     self.headers['Authorization'] = u'Bearer {0}'.format(self.authorization.get('access_token'))
     if auth_dialog:
         self.auth_dialog.close()
Esempio n. 7
0
 def _get_database(self):
     '''get reference to our sqllite _database - performs basic integrity check'''
     try:
         connection = sqlite3.connect(self._db_file,
                                      timeout=30,
                                      isolation_level=None)
         connection.execute('SELECT * FROM simplecache LIMIT 1')
         return connection
     except Exception:
         # our _database is corrupt or doesn't exist yet, we simply try to recreate it
         if xbmcvfs.exists(self._db_file):
             xbmcvfs.delete(self._db_file)
         try:
             connection = sqlite3.connect(self._db_file,
                                          timeout=30,
                                          isolation_level=None)
             connection.execute("""CREATE TABLE IF NOT EXISTS simplecache(
                 id TEXT UNIQUE, expires INTEGER, data TEXT, checksum INTEGER)"""
                                )
             return connection
         except Exception as error:
             kodi_log(
                 "CACHE: Exception while initializing _database: {}".format(
                     error), 1)
             self.close()
             return None
Esempio n. 8
0
 def _execute_sql(self, query, data=None):
     '''little wrapper around execute and executemany to just retry a db command if db is locked'''
     retries = 0
     result = None
     error = None
     # always use new db object because we need to be sure that data is available for other simplecache instances
     with self._get_database() as _database:
         while not retries == 10 and not self._monitor.abortRequested():
             if self._exit:
                 return None
             try:
                 if isinstance(data, list):
                     result = _database.executemany(query, data)
                 elif data:
                     result = _database.execute(query, data)
                 else:
                     result = _database.execute(query)
                 return result
             except sqlite3.OperationalError as error:
                 if "_database is locked" in error:
                     kodi_log("CACHE: retrying DB commit...")
                     retries += 1
                     self._monitor.waitForAbort(0.5)
                 else:
                     break
             except Exception:
                 break
         kodi_log("CACHE: _database ERROR ! -- {}".format(error), 1)
     return None
Esempio n. 9
0
def create_file(content, filename, *args, **kwargs):
    """
    Create the file and folder structure: filename=.strm file, content= content of file.
    *args = folders to create.
    """

    # Validify and build path
    path = kwargs.get('basedir', '').replace('\\', '/')  # Convert MS-DOS style paths to UNIX style
    if not path:  # Make sure we actually have a basedir
        return
    for folder in args:
        folder = validify_filename(folder)
        path = '{}{}/'.format(path, folder)

    # Validify content of file
    if kwargs.get('clean_url', True):
        content = clean_content(content)
    if not content:
        return
    if not filename:
        return

    # Check that we can actually make the path
    if not make_path(path, warn_dialog=True):
        return

    # Write out our file
    filepath = '{}{}.{}'.format(path, validify_filename(filename), kwargs.get('file_ext', 'strm'))
    write_to_file(filepath, content)
    kodi_log(['ADD LIBRARY -- Successfully added:\n', filepath, '\n', content], 2)
    return filepath
Esempio n. 10
0
def library_autoupdate(list_slugs=None,
                       user_slugs=None,
                       busy_spinner=False,
                       force=False):
    kodi_log(u'UPDATING TV SHOWS LIBRARY', 1)
    xbmcgui.Dialog().notification(
        'TMDbHelper', u'{}...'.format(ADDON.getLocalizedString(32167)))

    # Update library from Trakt lists
    library_adder = None
    user_lists = _get_monitor_userlists(list_slugs, user_slugs)
    for list_slug, user_slug in user_lists:
        library_adder = add_to_library(info='trakt',
                                       user_slug=user_slug,
                                       list_slug=list_slug,
                                       confirm=False,
                                       allow_update=False,
                                       busy_spinner=busy_spinner,
                                       force=force,
                                       library_adder=library_adder,
                                       finished=False)

    # Update library from nfos
    add_to_library(info='update',
                   busy_spinner=busy_spinner,
                   library_adder=library_adder,
                   finished=True,
                   force=force)
Esempio n. 11
0
 def get_stored_token(self):
     try:
         token = loads(ADDON.getSettingString('trakt_token')) or {}
     except Exception as exc:
         token = {}
         kodi_log(exc, 1)
     return token
Esempio n. 12
0
 def get_simple_api_request(self,
                            request=None,
                            postdata=None,
                            headers=None,
                            method=None):
     try:
         if method == 'delete':
             return requests.delete(request,
                                    headers=headers,
                                    timeout=self.timeout)
         if method == 'put':
             return requests.put(request,
                                 data=postdata,
                                 headers=headers,
                                 timeout=self.timeout)
         if postdata or method == 'post':  # If pass postdata assume we want to post
             return requests.post(request,
                                  data=postdata,
                                  headers=headers,
                                  timeout=self.timeout)
         return requests.get(request, headers=headers, timeout=self.timeout)
     except requests.exceptions.ConnectionError as errc:
         self.connection_error(errc)
     except requests.exceptions.Timeout as errt:
         self.timeout_error(errt)
     except Exception as err:
         kodi_log(u'RequestError: {}'.format(err), 1)
    def colors(self, source):
        filename = '{}.png'.format(md5hash(source))
        destination = self.save_path + filename

        try:
            if xbmcvfs.exists(destination):
                os.utime(destination, None)
                img = Image.open(xbmc.translatePath(destination))
            else:
                img = _openimage(source, self.save_path, filename)
                img.thumbnail((256, 256))
                img = img.convert('RGB')
                img.save(destination)

            maincolor_rgb = self.get_maincolor(img)
            maincolor_hex = self.rgb_to_hex(*self.get_color_lumsat(
                *maincolor_rgb))
            compcolor_rgb = self.get_compcolor(*maincolor_rgb)
            compcolor_hex = self.rgb_to_hex(*self.get_color_lumsat(
                *compcolor_rgb))

            maincolor_propname = self.save_prop + '.Main'
            maincolor_propchek = self.save_prop + '.MainCheck'
            maincolor_propvalu = get_property(maincolor_propname)
            if not maincolor_propvalu:
                get_property(maincolor_propname, set_property=maincolor_hex)
            else:
                get_property(maincolor_propchek,
                             set_property=maincolor_propvalu)
                thread_maincolor = Thread(target=self.set_prop_colorgradient,
                                          args=[
                                              maincolor_propname,
                                              maincolor_propvalu,
                                              maincolor_hex, maincolor_propchek
                                          ])
                thread_maincolor.start()

            compcolor_propname = self.save_prop + '.Comp'
            compcolor_propchek = self.save_prop + '.CompCheck'
            compcolor_propvalu = get_property(compcolor_propname)
            if not compcolor_propvalu:
                get_property(compcolor_propname, set_property=compcolor_hex)
            else:
                get_property(compcolor_propchek,
                             set_property=compcolor_propvalu)
                thread_compcolor = Thread(target=self.set_prop_colorgradient,
                                          args=[
                                              compcolor_propname,
                                              compcolor_propvalu,
                                              compcolor_hex, compcolor_propchek
                                          ])
                thread_compcolor.start()

            img.close()
            return maincolor_hex

        except Exception as exc:
            kodi_log(exc, 1)
            return ''
 def wrapper(self, *args, **kwargs):
     """ Syntactic sugar to log output of function """
     response = func(self, *args, **kwargs)
     log_text = '{}.{}.'.format(self.__class__.__name__, func_name)
     log_text = format_name(log_text, *args, **kwargs)
     kodi_log(log_text, 1)
     kodi_log(response, 1)
     return response
Esempio n. 15
0
 def _create(self, title='', message='', total=100):
     self._pd = xbmcgui.DialogProgressBG()
     self._pd.create(title, message)
     self._count = 0
     self._total = total
     self._title = title
     kodi_log([self._title, ' - 00 ', message], self.logging)
     return self._pd
Esempio n. 16
0
def run_plugin(**kwargs):
    with busy_dialog():
        kodi_log([
            'lib.script.router - attempting to play\n',
            kwargs.get('run_plugin')
        ], 1)
        xbmc.executebuiltin(
            try_encode(u'RunPlugin({})'.format(kwargs.get('run_plugin'))))
Esempio n. 17
0
def play_media(**kwargs):
    with busy_dialog():
        kodi_log([
            'lib.script.router - attempting to play\n',
            kwargs.get('play_media')
        ], 1)
        xbmc.executebuiltin(
            try_encode(u'PlayMedia({})'.format(kwargs.get('play_media'))))
Esempio n. 18
0
 def close(self):
     '''tell any tasks to stop immediately (as we can be called multithreaded) and cleanup objects'''
     self._exit = True
     # wait for all tasks to complete
     while self._busy_tasks and not self._monitor.abortRequested():
         xbmc.sleep(25)
     del self._win
     del self._monitor
     kodi_log("CACHE: Closed")
Esempio n. 19
0
def timer_func(timer_name):
    timer_a = timer()
    try:
        yield
    finally:
        timer_z = timer()
        total_time = timer_z - timer_a
        if total_time > 0.05:
            kodi_log(u'{}\n{:.3f} sec'.format(timer_name, total_time), 1)
Esempio n. 20
0
 def set_property(self, key, value):
     key = '{}.{}'.format(self.property_prefix, key)
     try:
         if value is None:
             get_property(key, clear_property=True)
         else:
             get_property(key, set_property=u'{0}'.format(value))
     except Exception as exc:
         kodi_log(u'set_property: {}{}'.format(key, exc), 1)
 def connection_error(self, err, wait_time=30, msg_affix=''):
     self.req_connect_err = set_timestamp(wait_time)
     get_property(self.req_connect_err_prop, self.req_connect_err)
     kodi_log(
         u'ConnectionError: {} {}\nSuppressing retries for 30 seconds'.
         format(msg_affix, err), 1)
     xbmcgui.Dialog().notification(
         ADDON.getLocalizedString(32308).format(' '.join(
             [self.req_api_name, msg_affix])),
         ADDON.getLocalizedString(32307).format('30'))
 def timeout_error(self, err):
     """ Log timeout error
     If two timeouts occur in x3 the timeout limit then set connection error
     e.g. if timeout limit is 10s then two timeouts within 30s trigger connection error
     """
     kodi_log(u'ConnectionTimeOut: {}'.format(err), 1)
     if get_timestamp(self.req_timeout_err):
         self.connection_error(err, msg_affix='timeout')
     self.req_timeout_err = set_timestamp(self.timeout * 3)
     get_property(self.req_timeout_err_prop, self.req_timeout_err)
Esempio n. 23
0
 def set_list_properties(self, items, key, prop):
     if not isinstance(items, list):
         return
     try:
         joinlist = [i[key] for i in items[:10] if i.get(key)]
         joinlist = ' / '.join(joinlist)
         self.properties.add(prop)
         self.set_property(prop, joinlist)
     except Exception as exc:
         kodi_log(u'Func: set_list_properties\n{0}'.format(exc), 1)
 def clear_dir(self, folder):
     for filename in os.listdir(folder):
         file_path = os.path.join(folder, filename)
         try:
             if os.path.isfile(file_path):
                 os.unlink(file_path)
             elif os.path.isdir(file_path):
                 self.recursive_delete_dir(file_path)
         except Exception as e:
             kodi_log(u'Could not delete file {0}: {1}'.format(file_path, str(e)))
 def get_database(self, dbtype, tvshowid=None, attempt_reconnect=False, logging=True):
     retries = 5 if attempt_reconnect else 1
     while not xbmc.Monitor().abortRequested() and retries > 0:
         database = self._get_kodi_db(dbtype, tvshowid)
         if database:
             return database
         xbmc.Monitor().waitForAbort(1)
         retries -= 1
     if logging:
         kodi_log(u'Getting KodiDB {} FAILED!'.format(dbtype), 1)
Esempio n. 26
0
 def __init__(self, folder=None, filename=None, mem_only=False):
     '''Initialize our caching class'''
     folder = folder or 'database'
     filename = filename or 'defaultcache.db'
     self._win = xbmcgui.Window(10000)
     self._monitor = xbmc.Monitor()
     self._db_file = get_file_path(folder, filename)
     self._sc_name = '{}_{}_simplecache'.format(folder, filename)
     self._mem_only = mem_only
     self.check_cleanup()
     kodi_log("CACHE: Initialized")
Esempio n. 27
0
def _openimage(image, targetpath, filename):
    """ Open image helper with thanks to sualfred """
    # some paths require unquoting to get a valid cached thumb hash
    cached_image_path = urllib.unquote(image.replace('image://', ''))
    if cached_image_path.endswith('/'):
        cached_image_path = cached_image_path[:-1]

    cached_files = []
    for path in [xbmc.getCacheThumbName(cached_image_path), xbmc.getCacheThumbName(image)]:
        cached_files.append(os.path.join('special://profile/Thumbnails/', path[0], path[:-4] + '.jpg'))
        cached_files.append(os.path.join('special://profile/Thumbnails/', path[0], path[:-4] + '.png'))
        cached_files.append(os.path.join('special://profile/Thumbnails/Video/', path[0], path))

    for i in range(1, 4):
        try:
            ''' Try to get cached image at first
            '''
            for cache in cached_files:
                if xbmcvfs.exists(cache):
                    try:
                        img = _imageopen(xbmcvfs.translatePath(cache))
                        return img

                    except Exception as error:
                        kodi_log('Image error: Could not open cached image --> %s' % error, 2)

            ''' Skin images will be tried to be accessed directly. For all other ones
                the source will be copied to the addon_data folder to get access.
            '''
            if xbmc.skinHasImage(image):
                if not image.startswith('special://skin'):
                    image = os.path.join('special://skin/media/', image)

                try:  # in case image is packed in textures.xbt
                    img = _imageopen(xbmcvfs.translatePath(image))
                    return img

                except Exception:
                    return ''

            else:
                targetfile = os.path.join(targetpath, filename)
                if not xbmcvfs.exists(targetfile):
                    xbmcvfs.copy(image, targetfile)

                img = _imageopen(targetfile)
                return img

        except Exception as error:
            kodi_log('Image error: Could not get image for %s (try %d) -> %s' % (image, i, error), 2)
            xbmc.sleep(500)
            pass

    return ''
 def is_unaired(self, format_label=u'[COLOR=ffcc0000][I]{}[/I][/COLOR]', check_hide_settings=True):
     try:
         if not is_future_timestamp(self.infolabels.get('premiered'), "%Y-%m-%d", 10):
             return
         if format_label:
             self.label = format_label.format(self.label)
     except Exception as exc:
         kodi_log(u'Error: {}'.format(exc), 1)
     if not check_hide_settings:
         return True
     return self.unaired_bool()
 def wrapper(self, *args, **kwargs):
     """ Syntactic sugar to time a class function """
     timer_a = timer()
     response = func(self, *args, **kwargs)
     timer_z = timer()
     total_time = timer_z - timer_a
     if total_time > 0.001:
         timer_name = '{}.{}.'.format(self.__class__.__name__,
                                      func_name)
         timer_name = format_name(timer_name, *args, **kwargs)
         kodi_log('{}\n{:.3f} sec'.format(timer_name, total_time), 1)
     return response
 def set_params_to_container(self, **kwargs):
     for k, v in viewitems(kwargs):
         if not k or not v:
             continue
         try:
             xbmcplugin.setProperty(
                 self.handle, u'Param.{}'.format(k),
                 u'{}'.format(v))  # Set params to container properties
         except Exception as exc:
             kodi_log(
                 u'Error: {}\nUnable to set Param.{} to {}'.format(
                     exc, k, v), 1)