def post_data(self,
                  url,
                  data_in,
                  custom_timeout=int(plugin_addon.getSetting('timeout'))):
        """
        Send a message to the server and wait for a response
        Args:
            url: the URL to send the data to
            data_in: the message to send (in json)
            custom_timeout: if not given timeout from plugin setting will be used

        Returns: The response from the server
        """
        import error_handler as eh
        from error_handler import ErrorPriority
        if data_in is None:
            data_in = b''

        headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }

        apikey = plugin_addon.getSetting('apikey')
        if apikey is not None and apikey != '':
            headers['apikey'] = apikey

        eh.spam('POSTing Data ---')
        eh.spam('URL:', url)
        eh.spam('Headers:', headers)
        eh.spam('POST Body:', data_in)

        try:
            # self.encode(url) # py3 fix
            req = Request(url, self.encode(data_in), headers)
            data_out = None

            response = urlopen(req, timeout=custom_timeout)
            data_out = response.read()
            response.close()
            eh.spam('Response Body:', data_out)
            eh.spam('Checking Response for a text error.\n')
            if data_out is not None and data_out != '':
                self.parse_possible_error(req, data_out)
        except timeout:
            # if using very short time out to not wait for response it will throw time out err,
            # but we check if that was intended by checking custom_timeout
            # if it wasn't intended we handle it the old way
            if custom_timeout == int(plugin_addon.getSetting('timeout')):
                eh.exception(ErrorPriority.HIGH)
        except http_error as err:
            raise err
        except Exception as ex:
            xbmc.log('==== post_data error ==== %s ' % ex, xbmc.LOGNOTICE)
            eh.exception(ErrorPriority.HIGH)

        return data_out
예제 #2
0
def send_profile():
    eh.spam('Trying to send_profile(). Wish me luck!')
    log_setsuzoku(Category.EIGAKAN, Action.PROFILE, Event.SEND)
    # setup client on server
    settings = {}

    # tweak-ninja
    settings['manual_mode'] = plugin_addon.getSetting('eigakan_manual_mode')
    settings['h_resolution'] = plugin_addon.getSetting('eigakan_h_resolution')
    settings['h_bitrate'] = plugin_addon.getSetting('eigakan_h_bitrate')
    settings['l_resolution'] = plugin_addon.getSetting('eigakan_l_resolution')
    settings['l_bitrate'] = plugin_addon.getSetting('eigakan_l_bitrate')
    settings['x264_preset'] = plugin_addon.getSetting('eigakan_x264_preset')
    settings['burn_subs'] = plugin_addon.getSetting('burnEigakan')
    # lang-master
    settings['pref_audio'] = plugin_addon.getSetting('audiolangEigakan')
    settings['pref_subs'] = plugin_addon.getSetting('subEigakan')

    settings = json.dumps(settings)

    eh.spam('send_profile() data = %s' % settings)

    try:
        pyproxy.post_data(eigakan_host + '/api/clientid/%s' % get_device_id(), settings)
        # if no error, lets mark that we did full handshake with eigakan
        plugin_addon.setSetting('eigakan_handshake', 'true')
    except Exception as ex:
        plugin_addon.setSetting('eigakan_handshake', 'false')
        eh.spam('error while send_profile(): %s' % ex)
    def get_json(self, url_in, direct=False, force_cache=False, cache_time=0):
        """
        use 'get' to return json body as string
        :param url_in:
        :param direct: force to bypass cache
        :param force_cache: force to use cache even if disabled
        :param cache_time: ignore setting to set custom cache expiration time, mainly to expire data quicker to refresh watch flags
        :return:
        """

        import error_handler as eh
        from error_handler import ErrorPriority
        try:
            timeout = plugin_addon.getSetting('timeout')
            if self.api_key is None or self.api_key == '':
                apikey = plugin_addon.getSetting('apikey')
            else:
                apikey = self.api_key
            # if cache is disabled, overwrite argument and force it to direct
            if plugin_addon.getSetting('enableCache') != 'true':
                direct = True
            if direct and not force_cache:
                body = self.get_data(url_in, None, timeout, apikey)
            else:
                import cache
                eh.spam('Getting a Cached Response ---')
                eh.spam('URL:', url_in)
                db_row = cache.get_data_from_cache(url_in)
                if db_row is not None:
                    valid_until = cache_time if cache_time > 0 else int(
                        plugin_addon.getSetting('expireCache'))
                    expire_second = time.time() - float(db_row[1])
                    if expire_second > valid_until:
                        # expire, get new date
                        eh.spam('The cached data is stale.')
                        body = self.get_data(url_in, None, timeout, apikey)
                        cache.remove_cache(url_in)
                        cache.add_cache(url_in, body)
                    else:
                        body = db_row[0]
                else:
                    eh.spam('No cached data was found for the URL.')
                    body = self.get_data(url_in, None, timeout, apikey)
                    cache.add_cache(url_in, body)
        except http_error as err:
            raise err
        except Exception as ex:
            xbmc.log(' ========= ERROR JSON ============  %s' % ex,
                     xbmc.LOGNOTICE)
            eh.exception(ErrorPriority.HIGH)
            body = None
        return body
예제 #4
0
def clear_image_cache():
    """
    Clear image cache in kodi db
    :return:
    """
    log_setsuzoku(Category.MAINTENANCE, Action.IMAGE, Event.CLEAN)

    ret = xbmcgui.Dialog().yesno(plugin_addon.getLocalizedString(30104),
                                 plugin_addon.getLocalizedString(30081), plugin_addon.getLocalizedString(30112))
    if ret:
        db_files = []
        db_path = os.path.join(pyproxy.decode(xbmc.translatePath('special://home')), 'userdata')
        db_path = os.path.join(db_path, 'Database')
        for r, d, f in os.walk(db_path):
            for files in f:
                if 'Textures' in files:
                    db_files.append(files)
        for db_file in db_files:
            db_connection = database.connect(os.path.join(db_path, db_file))
            db_cursor = db_connection.cursor()
            db_cursor.execute('DELETE FROM texture WHERE url LIKE "%' + plugin_addon.getSetting('port') + '/api/%"')
            db_connection.commit()
            db_cursor.execute('DELETE FROM texture WHERE url LIKE "%nakamori%"')
            db_connection.commit()
            db_connection.close()
        if len(db_files) > 0:
            xbmcgui.Dialog().ok('', plugin_addon.getLocalizedString(30138))
예제 #5
0
def show_messages():
    # finalize the defaultdict so that it won't create new keys anymore
    __exceptions.default_factory = None
    if len(__exceptions) == 0:
        return
    if ErrorPriority.BLOCKING in __exceptions:
        exes = __exceptions[ErrorPriority.BLOCKING]
        exes = Counter(exes).items()
        exes = sorted(exes)
        print_exceptions(exes)
        show_dialog_for_exception(exes[0])
        sys.exit()
    if ErrorPriority.HIGHEST in __exceptions:
        exes = __exceptions[ErrorPriority.HIGHEST]
        exes = Counter(exes).items()
        exes = sorted(exes)
        print_exceptions(exes)
        show_dialog_for_exception(exes[0])
    if ErrorPriority.HIGH in __exceptions:
        exes = __exceptions[ErrorPriority.HIGH]
        exes = Counter(exes).items()
        exes = sorted(exes)
        print_exceptions(exes)
        show_notification_for_exception(exes[0])
    if ErrorPriority.NORMAL in __exceptions:
        exes = __exceptions[ErrorPriority.NORMAL]
        exes = Counter(exes).items()
        exes = sorted(exes)
        print_exceptions(exes)
    if ErrorPriority.LOW in __exceptions:
        exes = __exceptions[ErrorPriority.LOW]
        exes = Counter(exes).items()
        exes = sorted(exes)
        # log all if we are spamming
        if plugin_addon.getSetting('spamLog') != 'true':
            exes = next([x for x in exes if x[1] > 5], [])
        print_exceptions(exes)
    if plugin_addon.getSetting(
            'spamLog') == 'true' and ErrorPriority.LOWEST in __exceptions:
        exes = __exceptions[ErrorPriority.LOWEST]
        exes = Counter(exes).items()
        exes = sorted(exes)
        # log only if we are spamming
        if plugin_addon.getSetting('spamLog') != 'true':
            exes = next([x for x in exes if x[1] > 5], [])
            print_exceptions(exes)
 def external_player(self, player_obj):
     """
     In Kodi 18+, xbmc.Player has a isExternalPlayer() method. In earlier versions, the user must specify
     :param player_obj: the player object to check
     :return: true or false
     :rtype: bool
     """
     return plugin_addon.getSetting('external_player').lower() == 'true'
 def post_json(self,
               url_in,
               body,
               custom_timeout=int(plugin_addon.getSetting('timeout'))):
     """
     Push data to server using 'POST' method
     :param url_in:
     :param body:
     :param custom_timeout: if not given timeout from plugin setting will be used
     :return:
     """
     if len(body) > 3:
         proper_body = '{' + body + '}'
         return self.post_data(url=url_in,
                               data_in=proper_body,
                               custom_timeout=custom_timeout)
     else:
         return None
예제 #8
0
def exception_internal(exc_type, exc_obj, exc_tb, priority, message=''):
    """
    The priority determines how the system will handle or display the error. The message is self-explanatory.
    sys.exc_info() will give the required information for the first arguments. Otherwise, just pass None to them.
    :param exc_type:
    :param exc_obj:
    :type exc_obj: Exception
    :param exc_tb:
    :param priority: The priority of the Error
    :type priority: ErrorPriority
    :param message: a custom message to give the user. If left blank, it will use the exception's
    :return:
    """
    msg = message
    # apparently sometimes they give us exc_type as a str instead of a type
    if exc_type is None:
        exc_type = 'Exception'
    if not isinstance(exc_type, str):
        exc_type = exc_type.__name__

    place = get_simple_trace(fullpath=True)

    if exc_obj is not None and exc_tb is not None:
        if msg == '':
            msg = str(exc_obj)
        ex = NakamoriError(msg, exc_type, place)
        if priority == ErrorPriority.BLOCKING or plugin_addon.getSetting(
                'spamLog') == 'true':
            for line in traceback.format_exc().replace('\r', '\n').split('\n'):
                # skip empty lines
                if len(line) == 0:
                    continue
                # skip the try_function wrapper
                if ' in try_inner2' in line or 'return func(*args, **kwargs)' in line or 'error_handler' in line:
                    continue

                tr = line.replace('\\', '/').replace(addon_path, '.')
                ex.exc_full_trace.append(tr)
    else:
        ex = NakamoriError(msg, exc_type, place)
    # Learning opportunity! If you don't want it to interrupt you with errors, then change the logic in show_...
    # That way, you will still get logs of the errors, but no interruptions!
    # With the previous logic, you are basically saying `if False: else xbmc.log()`
    __exceptions[priority].append(ex)
예제 #9
0
def check_eigakan():
    try:
        eigakan_data = pyproxy.get_json(eigakan_host + '/api/version')

        if eigakan_data is None:
            return False
        elif 'eigakan' not in eigakan_data:
            # raise RuntimeError('Invalid response from Eigakan')
            return False
        else:
            if plugin_addon.getSetting('eigakan_handshake') == 'false':
                eh.spam('We did not find Eigakan handshake')
                try:
                    pyproxy.get_json(eigakan_host + '/api/clientid/%s' % get_device_id())
                except http_err as err:
                    if int(err.code) == 404:
                        eh.spam('We did not find device profile on Eigakan, sending new one...')
                        plugin_addon.setSetting('eigakan_handshake', 'false')
                        send_profile()
                    else:
                        return False
            return True
    except:
        return False
예제 #10
0
def move_position_on_list(control_list, position=0, absolute=False):
    """
    Move to the position in a list - use episode number for position
    Args:
        control_list: the list control
        position: the move_position_on_listindex of the item not including settings
        absolute: bypass setting and set position directly
    """
    if not absolute:
        if position < 0:
            position = 0
        if plugin_addon.getSetting('show_continue') == 'true':
            position = int(position + 1)
        if get_kodi_setting('filelists.showparentdiritems'):
            position = int(position + 1)
    try:
        control_list.selectItem(position)
        xbmc.log(' move_position_on_list : %s ' % position, xbmc.LOGNOTICE)
    except:
        try:
            control_list.selectItem(position - 1)
        except Exception as e:
            xbmc.log(' -----> ERROR -----> %s' % e, xbmc.LOGNOTICE)
            eh.exception(ErrorPriority.HIGH, localize2(30015))
예제 #11
0
def spam(*args):
    if plugin_addon.getSetting('spamLog') == 'true':
        log(*args)
예제 #12
0
from nakamori_utils.script_utils import log_setsuzoku
from setsuzoku import Category, Action, Event

try:
    from sqlite3 import dbapi2 as database
except:
    # noinspection PyUnresolvedReferences
    from pysqlite2 import dbapi2 as database


localize = script_addon.getLocalizedString
localize2 = lib_addon.getLocalizedString

sorting_types = []

eigakan_url = plugin_addon.getSetting('ipEigakan')
eigakan_port = plugin_addon.getSetting('portEigakan')
eigakan_host = 'http://' + eigakan_url + ':' + eigakan_port


class Sorting(object):
    class SortingMethod(object):
        def __init__(self, container_id, name, listitem_id):
            self.container_id = container_id
            self.name = name
            self.listitem_id = listitem_id
            sorting_types.append(self)

    # There are apparently two lists. SetSortMethod uses a container sorting list, and ListItem uses the one from stubs
    none = SortingMethod(45, localize2(30001), xbmcplugin.SORT_METHOD_UNSORTED)
    label = SortingMethod(1, localize2(30002), xbmcplugin.SORT_METHOD_LABEL)