Example #1
0
def build_notify_text(session=None, timeline=None, state=None):
    import re

    # Get the server name
    server_name = plexpy.CONFIG.PMS_NAME

    # Get the server uptime
    plex_tv = plextv.PlexTV()
    server_times = plex_tv.get_server_times()

    if server_times:
        updated_at = server_times[0]['updated_at']
        server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_float(updated_at)))
    else:
        logger.error(u"PlexPy Notifier :: Unable to retrieve server uptime.")
        server_uptime = 'N/A'

    # Get metadata feed for item
    if session:
        rating_key = session['rating_key']
    elif timeline:
        rating_key = timeline['rating_key']

    pms_connect = pmsconnect.PmsConnect()
    metadata_list = pms_connect.get_metadata_details(rating_key=rating_key)

    if metadata_list:
        metadata = metadata_list['metadata']
    else:
        logger.error(u"PlexPy Notifier :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
        return []

    # Check for exclusion tags
    if metadata['media_type'] == 'movie':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<tv>[^>]+.</tv>|<music>[^>]+.</music>', re.IGNORECASE)
    elif metadata['media_type'] == 'show' or metadata['media_type'] == 'episode':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<movie>[^>]+.</movie>|<music>[^>]+.</music>', re.IGNORECASE)
    elif metadata['media_type'] == 'artist' or metadata['media_type'] == 'track':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', re.IGNORECASE)
    else:
        pattern = None

    if metadata['media_type'] == 'movie' \
        or metadata['media_type'] == 'show' or metadata['media_type'] == 'episode' \
        or metadata['media_type'] == 'artist' or metadata['media_type'] == 'track' \
        and pattern:
        # Remove the unwanted tags and strip any unmatch tags too.
        on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
        on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
        on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
        on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
        on_pause_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
        on_pause_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
        on_resume_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
        on_resume_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
        on_buffer_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
        on_buffer_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
        on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
        on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
        on_created_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT))
        on_created_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT))
    else:
        on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
        on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
        on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
        on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
        on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
        on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
        on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
        on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
        on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
        on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
        on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
        on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
        on_created_subject = plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT
        on_created_body = plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT

    # Create a title
    if metadata['media_type'] == 'episode' or metadata['media_type'] == 'track':
        full_title = '%s - %s' % (metadata['grandparent_title'],
                                  metadata['title'])
    else:
        full_title = metadata['title']

    duration = helpers.convert_milliseconds_to_minutes(metadata['duration'])

    # Default values
    video_decision = ''
    audio_decision = ''
    transcode_decision = ''
    stream_duration = 0
    view_offset = 0
    user = ''
    platform = ''
    player = ''
    ip_address = 'N/A'

    # Session values
    if session:
        # Generate a combined transcode decision value
        video_decision = session['video_decision'].title()
        audio_decision = session['audio_decision'].title()

        if session['video_decision'] == 'transcode' or session['audio_decision'] == 'transcode':
            transcode_decision = 'Transcode'
        elif session['video_decision'] == 'copy' or session['audio_decision'] == 'copy':
            transcode_decision = 'Direct Stream'
        else:
            transcode_decision = 'Direct Play'

        if state != 'play':
            if session['paused_counter']:
                stream_duration = int((time.time() - helpers.cast_to_float(session['started']) -
                                       helpers.cast_to_float(session['paused_counter'])) / 60)
            else:
                stream_duration = int((time.time() - helpers.cast_to_float(session['started'])) / 60)

        view_offset = helpers.convert_milliseconds_to_minutes(session['view_offset'])
        user = session['friendly_name']
        platform = session['platform']
        player = session['player']
        ip_address = session['ip_address'] if session['ip_address'] else 'N/A'

    progress_percent = helpers.get_percent(view_offset, duration)

    available_params = {'server_name': server_name,
                        'server_uptime': server_uptime,
                        'user': user,
                        'platform': platform,
                        'player': player,
                        'ip_address': ip_address,
                        'media_type': metadata['media_type'],
                        'title': full_title,
                        'show_name': metadata['grandparent_title'],
                        'episode_name': metadata['title'],
                        'artist_name': metadata['grandparent_title'],
                        'album_name': metadata['parent_title'],
                        'track_name': metadata['title'],
                        'season_num': metadata['parent_index'].zfill(1),
                        'season_num00': metadata['parent_index'].zfill(2),
                        'episode_num': metadata['index'].zfill(1),
                        'episode_num00': metadata['index'].zfill(2),
                        'video_decision': video_decision,
                        'audio_decision': audio_decision,
                        'transcode_decision': transcode_decision,
                        'year': metadata['year'],
                        'studio': metadata['studio'],
                        'content_rating': metadata['content_rating'],
                        'directors': ', '.join(metadata['directors']),
                        'writers': ', '.join(metadata['writers']),
                        'actors': ', '.join(metadata['actors']),
                        'genres': ', '.join(metadata['genres']),
                        'summary': metadata['summary'],
                        'tagline': metadata['tagline'],
                        'rating': metadata['rating'],
                        'duration': duration,
                        'stream_duration': stream_duration,
                        'remaining_duration': duration - view_offset,
                        'progress': view_offset,
                        'progress_percent': progress_percent
                        }

    # Default subject text
    subject_text = 'PlexPy (%s)' % server_name

    if state == 'play':
        # Default body text
        body_text = '%s (%s) is watching %s' % (session['friendly_name'],
                                                session['player'],
                                                full_title)

        if on_start_subject and on_start_body:
            try:
                subject_text = unicode(on_start_subject).format(**available_params)
            except LookupError, e:
                logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e)
            except:
Example #2
0
def build_notify_text(session=None, timeline=None, state=None):
    # Get the server name
    server_name = plexpy.CONFIG.PMS_NAME

    # Get the server uptime
    plex_tv = plextv.PlexTV()
    server_times = plex_tv.get_server_times()

    if server_times:
        updated_at = server_times[0]['updated_at']
        server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_float(updated_at)))
    else:
        logger.error(u"PlexPy NotificationHandler :: Unable to retrieve server uptime.")
        server_uptime = 'N/A'

    # Get metadata feed for item
    if session:
        rating_key = session['rating_key']
    elif timeline:
        rating_key = timeline['rating_key']

    pms_connect = pmsconnect.PmsConnect()
    metadata_list = pms_connect.get_metadata_details(rating_key=rating_key)

    stream_count = pms_connect.get_current_activity().get('stream_count', '')

    if metadata_list:
        metadata = metadata_list['metadata']
    else:
        logger.error(u"PlexPy NotificationHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
        return []

    # Check for exclusion tags
    if metadata['media_type'] == 'movie':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('\n*<tv>[^>]+.</tv>\n*|\n*<music>[^>]+.</music>\n*', re.IGNORECASE | re.DOTALL)
    elif metadata['media_type'] == 'show' or metadata['media_type'] == 'episode':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('\n*<movie>[^>]+.</movie>\n*|\n*?<music>[^>]+.</music>\n*', re.IGNORECASE | re.DOTALL)
    elif metadata['media_type'] == 'artist' or metadata['media_type'] == 'track':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('\n*<tv>[^>]+.</tv>\n*|\n*<movie>[^>]+.</movie>\n*', re.IGNORECASE | re.DOTALL)
    else:
        pattern = None

    if metadata['media_type'] == 'movie' \
        or metadata['media_type'] == 'show' or metadata['media_type'] == 'episode' \
        or metadata['media_type'] == 'artist' or metadata['media_type'] == 'track' \
        and pattern:
        # Remove the unwanted tags and strip any unmatch tags too.
        on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
        on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
        on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
        on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
        on_pause_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
        on_pause_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
        on_resume_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
        on_resume_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
        on_buffer_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
        on_buffer_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
        on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
        on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
        on_created_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT))
        on_created_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT))
        script_args_text = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT))
    else:
        on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
        on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
        on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
        on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
        on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
        on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
        on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
        on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
        on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
        on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
        on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
        on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
        on_created_subject = plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT
        on_created_body = plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT
        script_args_text = plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT

    # Create a title
    if metadata['media_type'] == 'episode' or metadata['media_type'] == 'track':
        full_title = '%s - %s' % (metadata['grandparent_title'],
                                  metadata['title'])
    else:
        full_title = metadata['title']

    duration = helpers.convert_milliseconds_to_minutes(metadata['duration'])

    # Default values
    user = ''
    platform = ''
    player = ''
    ip_address = 'N/A'
    stream_duration = 0
    view_offset = 0
    container = ''
    video_codec = ''
    video_bitrate = ''
    video_width = ''
    video_height = ''
    video_resolution = ''
    video_framerate = ''
    aspect_ratio = ''
    audio_codec = ''
    audio_channels = ''
    transcode_decision = ''
    video_decision = ''
    audio_decision = ''
    transcode_container = ''
    transcode_video_codec = ''
    transcode_video_width = ''
    transcode_video_height = ''
    transcode_audio_codec = ''
    transcode_audio_channels = ''

    # Session values
    if session:
        # Generate a combined transcode decision value
        video_decision = session['video_decision'].title()
        audio_decision = session['audio_decision'].title()

        if session['video_decision'] == 'transcode' or session['audio_decision'] == 'transcode':
            transcode_decision = 'Transcode'
        elif session['video_decision'] == 'copy' or session['audio_decision'] == 'copy':
            transcode_decision = 'Direct Stream'
        else:
            transcode_decision = 'Direct Play'

        if state != 'play':
            if session['paused_counter']:
                stream_duration = int((time.time() - helpers.cast_to_float(session['started']) -
                                       helpers.cast_to_float(session['paused_counter'])) / 60)
            else:
                stream_duration = int((time.time() - helpers.cast_to_float(session['started'])) / 60)

        view_offset = helpers.convert_milliseconds_to_minutes(session['view_offset'])
        user = session['friendly_name']
        platform = session['platform']
        player = session['player']
        ip_address = session['ip_address'] if session['ip_address'] else 'N/A'
        container = session['container']
        video_codec = session['video_codec']
        video_bitrate = session['bitrate']
        video_width = session['width']
        video_height = session['height']
        video_resolution = session['video_resolution']
        video_framerate = session['video_framerate']
        aspect_ratio = session['aspect_ratio']
        audio_codec = session['audio_codec']
        audio_channels = session['audio_channels']
        transcode_container = session['transcode_container']
        transcode_video_codec = session['transcode_video_codec']
        transcode_video_width = session['transcode_width']
        transcode_video_height = session['transcode_height']
        transcode_audio_codec = session['transcode_audio_codec']
        transcode_audio_channels = session['transcode_audio_channels']

    progress_percent = helpers.get_percent(view_offset, duration)

    # Fix metadata params for notify recently added grandparent
    if state == 'created' and plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT:
        show_name = metadata['title']
        episode_name = ''
        artist_name = metadata['title']
        album_name = ''
        track_name = ''
    else:
        show_name = metadata['grandparent_title']
        episode_name = metadata['title']
        artist_name = metadata['grandparent_title']
        album_name = metadata['parent_title']
        track_name = metadata['title']

    available_params = {'server_name': server_name,
                        'server_uptime': server_uptime,
                        'streams': stream_count,
                        'action': state,
                        'datestamp': arrow.now().format(plexpy.CONFIG.DATE_FORMAT.replace('Do','').replace('zz','')),
                        'timestamp': arrow.now().format(plexpy.CONFIG.TIME_FORMAT.replace('Do','').replace('zz','')),
                        'user': user,
                        'platform': platform,
                        'player': player,
                        'ip_address': ip_address,
                        'media_type': metadata['media_type'],
                        'stream_duration': stream_duration,
                        'remaining_duration': duration - view_offset,
                        'progress': view_offset,
                        'progress_percent': progress_percent,
                        'container': container,
                        'video_codec': video_codec,
                        'video_bitrate': video_bitrate,
                        'video_width': video_width,
                        'video_height': video_height,
                        'video_resolution': video_resolution,
                        'video_framerate': video_framerate,
                        'aspect_ratio': aspect_ratio,
                        'audio_codec': audio_codec,
                        'audio_channels': audio_channels,
                        'transcode_decision': transcode_decision,
                        'video_decision': video_decision,
                        'audio_decision': audio_decision,
                        'transcode_container': transcode_container,
                        'transcode_video_codec': transcode_video_codec,
                        'transcode_video_width': transcode_video_width,
                        'transcode_video_height': transcode_video_height,
                        'transcode_audio_codec': transcode_audio_codec,
                        'transcode_audio_channels': transcode_audio_channels,
                        'title': full_title,
                        'library_name': metadata['library_name'],
                        'show_name': show_name,
                        'episode_name': episode_name,
                        'artist_name': artist_name,
                        'album_name': album_name,
                        'track_name': track_name,
                        'season_num': metadata['parent_media_index'].zfill(1),
                        'season_num00': metadata['parent_media_index'].zfill(2),
                        'episode_num': metadata['media_index'].zfill(1),
                        'episode_num00': metadata['media_index'].zfill(2),
                        'year': metadata['year'],
                        'studio': metadata['studio'],
                        'content_rating': metadata['content_rating'],
                        'directors': ', '.join(metadata['directors']),
                        'writers': ', '.join(metadata['writers']),
                        'actors': ', '.join(metadata['actors']),
                        'genres': ', '.join(metadata['genres']),
                        'summary': metadata['summary'],
                        'tagline': metadata['tagline'],
                        'rating': metadata['rating'],
                        'duration': duration
                        }

    # Default subject text
    subject_text = 'PlexPy (%s)' % server_name

    # Default scripts args
    script_args = []

    # Regex to match {param} but not "{param}"
    params_to_quote = re.compile(r'(?<!\")([\{][^}]+[\}])(?!\"\})')
    script_args_text = re.sub(params_to_quote, r'"\g<0>"', script_args_text)

    if script_args_text:
        try:
            script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
        except LookupError as e:
            logger.error(u"PlexPy Notifier :: Unable to parse field %s in script argument. Using fallback." % e)
        except Exception as e:
            logger.error(u"PlexPy Notifier :: Unable to parse custom script arguments %s. Using fallback." % e)

    if state == 'play':
        # Default body text
        body_text = '%s (%s) is watching %s' % (session['friendly_name'],
                                                session['player'],
                                                full_title)

        if on_start_subject and on_start_body:
            try:
                subject_text = unicode(on_start_subject).format(**available_params)
            except LookupError, e:
                logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in notification subject. Using fallback." % e)
            except:
Example #3
0
def build_notify_text(session=None, timeline=None, state=None):
    import re

    # Get the server name
    server_name = plexpy.CONFIG.PMS_NAME

    # Get the server uptime
    plex_tv = plextv.PlexTV()
    server_times = plex_tv.get_server_times()

    if server_times:
        updated_at = server_times[0]['updated_at']
        server_uptime = helpers.human_duration(
            int(time.time() - helpers.cast_to_float(updated_at)))
    else:
        logger.error(u"PlexPy Notifier :: Unable to retrieve server uptime.")
        server_uptime = 'N/A'

    # Get metadata feed for item
    if session:
        rating_key = session['rating_key']
    elif timeline:
        rating_key = timeline['rating_key']

    pms_connect = pmsconnect.PmsConnect()
    metadata_list = pms_connect.get_metadata_details(rating_key=rating_key)

    if metadata_list:
        metadata = metadata_list['metadata']
    else:
        logger.error(
            u"PlexPy Notifier :: Unable to retrieve metadata for rating_key %s"
            % str(rating_key))
        return []

    # Check for exclusion tags
    if metadata['media_type'] == 'movie':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<tv>[^>]+.</tv>|<music>[^>]+.</music>',
                             re.IGNORECASE)
    elif metadata['media_type'] == 'show' or metadata[
            'media_type'] == 'episode':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<movie>[^>]+.</movie>|<music>[^>]+.</music>',
                             re.IGNORECASE)
    elif metadata['media_type'] == 'artist' or metadata[
            'media_type'] == 'track':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>',
                             re.IGNORECASE)
    else:
        pattern = None

    if metadata['media_type'] == 'movie' \
        or metadata['media_type'] == 'show' or metadata['media_type'] == 'episode' \
        or metadata['media_type'] == 'artist' or metadata['media_type'] == 'track' \
        and pattern:
        # Remove the unwanted tags and strip any unmatch tags too.
        on_start_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
        on_start_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
        on_stop_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
        on_stop_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
        on_pause_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
        on_pause_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
        on_resume_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
        on_resume_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
        on_buffer_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
        on_buffer_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
        on_watched_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
        on_watched_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
        on_created_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT))
        on_created_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT))
    else:
        on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
        on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
        on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
        on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
        on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
        on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
        on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
        on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
        on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
        on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
        on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
        on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
        on_created_subject = plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT
        on_created_body = plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT

    # Create a title
    if metadata['media_type'] == 'episode' or metadata['media_type'] == 'track':
        full_title = '%s - %s' % (metadata['grandparent_title'],
                                  metadata['title'])
    else:
        full_title = metadata['title']

    duration = helpers.convert_milliseconds_to_minutes(metadata['duration'])

    # Default values
    video_decision = ''
    audio_decision = ''
    transcode_decision = ''
    stream_duration = 0
    view_offset = 0
    user = ''
    platform = ''
    player = ''
    ip_address = 'N/A'

    # Session values
    if session:
        # Generate a combined transcode decision value
        video_decision = session['video_decision'].title()
        audio_decision = session['audio_decision'].title()

        if session['video_decision'] == 'transcode' or session[
                'audio_decision'] == 'transcode':
            transcode_decision = 'Transcode'
        elif session['video_decision'] == 'copy' or session[
                'audio_decision'] == 'copy':
            transcode_decision = 'Direct Stream'
        else:
            transcode_decision = 'Direct Play'

        if state != 'play':
            if session['paused_counter']:
                stream_duration = int(
                    (time.time() - helpers.cast_to_float(session['started']) -
                     helpers.cast_to_float(session['paused_counter'])) / 60)
            else:
                stream_duration = int(
                    (time.time() - helpers.cast_to_float(session['started'])) /
                    60)

        view_offset = helpers.convert_milliseconds_to_minutes(
            session['view_offset'])
        user = session['friendly_name']
        platform = session['platform']
        player = session['player']
        ip_address = session['ip_address'] if session['ip_address'] else 'N/A'

    progress_percent = helpers.get_percent(view_offset, duration)

    available_params = {
        'server_name': server_name,
        'server_uptime': server_uptime,
        'user': user,
        'platform': platform,
        'player': player,
        'ip_address': ip_address,
        'media_type': metadata['media_type'],
        'title': full_title,
        'show_name': metadata['grandparent_title'],
        'episode_name': metadata['title'],
        'artist_name': metadata['grandparent_title'],
        'album_name': metadata['parent_title'],
        'track_name': metadata['title'],
        'season_num': metadata['parent_index'].zfill(1),
        'season_num00': metadata['parent_index'].zfill(2),
        'episode_num': metadata['index'].zfill(1),
        'episode_num00': metadata['index'].zfill(2),
        'video_decision': video_decision,
        'audio_decision': audio_decision,
        'transcode_decision': transcode_decision,
        'year': metadata['year'],
        'studio': metadata['studio'],
        'content_rating': metadata['content_rating'],
        'directors': ', '.join(metadata['directors']),
        'writers': ', '.join(metadata['writers']),
        'actors': ', '.join(metadata['actors']),
        'genres': ', '.join(metadata['genres']),
        'summary': metadata['summary'],
        'tagline': metadata['tagline'],
        'rating': metadata['rating'],
        'duration': duration,
        'stream_duration': stream_duration,
        'remaining_duration': duration - view_offset,
        'progress': view_offset,
        'progress_percent': progress_percent
    }

    # Default subject text
    subject_text = 'PlexPy (%s)' % server_name

    if state == 'play':
        # Default body text
        body_text = '%s (%s) is watching %s' % (session['friendly_name'],
                                                session['player'], full_title)

        if on_start_subject and on_start_body:
            try:
                subject_text = unicode(on_start_subject).format(
                    **available_params)
            except LookupError, e:
                logger.error(
                    u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback."
                    % e)
            except:
Example #4
0
def build_notify_text(session, state):
    from plexpy import pmsconnect, helpers
    import re

    # Get the server name
    pms_connect = pmsconnect.PmsConnect()
    server_name = pms_connect.get_server_pref(pref="FriendlyName")

    # Get metadata feed for item
    metadata = pms_connect.get_metadata_details(rating_key=session["rating_key"])

    if metadata:
        item_metadata = metadata["metadata"]
    else:
        logger.error(u"PlexPy Notifier :: Unable to retrieve metadata for rating_key %s" % str(session["rating_key"]))
        return []

    # Check for exclusion tags
    if session["media_type"] == "episode":
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile("<movie>[^>]+.</movie>|<music>[^>]+.</music>", re.IGNORECASE)
    elif session["media_type"] == "movie":
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile("<tv>[^>]+.</tv>|<music>[^>]+.</music>", re.IGNORECASE)
    elif session["media_type"] == "track":
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile("<tv>[^>]+.</tv>|<movie>[^>]+.</movie>", re.IGNORECASE)
    else:
        pattern = None

    if (
        session["media_type"] == "episode"
        or session["media_type"] == "movie"
        or session["media_type"] == "track"
        and pattern
    ):
        # Remove the unwanted tags and strip any unmatch tags too.
        on_start_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
        on_start_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
        on_stop_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
        on_stop_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
        on_pause_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
        on_pause_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
        on_resume_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
        on_resume_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
        on_buffer_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
        on_buffer_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
        on_watched_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
        on_watched_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
    else:
        on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
        on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
        on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
        on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
        on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
        on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
        on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
        on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
        on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
        on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
        on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
        on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT

    # Create a title
    if session["media_type"] == "episode":
        full_title = "%s - %s" % (session["grandparent_title"], session["title"])
    elif session["media_type"] == "track":
        full_title = "%s - %s" % (session["grandparent_title"], session["title"])
    else:
        full_title = session["title"]

    # Generate a combined transcode decision value
    if session["video_decision"]:
        if session["video_decision"] == "transcode":
            transcode_decision = "Transcode"
        elif session["video_decision"] == "copy" or session["audio_decision"] == "copy":
            transcode_decision = "Direct Stream"
        else:
            transcode_decision = "Direct Play"
    else:
        if session["audio_decision"] == "transcode":
            transcode_decision = "Transcode"
        else:
            transcode_decision = "Direct Play"

    duration = helpers.convert_milliseconds_to_minutes(item_metadata["duration"])
    view_offset = helpers.convert_milliseconds_to_minutes(session["view_offset"])
    stream_duration = 0
    if state != "play":
        if session["paused_counter"]:
            stream_duration = int(
                (
                    time.time()
                    - helpers.cast_to_float(session["started"])
                    - helpers.cast_to_float(session["paused_counter"])
                )
                / 60
            )
        else:
            stream_duration = int((time.time() - helpers.cast_to_float(session["started"])) / 60)

    progress_percent = helpers.get_percent(view_offset, duration)

    available_params = {
        "server_name": server_name,
        "user": session["friendly_name"],
        "platform": session["platform"],
        "player": session["player"],
        "media_type": session["media_type"],
        "title": full_title,
        "show_name": item_metadata["grandparent_title"],
        "episode_name": item_metadata["title"],
        "artist_name": item_metadata["grandparent_title"],
        "album_name": item_metadata["parent_title"],
        "season_num": item_metadata["parent_index"],
        "season_num00": item_metadata["parent_index"].zfill(2),
        "episode_num": item_metadata["index"],
        "episode_num00": item_metadata["index"].zfill(2),
        "transcode_decision": transcode_decision,
        "year": item_metadata["year"],
        "studio": item_metadata["studio"],
        "content_rating": item_metadata["content_rating"],
        "summary": item_metadata["summary"],
        "rating": item_metadata["rating"],
        "duration": duration,
        "stream_duration": stream_duration,
        "remaining_duration": duration - view_offset,
        "progress": view_offset,
        "progress_percent": progress_percent,
    }

    # Default subject text
    subject_text = "PlexPy (%s)" % server_name

    if state == "play":
        # Default body text
        body_text = "%s (%s) is watching %s" % (session["friendly_name"], session["player"], full_title)

        if on_start_subject and on_start_body:
            try:
                subject_text = unicode(on_start_subject).format(**available_params)
            except LookupError, e:
                logger.error(
                    u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e
                )
            except:
def build_notify_text(session, state):
    from plexpy import pmsconnect, helpers
    import re

    # Get the server name
    pms_connect = pmsconnect.PmsConnect()
    server_name = pms_connect.get_server_pref(pref='FriendlyName')

    # Get metadata feed for item
    metadata = pms_connect.get_metadata_details(rating_key=session['rating_key'])

    if metadata:
        item_metadata = metadata['metadata']
    else:
        logger.error(u"PlexPy Notifier :: Unable to retrieve metadata for rating_key %s" % str(session['rating_key']))
        return []

    # Check for exclusion tags
    if session['media_type'] == 'episode':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<movie>[^>]+.</movie>|<music>[^>]+.</music>', re.IGNORECASE)
    elif session['media_type'] == 'movie':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<tv>[^>]+.</tv>|<music>[^>]+.</music>', re.IGNORECASE)
    elif session['media_type'] == 'track':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', re.IGNORECASE)
    else:
        pattern = None

    if session['media_type'] == 'episode' or session['media_type'] == 'movie' or session['media_type'] == 'track' \
            and pattern:
        # Remove the unwanted tags and strip any unmatch tags too.
        on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
        on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
        on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
        on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
        on_pause_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
        on_pause_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
        on_resume_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
        on_resume_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
        on_buffer_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
        on_buffer_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
        on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
        on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
    else:
        on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
        on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
        on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
        on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
        on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
        on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
        on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
        on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
        on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
        on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
        on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
        on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT

    # Create a title
    if session['media_type'] == 'episode':
        full_title = '%s - %s' % (session['grandparent_title'],
                                  session['title'])
    elif session['media_type'] == 'track':
        full_title = '%s - %s' % (session['grandparent_title'],
                                  session['title'])
    else:
        full_title = session['title']

    # Generate a combined transcode decision value
    if session['video_decision']:
        if session['video_decision'] == 'transcode':
            transcode_decision = 'Transcode'
        elif session['video_decision'] == 'copy' or session['audio_decision'] == 'copy':
            transcode_decision = 'Direct Stream'
        else:
            transcode_decision = 'Direct Play'
    else:
        if session['audio_decision'] == 'transcode':
            transcode_decision = 'Transcode'
        else:
            transcode_decision = 'Direct Play'

    duration = helpers.convert_milliseconds_to_minutes(item_metadata['duration'])
    view_offset = helpers.convert_milliseconds_to_minutes(session['view_offset'])
    stream_duration = 0
    if state != 'play':
        if session['paused_counter']:
            stream_duration = int((time.time() - helpers.cast_to_float(session['started']) -
                                   helpers.cast_to_float(session['paused_counter'])) / 60)
        else:
            stream_duration = int((time.time() - helpers.cast_to_float(session['started'])) / 60)

    progress_percent = helpers.get_percent(view_offset, duration)

    available_params = {'server_name': server_name,
                        'user': session['friendly_name'],
                        'player': session['player'],
                        'title': full_title,
                        'show_name': item_metadata['grandparent_title'],
                        'episode_name': item_metadata['title'],
                        'platform': session['platform'],
                        'media_type': session['media_type'],
                        'transcode_decision': transcode_decision,
                        'year': item_metadata['year'],
                        'studio': item_metadata['studio'],
                        'content_rating': item_metadata['content_rating'],
                        'summary': item_metadata['summary'],
                        'season_num': item_metadata['parent_index'],
                        'season_num00': item_metadata['parent_index'].zfill(2),
                        'episode_num': item_metadata['index'],
                        'episode_num00': item_metadata['index'].zfill(2),
                        'album_name': item_metadata['parent_title'],
                        'rating': item_metadata['rating'],
                        'duration': duration,
                        'stream_duration': stream_duration,
                        'progress': view_offset,
                        'progress_percent': progress_percent
                        }

    # Default subject text
    subject_text = 'PlexPy (%s)' % server_name

    if state == 'play':
        # Default body text
        body_text = '%s (%s) is watching %s' % (session['friendly_name'],
                                                session['player'],
                                                full_title)

        if on_start_subject and on_start_body:
            try:
                subject_text = unicode(on_start_subject).format(**available_params)
            except LookupError, e:
                logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e)
            except:
Example #6
0
def build_notify_text(session, state):
    from plexpy import pmsconnect, helpers
    import re

    # Get the server name
    pms_connect = pmsconnect.PmsConnect()
    server_name = pms_connect.get_server_pref(pref='FriendlyName')

    # Get metadata feed for item
    metadata = pms_connect.get_metadata_details(
        rating_key=session['rating_key'])

    if metadata:
        item_metadata = metadata['metadata']
    else:
        logger.error(
            u"PlexPy Notifier :: Unable to retrieve metadata for rating_key %s"
            % str(session['rating_key']))
        return []

    # Check for exclusion tags
    if session['media_type'] == 'episode':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<movie>[^>]+.</movie>|<music>[^>]+.</music>',
                             re.IGNORECASE)
    elif session['media_type'] == 'movie':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<tv>[^>]+.</tv>|<music>[^>]+.</music>',
                             re.IGNORECASE)
    elif session['media_type'] == 'track':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>',
                             re.IGNORECASE)
    else:
        pattern = None

    if session['media_type'] == 'episode' or session['media_type'] == 'movie' or session['media_type'] == 'track' \
            and pattern:
        # Remove the unwanted tags and strip any unmatch tags too.
        on_start_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
        on_start_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
        on_stop_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
        on_stop_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
        on_pause_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
        on_pause_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
        on_resume_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
        on_resume_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
        on_buffer_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
        on_buffer_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
        on_watched_subject = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
        on_watched_body = strip_tag(
            re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
    else:
        on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
        on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
        on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
        on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
        on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
        on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
        on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
        on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
        on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
        on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
        on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
        on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT

    # Create a title
    if session['media_type'] == 'episode':
        full_title = '%s - %s' % (session['grandparent_title'],
                                  session['title'])
    elif session['media_type'] == 'track':
        full_title = '%s - %s' % (session['grandparent_title'],
                                  session['title'])
    else:
        full_title = session['title']

    # Generate a combined transcode decision value
    if session['video_decision']:
        if session['video_decision'] == 'transcode':
            transcode_decision = 'Transcode'
        elif session['video_decision'] == 'copy' or session[
                'audio_decision'] == 'copy':
            transcode_decision = 'Direct Stream'
        else:
            transcode_decision = 'Direct Play'
    else:
        if session['audio_decision'] == 'transcode':
            transcode_decision = 'Transcode'
        else:
            transcode_decision = 'Direct Play'

    duration = helpers.convert_milliseconds_to_minutes(
        item_metadata['duration'])
    view_offset = helpers.convert_milliseconds_to_minutes(
        session['view_offset'])
    stream_duration = 0
    if state != 'play':
        if session['paused_counter']:
            stream_duration = int(
                (time.time() - helpers.cast_to_float(session['started']) -
                 helpers.cast_to_float(session['paused_counter'])) / 60)
        else:
            stream_duration = int(
                (time.time() - helpers.cast_to_float(session['started'])) / 60)

    progress_percent = helpers.get_percent(view_offset, duration)

    available_params = {
        'server_name': server_name,
        'user': session['friendly_name'],
        'platform': session['platform'],
        'player': session['player'],
        'media_type': session['media_type'],
        'title': full_title,
        'show_name': item_metadata['grandparent_title'],
        'episode_name': item_metadata['title'],
        'artist_name': item_metadata['grandparent_title'],
        'album_name': item_metadata['parent_title'],
        'season_num': item_metadata['parent_index'],
        'season_num00': item_metadata['parent_index'].zfill(2),
        'episode_num': item_metadata['index'],
        'episode_num00': item_metadata['index'].zfill(2),
        'transcode_decision': transcode_decision,
        'year': item_metadata['year'],
        'studio': item_metadata['studio'],
        'content_rating': item_metadata['content_rating'],
        'summary': item_metadata['summary'],
        'rating': item_metadata['rating'],
        'duration': duration,
        'stream_duration': stream_duration,
        'remaining_duration': duration - view_offset,
        'progress': view_offset,
        'progress_percent': progress_percent
    }

    # Default subject text
    subject_text = 'PlexPy (%s)' % server_name

    if state == 'play':
        # Default body text
        body_text = '%s (%s) is watching %s' % (session['friendly_name'],
                                                session['player'], full_title)

        if on_start_subject and on_start_body:
            try:
                subject_text = unicode(on_start_subject).format(
                    **available_params)
            except LookupError, e:
                logger.error(
                    u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback."
                    % e)
            except:
Example #7
0
    def get_metadata_details(self, rating_key=''):
        metadata = self.get_metadata(rating_key, output_format='xml')
        metadata_list = []

        xml_head = metadata.getElementsByTagName('MediaContainer')
        if not xml_head:
            logger.warn("Error parsing XML for Plex metadata.")
            return None

        for a in xml_head:
            if a.getAttribute('size'):
                if a.getAttribute('size') != '1':
                    metadata_list = {'metadata': None}
                    return metadata_list

            if a.getElementsByTagName('Directory'):
                metadata_main = a.getElementsByTagName('Directory')[0]
                metadata_type = helpers.get_xml_attr(metadata_main, 'type')
            elif a.getElementsByTagName('Video'):
                metadata_main = a.getElementsByTagName('Video')[0]
                metadata_type = helpers.get_xml_attr(metadata_main, 'type')
            else:
                logger.debug(u"Metadata failed")

        genres = []
        actors = []
        writers = []
        directors = []

        if metadata_main.getElementsByTagName('Genre'):
            for genre in metadata_main.getElementsByTagName('Genre'):
                genres.append(helpers.get_xml_attr(genre, 'tag'))

        if metadata_main.getElementsByTagName('Role'):
            for actor in metadata_main.getElementsByTagName('Role'):
                actors.append(helpers.get_xml_attr(actor, 'tag'))

        if metadata_main.getElementsByTagName('Writer'):
            for writer in metadata_main.getElementsByTagName('Writer'):
                writers.append(helpers.get_xml_attr(writer, 'tag'))

        if metadata_main.getElementsByTagName('Director'):
            for director in metadata_main.getElementsByTagName('Director'):
                directors.append(helpers.get_xml_attr(director, 'tag'))

        if metadata_type == 'show':
            metadata = {'type': metadata_type,
                        'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
                        'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
                        'parent_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
                        'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
                        'index': helpers.get_xml_attr(metadata_main, 'index'),
                        'studio': helpers.get_xml_attr(metadata_main, 'studio'),
                        'title': helpers.get_xml_attr(metadata_main, 'title'),
                        'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
                        'summary': helpers.get_xml_attr(metadata_main, 'summary'),
                        'rating': helpers.get_xml_attr(metadata_main, 'rating'),
                        'duration': helpers.convert_milliseconds_to_minutes(helpers.get_xml_attr(metadata_main, 'duration')),
                        'year': helpers.get_xml_attr(metadata_main, 'year'),
                        'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
                        'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
                        'art': helpers.get_xml_attr(metadata_main, 'art'),
                        'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
                        'writers': writers,
                        'directors': directors,
                        'genres': genres,
                        'actors': actors
                        }
            metadata_list = {'metadata': metadata}
        elif metadata_type == 'episode':
            metadata = {'type': metadata_type,
                        'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
                        'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
                        'parent_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
                        'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
                        'index': helpers.get_xml_attr(metadata_main, 'index'),
                        'studio': helpers.get_xml_attr(metadata_main, 'studio'),
                        'title': helpers.get_xml_attr(metadata_main, 'title'),
                        'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
                        'summary': helpers.get_xml_attr(metadata_main, 'summary'),
                        'rating': helpers.get_xml_attr(metadata_main, 'rating'),
                        'duration': helpers.convert_milliseconds_to_minutes(helpers.get_xml_attr(metadata_main, 'duration')),
                        'year': helpers.get_xml_attr(metadata_main, 'year'),
                        'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
                        'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
                        'art': helpers.get_xml_attr(metadata_main, 'art'),
                        'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
                        'writers': writers,
                        'directors': directors,
                        'genres': genres,
                        'actors': actors
                        }
            metadata_list = {'metadata': metadata}
        elif metadata_type == 'movie':
            metadata = {'type': metadata_type,
                        'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
                        'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
                        'parent_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
                        'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
                        'index': helpers.get_xml_attr(metadata_main, 'index'),
                        'studio': helpers.get_xml_attr(metadata_main, 'studio'),
                        'title': helpers.get_xml_attr(metadata_main, 'title'),
                        'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
                        'summary': helpers.get_xml_attr(metadata_main, 'summary'),
                        'rating': helpers.get_xml_attr(metadata_main, 'rating'),
                        'duration': helpers.convert_milliseconds_to_minutes(helpers.get_xml_attr(metadata_main, 'duration')),
                        'year': helpers.get_xml_attr(metadata_main, 'year'),
                        'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
                        'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
                        'art': helpers.get_xml_attr(metadata_main, 'art'),
                        'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
                        'genres': genres,
                        'actors': actors,
                        'writers': writers,
                        'directors': directors
                        }
            metadata_list = {'metadata': metadata}
        elif metadata_type == 'season':
            parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
            show_details = self.get_metadata_details(parent_rating_key)
            metadata = {'type': metadata_type,
                        'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
                        'grandparent_title': helpers.get_xml_attr(metadata_main, 'grandparentTitle'),
                        'parent_index': helpers.get_xml_attr(metadata_main, 'parentIndex'),
                        'parent_title': helpers.get_xml_attr(metadata_main, 'parentTitle'),
                        'index': helpers.get_xml_attr(metadata_main, 'index'),
                        'studio': helpers.get_xml_attr(metadata_main, 'studio'),
                        'title': helpers.get_xml_attr(metadata_main, 'title'),
                        'content_rating': helpers.get_xml_attr(metadata_main, 'contentRating'),
                        'summary': show_details['metadata']['summary'],
                        'rating': helpers.get_xml_attr(metadata_main, 'rating'),
                        'duration': show_details['metadata']['duration'],
                        'year': helpers.get_xml_attr(metadata_main, 'year'),
                        'thumb': helpers.get_xml_attr(metadata_main, 'thumb'),
                        'parent_thumb': helpers.get_xml_attr(metadata_main, 'parentThumb'),
                        'art': helpers.get_xml_attr(metadata_main, 'art'),
                        'originally_available_at': helpers.get_xml_attr(metadata_main, 'originallyAvailableAt'),
                        'genres': genres,
                        'actors': actors,
                        'writers': writers,
                        'directors': directors
                        }
            metadata_list = {'metadata': metadata}
        else:
            return None

        return metadata_list
Example #8
0
            for writer in metadata_main.getElementsByTagName('Writer'):
                writers.append(self.get_xml_attr(writer, 'tag'))

        if metadata_main.getElementsByTagName('Director'):
            for director in metadata_main.getElementsByTagName('Director'):
                directors.append(self.get_xml_attr(director, 'tag'))

        if metadata_type == 'show':
            metadata = {'type': metadata_type,
                        'ratingKey': self.get_xml_attr(metadata_main, 'ratingKey'),
                        'studio': self.get_xml_attr(metadata_main, 'studio'),
                        'title': self.get_xml_attr(metadata_main, 'title'),
                        'contentRating': self.get_xml_attr(metadata_main, 'contentRating'),
                        'summary': self.get_xml_attr(metadata_main, 'summary'),
                        'rating': self.get_xml_attr(metadata_main, 'rating'),
                        'duration': helpers.convert_milliseconds_to_minutes(self.get_xml_attr(metadata_main, 'duration')),
                        'year': self.get_xml_attr(metadata_main, 'year'),
                        'thumb': self.get_xml_attr(metadata_main, 'thumb'),
                        'art': self.get_xml_attr(metadata_main, 'art'),
                        'originallyAvailableAt': self.get_xml_attr(metadata_main, 'originallyAvailableAt'),
                        'writers': writers,
                        'directors': directors,
                        'genres': genres,
                        'actors': actors
                        }
            metadata_list = {'metadata': metadata}
        elif metadata_type == 'episode':
            metadata = {'type': metadata_type,
                        'ratingKey': self.get_xml_attr(metadata_main, 'ratingKey'),
                        'grandparentTitle': self.get_xml_attr(metadata_main, 'grandparentTitle'),
                        'parentIndex': self.get_xml_attr(metadata_main, 'parentIndex'),
def build_notify_text(session=None, timeline=None, state=None):
    # Get time formats
    date_format = plexpy.CONFIG.DATE_FORMAT.replace("Do", "").replace("zz", "")
    time_format = plexpy.CONFIG.TIME_FORMAT.replace("Do", "").replace("zz", "")
    duration_format = plexpy.CONFIG.TIME_FORMAT.replace("Do", "").replace("zz", "").replace("a", "").replace("A", "")

    # Get the server name
    server_name = plexpy.CONFIG.PMS_NAME

    # Get the server uptime
    plex_tv = plextv.PlexTV()
    server_times = plex_tv.get_server_times()

    if server_times:
        updated_at = server_times[0]["updated_at"]
        server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_float(updated_at)))
    else:
        logger.error(u"PlexPy NotificationHandler :: Unable to retrieve server uptime.")
        server_uptime = "N/A"

    # Get metadata feed for item
    if session:
        rating_key = session["rating_key"]
    elif timeline:
        rating_key = timeline["rating_key"]

    pms_connect = pmsconnect.PmsConnect()
    metadata_list = pms_connect.get_metadata_details(rating_key=rating_key)

    stream_count = pms_connect.get_current_activity().get("stream_count", "")

    if metadata_list:
        metadata = metadata_list["metadata"]
    else:
        logger.error(u"PlexPy NotificationHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
        return []

    # Check for exclusion tags
    if metadata["media_type"] == "movie":
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile("\n*<tv>[^>]+.</tv>\n*|\n*<music>[^>]+.</music>\n*", re.IGNORECASE | re.DOTALL)
    elif metadata["media_type"] == "show" or metadata["media_type"] == "episode":
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile("\n*<movie>[^>]+.</movie>\n*|\n*?<music>[^>]+.</music>\n*", re.IGNORECASE | re.DOTALL)
    elif metadata["media_type"] == "artist" or metadata["media_type"] == "track":
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile("\n*<tv>[^>]+.</tv>\n*|\n*<movie>[^>]+.</movie>\n*", re.IGNORECASE | re.DOTALL)
    else:
        pattern = None

    if (
        metadata["media_type"] == "movie"
        or metadata["media_type"] == "show"
        or metadata["media_type"] == "episode"
        or metadata["media_type"] == "artist"
        or metadata["media_type"] == "track"
        and pattern
    ):
        # Remove the unwanted tags and strip any unmatch tags too.
        on_start_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
        on_start_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
        on_stop_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
        on_stop_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
        on_pause_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
        on_pause_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
        on_resume_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
        on_resume_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
        on_buffer_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
        on_buffer_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
        on_watched_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
        on_watched_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
        on_created_subject = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT))
        on_created_body = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT))
        script_args_text = strip_tag(re.sub(pattern, "", plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT))
    else:
        on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
        on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
        on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
        on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
        on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
        on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
        on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
        on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
        on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
        on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
        on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
        on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
        on_created_subject = plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT
        on_created_body = plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT
        script_args_text = plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT

    # Create a title
    if metadata["media_type"] == "episode" or metadata["media_type"] == "track":
        full_title = "%s - %s" % (metadata["grandparent_title"], metadata["title"])
    else:
        full_title = metadata["title"]

    # Session values
    if session is None:
        session = {}

    # Generate a combined transcode decision value
    if session.get("video_decision", "") == "transcode" or session.get("audio_decision", "") == "transcode":
        transcode_decision = "Transcode"
    elif session.get("video_decision", "") == "copy" or session.get("audio_decision", "") == "copy":
        transcode_decision = "Direct Stream"
    else:
        transcode_decision = "Direct Play"

    if state != "play":
        stream_duration = helpers.convert_seconds_to_minutes(
            time.time()
            - helpers.cast_to_float(session.get("started", 0))
            - helpers.cast_to_float(session.get("paused_counter", 0))
        )
    else:
        stream_duration = 0

    view_offset = helpers.convert_milliseconds_to_minutes(session.get("view_offset", 0))
    duration = helpers.convert_milliseconds_to_minutes(metadata["duration"])
    progress_percent = helpers.get_percent(view_offset, duration)
    remaining_duration = duration - view_offset

    # Fix metadata params for notify recently added grandparent
    if state == "created" and plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT:
        show_name = metadata["title"]
        episode_name = ""
        artist_name = metadata["title"]
        album_name = ""
        track_name = ""
    else:
        show_name = metadata["grandparent_title"]
        episode_name = metadata["title"]
        artist_name = metadata["grandparent_title"]
        album_name = metadata["parent_title"]
        track_name = metadata["title"]

    available_params = {  # Global paramaters
        "server_name": server_name,
        "server_uptime": server_uptime,
        "action": state.title(),
        "datestamp": arrow.now().format(date_format),
        "timestamp": arrow.now().format(time_format),
        # Stream parameters
        "streams": stream_count,
        "user": session.get("friendly_name", ""),
        "platform": session.get("platform", ""),
        "player": session.get("player", ""),
        "ip_address": session.get("ip_address", "N/A"),
        "stream_duration": stream_duration,
        "stream_time": arrow.get(stream_duration * 60).format(duration_format),
        "remaining_duration": remaining_duration,
        "remaining_time": arrow.get(remaining_duration * 60).format(duration_format),
        "progress_duration": view_offset,
        "progress_time": arrow.get(view_offset * 60).format(duration_format),
        "progress_percent": progress_percent,
        "container": session.get("container", ""),
        "video_codec": session.get("video_codec", ""),
        "video_bitrate": session.get("bitrate", ""),
        "video_width": session.get("width", ""),
        "video_height": session.get("height", ""),
        "video_resolution": session.get("video_resolution", ""),
        "video_framerate": session.get("video_framerate", ""),
        "aspect_ratio": session.get("aspect_ratio", ""),
        "audio_codec": session.get("audio_codec", ""),
        "audio_channels": session.get("audio_channels", ""),
        "transcode_decision": transcode_decision,
        "video_decision": session.get("video_decision", "").title(),
        "audio_decision": session.get("audio_decision", "").title(),
        "transcode_container": session.get("transcode_container", ""),
        "transcode_video_codec": session.get("transcode_video_codec", ""),
        "transcode_video_width": session.get("transcode_width", ""),
        "transcode_video_height": session.get("transcode_height", ""),
        "transcode_audio_codec": session.get("transcode_audio_codec", ""),
        "transcode_audio_channels": session.get("transcode_audio_channels", ""),
        "session_key": session.get("session_key", ""),
        "user_id": session.get("user_id", ""),
        # Metadata parameters
        "media_type": metadata["media_type"],
        "title": full_title,
        "library_name": metadata["library_name"],
        "show_name": show_name,
        "episode_name": episode_name,
        "artist_name": artist_name,
        "album_name": album_name,
        "track_name": track_name,
        "season_num": metadata["parent_media_index"].zfill(1),
        "season_num00": metadata["parent_media_index"].zfill(2),
        "episode_num": metadata["media_index"].zfill(1),
        "episode_num00": metadata["media_index"].zfill(2),
        "track_num": metadata["media_index"].zfill(1),
        "track_num00": metadata["media_index"].zfill(2),
        "year": metadata["year"],
        "studio": metadata["studio"],
        "content_rating": metadata["content_rating"],
        "directors": ", ".join(metadata["directors"]),
        "writers": ", ".join(metadata["writers"]),
        "actors": ", ".join(metadata["actors"]),
        "genres": ", ".join(metadata["genres"]),
        "summary": metadata["summary"],
        "tagline": metadata["tagline"],
        "rating": metadata["rating"],
        "duration": metadata["duration"],
        "section_id": metadata["section_id"],
        "rating_key": metadata["rating_key"],
        "parent_rating_key": metadata["parent_rating_key"],
        "grandparent_rating_key": metadata["grandparent_rating_key"],
    }

    # Default subject text
    subject_text = "PlexPy (%s)" % server_name

    # Default scripts args
    script_args = []

    if script_args_text:
        try:
            script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
        except LookupError as e:
            logger.error(u"PlexPy Notifier :: Unable to parse field %s in script argument. Using fallback." % e)
        except Exception as e:
            logger.error(u"PlexPy Notifier :: Unable to parse custom script arguments %s. Using fallback." % e)

    if state == "play":
        # Default body text
        body_text = "%s (%s) started playing %s" % (session["friendly_name"], session["player"], full_title)

        if on_start_subject and on_start_body:
            try:
                subject_text = unicode(on_start_subject).format(**available_params)
            except LookupError, e:
                logger.error(
                    u"PlexPy NotificationHandler :: Unable to parse field %s in notification subject. Using fallback."
                    % e
                )
            except:
Example #10
0
def build_notify_text(session=None, timeline=None, state=None):
    # Get time formats
    date_format = plexpy.CONFIG.DATE_FORMAT.replace('Do','').replace('zz','')
    time_format = plexpy.CONFIG.TIME_FORMAT.replace('Do','').replace('zz','')
    duration_format = plexpy.CONFIG.TIME_FORMAT.replace('Do','').replace('zz','').replace('a','').replace('A','')

    # Get the server name
    server_name = plexpy.CONFIG.PMS_NAME

    # Get the server uptime
    plex_tv = plextv.PlexTV()
    server_times = plex_tv.get_server_times()

    if server_times:
        updated_at = server_times[0]['updated_at']
        server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_int(updated_at)))
    else:
        logger.error(u"PlexPy NotificationHandler :: Unable to retrieve server uptime.")
        server_uptime = 'N/A'

    # Get metadata feed for item
    if session:
        rating_key = session['rating_key']
    elif timeline:
        rating_key = timeline['rating_key']

    pms_connect = pmsconnect.PmsConnect()
    metadata_list = pms_connect.get_metadata_details(rating_key=rating_key)

    stream_count = pms_connect.get_current_activity().get('stream_count', '')

    if metadata_list:
        metadata = metadata_list['metadata']
    else:
        logger.error(u"PlexPy NotificationHandler :: Unable to retrieve metadata for rating_key %s" % str(rating_key))
        return []

    # Check for exclusion tags
    if metadata['media_type'] == 'movie':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('\n*<tv>[^>]+.</tv>\n*|\n*<music>[^>]+.</music>\n*', re.IGNORECASE | re.DOTALL)
    elif metadata['media_type'] == 'show' or metadata['media_type'] == 'episode':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('\n*<movie>[^>]+.</movie>\n*|\n*?<music>[^>]+.</music>\n*', re.IGNORECASE | re.DOTALL)
    elif metadata['media_type'] == 'artist' or metadata['media_type'] == 'track':
        # Regex pattern to remove the text in the tags we don't want
        pattern = re.compile('\n*<tv>[^>]+.</tv>\n*|\n*<movie>[^>]+.</movie>\n*', re.IGNORECASE | re.DOTALL)
    else:
        pattern = None

    if metadata['media_type'] == 'movie' \
        or metadata['media_type'] == 'show' or metadata['media_type'] == 'episode' \
        or metadata['media_type'] == 'artist' or metadata['media_type'] == 'track' \
        and pattern:
        # Remove the unwanted tags and strip any unmatch tags too.
        on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
        on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
        on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
        on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
        on_pause_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
        on_pause_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
        on_resume_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
        on_resume_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
        on_buffer_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
        on_buffer_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
        on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
        on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
        on_created_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT))
        on_created_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT))
        script_args_text = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT))
    else:
        on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
        on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
        on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
        on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
        on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
        on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
        on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
        on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
        on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
        on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
        on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
        on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
        on_created_subject = plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT
        on_created_body = plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT
        script_args_text = plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT

    # Create a title
    if metadata['media_type'] == 'episode' or metadata['media_type'] == 'track':
        full_title = '%s - %s' % (metadata['grandparent_title'],
                                  metadata['title'])
    else:
        full_title = metadata['title']

    # Session values
    if session is None:
        session = {}

    # Generate a combined transcode decision value
    if session.get('video_decision','') == 'transcode' or session.get('audio_decision','') == 'transcode':
        transcode_decision = 'Transcode'
    elif session.get('video_decision','') == 'copy' or session.get('audio_decision','') == 'copy':
        transcode_decision = 'Direct Stream'
    else:
        transcode_decision = 'Direct Play'
    
    if state != 'play':
        stream_duration = int((time.time() -
                               helpers.cast_to_int(session.get('started', 0)) -
                               helpers.cast_to_int(session.get('paused_counter', 0))) / 60)
    else:
        stream_duration = 0

    view_offset = helpers.convert_milliseconds_to_minutes(session.get('view_offset', 0))
    duration = helpers.convert_milliseconds_to_minutes(metadata['duration'])
    progress_percent = helpers.get_percent(view_offset, duration)
    remaining_duration = duration - view_offset

    # Get media IDs from guid and build URLs
    if 'imdb://' in metadata['guid']:
        metadata['imdb_id'] = metadata['guid'].split('imdb://')[1].split('?')[0]
        metadata['imdb_url'] = 'https://www.imdb.com/title/' + metadata['imdb_id']
        metadata['trakt_url'] = 'https://trakt.tv/search/imdb/' + metadata['imdb_id']

    if 'thetvdb://' in metadata['guid']:
        metadata['thetvdb_id'] = metadata['guid'].split('thetvdb://')[1].split('/')[0]
        metadata['thetvdb_url'] = 'https://thetvdb.com/?tab=series&id=' + metadata['thetvdb_id']
        metadata['trakt_url'] = 'https://trakt.tv/search/tvdb/' + metadata['thetvdb_id'] + '?id_type=show'

    elif 'thetvdbdvdorder://' in metadata['guid']:
        metadata['thetvdb_id'] = metadata['guid'].split('thetvdbdvdorder://')[1].split('/')[0]
        metadata['thetvdb_url'] = 'https://thetvdb.com/?tab=series&id=' + metadata['thetvdb_id']
        metadata['trakt_url'] = 'https://trakt.tv/search/tvdb/' + metadata['thetvdb_id'] + '?id_type=show'

    if 'themoviedb://' in metadata['guid']:
        if metadata['media_type'] == 'movie':
            metadata['themoviedb_id'] = metadata['guid'].split('themoviedb://')[1].split('?')[0]
            metadata['themoviedb_url'] = 'https://www.themoviedb.org/movie/' + metadata['themoviedb_id']
            metadata['trakt_url'] = 'https://trakt.tv/search/tmdb/' + metadata['themoviedb_id'] + '?id_type=movie'

        elif metadata['media_type'] == 'show' or metadata['media_type'] == 'episode':
            metadata['themoviedb_id'] = metadata['guid'].split('themoviedb://')[1].split('/')[0]
            metadata['themoviedb_url'] = 'https://www.themoviedb.org/tv/' + metadata['themoviedb_id']
            metadata['trakt_url'] = 'https://trakt.tv/search/tmdb/' + metadata['themoviedb_id'] + '?id_type=show'

    if 'lastfm://' in metadata['guid']:
        metadata['lastfm_id'] = metadata['guid'].split('lastfm://')[1].rsplit('/', 1)[0]
        metadata['lastfm_url'] = 'https://www.last.fm/music/' + metadata['lastfm_id']

    if metadata['media_type'] == 'movie' or metadata['media_type'] == 'show' or metadata['media_type'] == 'artist':
        thumb = metadata['thumb']
    elif metadata['media_type'] == 'episode':
        thumb = metadata['grandparent_thumb']
    elif metadata['media_type'] == 'track':
        thumb = metadata['parent_thumb']
    else:
        thumb = None

    if thumb:
        # Retrieve the poster from Plex and cache to file
        urllib.urlretrieve(plexpy.CONFIG.PMS_URL + thumb + '?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN,
                           os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster.jpg'))
        # Upload thumb to Imgur and get link
        metadata['poster_url'] = helpers.uploadToImgur(os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster.jpg'), full_title)

    # Fix metadata params for notify recently added grandparent
    if state == 'created' and plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT:
        show_name = metadata['title']
        episode_name = ''
        artist_name = metadata['title']
        album_name = ''
        track_name = ''
    else:
        show_name = metadata['grandparent_title']
        episode_name = metadata['title']
        artist_name = metadata['grandparent_title']
        album_name = metadata['parent_title']
        track_name = metadata['title']

    available_params = {# Global paramaters
                        'server_name': server_name,
                        'server_uptime': server_uptime,
                        'action': state.title(),
                        'datestamp': arrow.now().format(date_format),
                        'timestamp': arrow.now().format(time_format),
                        # Stream parameters
                        'streams': stream_count,
                        'user': session.get('friendly_name',''),
                        'platform': session.get('platform',''),
                        'player': session.get('player',''),
                        'ip_address': session.get('ip_address','N/A'),
                        'stream_duration': stream_duration,
                        'stream_time': arrow.get(stream_duration * 60).format(duration_format),
                        'remaining_duration': remaining_duration,
                        'remaining_time': arrow.get(remaining_duration * 60).format(duration_format),
                        'progress_duration': view_offset,
                        'progress_time': arrow.get(view_offset * 60).format(duration_format),
                        'progress_percent': progress_percent,
                        'container': session.get('container',''),
                        'video_codec': session.get('video_codec',''),
                        'video_bitrate': session.get('bitrate',''),
                        'video_width': session.get('width',''),
                        'video_height': session.get('height',''),
                        'video_resolution': session.get('video_resolution',''),
                        'video_framerate': session.get('video_framerate',''),
                        'aspect_ratio': session.get('aspect_ratio',''),
                        'audio_codec': session.get('audio_codec',''),
                        'audio_channels': session.get('audio_channels',''),
                        'transcode_decision': transcode_decision,
                        'video_decision': session.get('video_decision','').title(),
                        'audio_decision': session.get('audio_decision','').title(),
                        'transcode_container': session.get('transcode_container',''),
                        'transcode_video_codec': session.get('transcode_video_codec',''),
                        'transcode_video_width': session.get('transcode_width',''),
                        'transcode_video_height': session.get('transcode_height',''),
                        'transcode_audio_codec': session.get('transcode_audio_codec',''),
                        'transcode_audio_channels': session.get('transcode_audio_channels',''),
                        'session_key': session.get('session_key',''),
                        'user_id': session.get('user_id',''),
                        'machine_id': session.get('machine_id',''),
                        # Metadata parameters
                        'media_type': metadata['media_type'],
                        'title': full_title,
                        'library_name': metadata['library_name'],
                        'show_name': show_name,
                        'episode_name': episode_name,
                        'artist_name': artist_name,
                        'album_name': album_name,
                        'track_name': track_name,
                        'season_num': metadata['parent_media_index'].zfill(1),
                        'season_num00': metadata['parent_media_index'].zfill(2),
                        'episode_num': metadata['media_index'].zfill(1),
                        'episode_num00': metadata['media_index'].zfill(2),
                        'track_num': metadata['media_index'].zfill(1),
                        'track_num00': metadata['media_index'].zfill(2),
                        'year': metadata['year'],
                        'studio': metadata['studio'],
                        'content_rating': metadata['content_rating'],
                        'directors': ', '.join(metadata['directors']),
                        'writers': ', '.join(metadata['writers']),
                        'actors': ', '.join(metadata['actors']),
                        'genres': ', '.join(metadata['genres']),
                        'summary': metadata['summary'],
                        'tagline': metadata['tagline'],
                        'rating': metadata['rating'],
                        'duration': duration,
                        'poster_url': metadata.get('poster_url',''),
                        'imdb_id': metadata.get('imdb_id',''),
                        'imdb_url': metadata.get('imdb_url',''),
                        'thetvdb_id': metadata.get('thetvdb_id',''),
                        'thetvdb_url': metadata.get('thetvdb_url',''),
                        'themoviedb_id': metadata.get('themoviedb_id',''),
                        'themoviedb_url': metadata.get('themoviedb_url',''),
                        'lastfm_url': metadata.get('lastfm_url',''),
                        'trakt_url': metadata.get('trakt_url',''),
                        'section_id': metadata['section_id'],
                        'rating_key': metadata['rating_key'],
                        'parent_rating_key': metadata['parent_rating_key'],
                        'grandparent_rating_key': metadata['grandparent_rating_key']
                        }

    # Default subject text
    subject_text = 'PlexPy (%s)' % server_name

    # Default scripts args
    script_args = []

    if script_args_text:
        try:
            script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
        except LookupError as e:
            logger.error(u"PlexPy Notifier :: Unable to parse field %s in script argument. Using fallback." % e)
        except Exception as e:
            logger.error(u"PlexPy Notifier :: Unable to parse custom script arguments %s. Using fallback." % e)

    if state == 'play':
        # Default body text
        body_text = '%s (%s) started playing %s' % (session['friendly_name'],
                                                    session['player'],
                                                    full_title)

        if on_start_subject and on_start_body:
            try:
                subject_text = unicode(on_start_subject).format(**available_params)
            except LookupError, e:
                logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in notification subject. Using fallback." % e)
            except: