def get_synced_items(self, machine_id=None, user_id=None): sync_list = self.get_plextv_sync_lists(machine_id) user_data = users.Users() synced_items = [] try: xml_parse = minidom.parseString(sync_list) except Exception as e: logger.warn( u"PlexPy PlexTV :: Unable to parse XML for get_synced_items: %s" % e) return [] except: logger.warn( u"PlexPy PlexTV :: Unable to parse XML for get_synced_items.") return [] xml_head = xml_parse.getElementsByTagName('SyncList') if not xml_head: logger.warn( u"PlexPy PlexTV :: Unable to parse XML for get_synced_items.") else: for a in xml_head: client_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 and user_id != device_user_id: continue for synced in a.getElementsByTagName('SyncItems'): sync_item = synced.getElementsByTagName('SyncItem') for item in sync_item: sync_id = helpers.get_xml_attr(item, 'id') 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_audio_boost = helpers.get_xml_attr( settings, 'audioBoost') settings_music_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') settings_video_quality = helpers.get_xml_attr( settings, 'videoQuality') settings_video_resolution = helpers.get_xml_attr( settings, 'videoResolution') for location in item.getElementsByTagName('Location'): clean_uri = helpers.get_xml_attr( location, 'uri').split('%2F') rating_key = next( (clean_uri[(idx + 1) % len(clean_uri)] for idx, item in enumerate(clean_uri) if item == 'metadata'), None) sync_details = { "device_name": helpers.sanitize(device_name), "platform": helpers.sanitize(device_platform), "username": helpers.sanitize(device_username), "friendly_name": helpers.sanitize(device_friendly_name), "user_id": device_user_id, "root_title": helpers.sanitize(sync_root_title), "title": helpers.sanitize(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, "music_bitrate": settings_music_bitrate, "photo_quality": settings_photo_quality, "video_quality": settings_video_quality, "total_size": status_total_size, "failure": status_failure, "sync_id": sync_id } synced_items.append(sync_details) return synced_items
def get_synced_items(self, machine_id=None, user_id=None): sync_list = self.get_plextv_sync_lists(machine_id) user_data = users.Users() synced_items = [] try: xml_parse = minidom.parseString(sync_list) except Exception as e: logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_synced_items: %s" % e) return [] except: logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_synced_items.") return [] xml_head = xml_parse.getElementsByTagName('SyncList') if not xml_head: logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_synced_items.") else: for a in xml_head: client_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 and user_id != device_user_id: continue for synced in a.getElementsByTagName('SyncItems'): sync_item = synced.getElementsByTagName('SyncItem') for item in sync_item: sync_id = helpers.get_xml_attr(item, 'id') 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_audio_boost = helpers.get_xml_attr(settings, 'audioBoost') settings_music_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') settings_video_quality = helpers.get_xml_attr(settings, 'videoQuality') settings_video_resolution = helpers.get_xml_attr(settings, 'videoResolution') for location in item.getElementsByTagName('Location'): clean_uri = helpers.get_xml_attr(location, 'uri').split('%2F') rating_key = next((clean_uri[(idx + 1) % len(clean_uri)] for idx, item in enumerate(clean_uri) if item == 'metadata'), None) sync_details = {"device_name": helpers.sanitize(device_name), "platform": helpers.sanitize(device_platform), "username": helpers.sanitize(device_username), "friendly_name": helpers.sanitize(device_friendly_name), "user_id": device_user_id, "root_title": helpers.sanitize(sync_root_title), "title": helpers.sanitize(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, "music_bitrate": settings_music_bitrate, "photo_quality": settings_photo_quality, "video_quality": settings_video_quality, "total_size": status_total_size, "failure": status_failure, "sync_id": sync_id } synced_items.append(sync_details) return synced_items
def ssp_query(self, table_name=None, columns=[], custom_where=[], group_by=[], join_types=[], join_tables=[], join_evals=[], kwargs=None): if not table_name: logger.error('PlexPy DataTables :: No table name received.') return None # Set default variable values parameters = {} args = [] group = '' order = '' where = '' join = '' c_where = '' # Fetch all our parameters if kwargs.get('json_data'): parameters = helpers.process_json_kwargs(json_kwargs=kwargs.get('json_data')) else: logger.error('PlexPy DataTables :: Parameters for Datatables must be sent as a serialised json object ' 'named json_data.') return None dt_columns = parameters['columns'] extracted_columns = self.extract_columns(columns=columns) # Build grouping if group_by: for g in group_by: group += g + ', ' if group: grouping = True group = 'GROUP BY ' + group.rstrip(', ') else: grouping = False # Build join parameters if join_types: counter = 0 for join_type in join_types: if join_type.upper() == 'LEFT OUTER JOIN': join_item = 'LEFT OUTER JOIN %s ON %s = %s ' % \ (join_tables[counter], join_evals[counter][0], join_evals[counter][1]) elif join_type.upper() == 'JOIN' or join_type.upper() == 'INNER JOIN': join_item = 'JOIN %s ON %s = %s ' % \ (join_tables[counter], join_evals[counter][0], join_evals[counter][1]) else: join_item = '' counter += 1 join += join_item # Build custom where parameters if custom_where: for w in custom_where: c_where += w[0] + ' = ? AND ' # The order of our args changes if we are grouping #if grouping: # args.insert(0, w[1]) #else: # args.append(w[1]) # My testing shows that order of args doesn't change args.append(w[1]) if c_where: c_where = 'WHERE ' + c_where.rstrip(' AND ') # Build ordering for o in parameters['order']: sort_order = ' COLLATE NOCASE' if o['dir'] == 'desc': sort_order = ' COLLATE NOCASE DESC' # We first see if a name was sent though for the column sort. if dt_columns[int(o['column'])]['data']: # We have a name, now check if it's a valid column name for our query # so we don't just inject a random value if any(d.lower() == dt_columns[int(o['column'])]['data'].lower() for d in extracted_columns['column_named']): order += dt_columns[int(o['column'])]['data'] + '%s' % sort_order else: # if we receive a bogus name, rather not sort at all. pass # If no name exists for the column, just use the column index to sort else: order += extracted_columns['column_named'][int(o['column'])] order += ', ' if order: order = 'ORDER BY ' + order.rstrip(', ') # Build where parameters if parameters['search']['value']: counter = 0 for s in parameters['columns']: if s['searchable']: # We first see if a name was sent though for the column search. if s['data']: # We have a name, now check if it's a valid column name for our query # so we don't just inject a random value if any(d.lower() == s['data'].lower() for d in extracted_columns['column_named']): where += s['data'] + ' LIKE ? OR ' args.append('%' + parameters['search']['value'] + '%') else: # if we receive a bogus name, rather not search at all. pass # If no name exists for the column, just use the column index to search else: where += extracted_columns['column_named'][counter] + ' LIKE ? OR ' args.append('%' + parameters['search']['value'] + '%') counter += 1 if where: where = 'WHERE ' + where.rstrip(' OR ') # Build our queries if grouping: if c_where == '': query = 'SELECT * FROM (SELECT %s FROM %s %s %s) %s %s' \ % (extracted_columns['column_string'], table_name, join, group, where, order) else: query = 'SELECT * FROM (SELECT %s FROM %s %s %s %s) %s %s' \ % (extracted_columns['column_string'], table_name, join, c_where, group, where, order) else: if c_where == '': query = 'SELECT %s FROM %s %s %s %s' \ % (extracted_columns['column_string'], table_name, join, where, order) else: query = 'SELECT * FROM (SELECT %s FROM %s %s %s %s) %s' \ % (extracted_columns['column_string'], table_name, join, where, order, c_where) # logger.debug(u"Query: %s" % query) # Execute the query filtered = self.ssp_db.select(query, args=args) # Build grand totals totalcount = self.ssp_db.select('SELECT COUNT(id) as total_count from %s' % table_name)[0]['total_count'] # Get draw counter draw_counter = int(parameters['draw']) # Paginate results result = filtered[parameters['start']:(parameters['start'] + parameters['length'])] # Sanitize on the way out result = [{k: helpers.sanitize(v) if isinstance(v, basestring) else v for k, v in row.iteritems()} for row in result] output = {'result': result, 'draw': draw_counter, 'filteredCount': len(filtered), 'totalCount': totalcount} return output
def ssp_query(self, table_name=None, columns=[], custom_where=[], group_by=[], join_types=[], join_tables=[], join_evals=[], kwargs=None): if not table_name: logger.error('PlexPy DataTables :: No table name received.') return None # Set default variable values parameters = {} args = [] group = '' order = '' where = '' join = '' c_where = '' # Fetch all our parameters if kwargs.get('json_data'): parameters = helpers.process_json_kwargs( json_kwargs=kwargs.get('json_data')) else: logger.error( 'PlexPy DataTables :: Parameters for Datatables must be sent as a serialised json object ' 'named json_data.') return None dt_columns = parameters['columns'] extracted_columns = self.extract_columns(columns=columns) # Build grouping if group_by: for g in group_by: group += g + ', ' if group: grouping = True group = 'GROUP BY ' + group.rstrip(', ') else: grouping = False # Build join parameters if join_types: counter = 0 for join_type in join_types: if join_type.upper() == 'LEFT OUTER JOIN': join_item = 'LEFT OUTER JOIN %s ON %s = %s ' % \ (join_tables[counter], join_evals[counter][0], join_evals[counter][1]) elif join_type.upper() == 'JOIN' or join_type.upper( ) == 'INNER JOIN': join_item = 'JOIN %s ON %s = %s ' % \ (join_tables[counter], join_evals[counter][0], join_evals[counter][1]) else: join_item = '' counter += 1 join += join_item # Build custom where parameters if custom_where: for w in custom_where: c_where += w[0] + ' = ? AND ' # The order of our args changes if we are grouping #if grouping: # args.insert(0, w[1]) #else: # args.append(w[1]) # My testing shows that order of args doesn't change args.append(w[1]) if c_where: c_where = 'WHERE ' + c_where.rstrip(' AND ') # Build ordering for o in parameters['order']: sort_order = ' COLLATE NOCASE' if o['dir'] == 'desc': sort_order = ' COLLATE NOCASE DESC' # We first see if a name was sent though for the column sort. if dt_columns[int(o['column'])]['data']: # We have a name, now check if it's a valid column name for our query # so we don't just inject a random value if any(d.lower() == dt_columns[int(o['column'])] ['data'].lower() for d in extracted_columns['column_named']): order += dt_columns[int( o['column'])]['data'] + '%s' % sort_order else: # if we receive a bogus name, rather not sort at all. pass # If no name exists for the column, just use the column index to sort else: order += extracted_columns['column_named'][int(o['column'])] order += ', ' if order: order = 'ORDER BY ' + order.rstrip(', ') # Build where parameters if parameters['search']['value']: counter = 0 for s in parameters['columns']: if s['searchable']: # We first see if a name was sent though for the column search. if s['data']: # We have a name, now check if it's a valid column name for our query # so we don't just inject a random value if any(d.lower() == s['data'].lower() for d in extracted_columns['column_named']): where += s['data'] + ' LIKE ? OR ' args.append('%' + parameters['search']['value'] + '%') else: # if we receive a bogus name, rather not search at all. pass # If no name exists for the column, just use the column index to search else: where += extracted_columns['column_named'][ counter] + ' LIKE ? OR ' args.append('%' + parameters['search']['value'] + '%') counter += 1 if where: where = 'WHERE ' + where.rstrip(' OR ') # Build our queries if grouping: if c_where == '': query = 'SELECT * FROM (SELECT %s FROM %s %s %s) %s %s' \ % (extracted_columns['column_string'], table_name, join, group, where, order) else: query = 'SELECT * FROM (SELECT %s FROM %s %s %s %s) %s %s' \ % (extracted_columns['column_string'], table_name, join, c_where, group, where, order) else: if c_where == '': query = 'SELECT %s FROM %s %s %s %s' \ % (extracted_columns['column_string'], table_name, join, where, order) else: query = 'SELECT * FROM (SELECT %s FROM %s %s %s %s) %s' \ % (extracted_columns['column_string'], table_name, join, where, order, c_where) # logger.debug(u"Query: %s" % query) # Execute the query filtered = self.ssp_db.select(query, args=args) # Build grand totals totalcount = self.ssp_db.select( 'SELECT COUNT(id) as total_count from %s' % table_name)[0]['total_count'] # Get draw counter draw_counter = int(parameters['draw']) # Paginate results result = filtered[parameters['start']:(parameters['start'] + parameters['length'])] # Sanitize on the way out result = [{ k: helpers.sanitize(v) if isinstance(v, basestring) else v for k, v in row.iteritems() } for row in result] output = { 'result': result, 'draw': draw_counter, 'filteredCount': len(filtered), 'totalCount': totalcount } return output
def get_synced_items(self, machine_id=None, client_id_filter=None, user_id_filter=None, rating_key_filter=None, sync_id_filter=None, server_id_filter=None): 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)] user_data = users.Users() synced_items = [] for server in plexpy.PMS_SERVERS: if server_id_filter and int(server_id_filter) != server.CONFIG.ID: continue if not session.allow_session_server(server.CONFIG.ID): continue machine_id = server.CONFIG.PMS_IDENTIFIER sync_list = self.get_plextv_sync_lists(machine_id, output_format='xml') try: xml_head = sync_list.getElementsByTagName('SyncList') except Exception as e: logger.warn( u"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: for location in item.getElementsByTagName('Location'): clean_uri = helpers.get_xml_attr( location, 'uri').split('%2F') rating_key = next( (clean_uri[(idx + 1) % len(clean_uri)] for idx, item in enumerate(clean_uri) if item == 'metadata'), None) # 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": helpers.sanitize(device_name), "server_id": server.CONFIG.ID, "server_name": server.CONFIG.PMS_NAME, "platform": helpers.sanitize(device_platform), "user_id": device_user_id, "user": helpers.sanitize(device_friendly_name), "username": helpers.sanitize(device_username), "root_title": helpers.sanitize(sync_root_title), "sync_title": helpers.sanitize(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 } synced_items.append(sync_details) return session.filter_session_info(synced_items, filter_key='user_id')
for settings in item.getElementsByTagName('MediaSettings'): settings_audio_boost = helpers.get_xml_attr(settings, 'audioBoost') settings_music_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') settings_video_quality = helpers.get_xml_attr(settings, 'videoQuality') settings_video_resolution = helpers.get_xml_attr(settings, 'videoResolution') if helpers.get_xml_attr(item.getElementsByTagName('Location')[0], 'uri').endswith('%2Fchildren'): clean_uri = helpers.get_xml_attr(item.getElementsByTagName('Location')[0], 'uri')[:-11] else: clean_uri = helpers.get_xml_attr(item.getElementsByTagName('Location')[0], 'uri') rating_key = clean_uri.rpartition('%2F')[-1] sync_details = {"device_name": helpers.sanitize(device_name), "platform": helpers.sanitize(device_platform), "username": helpers.sanitize(device_username), "friendly_name": helpers.sanitize(device_friendly_name), "user_id": device_user_id, "root_title": helpers.sanitize(sync_root_title), "title": helpers.sanitize(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, "music_bitrate": settings_music_bitrate,
def ssp_query(self, table_name=None, table_name_union=None, columns=[], columns_union=[], custom_where=[], custom_where_union=[], group_by=[], group_by_union=[], join_types=[], join_tables=[], join_evals=[], union_join_types=[], union_join_tables=[], union_join_evals=[], kwargs=None): if not table_name: logger.error('Tautulli DataTables :: No table name received.') return None # Fetch all our parameters if kwargs.get('json_data'): parameters = helpers.process_json_kwargs( json_kwargs=kwargs.get('json_data')) else: logger.error( 'Tautulli DataTables :: Parameters for Datatables must be sent as a serialised json object ' 'named json_data.') return None extracted_columns = self.extract_columns(columns=columns) join = self.build_join(join_types, join_tables, join_evals) union_join = self.build_join(union_join_types, union_join_tables, union_join_evals) group = self.build_grouping(group_by) c_where, cw_args = self.build_custom_where(custom_where) order = self.build_order(parameters['order'], extracted_columns['column_named'], parameters['columns']) where, w_args = self.build_where(parameters['search']['value'], extracted_columns['column_named'], parameters['columns']) # Build union parameters if table_name_union: extracted_columns_union = self.extract_columns( columns=columns_union) group_u = self.build_grouping(group_by_union) c_where_u, cwu_args = self.build_custom_where(custom_where_union) union = 'UNION SELECT %s FROM %s %s %s %s' % ( extracted_columns_union['column_string'], table_name_union, union_join, c_where_u, group_u) else: union = '' cwu_args = [] args = cw_args + cwu_args + w_args # Build the query query = 'SELECT * FROM (SELECT %s FROM %s %s %s %s %s) %s %s' \ % (extracted_columns['column_string'], table_name, join, c_where, group, union, where, order) # logger.debug(u"Query: %s" % query) # Execute the query filtered = self.ssp_db.select(query, args=args) # Remove NULL rows filtered = [ row for row in filtered if not all(v is None for v in row.values()) ] # Build grand totals totalcount = self.ssp_db.select( 'SELECT COUNT(id) as total_count from %s' % table_name)[0]['total_count'] # Get draw counter draw_counter = int(parameters['draw']) # Paginate results result = filtered[parameters['start']:(parameters['start'] + parameters['length'])] # Sanitize on the way out result = [{ k: helpers.sanitize(v) if isinstance(v, str) else v for k, v in row.items() } for row in result] output = { 'result': result, 'draw': draw_counter, 'filteredCount': len(filtered), 'totalCount': totalcount } return output