示例#1
0
    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, e:
            logger.warn("Error parsing XML for Plex sync lists: %s" % e)
            return []
示例#2
0
    def _getUserips(self, user_id=None, user=None, **kwargs):
        custom_where = []
        if user_id:
            custom_where = [['user_id', user_id]]
        elif user:
            custom_where = [['user', user]]

        user_data = users.Users()
        history = user_data.get_user_unique_ips(kwargs=kwargs,
                                                custom_where=custom_where)

        if history:
            self.data = history
            return history
        else:
            self.msg = 'Failed to find users ips'
示例#3
0
    def __init__(self, username=None, password=None, token=None, headers=None):
        self.username = username
        self.password = password
        self.token = token
        self.headers = headers

        self.urls = 'https://plex.tv'
        self.timeout = plexpy.CONFIG.PMS_TIMEOUT
        self.ssl_verify = plexpy.CONFIG.VERIFY_SSL_CERT

        if self.username is None and self.password is None:
            if not self.token:
                # Check if we should use the admin token, or the guest server token
                if session.get_session_user_id():
                    user_data = users.Users()
                    user_tokens = user_data.get_tokens(
                        user_id=session.get_session_user_id())
                    self.token = user_tokens['server_token']
                else:
                    self.token = plexpy.CONFIG.PMS_TOKEN

            if not self.token:
                logger.error(
                    u"Tautulli PlexTV :: PlexTV called, but no token provided."
                )
                return

        self.http_handler = http_handler.HTTPHandler(
            urls=self.urls,
            token=self.token,
            timeout=self.timeout,
            ssl_verify=self.ssl_verify,
            headers=self.headers)

        plexpass = self.get_plexpass_status()
        plexpy.CONFIG.PMS_PLEXPASS = plexpass
        plexpy.CONFIG.write()
示例#4
0
def import_from_plexwatch(database=None,
                          table_name=None,
                          import_ignore_interval=0):

    try:
        connection = sqlite3.connect(database, timeout=20)
        connection.row_factory = sqlite3.Row
    except sqlite3.OperationalError:
        logger.error(u"PlexPy Importer :: Invalid filename.")
        return None
    except ValueError:
        logger.error(u"PlexPy Importer :: Invalid filename.")
        return None

    try:
        connection.execute('SELECT ratingKey from %s' % table_name)
    except sqlite3.OperationalError:
        logger.error(
            u"PlexPy Importer :: Database specified does not contain the required fields."
        )
        return None

    logger.debug(u"PlexPy Importer :: PlexWatch data import in progress...")

    logger.debug(
        u"PlexPy Importer :: Disabling monitoring while import in progress.")
    plexpy.schedule_job(activity_pinger.check_active_sessions,
                        'Check for active sessions',
                        hours=0,
                        minutes=0,
                        seconds=0)
    plexpy.schedule_job(activity_pinger.check_recently_added,
                        'Check for recently added items',
                        hours=0,
                        minutes=0,
                        seconds=0)
    plexpy.schedule_job(activity_pinger.check_server_response,
                        'Check for server response',
                        hours=0,
                        minutes=0,
                        seconds=0)

    ap = activity_processor.ActivityProcessor()
    user_data = users.Users()

    # Get the latest friends list so we can pull user id's
    try:
        plextv.refresh_users()
    except:
        logger.debug(
            u"PlexPy Importer :: Unable to refresh the users list. Aborting import."
        )
        return None

    query = 'SELECT time AS started, ' \
            'stopped, ' \
            'cast(ratingKey as text) AS rating_key, ' \
            'null AS user_id, ' \
            'user, ' \
            'ip_address, ' \
            'paused_counter, ' \
            'platform AS player, ' \
            'null AS platform, ' \
            'null as machine_id, ' \
            'parentRatingKey as parent_rating_key, ' \
            'grandparentRatingKey as grandparent_rating_key, ' \
            'null AS media_type, ' \
            'null AS view_offset, ' \
            'xml, ' \
            'rating as content_rating,' \
            'summary,' \
            'title AS full_title,' \
            '(case when orig_title_ep = "" then orig_title else ' \
            'orig_title_ep end) as title,' \
            '(case when orig_title_ep != "" then orig_title else ' \
            'null end) as grandparent_title ' \
            'FROM ' + table_name + ' ORDER BY id'

    result = connection.execute(query)

    for row in result:
        # Extract the xml from the Plexwatch db xml field.
        extracted_xml = extract_plexwatch_xml(row['xml'])

        # If we get back None from our xml extractor skip over the record and log error.
        if not extracted_xml:
            logger.error(
                u"PlexPy Importer :: Skipping record with ratingKey %s due to malformed xml."
                % str(row['rating_key']))
            continue

        # Skip line if we don't have a ratingKey to work with
        if not row['rating_key']:
            logger.error(
                u"PlexPy Importer :: Skipping record due to null ratingRey.")
            continue

        # If the user_id no longer exists in the friends list, pull it from the xml.
        if user_data.get_user_id(user=row['user']):
            user_id = user_data.get_user_id(user=row['user'])
        else:
            user_id = extracted_xml['user_id']

        session_history = {
            'started': row['started'],
            'stopped': row['stopped'],
            'rating_key': row['rating_key'],
            'title': row['title'],
            'parent_title': extracted_xml['parent_title'],
            'grandparent_title': row['grandparent_title'],
            'user_id': user_id,
            'user': row['user'],
            'ip_address': row['ip_address'],
            'paused_counter': row['paused_counter'],
            'player': row['player'],
            'platform': extracted_xml['platform'],
            'machine_id': extracted_xml['machine_id'],
            'parent_rating_key': row['parent_rating_key'],
            'grandparent_rating_key': row['grandparent_rating_key'],
            'media_type': extracted_xml['media_type'],
            'view_offset': extracted_xml['view_offset'],
            'video_decision': extracted_xml['video_decision'],
            'audio_decision': extracted_xml['audio_decision'],
            'duration': extracted_xml['duration'],
            'width': extracted_xml['width'],
            'height': extracted_xml['height'],
            'container': extracted_xml['container'],
            'video_codec': extracted_xml['video_codec'],
            'audio_codec': extracted_xml['audio_codec'],
            'bitrate': extracted_xml['bitrate'],
            'video_resolution': extracted_xml['video_resolution'],
            'video_framerate': extracted_xml['video_framerate'],
            'aspect_ratio': extracted_xml['aspect_ratio'],
            'audio_channels': extracted_xml['audio_channels'],
            'transcode_protocol': extracted_xml['transcode_protocol'],
            'transcode_container': extracted_xml['transcode_container'],
            'transcode_video_codec': extracted_xml['transcode_video_codec'],
            'transcode_audio_codec': extracted_xml['transcode_audio_codec'],
            'transcode_audio_channels':
            extracted_xml['transcode_audio_channels'],
            'transcode_width': extracted_xml['transcode_width'],
            'transcode_height': extracted_xml['transcode_height']
        }

        session_history_metadata = {
            'rating_key': helpers.latinToAscii(row['rating_key']),
            'parent_rating_key': row['parent_rating_key'],
            'grandparent_rating_key': row['grandparent_rating_key'],
            'title': row['title'],
            'parent_title': extracted_xml['parent_title'],
            'grandparent_title': row['grandparent_title'],
            'media_index': extracted_xml['media_index'],
            'parent_media_index': extracted_xml['parent_media_index'],
            'thumb': extracted_xml['thumb'],
            'parent_thumb': extracted_xml['parent_thumb'],
            'grandparent_thumb': extracted_xml['grandparent_thumb'],
            'art': extracted_xml['art'],
            'media_type': extracted_xml['media_type'],
            'year': extracted_xml['year'],
            'originally_available_at':
            extracted_xml['originally_available_at'],
            'added_at': extracted_xml['added_at'],
            'updated_at': extracted_xml['updated_at'],
            'last_viewed_at': extracted_xml['last_viewed_at'],
            'content_rating': row['content_rating'],
            'summary': row['summary'],
            'tagline': extracted_xml['tagline'],
            'rating': extracted_xml['rating'],
            'duration': extracted_xml['duration'],
            'guid': extracted_xml['guid'],
            'section_id': extracted_xml['section_id'],
            'directors': extracted_xml['directors'],
            'writers': extracted_xml['writers'],
            'actors': extracted_xml['actors'],
            'genres': extracted_xml['genres'],
            'studio': extracted_xml['studio'],
            'full_title': row['full_title']
        }

        # On older versions of PMS, "clip" items were still classified as "movie" and had bad ratingKey values
        # Just make sure that the ratingKey is indeed an integer
        if session_history_metadata['rating_key'].isdigit():
            ap.write_session_history(
                session=session_history,
                import_metadata=session_history_metadata,
                is_import=True,
                import_ignore_interval=import_ignore_interval)
        else:
            logger.debug(u"PlexPy Importer :: Item has bad rating_key: %s" %
                         session_history_metadata['rating_key'])

    logger.debug(u"PlexPy Importer :: PlexWatch data import complete.")
    import_users()

    logger.debug(u"PlexPy Importer :: Re-enabling monitoring.")
    plexpy.initialize_scheduler()
示例#5
0
    def write_session_history(self,
                              session=None,
                              import_metadata=None,
                              is_import=False,
                              import_ignore_interval=0):
        from plexpy import users

        user_data = users.Users()
        user_details = user_data.get_user_friendly_name(user=session['user'])

        if session:
            logging_enabled = False

            if is_import:
                if str(session['stopped']).isdigit():
                    stopped = int(session['stopped'])
                else:
                    stopped = int(time.time())
            else:
                stopped = int(time.time())

            if plexpy.CONFIG.MOVIE_LOGGING_ENABLE and str(session['rating_key']).isdigit() and \
                    session['media_type'] == 'movie':
                logging_enabled = True
            elif plexpy.CONFIG.TV_LOGGING_ENABLE and str(session['rating_key']).isdigit() and \
                    session['media_type'] == 'episode':
                logging_enabled = True
            elif plexpy.CONFIG.MUSIC_LOGGING_ENABLE and str(session['rating_key']).isdigit() and \
                    session['media_type'] == 'track':
                logging_enabled = True
            else:
                logger.debug(
                    u"PlexPy ActivityProcessor :: ratingKey %s not logged. Does not meet logging criteria. "
                    u"Media type is '%s'" %
                    (session['rating_key'], session['media_type']))

            if str(session['paused_counter']).isdigit():
                real_play_time = stopped - session['started'] - int(
                    session['paused_counter'])
            else:
                real_play_time = stopped - session['started']

            if plexpy.CONFIG.LOGGING_IGNORE_INTERVAL and not is_import:
                if (session['media_type'] == 'movie' or session['media_type'] == 'episode') and \
                        (real_play_time < int(plexpy.CONFIG.LOGGING_IGNORE_INTERVAL)):
                    logging_enabled = False
                    logger.debug(
                        u"PlexPy ActivityProcessor :: Play duration for ratingKey %s is %s secs which is less than %s "
                        u"seconds, so we're not logging it." %
                        (session['rating_key'], str(real_play_time),
                         plexpy.CONFIG.LOGGING_IGNORE_INTERVAL))
            if session['media_type'] == 'track' and not is_import:
                if real_play_time < 15 and session['duration'] >= 30:
                    logging_enabled = False
                    logger.debug(
                        u"PlexPy ActivityProcessor :: Play duration for ratingKey %s is %s secs, "
                        u"looks like it was skipped so we're not logging it" %
                        (session['rating_key'], str(real_play_time)))
            elif is_import and import_ignore_interval:
                if (session['media_type'] == 'movie' or session['media_type'] == 'episode') and \
                        (real_play_time < int(import_ignore_interval)):
                    logging_enabled = False
                    logger.debug(
                        u"PlexPy ActivityProcessor :: Play duration for ratingKey %s is %s secs which is less than %s "
                        u"seconds, so we're not logging it." %
                        (session['rating_key'], str(real_play_time),
                         import_ignore_interval))

            if not user_details['keep_history'] and not is_import:
                logging_enabled = False
                logger.debug(
                    u"PlexPy ActivityProcessor :: History logging for user '%s' is disabled."
                    % session['user'])

            if logging_enabled:
                # logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history table...")
                query = 'INSERT INTO session_history (started, stopped, rating_key, parent_rating_key, ' \
                        'grandparent_rating_key, media_type, user_id, user, ip_address, paused_counter, player, ' \
                        'platform, machine_id, view_offset) VALUES ' \
                        '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'

                args = [
                    session['started'], stopped, session['rating_key'],
                    session['parent_rating_key'],
                    session['grandparent_rating_key'], session['media_type'],
                    session['user_id'], session['user'], session['ip_address'],
                    session['paused_counter'], session['player'],
                    session['platform'], session['machine_id'],
                    session['view_offset']
                ]

                # logger.debug(u"PlexPy ActivityProcessor :: Writing session_history transaction...")
                self.db.action(query=query, args=args)

                # Check if we should group the session, select the last two rows from the user
                query = 'SELECT id, rating_key, user_id, reference_id FROM session_history \
                         WHERE user_id = ? ORDER BY id DESC LIMIT 2 '

                args = [session['user_id']]

                result = self.db.select(query=query, args=args)

                new_session = {
                    'id': result[0][0],
                    'rating_key': result[0][1],
                    'user_id': result[0][2],
                    'reference_id': result[0][3]
                }

                if len(result) == 1:
                    prev_session = None
                else:
                    prev_session = {
                        'id': result[1][0],
                        'rating_key': result[1][1],
                        'user_id': result[1][2],
                        'reference_id': result[1][3]
                    }

                query = 'UPDATE session_history SET reference_id = ? WHERE id = ? '
                # If rating_key is the same in the previous session, then set the reference_id to the previous row, else set the reference_id to the new id
                if (prev_session
                        is not None) and (prev_session['rating_key']
                                          == new_session['rating_key']):
                    args = [prev_session['reference_id'], new_session['id']]
                else:
                    args = [new_session['id'], new_session['id']]

                self.db.action(query=query, args=args)

                # logger.debug(u"PlexPy ActivityProcessor :: Successfully written history item, last id for session_history is %s"
                #              % last_id)

                # Write the session_history_media_info table
                # logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history_media_info table...")
                query = 'INSERT INTO session_history_media_info (id, rating_key, video_decision, audio_decision, ' \
                        'duration, width, height, container, video_codec, audio_codec, bitrate, video_resolution, ' \
                        'video_framerate, aspect_ratio, audio_channels, transcode_protocol, transcode_container, ' \
                        'transcode_video_codec, transcode_audio_codec, transcode_audio_channels, transcode_width, ' \
                        'transcode_height) VALUES ' \
                        '(last_insert_rowid(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'

                args = [
                    session['rating_key'], session['video_decision'],
                    session['audio_decision'], session['duration'],
                    session['width'], session['height'], session['container'],
                    session['video_codec'], session['audio_codec'],
                    session['bitrate'], session['video_resolution'],
                    session['video_framerate'], session['aspect_ratio'],
                    session['audio_channels'], session['transcode_protocol'],
                    session['transcode_container'],
                    session['transcode_video_codec'],
                    session['transcode_audio_codec'],
                    session['transcode_audio_channels'],
                    session['transcode_width'], session['transcode_height']
                ]

                # logger.debug(u"PlexPy ActivityProcessor :: Writing session_history_media_info transaction...")
                self.db.action(query=query, args=args)

                if not is_import:
                    logger.debug(
                        u"PlexPy ActivityProcessor :: Fetching metadata for item ratingKey %s"
                        % session['rating_key'])
                    pms_connect = pmsconnect.PmsConnect()
                    result = pms_connect.get_metadata_details(
                        rating_key=str(session['rating_key']))
                    metadata = result['metadata']
                else:
                    metadata = import_metadata

                # Write the session_history_metadata table
                directors = ";".join(metadata['directors'])
                writers = ";".join(metadata['writers'])
                actors = ";".join(metadata['actors'])
                genres = ";".join(metadata['genres'])

                # Build media item title
                if session['media_type'] == 'episode' or session[
                        'media_type'] == 'track':
                    full_title = '%s - %s' % (metadata['grandparent_title'],
                                              metadata['title'])
                elif session['media_type'] == 'movie':
                    full_title = metadata['title']
                else:
                    full_title = metadata['title']

                # logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history_metadata table...")
                query = 'INSERT INTO session_history_metadata (id, rating_key, parent_rating_key, ' \
                        'grandparent_rating_key, title, parent_title, grandparent_title, full_title, media_index, ' \
                        'parent_media_index, thumb, parent_thumb, grandparent_thumb, art, media_type, year, ' \
                        'originally_available_at, added_at, updated_at, last_viewed_at, content_rating, summary, ' \
                        'tagline, rating, duration, guid, directors, writers, actors, genres, studio) VALUES ' \
                        '(last_insert_rowid(), ' \
                        '?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'

                args = [
                    session['rating_key'], session['parent_rating_key'],
                    session['grandparent_rating_key'], session['title'],
                    session['parent_title'], session['grandparent_title'],
                    full_title, metadata['index'], metadata['parent_index'],
                    metadata['thumb'], metadata['parent_thumb'],
                    metadata['grandparent_thumb'], metadata['art'],
                    session['media_type'], metadata['year'],
                    metadata['originally_available_at'], metadata['added_at'],
                    metadata['updated_at'], metadata['last_viewed_at'],
                    metadata['content_rating'], metadata['summary'],
                    metadata['tagline'], metadata['rating'],
                    metadata['duration'], metadata['guid'], directors, writers,
                    actors, genres, metadata['studio']
                ]

                # logger.debug(u"PlexPy ActivityProcessor :: Writing session_history_metadata transaction...")
                self.db.action(query=query, args=args)
示例#6
0
    def write_session_history(self,
                              session=None,
                              import_metadata=None,
                              is_import=False,
                              import_ignore_interval=0):
        server_name = plexpy.PMS_SERVERS.get_server_by_id(
            session['server_id']).CONFIG.PMS_NAME

        library_id = plexpy.libraries.get_section_index(
            session['server_id'], session['section_id'])

        if not is_import:
            user_data = users.Users()
            user_details = user_data.get_details(user_id=session['user_id'])

            library_data = libraries.Libraries()
            library_details = library_data.get_details(id=library_id)

            # Return false if failed to retrieve user or library details
            if not user_details or not library_details:
                return False

        if session:
            logging_enabled = False

            # Reload json from raw stream info
            if session.get('raw_stream_info'):
                raw_stream_info = json.loads(session['raw_stream_info'])
                # Don't overwrite id, session_key, stopped, view_offset
                raw_stream_info.pop('id', None)
                raw_stream_info.pop('session_key', None)
                raw_stream_info.pop('stopped', None)
                raw_stream_info.pop('view_offset', None)
                session.update(raw_stream_info)

            session = defaultdict(str, session)

            if is_import:
                if str(session['stopped']).isdigit():
                    stopped = int(session['stopped'])
                else:
                    stopped = int(time.time())
            elif session['stopped']:
                stopped = int(session['stopped'])
            else:
                stopped = int(time.time())
                self.set_session_state(session_key=session['session_key'],
                                       state='stopped',
                                       stopped=stopped)

            if str(session['rating_key']).isdigit(
            ) and session['media_type'] in ('movie', 'episode', 'track'):
                logging_enabled = True
            else:
                logger.debug(
                    u"Tautulli ActivityProcessor :: %s: Session %s ratingKey %s not logged. "
                    u"Does not meet logging criteria. Media type is '%s'" %
                    (server_name, session['session_key'],
                     session['rating_key'], session['media_type']))
                return session['id']

            if str(session['paused_counter']).isdigit():
                real_play_time = stopped - int(session['started']) - int(
                    session['paused_counter'])
            else:
                real_play_time = stopped - int(session['started'])

            if not is_import and plexpy.CONFIG.LOGGING_IGNORE_INTERVAL:
                if (session['media_type'] == 'movie' or session['media_type'] == 'episode') and \
                        (real_play_time < int(plexpy.CONFIG.LOGGING_IGNORE_INTERVAL)):
                    logging_enabled = False
                    logger.debug(
                        u"Tautulli ActivityProcessor :: %s: Play duration for session %s ratingKey %s is %s secs "
                        u"which is less than %s seconds, so we're not logging it."
                        % (server_name, session['session_key'],
                           session['rating_key'], str(real_play_time),
                           plexpy.CONFIG.LOGGING_IGNORE_INTERVAL))
            if not is_import and session['media_type'] == 'track':
                if real_play_time < 15 and int(session['duration']) >= 30:
                    logging_enabled = False
                    logger.debug(
                        u"Tautulli ActivityProcessor :: %s: Play duration for session %s ratingKey %s is %s secs, "
                        u"looks like it was skipped so we're not logging it" %
                        (server_name, session['session_key'],
                         session['rating_key'], str(real_play_time)))
            elif is_import and import_ignore_interval:
                if (session['media_type'] == 'movie' or session['media_type'] == 'episode') and \
                        (real_play_time < int(import_ignore_interval)):
                    logging_enabled = False
                    logger.debug(
                        u"Tautulli ActivityProcessor :: %s: Play duration for ratingKey %s is %s secs which is less than %s "
                        u"seconds, so we're not logging it." %
                        (server_name, session['rating_key'],
                         str(real_play_time), import_ignore_interval))

            if not is_import and not user_details['keep_history']:
                logging_enabled = False
                logger.debug(
                    u"Tautulli ActivityProcessor :: %s: History logging for user '%s' is disabled."
                    % (server_name, user_details['username']))
            elif not is_import and not library_details['keep_history']:
                logging_enabled = False
                logger.debug(
                    u"Tautulli ActivityProcessor :: %s: History logging for library '%s' is disabled."
                    % (server_name, library_details['section_name']))

            if logging_enabled:

                # Fetch metadata first so we can return false if it fails
                if not is_import:
                    logger.debug(
                        u"Tautulli ActivityProcessor :: %s: Fetching metadata for item ratingKey %s"
                        % (server_name, session['rating_key']))
                    metadata = self.server.get_metadata_details(
                        rating_key=str(session['rating_key']))
                    if not metadata:
                        return False
                    else:
                        media_info = {}
                        if 'media_info' in metadata and len(
                                metadata['media_info']) > 0:
                            media_info = metadata['media_info'][0]
                else:
                    metadata = import_metadata
                    ## TODO: Fix media info from imports. Temporary media info from import session.
                    media_info = session

                # logger.debug(u"Tautulli ActivityProcessor :: %s: Attempting to write sessionKey %s to session_history table..."
                #              % (server_name, session['session_key']))
                keys = {'id': None}
                values = {
                    'started': session['started'],
                    'stopped': stopped,
                    'rating_key': session['rating_key'],
                    'server_id': session['server_id'],
                    'parent_rating_key': session['parent_rating_key'],
                    'grandparent_rating_key':
                    session['grandparent_rating_key'],
                    'media_type': session['media_type'],
                    'user_id': session['user_id'],
                    'user': session['user'],
                    'ip_address': session['ip_address'],
                    'paused_counter': session['paused_counter'],
                    'player': session['player'],
                    'product': session['product'],
                    'product_version': session['product_version'],
                    'platform': session['platform'],
                    'platform_version': session['platform_version'],
                    'profile': session['profile'],
                    'machine_id': session['machine_id'],
                    'bandwidth': session['bandwidth'],
                    'location': session['location'],
                    'quality_profile': session['quality_profile'],
                    'view_offset': session['view_offset']
                }

                # logger.debug(u"Tautulli ActivityProcessor :: %s: Writing sessionKey %s session_history transaction..."
                #              % (server_name, session['session_key']))
                self.db.upsert(table_name='session_history',
                               key_dict=keys,
                               value_dict=values)

                # Check if we should group the session, select the last two rows from the user
                query = 'SELECT id, server_id, rating_key, view_offset, user_id, reference_id FROM session_history ' \
                        'WHERE user_id = ? AND server_id = ? AND rating_key = ? ORDER BY id DESC LIMIT 2 '

                args = [
                    session['user_id'], session['server_id'],
                    session['rating_key']
                ]

                result = self.db.select(query=query, args=args)

                new_session = prev_session = None
                prev_progress_percent = media_watched_percent = 0
                # Get the last insert row id
                last_id = self.db.last_insert_id()

                if len(result) > 1:
                    new_session = {
                        'id': result[0]['id'],
                        'server_id': result[0]['server_id'],
                        'rating_key': result[0]['rating_key'],
                        'view_offset': result[0]['view_offset'],
                        'user_id': result[0]['user_id'],
                        'reference_id': result[0]['reference_id']
                    }

                    prev_session = {
                        'id': result[1]['id'],
                        'server_id': result[1]['server_id'],
                        'rating_key': result[1]['rating_key'],
                        'view_offset': result[1]['view_offset'],
                        'user_id': result[1]['user_id'],
                        'reference_id': result[1]['reference_id']
                    }

                    watched_percent = {
                        'movie': plexpy.CONFIG.MOVIE_WATCHED_PERCENT,
                        'episode': plexpy.CONFIG.TV_WATCHED_PERCENT,
                        'track': plexpy.CONFIG.MUSIC_WATCHED_PERCENT
                    }
                    prev_progress_percent = helpers.get_percent(
                        prev_session['view_offset'], session['duration'])
                    media_watched_percent = watched_percent.get(
                        session['media_type'], 0)

                query = 'UPDATE session_history SET reference_id = ? WHERE id = ? '

                # If previous session view offset less than watched percent,
                # and new session view offset is greater,
                # then set the reference_id to the previous row,
                # else set the reference_id to the new id
                if prev_session is None and new_session is None:
                    args = [last_id, last_id]
                elif prev_progress_percent < media_watched_percent and \
                        prev_session['view_offset'] <= new_session['view_offset']:
                    args = [prev_session['reference_id'], new_session['id']]
                else:
                    args = [new_session['id'], new_session['id']]

                self.db.action(query=query, args=args)

                # logger.debug(u"Tautulli ActivityProcessor :: %s: Successfully written history item, last id for session_history is %s"
                #              % (server_name, last_id))

                # Write the session_history_media_info table

                # logger.debug(u"Tautulli ActivityProcessor :: %s: Attempting to write to sessionKey %s session_history_media_info table..."
                #              % (server_name, session['session_key']))
                keys = {'id': last_id}
                values = {
                    'rating_key':
                    session['rating_key'],
                    'server_id':
                    session['server_id'],
                    'video_decision':
                    session['video_decision'],
                    'audio_decision':
                    session['audio_decision'],
                    'transcode_decision':
                    session['transcode_decision'],
                    'duration':
                    session['duration'],
                    'container':
                    session['container'],
                    'bitrate':
                    session['bitrate'],
                    'width':
                    session['width'],
                    'height':
                    session['height'],
                    'video_bit_depth':
                    session['video_bit_depth'],
                    'video_bitrate':
                    session['video_bitrate'],
                    'video_codec':
                    session['video_codec'],
                    'video_codec_level':
                    session['video_codec_level'],
                    'video_width':
                    session['video_width'],
                    'video_height':
                    session['video_height'],
                    'video_resolution':
                    session['video_resolution'],
                    'video_framerate':
                    session['video_framerate'],
                    'aspect_ratio':
                    session['aspect_ratio'],
                    'audio_codec':
                    session['audio_codec'],
                    'audio_bitrate':
                    session['audio_bitrate'],
                    'audio_channels':
                    session['audio_channels'],
                    'subtitle_codec':
                    session['subtitle_codec'],
                    'transcode_protocol':
                    session['transcode_protocol'],
                    'transcode_container':
                    session['transcode_container'],
                    'transcode_video_codec':
                    session['transcode_video_codec'],
                    'transcode_audio_codec':
                    session['transcode_audio_codec'],
                    'transcode_audio_channels':
                    session['transcode_audio_channels'],
                    'transcode_width':
                    session['transcode_width'],
                    'transcode_height':
                    session['transcode_height'],
                    'transcode_hw_requested':
                    session['transcode_hw_requested'],
                    'transcode_hw_full_pipeline':
                    session['transcode_hw_full_pipeline'],
                    'transcode_hw_decoding':
                    session['transcode_hw_decoding'],
                    'transcode_hw_decode':
                    session['transcode_hw_decode'],
                    'transcode_hw_decode_title':
                    session['transcode_hw_decode_title'],
                    'transcode_hw_encoding':
                    session['transcode_hw_encoding'],
                    'transcode_hw_encode':
                    session['transcode_hw_encode'],
                    'transcode_hw_encode_title':
                    session['transcode_hw_encode_title'],
                    'stream_container':
                    session['stream_container'],
                    'stream_container_decision':
                    session['stream_container_decision'],
                    'stream_bitrate':
                    session['stream_bitrate'],
                    'stream_video_decision':
                    session['stream_video_decision'],
                    'stream_video_bitrate':
                    session['stream_video_bitrate'],
                    'stream_video_codec':
                    session['stream_video_codec'],
                    'stream_video_codec_level':
                    session['stream_video_codec_level'],
                    'stream_video_bit_depth':
                    session['stream_video_bit_depth'],
                    'stream_video_height':
                    session['stream_video_height'],
                    'stream_video_width':
                    session['stream_video_width'],
                    'stream_video_resolution':
                    session['stream_video_resolution'],
                    'stream_video_framerate':
                    session['stream_video_framerate'],
                    'stream_audio_decision':
                    session['stream_audio_decision'],
                    'stream_audio_codec':
                    session['stream_audio_codec'],
                    'stream_audio_bitrate':
                    session['stream_audio_bitrate'],
                    'stream_audio_channels':
                    session['stream_audio_channels'],
                    'stream_subtitle_decision':
                    session['stream_subtitle_decision'],
                    'stream_subtitle_codec':
                    session['stream_subtitle_codec'],
                    'stream_subtitle_container':
                    session['stream_subtitle_container'],
                    'stream_subtitle_forced':
                    session['stream_subtitle_forced'],
                    'subtitles':
                    session['subtitles'],
                    'synced_version':
                    session['synced_version'],
                    'synced_version_profile':
                    session['synced_version_profile'],
                    'optimized_version':
                    session['optimized_version'],
                    'optimized_version_profile':
                    session['optimized_version_profile'],
                    'optimized_version_title':
                    session['optimized_version_title']
                }

                # logger.debug(u"Tautulli ActivityProcessor :: %s: Writing sessionKey %s session_history_media_info transaction..."
                #              % (server_name, session['session_key']))
                self.db.upsert(table_name='session_history_media_info',
                               key_dict=keys,
                               value_dict=values)

                # Write the session_history_metadata table
                directors = ";".join(metadata['directors'])
                writers = ";".join(metadata['writers'])
                actors = ";".join(metadata['actors'])
                genres = ";".join(metadata['genres'])
                labels = ";".join(metadata['labels'])

                # logger.debug(u"Tautulli ActivityProcessor :: %s: Attempting to write to sessionKey %s session_history_metadata table..."
                #              % (server_name, session['session_key']))
                keys = {'id': last_id}
                values = {
                    'rating_key': session['rating_key'],
                    'server_id': session['server_id'],
                    'parent_rating_key': session['parent_rating_key'],
                    'grandparent_rating_key':
                    session['grandparent_rating_key'],
                    'title': session['title'],
                    'parent_title': session['parent_title'],
                    'grandparent_title': session['grandparent_title'],
                    'original_title': session['original_title'],
                    'full_title': session['full_title'],
                    'media_index': metadata['media_index'],
                    'parent_media_index': metadata['parent_media_index'],
                    'section_id': metadata['section_id'],
                    'library_id': library_id,
                    'thumb': metadata['thumb'],
                    'parent_thumb': metadata['parent_thumb'],
                    'grandparent_thumb': metadata['grandparent_thumb'],
                    'art': metadata['art'],
                    'media_type': session['media_type'],
                    'year': metadata['year'],
                    'originally_available_at':
                    metadata['originally_available_at'],
                    'added_at': metadata['added_at'],
                    'updated_at': metadata['updated_at'],
                    'last_viewed_at': metadata['last_viewed_at'],
                    'content_rating': metadata['content_rating'],
                    'summary': metadata['summary'],
                    'tagline': metadata['tagline'],
                    'rating': metadata['rating'],
                    'duration': metadata['duration'],
                    'guid': metadata['guid'],
                    'directors': directors,
                    'writers': writers,
                    'actors': actors,
                    'genres': genres,
                    'studio': metadata['studio'],
                    'labels': labels
                }

                # logger.debug(u"Tautulli ActivityProcessor :: %s: Writing sessionKey %s session_history_metadata transaction..."
                #              % (server_name, session['session_key']))
                self.db.upsert(table_name='session_history_metadata',
                               key_dict=keys,
                               value_dict=values)

            # Return the session row id when the session is successfully written to the database
            return session['id']
示例#7
0
    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
示例#8
0
    def write_session_history(self,
                              session=None,
                              import_metadata=None,
                              is_import=False,
                              import_ignore_interval=0):
        from plexpy import users

        user_data = users.Users()
        user_details = user_data.get_user_friendly_name(user=session['user'])

        if session:
            logging_enabled = False

            if is_import:
                if str(session['stopped']).isdigit():
                    stopped = session['stopped']
                else:
                    stopped = int(time.time())
            else:
                stopped = int(time.time())

            if plexpy.CONFIG.VIDEO_LOGGING_ENABLE and \
                    (session['media_type'] == 'movie' or session['media_type'] == 'episode'):
                logging_enabled = True
            elif plexpy.CONFIG.MUSIC_LOGGING_ENABLE and \
                    session['media_type'] == 'track':
                logging_enabled = True
            else:
                logger.debug(
                    u"PlexPy Monitor :: ratingKey %s not logged. Does not meet logging criteria. "
                    u"Media type is '%s'" %
                    (session['rating_key'], session['media_type']))

            if plexpy.CONFIG.LOGGING_IGNORE_INTERVAL and not is_import:
                if (session['media_type'] == 'movie' or session['media_type'] == 'episode') and \
                        (int(stopped) - session['started'] < int(plexpy.CONFIG.LOGGING_IGNORE_INTERVAL)):
                    logging_enabled = False
                    logger.debug(
                        u"PlexPy Monitor :: Play duration for ratingKey %s is %s secs which is less than %s "
                        u"seconds, so we're not logging it." %
                        (session['rating_key'],
                         str(int(stopped) - session['started']),
                         plexpy.CONFIG.LOGGING_IGNORE_INTERVAL))
            elif is_import and import_ignore_interval:
                if (session['media_type'] == 'movie' or session['media_type'] == 'episode') and \
                        (int(stopped) - session['started'] < int(import_ignore_interval)):
                    logging_enabled = False
                    logger.debug(
                        u"PlexPy Monitor :: Play duration for ratingKey %s is %s secs which is less than %s "
                        u"seconds, so we're not logging it." %
                        (session['rating_key'],
                         str(int(stopped) - session['started']),
                         import_ignore_interval))

            if not user_details['keep_history'] and not is_import:
                logging_enabled = False
                logger.debug(
                    u"PlexPy Monitor :: History logging for user '%s' is disabled."
                    % session['user'])

            if logging_enabled:
                # logger.debug(u"PlexPy Monitor :: Attempting to write to session_history table...")
                query = 'INSERT INTO session_history (started, stopped, rating_key, parent_rating_key, ' \
                        'grandparent_rating_key, media_type, user_id, user, ip_address, paused_counter, player, ' \
                        'platform, machine_id, view_offset) VALUES ' \
                        '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'

                args = [
                    session['started'], stopped, session['rating_key'],
                    session['parent_rating_key'],
                    session['grandparent_rating_key'], session['media_type'],
                    session['user_id'], session['user'], session['ip_address'],
                    session['paused_counter'], session['player'],
                    session['platform'], session['machine_id'],
                    session['view_offset']
                ]

                # logger.debug(u"PlexPy Monitor :: Writing session_history transaction...")
                self.db.action(query=query, args=args)

                # logger.debug(u"PlexPy Monitor :: Successfully written history item, last id for session_history is %s"
                #              % last_id)

                # Write the session_history_media_info table
                # logger.debug(u"PlexPy Monitor :: Attempting to write to session_history_media_info table...")
                query = 'INSERT INTO session_history_media_info (id, rating_key, video_decision, audio_decision, ' \
                        'duration, width, height, container, video_codec, audio_codec, bitrate, video_resolution, ' \
                        'video_framerate, aspect_ratio, audio_channels, transcode_protocol, transcode_container, ' \
                        'transcode_video_codec, transcode_audio_codec, transcode_audio_channels, transcode_width, ' \
                        'transcode_height) VALUES ' \
                        '(last_insert_rowid(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'

                args = [
                    session['rating_key'], session['video_decision'],
                    session['audio_decision'], session['duration'],
                    session['width'], session['height'], session['container'],
                    session['video_codec'], session['audio_codec'],
                    session['bitrate'], session['video_resolution'],
                    session['video_framerate'], session['aspect_ratio'],
                    session['audio_channels'], session['transcode_protocol'],
                    session['transcode_container'],
                    session['transcode_video_codec'],
                    session['transcode_audio_codec'],
                    session['transcode_audio_channels'],
                    session['transcode_width'], session['transcode_height']
                ]

                # logger.debug(u"PlexPy Monitor :: Writing session_history_media_info transaction...")
                self.db.action(query=query, args=args)

                if not is_import:
                    logger.debug(
                        u"PlexPy Monitor :: Fetching metadata for item ratingKey %s"
                        % session['rating_key'])
                    pms_connect = pmsconnect.PmsConnect()
                    result = pms_connect.get_metadata_details(
                        rating_key=str(session['rating_key']))
                    metadata = result['metadata']
                else:
                    metadata = import_metadata

                # Write the session_history_metadata table
                directors = ";".join(metadata['directors'])
                writers = ";".join(metadata['writers'])
                actors = ";".join(metadata['actors'])
                genres = ";".join(metadata['genres'])

                # Build media item title
                if session['media_type'] == 'episode' or session[
                        'media_type'] == 'track':
                    full_title = '%s - %s' % (metadata['grandparent_title'],
                                              metadata['title'])
                elif session['media_type'] == 'movie':
                    full_title = metadata['title']
                else:
                    full_title = metadata['title']

                # logger.debug(u"PlexPy Monitor :: Attempting to write to session_history_metadata table...")
                query = 'INSERT INTO session_history_metadata (id, rating_key, parent_rating_key, ' \
                        'grandparent_rating_key, title, parent_title, grandparent_title, full_title, media_index, ' \
                        'parent_media_index, thumb, parent_thumb, grandparent_thumb, art, media_type, year, ' \
                        'originally_available_at, added_at, updated_at, last_viewed_at, content_rating, summary, ' \
                        'rating, duration, guid, directors, writers, actors, genres, studio) VALUES ' \
                        '(last_insert_rowid(), ' \
                        '?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'

                args = [
                    session['rating_key'], session['parent_rating_key'],
                    session['grandparent_rating_key'], session['title'],
                    session['parent_title'], session['grandparent_title'],
                    full_title, metadata['index'], metadata['parent_index'],
                    metadata['thumb'], metadata['parent_thumb'],
                    metadata['grandparent_thumb'], metadata['art'],
                    session['media_type'], metadata['year'],
                    metadata['originally_available_at'], metadata['added_at'],
                    metadata['updated_at'], metadata['last_viewed_at'],
                    metadata['content_rating'], metadata['summary'],
                    metadata['rating'], metadata['duration'], metadata['guid'],
                    directors, writers, actors, genres, metadata['studio']
                ]

                # logger.debug(u"PlexPy Monitor :: Writing session_history_metadata transaction...")
                self.db.action(query=query, args=args)
示例#9
0
def notify(stream_data=None, notify_action=None):
    from plexpy import users

    if stream_data and notify_action:
        # Check if notifications enabled for user
        user_data = users.Users()
        user_details = user_data.get_user_friendly_name(
            user=stream_data['user'])

        if not user_details['do_notify']:
            return

        if (stream_data['media_type'] == 'movie' and plexpy.CONFIG.MOVIE_NOTIFY_ENABLE) \
            or (stream_data['media_type'] == 'episode' and plexpy.CONFIG.TV_NOTIFY_ENABLE):

            progress_percent = helpers.get_percent(stream_data['view_offset'],
                                                   stream_data['duration'])

            for agent in notifiers.available_notification_agents():
                if agent['on_play'] and notify_action == 'play':
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])
                    # Set the notification state in the db
                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

                elif agent['on_stop'] and notify_action == 'stop' \
                    and (plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < plexpy.CONFIG.NOTIFY_WATCHED_PERCENT):
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])

                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

                elif agent['on_pause'] and notify_action == 'pause' \
                    and (plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < 99):
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])

                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

                elif agent['on_resume'] and notify_action == 'resume' \
                    and (plexpy.CONFIG.NOTIFY_CONSECUTIVE or progress_percent < 99):
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])

                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

                elif agent['on_buffer'] and notify_action == 'buffer':
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])

                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

                elif agent['on_watched'] and notify_action == 'watched':
                    # Get the current states for notifications from our db
                    notify_states = get_notify_state(session=stream_data)

                    # If there is nothing in the notify_log for our agent id but it is enabled we should notify
                    if not any(d['agent_id'] == agent['id']
                               for d in notify_states):
                        # Build and send notification
                        notify_strings = build_notify_text(session=stream_data,
                                                           state=notify_action)
                        notifiers.send_notification(config_id=agent['id'],
                                                    subject=notify_strings[0],
                                                    body=notify_strings[1])
                        # Set the notification state in the db
                        set_notify_state(session=stream_data,
                                         state=notify_action,
                                         agent_info=agent)

                    else:
                        # Check in our notify log if the notification has already been sent
                        for notify_state in notify_states:
                            if not notify_state['on_watched'] and (
                                    notify_state['agent_id'] == agent['id']):
                                # Build and send notification
                                notify_strings = build_notify_text(
                                    session=stream_data, state=notify_action)
                                notifiers.send_notification(
                                    config_id=agent['id'],
                                    subject=notify_strings[0],
                                    body=notify_strings[1])
                                # Set the notification state in the db
                                set_notify_state(session=stream_data,
                                                 state=notify_action,
                                                 agent_info=agent)

        elif (stream_data['media_type'] == 'track'
              and plexpy.CONFIG.MUSIC_NOTIFY_ENABLE):

            for agent in notifiers.available_notification_agents():
                if agent['on_play'] and notify_action == 'play':
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])
                    # Set the notification state in the db
                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

                elif agent['on_stop'] and notify_action == 'stop':
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])
                    # Set the notification state in the db
                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

                elif agent['on_pause'] and notify_action == 'pause':
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])
                    # Set the notification state in the db
                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

                elif agent['on_resume'] and notify_action == 'resume':
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])
                    # Set the notification state in the db
                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

                elif agent['on_buffer'] and notify_action == 'buffer':
                    # Build and send notification
                    notify_strings = build_notify_text(session=stream_data,
                                                       state=notify_action)
                    notifiers.send_notification(config_id=agent['id'],
                                                subject=notify_strings[0],
                                                body=notify_strings[1])
                    # Set the notification state in the db
                    set_notify_state(session=stream_data,
                                     state=notify_action,
                                     agent_info=agent)

        elif stream_data['media_type'] == 'clip':
            pass
        else:
            #logger.debug(u"PlexPy Notifier :: Notify called with unsupported media type.")
            pass
    else:
        logger.debug(
            u"PlexPy Notifier :: Notify called but incomplete data received.")
示例#10
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,
                         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')