示例#1
0
 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()
示例#2
0
 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
示例#3
0
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])
示例#4
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')
示例#5
0
 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)
示例#6
0
 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))
示例#7
0
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}
示例#8
0
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}
示例#9
0
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)
示例#10
0
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
示例#11
0
 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))