def root(self, pathitems=None):  # pylint: disable=unused-argument
     """Show profiles or home listing when profile auto-selection is enabled"""
     # Get the URL parent path of the navigation: xbmc.getInfoLabel('Container.FolderPath')
     #   it can be found in Kodi log as "ParentPath = [xyz]" but not always return the exact value
     is_parent_root_path = xbmc.getInfoLabel(
         'Container.FolderPath') == g.BASE_URL + '/'
     # Fetch initial page to refresh all session data
     if is_parent_root_path:
         common.make_call('fetch_initial_page')
     # Note when the profiles are updated to the database (by fetch_initial_page call),
     #   the update sanitize also relative settings to profiles (see _delete_non_existing_profiles in website.py)
     autoselect_profile_guid = g.LOCAL_DB.get_value(
         'autoselect_profile_guid', '')
     if autoselect_profile_guid:
         if is_parent_root_path:
             common.info('Performing auto-selection of profile {}',
                         autoselect_profile_guid)
         # Do not perform the profile switch if navigation come from a page that is not the root url,
         # prevents profile switching when returning to the main menu from one of the sub-menus
         if not is_parent_root_path or activate_profile(
                 autoselect_profile_guid):
             self.home(None, False, True)
             return
     list_data, extra_data = common.make_call('get_profiles',
                                              {'request_update': False})
     self._profiles(list_data, extra_data)
Beispiel #2
0
 def _login(self, modal_error_message=False):
     """Perform account login"""
     # If exists get the current esn value before extract a new session data
     current_esn = g.get_esn()
     try:
         # First we get the authentication url without logging in, required for login API call
         react_context = website.extract_json(self._get('profiles'),
                                              'reactContext')
         auth_url = website.extract_api_data(react_context)['auth_url']
         common.debug('Logging in...')
         login_response = self._post('login',
                                     data=_login_payload(
                                         common.get_credentials(),
                                         auth_url))
         validate_msg = website.validate_login(login_response)
         if validate_msg:
             self.session.cookies.clear()
             common.purge_credentials()
             if modal_error_message:
                 ui.show_ok_dialog(common.get_local_string(30008),
                                   validate_msg)
             else:
                 ui.show_notification(common.get_local_string(30009))
             return False
         website.extract_session_data(login_response)
     except Exception as exc:
         common.error(traceback.format_exc())
         self.session.cookies.clear()
         raise exc
     common.info('Login successful')
     ui.show_notification(common.get_local_string(30109))
     self.update_session_data(current_esn)
     return True
Beispiel #3
0
def resolveOPENLOAD(l):
    mediaid = l.split("/")
    #//openload.co/embed/T46sXRDbTos/
    mediaid = mediaid[len(mediaid) - 2]
    status = requests.get('https://api.openload.co/1/file/info?file=' +
                          mediaid)
    if status:
        if status.json().get('status') == 200:
            status = requests.get(
                'https://api.openload.co/1/streaming/get?file=' + mediaid)
            if status:
                if status.json().get('status') == 200:
                    link = status.json().get('result').get('url')
                    if link:
                        xbmcplugin.setResolvedUrl(common.addon_handle, True,
                                                  xbmcgui.ListItem(path=link))
                    else:
                        common.info('OPENLOAD - link not found', '', 200)
                else:
                    common.info(status.json().get('msg'))
            else:
                common.info('openload - request error', '', 200)
        else:
            common.info(status.json().get('msg'))
    else:
        common.info('openload - request error', '', 200)
    return 0
 def _activate_profile(self, guid, ignore_update_lolomo_data=False):
     """Set the profile identified by guid as active"""
     common.debug('Switching to profile {}', guid)
     current_active_guid = g.LOCAL_DB.get_active_profile_guid()
     if self.is_profile_session_active and guid == current_active_guid:
         common.info(
             'The profile session of guid {} is still active, activation not needed.',
             guid)
     if not self.is_profile_session_active or (
             self.is_profile_session_active
             and guid != current_active_guid):
         common.info('Activating profile {}', guid)
         # 20/05/2020 - The method 1 not more working for switching PIN locked profiles
         # INIT Method 1 - HTTP mode
         # response = self._get('switch_profile', params={'tkn': guid})
         # self.auth_url = self.website_extract_session_data(response)['auth_url']
         # END Method 1
         # INIT Method 2 - API mode
         import time
         self._get(endpoint='activate_profile',
                   params={
                       'switchProfileGuid': guid,
                       '_': int(time.time()),
                       'authURL': self.auth_url
                   })
         # Retrieve browse page to update authURL
         response = self._get('browse')
         self.auth_url = website.extract_session_data(response)['auth_url']
         # END Method 2
         self.is_profile_session_active = True
     g.LOCAL_DB.switch_active_profile(guid)
     g.CACHE_MANAGEMENT.identifier_prefix = guid
     self.update_session_data()
     if not ignore_update_lolomo_data:
         self.update_lolomo_data()
Beispiel #5
0
def play(p):
    xbmcplugin.setContent(common.addon_handle, 'movie')
    u = p.get('url', '')
    l = common.solveCFP(u)
    if not l == None:
        t = re.compile('<table class=\"table\">(.*?)<\/table>',
                       re.DOTALL).findall(l.text.encode('utf-8'))[0]
        rows = re.compile('(<tr.*?)<\/tr>', re.DOTALL).findall(t)
        players = []
        selList = []
        for r1 in range(len(rows)):
            tds = re.compile('(<td.*?<\/td>)', re.DOTALL).findall(rows[r1])
            pl = re.compile('> (.*?)<\/td>', re.DOTALL).findall(tds[0])[0]
            link = re.compile('<a href=\"(.*?)\" ',
                              re.DOTALL).findall(tds[1])[0]
            kind = re.compile('<td.*?>(.*?)<\/td>',
                              re.DOTALL).findall(tds[3])[0]
            players.append([pl, link])
            selList.append("%s [COLOR lime]%s[/COLOR] | %s" % (pl, kind, link))
        playfrom = xbmcgui.Dialog().select('Wybor zrodla', selList)
        if playfrom >= 0:
            common.log("Wybrano :" + players[playfrom][0] + " - link: " +
                       players[playfrom][1])
            player(players[playfrom])
    else:
        common.info("LINK FEATCHING FAILED", "E404", time=5000)
    xbmcplugin.endOfDirectory(common.addon_handle)
    def _activate_profile(self, guid):
        """Set the profile identified by guid as active"""
        common.debug('Switching to profile {}', guid)
        current_active_guid = g.LOCAL_DB.get_active_profile_guid()
        if self.is_profile_session_active and guid == current_active_guid:
            common.info(
                'The profile session of guid {} is still active, activation not needed.',
                guid)
        import time
        timestamp = time.time()
        common.info('Activating profile {}', guid)
        # 20/05/2020 - The method 1 not more working for switching PIN locked profiles
        # INIT Method 1 - HTTP mode
        # response = self._get('switch_profile', params={'tkn': guid})
        # self.auth_url = self.website_extract_session_data(response)['auth_url']
        # END Method 1
        # INIT Method 2 - API mode
        self._get(endpoint='activate_profile',
                  params={
                      'switchProfileGuid': guid,
                      '_': int(timestamp * 1000),
                      'authURL': self.auth_url
                  })
        # Retrieve browse page to update authURL
        response = self._get('browse')
        self.auth_url = website.extract_session_data(response)['auth_url']
        # END Method 2

        self.is_profile_session_active = True
        # Update the session profile cookie (only a test, see 'Profile idle timeout' in website.py)
        # expires = int(timestamp) + (g.LOCAL_DB.get_value('profile_gate_idle_timer', 30, TABLE_SESSION) * 60)
        # self.session.cookies.set('profilesNewSession', '0', domain='.netflix.com', path='/', expires=expires)
        g.LOCAL_DB.switch_active_profile(guid)
        g.CACHE_MANAGEMENT.identifier_prefix = guid
        cookies.save(self.account_hash, self.session.cookies)
Beispiel #7
0
def playEpizod(params):
	xbmcplugin.setContent(common.addon_handle, 'movie')
	u=MURL+params.get('url','')
	l=common.solveCFP(u)
	if not l==None:
		m=re.compile('<table class=\"data-view-table-strips data-view-table-big data-view-hover\">(.*?)<\/table>',re.DOTALL).findall(l.text.encode('utf-8'))[0]
		m1=re.compile('<tbody>(.*?)<\/tbody>',re.DOTALL).findall(m)
		rows=re.compile('<tr>(.*?)<\/tr>',re.DOTALL).findall(m1[0])
		KEY=re.compile("_Storage\.basic =  '(.*?)';",re.DOTALL).findall(l.text.encode('utf-8'))[0]
		XHR=re.compile("_Storage\.XHRService = '\/\/(.*?)';",re.DOTALL).findall(l.text.encode('utf-8'))[0]
		players=[]
		selList=[]
		for r in range(len(rows)):
			pl=re.compile('<td class=\"ep-pl-name\">.*?([\w\s\d]*?)<\/td>',re.DOTALL).findall(rows[r])[0] or 0
			audio=re.compile('<td class=\"ep-pl-alang\">.*?<span class=\"mobile-hidden\">(.*?)<\/span>',re.DOTALL).findall(rows[r])[0] or 0
			subs=re.compile('<td class=\"ep-pl-slang\">.*?<span class=\"mobile-hidden\">(.*?)<\/span>',re.DOTALL).findall(rows[r])[0] or 0
			res=re.compile('<td class=\"ep-pl-res\">.*?<\/span>(.*?)<\/td>',re.DOTALL).findall(rows[r])[0] or 0
			id=re.compile('\"online_id\":\"(.*?)\"',re.DOTALL).findall(rows[r])[0] or 0
			players.append([pl,id])
			selList.append("%s [COLOR blue]%s[/COLOR] A:%s N:%s" % (pl,res,audio,subs))
		playfrom=xbmcgui.Dialog().select('Wybor zrodla',selList)
		if playfrom>=0:
			player(players[playfrom],KEY,XHR)
	else:
		common.info("LINK FEATCHING FAILED","E404", time=5000)
	xbmcplugin.endOfDirectory(common.addon_handle)
def _compute_next_schedule():
    try:
        if g.ADDON.getSettingBool('use_mysql'):
            client_uuid = g.LOCAL_DB.get_value('client_uuid')
            uuid = g.SHARED_DB.get_value('auto_update_device_uuid')
            if client_uuid != uuid:
                common.debug(
                    'The auto update has been disabled because another device '
                    'has been set as the main update manager')
                return None

        time = g.ADDON.getSetting('lib_auto_upd_start') or '00:00'
        last_run = g.SHARED_DB.get_value('library_auto_update_last_start',
                                         datetime.utcfromtimestamp(0))
        update_frequency = g.ADDON.getSettingInt('lib_auto_upd_freq')

        last_run = last_run.replace(hour=int(time[0:2]), minute=int(time[3:5]))
        next_run = last_run + timedelta(days=[1, 2, 5, 7][update_frequency])
        if next_run >= datetime.now():
            common.info('Next library auto update is scheduled for {}',
                        next_run)
        return next_run
    except Exception:  # pylint: disable=broad-except
        # If settings.xml was not created yet, as at first service run
        # g.ADDON.getSettingBool('use_mysql') will thrown a TypeError
        # If any other error appears, we don't want the service to crash,
        # let's return None in all case
        # import traceback
        # common.debug(g.py2_decode(traceback.format_exc(), 'latin-1'))
        common.warn('Managed error at _compute_next_schedule')
        return None
def run(argv):
    # pylint: disable=broad-except,ungrouped-imports
    # Initialize globals right away to avoid stale values from the last addon invocation.
    # Otherwise Kodi's reuseLanguageInvoker will cause some really quirky behavior!
    # PR: https://github.com/xbmc/xbmc/pull/13814
    g.init_globals(argv)

    reset_log_level_global_var()
    info('Started (Version {})'.format(g.VERSION_RAW))
    info('URL is {}'.format(g.URL))
    success = True

    window_cls = Window(10000)  # Kodi home window

    # If you use multiple Kodi profiles you need to distinguish the property of current profile
    prop_nf_service_status = g.py2_encode('nf_service_status_' +
                                          get_current_kodi_profile_name())
    is_external_call = _check_addon_external_call(window_cls,
                                                  prop_nf_service_status)
    service_status = _get_service_status(window_cls, prop_nf_service_status)

    if service_status.get('status') != 'running':
        if not is_external_call:
            if service_status.get('status') == 'error':
                # The services are not started due to an error exception
                from resources.lib.kodi.ui import show_error_info
                show_error_info(
                    get_local_string(30105),
                    get_local_string(30240).format(
                        service_status.get('message')), False, False)
            else:
                # The services are not started yet
                from resources.lib.kodi.ui import show_backend_not_ready
                show_backend_not_ready()
        success = False

    if success:
        try:
            if _check_valid_credentials():
                if g.IS_ADDON_FIRSTRUN:
                    if check_addon_upgrade():
                        from resources.lib.config_wizard import run_addon_configuration
                        run_addon_configuration()
                route([part for part in g.PATH.split('/') if part])
            else:
                success = False
        except BackendNotReady:
            from resources.lib.kodi.ui import show_backend_not_ready
            show_backend_not_ready()
            success = False
        except Exception as exc:
            import traceback
            from resources.lib.kodi.ui import show_addon_error_info
            error(g.py2_decode(traceback.format_exc(), 'latin-1'))
            show_addon_error_info(exc)
            success = False

    if not success:
        _handle_endofdirectory()
    log_time_trace()
 def _home_autoselect_profile(self):
     """
     Show home listing if profile auto-selection is enabled
     :return: True when the auto-selection is done correctly
     """
     autoselect_profile_guid = g.LOCAL_DB.get_value(
         'autoselect_profile_guid', '')
     if autoselect_profile_guid:
         # Check if the GUID still exists in the profile list
         if autoselect_profile_guid not in g.LOCAL_DB.get_guid_profiles():
             common.warn(
                 'Auto-selection of profile not performed, the GUID {} not exist',
                 autoselect_profile_guid)
             g.LOCAL_DB.set_value('autoselect_profile_guid', '')
             g.settings_monitor_suspend(True)
             g.ADDON.setSetting('autoselect_profile_name', '')
             g.ADDON.setSettingBool('autoselect_profile_enabled', False)
             g.settings_monitor_suspend(False)
         else:
             common.info('Performing auto-selection of profile {}',
                         autoselect_profile_guid)
             api.activate_profile(autoselect_profile_guid)
             self.home(None, False)
             return True
     return False
Beispiel #11
0
 def _login(self, modal_error_message=False):
     """Perform account login"""
     # If exists get the current esn value before extract a new session data
     current_esn = g.get_esn()
     try:
         # First we get the authentication url without logging in, required for login API call
         react_context = website.extract_json(self._get('login'), 'reactContext')
         auth_url = website.extract_api_data(react_context)['auth_url']
         common.debug('Logging in...')
         login_response = self._post(
             'login',
             data=_login_payload(common.get_credentials(), auth_url))
         try:
             website.extract_session_data(login_response, validate=True, update_profiles=True)
             common.info('Login successful')
             ui.show_notification(common.get_local_string(30109))
             self.update_session_data(current_esn)
             return True
         except (LoginValidateError, LoginValidateErrorIncorrectPassword) as exc:
             self.session.cookies.clear()
             common.purge_credentials()
             if not modal_error_message:
                 raise
             ui.show_ok_dialog(common.get_local_string(30008), unicode(exc))
     except InvalidMembershipStatusError:
         ui.show_error_info(common.get_local_string(30008),
                            common.get_local_string(30180),
                            False, True)
     except Exception:  # pylint: disable=broad-except
         import traceback
         common.error(g.py2_decode(traceback.format_exc(), 'latin-1'))
         self.session.cookies.clear()
         raise
     return False
Beispiel #12
0
def request(l, d):
    s = requests.Session()
    head = {
        'authority': 'shinden.pl',
        'user-agent':
        'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.71',
        'X-Requested-With': 'XMLHttpRequest',
        'Host': 'shinden.pl',
        'contentType': 'application/x-www-form-urlencoded; charset=UTF-8',
        'Referer': 'https://shinden.pl',
        'pragma': 'no-cache',
        'cache-control': 'no-cache',
        'upgrade-insecure-requests': '1',
        'dnt': '1',
        'accept':
        'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'accept-encoding': 'identity',
        'accept-language': 'pl-PL,pl;q=0.9,en-US;q=0.8,en;q=0.7'
    }
    #try:
    r = s.get(l + "player_load", params=d)  #, headers=head,timeout=10)
    r.close()
    common.info('Pobieram dane playera', '')
    time.sleep(int(r.text))
    d['width'] = "800"
    r = s.get(l + "player_show", params=d)  #, headers=head,timeout=10)
    r.close()
    text = r.text.encode('utf-8')
    #except:
    #	log('nieudane request')
    #	text=''
    return text
Beispiel #13
0
    def logout(self, url):
        """Logout of the current account and reset the session"""
        common.debug('Logging out of current account')

        g.settings_monitor_suspend(True)

        # Disable and reset auto-update / auto-sync features
        g.ADDON.setSettingInt('lib_auto_upd_mode', 0)
        g.ADDON.setSettingBool('lib_sync_mylist', False)
        g.SHARED_DB.delete_key('sync_mylist_profile_guid')

        # Disable and reset the auto-select profile
        g.LOCAL_DB.set_value('autoselect_profile_guid', '')
        g.ADDON.setSetting('autoselect_profile_name', '')
        g.ADDON.setSettingBool('autoselect_profile_enabled', False)

        g.settings_monitor_suspend(False)

        # Delete cookie and credentials
        cookies.delete(self.account_hash)
        self._get('logout')
        common.purge_credentials()

        common.info('Logout successful')
        ui.show_notification(common.get_local_string(30113))
        self._init_session()
        xbmc.executebuiltin('Container.Update(path,replace)'
                            )  # Go to a fake page to clear screen
        # Open root page
        xbmc.executebuiltin('Container.Update({},replace)'.format(
            url))  # replace=reset history
Beispiel #14
0
 def _process_event_request(self, event):
     """Do the event post request"""
     event.status = Event.STATUS_REQUESTED
     # Request attempts can be made up to a maximum of 3 times per event
     while event.is_attempts_granted():
         common.info('EVENT [{}] - Executing request (attempt {})', event, event.req_attempt)
         params = {'reqAttempt': event.req_attempt,
                   'reqPriority': 20 if event.event_type == EVENT_START else 0,
                   'reqName': 'events/{}'.format(event)}
         url = ENDPOINTS['events'] + '?' + urlencode(params).replace('%2F', '/')
         try:
             response = self.chunked_request(url, event.request_data, g.get_esn(), disable_msl_switch=False)
             event.set_response(response)
             break
         except Exception as exc:  # pylint: disable=broad-except
             common.error('EVENT [{}] - The request has failed: {}', event, exc)
     if event.event_type == EVENT_STOP:
         self.clear_queue()
         if event.event_data['is_in_mylist']:
             # If video is in my list, invalidate the continueWatching list (update lolomo context data)
             api.update_lolomo_context('continueWatching')
         else:
             # Else invalidate the 'queue' list (update lolomo context data)
             # Todo: get 'queue' lolomo id/index
             # api.update_lolomo_context('queue')
             pass
         api.update_videoid_bookmark(event.get_video_id())
     # Below commented lines: let future requests continue to be sent, unstable connections like wi-fi cause problems
     # if not event.is_response_success():
         # The event request is unsuccessful then there is some problem,
         # no longer make any future requests from this event id
     #     return False
     return True
 def activate_profile(self, guid):
     """Set the profile identified by guid as active"""
     common.debug('Switching to profile {}', guid)
     current_active_guid = g.LOCAL_DB.get_active_profile_guid()
     if self.is_profile_session_active and guid == current_active_guid:
         common.info(
             'The profile session of guid {} is still active, activation not needed.',
             guid)
     if not self.is_profile_session_active or (
             self.is_profile_session_active
             and guid != current_active_guid):
         common.info('Activating profile {}', guid)
         # INIT Method 1 - HTTP mode
         response = self._get('switch_profile', params={'tkn': guid})
         self.auth_url = self.website_extract_session_data(
             response)['auth_url']
         # END Method 1
         # INIT Method 2 - API mode
         # import time
         # self._get(component='activate_profile',
         #           params={'switchProfileGuid': guid,
         #                   '_': int(time.time()),
         #                   'authURL': self.auth_url})
         # # Retrieve browse page to update authURL
         # response = self._get('browse')
         # self.auth_url = website.extract_session_data(response)['auth_url']
         # END Method 2
         self.is_profile_session_active = True
     g.LOCAL_DB.switch_active_profile(guid)
     g.CACHE_MANAGEMENT.identifier_prefix = guid
     self.update_session_data()
Beispiel #16
0
 def _verify_session_cookies(self):
     """Verify that the session cookies have not expired"""
     # pylint: disable=broad-except
     fallback_to_validate = False
     if not self.session.cookies:
         return False
     for cookie_name in LOGIN_COOKIES:
         if cookie_name not in self.session.cookies.keys():
             common.error(
                 'The cookie "{}" do not exist. It is not possible to check expiration. '
                 'Fallback to old validate method.'.format(cookie_name))
             fallback_to_validate = True
             break
         for cookie in list(self.session.cookies):
             if cookie.name != cookie_name:
                 continue
             if cookie.expires <= time.time():
                 common.info('Login is expired')
                 return False
     if fallback_to_validate:
         # Old method, makes a request at every time an user change page on Kodi
         # and try to re-extract all, working but slows down navigation.
         # If we can get session data, cookies are still valid
         try:
             website.validate_session_data(self._get('profiles'))
             self.update_session_data()
         except Exception:
             common.debug(traceback.format_exc())
             common.info(
                 'Failed to validate session data, login is expired')
             self.session.cookies.clear()
             return False
     return True
Beispiel #17
0
def resolveOTHER(l):
	link=''
	try:
		link=urlresolve.resolve("https://"+l)
	except:
		common.info('cos wiecej w logu','Blad resolveurl')
	if link:
		xbmcplugin.setResolvedUrl(common.addon_handle, True, xbmcgui.ListItem(path=link))
Beispiel #18
0
def play(videoid):
    """Play an episode or movie as specified by the path"""
    common.info('Playing {}', videoid)
    is_up_next_enabled = g.ADDON.getSettingBool('UpNextNotifier_enabled')
    metadata = [{}, {}]
    try:
        metadata = api.metadata(videoid)
        common.debug('Metadata is {}', metadata)
    except MetadataNotAvailable:
        common.warn('Metadata not available for {}', videoid)

    # Parental control PIN
    pin_result = _verify_pin(metadata[0].get('requiresPin', False))
    if not pin_result:
        if pin_result is not None:
            ui.show_notification(common.get_local_string(30106), time=10000)
        xbmcplugin.endOfDirectory(g.PLUGIN_HANDLE, succeeded=False)
        return

    list_item = get_inputstream_listitem(videoid)
    infos, art = infolabels.add_info_for_playback(videoid, list_item,
                                                  is_up_next_enabled)

    # Workaround for resuming strm files from library
    resume_position = infos.get('resume', {}).get('position') \
        if g.IS_SKIN_CALL and g.ADDON.getSettingBool('ResumeManager_enabled') else None
    if resume_position:
        index_selected = ui.ask_for_resume(
            resume_position) if g.ADDON.getSettingBool(
                'ResumeManager_dialog') else None
        if index_selected == -1:
            xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE,
                                      succeeded=False,
                                      listitem=list_item)
            return
        if index_selected == 1:
            resume_position = None

    xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE,
                              succeeded=True,
                              listitem=list_item)

    upnext_info = get_upnext_info(videoid, (infos, art),
                                  metadata) if is_up_next_enabled else None

    common.debug('Sending initialization signal')
    common.send_signal(common.Signals.PLAYBACK_INITIATED, {
        'videoid': videoid.to_dict(),
        'infos': infos,
        'art': art,
        'timeline_markers': get_timeline_markers(metadata[0]),
        'upnext_info': upnext_info,
        'resume_position': resume_position
    },
                       non_blocking=True)
    xbmcplugin.setResolvedUrl(handle=g.PLUGIN_HANDLE,
                              succeeded=True,
                              listitem=list_item)
 def logout(self):
     """Logout of the current account and reset the session"""
     common.debug('Logging out of current account')
     cookies.delete(self.account_hash)
     self._get('logout')
     common.purge_credentials()
     common.info('Logout successful')
     ui.show_notification(common.get_local_string(30113))
     self._init_session()
Beispiel #20
0
def update_library():
    """
    Update the local Kodi library with new episodes of exported shows
    """
    if not _update_running():
        common.info('Triggering library update')
        xbmc.executebuiltin(
            ('XBMC.RunPlugin(plugin://{}/?action=export-new-episodes'
             '&inbackground=True)').format(g.ADDON_ID))
Beispiel #21
0
def _sync_mylist(videoid, task_handler, enabled):
    """Add or remove exported items to My List, if enabled in settings"""
    operation = {
        'export_item': 'add',
        'remove_item': 'remove'
    }.get(task_handler.__name__)
    if enabled and operation and g.ADDON.getSettingBool('lib_sync_mylist'):
        common.info('Syncing my list due to change of Kodi library')
        api.update_my_list(videoid, operation)
Beispiel #22
0
 def _init_msl_handler(self):
     self.msl_requests = None
     try:
         msl_data = json.loads(common.load_file(MSL_DATA_FILENAME))
         common.info('Loaded MSL data from disk')
     except Exception:  # pylint: disable=broad-except
         msl_data = None
     self.msl_requests = MSLRequests(msl_data)
     self.switch_events_handler()
 def sync_library_with_mylist(self):
     """
     Perform a full sync of Kodi library with Netflix "My List",
     by deleting everything that was previously exported
     """
     common.info('Performing sync of Kodi library with My list')
     # Clear all the library
     self.clear_library()
     # Start the sync
     self.auto_update_library(True, show_nfo_dialog=True, clear_on_cancel=True)
Beispiel #24
0
 def on_tick(self, player_state):
     # Stops playback when paused for more than one hour.
     # Some users leave the playback paused also for more than 12 hours,
     # this complicates things to resume playback, because the manifest data expires and with it also all
     # the streams urls are no longer guaranteed, so we force the stop of the playback.
     if self.is_player_in_pause and (time.time() - self.start_time) > 3600:
         common.info(
             'The playback has been stopped because it has been exceeded 1 hour of pause'
         )
         common.stop_playback()
Beispiel #25
0
def opis(params):
	u=MURL+params.get('url','')
	l=common.solveCFP(u)
	if not l==None:
		try:
			m=re.compile('<section class=\"info-top\">(.*?)<\/section>',re.DOTALL).findall(l.text.encode('utf-8'))[0]
			opis=re.compile('<div.*?>(.*?)<\/div>',re.DOTALL).findall(m)[0]
			xbmcgui.Dialog().textviewer('Opis',opis)
		except:
			common.log("brak informacji o serii")
			common.info("Problem z pobraniem opisu","BRAK OPISU", time=5000)   
Beispiel #26
0
 def logout(self):
     """Logout of the current account and reset the session"""
     common.debug('Logging out of current account')
     cookies.delete(self.account_hash)
     self._get('logout')
     common.purge_credentials()
     common.info('Logout successful')
     ui.show_notification(common.get_local_string(30113))
     self._init_session()
     xbmc.executebuiltin('XBMC.Container.Update(path,replace)')  # Clean path history
     xbmc.executebuiltin('XBMC.ActivateWindow(Home)')
Beispiel #27
0
 def shutdown(self):
     """
     Stop the background services
     """
     for server in self.SERVERS:
         server['instance'].server_close()
         server['instance'].shutdown()
         server['instance'] = None
         server['thread'].join()
         server['thread'] = None
     common.info('Stopped MSL Service')
Beispiel #28
0
 def root(self, pathitems=None):
     """Show profiles or home listing is autologin es enabled"""
     # pylint: disable=unused-argument
     autologin = g.ADDON.getSettingBool('autologin_enable')
     profile_id = g.ADDON.getSetting('autologin_id')
     if autologin and profile_id:
         common.info('Performing auto-login for selected profile {}', profile_id)
         api.activate_profile(profile_id)
         self.home(None, False)
     else:
         self.profiles()
 def _prefetch_login(self):
     """Check if we have stored credentials.
     If so, do the login before the user requests it"""
     try:
         common.get_credentials()
         if not self._is_logged_in():
             self._login()
     except MissingCredentialsError:
         common.info('Login prefetch: No stored credentials are available')
     except LoginFailedError:
         ui.show_notification(common.get_local_string(30009))
    def invalidate(self, on_disk=False, bucket_names=None):
        """Clear cache buckets"""
        if not bucket_names:
            bucket_names = BUCKET_NAMES
        for bucket in bucket_names:
            self.window.clearProperty(self._window_property(bucket))
            if bucket in self.buckets:
                del self.buckets[bucket]

        if on_disk:
            self._invalidate_on_disk(bucket_names)
        common.info('Cache invalidated')