Beispiel #1
0
def get_servers():
    username = session[USERNAME]
    password = session[PASSWORD]
    plex_server = Plex(username, password)
    servers = plex_server.get_plex_server_resources()
    names = [server.name for server in servers]
    return jsonify(names)
Beispiel #2
0
    def read_line_retry(self, timeout=60, ping=False, stale_sleep=1.0):
        line = None
        stale_since = None

        while not line:
            line = self.read_line()

            if line:
                stale_since = None
                time.sleep(0.05)
                break

            if stale_since is None:
                stale_since = time.time()
                time.sleep(stale_sleep)
                continue
            elif (time.time() - stale_since) > timeout:
                return None
            elif (time.time() - stale_since) > timeout / 2:
                # Nothing returned for 5 seconds
                if self.file.get_path() != self.path:
                    log.debug("Log file moved (probably rotated), closing")
                    self.close()
                elif ping:
                    # Ping server to see if server is still active
                    Plex.detail()
                    ping = False

            time.sleep(stale_sleep)

        return line
Beispiel #3
0
def test_cache():
    http_cache = {}

    # Mock response
    body = read('fixtures/detail_a.xml', mode='r')

    responses.add_callback(
        responses.GET, 'http://mock:32400/',
        callback=lambda request: (200, {}, body),
        content_type='application/xml'
    )

    with Plex.configuration.cache(http=http_cache):
        # Check initial version retrieval
        assert Plex.version() == "0.9.9.16.555-50cd0c3"

        # Change body, ensure cached version is returned
        body = read('fixtures/detail_b.xml', mode='r')

        assert Plex.version() == "0.9.9.16.555-50cd0c3"

        # Clear cache, ensure version has changed
        http_cache.clear()

        assert Plex.version() == "0.9.9.14.531-7eef8c6"
Beispiel #4
0
    def read_line_retry(self, timeout=60, ping=False, stale_sleep=1.0):
        line = None
        stale_since = None

        while not line:
            line = self.read_line()

            if line:
                stale_since = None
                time.sleep(0.05)
                break

            if stale_since is None:
                stale_since = time.time()
                time.sleep(stale_sleep)
                continue
            elif (time.time() - stale_since) > timeout:
                return None
            elif (time.time() - stale_since) > timeout / 2:
                # Nothing returned for 5 seconds
                if self.file.get_path() != self.path:
                    log.debug("Log file moved (probably rotated), closing")
                    self.close()
                elif ping:
                    # Ping server to see if server is still active
                    Plex.detail()
                    ping = False

            time.sleep(stale_sleep)

        return line
Beispiel #5
0
def add_movies():
    data = request.json
    if (not data):
        return {
            "error": "You need to include movies, playlist name and users"
        }, 400

    movie_list = data["movies"]
    name = data["name"]
    users = data["users"]

    if (not movie_list or not name or not users):
        return {
            "error": "You need to include movies, playlist name and users"
        }, 400

    username = session[USERNAME]
    password = session[PASSWORD]
    server = session[SERVER]
    imdb_id = session[IMDB_ID]

    if (not username or not password or not server or not imdb_id):
        return {"error": "Could not find session data"}, 500

    plex_server = Plex(username, password)
    plex_server.add_resource_by_name(server)
    plex_server.connect()
    playlist, failed_movies = plex_server.add_playlist(name, movie_list)

    if (len(users) > 0 and playlist is not None):
        plex_server.copy_to_users(playlist, users)

    return jsonify(failed_movies)
Beispiel #6
0
    def fetch(result, player):
        # Fetch client details
        client = Plex.clients().get(player['key'])

        if not client:
            log.info('Unable to find client with key %r', player['key'])
            return result, None

        # Merge client details from plex API
        result = merge(result, dict([
            (key, getattr(client, key)) for key in [
                'device_class',
                'product',
                'version',

                'host',
                'address',
                'port',

                'protocol',
                'protocol_capabilities',
                'protocol_version'
            ] if getattr(client, key)
        ]))

        return result, client
    def create_session(self, info):
        if not info.get('ratingKey'):
            log.warn('Invalid ratingKey provided from activity info')
            return None

        # Metadata
        metadata = Metadata.get(info['ratingKey'])

        # Guid
        guid = Guid.parse(metadata.guid) if metadata else None

        ws = WatchSession.from_info(info, metadata, guid, info['ratingKey'])
        ws.skip = not metadata

        # Fetch client by `machineIdentifier`
        ws.client = Plex.clients().get(info['machineIdentifier'])

        if not ws.client:
            # Create dummy client from `info`
            ws.client = Client(Plex.client, 'clients')
            ws.client.name = info.get('client', None)
            ws.client.machine_identifier = info.get('machineIdentifier', None)

            ws.client.address = info.get('address', None)
            ws.client.port = info.get('port', None)

        # Create dummy user from `info`
        ws.user = User(Plex.client, 'accounts')
        ws.user.id = info['user_id']
        ws.user.title = info['user_name']

        ws.save()

        log.debug('created session: %s', ws)
        return ws
    def create_session(self, session_key, state):
        """
        :type session_key: str
        :type state: str

        :rtype: WatchSession or None
        """

        log.debug('Creating a WatchSession for the current media')

        item = Plex['status'].sessions().get(session_key)
        if not item:
            log.warn('Unable to find session with key "%s"', session_key)
            return None

        # Metadata
        metadata = Metadata.get(item.rating_key)

        # Guid
        guid = Guid.parse(metadata.guid) if metadata else None

        # Create WatchSession
        ws = WatchSession.from_session(item.session, metadata, guid, item.rating_key, state)
        ws.skip = not metadata

        # Fetch client by `machineIdentifier`
        ws.client = Plex.clients().get(item.session.player.machine_identifier)

        ws.save()

        log.debug('created session: %s', ws)
        return ws
Beispiel #9
0
def scrape_imdb():
    data = request.json
    if (not data):
        return {"error": "You need to include an IMDb id"}, 400

    imdb_id = data[IMDB_ID]

    if (not imdb_id):
        return {"error": "You need to include an IMDb id"}, 400

    username = session[USERNAME]
    password = session[PASSWORD]
    server = session[SERVER]

    if (not username or not password or not server):
        return {"error": "Could not find session data"}, 500

    plex_server = Plex(username, password)
    plex_server.add_resource_by_name(server)
    plex_server.connect()
    movies = plex_server.scrape_imdb("https://www.imdb.com/list/" + imdb_id)

    if (not movies):
        return {"error": "You need to include a valid IMDb id"}, 400

    session[IMDB_ID] = imdb_id

    return jsonify(movies)
Beispiel #10
0
def test_version():
    responses.add(responses.GET,
                  'http://mock:32400',
                  body=read('fixtures/detail_a.xml'),
                  status=200,
                  content_type='application/xml')

    version = Plex.version()

    assert version == "0.9.9.16.555-50cd0c3"
Beispiel #11
0
def test_version():
    responses.add(
        responses.GET, 'http://mock:32400',
        body=read('fixtures/detail_a.xml'), status=200,
        content_type='application/xml'
    )

    version = Plex.version()

    assert version == "0.9.9.16.555-50cd0c3"
Beispiel #12
0
def test_booleans():
    responses.add(
        responses.GET, 'http://mock:32400',
        body=read('fixtures/detail_a.xml'), status=200,
        content_type='application/xml'
    )

    detail = Plex.detail()
    assert detail is not None

    assert detail.multiuser is True
    assert detail.sync is False
def monitor(config):
    
    global dimmed
    global playing

    logger = logging.getLogger(__name__)
    
    while True:
        time.sleep(1)

        plex = Plex(config)
        metadata = plex.get_media_metadata_from_sessions(USER_ID)

        if metadata:
            
            playing = True
            lifx = Lifx(config)
            light_id = config.get('plex-lifx', 'lifx_light_id')
            state = metadata['srobbling']

            if state == 'playing' and not dimmed:
                
                logger.info("PLAYING - Dimming till 0 light bulb {light_id}".format(light_id=light_id))
                lifx.set_state(light_id, 'on', None, 0.5, None)
                time.sleep(1)
                lifx.set_state(light_id, 'off', None, 0, None)
                dimmed = True

            elif dimmed:
                
                logger.info("PAUSED - Dimming till 0.5 light bulb {light_id}".format(light_id=light_id))
                lifx.set_state(light_id, 'on', None, 0.5, None)
                dimmed = False

        elif playing:
            
            logger.info("STOPPED - Turning light bulb {light_id} on".format(light_id=light_id))
            lifx.set_state(light_id, 'on', None, 1, None)
            dimmed = False
            playing = False
    def init_raven(cls):
        # Retrieve server details
        server = Plex.detail()

        if not server:
            return

        # Set client name to a hash of `machine_identifier`
        RAVEN.name = md5(server.machine_identifier)

        RAVEN.tags.update({
            'server.version': server.version
        })
Beispiel #15
0
def choose_server():
    data = request.json
    if (not data):
        return {"error": "You need to include a server name"}, 400

    server = data[SERVER]

    if (not server):
        return {"error": "You need to include a server name"}, 400

    username = session[USERNAME]
    password = session[PASSWORD]
    plex_server = Plex(username, password)
    try:
        plex_server.add_resource_by_name(server)
    except NotMediaServerError:
        return {"error": "Not a plex server"}, 400
    except NoServerError:
        return {"error": "No server with that name"}, 400

    session[SERVER] = server
    return {"message": "Success"}, 200
Beispiel #16
0
def test_clients_filter():
    responses.add(
        responses.GET, 'http://mock:32400/clients',
        body=read('fixtures/clients.xml'), status=200,
        content_type='application/xml'
    )

    container = Plex.clients()
    assert container is not None

    items = list(container.filter(["a7d1b50a-42d1-40b5-9db6-6b0afd013438"]))
    assert len(items) == 1

    assert items[0].machine_identifier == "a7d1b50a-42d1-40b5-9db6-6b0afd013438"
Beispiel #17
0
def test_detail():
    responses.add(
        responses.GET, 'http://mock:32400',
        body=read('fixtures/detail_a.xml'), status=200,
        content_type='application/xml'
    )

    detail = Plex.detail()
    assert detail is not None

    assert detail.friendly_name == "Mock Server"

    assert detail.platform == "Windows"
    assert detail.platform_version == "6.2 (Build 9200)"
Beispiel #18
0
def test_detail():
    responses.add(responses.GET,
                  'http://mock:32400',
                  body=read('fixtures/detail_malformed.xml'),
                  status=200,
                  content_type='application/xml')

    detail = Plex.detail()

    if PARSER == 'etree.HTMLParser':
        assert detail is not None
        assert detail.platform_version == six.u('6.2 (Build 9200)\xff\xff')
    else:
        assert detail is None
Beispiel #19
0
def test_detail():
    responses.add(
        responses.GET, 'http://mock:32400',
        body=read('fixtures/detail_malformed.xml'), status=200,
        content_type='application/xml'
    )

    detail = Plex.detail()

    if PARSER == 'etree.HTMLParser':
        assert detail is not None
        assert detail.platform_version == six.u('6.2 (Build 9200)\xff\xff')
    else:
        assert detail is None
Beispiel #20
0
def test_detail():
    responses.add(responses.GET,
                  'http://mock:32400',
                  body=read('fixtures/detail_a.xml'),
                  status=200,
                  content_type='application/xml')

    detail = Plex.detail()
    assert detail is not None

    assert detail.friendly_name == "Mock Server"

    assert detail.platform == "Windows"
    assert detail.platform_version == "6.2 (Build 9200)"
    def test(cls):
        if Plex['status'].sessions() is None:
            log.info("Error while retrieving sessions, assuming WebSocket method isn't available")
            return False

        detail = Plex.detail()
        if detail is None:
            log.info('Error while retrieving server info for testing')
            return False

        if not detail.multiuser:
            log.info("Server info indicates multi-user support isn't available, WebSocket method not available")
            return False

        return True
Beispiel #22
0
def test_cache():
    http_cache = {}

    # Mock response
    body = read('fixtures/detail_a.xml', mode='r')

    responses.add_callback(responses.GET,
                           'http://mock:32400/',
                           callback=lambda request: (200, {}, body),
                           content_type='application/xml')

    with Plex.configuration.cache(http=http_cache):
        # Check initial version retrieval
        assert Plex.version() == "0.9.9.16.555-50cd0c3"

        # Change body, ensure cached version is returned
        body = read('fixtures/detail_b.xml', mode='r')

        assert Plex.version() == "0.9.9.16.555-50cd0c3"

        # Clear cache, ensure version has changed
        http_cache.clear()

        assert Plex.version() == "0.9.9.14.531-7eef8c6"
Beispiel #23
0
def test_clients_filter():
    responses.add(responses.GET,
                  'http://mock:32400/clients',
                  body=read('fixtures/clients.xml'),
                  status=200,
                  content_type='application/xml')

    container = Plex.clients()
    assert container is not None

    items = list(container.filter(["a7d1b50a-42d1-40b5-9db6-6b0afd013438"]))
    assert len(items) == 1

    assert items[
        0].machine_identifier == "a7d1b50a-42d1-40b5-9db6-6b0afd013438"
Beispiel #24
0
    def process_server_state(cls):
        # Check startup state
        server = Plex.detail()

        if server is None:
            log.info('Unable to check startup state, detail request failed')
            return

        # Check server startup state
        if server.start_state is None:
            return

        if server.start_state == 'startingPlugins':
            return cls.on_starting_plugins()

        log.error('Unhandled server start state %r', server.start_state)
Beispiel #25
0
def get_users():
    username = session[USERNAME]
    password = session[PASSWORD]
    server = session[SERVER]

    if (not username or not password or not server):
        return {"error": "Could not find session data"}, 500

    plex_server = Plex(username, password)
    plex_server.add_resource_by_name(server)
    plex_server.connect()
    users = plex_server.get_users()

    return jsonify(users)
Beispiel #26
0
    def process_server_state(cls):
        # Check startup state
        server = Plex.detail()

        if server is None:
            log.info('Unable to check startup state, detail request failed')
            return

        # Check server startup state
        if server.start_state is None:
            return

        if server.start_state == 'startingPlugins':
            return cls.on_starting_plugins()

        log.error('Unhandled server start state %r', server.start_state)
Beispiel #27
0
def test_clients():
    responses.add(
        responses.GET, 'http://mock:32400/clients',
        body=read('fixtures/clients.xml'), status=200,
        content_type='application/xml'
    )

    container = Plex.clients()
    assert container is not None

    items = list(container)
    assert len(items) == 1

    assert items[0].name == "One"
    assert items[0].address == "192.168.1.100"
    assert items[0].version == "1.2.2.331-2d6426d7"

    assert items[0].protocol_capabilities == "navigation,playback,timeline,mirror,playqueues"
Beispiel #28
0
def test_clients_get():
    responses.add(
        responses.GET, 'http://mock:32400/clients',
        body=read('fixtures/clients.xml'), status=200,
        content_type='application/xml'
    )

    container = Plex.clients()
    assert container is not None

    # Try retrieve item that exists
    item = container.get("a7d1b50a-42d1-40b5-9db6-6b0afd013438")
    assert item is not None

    assert item.machine_identifier == "a7d1b50a-42d1-40b5-9db6-6b0afd013438"

    # Try retrieve item that doesn't exist
    item = container.get("invalid-identifier")
    assert item is None
Beispiel #29
0
    def test(cls):
        if Plex['status'].sessions() is None:
            log.info(
                "Error while retrieving sessions, assuming WebSocket method isn't available"
            )
            return False

        detail = Plex.detail()
        if detail is None:
            log.info('Error while retrieving server info for testing')
            return False

        if not detail.multiuser:
            log.info(
                "Server info indicates multi-user support isn't available, WebSocket method not available"
            )
            return False

        return True
Beispiel #30
0
def test_clients_get():
    responses.add(responses.GET,
                  'http://mock:32400/clients',
                  body=read('fixtures/clients.xml'),
                  status=200,
                  content_type='application/xml')

    container = Plex.clients()
    assert container is not None

    # Try retrieve item that exists
    item = container.get("a7d1b50a-42d1-40b5-9db6-6b0afd013438")
    assert item is not None

    assert item.machine_identifier == "a7d1b50a-42d1-40b5-9db6-6b0afd013438"

    # Try retrieve item that doesn't exist
    item = container.get("invalid-identifier")
    assert item is None
Beispiel #31
0
def test_clients():
    responses.add(responses.GET,
                  'http://mock:32400/clients',
                  body=read('fixtures/clients.xml'),
                  status=200,
                  content_type='application/xml')

    container = Plex.clients()
    assert container is not None

    items = list(container)
    assert len(items) == 1

    assert items[0].name == "One"
    assert items[0].address == "192.168.1.100"
    assert items[0].version == "1.2.2.331-2d6426d7"

    assert items[
        0].protocol_capabilities == "navigation,playback,timeline,mirror,playqueues"
Beispiel #32
0
def sign_in():
    data = request.json

    if (not data):
        return {"error": "You need to include username and password"}, 400

    username = data[USERNAME]
    password = data[PASSWORD]

    if (not username or not password):
        return {"error": "You need to include username and password"}, 400

    try:
        plex_server = Plex(username, password)
    except SignInError:
        return {"error": "Wrong username or password"}, 401

    session[USERNAME] = username
    session[PASSWORD] = password
    return {"message": "Success"}, 200
Beispiel #33
0
def test_servers():
    responses.add(
        responses.GET, 'http://mock:32400/servers',
        body=read('fixtures/servers.xml'), status=200,
        content_type='application/xml'
    )

    container = Plex.servers()
    assert container is not None

    items = list(container)
    assert len(items) == 2

    assert items[0].name == "One"
    assert items[0].address == "192.168.1.100"
    assert items[0].version == "0.9.9.16.555-50cd0c3"

    assert items[1].name == "Two"
    assert items[1].address == "192.168.1.101"
    assert items[1].version == "0.9.9.14.531-7eef8c6"
Beispiel #34
0
def main():
    app = QApplication([])
    engine = QQmlApplicationEngine()

    # Instances of Objects
    plex = Plex(os.environ['USERNAME'], os.environ['PASSWORD'],
                os.environ['SERVER_NAME'])

    # Expose instances
    context = engine.rootContext()
    context.setContextProperty("plex", plex)

    # Load the view
    view_path = join(dirname(__file__), 'views/view.qml')
    engine.load(abspath(view_path))

    if not engine.rootObjects():
        sys.exit(-1)

    sys.exit(app.exec_())
Beispiel #35
0
def test_servers():
    responses.add(responses.GET,
                  'http://mock:32400/servers',
                  body=read('fixtures/servers.xml'),
                  status=200,
                  content_type='application/xml')

    container = Plex.servers()
    assert container is not None

    items = list(container)
    assert len(items) == 2

    assert items[0].name == "One"
    assert items[0].address == "192.168.1.100"
    assert items[0].version == "0.9.9.16.555-50cd0c3"

    assert items[1].name == "Two"
    assert items[1].address == "192.168.1.101"
    assert items[1].version == "0.9.9.14.531-7eef8c6"
Beispiel #36
0

def setup_logger():
    formatter = logging.Formatter('%(asctime)s %(message)s')
    handler = logging.FileHandler('failed-lookup.log')
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
    logger.setLevel(logging.INFO)


if __name__ == '__main__':
    config_parser.read('settings.ini')
    plex = PlexServer(config_parser.get('Plex', 'url'),
                      config_parser.get('Plex', 'token'))
    plex_interface = Plex()
    min_weight = int(config_parser.get('AniDB', 'min_tag_weight'))
    setup_logger()

    titles = []
    anime_library = plex.library.section(
        config_parser.get('Plex', 'anime_library'))
    plex_interface.set_library(anime_library)
    for video in anime_library.search():
        titles.append(AniDBTitle(video.title))
        #plex_interface.add_show(video.title, video)

    for anime in titles:
        print('Processing "{}"'.format(anime.title))

        anime.anidb_id = anidb.find_id(anime)
Beispiel #37
0
    def get_synced_items(self, machine_id=None, client_id_filter=None, user_id_filter=None,
                         rating_key_filter=None, sync_id_filter=None):

        if not machine_id:
            machine_id = plexpy.CONFIG.PMS_IDENTIFIER

        if isinstance(rating_key_filter, list):
            rating_key_filter = [str(k) for k in rating_key_filter]
        elif rating_key_filter:
            rating_key_filter = [str(rating_key_filter)]

        if isinstance(user_id_filter, list):
            user_id_filter = [str(k) for k in user_id_filter]
        elif user_id_filter:
            user_id_filter = [str(user_id_filter)]

        sync_list = self.get_plextv_sync_lists(machine_id, output_format='xml')
        user_data = users.Users()

        synced_items = []

        try:
            xml_head = sync_list.getElementsByTagName('SyncList')
        except Exception as e:
            logger.warn("Tautulli PlexTV :: Unable to parse XML for get_synced_items: %s." % e)
            return {}

        for a in xml_head:
            client_id = helpers.get_xml_attr(a, 'clientIdentifier')

            # Filter by client_id
            if client_id_filter and str(client_id_filter) != client_id:
                continue

            sync_list_id = helpers.get_xml_attr(a, 'id')
            sync_device = a.getElementsByTagName('Device')

            for device in sync_device:
                device_user_id = helpers.get_xml_attr(device, 'userID')
                try:
                    device_username = user_data.get_details(user_id=device_user_id)['username']
                    device_friendly_name = user_data.get_details(user_id=device_user_id)['friendly_name']
                except:
                    device_username = ''
                    device_friendly_name = ''
                device_name = helpers.get_xml_attr(device, 'name')
                device_product = helpers.get_xml_attr(device, 'product')
                device_product_version = helpers.get_xml_attr(device, 'productVersion')
                device_platform = helpers.get_xml_attr(device, 'platform')
                device_platform_version = helpers.get_xml_attr(device, 'platformVersion')
                device_type = helpers.get_xml_attr(device, 'device')
                device_model = helpers.get_xml_attr(device, 'model')
                device_last_seen = helpers.get_xml_attr(device, 'lastSeenAt')

            # Filter by user_id
            if user_id_filter and device_user_id not in user_id_filter:
                continue

            for synced in a.getElementsByTagName('SyncItems'):
                sync_item = synced.getElementsByTagName('SyncItem')
                for item in sync_item:

                    sync_media_type = None
                    rating_key = None
                    for location in item.getElementsByTagName('Location'):
                        location_uri = unquote(helpers.get_xml_attr(location, 'uri'))

                        if location_uri.startswith('library://'):
                            if 'collection' in location_uri:
                                sync_media_type = 'collection'
                            clean_uri = location_uri.split('/')
                            rating_key = next((j for i, j in zip(clean_uri[:-1], clean_uri[1:])
                                              if i in ('metadata', 'collections')), None)

                        elif location_uri.startswith('playlist://'):
                            sync_media_type = 'playlist'
                            tokens = users.Users().get_tokens(user_id=device_user_id)
                            if tokens['server_token']:
                                plex = Plex(token=tokens['server_token'])
                                for playlist in plex.PlexServer.playlists():
                                    if location_uri.endswith(playlist.guid):
                                        rating_key = str(playlist.ratingKey)  # String for backwards consistency

                    # Filter by rating_key
                    if rating_key_filter and rating_key not in rating_key_filter:
                        continue

                    sync_id = helpers.get_xml_attr(item, 'id')

                    # Filter by sync_id
                    if sync_id_filter and str(sync_id_filter) != sync_id:
                        continue

                    sync_version = helpers.get_xml_attr(item, 'version')
                    sync_root_title = helpers.get_xml_attr(item, 'rootTitle')
                    sync_title = helpers.get_xml_attr(item, 'title')
                    sync_metadata_type = helpers.get_xml_attr(item, 'metadataType')
                    sync_content_type = helpers.get_xml_attr(item, 'contentType')

                    for status in item.getElementsByTagName('Status'):
                        status_failure_code = helpers.get_xml_attr(status, 'failureCode')
                        status_failure = helpers.get_xml_attr(status, 'failure')
                        status_state = helpers.get_xml_attr(status, 'state')
                        status_item_count = helpers.get_xml_attr(status, 'itemsCount')
                        status_item_complete_count = helpers.get_xml_attr(status, 'itemsCompleteCount')
                        status_item_downloaded_count = helpers.get_xml_attr(status, 'itemsDownloadedCount')
                        status_item_ready_count = helpers.get_xml_attr(status, 'itemsReadyCount')
                        status_item_successful_count = helpers.get_xml_attr(status, 'itemsSuccessfulCount')
                        status_total_size = helpers.get_xml_attr(status, 'totalSize')
                        status_item_download_percent_complete = helpers.get_percent(
                            status_item_downloaded_count, status_item_count)

                    for settings in item.getElementsByTagName('MediaSettings'):
                        settings_video_bitrate = helpers.get_xml_attr(settings, 'maxVideoBitrate')
                        settings_video_quality = helpers.get_xml_attr(settings, 'videoQuality')
                        settings_video_resolution = helpers.get_xml_attr(settings, 'videoResolution')
                        settings_audio_boost = helpers.get_xml_attr(settings, 'audioBoost')
                        settings_audio_bitrate = helpers.get_xml_attr(settings, 'musicBitrate')
                        settings_photo_quality = helpers.get_xml_attr(settings, 'photoQuality')
                        settings_photo_resolution = helpers.get_xml_attr(settings, 'photoResolution')

                    sync_details = {"device_name": device_name,
                                    "platform": device_platform,
                                    "user_id": device_user_id,
                                    "user": device_friendly_name,
                                    "username": device_username,
                                    "root_title": sync_root_title,
                                    "sync_title": sync_title,
                                    "metadata_type": sync_metadata_type,
                                    "content_type": sync_content_type,
                                    "rating_key": rating_key,
                                    "state": status_state,
                                    "item_count": status_item_count,
                                    "item_complete_count": status_item_complete_count,
                                    "item_downloaded_count": status_item_downloaded_count,
                                    "item_downloaded_percent_complete": status_item_download_percent_complete,
                                    "video_bitrate": settings_video_bitrate,
                                    "audio_bitrate": settings_audio_bitrate,
                                    "photo_quality": settings_photo_quality,
                                    "video_quality": settings_video_quality,
                                    "total_size": status_total_size,
                                    "failure": status_failure,
                                    "client_id": client_id,
                                    "sync_id": sync_id,
                                    "sync_media_type": sync_media_type
                                    }

                    synced_items.append(sync_details)

        return session.filter_session_info(synced_items, filter_key='user_id')