示例#1
0
def can_user_connect():
    # what better way to try than to just attempt to load the main menu?
    try:
        # TRY to use new method which is faster
        try:
            url = server + '/api/ping'
            ping = pyproxy.get_json(url, True)
            if ping is not None and b'pong' in ping:
                return True
            else:  # should never happen
                return False
        except python_version_proxy.http_error as ex:
            # return false if it's an unauthorized response
            if ex.code == 401:
                return False
            eh.exception(ErrorPriority.NORMAL)

        # TODO DEPRECATE THIS AS MOST FUNCTIONS REQUIRE 3.9.5+ anyway
        # but since no one has it, we can't count on it actually working, so fall back
        from shoko_models.v2 import Filter
        f = Filter(0, build_full_object=True, get_children=False)
        if f.size < 1:
            raise RuntimeError(localized(30027))
        return True
    except Exception as ex:
        xbmc.log(' ===== auth error ===== %s ' % ex, xbmc.LOGNOTICE)
        # because we always check for connection first, we can assume that auth is the only problem
        # we need to log in
        eh.exception(ErrorPriority.NORMAL)
        plugin_addon.setSetting('apikey', '')
        return False
示例#2
0
def match_title(data, lang, title_type):
    try:
        exclude = False
        if title_type.startswith('!'):
            title_type = title_type[1:]
            exclude = True

        for title_tag in data.get('titles', []):
            title = pyproxy.decode(title_tag.get('Title', ''))
            if pyproxy.decode(title_tag.get('Title', '')) == '':
                continue

            if title_tag.get('Language', '').lower() != lang.lower():
                continue
            # does it match the proper type
            if exclude and title_tag.get('Type',
                                         '').lower() == title_type.lower():
                continue

            if not exclude and title_tag.get('Type',
                                             '').lower() != title_type.lower():
                continue

            return title
        return None
    except:
        eh.exception(ErrorPriority.NORMAL)
        return None
 def onPlayBackResumed(self):
     spam('Playback Resumed')
     self.PlaybackStatus = PlaybackStatus.PLAYING
     try:
         self.start_loops()
     except:
         eh.exception(ErrorPriority.HIGH)
示例#4
0
def get_tags(tag_node):
    """
    Get the tags from the new style
    Args:
        tag_node: node containing group

    Returns: a string of all of the tags formatted

    """
    try:
        if tag_node is None:
            return ''
        if len(tag_node) == 0:
            return ''
        short_tag = plugin_addon.getSetting('short_tag_list') == 'true'
        temp_genres = []
        current_length = 0
        # the '3' here is because the separator ' | ' is 3 chars
        for tag in tag_node:
            if isinstance(tag, str) or isinstance(tag, unicode):
                if short_tag and current_length + len(tag) + 3 > 50:
                    break
                temp_genres.append(tag)
                current_length += len(tag) + 3
            else:
                temp_genre = pyproxy.decode(tag['tag']).strip()
                if short_tag and current_length + len(temp_genre) + 3 > 50:
                    break
                temp_genres.append(temp_genre)
                current_length += len(temp_genre) + 3
        return kproxy.parse_tags(temp_genres)
    except:
        eh.exception(ErrorPriority.NORMAL)
        return ''
示例#5
0
def move_to_index(index, absolute=False):
    try:
        # putting this in a method crashes kodi to desktop.
        # region F**k if I know....
        elapsed = 0
        interval = 250
        wait_time = 4000
        control_list = None
        while True:
            if elapsed >= wait_time:
                break
            try:
                wind = xbmcgui.Window(xbmcgui.getCurrentWindowId())
                control_list = wind.getControl(wind.getFocusId())
                if isinstance(control_list, xbmcgui.ControlList):
                    break
            except:
                pass
            xbmc.sleep(interval)
            elapsed += interval
        # endregion F**k if I know....
        if isinstance(control_list, xbmcgui.ControlList):
            move_position_on_list(control_list, index, absolute)
    except:
        eh.exception(ErrorPriority.HIGH, localize2(30014))
 def onPlayBackEnded(self):
     spam('Playback Ended')
     try:
         self.handle_finished_episode()
     except:
         eh.exception(ErrorPriority.HIGH)
     self.PlaybackStatus = PlaybackStatus.ENDED
    def onPlayBackStarted(self):
        spam('Playback Started')
        try:
            if plugin_addon.getSetting('enableEigakan') == 'true':
                log('Player is set to use Transcoding')
                self.is_transcoded = True

            # wait until the player is init'd and playing
            self.set_duration()

            self.PlaybackStatus = PlaybackStatus.PLAYING
            # we are making the player global, so if a stop is issued, then Playing will change
            while not self.isPlaying(
            ) and self.PlaybackStatus == PlaybackStatus.PLAYING:
                xbmc.sleep(250)

            # TODO get series and populate info so we know if its movie or not
            # TODO maybe we could read trakt_id from shoko,
            self.is_movie = False
            if self.duration > 0 and self.scrobble:
                scrobble_trakt(self.ep_id, 1, self.getTime(), self.duration,
                               self.is_movie)

            self.start_loops()
        except:
            eh.exception(ErrorPriority.HIGHEST)
 def scrobble_time(self):
     if not self.scrobble:
         return
     try:
         scrobble_trakt(self.ep_id, 2, self.time, self.duration,
                        self.is_movie)
     except:
         eh.exception(ErrorPriority.HIGH)
    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
示例#10
0
def kodi_jsonrpc(method, params):
    try:
        values = (pyproxy.decode(method), json.dumps(params))
        request = '{"jsonrpc":"2.0","method":"%s","params":%s, "id": 1}' % values
        return_data = xbmc.executeJSONRPC(request)
        result = json.loads(return_data)
        return result
    except:
        eh.exception(ErrorPriority.HIGH, localize2(30016))
        return None
示例#11
0
def move_position_on_list_to_next(control_list):
    position = control_list.getSelectedPosition()
    if position != -1:
        try:
            control_list.selectItem(position+1)
        except:
            try:
                if position != 0:
                    control_list.selectItem(position - 1)
            except:
                eh.exception(ErrorPriority.HIGH, localize2(30015))
    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
示例#13
0
def get_kodi_setting(setting):
    try:
        if setting in kodi_settings_cache:
            return kodi_settings_cache[setting]

        method = 'Settings.GetSettingValue'
        params = {'setting': setting}
        result = kodi_jsonrpc(method, params)
        if result is not None and 'result' in result and 'value' in result['result']:
            result = result['result']['value']
            kodi_settings_cache[setting] = result
            return result
    except:
        eh.exception(ErrorPriority.HIGH)
    return None
    def onAVStarted(self):
        # Will be called when Kodi has a video or audiostream, before playing file
        spam('onAVStarted')

        # isExternalPlayer() ONLY works when isPlaying(), other than that it throw 0 always
        # setting it before results in false setting
        try:
            is_external = str(kodi_proxy.external_player(self)).lower()
            plugin_addon.setSetting(id='external_player', value=is_external)
        except:
            eh.exception(ErrorPriority.HIGH)
        spam(self)

        if kodi_proxy.external_player(self):
            log('Using External Player')
            self.is_external = True
示例#15
0
def debug_init():
    """
    start debugger if it's enabled
    also dump argv if spamLog
    :return:
    """
    if plugin_addon.getSetting('remote_debug') == 'true':
        # try pycharm first
        try:
            import pydevd
            # try to connect multiple times...in case we forgot to start it
            # TODO Show a message to the user that we are waiting on the debugger
            connected = False
            tries = 0
            while not connected and tries < 60:
                try:
                    pydevd.settrace(host=plugin_addon.getSetting('remote_ip'),
                                    stdoutToServer=True,
                                    stderrToServer=True,
                                    port=5678,
                                    suspend=False)
                    eh.spam('Connected to debugger')
                    connected = True
                except:
                    tries += 1
                    # we keep this message the same, as kodi will merge them into Previous line repeats...
                    eh.spam('Failed to connect to debugger')
                    xbmc.sleep(1000)
        except (ImportError, NameError):
            eh.log(
                'unable to import pycharm debugger, falling back on the web-pdb'
            )
            try:
                import web_pdb
                web_pdb.set_trace()
            except Exception:
                eh.exception(ErrorPriority.NORMAL,
                             'Unable to start debugger, disabling it')
                plugin_addon.setSetting('remote_debug', 'false')
        except:
            eh.exception(ErrorPriority.HIGHEST, 'Unable to start debugger')

    eh.spam('argv:', sys.argv)
示例#16
0
def get_title(data, lang=None, title_type=None):
    """
    Get the title based on settings
    :param data: json node containing the title
    :return: string of the desired title
    :rtype: str

    """
    try:
        if 'titles' not in data or plugin_addon.getSetting(
                'use_server_title') == 'true':
            return pyproxy.decode(data.get('name', ''))
        # xbmc.log(data.get('title', 'Unknown'))
        title = pyproxy.decode(data.get('name', '').lower())
        if is_type_list(title):
            return pyproxy.decode(data.get('name', ''))

        if lang is None:
            lang = plugin_addon.getSetting('displaylang')
        if title_type is None:
            title_type = plugin_addon.getSetting('title_type')

        # try to match
        title = match_title(data, lang, title_type)
        if title is not None:
            return title

        # fallback on any type of same language
        title = match_title(data, lang, '!short')
        if title is not None:
            return title

        # fallback on x-jat main title
        title = match_title(data, 'x-jat', 'main')
        if title is not None:
            return title

        # fallback on directory title
        return pyproxy.decode(data.get('name', ''))
    except:
        eh.exception(ErrorPriority.NORMAL)
        return 'util.error'
示例#17
0
def set_window_heading(category, window_name):
    """
    Sets the window titles
    Args:
        category: Primary name
        window_name: Secondary name
    """
    handle = int(sys.argv[1])
    xbmcplugin.setPluginCategory(handle, category)

    window_obj = xbmcgui.Window(xbmcgui.getCurrentWindowId())
    try:
        window_obj.setProperty('heading', str(window_name))
    except Exception as e:
        eh.exception(ErrorPriority.LOW, localize2(30013))
        window_obj.clearProperty('heading')
    try:
        window_obj.setProperty('heading2', str(window_name))
    except Exception as e:
        eh.exception(ErrorPriority.LOW, localize2(30013) + ' 2')
        window_obj.clearProperty('heading2')
示例#18
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))
示例#19
0
 def vote(self, vote_type):
     if self.dbid == '':
         eh.exception(eh.ErrorPriority.HIGHEST, 'Unable to Vote for Series', 'No ID was found on the object')
         return
     if vote_type == 'series':
         try:
             self._vote_series()
         except:
             eh.exception(eh.ErrorPriority.HIGHEST)
     elif vote_type == self.media_type:
         try:
             self._vote_episode()
         except:
             eh.exception(eh.ErrorPriority.HIGHEST)
示例#20
0
def get_server_status(ip=plugin_addon.getSetting('ipaddress'),
                      port=plugin_addon.getSetting('port')):
    """
    Try to query server for status, display messages as needed
    don't bother with caching, this endpoint is really fast
    :return: bool
    """
    if port is None:
        port = plugin_addon.getSetting('port')
    if isinstance(port, basestring):
        port = pyproxy.safe_int(port)
        port = port if port != 0 else 8111

    url = 'http://%s:%i/api/init/status' % (ip, port)
    try:
        # this should throw if there's an error code
        response = pyproxy.get_json(url, True)

        # we should have a json response now
        # example:
        # {"startup_state":"Complete!","server_started":false,"server_uptime":"04:00:45","first_run":false,"startup_failed":false,"startup_failed_error_message":""}
        json_tree = json.loads(response)

        server_started = json_tree.get('server_started', False)
        startup_failed = json_tree.get('startup_failed', False)
        startup_state = json_tree.get('startup_state', '')

        # server started successfully
        if server_started:
            return True

        # not started successfully
        if startup_failed:
            # server finished trying to start, but failed
            message_box(localized(30017), localized(30018), localized(30019),
                        localized(30020))
            return False

        was_canceled = False
        busy = xbmcgui.DialogProgress()
        busy.create(localized(30021), startup_state)
        busy.update(1)
        # poll every second until the server gives us a response that we want
        while True:
            xbmc.sleep(1000)
            response = pyproxy.get_json(url, True)

            # this should not happen
            if response is None or pyproxy.safe_int(response) > 200:
                busy.close()
                message_box(localized(30022), localized(30023),
                            localized(30033), localized(30034))
                return False

            json_tree = json.loads(response)
            server_started = json_tree.get('server_started', False)
            if server_started:
                busy.close()
                return True

            startup_failed = json_tree.get('startup_failed', False)

            if json_tree.get('startup_state', '') == startup_state:
                continue
            startup_state = json_tree.get('startup_state', '')

            busy.update(1, localized(30021), startup_state)
            if startup_failed:
                break

            if busy.iscanceled():
                was_canceled = True
                break

        busy.close()

        if was_canceled:
            return False

        if startup_failed:
            message_box(localized(30017), localized(30018), localized(30019),
                        localized(30020))
            return False
        return True
    except python_version_proxy.http_error as httperror:
        eh.exception(ErrorPriority.NORMAL)
        if httperror.code == 503:
            return startup_handle_no_connection(ip, port)
        if httperror.code == 404:
            return startup_handle_404()
        show_connection_error()
        return False
    except:
        eh.exception(ErrorPriority.HIGHEST)
        return False
def player_loop(player, is_transcoded, is_transcode_finished, ep_id,
                party_mode):
    try:
        monitor = xbmc.Monitor()

        # seek to beginning of stream :hack: https://github.com/peak3d/inputstream.adaptive/issues/94
        if is_transcoded:
            while not xbmc.Player().isPlayingVideo():
                monitor.waitForAbort(0.25)

            if not is_transcode_finished:
                if xbmc.Player().isPlayingVideo():
                    log('Seek back - so the stream is from beginning')
                    # TODO part1: hack is temporary and not working in 100%
                    # TODO part2: (with small segments + fast cpu, you wont start from 1st segment)
                    #xbmc.executebuiltin('Seek(-60)')
                    xbmc.executeJSONRPC(
                        '{"jsonrpc":"2.0","method":"Player.Seek","params":{"playerid":1,"value":{"seconds":0}},"id":1}'
                    )

        while player.PlaybackStatus != PlaybackStatus.STOPPED and player.PlaybackStatus != PlaybackStatus.ENDED:
            xbmc.sleep(500)

        if player.PlaybackStatus == PlaybackStatus.STOPPED or player.PlaybackStatus == PlaybackStatus.ENDED:
            log('Playback Ended - Shutting Down: ', monitor.abortRequested())

            if player.is_finished:
                log('post-finish: start events')

                if ep_id != 0:
                    from shoko_models.v2 import Episode
                    ep = Episode(ep_id, build_full_object=False)
                    spam('mark as watched, episode')
                    ep.set_watched_status(True)

                # wait till directory is loaded
                while kodi_utils.is_dialog_active():
                    xbmc.sleep(500)
                # refresh it, so it moves onto next item and the mark watched is refreshed
                kodi_utils.refresh()

                # wait till it load again
                while kodi_utils.is_dialog_active():
                    xbmc.sleep(500)

                if int(ep_id) != 0 and plugin_addon.getSetting(
                        'vote_always') == 'true' and not party_mode:
                    spam('vote_always, voting on episode')
                    script_utils.vote_for_episode(ep_id)

                if int(ep_id) != 0 and plugin_addon.getSetting(
                        'vote_on_series') == 'true' and not party_mode:
                    from shoko_models.v2 import get_series_for_episode
                    series = get_series_for_episode(ep_id)
                    # voting should be only when you really watch full series
                    spam('vote_on_series, mark: %s / %s' %
                         (series.sizes.watched_episodes,
                          series.sizes.total_episodes))
                    if series.sizes.watched_episodes - series.sizes.total_episodes == 0:
                        script_utils.vote_for_series(series.id)

            return -1
        else:
            log(
                'Playback Ended - Playback status was not "Stopped" or "Ended". It was ',
                player.PlaybackStatus)
        return 0
    except:
        eh.exception(ErrorPriority.HIGHEST)
        return -1
def play_video(file_id,
               ep_id=0,
               mark_as_watched=True,
               resume=False,
               force_direct_play=False,
               force_transcode_play=False,
               party_mode=False):
    """
    Plays a file
    :param file_id: file ID. It is needed to look up the file
    :param ep_id: episode ID, not needed, but it fills in a lot of info
    :param mark_as_watched: should we mark it after playback
    :param resume: should we auto-resume
    :param force_direct_play: force direct play
    :param force_transcode_play: force transcoding file
    :return: True if successfully playing
    """

    eh.spam('Processing play_video %s %s %s %s %s %s' %
            (file_id, ep_id, mark_as_watched, resume, force_direct_play,
             force_transcode_play))

    from shoko_models.v2 import Episode, File, get_series_for_episode

    # check if we're already playing something
    player = xbmc.Player()
    if player.isPlayingVideo():
        playing_item = player.getPlayingFile()
        log('Player is currently playing %s' % playing_item)
        log('Player Stopping')
        player.stop()

    # wait for it to stop
    while True:
        try:
            if not player.isPlayingVideo():
                break
            xbmc.sleep(500)
            continue
        except:
            pass

    # now continue
    file_url = ''

    if int(ep_id) != 0:
        ep = Episode(ep_id, build_full_object=True)
        series = get_series_for_episode(ep_id)
        ep.series_id = series.id
        ep.series_name = series.name
        item = ep.get_listitem()
        f = ep.get_file_with_id(file_id)
    else:
        f = File(file_id, build_full_object=True)
        item = f.get_listitem()

    if item is not None:
        if resume:
            # TODO looks like this does nothing...
            item.resume()
        else:
            item.setProperty('ResumeTime', '0')
        file_url = f.url_for_player if f is not None else None

    if file_url is not None:
        is_transcoded = False
        m3u8_url = ''
        subs_extension = ''
        is_finished = False
        if not force_direct_play:
            if 'smb://' in file_url:
                file_url = f.remote_url_for_player
            is_transcoded, m3u8_url, subs_extension, is_finished = process_transcoder(
                file_id, file_url, force_transcode_play)

        player = Player()
        player.feed(file_id, ep_id, f.duration,
                    m3u8_url if is_transcoded else file_url, mark_as_watched)

        try:
            item.setProperty('IsPlayable', 'true')

            if is_transcoded:
                #player.play(item=m3u8_url)
                url_for_player = m3u8_url
                item.setPath(url_for_player)
                item.setProperty('inputstreamaddon', 'inputstream.adaptive')
                item.setProperty('inputstream.adaptive.manifest_type', 'mpd')
                item.setMimeType('application/dash+xml')
                item.setContentLookup(False)

                # TODO maybe extract all subs and include them ?
                subs_url = eigakan_host + '/api/video/%s/%s/subs.%s' % (
                    clientid, file_id, subs_extension)
                if pyproxy.head(url_in=subs_url):
                    item.setSubtitles([
                        subs_url,
                    ])
                    item.addStreamInfo('subtitle', {
                        'language': 'Default',
                    })

            else:
                #file_url = f.remote_url_for_player
                #player.play(item=file_url, listitem=item)
                url_for_player = f.url_for_player  # file_url
                item.setPath(url_for_player)

            handle = int(sys.argv[1])

            if handle == -1:
                player.play(item=url_for_player, listitem=item)
            else:
                # thanks to anxdpanic for pointing in right direction
                xbmcplugin.setResolvedUrl(handle, True, item)
        except:
            eh.exception(ErrorPriority.BLOCKING)

        # leave player alive so we can handle onPlayBackStopped/onPlayBackEnded
        # TODO Move the instance to Service, so that it is never disposed
        xbmc.sleep(int(plugin_addon.getSetting('player_sleep')))
        return player_loop(player, is_transcoded, is_finished, ep_id,
                           party_mode)
def process_transcoder(file_id, file_url, force_transcode_play=False):
    """

    :param file_id:
    :param file_url:
    :param force_transcode_play: force transcode
    :return:
    """

    is_transcoded = False
    m3u8_url = ''
    subs_type = ''
    is_finished = False

    if plugin_addon.getSetting(
            'enableEigakan') != 'true' and not force_transcode_play:
        return is_transcoded, m3u8_url, subs_type, is_finished

    video_url = trancode_url(file_id)
    post_data = '"file":"' + file_url + '"'

    is_dash = True
    end_url = eigakan_host + '/api/video/%s/%s/end.eigakan' % (clientid,
                                                               file_id)
    if is_dash:
        m3u8_url = eigakan_host + '/api/video/%s/%s/play.mpd' % (clientid,
                                                                 file_id)
        ts_url = eigakan_host + '/api/video/%s/%s/%s' % (clientid, file_id,
                                                         magic_chunk)
    else:
        m3u8_url = eigakan_host + '/api/video/%s/%s/play.m3u8' % (clientid,
                                                                  file_id)
        ts_url = eigakan_host + '/api/video/%s/%s/play0.ts' % (clientid,
                                                               file_id)

    try:
        kodi_utils.check_eigakan()

        # server is alive so send profile of device we didn't before
        if plugin_addon.getSetting('eigakan_handshake') == 'false':
            kodi_utils.send_profile()
        settings = get_client_settings()

        # check if file is already transcoded
        is_finished = pyproxy.head(url_in=end_url)
        if not is_finished:
            # let's probe file, maybe we already know which streams we want
            busy.create(plugin_addon.getLocalizedString(30160),
                        plugin_addon.getLocalizedString(30177))
            audio_streams, subs_streams = eigakan_utils.probe_file(
                file_id, file_url)
            busy.close()

            # pick streams that are preferred via profile on eigakan
            a_index, s_index, subs_type = eigakan_utils.pick_best_streams(
                audio_streams, subs_streams)

            # region BUSY Dialog Hell
            # please wait, Sending request to Transcode server...
            busy.create(plugin_addon.getLocalizedString(30160),
                        plugin_addon.getLocalizedString(30165))
            if a_index > -1:
                post_data += ',"audio":"%s"' % a_index
            if s_index > -1:
                post_data += ',"subtitles":"%s"' % s_index
            pyproxy.post_json(video_url, post_data,
                              custom_timeout=0.1)  # non blocking
            xbmc.sleep(1000)
            # busy.close()

            try_count = 0
            found = False
            # please wait,waiting for being queued
            busy.update(0, plugin_addon.getLocalizedString(30192))
            while True:
                if busy.iscanceled():
                    break
                if eigakan_utils.is_fileid_added_to_transcoder(file_id):
                    break

                try_count += 1
                busy.update(try_count)
                xbmc.sleep(1000)

            try_count = 0
            found = False
            # plase wait, waiting for subs to be dump
            busy.update(try_count, plugin_addon.getLocalizedString(30205))
            while True:
                if busy.iscanceled():
                    break
                ask_for_subs = json.loads(
                    pyproxy.get_json(eigakan_host + '/api/queue/%s' % file_id))
                if ask_for_subs is None:
                    ask_for_subs = {}
                y = ask_for_subs.get('queue', {"videos": {}}).get('videos', {})

                for k in y:
                    if int(k) == int(file_id):
                        found = True
                        break
                    if found:
                        break
                if found:
                    break
                try_count += 1
                if try_count >= 100:
                    try_count = 0
                    busy.update(try_count,
                                plugin_addon.getLocalizedString(30218))
                busy.update(try_count)
                xbmc.sleep(1000)

            try_count = 0
            found = False
            # please waiting, waiting for starting transcode
            busy.update(try_count, plugin_addon.getLocalizedString(30206))
            while True:
                if busy.iscanceled():
                    break
                ask_for_subs = json.loads(
                    pyproxy.get_json(eigakan_host + '/api/queue/%s' % file_id))
                if ask_for_subs is None:
                    ask_for_subs = {}
                x = ask_for_subs.get('queue', {"videos": {}}).get('videos', {})
                for k in x:
                    if int(k) == int(file_id):
                        percent = x[k].get('percent', 0)
                        if int(percent) > 0:
                            found = True
                            log('percent found of transcoding: %s' % percent)
                            break
                if found:
                    break
                try_count += 1
                if try_count >= 100:
                    try_count = 0
                    busy.update(try_count,
                                plugin_addon.getLocalizedString(30218))
                busy.update(try_count)
                xbmc.sleep(1000)

            try_count = 0
            # please wait, Waiting for response from Server...
            busy.update(try_count, plugin_addon.getLocalizedString(30164))
            while True:
                if busy.iscanceled():
                    break
                if pyproxy.head(url_in=ts_url) is False:
                    try_count += 1
                    busy.update(try_count)
                    xbmc.sleep(1000)
                else:
                    break
            busy.close()

            # endregion

        if pyproxy.head(url_in=ts_url):
            is_transcoded = True

    except:
        eh.exception(ErrorPriority.BLOCKING)
        try:
            busy.close()
        except:
            pass

    return is_transcoded, m3u8_url, subs_type, is_finished