def validate(self, secret): result = models.Challenge.validate(self.client, self.identifier, secret) if result == models.Challenge.SUCCESS: return True elif result == models.Challenge.INVALID_SECRET: raise errors.InvalidArgument('An invalid secret was provided') elif result == models.Challenge.TOO_MANY_ATTEMPTS: raise errors.ResourceNotFound('Too many attempts') elif result == models.Challenge.EXPIRED: raise errors.ResourceNotFound('Challenge has expired') # Unexpected result. raise errors.ServerError()
def join_service_content(self, service_content_id, autocreate=True, **kwargs): # Variable name should stay "service_content_id" to prevent duplicate in kwargs. try: service, team, resource = identifiers.parse_service( service_content_id) content_id = identifiers.build_service(service, team, resource) except: raise errors.InvalidArgument('Invalid service identifier') q = models.Stream.query(models.Stream.service_content_id == content_id) stream = q.get() if not stream: if not autocreate: raise errors.ResourceNotFound('Cannot join that stream') handler = self.get_or_create([], service_content_id=content_id, **kwargs) logging.debug('Created stream for %s (%r)', content_id, handler.title) return handler handler = Stream(stream).join(self.account, do_not_bump=True) if 'title' in kwargs and handler.title != kwargs['title']: handler.set_title(kwargs['title']) if not handler.visible: handler.show() logging.debug('Joined stream for %s (%r)', content_id, handler.title) members = kwargs.get('service_members') if members and set(handler.service_members) != set(members): handler._stream.service_members = members handler._stream.put() logging.debug('Updated member list of %s (%r)', content_id, handler.title) return handler
def get_video_async(video_id, snippet=True, statistics=False): if not (snippet or statistics): raise errors.InvalidArgument( 'Specify at least one of snippet, statistics') parts = [] if snippet: parts.append('snippet') if statistics: parts.append('statistics') try: qs = urllib.urlencode({ 'id': video_id, 'key': config.YOUTUBE_API_KEY, 'part': ','.join(parts), }) result = yield _fetch_async( 'https://www.googleapis.com/youtube/v3/videos?%s' % (qs, ), follow_redirects=False, deadline=10) data = json.loads(result.content) except Exception as e: logging.exception('YouTube call failed.') raise errors.ServerError() if result.status_code == 404: raise errors.ResourceNotFound('That video does not exist') elif result.status_code != 200: logging.debug('Could not get YouTube video (%d): %r', result.status_code, data) raise errors.InvalidArgument('Invalid video id') if data['pageInfo']['totalResults'] == 0: raise ndb.Return(None) if not data['items']: logging.warning('Expected at least one item in data: %r', data) raise ndb.Return(None) raise ndb.Return(data['items'][0])
def get_handler(identifier): """Returns an account handler for the given identifier.""" if isinstance(identifier, AccountHandler): # Assume that account handlers have already been resolved before. return identifier # Parse and normalize the identifier. identifier_type = 'unknown' if isinstance(identifier, basestring): identifier, identifier_type = identifiers.parse(identifier) # Attempt to find a Roger account for the provided identifier. account = models.Account.resolve(identifier) if account: # First check if there is a static handler for the account. for identity in account.identifiers: cls = _static_handlers.get(identity.id()) if cls: return cls.handler # Support custom handlers for specific statuses. if account.status in _status_handlers: return _status_handlers[account.status](account) # No special handling for this account. return AccountHandler(account) # Finally check if the identifier has a static handler. if identifier in _static_handlers: # Use a static handler for this identifier. return _static_handlers[identifier].handler # Give up. logging.info('Could not get a handler for "%s" (%s)', identifier, identifier_type) raise errors.ResourceNotFound('That account does not exist')
def get_by_id(self, stream_id, all_chunks=False, **kwargs): try: if all_chunks: stream, chunks = models.Stream.get_by_id_with_chunks( int(stream_id)) else: stream = models.Stream.get_by_id(int(stream_id)) chunks = None except (TypeError, ValueError): raise errors.InvalidArgument('Invalid stream id') if not stream: raise errors.ResourceNotFound('That stream does not exist') return MutableStream(self.account, stream, chunks=chunks, **kwargs)
def get_recent_messages_async(self, thread_id, cursor=None, limit=50): key = ndb.Key('Thread', thread_id) q = models.ThreadMessage.query(ancestor=key) q = q.order(-models.ThreadMessage.created) q_future = q.fetch_page_async(limit, start_cursor=cursor) thread, (messages, next_cursor, more) = yield key.get_async(), q_future if not more: next_cursor = None if not thread or not any(self.account_key == a.account for a in thread.accounts): raise errors.ResourceNotFound('Thread not found') raise ndb.Return((ThreadWithAccount(self.account_key, thread), messages, next_cursor))
def post_transcode_complete(): try: content_id = int(flask_extras.get_parameter('content_id')) except: raise errors.InvalidArgument('Invalid content_id parameter') stream_url = flask_extras.get_parameter('stream_url') if not stream_url: raise errors.InvalidArgument('Invalid stream_url parameter') content = models.Content.get_by_id(content_id) if not content: raise errors.ResourceNotFound('Content not found') if not content.metadata: content.metadata = {} content.metadata['raw_video_url'] = content.video_url content.video_url = stream_url content.put() return {'success': True}
def post_chunk_played(): # Only internal websites can use this endpoint. try: payload = security.decrypt(config.WEB_ENCRYPTION_KEY, flask_extras.get_parameter('payload'), block_segments=True) data = json.loads(payload) fingerprint = data['fingerprint'] stream_key = ndb.Key('Stream', data['stream_id']) chunk_key = ndb.Key('Chunk', data['chunk_id'], parent=stream_key) except: raise errors.InvalidArgument('Invalid payload') cache_key = 'external_plays:%d:%d:%s' % (stream_key.id(), chunk_key.id(), fingerprint) if memcache.get(cache_key): logging.debug( 'Repeat chunk play for fingerprint %s (stream %d chunk %d)', fingerprint, stream_key.id(), chunk_key.id()) return {'success': True} memcache.set(cache_key, True, 172800) stream, chunk = ndb.get_multi([stream_key, chunk_key]) if not stream or not chunk: raise errors.ResourceNotFound('That chunk does not exist') chunk.external_plays += 1 chunk.put() for local_chunk in stream.chunks: if local_chunk.chunk_id == chunk.key.id(): local_chunk.external_plays = chunk.external_plays stream.put() break logging.debug('New chunk play for fingerprint %s (stream %d chunk %d)', fingerprint, stream_key.id(), chunk_key.id()) logging.debug('Total external chunk plays is now %d', chunk.external_plays) handler = streams.MutableStream(chunk.sender, stream) if chunk.external_plays == 1: handler.notify_first_play(chunk) handler.notify(notifs.ON_STREAM_CHUNK_EXTERNAL_PLAY, add_stream=True, chunk=chunk) return {'success': True}
def get_by_invite_token(invite_token, *args, **kwargs): stream = models.Stream.query( models.Stream.invite_token == invite_token).get() if not stream: raise errors.ResourceNotFound('Invalid invite token') return Stream(stream)
def get_account(identifier): """Utility function for getting an Account instance.""" account = models.Account.resolve(identifier) if not account: raise errors.ResourceNotFound('That account does not exist') return account
def get_by_id_async(self, thread_id): thread = yield models.Thread.get_by_id_async(thread_id) if not thread: raise errors.ResourceNotFound('Thread not found') raise ndb.Return(ThreadWithAccount(self.account_key, thread))