def import_from_plexwatch(database=None, table_name=None, import_ignore_interval=0): try: connection = sqlite3.connect(database, timeout=20) connection.row_factory = sqlite3.Row except sqlite3.OperationalError: logger.error(u"Tautulli Importer :: Invalid filename.") return None except ValueError: logger.error(u"Tautulli Importer :: Invalid filename.") return None try: connection.execute('SELECT ratingKey from %s' % table_name) except sqlite3.OperationalError: logger.error( u"Tautulli Importer :: Database specified does not contain the required fields." ) return None logger.debug(u"Tautulli Importer :: PlexWatch data import in progress...") ap = activity_processor.ActivityProcessor() user_data = users.Users() # Get the latest friends list so we can pull user id's try: users.refresh_users() except: logger.debug( u"Tautulli Importer :: Unable to refresh the users list. Aborting import." ) return None query = 'SELECT time AS started, ' \ 'stopped, ' \ 'cast(ratingKey as text) AS rating_key, ' \ 'null AS user_id, ' \ 'user, ' \ 'ip_address, ' \ 'paused_counter, ' \ 'platform AS player, ' \ 'null AS platform, ' \ 'null as machine_id, ' \ 'parentRatingKey as parent_rating_key, ' \ 'grandparentRatingKey as grandparent_rating_key, ' \ 'null AS media_type, ' \ 'null AS view_offset, ' \ 'xml, ' \ 'rating as content_rating,' \ 'summary,' \ 'title AS full_title,' \ '(case when orig_title_ep = "" then orig_title else ' \ 'orig_title_ep end) as title,' \ '(case when orig_title_ep != "" then orig_title else ' \ 'null end) as grandparent_title ' \ 'FROM ' + table_name + ' ORDER BY id' result = connection.execute(query) for row in result: # Extract the xml from the Plexwatch db xml field. extracted_xml = extract_plexwatch_xml(row['xml']) # If we get back None from our xml extractor skip over the record and log error. if not extracted_xml: logger.error( u"Tautulli Importer :: Skipping record with ratingKey %s due to malformed xml." % str(row['rating_key'])) continue # Skip line if we don't have a ratingKey to work with if not row['rating_key']: logger.error( u"Tautulli Importer :: Skipping record due to null ratingKey.") continue # If the user_id no longer exists in the friends list, pull it from the xml. if user_data.get_user_id(user=row['user']): user_id = user_data.get_user_id(user=row['user']) else: user_id = extracted_xml['user_id'] session_history = { 'started': row['started'], 'stopped': row['stopped'], 'rating_key': row['rating_key'], 'title': row['title'], 'parent_title': extracted_xml['parent_title'], 'grandparent_title': row['grandparent_title'], 'original_title': extracted_xml['original_title'], 'full_title': row['full_title'], 'user_id': user_id, 'user': row['user'], 'ip_address': row['ip_address'] if row['ip_address'] else extracted_xml['ip_address'], 'paused_counter': row['paused_counter'], 'player': row['player'], 'platform': extracted_xml['platform'], 'machine_id': extracted_xml['machine_id'], 'parent_rating_key': row['parent_rating_key'], 'grandparent_rating_key': row['grandparent_rating_key'], 'media_type': extracted_xml['media_type'], 'view_offset': extracted_xml['view_offset'], 'video_decision': extracted_xml['video_decision'], 'audio_decision': extracted_xml['audio_decision'], 'transcode_decision': extracted_xml['transcode_decision'], 'duration': extracted_xml['duration'], 'width': extracted_xml['width'], 'height': extracted_xml['height'], 'container': extracted_xml['container'], 'video_codec': extracted_xml['video_codec'], 'audio_codec': extracted_xml['audio_codec'], 'bitrate': extracted_xml['bitrate'], 'video_resolution': extracted_xml['video_resolution'], 'video_framerate': extracted_xml['video_framerate'], 'aspect_ratio': extracted_xml['aspect_ratio'], 'audio_channels': extracted_xml['audio_channels'], 'transcode_protocol': extracted_xml['transcode_protocol'], 'transcode_container': extracted_xml['transcode_container'], 'transcode_video_codec': extracted_xml['transcode_video_codec'], 'transcode_audio_codec': extracted_xml['transcode_audio_codec'], 'transcode_audio_channels': extracted_xml['transcode_audio_channels'], 'transcode_width': extracted_xml['transcode_width'], 'transcode_height': extracted_xml['transcode_height'] } session_history_metadata = { 'rating_key': helpers.latinToAscii(row['rating_key']), 'parent_rating_key': row['parent_rating_key'], 'grandparent_rating_key': row['grandparent_rating_key'], 'title': row['title'], 'parent_title': extracted_xml['parent_title'], 'grandparent_title': row['grandparent_title'], 'original_title': extracted_xml['original_title'], 'media_index': extracted_xml['media_index'], 'parent_media_index': extracted_xml['parent_media_index'], 'thumb': extracted_xml['thumb'], 'parent_thumb': extracted_xml['parent_thumb'], 'grandparent_thumb': extracted_xml['grandparent_thumb'], 'art': extracted_xml['art'], 'media_type': extracted_xml['media_type'], 'year': extracted_xml['year'], 'originally_available_at': extracted_xml['originally_available_at'], 'added_at': extracted_xml['added_at'], 'updated_at': extracted_xml['updated_at'], 'last_viewed_at': extracted_xml['last_viewed_at'], 'content_rating': row['content_rating'], 'summary': row['summary'], 'tagline': extracted_xml['tagline'], 'rating': extracted_xml['rating'], 'duration': extracted_xml['duration'], 'guid': extracted_xml['guid'], 'section_id': extracted_xml['section_id'], 'directors': extracted_xml['directors'], 'writers': extracted_xml['writers'], 'actors': extracted_xml['actors'], 'genres': extracted_xml['genres'], 'studio': extracted_xml['studio'], 'labels': extracted_xml['labels'], 'full_title': row['full_title'], 'width': extracted_xml['width'], 'height': extracted_xml['height'], 'container': extracted_xml['container'], 'video_codec': extracted_xml['video_codec'], 'audio_codec': extracted_xml['audio_codec'], 'bitrate': extracted_xml['bitrate'], 'video_resolution': extracted_xml['video_resolution'], 'video_framerate': extracted_xml['video_framerate'], 'aspect_ratio': extracted_xml['aspect_ratio'], 'audio_channels': extracted_xml['audio_channels'] } # On older versions of PMS, "clip" items were still classified as "movie" and had bad ratingKey values # Just make sure that the ratingKey is indeed an integer if session_history_metadata['rating_key'].isdigit(): ap.write_session_history( session=session_history, import_metadata=session_history_metadata, is_import=True, import_ignore_interval=import_ignore_interval) else: logger.debug(u"Tautulli Importer :: Item has bad rating_key: %s" % session_history_metadata['rating_key']) logger.debug(u"Tautulli Importer :: PlexWatch data import complete.") import_users()
def plex_user_login(username=None, password=None, token=None, headers=None): user_token = None user_id = None # Try to login to Plex.tv to check if the user has a vaild account if username and password: plex_tv = PlexTV(username=username, password=password, headers=headers) plex_user = plex_tv.get_token() if plex_user: user_token = plex_user['auth_token'] user_id = plex_user['user_id'] elif token: plex_tv = PlexTV(token=token, headers=headers) plex_user = plex_tv.get_plex_account_details() if plex_user: user_token = token user_id = plex_user['user_id'] else: return None if user_token and user_id: # Try to retrieve the user from the database. # Also make sure guest access is enabled for the user and the user is not deleted. user_data = Users() user_details = user_data.get_details(user_id=user_id) if user_id != str(user_details['user_id']): # The user is not in the database. return None elif plexpy.CONFIG.HTTP_PLEX_ADMIN and user_details['is_admin']: # Plex admin login return user_details, 'admin' elif not user_details['allow_guest'] or user_details['deleted_user']: # Guest access is disabled or the user is deleted. return None # Stop here if guest access is not enabled if not plexpy.CONFIG.ALLOW_GUEST_ACCESS: return None # The user is in the database, and guest access is enabled, so try to retrieve a server token. # If a server token is returned, then the user is a valid friend of the server. plex_tv = PlexTV(token=user_token, headers=headers) server_token = plex_tv.get_server_token() if server_token: # Register the new user / update the access tokens. monitor_db = MonitorDatabase() try: logger.debug( u"Tautulli WebAuth :: Registering token for user '%s' in the database." % user_details['username']) result = monitor_db.action( 'UPDATE users SET server_token = ? WHERE user_id = ?', [server_token, user_details['user_id']]) if result: # Refresh the users list to make sure we have all the correct permissions. refresh_users() # Successful login return user_details, 'guest' else: logger.warn( u"Tautulli WebAuth :: Unable to register user '%s' in database." % user_details['username']) return None except Exception as e: logger.warn( u"Tautulli WebAuth :: Unable to register user '%s' in database: %s." % (user_details['username'], e)) return None else: logger.warn( u"Tautulli WebAuth :: Unable to retrieve Plex.tv server token for user '%s'." % user_details['username']) return None elif username: logger.warn( u"Tautulli WebAuth :: Unable to retrieve Plex.tv user token for user '%s'." % username) return None elif token: logger.warn( u"Tautulli WebAuth :: Unable to retrieve Plex.tv user token for Plex OAuth." ) return None
def refresh_users(self): result = users.refresh_users() return result