Exemplo n.º 1
0
def process(opcode, data):
    from plexpy import activity_handler

    if opcode not in opcode_data:
        return False

    try:
        info = json.loads(data)
    except Exception as ex:
        logger.warn(u'PlexPy WebSocket :: Error decoding message from websocket: %s' % ex)
        logger.debug(data)
        return False

    type = info.get('type')

    if not type:
        return False

    if type == 'playing':
        # logger.debug('%s.playing %s' % (name, info))
        try:
            time_line = info.get('_children')
        except:
            logger.debug(u"PlexPy WebSocket :: Session found but unable to get timeline data.")
            return False

        activity = activity_handler.ActivityHandler(timeline=time_line[0])
        activity.process()

    return True
Exemplo n.º 2
0
    def update(self):

        # From what I read you can't update the music library on a per directory or per path basis
        # so need to update the whole thing

        hosts = [x.strip() for x in self.server_hosts.split(',')]

        for host in hosts:
            logger.info('Sending library update command to Plex Media Server@ ' + host)
            url = "%s/library/sections" % host
            try:
                xml_sections = minidom.parse(urllib.urlopen(url))
            except IOError, e:
                logger.warn("Error while trying to contact Plex Media Server: %s" % e)
                return False

            sections = xml_sections.getElementsByTagName('Directory')
            if not sections:
                logger.info(u"Plex Media Server not running on: " + host)
                return False

            for s in sections:
                if s.getAttribute('type') == "artist":
                    url = "%s/library/sections/%s/refresh" % (host, s.getAttribute('key'))
                    try:
                        urllib.urlopen(url)
                    except Exception as e:
                        logger.warn("Error updating library section for Plex Media Server: %s" % e)
                        return False
Exemplo n.º 3
0
    def get_current_activity(self):
        session_data = self.get_sessions(output_format="xml")

        try:
            xml_head = session_data.getElementsByTagName("MediaContainer")
        except:
            logger.warn("Unable to parse XML for get_sessions.")
            return []

        session_list = []

        for a in xml_head:
            if a.getAttribute("size"):
                if a.getAttribute("size") == "0":
                    session_list = {"stream_count": "0", "sessions": []}
                    return session_list

            if a.getElementsByTagName("Track"):
                session_data = a.getElementsByTagName("Track")
                session_type = "track"
                for session in session_data:
                    session_output = self.get_session_each(session_type, session)
                    session_list.append(session_output)
            if a.getElementsByTagName("Video"):
                session_data = a.getElementsByTagName("Video")
                session_type = "video"
                for session in session_data:
                    session_output = self.get_session_each(session_type, session)
                    session_list.append(session_output)

        output = {"stream_count": helpers.get_xml_attr(xml_head[0], "size"), "sessions": session_list}

        return output
Exemplo n.º 4
0
def refresh_users():
    logger.info(u"PlexPy PlexTV :: 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(u"PlexPy PlexTV :: Users list refreshed.")
    else:
        logger.warn(u"PlexPy PlexTV :: Unable to refresh users list.")
Exemplo n.º 5
0
    def get_user_list(self, kwargs=None):
        data_tables = datatables.DataTables()

        columns = ['session_history.id',
                   'users.thumb as thumb',
                   '(case when users.friendly_name is null then session_history.user else \
                    users.friendly_name end) as friendly_name',
                   'session_history.started',
                   'session_history.ip_address',
                   'COUNT(session_history.id) as plays',
                   'session_history.user',
                   'session_history.user_id',
                   '(case when typeof(session_history.user_id) = "integer" \
                    then session_history.user_id else -1 end) as grp_id',
                   ]
        try:
            query = data_tables.ssp_query(table_name='session_history',
                                          columns=columns,
                                          custom_where=[],
                                          group_by=['grp_id'],
                                          join_types=['LEFT OUTER JOIN'],
                                          join_tables=['users'],
                                          join_evals=[['grp_id', 'users.user_id']],
                                          kwargs=kwargs)
        except:
            logger.warn("Unable to execute database query.")
            return {'recordsFiltered': 0,
                    'recordsTotal': 0,
                    'draw': 0,
                    'data': 'null',
                    'error': 'Unable to execute database query.'}

        users = query['result']

        rows = []
        for item in users:
            if not item['thumb'] or item['thumb'] == '':
                user_thumb = common.DEFAULT_USER_THUMB
            else:
                user_thumb = item['thumb']

            row = {"id": item['id'],
                   "plays": item['plays'],
                   "started": item['started'],
                   "friendly_name": item["friendly_name"],
                   "ip_address": item["ip_address"],
                   "thumb": user_thumb,
                   "user": item["user"],
                   "user_id": item['user_id']
                   }

            rows.append(row)

        dict = {'recordsFiltered': query['filteredCount'],
                'recordsTotal': query['totalCount'],
                'data': rows,
                'draw': query['draw']
        }

        return dict
Exemplo n.º 6
0
def shutdown(restart=False, update=False):
    cherrypy.engine.exit()
    SCHED.shutdown(wait=False)

    CONFIG.write()

    if not restart and not update:
        logger.info('PlexPy is shutting down...')

    if update:
        logger.info('PlexPy is updating...')
        try:
            versioncheck.update()
        except Exception as e:
            logger.warn('PlexPy failed to update: %s. Restarting.', e)

    if CREATEPID:
        logger.info('Removing pidfile %s', PIDFILE)
        os.remove(PIDFILE)

    if restart:
        logger.info('PlexPy is restarting...')
        popen_list = [sys.executable, FULL_PATH]
        popen_list += ARGS
        if '--nolaunch' not in popen_list:
            popen_list += ['--nolaunch']
        logger.info('Restarting PlexPy with %s', popen_list)
        subprocess.Popen(popen_list, cwd=os.getcwd())

    os._exit(0)
Exemplo n.º 7
0
    def notify(self, subject, message):
        if not subject or not message:
            return

        message = MIMEText(message, 'plain', "utf-8")
        message['Subject'] = subject
        message['From'] = email.utils.formataddr(('PlexPy', plexpy.CONFIG.EMAIL_FROM))
        message['To'] = plexpy.CONFIG.EMAIL_TO

        try:
            mailserver = smtplib.SMTP(plexpy.CONFIG.EMAIL_SMTP_SERVER, plexpy.CONFIG.EMAIL_SMTP_PORT)

            if (plexpy.CONFIG.EMAIL_TLS):
                mailserver.starttls()

            mailserver.ehlo()

            if plexpy.CONFIG.EMAIL_SMTP_USER:
                mailserver.login(plexpy.CONFIG.EMAIL_SMTP_USER, plexpy.CONFIG.EMAIL_SMTP_PASSWORD)

            mailserver.sendmail(plexpy.CONFIG.EMAIL_FROM, plexpy.CONFIG.EMAIL_TO, message.as_string())
            mailserver.quit()
            return True

        except Exception, e:
            logger.warn('Error sending Email: %s' % e)
            return False
Exemplo n.º 8
0
    def discover(self):
        """ Query plex for all servers online. Returns the ones you own in a selectize format """
        result = self.get_plextv_resources(include_https=True, output_format='raw')
        servers = xmltodict.parse(result, process_namespaces=True, attr_prefix='')
        clean_servers = []

        try:
            if servers:
                # Fix if its only one "device"
                if int(servers['MediaContainer']['size']) == 1:
                    servers['MediaContainer']['Device'] = [servers['MediaContainer']['Device']]

                for server in servers['MediaContainer']['Device']:
                    # Only grab servers online and own
                    if server.get('presence', None) == '1' and server.get('owned', None) == '1' and server.get('provides', None) == 'server':
                        # If someone only has one connection..
                        if isinstance(server['Connection'], dict):
                            server['Connection'] = [server['Connection']]

                        for s in server['Connection']:
                            # to avoid circular ref
                            d = {}
                            d.update(s)
                            d.update(server)
                            d['label'] = d['name']
                            d['value'] = d['address']
                            del d['Connection']
                            clean_servers.append(d)

        except Exception as e:
            logger.warn('Failed to get servers from plex %s' % e)
            return clean_servers

        return json.dumps(clean_servers, indent=4)
Exemplo n.º 9
0
    def get_user_stats(self, section_id=None):
        monitor_db = database.MonitorDatabase()

        user_stats = []

        try:
            if str(section_id).isdigit():
                query = 'SELECT (CASE WHEN users.friendly_name IS NULL THEN users.username ' \
                        'ELSE users.friendly_name END) AS user, users.user_id, users.thumb, COUNT(user) AS user_count ' \
                        'FROM session_history ' \
                        'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
                        'JOIN users ON users.user_id = session_history.user_id ' \
                        'WHERE section_id = ? ' \
                        'GROUP BY users.user_id ' \
                        'ORDER BY user_count DESC'
                result = monitor_db.select(query, args=[section_id])
            else:
                result = []
        except Exception as e:
            logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_user_stats: %s." % e)
            result = []
        
        for item in result:
            row = {'user': item['user'],
                   'user_id': item['user_id'],
                   'thumb': item['thumb'],
                   'total_plays': item['user_count']
                   }
            user_stats.append(row)
        
        return user_stats
Exemplo n.º 10
0
    def delete_all_history(self, user_id=None):
        monitor_db = database.MonitorDatabase()

        try:
            if str(user_id).isdigit():
                logger.info(u"PlexPy DataFactory :: Deleting all history for user id %s from database." % user_id)
                session_history_media_info_del = \
                    monitor_db.action('DELETE FROM '
                                      'session_history_media_info '
                                      'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id '
                                      'FROM session_history_media_info '
                                      'JOIN session_history ON session_history_media_info.id = session_history.id '
                                      'WHERE session_history.user_id = ?)', [user_id])
                session_history_metadata_del = \
                    monitor_db.action('DELETE FROM '
                                      'session_history_metadata '
                                      'WHERE session_history_metadata.id IN (SELECT session_history_metadata.id '
                                      'FROM session_history_metadata '
                                      'JOIN session_history ON session_history_metadata.id = session_history.id '
                                      'WHERE session_history.user_id = ?)', [user_id])
                session_history_del = \
                    monitor_db.action('DELETE FROM '
                                      'session_history '
                                      'WHERE session_history.user_id = ?', [user_id])

                return 'Deleted all items for user_id %s.' % user_id
            else:
                return 'Unable to delete items. Input user_id not valid.'
        except Exception as e:
            logger.warn(u"PlexPy Users :: Unable to execute database query for delete_all_history: %s." % e)
Exemplo n.º 11
0
def check_server_response():

    with monitor_lock:
        pms_connect = pmsconnect.PmsConnect()
        server_response = pms_connect.get_server_response()

        global ext_ping_count
        
        # Check for remote access
        if server_response:
        
            mapping_state = server_response['mapping_state']
            mapping_error = server_response['mapping_error']

            # Check if the port is mapped
            if not mapping_state == 'mapped':
                ext_ping_count += 1
                logger.warn(u"PlexPy Monitor :: Plex remote access port not mapped, ping attempt %s." \
                            % str(ext_ping_count))
            # Check if the port is open
            elif mapping_error == 'unreachable':
                ext_ping_count += 1
                logger.warn(u"PlexPy Monitor :: Plex remote access port mapped, but mapping failed, ping attempt %s." \
                            % str(ext_ping_count))
            # Reset external ping counter
            else:
                ext_ping_count = 0

        if ext_ping_count == 3:
            # Fire off notifications
            threading.Thread(target=notification_handler.notify_timeline,
                                kwargs=dict(notify_action='extdown')).start()
Exemplo n.º 12
0
    def delete_all_history(self, section_id=None):
        monitor_db = database.MonitorDatabase()

        try:
            if section_id.isdigit():
                logger.info(u"PlexPy Libraries :: Deleting all history for library id %s from database." % section_id)
                session_history_media_info_del = \
                    monitor_db.action('DELETE FROM '
                                      'session_history_media_info '
                                      'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id '
                                      'FROM session_history_media_info '
                                      'JOIN session_history_metadata ON session_history_media_info.id = session_history_metadata.id '
                                      'WHERE session_history_metadata.section_id = ?)', [section_id])
                session_history_del = \
                    monitor_db.action('DELETE FROM '
                                      'session_history '
                                      'WHERE session_history.id IN (SELECT session_history.id '
                                      'FROM session_history '
                                      'JOIN session_history_metadata ON session_history.id = session_history_metadata.id '
                                      'WHERE session_history_metadata.section_id = ?)', [section_id])
                session_history_metadata_del = \
                    monitor_db.action('DELETE FROM '
                                      'session_history_metadata '
                                      'WHERE session_history_metadata.section_id = ?', [section_id])

                return 'Deleted all items for section_id %s.' % section_id
            else:
                return 'Unable to delete items, section_id not valid.'
        except Exception as e:
            logger.warn(u"PlexPy Libraries :: Unable to execute database query for delete_all_history: %s." % e)
Exemplo n.º 13
0
def shutdown(restart=False, update=False):
    cherrypy.engine.exit()
    SCHED.shutdown(wait=False)

    CONFIG.write()

    if not restart and not update:
        logger.info('PlexPy is shutting down...')

    if update:
        logger.info('PlexPy is updating...')
        try:
            versioncheck.update()
        except Exception as e:
            logger.warn('PlexPy failed to update: %s. Restarting.', e)

    if CREATEPID:
        logger.info('Removing pidfile %s', PIDFILE)
        os.remove(PIDFILE)

    if restart:
        logger.info('PlexPy is restarting...')
        exe = sys.executable
        args = [exe, FULL_PATH]
        args += ARGS
        if '--nolaunch' not in args:
            args += ['--nolaunch']
        logger.info('Restarting PlexPy with %s', args)
        os.execv(exe, args)

    os._exit(0)
Exemplo n.º 14
0
    def action(self, query, args=None, return_last_id=False):
        if query is None:
            return

        with db_lock:
            sql_result = None
            attempts = 0

            while attempts < 5:
                try:
                    with self.connection as c:
                        if args is None:
                            sql_result = c.execute(query)
                        else:
                            sql_result = c.execute(query, args)
                    # Our transaction was successful, leave the loop
                    break

                except sqlite3.OperationalError, e:
                    if "unable to open database file" in e.message or "database is locked" in e.message:
                        logger.warn('Database Error: %s', e)
                        attempts += 1
                        time.sleep(1)
                    else:
                        logger.error('Database error: %s', e)
                        raise

                except sqlite3.DatabaseError, e:
                    logger.error('Fatal Error executing %s :: %s', query, e)
                    raise
Exemplo n.º 15
0
    def get_season_children(self, rating_key=''):
        episode_data = self.get_episode_list(rating_key, output_format='xml')
        episode_list = []

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

        for a in xml_head:
            if a.getAttribute('size'):
                if a.getAttribute('size') == '0':
                    logger.debug(u"No episode data.")
                    episode_list = {'episode_count': '0',
                                    'episode_list': []
                                    }
                    return episode_list

            if a.getElementsByTagName('Video'):
                result_data = a.getElementsByTagName('Video')
                for result in result_data:
                    episode_output = {'rating_key': helpers.get_xml_attr(result, 'ratingKey'),
                                      'index': helpers.get_xml_attr(result, 'index'),
                                      'title': helpers.get_xml_attr(result, 'title'),
                                      'thumb': helpers.get_xml_attr(result, 'thumb')
                                      }
                    episode_list.append(episode_output)

        output = {'episode_count': helpers.get_xml_attr(xml_head[0], 'size'),
                  'title': helpers.get_xml_attr(xml_head[0], 'title2'),
                  'episode_list': episode_list
                  }

        return output
Exemplo n.º 16
0
def shutdown(restart=False, update=False):
    cherrypy.engine.exit()
    SCHED.shutdown(wait=False)

    # Clear any sessions in the db - Not sure yet if we should do this. More testing required
    # logger.debug(u'Clearing Plex sessions.')
    # monitor.drop_session_db()

    CONFIG.write()

    if not restart and not update:
        logger.info('PlexPy is shutting down...')

    if update:
        logger.info('PlexPy is updating...')
        try:
            versioncheck.update()
        except Exception as e:
            logger.warn('PlexPy failed to update: %s. Restarting.', e)

    if CREATEPID:
        logger.info('Removing pidfile %s', PIDFILE)
        os.remove(PIDFILE)

    if restart:
        logger.info('PlexPy is restarting...')
        popen_list = [sys.executable, FULL_PATH]
        popen_list += ARGS
        if '--nolaunch' not in popen_list:
            popen_list += ['--nolaunch']
        logger.info('Restarting PlexPy with %s', popen_list)
        subprocess.Popen(popen_list, cwd=os.getcwd())

    os._exit(0)
Exemplo n.º 17
0
    def _sendhttp(self, host, command):

        username = self.username
        password = self.password

        url_command = urllib.urlencode(command)

        url = host + '/xbmcCmds/xbmcHttp/?' + url_command

        req = urllib2.Request(url)

        if password:
            base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
            req.add_header("Authorization", "Basic %s" % base64string)

        logger.info('Plex url: %s' % url)

        try:
            handle = urllib2.urlopen(req)
        except Exception as e:
            logger.warn('Error opening Plex url: %s' % e)
            return

        response = handle.read().decode(plexpy.SYS_ENCODING)

        return response
Exemplo n.º 18
0
    def get_current_activity(self):
        session_data = self.get_sessions(output_format='xml')
        session_list = []

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

        for a in xml_head:
            if a.getAttribute('size'):
                if a.getAttribute('size') == '0':
                    session_list = {'stream_count': '0',
                                    'sessions': []
                                    }
                    return session_list

            if a.getElementsByTagName('Track'):
                session_data = a.getElementsByTagName('Track')
                session_type = 'track'
                for session in session_data:
                    session_output = self.get_session_each(session_type, session)
                    session_list.append(session_output)
            if a.getElementsByTagName('Video'):
                session_data = a.getElementsByTagName('Video')
                session_type = 'video'
                for session in session_data:
                    session_output = self.get_session_each(session_type, session)
                    session_list.append(session_output)

        output = {'stream_count': helpers.get_xml_attr(xml_head[0], 'size'),
                  'sessions': session_list
                  }

        return output
Exemplo n.º 19
0
def uploadToImgur(imgPath, imgTitle=''):
    from plexpy import logger

    client_id = '743b1a443ccd2b0'
    img_url = ''

    try:
        with open(imgPath, 'rb') as imgFile:
            img = imgFile.read()
    except IOError as e:
        logger.error(u"PlexPy Helpers :: Unable to read image file for Imgur: %s" % e)
        return img_url

    headers = {'Authorization': 'Client-ID %s' % client_id}
    data = {'type': 'base64',
            'image': base64.b64encode(img)}
    if imgTitle:
        data['title'] = imgTitle
        data['name'] = imgTitle + '.jpg'

    request = urllib2.Request('https://api.imgur.com/3/image', headers=headers, data=urllib.urlencode(data))
    response = urllib2.urlopen(request)
    response = json.loads(response.read())
    
    if response.get('status') == 200:
        logger.debug(u"PlexPy Helpers :: Image uploaded to Imgur.")
        img_url = response.get('data').get('link', '')
    elif response.get('status') >= 400 and response.get('status') < 500:
        logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur: %s" % response.reason)
    else:
        logger.warn(u"PlexPy Helpers :: Unable to upload image to Imgur.")

    return img_url
Exemplo n.º 20
0
    def notify(self, subject, message):

        message = MIMEText(message, "plain", "utf-8")
        message["Subject"] = subject
        message["From"] = email.utils.formataddr(("PlexPy", plexpy.CONFIG.EMAIL_FROM))
        message["To"] = plexpy.CONFIG.EMAIL_TO

        try:
            mailserver = smtplib.SMTP(plexpy.CONFIG.EMAIL_SMTP_SERVER, plexpy.CONFIG.EMAIL_SMTP_PORT)

            if plexpy.CONFIG.EMAIL_TLS:
                mailserver.starttls()

            mailserver.ehlo()

            if plexpy.CONFIG.EMAIL_SMTP_USER:
                mailserver.login(plexpy.CONFIG.EMAIL_SMTP_USER, plexpy.CONFIG.EMAIL_SMTP_PASSWORD)

            mailserver.sendmail(plexpy.CONFIG.EMAIL_FROM, plexpy.CONFIG.EMAIL_TO, message.as_string())
            mailserver.quit()
            return True

        except Exception, e:
            logger.warn("Error sending Email: %s" % e)
            return False
Exemplo n.º 21
0
    def get_player_stats(self, user_id=None):
        monitor_db = database.MonitorDatabase()

        player_stats = []
        result_id = 0

        try:
            if str(user_id).isdigit():
                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:
                result = []
        except Exception as e:
            logger.warn(u"PlexPy Users :: Unable to execute database query for get_player_stats: %s." % e)
            result = []

        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
Exemplo n.º 22
0
    def get_user_platform_stats(self, user=None, user_id=None):
        monitor_db = database.MonitorDatabase()

        platform_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:
            row = {'platform_name': item[0],
                   'platform_type': item[2],
                   'total_plays': item[1],
                   'result_id': result_id
                   }
            platform_stats.append(row)
            result_id += 1

        return platform_stats
Exemplo n.º 23
0
    def user(self, user=None):
        try:
            data_factory = datafactory.DataFactory()
            user_details = data_factory.get_user_details(user=user)
        except:
            logger.warn("Unable to retrieve friendly name for user %s " % user)

        return serve_template(templatename="user.html", title="User", data=user_details)
Exemplo n.º 24
0
    def user(self, user=None):
        try:
            plex_watch = plexwatch.PlexWatch()
            user_details = plex_watch.get_user_details(user)
        except:
            logger.warn("Unable to retrieve friendly name for user %s " % user)

        return serve_template(templatename="user.html", title="User", data=user_details)
Exemplo n.º 25
0
    def get_current_activity(self):
        session_data = self.get_sessions()
        session_list = []

        try:
            xml_parse = minidom.parseString(session_data)
        except Exception, e:
            logger.warn("Error parsing XML for Plex session data: %s" % e)
            return None
Exemplo n.º 26
0
    def get_season_children(self, rating_key=''):
        episode_data = self.get_episode_list(rating_key)
        episode_list = []

        try:
            xml_parse = minidom.parseString(episode_data)
        except Exception, e:
            logger.warn("Error parsing XML for Plex session data: %s" % e)
            return None
Exemplo n.º 27
0
    def get_server_pref(self, pref=None, **kwargs):

        pms_connect = pmsconnect.PmsConnect()
        result = pms_connect.get_server_pref(pref=pref)

        if result:
            return result
        else:
            logger.warn("Unable to retrieve data.")
Exemplo n.º 28
0
    def get_metadata_details(self, rating_key=''):
        metadata = self.get_metadata(rating_key)
        metadata_list = []

        try:
            xml_parse = minidom.parseString(metadata)
        except Exception, e:
            logger.warn("Error parsing XML for Plex metadata: %s" % e)
            return None
Exemplo n.º 29
0
    def get_plex_log(self, window=1000, **kwargs):
        log_lines = []
        try:
            log_lines = {"data": log_reader.get_log_tail(window=window)}
        except:
            logger.warn("Unable to retrieve Plex Logs.")

        cherrypy.response.headers["Content-type"] = "application/json"
        return json.dumps(log_lines)
Exemplo n.º 30
0
    def get_recently_added_details(self, count='0'):
        recent = self.get_recently_added(count)
        recents_list = []

        try:
            xml_parse = minidom.parseString(recent)
        except Exception, e:
            logger.warn("Error parsing XML for Plex recently added: %s" % e)
            return None
Exemplo n.º 31
0
    def delete_all_history(self):
        monitor_db = database.MonitorDatabase()

        try:
            logger.info(
                u"Tautulli Servers :: %s: Deleting all history from database."
                % self.CONFIG.PMS_NAME)
            query = 'SELECT session_key FROM sessions WHERE server_id = ?'
            result = monitor_db.select(query, [self.CONFIG.ID])
            ap = activity_processor.ActivityProcessor(server=self)
            for item in result:
                ap.delete_session(session_key=item['session_key'])
                activity_handler.delete_metadata_cache(
                    session_key=item['session_key'], server=self)
            sessions_del = \
                monitor_db.action('DELETE FROM '
                                  'sessions '
                                  'WHERE server_id = ?', [self.CONFIG.ID])
            session_history_media_info_del = \
                monitor_db.action('DELETE FROM '
                                  'session_history_media_info '
                                  'WHERE server_id = ?', [self.CONFIG.ID])
            session_history_metadata_del = \
                monitor_db.action('DELETE FROM '
                                  'session_history_metadata '
                                  'WHERE server_id = ?', [self.CONFIG.ID])
            session_history_del = \
                monitor_db.action('DELETE FROM '
                                  'session_history '
                                  'WHERE server_id = ?', [self.CONFIG.ID])
            recently_added_del = \
                monitor_db.action('DELETE FROM '
                                  'recently_added '
                                  'WHERE server_id = ?', [self.CONFIG.ID])
            themoviedb_lookup_del = \
                monitor_db.action('DELETE FROM '
                                  'themoviedb_lookup '
                                  'WHERE server_id = ?', [self.CONFIG.ID])
            tvmaze_lookup_del = \
                monitor_db.action('DELETE FROM '
                                  'tvmaze_lookup '
                                  'WHERE server_id = ?', [self.CONFIG.ID])

            return True

        except Exception as e:
            logger.warn(
                u"Tautulli Servers :: %s: Unable to execute database query for delete_all_history: %s."
                % (self.CONFIG.PMS_NAME, e))
            return False
Exemplo n.º 32
0
def delete_sessions():
    logger.debug(
        u"Tautulli Database :: Clearing temporary sessions from database.")
    monitor_db = MonitorDatabase()

    try:
        monitor_db.action('DELETE FROM sessions')
        monitor_db.action('VACUUM')
        return True
    except Exception as e:
        logger.warn(
            u"Tautulli Database :: Unable to clear temporary sessions from database: %s."
            % e)
        return False
Exemplo n.º 33
0
    def get_token(self):
        plextv_response = self.get_plex_auth(output_format='xml')

        if plextv_response:
            xml_head = plextv_response.getElementsByTagName('user')
            if not xml_head:
                logger.warn("Error parsing XML for Plex.tv token: %s" % e)
                return []

            auth_token = xml_head[0].getAttribute('authenticationToken')

            return auth_token
        else:
            return []
Exemplo n.º 34
0
    def delete_login_log(self):
        monitor_db = database.MonitorDatabase()

        try:
            logger.info(
                u"Tautulli Users :: Clearing login logs from database.")
            monitor_db.action('DELETE FROM user_login')
            monitor_db.action('VACUUM')
            return True
        except Exception as e:
            logger.warn(
                u"Tautulli Users :: Unable to execute database query for delete_login_log: %s."
                % e)
            return False
Exemplo n.º 35
0
def set_last_seen(device_token=None):
    db = database.MonitorDatabase()

    last_seen = int(time.time())

    try:
        result = db.action(
            'UPDATE mobile_devices SET last_seen = ? WHERE device_token = ?',
            args=[last_seen, device_token])
    except Exception as e:
        logger.warn(
            u"Tautulli MobileApp :: Failed to set last_seen time for device: %s."
            % e)
        return
Exemplo n.º 36
0
    def get_user_unique_ips(self, kwargs=None, custom_where=None):
        data_tables = datatables.DataTables()

        columns = ['session_history.started as last_seen',
                   'session_history.ip_address as ip_address',
                   'COUNT(session_history.id) as play_count',
                   'session_history.player as platform',
                   'session_history_metadata.full_title as last_watched',
                   'session_history.user as user',
                   'session_history.user_id as user_id'
                   ]

        try:
            query = data_tables.ssp_query(table_name='session_history',
                                          columns=columns,
                                          custom_where=custom_where,
                                          group_by=['ip_address'],
                                          join_types=['JOIN'],
                                          join_tables=['session_history_metadata'],
                                          join_evals=[['session_history.id', 'session_history_metadata.id']],
                                          kwargs=kwargs)
        except:
            logger.warn("Unable to execute database query.")
            return {'recordsFiltered': 0,
                    'recordsTotal': 0,
                    'draw': 0,
                    'data': 'null',
                    'error': 'Unable to execute database query.'}

        results = query['result']

        rows = []
        for item in results:
            row = {"last_seen": item['last_seen'],
                   "ip_address": item['ip_address'],
                   "play_count": item['play_count'],
                   "platform": item['platform'],
                   "last_watched": item['last_watched']
                   }

            rows.append(row)

        dict = {'recordsFiltered': query['filteredCount'],
                'recordsTotal': query['totalCount'],
                'data': rows,
                'draw': query['draw']
        }

        return dict
Exemplo n.º 37
0
        def get_user_details(user_id=user_id, user=user):
            monitor_db = database.MonitorDatabase()

            try:
                if str(user_id).isdigit():
                    query = 'SELECT user_id, username, friendly_name, thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \
                            'email, is_home_user, is_allow_sync, is_restricted, do_notify, keep_history ' \
                            'FROM users ' \
                            'WHERE user_id = ? '
                    result = monitor_db.select(query, args=[user_id])
                elif user:
                    query = 'SELECT user_id, username, friendly_name, thumb AS user_thumb, custom_avatar_url AS custom_thumb, ' \
                            'email, is_home_user, is_allow_sync, is_restricted, do_notify, keep_history ' \
                            'FROM users ' \
                            'WHERE username = ? '
                    result = monitor_db.select(query, args=[user])
                else:
                    result = []
            except Exception as e:
                logger.warn(u"PlexPy Users :: Unable to execute database query for get_details: %s." % e)
                result = []

            user_details = {}
            if result:
                for item in result:
                    if item['friendly_name']:
                        friendly_name = item['friendly_name']
                    else:
                        friendly_name = item['username']

                    if item['custom_thumb'] and item['custom_thumb'] != item['user_thumb']:
                        user_thumb = item['custom_thumb']
                    elif item['user_thumb']:
                        user_thumb = item['user_thumb']
                    else:
                        user_thumb = common.DEFAULT_USER_THUMB

                    user_details = {'user_id': item['user_id'],
                                    'username': item['username'],
                                    'friendly_name': friendly_name,
                                    'user_thumb': user_thumb,
                                    'email': item['email'],
                                    'is_home_user': item['is_home_user'],
                                    'is_allow_sync': item['is_allow_sync'],
                                    'is_restricted': item['is_restricted'],
                                    'do_notify': item['do_notify'],
                                    'keep_history': item['keep_history']
                                    }
            return user_details
Exemplo n.º 38
0
    def get_watch_time_stats(self, user_id=None):
        monitor_db = database.MonitorDatabase()

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

        for days in time_queries:
            try:
                if days > 0:
                    if str(user_id).isdigit():
                        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])
                    else:
                        result = []
                else:
                    if str(user_id).isdigit():
                        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_id = ?'
                        result = monitor_db.select(query, args=[user_id])
                    else:
                        result = []
            except Exception as e:
                logger.warn(u"PlexPy Users :: Unable to execute database query for get_watch_time_stats: %s." % e)
                result = []

            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
Exemplo n.º 39
0
    def get_recently_watched(self, user_id=None, limit='10'):
        monitor_db = database.MonitorDatabase()
        recently_watched = []

        if not limit.isdigit():
            limit = '10'

        try:
            if str(user_id).isdigit():
                query = 'SELECT session_history.id, session_history.media_type, session_history.rating_key, session_history.parent_rating_key, ' \
                        'title, parent_title, grandparent_title, thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \
                        'year, started, user ' \
                        'FROM session_history_metadata ' \
                        'JOIN session_history ON session_history_metadata.id = session_history.id ' \
                        'WHERE user_id = ? ' \
                        'GROUP BY (CASE WHEN session_history.media_type = "track" THEN session_history.parent_rating_key ' \
                        '   ELSE session_history.rating_key END) ' \
                        'ORDER BY started DESC LIMIT ?'
                result = monitor_db.select(query, args=[user_id, limit])
            else:
                result = []
        except Exception as e:
            logger.warn(u"PlexPy Users :: Unable to execute database query for get_recently_watched: %s." % e)
            result = []

        for row in result:
                if row['media_type'] == 'episode' and row['parent_thumb']:
                    thumb = row['parent_thumb']
                elif row['media_type'] == 'episode':
                    thumb = row['grandparent_thumb']
                else:
                    thumb = row['thumb']

                recent_output = {'row_id': row['id'],
                                 'media_type': row['media_type'],
                                 'rating_key': row['rating_key'],
                                 'title': row['title'],
                                 'parent_title': row['parent_title'],
                                 'grandparent_title': row['grandparent_title'],
                                 'thumb': thumb,
                                 'media_index': row['media_index'],
                                 'parent_media_index': row['parent_media_index'],
                                 'year': row['year'],
                                 'time': row['started'],
                                 'user': row['user']
                                 }
                recently_watched.append(recent_output)

        return recently_watched
Exemplo n.º 40
0
    def osxnotifyregister(self, app):
        cherrypy.response.headers[
            'Cache-Control'] = "max-age=0,no-cache,no-store"
        from osxnotify import registerapp as osxnotify

        result, msg = osxnotify.registerapp(app)
        if result:
            osx_notify = notifiers.OSX_NOTIFY()
            osx_notify.notify('Registered', result, 'Success :-)')
            logger.info(
                'Registered %s, to re-register a different app, delete this app first'
                % result)
        else:
            logger.warn(msg)
        return msg
Exemplo n.º 41
0
    def get_server_identity(self):
        identity = self.get_local_server_identity(output_format='xml')

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

        server_identity = {}
        for a in xml_head:
            server_identity = {"machine_identifier": helpers.get_xml_attr(a, 'machineIdentifier'),
                               "version": helpers.get_xml_attr(a, 'version')
                               }

        return server_identity
Exemplo n.º 42
0
def add_newsletter_config(agent_id=None, **kwargs):
    if str(agent_id).isdigit():
        agent_id = int(agent_id)
    else:
        logger.error(
            u"Tautulli Newsletters :: Unable to add new newsletter: invalid agent_id %s."
            % agent_id)
        return False

    agent = next(
        (a for a in available_newsletter_agents() if a['id'] == agent_id),
        None)

    if not agent:
        logger.error(
            u"Tautulli Newsletters :: Unable to retrieve new newsletter agent: invalid agent_id %s."
            % agent_id)
        return False

    agent_class = get_agent_class(agent_id=agent['id'])

    keys = {'id': None}
    values = {
        'agent_id': agent['id'],
        'agent_name': agent['name'],
        'agent_label': agent['label'],
        'id_name': '',
        'friendly_name': '',
        'newsletter_config': json.dumps(agent_class.config),
        'email_config': json.dumps(agent_class.email_config),
        'subject': agent_class.subject,
        'body': agent_class.body,
        'message': agent_class.message
    }

    db = database.MonitorDatabase()
    try:
        db.upsert(table_name='newsletters', key_dict=keys, value_dict=values)
        newsletter_id = db.last_insert_id()
        logger.info(
            u"Tautulli Newsletters :: Added new newsletter agent: %s (newsletter_id %s)."
            % (agent['label'], newsletter_id))
        blacklist_logger()
        return newsletter_id
    except Exception as e:
        logger.warn(
            u"Tautulli Newsletters :: Unable to add newsletter agent: %s." % e)
        return False
Exemplo n.º 43
0
    def get_player_stats(self, user_id=None, grouping=None):
        if not session.allow_session_user(user_id):
            return []

        if grouping is None:
            grouping = plexpy.CONFIG.GROUP_HISTORY_TABLES

        monitor_db = database.MonitorDatabase()

        player_stats = []
        result_id = 0

        group_by = 'reference_id' if grouping else 'id'

        try:
            if str(user_id).isdigit():
                query = 'SELECT player, COUNT(DISTINCT %s) as player_count, platform ' \
                        'FROM session_history ' \
                        'WHERE user_id = ? ' \
                        'GROUP BY player ' \
                        'ORDER BY player_count DESC' % group_by
                result = monitor_db.select(query, args=[user_id])
            else:
                result = []
        except Exception as e:
            logger.warn(
                u"Tautulli Users :: Unable to execute database query for get_player_stats: %s."
                % e)
            result = []

        for item in result:
            # Rename Mystery platform names
            platform = common.PLATFORM_NAME_OVERRIDES.get(
                item['platform'], item['platform'])
            platform_name = next((v for k, v in common.PLATFORM_NAMES.items()
                                  if k in platform.lower()), 'default')

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

        return player_stats
Exemplo n.º 44
0
    def get_current_activity(self, **kwargs):

        try:
            pms_connect = pmsconnect.PmsConnect()
            result = pms_connect.get_current_activity()
        except:
            return serve_template(templatename="current_activity.html",
                                  data=None)

        if result:
            return serve_template(templatename="current_activity.html",
                                  data=result)
        else:
            return serve_template(templatename="current_activity.html",
                                  data=None)
            logger.warn('Unable to retrieve data.')
Exemplo n.º 45
0
def daemonize():
    if threading.activeCount() != 1:
        logger.warn(
            'There are %r active threads. Daemonizing may cause'
            ' strange behavior.', threading.enumerate())

    sys.stdout.flush()
    sys.stderr.flush()

    # Do first fork
    try:
        pid = os.fork()  # @UndefinedVariable - only available in UNIX
        if pid != 0:
            sys.exit(0)
    except OSError, e:
        raise RuntimeError("1st fork failed: %s [%d]", e.strerror, e.errno)
Exemplo n.º 46
0
    def delete(self, user_id=None):
        monitor_db = database.MonitorDatabase()

        try:
            if str(user_id).isdigit():
                self.delete_all_history(user_id)
                logger.info(u"PlexPy DataFactory :: Deleting user with id %s from database." % user_id)
                monitor_db.action('UPDATE users SET deleted_user = 1 WHERE user_id = ?', [user_id])
                monitor_db.action('UPDATE users SET keep_history = 0 WHERE user_id = ?', [user_id])
                monitor_db.action('UPDATE users SET do_notify = 0 WHERE user_id = ?', [user_id])

                return 'Deleted user with id %s.' % user_id
            else:
                return 'Unable to delete user, user_id not valid.'
        except Exception as e:
            logger.warn(u"PlexPy Users :: Unable to execute database query for delete: %s." % e)
Exemplo n.º 47
0
    def get_server_urls(self, include_https=True):

        if plexpy.CONFIG.PMS_IDENTIFIER:
            server_id = plexpy.CONFIG.PMS_IDENTIFIER
        else:
            logger.error('PlexPy PlexTV connector :: Unable to retrieve server identity.')
            return []

        plextv_resources = self.get_plextv_resources(include_https=include_https)
        server_urls = []

        try:
            xml_parse = minidom.parseString(plextv_resources)
        except Exception, e:
            logger.warn("Error parsing XML for Plex resources: %s" % e)
            return []
Exemplo n.º 48
0
    def undelete(self, section_id=None, section_name=None):
        monitor_db = database.MonitorDatabase()

        try:
            if section_id and section_id.isdigit():
                logger.info(
                    u"PlexPy Libraries :: Re-adding library with id %s to database."
                    % section_id)
                monitor_db.action(
                    'UPDATE library_sections SET deleted_section = 0 WHERE section_id = ?',
                    [section_id])
                monitor_db.action(
                    'UPDATE library_sections SET keep_history = 1 WHERE section_id = ?',
                    [section_id])
                monitor_db.action(
                    'UPDATE library_sections SET do_notify = 1 WHERE section_id = ?',
                    [section_id])
                monitor_db.action(
                    'UPDATE library_sections SET do_notify_created = 1 WHERE section_id = ?',
                    [section_id])

                return 'Re-added library with id %s.' % section_id
            elif section_name:
                logger.info(
                    u"PlexPy Libraries :: Re-adding library with name %s to database."
                    % section_name)
                monitor_db.action(
                    'UPDATE library_sections SET deleted_section = 0 WHERE section_name = ?',
                    [section_name])
                monitor_db.action(
                    'UPDATE library_sections SET keep_history = 1 WHERE section_name = ?',
                    [section_name])
                monitor_db.action(
                    'UPDATE library_sections SET do_notify = 1 WHERE section_name = ?',
                    [section_name])
                monitor_db.action(
                    'UPDATE library_sections SET do_notify_created = 1 WHERE section_name = ?',
                    [section_name])

                return 'Re-added library with section_name %s.' % section_name
            else:
                return 'Unable to re-add library, section_id or section_name not valid.'
        except Exception as e:
            logger.warn(
                u"PlexPy Libraries :: Unable to execute database query for undelete: %s."
                % e)
Exemplo n.º 49
0
def check_server_response():

    with monitor_lock:
        pms_connect = pmsconnect.PmsConnect()
        server_response = pms_connect.get_server_response()

        global ext_ping_count

        # Check for remote access
        if server_response:

            mapping_state = server_response['mapping_state']
            mapping_error = server_response['mapping_error']

            # Check if the port is mapped
            if not mapping_state == 'mapped':
                ext_ping_count += 1
                logger.warn(u"PlexPy Monitor :: Plex remote access port not mapped, ping attempt %s." \
                            % str(ext_ping_count))
            # Check if the port is open
            elif mapping_error == 'unreachable':
                ext_ping_count += 1
                logger.warn(u"PlexPy Monitor :: Plex remote access port mapped, but mapping failed, ping attempt %s." \
                            % str(ext_ping_count))
            # Reset external ping counter
            else:
                if ext_ping_count >= 3:
                    logger.info(
                        u"PlexPy Monitor :: Plex remote access is back up.")

                    # Check if any notification agents have notifications enabled
                    if any(d['on_extup']
                           for d in notifiers.available_notification_agents()):
                        # Fire off notifications
                        threading.Thread(
                            target=notification_handler.notify_timeline,
                            kwargs=dict(notify_action='extup')).start()
                ext_ping_count = 0

        if ext_ping_count == 3:
            # Check if any notification agents have notifications enabled
            if any(d['on_extdown']
                   for d in notifiers.available_notification_agents()):
                # Fire off notifications
                threading.Thread(target=notification_handler.notify_timeline,
                                 kwargs=dict(notify_action='extdown')).start()
Exemplo n.º 50
0
    def _getSync(self, machine_id=None, user_id=None, **kwargs):

        pms_connect = pmsconnect.PmsConnect()
        server_id = pms_connect.get_server_identity()

        plex_tv = plextv.PlexTV()
        if not machine_id:
            result = plex_tv.get_synced_items(machine_id=server_id['machine_identifier'], user_id=user_id)
        else:
            result = plex_tv.get_synced_items(machine_id=machine_id, user_id=user_id)

        if result:
            self.data = result
            return result
        else:
            self.msg = 'Unable to retrieve sync data for user'
            logger.warn('Unable to retrieve sync data for user.')
Exemplo n.º 51
0
    def process(self, opcode, data):
        if opcode not in self.opcode_data:
            return False

        try:
            logger.websocket_debug(data)
            info = json.loads(data.decode('utf-8'))
        except Exception as e:
            logger.warn(u"Tautulli WebSocket :: %s: Error decoding message from websocket: %s" % (self.server.CONFIG.PMS_NAME, e))
            logger.websocket_error(data)
            return False

        info = info.get('NotificationContainer', info)
        type = info.get('type')

        if not type:
            return False

        if type == 'playing':
            time_line = info.get('PlaySessionStateNotification', info.get('_children', {}))

            if not time_line:
                logger.debug(u"Tautulli WebSocket :: %s: Session found but unable to get timeline data." % self.server.CONFIG.PMS_NAME)
                return False

            try:
                activity = activity_handler.ActivityHandler(self.server, timeline=time_line[0])
                activity.process()
            except Exception as e:
                logger.error(u"Tautulli WebSocket :: %s: Failed to process session data: %s." % (self.server.CONFIG.PMS_NAME, e))

        if type == 'timeline':
            time_line = info.get('TimelineEntry', info.get('_children', {}))

            if not time_line:
                logger.debug(u"Tautulli WebSocket :: %s: Timeline event found but unable to get timeline data." % self.server.CONFIG.PMS_NAME)
                return False

            try:
                activity = activity_handler.TimelineHandler(self.server, timeline=time_line[0])
                activity.process()
            except Exception as e:
                logger.error(u"Tautulli WebSocket :: %s: Failed to process timeline data: %s." % (self.server.CONFIG.PMS_NAME, e))

        return True
Exemplo n.º 52
0
def checkGithub():
    plexpy.COMMITS_BEHIND = 0

    # Get the latest version available from github
    logger.info('Retrieving latest version information from GitHub')
    url = 'https://api.github.com/repos/%s/plexpy/commits/%s' % (plexpy.CONFIG.GIT_USER, plexpy.CONFIG.GIT_BRANCH)
    version = request.request_json(url, timeout=20, validator=lambda x: type(x) == dict)

    if version is None:
        logger.warn('Could not get the latest version from GitHub. Are you running a local development version?')
        return plexpy.CURRENT_VERSION

    plexpy.LATEST_VERSION = version['sha']
    logger.debug("Latest version is %s", plexpy.LATEST_VERSION)

    # See how many commits behind we are
    if not plexpy.CURRENT_VERSION:
        logger.info('You are running an unknown version of PlexPy. Run the updater to identify your version')
        return plexpy.LATEST_VERSION

    if plexpy.LATEST_VERSION == plexpy.CURRENT_VERSION:
        logger.info('PlexPy is up to date')
        return plexpy.LATEST_VERSION

    logger.info('Comparing currently installed version with latest GitHub version')
    url = 'https://api.github.com/repos/%s/plexpy/compare/%s...%s' % (plexpy.CONFIG.GIT_USER, plexpy.LATEST_VERSION, plexpy.CURRENT_VERSION)
    commits = request.request_json(url, timeout=20, whitelist_status_code=404, validator=lambda x: type(x) == dict)

    if commits is None:
        logger.warn('Could not get commits behind from GitHub.')
        return plexpy.LATEST_VERSION

    try:
        plexpy.COMMITS_BEHIND = int(commits['behind_by'])
        logger.debug("In total, %d commits behind", plexpy.COMMITS_BEHIND)
    except KeyError:
        logger.info('Cannot compare versions. Are you running a local development version?')
        plexpy.COMMITS_BEHIND = 0

    if plexpy.COMMITS_BEHIND > 0:
        logger.info('New version is available. You are %s commits behind' % plexpy.COMMITS_BEHIND)
    elif plexpy.COMMITS_BEHIND == 0:
        logger.info('PlexPy is up to date')

    return plexpy.LATEST_VERSION
Exemplo n.º 53
0
    def get_server_times(self):
        servers = self.get_plextv_server_list(output_format='xml')
        server_times = []

        try:
            xml_head = servers.getElementsByTagName('Server')
        except:
            logger.warn("Error parsing XML for Plex servers.")
            return []

        for a in xml_head:
            if helpers.get_xml_attr(a, 'machineIdentifier') == plexpy.CONFIG.PMS_IDENTIFIER:
                server_times.append({"created_at": helpers.get_xml_attr(a, 'createdAt'),
                                     "updated_at": helpers.get_xml_attr(a, 'updatedAt')
                                     })
                break

        return server_times
Exemplo n.º 54
0
    def get_plexpass_status(self):
        account_data = self.get_plextv_user_details(output_format='xml')

        try:
            subscription = account_data.getElementsByTagName('subscription')
        except Exception as e:
            logger.warn(
                u"Tautulli PlexTV :: Unable to parse XML for get_plexpass_status: %s."
                % e)
            return False

        if subscription and helpers.get_xml_attr(subscription[0],
                                                 'active') == '1':
            return True
        else:
            logger.debug(
                u"Tautulli PlexTV :: Plex Pass subscription not found.")
            return False
Exemplo n.º 55
0
    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_names = {
                'Mystery 3': 'Playstation 3',
                'Mystery 4': 'Playstation 4',
                'Mystery 5': 'Xbox 360'
            }
            platform_type = platform_names.get(item[2], item[2])

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

        return player_stats
Exemplo n.º 56
0
def process(opcode, data):
    from plexpy import activity_handler

    if opcode not in opcode_data:
        return False

    try:
        info = json.loads(data)
    except Exception as ex:
        logger.warn(
            u'PlexPy WebSocket :: Error decoding message from websocket: %s' %
            ex)
        logger.debug(data)
        return False

    type = info.get('type')

    if not type:
        return False

    if type == 'playing':
        # logger.debug('%s.playing %s' % (name, info))
        try:
            time_line = info.get('_children')
        except:
            logger.debug(
                u"PlexPy WebSocket :: Session found but unable to get timeline data."
            )
            return False

        activity = activity_handler.ActivityHandler(timeline=time_line[0])
        activity.process()

    #if type == 'timeline':
    #    try:
    #        time_line = info.get('_children')
    #    except:
    #        logger.debug(u"PlexPy WebSocket :: Timeline event found but unable to get timeline data.")
    #        return False

    #    activity = activity_handler.TimelineHandler(timeline=time_line[0])
    #    activity.process()

    return True
Exemplo n.º 57
0
        def get_library_details(section_id=section_id):
            monitor_db = database.MonitorDatabase()

            try:
                if str(section_id).isdigit():
                    query = 'SELECT section_id, section_name, section_type, count, parent_count, child_count, ' \
                            'thumb AS library_thumb, custom_thumb_url AS custom_thumb, art, ' \
                            'do_notify, do_notify_created, keep_history ' \
                            'FROM library_sections ' \
                            'WHERE section_id = ? '
                    result = monitor_db.select(query, args=[section_id])
                else:
                    result = []
            except Exception as e:
                logger.warn(
                    u"PlexPy Libraries :: Unable to execute database query for get_details: %s."
                    % e)
                result = []

            library_details = {}
            if result:
                for item in result:
                    if item['custom_thumb'] and item['custom_thumb'] != item[
                            'library_thumb']:
                        library_thumb = item['custom_thumb']
                    elif item['library_thumb']:
                        library_thumb = item['library_thumb']
                    else:
                        library_thumb = common.DEFAULT_COVER_THUMB

                    library_details = {
                        'section_id': item['section_id'],
                        'section_name': item['section_name'],
                        'section_type': item['section_type'],
                        'library_thumb': library_thumb,
                        'library_art': item['art'],
                        'count': item['count'],
                        'parent_count': item['parent_count'],
                        'child_count': item['child_count'],
                        'do_notify': item['do_notify'],
                        'do_notify_created': item['do_notify_created'],
                        'keep_history': item['keep_history']
                    }
            return library_details
Exemplo n.º 58
0
    def delete_all_users(self):
        monitor_db = database.MonitorDatabase()

        try:
            logger.info(
                u"Tautulli Servers :: %s: Deleting all user tokens from database."
                % self.CONFIG.PMS_NAME)
            user_shared_libraries_del = \
                monitor_db.action('DELETE FROM '
                                  'user_shared_libraries '
                                  'WHERE server_id = ?', [self.CONFIG.ID])

            return True

        except Exception as e:
            logger.warn(
                u"Tautulli Servers :: %s: Unable to execute database query for delete_all_users: %s."
                % (self.CONFIG.PMS_NAME, e))
            return False
Exemplo n.º 59
0
    def get_cloud_server_status(self, server):
        cloud_status = self.cloud_server_status(output_format='xml')

        try:
            status_info = cloud_status.getElementsByTagName('info')
        except Exception as e:
            logger.warn(
                u"Tautulli PlexTV :: Unable to parse XML for get_cloud_server_status: %s."
                % e)
            return False

        for info in status_info:
            servers = info.getElementsByTagName('server')
            for s in servers:
                if helpers.get_xml_attr(s, 'address') == server.CONFIG.PMS_IP:
                    if helpers.get_xml_attr(info, 'running') == '1':
                        return True
                    else:
                        return False
Exemplo n.º 60
0
    def notify(self, title, subtitle=None, text=None, sound=True, image=None):

        try:
            self.swizzle(self.objc.lookUpClass('NSBundle'),
                         b'bundleIdentifier', self.swizzled_bundleIdentifier)

            NSUserNotification = self.objc.lookUpClass('NSUserNotification')
            NSUserNotificationCenter = self.objc.lookUpClass(
                'NSUserNotificationCenter')
            NSAutoreleasePool = self.objc.lookUpClass('NSAutoreleasePool')

            if not NSUserNotification or not NSUserNotificationCenter:
                return False

            pool = NSAutoreleasePool.alloc().init()

            notification = NSUserNotification.alloc().init()
            notification.setTitle_(title)
            if subtitle:
                notification.setSubtitle_(subtitle)
            if text:
                notification.setInformativeText_(text)
            if sound:
                notification.setSoundName_(
                    "NSUserNotificationDefaultSoundName")
            if image:
                source_img = self.AppKit.NSImage.alloc(
                ).initByReferencingFile_(image)
                notification.setContentImage_(source_img)
                #notification.set_identityImage_(source_img)
            notification.setHasActionButton_(False)

            notification_center = NSUserNotificationCenter.defaultUserNotificationCenter(
            )
            notification_center.deliverNotification_(notification)

            del pool
            return True

        except Exception as e:
            logger.warn('Error sending OS X Notification: %s' % e)
            return False