def handle_finished_episode(self): self.Playlist = None if self.scrobble: scrobble_trakt(self.ep_id, 3, self.time, self.duration, self.is_movie) if self.is_transcoded: pyproxy.get_json(trancode_url(self.file_id) + '/cancel') self.is_finished = finished_episode(self.ep_id, self.file_id, self.time, self.duration)
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
def query_last_watched_episodes(): s_watch = True if xbmcaddon.Addon('service.nakamori').getSetting( 'sv-watch') == 'true' else False s_rate = True if xbmcaddon.Addon('service.nakamori').getSetting( 'sv-rate') == 'true' else False if s_watch or s_rate: log('====> query_last_watched_episodes') from nakamori_utils.globalvars import server # [{"type":"ep","view":1,"view_date":"2019-09-03T13:42:36.9194063+02:00","eptype":"Episode","epnumber":10,"aid":14662,"eid":219322,"id":74,"name":"Episode 10","summary":"Episode Overview not Available","year":"2019","air":"2019-09-02","rating":"2.80","votes":"1","art":{}}] today = date.today().strftime("%Y-%m-%d") offset = 0 limit = 100 # setting without limit results in loop url = server + '/api/ep/last_watched?query=%s&limit=%s&offset=%s' % ( today, limit, offset) spam('====> url: %s' % url) x = pyproxy.get_json(url, True) if x is not None and len(x) > 2: # [] x = json.loads(x) while len(x) > 0: for y in x: if isinstance(y, dict): spam('====> query_last_watched_episodes x: %s %s' % (type(y), y)) watch_date = y.get('view_date', '') aid = y.get('aid', 0) eid = y.get('eid', 0) shoko_eid = y.get('id', 0) user_rating = 0 if s_rate: user_rating = y.get('userrating', 0) sync.add_to_queue(aid, eid, shoko_eid, user_rating) offset = offset + limit url = server + '/api/ep/last_watched?query=%s&limit=%s&offset=%s' % ( today, limit, offset) spam('====> url: %s' % url) x = pyproxy.get_json(url, True) if x is None: break if x == '[]': break # finish checking sync.add_date(today) else: log('====> query_last_watched_episodes - DISABLED')
def get_client_settings(): settings = {} try: settings = json.loads( pyproxy.get_json(eigakan_host + '/api/clientid/%s' % clientid)) except http_error as er: if er.code == 404: log('Client profile not found on Eigakan, sending new one...') kodi_utils.send_profile() return settings
def is_fileid_added_to_transcoder(file_id): ask_for_queue = json.loads( pyproxy.get_json(eigakan_host + '/api/queue/status')) if ask_for_queue is None: ask_for_queue = {} # {"queue":{"queue":["6330","6330"],"subtitles":{"6330":{"status":"{'init'}"}},"videos":{}}} x = ask_for_queue.get('queue', {'queue': ''}).get('queue', []) for y in x: if int(y) == int(file_id): return True return False
def trakt_scrobble(ep_id, status, progress, movie, notification): note_text = '' if status == 1: # start progress = 0 note_text = localized(30028) elif status == 2: # pause note_text = localized(30029) elif status == 3: # finish progress = 100 note_text = localized(30030) if notification: xbmc.executebuiltin( 'XBMC.Notification(%s, %s %s, 7500, %s)' % ('Trakt.tv', note_text, '', plugin_addon.getAddonInfo('icon'))) try: pyproxy.get_json( server + '/api/ep/scrobble?id=%i&ismovie=%s&status=%i&progress=%i' % (ep_id, movie, status, progress)) except python_version_proxy.http_error as htex: if htex.code == 500: try: xbmc.sleep(1000) pyproxy.get_json( server + '/api/ep/scrobble?id=%i&ismovie=%s&status=%i&progress=%i' % (ep_id, movie, status, progress)) except: xbmc.log('trakt_scrobble error - double exception', xbmc.LOGNOTICE) else: xbmc.log('trakt_scrobble error - single exception', xbmc.LOGNOTICE)
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
def can_connect(ip=None, port=None): 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 if ip is None: ip = plugin_addon.getSetting('ipaddress') try: # this handles the case of errors as well json_file = pyproxy.get_json('http://%s:%i/api/version' % (ip, port), direct=True) if json_file is None: return False return True except Exception as ex: return False
def get_version(ip=plugin_addon.getSetting('ipaddress'), port=plugin_addon.getSetting('port'), force=False): legacy = LooseVersion('0.0') version = '' try: _shoko_version = plugin_addon.getSetting('good_version') _good_ip = plugin_addon.getSetting('good_ip') if not force and _shoko_version != LooseVersion( '0.1') and _good_ip == ip: return _shoko_version json_file = pyproxy.get_json('http://' + str(ip) + ':' + str(port) + '/api/version', direct=True) if json_file is None: return legacy try: data = json.loads(json_file) except: return legacy for module in data: if module['name'] == 'server': version = module['version'] break plugin_addon.setSetting(id='good_ip', value=ip) if version != '': try: _shoko_version = LooseVersion(version) plugin_addon.setSetting(id='good_version', value=str(_shoko_version)) except: return legacy return _shoko_version except: pass return legacy
def import_folder_list(): """ Create DialogBox with folder list to pick if there :return: int (vl of selected folder) """ pick_folder = [] get_id = [] import_list = json.loads(pyproxy.get_json(server + '/api/folder/list')) if len(import_list) > 1: for body in import_list: location = str(body['ImportFolderLocation']) pick_folder.append(location) get_id.append(str(body['ImportFolderID'])) my_folder = xbmcgui.Dialog().select(plugin_addon.getLocalizedString(30119), pick_folder) if my_folder > -1: return get_id[my_folder] else: # cancel -1,0 return 0 elif len(import_list) == 1: return import_list[0]['ImportFolderID'] else: return 0
def perform_server_action(command, object_id=None, refresh='refresh10', post=False, post_body=''): """ Performs an action on the server Args: object_id: the object_id or None command: string representing api/command?object_id=... refresh: whether to refresh post: is it a POST endpoint post_body: the body to post, minus the {} """ key_url = server + '/api/' + command if object_id is not None and object_id != 0 and object_id != '': key_url = pyproxy.set_parameter(key_url, 'id', object_id) eh.spam('url:', key_url, 'id:', object_id) eh.spam('post:', post, 'body:', post_body) if post: response = pyproxy.post_json(key_url, post_body) else: response = pyproxy.get_json(key_url) eh.spam(response) refresh_message = localization_refresh_map.get(refresh, '') xbmc.executebuiltin('XBMC.Notification(%s, %s, 2000, %s)' % (localization_notification_map.get(command, command), refresh_message, plugin_addon.getAddonInfo('icon'))) # there's a better way to do this, but I don't feel like trying to make it work in Python if refresh != '' and refresh != 'awhile': xbmc.sleep(10000) kodi_utils.refresh()
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
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