def run(cls): metadata = {} # Retrieve names of test functions names = [ name for name in dir(cls) if name.startswith('test_') ] if not names: return cls.on_failure('No tests defined') # Run tests for name in names: # Retrieve function by name func = getattr(cls, name, None) if not func: return cls.on_failure('Unable to find function: %r' % name) try: # Run test function result = func() if not result: continue # Merge function result into `metadata` merge(metadata, result, recursive=True) except Exception, ex: return cls.on_exception('Exception raised in %r: %s' % (name, ex))
def build_failure(cls, message, **kwargs): result = {'success': False, 'message': message} # Merge extra attributes merge(result, kwargs) return result
def run(cls, search_paths): metadata = {} message = None success = None # Retrieve names of test functions names = [name for name in dir(cls) if name.startswith('test_')] if not names: return cls.build_failure('No tests defined') # Run tests for name in names: # Ensure function exists if not hasattr(cls, name): return cls.build_failure('Unable to find function: %r' % name) # Run test try: result = cls.spawn(name, search_paths) # Merge test result into `metadata` merge(metadata, result, recursive=True) # Test successful message = None success = True except Exception, ex: if success: continue message = ex.message success = False
def to_dict(self, obj, info, fetch=False): view_offset = to_integer(info.get('time')) rating_key = info.get('ratingKey') result = { 'view_offset': view_offset, 'updated_at': datetime.utcnow() } if not fetch: # Return simple update return merge(result, { 'progress': self.get_progress(obj.duration, view_offset) }) # Retrieve session # Retrieve metadata and guid p_metadata, guid = self.get_metadata(rating_key) if not p_metadata: log.warn('Unable to retrieve metadata for rating_key %r', rating_key) return result if not guid or not guid.valid: return merge(result, { 'duration': p_metadata.duration, 'progress': self.get_progress(p_metadata.duration, view_offset) }) try: # Create/Retrieve `Client` for session result['client'] = ClientManager.get.or_create({ 'key': info.get('machineIdentifier'), 'title': info.get('client') }, fetch=True) # Create/Retrieve `User` for session result['user'] = UserManager.get.or_create({ 'key': to_integer(info.get('user_id')), 'title': info.get('user_name') }, fetch=True) # Pick account from `client` or `user` objects result['account'] = self.get_account(result) except FilteredException: log.debug('Activity has been filtered') result['client'] = None result['user'] = None result['account'] = None return merge(result, { 'duration': p_metadata.duration, 'progress': self.get_progress(p_metadata.duration, view_offset) })
def on_failure(cls, message, **kwargs): result = { 'success': False, 'message': message } # Merge extra attributes merge(result, kwargs) return result
def run(cls, search_paths): metadata = {} message = None success = None # Retrieve names of test functions names = [ name for name in dir(cls) if name.startswith('test_') ] if not names: return cls.build_failure('No tests defined') # Run tests for name in names: # Ensure function exists if not hasattr(cls, name): return cls.build_failure('Unable to find function: %r' % name) # Run test try: result = cls.spawn(name, search_paths) # Merge test result into `metadata` merge(metadata, result, recursive=True) # Test successful message = None success = True except Exception as ex: if success: continue message = ex.message success = False if not success: # Trigger event cls.on_failure(message) # Build result return cls.build_failure(message) # Trigger event cls.on_success(metadata) # Build result return cls.build_success(metadata)
def fetch(result, player): # Fetch client details client = Plex.clients().get(player['key']) if not client: log.info('Unable to find client with key %r', player['key']) return result, None # Merge client details from plex API result = merge(result, dict([ (key, getattr(client, key)) for key in [ 'device_class', 'product', 'version', 'host', 'address', 'port', 'protocol', 'protocol_capabilities', 'protocol_version' ] if getattr(client, key) ])) return result, client
def build_request(cls, session, part=None, rating_key=None, view_offset=None): # Retrieve metadata for session if part is None: part = session.part if rating_key is None: rating_key = session.rating_key # Retrieve metadata metadata = Metadata.get(rating_key) # Validate metadata if not metadata: log.warn('Unable to retrieve metadata for rating_key %r', rating_key) return None if metadata.type not in ['movie', 'episode']: log.info('Ignoring session with type %r for rating_key %r', metadata.type, rating_key) return None # Apply library/section filter if not Filters.is_valid_metadata_section(metadata): log.info('Ignoring session in filtered section: %r', metadata.section.title) return None # Parse guid guid = Guid.parse(metadata.guid, strict=True) if not guid or not guid.valid: log_unsupported_guid(log, guid) return None # Build request from guid/metadata if type(metadata) is Movie: result = cls.build_movie(metadata, guid, part) elif type(metadata) is Episode: result = cls.build_episode(metadata, guid, part) else: log.warn('Unknown metadata type: %r', type(metadata)) return None if not result: log.info('Unable to build request for session: %r', session) return None # Retrieve media progress if view_offset is not None: # Calculate progress from `view_offset` parameter progress = UpdateSession.get_progress( metadata.duration, view_offset, part, session.part_count, session.part_duration ) else: # Use session progress progress = session.progress # Merge progress into request return merge(result, { 'progress': progress })
def test(): """Test native libraries to ensure they can be correctly loaded""" log.info('Testing native library support...') metadata = {} for test in LIBRARY_TESTS: # Run tests result = test.run() if not result.get('success'): # Write message to logfile log.error('%s: unavailable - %s', test.name, result.get('message'), exc_info=result.get('exc_info')) if not test.optional: return continue # Test successful t_metadata = result.get('metadata') or {} t_versions = t_metadata.get('versions') if t_versions: if len(t_versions) > 1: log.info('%s: available (%s)', test.name, ', '.join([ '%s: %s' % (key, value) for key, value in t_versions.items() ])) else: key = t_versions.keys()[0] log.info('%s: available (%s)', test.name, t_versions[key]) else: log.info('%s: available', test.name) # Merge result into `metadata` merge(metadata, t_metadata, recursive=True) # Include versions in error reports versions = metadata.get('versions') or {} RAVEN.tags.update(dict([ ('%s.version' % key, value) for key, value in versions.items() ]))
def build_request(cls, session, rating_key=None, view_offset=None): # Retrieve metadata for session if rating_key is None: rating_key = session.rating_key # Retrieve metadata metadata = Metadata.get(rating_key) # Queue a flush for the metadata cache Metadata.cache.flush_queue() # Validate metadata if not metadata: log.warn('Unable to retrieve metadata for rating_key %r', rating_key) return None if metadata.type not in ['movie', 'episode']: log.info('Ignoring session with type %r for rating_key %r', metadata.type, rating_key) return None # Apply library/section filter if not Filters.is_valid_metadata_section(metadata): return None # Parse guid guid = Guid.parse(metadata.guid) # Build request from guid/metadata if type(metadata) is Movie: result = cls.build_movie(metadata, guid) elif type(metadata) is Episode: result = cls.build_episode(metadata, guid) else: return None if not result: return None # Retrieve media progress if view_offset is not None: # Calculate progress from `view_offset` parameter progress = UpdateSession.get_progress(metadata.duration, view_offset) else: # Use session progress progress = session.progress # Merge progress into request return merge(result, {'progress': progress})
def build_request(cls, session, rating_key=None, view_offset=None): # Retrieve metadata for session if rating_key is None: rating_key = session.rating_key # Retrieve metadata metadata = Metadata.get(rating_key) # Queue a flush for the metadata cache Metadata.cache.flush_queue() # Validate metadata if not metadata: log.warn('Unable to retrieve metadata for rating_key %r', rating_key) return None if metadata.type not in ['movie', 'episode']: log.info('Ignoring session with type %r for rating_key %r', metadata.type, rating_key) return None # Apply library/section filter if not Filters.is_valid_metadata_section(metadata): return None # Parse guid guid = Guid.parse(metadata.guid) # Build request from guid/metadata if type(metadata) is Movie: result = cls.build_movie(metadata, guid) elif type(metadata) is Episode: result = cls.build_episode(metadata, guid) else: return None if not result: return None # Retrieve media progress if view_offset is not None: # Calculate progress from `view_offset` parameter progress = UpdateSession.get_progress(metadata.duration, view_offset) else: # Use session progress progress = session.progress # Merge progress into request return merge(result, { 'progress': progress })
'raven.processors.RemoveStackLocalsProcessor', 'plugin.raven.processors.RelativePathProcessor' ], 'exclude_paths': [ 'Framework.api', 'Framework.code', 'Framework.components', 'Framework.core', 'urllib2' ], # Plugin + System details 'release': PLUGIN_VERSION, 'tags': merge(SystemHelper.attributes(), { 'plugin.version': VERSION, 'plugin.branch': PLUGIN_VERSION_BRANCH }) } # Configure raven breadcrumbs breadcrumbs.ignore_logger('plugin.core.logger.handlers.error_reporter.ErrorReporter') breadcrumbs.ignore_logger('peewee') class ErrorReporter(Client): server = 'sentry.skipthe.net' key = 'c0cb82d902b4468cabb01239c22a5642:773fc0ca417b4b1cb29b9b7f75eaadd9' project = 1 def __init__(self, dsn=None, raise_send_errors=False, **options): # Build URI
def build_request(cls, session, part=None, rating_key=None, view_offset=None): # Retrieve metadata for session if part is None: part = session.part if rating_key is None: rating_key = session.rating_key # Retrieve metadata metadata = Metadata.get(rating_key) # Validate metadata if not metadata: log.warn('Unable to retrieve metadata for rating_key %r', rating_key) return None if metadata.type not in ['movie', 'episode']: log.info('Ignoring session with type %r for rating_key %r', metadata.type, rating_key) return None # Apply library/section filter if not Filters.is_valid_metadata_section(metadata): log.info('Ignoring session in filtered section: %r', metadata.section.title) return None # Parse guid guid = Guid.parse(metadata.guid, strict=True) if not guid or not guid.valid: log_unsupported_guid(log, guid) return None # Build request from guid/metadata if type(metadata) is Movie: result = cls.build_movie(metadata, guid, part) elif type(metadata) is Episode: result = cls.build_episode(metadata, guid, part) else: log.warn('Unknown metadata type: %r', type(metadata)) return None if not result: log.info('Unable to build request for session: %r', session) return None # Retrieve media progress if view_offset is not None: # Calculate progress from `view_offset` parameter progress = UpdateSession.get_progress(metadata.duration, view_offset, part, session.part_count, session.part_duration) else: # Use session progress progress = session.progress # Merge progress into request return merge(result, {'progress': progress})
def test(): """Test native libraries to ensure they can be correctly loaded""" log.info('Testing native library support...') # Retrieve library directories search_paths = [] for path in sys.path: path_lower = path.lower() if 'trakttv.bundle' not in path_lower and 'com.plexapp.plugins.trakttv' not in path_lower: continue search_paths.append(path) # Run library tests metadata = {} for test in LIBRARY_TESTS: # Run tests result = test.run(search_paths) if not result.get('success'): log_func = logging.warn if test.optional else logging.error # Write message to logfile if 'traceback' in result: log_func('%s: unavailable - %s\n%%s' % (test.name, result.get('message')), result['traceback']) else: log_func('%s: unavailable - %s' % (test.name, result.get('message')), exc_info=result.get('exc_info')) if not test.optional: return continue # Test successful t_metadata = result.get('metadata') or {} t_versions = t_metadata.get('versions') if t_versions: expanded = len(t_versions) > 1 or ( t_versions and t_versions.keys()[0] != test.name ) if expanded: log.info('%s: available (%s)', test.name, ', '.join([ '%s: %s' % (key, value) for key, value in t_versions.items() ])) else: key = t_versions.keys()[0] log.info('%s: available (%s)', test.name, t_versions[key]) else: log.info('%s: available', test.name) # Merge result into `metadata` merge(metadata, t_metadata, recursive=True) # Include versions in error reports versions = metadata.get('versions') or {}
], 'exclude_paths': [ 'Framework.api', 'Framework.code', 'Framework.components', 'Framework.core', 'urllib2' ], # Release details 'release': PLUGIN_VERSION, 'environment': ENVIRONMENTS.get(PLUGIN_VERSION_BRANCH, 'development'), # Tags 'tags': merge(SystemHelper.attributes(), { 'plugin.version': VERSION, 'plugin.branch': PLUGIN_VERSION_BRANCH }) } # Configure raven breadcrumbs breadcrumbs.ignore_logger( 'plugin.core.logger.handlers.error_reporter.ErrorReporter') breadcrumbs.ignore_logger('peewee') class ErrorReporterClient(Client): server = 'sentry.skipthe.net' def __init__(self, project, key, raise_send_errors=False, **kwargs): self.project = project self.key = key
def to_dict(self, obj, info, fetch=False): fetch = resolve(fetch, obj, info) view_offset = to_integer(info.get('viewOffset')) result = { 'rating_key': to_integer(info.get('ratingKey')), 'view_offset': view_offset, 'updated_at': datetime.utcnow() } if not fetch: # Return simple update return merge( result, {'progress': self.get_progress(obj.duration, view_offset)}) # Retrieve session key session_key = to_integer(info.get('sessionKey')) if not session_key: log.info('Missing session key, unable to fetch session details') return result # Retrieve active sessions log.debug('Fetching details for session #%s', session_key) p_sessions = Plex['status'].sessions() if not p_sessions: log.info('Unable to retrieve active sessions') return result # Find session matching `session_key` p_item = p_sessions.get(session_key) if not p_item: log.info('Unable to find session with key %r', session_key) return result # Retrieve metadata and guid p_metadata, guid = self.get_metadata(p_item.rating_key) if not p_metadata: log.info('Unable to retrieve metadata for rating_key %r', p_item.rating_key) return result if not guid: return merge( result, { 'duration': p_metadata.duration, 'progress': self.get_progress(p_metadata.duration, view_offset) }) try: # Create/Retrieve `Client` for session result['client'] = ClientManager.get.or_create( p_item.session.player, fetch=True, match=True, filtered_exception=True) # Create/Retrieve `User` for session result['user'] = UserManager.get.or_create(p_item.session.user, fetch=True, match=True, filtered_exception=True) # Pick account from `client` or `user` objects result['account'] = self.get_account(result) except FilteredException: log.debug('Activity has been filtered') result['client'] = None result['user'] = None result['account'] = None return merge( result, { 'duration': p_metadata.duration, 'progress': self.get_progress(p_metadata.duration, view_offset) })
def test(): """Test native libraries to ensure they can be correctly loaded""" log.info('Testing native library support...') # Retrieve library directories search_paths = [] for path in sys.path: path_lower = path.lower() if 'trakttv.bundle' not in path_lower and 'com.plexapp.plugins.trakttv' not in path_lower: continue search_paths.append(path) # Run library tests metadata = {} for test in LIBRARY_TESTS: # Run tests result = test.run(search_paths) if not result.get('success'): log_func = logging.warn if test.optional else logging.error # Write message to logfile if 'traceback' in result: log_func( '%s: unavailable - %s\n%%s' % (test.name, result.get('message')), result['traceback']) else: log_func('%s: unavailable - %s' % (test.name, result.get('message')), exc_info=result.get('exc_info')) if not test.optional: return continue # Test successful t_metadata = result.get('metadata') or {} t_versions = t_metadata.get('versions') if t_versions: expanded = len(t_versions) > 1 or ( t_versions and t_versions.keys()[0] != test.name) if expanded: log.info( '%s: available (%s)', test.name, ', '.join([ '%s: %s' % (key, value) for key, value in t_versions.items() ])) else: key = t_versions.keys()[0] log.info('%s: available (%s)', test.name, t_versions[key]) else: log.info('%s: available', test.name) # Merge result into `metadata` merge(metadata, t_metadata, recursive=True) # Include versions in error reports versions = metadata.get('versions') or {} RAVEN.tags.update( dict([('%s.version' % key, value) for key, value in versions.items()]))
def to_dict(self, obj, info, fetch=False): fetch = resolve(fetch, obj, info) view_offset = to_integer(info.get('viewOffset')) result = { 'rating_key': to_integer(info.get('ratingKey')), 'view_offset': view_offset, 'updated_at': datetime.utcnow() } if not fetch: # Return simple update return merge(result, { 'progress': self.get_progress( obj.duration, view_offset, obj.part, obj.part_count, obj.part_duration ) }) # Retrieve session key session_key = to_integer(info.get('sessionKey')) if not session_key: log.info('Missing session key, unable to fetch session details') return result # Retrieve active sessions log.debug('Fetching details for session #%s', session_key) p_sessions = Plex['status'].sessions() if not p_sessions: log.info('Unable to retrieve active sessions') return result # Find session matching `session_key` p_item = p_sessions.get(session_key) if not p_item: log.info('Unable to find session with key %r', session_key) return result # Retrieve metadata and guid p_metadata, guid = self.get_metadata(p_item.rating_key) if not p_metadata: log.info('Unable to retrieve metadata for rating_key %r', p_item.rating_key) return result if not guid or not guid.valid: return merge(result, { 'duration': p_metadata.duration, 'progress': self.get_progress(p_metadata.duration, view_offset) }) # Retrieve media parts part, part_count, part_duration = self.match_parts(p_metadata, guid, view_offset) log.debug('Part: %s (part_count: %s, part_duration: %s)', part, part_count, part_duration) # Find matching client + user for session try: # Create/Retrieve `Client` for session result['client'] = ClientManager.get.or_create( p_item.session.player, fetch=True, match=True, filtered_exception=True ) # Create/Retrieve `User` for session result['user'] = UserManager.get.or_create( p_item.session.user, fetch=True, match=True, filtered_exception=True ) # Pick account from `client` or `user` objects result['account'] = self.get_account(result) except FilteredException: log.debug('Activity has been filtered') result['client'] = None result['user'] = None result['account'] = None return merge(result, { 'part': part, 'part_count': part_count, 'part_duration': part_duration, 'duration': p_metadata.duration, 'progress': self.get_progress( p_metadata.duration, view_offset, part, part_count, part_duration ) })