Example #1
0
def showServerSessions():
    log.debug("showServerSessions Called")

    handle = int(sys.argv[1])
    downloadUtils = DownloadUtils()
    url = "{server}/emby/Sessions"
    result_data = downloadUtils.downloadUrl(url)
    results = json.loads(result_data)

    if results is None:
        return

    list_items = []
    for session in results:
        device_name = session.get("DeviceName", "na")
        user_name = session.get("UserName", "na")
        client_name = session.get("Client", "na")

        session_info = device_name + " - " + user_name + " - " + client_name

        # playstate
        percenatge_played = 0
        play_state = session.get("PlayState", None)
        if play_state is not None:
            runtime = 0
            media_id = play_state.get("MediaSourceId", None)
            log.debug("Media ID: {0}", media_id)
            if media_id is not None:
                url = "{server}/emby/Users/{userid}/Items/" + media_id + "?format=json"
                jsonData = downloadUtils.downloadUrl(url)
                media_info = json.loads(jsonData)
                if media_info:
                    log.debug("Media Info: {0}", media_info)
                    runtime = media_info.get("RunTimeTicks", 0)
                    log.debug("Media Runtime: {0}", runtime)

            position_ticks = play_state.get("PositionTicks", 0)
            log.debug("Media PositionTicks: {0}", position_ticks)
            if position_ticks > 0 and runtime > 0:
                percenatge_played = (position_ticks / float(runtime)) * 100.0
                percenatge_played = int(percenatge_played)

        now_playing = session.get("NowPlayingItem", None)
        log.debug("NOW_PLAYING: {0}", now_playing)
        if now_playing is not None:
            session_info += " (" + now_playing.get(
                "Name", "na") + " " + str(percenatge_played) + "%)"

        log.debug("session_info: {0}", session_info)
        list_item = xbmcgui.ListItem(label=session_info)
        item_tuple = ("", list_item, False)
        list_items.append(item_tuple)

    xbmcplugin.addDirectoryItems(handle, list_items)
    xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
 def process_plex_node(self, url, viewOffset, directplay=False,
                       node=True):
     """
     Called for Plex directories or redirect for playback (e.g. trailers,
     clips, watchlater)
     """
     log.info('process_plex_node called with url: %s, viewOffset: %s'
              % (url, viewOffset))
     # Plex redirect, e.g. watch later. Need to get actual URLs
     if url.startswith('http') or url.startswith('{server}'):
         xml = DownloadUtils().downloadUrl(url)
     else:
         xml = DownloadUtils().downloadUrl('{server}%s' % url)
     try:
         xml[0].attrib
     except:
         log.error('Could not download PMS metadata')
         return
     if viewOffset != '0':
         try:
             viewOffset = int(v.PLEX_TO_KODI_TIMEFACTOR * float(viewOffset))
         except:
             pass
         else:
             window('plex_customplaylist.seektime', value=str(viewOffset))
             log.info('Set resume point to %s' % str(viewOffset))
     api = API(xml[0])
     typus = v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[api.getType()]
     if node is True:
         plex_id = None
         kodi_id = 'plexnode'
     else:
         plex_id = api.getRatingKey()
         kodi_id = None
         with plexdb.Get_Plex_DB() as plex_db:
             plexdb_item = plex_db.getItem_byId(plex_id)
             try:
                 kodi_id = plexdb_item[0]
             except TypeError:
                 log.info('Couldnt find item %s in Kodi db'
                          % api.getRatingKey())
     playqueue = self.playqueue.get_playqueue_from_type(typus)
     with lock:
         result = PlaybackUtils(xml, playqueue).play(
             plex_id,
             kodi_id=kodi_id,
             plex_lib_UUID=xml.attrib.get('librarySectionUUID'))
     if directplay:
         if result.listitem:
             listitem = convert_PKC_to_listitem(result.listitem)
             Player().play(listitem.getfilename(), listitem)
         return Playback_Successful()
     else:
         return result
Example #3
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)
        self.doUtils = DownloadUtils().downloadUrl

        self.machineIdentifier = window('plex_machineIdentifier')
Example #4
0
 def __init__(self, callback):
     self.mgr = callback
     self.doUtils = DownloadUtils().downloadUrl
     self.xbmcplayer = Player()
     self.playqueue = self.mgr.playqueue
     Monitor.__init__(self)
     log.info("Kodi monitor started.")
Example #5
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)
        self.doUtils = DownloadUtils().downloadUrl

        self.userid = window('currUserId')
        self.server = window('pms_server')
        self.machineIdentifier = window('plex_machineIdentifier')
Example #6
0
def get_pin():
    """
    For plex.tv sign-in: returns 4-digit code and identifier as 2 str
    """
    code = None
    identifier = None
    # Download
    xml = DU().downloadUrl('https://plex.tv/pins.xml',
                           authenticate=False,
                           action_type="POST")
    try:
        xml.attrib
    except AttributeError:
        LOG.error("Error, no PIN from plex.tv provided")
        return None, None
    code = xml.find('code').text
    identifier = xml.find('id').text
    LOG.info('Successfully retrieved code and id from plex.tv')
    return code, identifier
Example #7
0
def check_pin(identifier):
    """
    Checks with plex.tv whether user entered the correct PIN on plex.tv/pin

    Returns False if not yet done so, or the XML response file as etree
    """
    # Try to get a temporary token
    xml = DU().downloadUrl('https://plex.tv/pins/%s.xml' % identifier,
                           authenticate=False)
    try:
        temp_token = xml.find('auth_token').text
    except AttributeError:
        LOG.error("Could not find token in plex.tv answer")
        return False
    if not temp_token:
        return False
    # Use temp token to get the final plex credentials
    xml = DU().downloadUrl('https://plex.tv/users/account',
                           authenticate=False,
                           parameters={'X-Plex-Token': temp_token})
    return xml
def _poke_pms(pms, queue):
    data = pms['connections'][0].attrib
    if data['local'] == '1':
        protocol = data['protocol']
        address = data['address']
        port = data['port']
        url = '%s://%s:%s' % (protocol, address, port)
    else:
        url = data['uri']
        if url.count(':') == 1:
            url = '%s:%s' % (url, data['port'])
        protocol, address, port = url.split(':', 2)
        address = address.replace('/', '')
    xml = DU().downloadUrl('%s/identity' % url,
                           authenticate=False,
                           headerOptions={'X-Plex-Token': pms['token']},
                           verifySSL=False,
                           timeout=10)
    try:
        xml.attrib['machineIdentifier']
    except (AttributeError, KeyError):
        # No connection, delete the one we just tested
        del pms['connections'][0]
        if pms['connections']:
            # Still got connections left, try them
            return _poke_pms(pms, queue)
        return
    else:
        # Connection successful - correct pms?
        if xml.get('machineIdentifier') == pms['machineIdentifier']:
            # process later
            pms['baseURL'] = url
            pms['protocol'] = protocol
            pms['ip'] = address
            pms['port'] = port
            queue.put(pms)
            return
    LOG.info('Found a pms at %s, but the expected machineIdentifier of '
             '%s did not match the one we found: %s',
             url, pms['uuid'], xml.get('machineIdentifier'))
Example #9
0
    def __init__(self):
        self.__dict__ = self.__shared_state

        self.auth = True
        self.retry = 0

        self.currUser = None
        self.currServer = None
        self.currToken = None
        self.HasAccess = True
        self.AdditionalUser = []

        self.userSettings = None

        self.addon = xbmcaddon.Addon()
        self.doUtils = DU()

        Thread.__init__(self)
Example #10
0
    def get_items(self, url, gui_options, use_cache=False):

        home_window = HomeWindow()
        log.debug("last_content_url : {0}", url)
        home_window.setProperty("last_content_url", url)

        user_id = DownloadUtils().getUserId()

        m = hashlib.md5()
        m.update(user_id + "|" + url)
        url_hash = m.hexdigest()
        cache_file = os.path.join(self.addon_dir, "cache_" + url_hash + ".pickle")

        #changed_url = url + "&MinDateLastSavedForUser="******"2019-09-16T13:45:30")
        #results = self.GetContent(changed_url)
        #log.debug("DataManager Changes Since Date : {0}", results)

        item_list = None
        baseline_name = None
        cache_thread = CacheManagerThread()
        cache_thread.gui_options = gui_options

        home_window.setProperty(cache_file, "true")

        clear_cache = home_window.getProperty("skip_cache_for_" + url)
        if clear_cache and os.path.isfile(cache_file):
            log.debug("Clearing cache data and loading new data")
            home_window.clearProperty("skip_cache_for_" + url)
            os.remove(cache_file)

        # try to load the list item data form the cache
        if os.path.isfile(cache_file) and use_cache:
            log.debug("Loading url data from cached pickle data")

            with open(cache_file, 'rb') as handle:
                try:
                    cache_item = cPickle.load(handle)
                    cache_thread.cached_item = cache_item
                    item_list = cache_item.item_list
                except Exception, err:
                    log.debug("Pickle Data Load Failed : {0}", err)
                    item_list = None
Example #11
0
from utils import getArt
from simple_logging import SimpleLogging
from translation import i18n
from downloadutils import DownloadUtils
from datamanager import DataManager
from kodi_utils import HomeWindow

log = SimpleLogging(__name__)
kodi_version = int(xbmc.getInfoLabel('System.BuildVersion')[:2])

addon_instance = xbmcaddon.Addon()
addon_path = addon_instance.getAddonInfo('path')
PLUGINPATH = xbmc.translatePath(os.path.join(addon_path))

download_utils = DownloadUtils()
home_window = HomeWindow()


class ItemDetails():

    name = None
    id = None
    path = None
    is_folder = False
    plot = None
    series_name = None
    episode_number = 0
    season_number = 0
    track_number = 0
Example #12
0
class UserClient(Thread):

    # Borg - multiple instances, shared state
    __shared_state = {}

    def __init__(self):
        self.__dict__ = self.__shared_state

        self.auth = True
        self.retry = 0

        self.currUser = None
        self.currServer = None
        self.currToken = None
        self.HasAccess = True
        self.AdditionalUser = []

        self.userSettings = None

        self.addon = xbmcaddon.Addon()
        self.doUtils = DU()

        Thread.__init__(self)

    def getUsername(self):
        """
        Returns username as unicode
        """
        username = settings('username')
        if not username:
            LOG.debug("No username saved, trying to get Plex username")
            username = settings('plexLogin')
            if not username:
                LOG.debug("Also no Plex username found")
                return ""
        return username

    def getServer(self, prefix=True):
        # Original host
        self.servername = settings('plex_servername')
        HTTPS = settings('https') == "true"
        host = settings('ipaddress')
        port = settings('port')
        self.machineIdentifier = settings('plex_machineIdentifier')

        server = host + ":" + port

        if not host:
            LOG.debug("No server information saved.")
            return False

        # If https is true
        if prefix and HTTPS:
            server = "https://%s" % server
        # If https is false
        elif prefix and not HTTPS:
            server = "http://%s" % server
        # User entered IP; we need to get the machineIdentifier
        if self.machineIdentifier == '' and prefix is True:
            self.machineIdentifier = PF.GetMachineIdentifier(server)
            if self.machineIdentifier is None:
                self.machineIdentifier = ''
            settings('plex_machineIdentifier', value=self.machineIdentifier)
        LOG.debug('Returning active server: %s', server)
        return server

    def getSSLverify(self):
        # Verify host certificate
        return None if settings('sslverify') == 'true' else False

    def getSSL(self):
        # Client side certificate
        return None if settings('sslcert') == 'None' \
            else settings('sslcert')

    def setUserPref(self):
        LOG.debug('Setting user preferences')
        # Only try to get user avatar if there is a token
        if self.currToken:
            url = PF.GetUserArtworkURL(self.currUser)
            if url:
                window('PlexUserImage', value=url)
        # Set resume point max
        # url = "{server}/emby/System/Configuration?format=json"
        # result = doUtils.downloadUrl(url)

    def hasAccess(self):
        # Plex: always return True for now
        return True

    def loadCurrUser(self, username, userId, usertoken, authenticated=False):
        LOG.debug('Loading current user')
        doUtils = self.doUtils

        self.currToken = usertoken
        self.currServer = self.getServer()
        self.ssl = self.getSSLverify()
        self.sslcert = self.getSSL()

        if authenticated is False:
            if self.currServer is None:
                return False
            LOG.debug('Testing validity of current token')
            res = PF.check_connection(self.currServer,
                                      token=self.currToken,
                                      verifySSL=self.ssl)
            if res is False:
                # PMS probably offline
                return False
            elif res == 401:
                LOG.error('Token is no longer valid')
                return 401
            elif res >= 400:
                LOG.error('Answer from PMS is not as expected. Retrying')
                return False

        # Set to windows property
        state.PLEX_USER_ID = userId or None
        state.PLEX_USERNAME = username
        # This is the token for the current PMS (might also be '')
        window('pms_token', value=usertoken)
        state.PMS_TOKEN = usertoken
        # This is the token for plex.tv for the current user
        # Is only '' if user is not signed in to plex.tv
        window('plex_token', value=settings('plexToken'))
        state.PLEX_TOKEN = settings('plexToken') or None
        window('plex_restricteduser', value=settings('plex_restricteduser'))
        state.RESTRICTED_USER = True \
            if settings('plex_restricteduser') == 'true' else False
        window('pms_server', value=self.currServer)
        window('plex_machineIdentifier', value=self.machineIdentifier)
        window('plex_servername', value=self.servername)
        window('plex_authenticated', value='true')
        state.AUTHENTICATED = True

        window('useDirectPaths', value='true'
               if settings('useDirectPaths') == "1" else 'false')
        state.DIRECT_PATHS = True if settings('useDirectPaths') == "1" \
            else False
        state.INDICATE_MEDIA_VERSIONS = True \
            if settings('indicate_media_versions') == "true" else False
        window('plex_force_transcode_pix', value='true'
               if settings('force_transcode_pix') == "1" else 'false')

        # Start DownloadUtils session
        doUtils.startSession(reset=True)
        # self.getAdditionalUsers()
        # Set user preferences in settings
        self.currUser = username
        self.setUserPref()

        # Writing values to settings file
        settings('username', value=username)
        settings('userid', value=userId)
        settings('accessToken', value=usertoken)
        return True

    def authenticate(self):
        LOG.debug('Authenticating user')

        # Give attempts at entering password / selecting user
        if self.retry >= 2:
            LOG.error("Too many retries to login.")
            state.PMS_STATUS = 'Stop'
            dialog('ok', lang(33001), lang(39023))
            executebuiltin(
                'Addon.OpenSettings(plugin.video.plexkodiconnect)')
            return False

        # Get /profile/addon_data
        addondir = translatePath(self.addon.getAddonInfo('profile'))

        # If there's no settings.xml
        if not exists("%ssettings.xml" % addondir):
            LOG.error("Error, no settings.xml found.")
            self.auth = False
            return False
        server = self.getServer()
        # If there is no server we can connect to
        if not server:
            LOG.info("Missing server information.")
            self.auth = False
            return False

        # If there is a username in the settings, try authenticating
        username = settings('username')
        userId = settings('userid')
        usertoken = settings('accessToken')
        enforceLogin = settings('enforceUserLogin')
        # Found a user in the settings, try to authenticate
        if username and enforceLogin == 'false':
            LOG.debug('Trying to authenticate with old settings')
            answ = self.loadCurrUser(username,
                                     userId,
                                     usertoken,
                                     authenticated=False)
            if answ is True:
                # SUCCESS: loaded a user from the settings
                return True
            elif answ == 401:
                LOG.error("User token no longer valid. Sign user out")
                settings('username', value='')
                settings('userid', value='')
                settings('accessToken', value='')
            else:
                LOG.debug("Could not yet authenticate user")
                return False

        # Could not use settings - try to get Plex user list from plex.tv
        plextoken = settings('plexToken')
        if plextoken:
            LOG.info("Trying to connect to plex.tv to get a user list")
            userInfo = plex_tv.choose_home_user(plextoken)
            if userInfo is False:
                # FAILURE: Something went wrong, try again
                self.auth = True
                self.retry += 1
                return False
            username = userInfo['username']
            userId = userInfo['userid']
            usertoken = userInfo['token']
        else:
            LOG.info("Trying to authenticate without a token")
            username = ''
            userId = ''
            usertoken = ''

        if self.loadCurrUser(username, userId, usertoken, authenticated=False):
            # SUCCESS: loaded a user from the settings
            return True
        # Something went wrong, try again
        self.auth = True
        self.retry += 1
        return False

    def resetClient(self):
        LOG.debug("Reset UserClient authentication.")
        self.doUtils.stopSession()

        window('plex_authenticated', clear=True)
        state.AUTHENTICATED = False
        window('pms_token', clear=True)
        state.PLEX_TOKEN = None
        state.PLEX_TRANSIENT_TOKEN = None
        state.PMS_TOKEN = None
        window('plex_token', clear=True)
        window('pms_server', clear=True)
        window('plex_machineIdentifier', clear=True)
        window('plex_servername', clear=True)
        state.PLEX_USER_ID = None
        state.PLEX_USERNAME = None
        window('plex_restricteduser', clear=True)
        state.RESTRICTED_USER = False

        settings('username', value='')
        settings('userid', value='')
        settings('accessToken', value='')

        self.currToken = None
        self.auth = True
        self.currUser = None

        self.retry = 0

    def run(self):
        LOG.info("----===## Starting UserClient ##===----")
        stopped = self.stopped
        suspended = self.suspended
        while not stopped():
            while suspended():
                if stopped():
                    break
                sleep(1000)

            if state.PMS_STATUS == "Stop":
                sleep(500)
                continue

            # Verify the connection status to server
            elif state.PMS_STATUS == "restricted":
                # Parental control is restricting access
                self.HasAccess = False

            elif state.PMS_STATUS == "401":
                # Unauthorized access, revoke token
                state.PMS_STATUS = 'Auth'
                window('plex_serverStatus', value='Auth')
                self.resetClient()
                sleep(3000)

            if self.auth and (self.currUser is None):
                # Try to authenticate user
                if not state.PMS_STATUS or state.PMS_STATUS == "Auth":
                    # Set auth flag because we no longer need
                    # to authenticate the user
                    self.auth = False
                    if self.authenticate():
                        # Successfully authenticated and loaded a user
                        LOG.info("Successfully authenticated!")
                        LOG.info("Current user: %s", self.currUser)
                        LOG.info("Current userId: %s", state.PLEX_USER_ID)
                        self.retry = 0
                        state.SUSPEND_LIBRARY_THREAD = False
                        window('plex_serverStatus', clear=True)
                        state.PMS_STATUS = False

            if not self.auth and (self.currUser is None):
                # Loop if no server found
                server = self.getServer()

                # The status Stop is for when user cancelled password dialog.
                # Or retried too many times
                if server and state.PMS_STATUS != "Stop":
                    # Only if there's information found to login
                    LOG.debug("Server found: %s", server)
                    self.auth = True

            # Minimize CPU load
            sleep(100)

        LOG.info("##===---- UserClient Stopped ----===##")
Example #13
0
def _pms_list_from_plex_tv(token):
    """
    get Plex media Server List from plex.tv/pms/resources
    """
    xml = DU().downloadUrl('https://plex.tv/api/resources',
                           authenticate=False,
                           parameters={'includeHttps': 1},
                           headerOptions={'X-Plex-Token': token})
    try:
        xml.attrib
    except AttributeError:
        LOG.error('Could not get list of PMS from plex.tv')
        return

    from Queue import Queue
    queue = Queue()
    thread_queue = []

    max_age_in_seconds = 2*60*60*24
    for device in xml.findall('Device'):
        if 'server' not in device.get('provides'):
            # No PMS - skip
            continue
        if device.find('Connection') is None:
            # no valid connection - skip
            continue
        # check MyPlex data age - skip if >2 days
        info_age = time() - int(device.get('lastSeenAt'))
        if info_age > max_age_in_seconds:
            LOG.debug("Skip server %s not seen for 2 days", device.get('name'))
            continue
        pms = {
            'machineIdentifier': device.get('clientIdentifier'),
            'name': device.get('name'),
            'token': device.get('accessToken'),
            'ownername': device.get('sourceTitle'),
            'product': device.get('product'),  # e.g. 'Plex Media Server'
            'version': device.get('productVersion'),  # e.g. '1.11.2.4772-3e...'
            'device': device.get('device'),  # e.g. 'PC' or 'Windows'
            'platform': device.get('platform'),  # e.g. 'Windows', 'Android'
            'local': device.get('publicAddressMatches') == '1',
            'owned': device.get('owned') == '1',
            'relay': device.get('relay') == '1',
            'presence': device.get('presence') == '1',
            'httpsRequired': device.get('httpsRequired') == '1',
            'connections': []
        }
        # Try a local connection first, no matter what plex.tv tells us
        for connection in device.findall('Connection'):
            if connection.get('local') == '1':
                pms['connections'].append(connection)
        # Then try non-local
        for connection in device.findall('Connection'):
            if connection.get('local') != '1':
                pms['connections'].append(connection)
        # Spawn threads to ping each PMS simultaneously
        thread = Thread(target=_poke_pms, args=(pms, queue))
        thread_queue.append(thread)

    max_threads = 5
    threads = []
    # poke PMS, own thread for each PMS
    while True:
        # Remove finished threads
        for thread in threads:
            if not thread.isAlive():
                threads.remove(thread)
        if len(threads) < max_threads:
            try:
                thread = thread_queue.pop()
            except IndexError:
                # We have done our work
                break
            else:
                thread.start()
                threads.append(thread)
        else:
            sleep(50)
    # wait for requests being answered
    for thread in threads:
        thread.join()
    # declare new PMSs
    pms_list = []
    while not queue.empty():
        pms = queue.get()
        del pms['connections']
        pms_list.append(pms)
        queue.task_done()
    return pms_list
 def GetContent(self, url):
     jsonData = DownloadUtils().downloadUrl(url)
     result = self.loadJasonData(jsonData)
     return result
def showServerSessions():
    log.debug("showServerSessions Called")

    handle = int(sys.argv[1])
    downloadUtils = DownloadUtils()
    data_manager = DataManager()

    url = "{server}/emby/Users/{userid}"
    results = data_manager.GetContent(url)

    is_admin = results.get("Policy", {}).get("IsAdministrator", False)
    if not is_admin:
        xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
        return

    url = "{server}/emby/Sessions"
    results = data_manager.GetContent(url)
    log.debug("session_info: {0}", results)

    if results is None:
        return

    list_items = []
    for session in results:
        device_name = session.get("DeviceName", "na")
        user_name = session.get("UserName", "na")
        client_name = session.get("Client", "na")
        client_version = session.get("ApplicationVersion", "na")

        play_state = session.get("PlayState", None)
        now_playing = session.get("NowPlayingItem", None)
        transcoding_info = session.get("TranscodingInfo", None)

        session_info = user_name + " - " + client_name
        user_session_details = ""

        percenatge_played = 0
        position_ticks = 0
        runtime = 0
        play_method = "na"

        if play_state is not None:
            position_ticks = play_state.get("PositionTicks", 0)
            play_method = play_state.get("PlayMethod", "na")

        art = {}
        if now_playing:
            server = downloadUtils.getServer()
            art = getArt(now_playing, server)

            runtime = now_playing.get("RunTimeTicks", 0)
            if position_ticks > 0 and runtime > 0:
                percenatge_played = (position_ticks / float(runtime)) * 100.0
                percenatge_played = int(percenatge_played)

            session_info += " (" + now_playing.get(
                "Name", "na") + " " + str(percenatge_played) + "%)"
            user_session_details += now_playing.get(
                "Name", "na") + " " + str(percenatge_played) + "%" + "\n"

        else:
            session_info += " (idle)"
            user_session_details += "Idle" + "\n"

        transcoding_details = ""
        if transcoding_info:
            if not transcoding_info.get("IsVideoDirect", None):
                transcoding_details += "Video:" + transcoding_info.get(
                    "VideoCodec", "") + ":" + str(
                        transcoding_info.get("Width", 0)) + "x" + str(
                            transcoding_info.get("Height", 0)) + "\n"
            else:
                transcoding_details += "Video:direct\n"

            if not transcoding_info.get("IsAudioDirect", None):
                transcoding_details += "Audio:" + transcoding_info.get(
                    "AudioCodec", "") + ":" + str(
                        transcoding_info.get("AudioChannels", 0)) + "\n"
            else:
                transcoding_details += "Audio:direct\n"

            transcoding_details += "Bitrate:" + str(
                transcoding_info.get("Bitrate", 0)) + "\n"

        list_item = xbmcgui.ListItem(label=session_info)
        list_item.setArt(art)

        user_session_details += device_name + "(" + client_version + ")\n"
        user_session_details += client_name + "\n"
        user_session_details += play_method + "\n"
        user_session_details += transcoding_details + "\n"

        info_labels = {}
        info_labels["duration"] = str(runtime / 10000000)
        info_labels["mediatype"] = "movie"
        info_labels["plot"] = user_session_details
        list_item.setInfo('video', info_labels)

        list_item.setProperty('TotalTime', str(runtime / 10000000))
        list_item.setProperty('ResumeTime', str(position_ticks / 10000000))
        list_item.setProperty("complete_percentage", str(percenatge_played))

        item_tuple = ("", list_item, False)
        list_items.append(item_tuple)

    xbmcplugin.setContent(handle, "movies")
    xbmcplugin.addDirectoryItems(handle, list_items)
    xbmcplugin.endOfDirectory(handle, cacheToDisc=False)
Example #16
0
def checkServer(force=False, change_user=False, notify=False):
    log.debug("checkServer Called")

    settings = xbmcaddon.Addon()
    serverUrl = ""
    something_changed = False

    if force is False:
        # if not forcing use server details from settings
        svr = downloadUtils.getServer()
        if svr is not None:
            serverUrl = svr

    # if the server is not set then try to detect it
    if serverUrl == "":
        serverInfo = getServerDetails()

        serverNames = []
        for server in serverInfo:
            serverNames.append(server.get("Name", i18n('n/a')))
        if serverNames:
            return_index = xbmcgui.Dialog().select(i18n('select_server'), serverNames)
        else:
            xbmcgui.Dialog().ok(__addon_name__, i18n('no_server_detected'))
            return_index = -1

        if (return_index == -1):
            xbmc.executebuiltin("ActivateWindow(Home)")
            return

        serverUrl = serverInfo[return_index]["Address"]
        log.debug("Selected server: {0}", serverUrl)

        # parse the url
        url_bits = urlparse(serverUrl)
        server_address = url_bits.hostname
        server_port = str(url_bits.port)
        server_protocol = url_bits.scheme
        log.debug("Detected server info {0} - {1} - {2}", server_protocol, server_address, server_port)

        # save the server info
        settings.setSetting("port", server_port)
        settings.setSetting("ipaddress", server_address)

        if server_protocol == "https":
            settings.setSetting("use_https", "true")
        else:
            settings.setSetting("use_https", "false")

        something_changed = True
        if notify:
            xbmcgui.Dialog().ok(i18n('server_detect_succeeded'), i18n('found_server'),
                                i18n('address:') + server_address, i18n('server_port:') + server_port)

    # we need to change the user
    current_username = settings.getSetting("username")
    current_username = unicode(current_username, "utf-8")

    # if asked or we have no current user then show user selection screen
    if change_user or len(current_username) == 0:
        # get a list of users
        log.debug("Getting user list")
        jsonData = downloadUtils.downloadUrl(serverUrl + "/emby/Users/Public?format=json", authenticate=False)

        # TODO: add a setting to enable this
        show_manual = False

        log.debug("jsonData: {0}", jsonData)
        try:
            result = json.loads(jsonData)
        except:
            result = None

        if result is None:
            xbmcgui.Dialog().ok(i18n('error'),
                                i18n('unable_connect_server'),
                                i18n('address:') + serverUrl)
        else:
            selected_id = 0
            names = []
            user_list = []
            secured = []
            for user in result:
                config = user.get("Configuration")
                if (config != None):
                    if (config.get("IsHidden") is None) or (config.get("IsHidden") is False):
                        name = user.get("Name")
                        user_list.append(name)
                        if (user.get("HasPassword") is True):
                            secured.append(True)
                            name = i18n('username_secured') % name
                        else:
                            secured.append(False)
                        names.append(name)
                        if current_username == name:
                            selected_id = len(names) - 1

            if (len(current_username) > 0) and (not any(n == current_username for n in user_list)):
                names.insert(0, i18n('username_userdefined') % current_username)
                user_list.insert(0, current_username)
                secured.insert(0, True)

            if show_manual:
                names.append(i18n('username_userinput'))
                user_list.append('')
                secured.append(True)

            log.debug("User List: {0}", names)
            log.debug("User List: {0}", user_list)

            if current_username:
                selection_title = i18n('select_user') + " (" + current_username + ")"
            else:
                selection_title = i18n('select_user')

            return_value = xbmcgui.Dialog().select(selection_title, names, preselect=selected_id)

            if return_value > -1 and return_value != selected_id:

                log.debug("Selected User Index: {0}", return_value)
                if show_manual and return_value == (len(user_list) -1):
                    kb = xbmc.Keyboard()
                    kb.setHeading(i18n('username:'******'password', saved_password)
                        else:
                            kb = xbmc.Keyboard()
                            kb.setHeading(i18n('password:'******'password', kb.getText())

                                # should we save the password
                                save_password = xbmcgui.Dialog().yesno( "Save Password?",
                                                                        "Do you want to save the password?")
                                if save_password:
                                    log.debug("Saving password for fast user switching: {0}", hashed_username)
                                    settings.setSetting("saved_user_password_" + hashed_username, kb.getText())
                    else:
                        log.debug("Saving username is no password: {0}", selected_user)
                        settings.setSetting("username", selected_user)
                        settings.setSetting('password', '')

        if something_changed:
            home_window = HomeWindow()
            home_window.clearProperty("userid")
            home_window.clearProperty("AccessToken")
            home_window.setProperty("embycon_widget_reload", str(time.time()))
            download_utils = DownloadUtils()
            download_utils.authenticate()
            download_utils.getUserId()
            xbmc.executebuiltin("ActivateWindow(Home)")
            xbmc.executebuiltin("ReloadSkin()")