예제 #1
0
파일: users.py 프로젝트: zobe123/Plex-CS
    def set_user_profile_url(self, user=None, user_id=None, profile_url=None):
        if user_id:
            if profile_url.strip() == '':
                profile_url = None

            monitor_db = database.MonitorDatabase()

            control_value_dict = {"user_id": user_id}
            new_value_dict = {"custom_avatar_url": profile_url}
            try:
                monitor_db.upsert('users', new_value_dict, control_value_dict)
            except Exception as e:
                logger.debug(u"Uncaught exception %s" % e)
        if user:
            if profile_url.strip() == '':
                profile_url = None

            monitor_db = database.MonitorDatabase()

            control_value_dict = {"username": user}
            new_value_dict = {"custom_avatar_url": profile_url}
            try:
                monitor_db.upsert('users', new_value_dict, control_value_dict)
            except Exception as e:
                logger.debug(u"Uncaught exception %s" % e)
예제 #2
0
파일: users.py 프로젝트: zobe123/Plex-CS
    def get_user_friendly_name(self, user=None, user_id=None):
        if user_id:
            monitor_db = database.MonitorDatabase()
            query = 'select username, ' \
                    '(CASE WHEN friendly_name IS NULL THEN username ELSE friendly_name END) as friendly_name,' \
                    'do_notify, keep_history, custom_avatar_url as thumb ' \
                    'FROM users WHERE user_id = ?'
            result = monitor_db.select(query, args=[user_id])
            if result:
                user_detail = {
                    'user_id': user_id,
                    'user': result[0]['username'],
                    'friendly_name': result[0]['friendly_name'],
                    'thumb': result[0]['thumb'],
                    'do_notify': helpers.checked(result[0]['do_notify']),
                    'keep_history': helpers.checked(result[0]['keep_history'])
                }
                return user_detail
            else:
                user_detail = {
                    'user_id': user_id,
                    'user': '',
                    'friendly_name': '',
                    'do_notify': '',
                    'thumb': '',
                    'keep_history': ''
                }
                return user_detail
        elif user:
            monitor_db = database.MonitorDatabase()
            query = 'select user_id, ' \
                    '(CASE WHEN friendly_name IS NULL THEN username ELSE friendly_name END) as friendly_name,' \
                    'do_notify, keep_history, custom_avatar_url as thumb  ' \
                    'FROM users WHERE username = ?'
            result = monitor_db.select(query, args=[user])
            if result:
                user_detail = {
                    'user_id': result[0]['user_id'],
                    'user': user,
                    'friendly_name': result[0]['friendly_name'],
                    'thumb': result[0]['thumb'],
                    'do_notify': helpers.checked(result[0]['do_notify']),
                    'keep_history': helpers.checked(result[0]['keep_history'])
                }
                return user_detail
            else:
                user_detail = {
                    'user_id': None,
                    'user': user,
                    'friendly_name': '',
                    'do_notify': '',
                    'thumb': '',
                    'keep_history': ''
                }
                return user_detail

        return None
예제 #3
0
파일: plextv.py 프로젝트: zobe123/Plex-CS
def refresh_users():
    logger.info("Requesting users list refresh...")
    result = PlexTV().get_full_users_list()
    monitor_db = database.MonitorDatabase()

    if len(result) > 0:
        for item in result:
            control_value_dict = {"user_id": item['user_id']}
            new_value_dict = {"username": item['username'],
                              "thumb": item['thumb'],
                              "email": item['email'],
                              "is_home_user": item['is_home_user'],
                              "is_allow_sync": item['is_allow_sync'],
                              "is_restricted": item['is_restricted']
                              }

            # Check if we've set a custom avatar if so don't overwrite it.
            if item['user_id']:
                avatar_urls = monitor_db.select('SELECT thumb, custom_avatar_url '
                                                'FROM users WHERE user_id = ?',
                                                [item['user_id']])
                if avatar_urls:
                    if not avatar_urls[0]['custom_avatar_url'] or \
                            avatar_urls[0]['custom_avatar_url'] == avatar_urls[0]['thumb']:
                        new_value_dict['custom_avatar_url'] = item['thumb']
                else:
                    new_value_dict['custom_avatar_url'] = item['thumb']

            monitor_db.upsert('users', new_value_dict, control_value_dict)

        logger.info("Users list refreshed.")
    else:
        logger.warn("Unable to refresh users list.")
예제 #4
0
파일: users.py 프로젝트: zobe123/Plex-CS
    def set_user_friendly_name(self,
                               user=None,
                               user_id=None,
                               friendly_name=None,
                               do_notify=0,
                               keep_history=1):
        if user_id:
            if friendly_name.strip() == '':
                friendly_name = None

            monitor_db = database.MonitorDatabase()

            control_value_dict = {"user_id": user_id}
            new_value_dict = {
                "friendly_name": friendly_name,
                "do_notify": do_notify,
                "keep_history": keep_history
            }
            try:
                monitor_db.upsert('users', new_value_dict, control_value_dict)
            except Exception as e:
                logger.debug(u"Uncaught exception %s" % e)
        if user:
            if friendly_name.strip() == '':
                friendly_name = None

            monitor_db = database.MonitorDatabase()

            control_value_dict = {"username": user}
            new_value_dict = {
                "friendly_name": friendly_name,
                "do_notify": do_notify,
                "keep_history": keep_history
            }
            try:
                monitor_db.upsert('users', new_value_dict, control_value_dict)
            except Exception as e:
                logger.debug(u"Uncaught exception %s" % e)
예제 #5
0
파일: users.py 프로젝트: zobe123/Plex-CS
    def get_user_id(self, user=None):
        if user:
            try:
                monitor_db = database.MonitorDatabase()
                query = 'select user_id FROM users WHERE username = ?'
                result = monitor_db.select_single(query, args=[user])
                if result:
                    return result['user_id']
                else:
                    return None
            except:
                return None

        return None
예제 #6
0
파일: users.py 프로젝트: zobe123/Plex-CS
    def get_user_watch_time_stats(self, user=None, user_id=None):
        monitor_db = database.MonitorDatabase()

        time_queries = [1, 7, 30, 0]
        user_watch_time_stats = []

        for days in time_queries:
            if days > 0:
                if user_id:
                    query = 'SELECT (SUM(stopped - started) - ' \
                            'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
                            'COUNT(id) AS total_plays ' \
                            'FROM session_history ' \
                            'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
                            'AND user_id = ?' % days
                    result = monitor_db.select(query, args=[user_id])
                elif user:
                    query = 'SELECT (SUM(stopped - started) - ' \
                            'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
                            'COUNT(id) AS total_plays ' \
                            'FROM session_history ' \
                            'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
                            'AND user = ?' % days
                    result = monitor_db.select(query, args=[user])
            else:
                query = 'SELECT (SUM(stopped - started) - ' \
                        'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
                        'COUNT(id) AS total_plays ' \
                        'FROM session_history ' \
                        'WHERE user = ?'
                result = monitor_db.select(query, args=[user])

            for item in result:
                if item['total_time']:
                    total_time = item['total_time']
                    total_plays = item['total_plays']
                else:
                    total_time = 0
                    total_plays = 0

                row = {
                    'query_days': days,
                    'total_time': total_time,
                    'total_plays': total_plays
                }

                user_watch_time_stats.append(row)

        return user_watch_time_stats
예제 #7
0
def import_users():
    from plexcs import database

    logger.debug(u"Plex:CS Importer :: Importing PlexWatch Users...")
    monitor_db = database.MonitorDatabase()

    query = 'INSERT OR IGNORE INTO users (user_id, username) ' \
            'SELECT user_id, user ' \
            'FROM session_history WHERE user_id != 1 GROUP BY user_id'

    try:
        monitor_db.action(query)
        logger.debug(u"Plex:CS Importer :: Users imported.")
    except:
        logger.debug(u"Plex:CS Importer :: Failed to import users.")
예제 #8
0
def get_notify_state_timeline(timeline):
    monitor_db = database.MonitorDatabase()
    result = monitor_db.select(
        'SELECT on_created, agent_id '
        'FROM notify_log '
        'WHERE rating_key = ? '
        'ORDER BY id DESC',
        args=[timeline['rating_key']])
    notify_states = []
    for item in result:
        notify_state = {
            'on_created': item['on_created'],
            'agent_id': item['agent_id']
        }
        notify_states.append(notify_state)

    return notify_states
예제 #9
0
def set_notify_state(session, state, agent_info):

    if session and state and agent_info:
        monitor_db = database.MonitorDatabase()

        if state == 'play':
            values = {'on_play': int(time.time())}
        elif state == 'stop':
            values = {'on_stop': int(time.time())}
        elif state == 'pause':
            values = {'on_pause': int(time.time())}
        elif state == 'resume':
            values = {'on_resume': int(time.time())}
        elif state == 'buffer':
            values = {'on_buffer': int(time.time())}
        elif state == 'watched':
            values = {'on_watched': int(time.time())}
        elif state == 'created':
            values = {'on_created': int(time.time())}
        else:
            return

        if state == 'created':
            keys = {
                'rating_key': session['rating_key'],
                'agent_id': agent_info['id'],
                'agent_name': agent_info['name']
            }
        else:
            keys = {
                'session_key': session['session_key'],
                'rating_key': session['rating_key'],
                'user_id': session['user_id'],
                'user': session['user'],
                'agent_id': agent_info['id'],
                'agent_name': agent_info['name']
            }

        monitor_db.upsert(table_name='notify_log',
                          key_dict=keys,
                          value_dict=values)
    else:
        logger.error('Plex:CS Notifier :: Unable to set notify state.')
예제 #10
0
파일: users.py 프로젝트: zobe123/Plex-CS
    def get_user_player_stats(self, user=None, user_id=None):
        monitor_db = database.MonitorDatabase()

        player_stats = []
        result_id = 0

        try:
            if user_id:
                query = 'SELECT player, COUNT(player) as player_count, platform ' \
                        'FROM session_history ' \
                        'WHERE user_id = ? ' \
                        'GROUP BY player ' \
                        'ORDER BY player_count DESC'
                result = monitor_db.select(query, args=[user_id])
            else:
                query = 'SELECT player, COUNT(player) as player_count, platform ' \
                        'FROM session_history ' \
                        'WHERE user = ? ' \
                        'GROUP BY player ' \
                        'ORDER BY player_count DESC'
                result = monitor_db.select(query, args=[user])
        except:
            logger.warn("Unable to execute database query.")
            return None

        for item in result:
            # Rename Mystery platform names
            platform_type = common.PLATFORM_NAME_OVERRIDES.get(
                item['platform'], item['platform'])

            row = {
                'player_name': item['player'],
                'platform_type': platform_type,
                'total_plays': item['player_count'],
                'result_id': result_id
            }
            player_stats.append(row)
            result_id += 1

        return player_stats
예제 #11
0
def get_notify_state(session):
    monitor_db = database.MonitorDatabase()
    result = monitor_db.select(
        'SELECT on_play, on_stop, on_pause, on_resume, on_buffer, on_watched, agent_id '
        'FROM notify_log '
        'WHERE session_key = ? '
        'AND rating_key = ? '
        'AND user = ? '
        'ORDER BY id DESC',
        args=[session['session_key'], session['rating_key'], session['user']])
    notify_states = []
    for item in result:
        notify_state = {
            'on_play': item['on_play'],
            'on_stop': item['on_stop'],
            'on_pause': item['on_pause'],
            'on_resume': item['on_resume'],
            'on_buffer': item['on_buffer'],
            'on_watched': item['on_watched'],
            'agent_id': item['agent_id']
        }
        notify_states.append(notify_state)

    return notify_states
예제 #12
0
def check_active_sessions(ws_request=False):

    with monitor_lock:
        pms_connect = pmsconnect.PmsConnect()
        session_list = pms_connect.get_current_activity()
        monitor_db = database.MonitorDatabase()
        monitor_process = activity_processor.ActivityProcessor()
        # logger.debug(u"Plex:CS Monitor :: Checking for active streams.")

        global int_ping_count

        if session_list:
            int_ping_count = 0

            media_container = session_list['sessions']

            # Check our temp table for what we must do with the new streams
            db_streams = monitor_db.select('SELECT started, session_key, rating_key, media_type, title, parent_title, '
                                           'grandparent_title, user_id, user, friendly_name, ip_address, player, '
                                           'platform, machine_id, parent_rating_key, grandparent_rating_key, state, '
                                           'view_offset, duration, video_decision, audio_decision, 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, '
                                           'paused_counter, last_paused '
                                           'FROM sessions')
            for stream in db_streams:
                if any(d['session_key'] == str(stream['session_key']) and d['rating_key'] == str(stream['rating_key'])
                       for d in media_container):
                    # The user's session is still active
                    for session in media_container:
                        if session['session_key'] == str(stream['session_key']) and \
                                session['rating_key'] == str(stream['rating_key']):
                            # The user is still playing the same media item
                            # Here we can check the play states
                            if session['state'] != stream['state']:
                                if session['state'] == 'paused':
                                    # Push any notifications -
                                    # Push it on it's own thread so we don't hold up our db actions
                                    threading.Thread(target=notification_handler.notify,
                                                     kwargs=dict(stream_data=stream, notify_action='pause')).start()

                                if session['state'] == 'playing' and stream['state'] == 'paused':
                                    # Push any notifications -
                                    # Push it on it's own thread so we don't hold up our db actions
                                    threading.Thread(target=notification_handler.notify,
                                                     kwargs=dict(stream_data=stream, notify_action='resume')).start()

                            if stream['state'] == 'paused' and not ws_request:
                                # The stream is still paused so we need to increment the paused_counter
                                # Using the set config parameter as the interval, probably not the most accurate but
                                # it will have to do for now. If it's a websocket request don't use this method.
                                paused_counter = int(stream['paused_counter']) + plexcs.CONFIG.MONITORING_INTERVAL
                                monitor_db.action('UPDATE sessions SET paused_counter = ? '
                                                  'WHERE session_key = ? AND rating_key = ?',
                                                  [paused_counter, stream['session_key'], stream['rating_key']])

                            if session['state'] == 'buffering' and plexcs.CONFIG.BUFFER_THRESHOLD > 0:
                                # The stream is buffering so we need to increment the buffer_count
                                # We're going just increment on every monitor ping,
                                # would be difficult to keep track otherwise
                                monitor_db.action('UPDATE sessions SET buffer_count = buffer_count + 1 '
                                                  'WHERE session_key = ? AND rating_key = ?',
                                                  [stream['session_key'], stream['rating_key']])

                                # Check the current buffer count and last buffer to determine if we should notify
                                buffer_values = monitor_db.select('SELECT buffer_count, buffer_last_triggered '
                                                                  'FROM sessions '
                                                                  'WHERE session_key = ? AND rating_key = ?',
                                                                  [stream['session_key'], stream['rating_key']])

                                if buffer_values[0]['buffer_count'] >= plexcs.CONFIG.BUFFER_THRESHOLD:
                                    # Push any notifications -
                                    # Push it on it's own thread so we don't hold up our db actions
                                    # Our first buffer notification
                                    if buffer_values[0]['buffer_count'] == plexcs.CONFIG.BUFFER_THRESHOLD:
                                        logger.info(u"Plex:CS Monitor :: User '%s' has triggered a buffer warning."
                                                    % stream['user'])
                                        # Set the buffer trigger time
                                        monitor_db.action('UPDATE sessions '
                                                          'SET buffer_last_triggered = strftime("%s","now") '
                                                          'WHERE session_key = ? AND rating_key = ?',
                                                          [stream['session_key'], stream['rating_key']])

                                        threading.Thread(target=notification_handler.notify,
                                                         kwargs=dict(stream_data=stream, notify_action='buffer')).start()
                                    else:
                                        # Subsequent buffer notifications after wait time
                                        if int(time.time()) > buffer_values[0]['buffer_last_triggered'] + \
                                                plexcs.CONFIG.BUFFER_WAIT:
                                            logger.info(u"Plex:CS Monitor :: User '%s' has triggered multiple buffer warnings."
                                                    % stream['user'])
                                            # Set the buffer trigger time
                                            monitor_db.action('UPDATE sessions '
                                                              'SET buffer_last_triggered = strftime("%s","now") '
                                                              'WHERE session_key = ? AND rating_key = ?',
                                                              [stream['session_key'], stream['rating_key']])

                                            threading.Thread(target=notification_handler.notify,
                                                             kwargs=dict(stream_data=stream, notify_action='buffer')).start()

                                logger.debug(u"Plex:CS Monitor :: Stream buffering. Count is now %s. Last triggered %s."
                                             % (buffer_values[0]['buffer_count'],
                                                buffer_values[0]['buffer_last_triggered']))

                            # Check if the user has reached the offset in the media we defined as the "watched" percent
                            # Don't trigger if state is buffer as some clients push the progress to the end when
                            # buffering on start.
                            if session['view_offset'] and session['duration'] and session['state'] != 'buffering':
                                if helpers.get_percent(session['view_offset'],
                                                       session['duration']) > plexcs.CONFIG.NOTIFY_WATCHED_PERCENT:
                                    # Push any notifications -
                                    # Push it on it's own thread so we don't hold up our db actions
                                    threading.Thread(target=notification_handler.notify,
                                                     kwargs=dict(stream_data=stream, notify_action='watched')).start()

                else:
                    # The user has stopped playing a stream
                    logger.debug(u"Plex:CS Monitor :: Removing sessionKey %s ratingKey %s from session queue"
                                 % (stream['session_key'], stream['rating_key']))
                    monitor_db.action('DELETE FROM sessions WHERE session_key = ? AND rating_key = ?',
                                      [stream['session_key'], stream['rating_key']])

                    # Check if the user has reached the offset in the media we defined as the "watched" percent
                    if stream['view_offset'] and stream['duration']:
                        if helpers.get_percent(stream['view_offset'],
                                               stream['duration']) > plexcs.CONFIG.NOTIFY_WATCHED_PERCENT:
                            # Push any notifications -
                            # Push it on it's own thread so we don't hold up our db actions
                            threading.Thread(target=notification_handler.notify,
                                             kwargs=dict(stream_data=stream, notify_action='watched')).start()

                    # Push any notifications - Push it on it's own thread so we don't hold up our db actions
                    threading.Thread(target=notification_handler.notify,
                                     kwargs=dict(stream_data=stream, notify_action='stop')).start()

                    # Write the item history on playback stop
                    monitor_process.write_session_history(session=stream)

            # Process the newly received session data
            for session in media_container:
                monitor_process.write_session(session)
        else:
            logger.debug(u"Plex:CS Monitor :: Unable to read session list.")

            int_ping_count += 1
            logger.warn(u"Plex:CS Monitor :: Unable to get an internal response from the server, ping attempt %s." \
                        % str(int_ping_count))

        if int_ping_count == 3:
            # Fire off notifications
            threading.Thread(target=notification_handler.notify_timeline,
                                kwargs=dict(notify_action='intdown')).start()
예제 #13
0
 def __init__(self):
     self.db = database.MonitorDatabase()
예제 #14
0
파일: users.py 프로젝트: zobe123/Plex-CS
    def get_user_details(self, user=None, user_id=None):
        from plexcs import plextv

        monitor_db = database.MonitorDatabase()

        if user:
            query = 'SELECT user_id, username, friendly_name, email, ' \
                    'custom_avatar_url as thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
                    'FROM users ' \
                    'WHERE username = ? ' \
                    'UNION ALL ' \
                    'SELECT null, user, null, null, null, null, null, null, null ' \
                    'FROM session_history ' \
                    'WHERE user = ? ' \
                    'GROUP BY user ' \
                    'LIMIT 1'
            result = monitor_db.select(query, args=[user, user])
        elif user_id:
            query = 'SELECT user_id, username, friendly_name, email, ' \
                    'custom_avatar_url as thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
                    'FROM users ' \
                    'WHERE user_id = ? ' \
                    'UNION ALL ' \
                    'SELECT user_id, user, null, null, null, null, null, null, null ' \
                    'FROM session_history ' \
                    'WHERE user_id = ? ' \
                    'GROUP BY user ' \
                    'LIMIT 1'
            result = monitor_db.select(query, args=[user_id, user_id])
        else:
            result = None

        if result:
            user_details = {}
            for item in result:
                if not item['friendly_name']:
                    friendly_name = item['username']
                else:
                    friendly_name = item['friendly_name']
                if not item['thumb'] or item['thumb'] == '':
                    user_thumb = common.DEFAULT_USER_THUMB
                else:
                    user_thumb = item['thumb']

                user_details = {
                    "user_id": item['user_id'],
                    "username": item['username'],
                    "friendly_name": friendly_name,
                    "email": item['email'],
                    "thumb": user_thumb,
                    "is_home_user": item['is_home_user'],
                    "is_allow_sync": item['is_allow_sync'],
                    "is_restricted": item['is_restricted'],
                    "do_notify": item['do_notify']
                }
            return user_details
        else:
            logger.warn(
                u"Plex:CS :: Unable to retrieve user from local database. Requesting user list refresh."
            )
            # Let's first refresh the user list to make sure the user isn't newly added and not in the db yet
            if user:
                # Refresh users
                plextv.refresh_users()
                query = 'SELECT user_id, username, friendly_name, email, ' \
                        'custom_avatar_url as thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
                        'FROM users ' \
                        'WHERE username = ? ' \
                        'UNION ALL ' \
                        'SELECT null, user, null, null, null, null, null, null, null ' \
                        'FROM session_history ' \
                        'WHERE user = ? ' \
                        'GROUP BY user ' \
                        'LIMIT 1'
                result = monitor_db.select(query, args=[user, user])
            elif user_id:
                # Refresh users
                plextv.refresh_users()
                query = 'SELECT user_id, username, friendly_name, email, ' \
                        'custom_avatar_url as thumb, is_home_user, is_allow_sync, is_restricted, do_notify ' \
                        'FROM users ' \
                        'WHERE user_id = ? ' \
                        'UNION ALL ' \
                        'SELECT user_id, user, null, null, null, null, null, null, null ' \
                        'FROM session_history ' \
                        'WHERE user_id = ? ' \
                        'GROUP BY user ' \
                        'LIMIT 1'
                result = monitor_db.select(query, args=[user_id, user_id])
            else:
                result = None

            if result:
                user_details = {}
                for item in result:
                    if not item['friendly_name']:
                        friendly_name = item['username']
                    else:
                        friendly_name = item['friendly_name']
                    if not item['thumb'] or item['thumb'] == '':
                        user_thumb = common.DEFAULT_USER_THUMB
                    else:
                        user_thumb = item['thumb']

                    user_details = {
                        "user_id": item['user_id'],
                        "username": item['username'],
                        "friendly_name": friendly_name,
                        "email": item['email'],
                        "thumb": user_thumb,
                        "is_home_user": item['is_home_user'],
                        "is_allow_sync": item['is_allow_sync'],
                        "is_restricted": item['is_restricted'],
                        "do_notify": item['do_notify']
                    }
                return user_details
            else:
                # If there is no user data we must return something
                # Use "Local" user to retain compatibility with PlexWatch database value
                return {
                    "user_id": None,
                    "username": '******',
                    "friendly_name": 'Local',
                    "email": '',
                    "thumb": '',
                    "is_home_user": 0,
                    "is_allow_sync": 0,
                    "is_restricted": 0,
                    "do_notify": 0
                }