def userkeys(cls, slug, username): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} # !!! Move this into the user model user_path = join(cls.datapath, slug, username) if not exists(user_path): response.status_int = 404 return {'ok': False, 'msg': 'User does not exist: %s' % slug} userdata = UserData(user=get_user(username), game=game) if userdata is None: response.status_int = 400 return {'ok': False, 'msg': 'No session with that ID exists'} data_list = userdata.get_keys() userdata = { } for i in data_list: file_path = join(cls.datapath, slug, username, i) + '.txt' f = _File(i, file_path, username, file_path) userdata[f.name] = { 'assetName': f.name, 'isJson': f.is_json(), 'size': f.get_size() } return { 'ok': True, 'data': userdata }
def check(cls, slug): # get game game = get_game_by_slug(slug) if game is None: response.status_int = 404 return {'ok': False, 'msg': 'No game with that slug.'} try: game.load() except GameError: response.status_int = 405 return {'ok': False, 'msg': 'Can\'t deploy a temporary game.'} # check if game is deployable complete, issues = game.check_completeness() if not complete: response.status_int = 400 return {'ok': False, 'msg': issues} issues, critical = game.validate_yaml() if not issues: return {'ok': True, 'msg': ''} elif critical: response.status_int = 400 return {'ok': False, 'msg': issues}
def badges_list(cls, slug): try: game = get_game_by_slug(slug) if game is None: raise ApiException('No game with that slug') badges = Badges.get_singleton(game).badges # Patch any unset total values in the response (to be consistent with the hub and game site) for badge in badges: if 'total' not in badge: badge['total'] = None if 'predescription' not in badge: badge['predescription'] = None return {'ok': True, 'data': badges} except BadgesUnsupportedException: return {'ok': False, 'data': []} except ApiException as message: response.status_int = 404 return {'ok': False, 'msg': str(message)} except ScannerError as message: response.status_int = 404 return {'ok': False, 'msg': 'Could not parse YAML file. %s' % (message)}
def badges_user_list(cls, slug=None): try: game = get_game_by_slug(slug) if game is None: raise ApiException('No game with that slug') # get the user from the environment # get a user model (simulation) user = get_current_user() # try to get a user_id from the context badges_obj = Badges.get_singleton(game) badges = badges_obj.badges badges_total_dict = dict((b['key'], b.get('total')) for b in badges) userbadges = badges_obj.find_userbadges_by_user(user.username) for key, userbadge in userbadges.iteritems(): del userbadge['username'] try: total = badges_total_dict[key] except KeyError: # the badge has been deleted or its key renamed so we just skip it continue userbadge['total'] = total userbadge['achieved'] = (userbadge['current'] >= total) response.status_int = 200 return {'ok': True, 'data': userbadges.values()} except BadgesUnsupportedException: return {'ok': False, 'data': []} except ApiException as message: response.status_int = 404 return {'ok': False, 'msg': str(message)}
def overview(self, slug): """ Display the game's metrics """ game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} self._update_metrics(slug, game) return { 'ok': True, 'data': { 'staticFilePrefix': 'staticmax/', 'mappingTable': game.mapping_table, 'slug': game.slug, 'title': game.title, 'sessions': [{ 'time': s.time, 'timeStamp': s.timestamp, 'numFiles': s.num_files, 'numRequests': s.num_requests, 'humanSize': s.h_size, 'humanTotalSize': s.h_total_size } for s in self._get_overviews(slug)], } }
def _get_game(slug): game = get_game_by_slug(slug) if not game: raise NotFound('No game with slug %s' % slug) return game
def userkeys(cls, slug, username): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} # !!! Move this into the user model user_path = join(cls.datapath, slug, username) if not exists(user_path): response.status_int = 404 return {'ok': False, 'msg': 'User does not exist: %s' % slug} userdata = UserData(user=get_user(username), game=game) if userdata is None: response.status_int = 400 return {'ok': False, 'msg': 'No session with that ID exists'} data_list = userdata.get_keys() userdata = {} for i in data_list: file_path = join(cls.datapath, slug, username, i) + '.txt' f = _File(i, file_path, username, file_path) userdata[f.name] = { 'assetName': f.name, 'isJson': f.is_json(), 'size': f.get_size() } return {'ok': True, 'data': userdata}
def start(cls): """ Start deploying the game. """ response.headers['Cache-Control'] = 'no-store, no-cache, max-age=0' hub_pool = cls.hub_pool if not hub_pool or not cls.cookie_name: response.status_int = 500 return {'ok': False, 'msg': 'Wrong deployment configuration.'} form = request.params try: cookie_value = form[cls.cookie_name] game = form['local'] hub_project = form['project'] hub_version = form['version'] hub_versiontitle = form.get('versiontitle', '') except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Wrong project information.'} game = get_game_by_slug(game) if not game or not game.path.is_set() or not game.path.is_correct(): response.status_int = 400 return {'ok': False, 'msg': 'Wrong game to upload.'} hub_cookie = '%s=%s' % (cls.cookie_name, cookie_value) cls._create_deploy_info(game, hub_project, hub_version, hub_versiontitle, hub_cookie) return { 'ok': True, 'data': 'local=%s&project=%s&version=%s' % (game.slug, hub_project, hub_version) }
def create_session(cls, slug, mode=None): """ Returns application settings for local. """ game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} if 'canvas' == mode: prefix = 'play/%s/' % slug else: prefix = '' mapping_table = 'mapping_table.json' if game: mapping_table = str(game.mapping_table) user = get_current_user() game_session_list = GameSessionList.get_instance() game_session_id = game_session_list.create_session(user, game) StoreList.reset() DataShareList.reset() GameNotificationKeysList.reset() return { 'ok': True, 'mappingTable': { 'mappingTableURL': prefix + mapping_table, 'mappingTablePrefix': prefix + 'staticmax/', 'assetPrefix': 'missing/' }, 'gameSessionId': game_session_id }
def checkout_transaction(cls): user = get_current_user() try: game_slug = request.POST['gameSlug'] transaction_items_json = request.POST['basket'] except KeyError as e: response.status_int = 400 return {'ok': False, 'msg': 'Missing parameter %s' % str(e)} try: transaction_items = _json_decoder.decode(transaction_items_json) except JSONDecodeError as e: response.status_int = 400 return {'ok': False, 'msg': 'Basket parameter JSON error: %s' % str(e)} if not isinstance(transaction_items, dict): response.status_int = 400 return {'ok': False, 'msg': 'Basket parameter JSON must be a dictionary'} game = get_game_by_slug(game_slug) if game is None: response.status_int = 404 return {'ok': False, 'msg': 'No game with slug %s' % game_slug} try: transaction = Transaction(user, game, transaction_items) return {'ok': True, 'data': {'transactionId': transaction.id}} except ValidationException as e: response.status_int = 400 return {'ok': False, 'msg': str(e)} except StoreError as e: response.status_int = e.response_code return {'ok': False, 'msg': str(e)}
def overview(self, slug): """ Display the game's metrics """ game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} self._update_metrics(slug, game) return { 'ok': True, 'data': { 'staticFilePrefix' : 'staticmax/', 'mappingTable': game.mapping_table, 'slug': game.slug, 'title': game.title, 'sessions': [ { 'time': s.time, 'timeStamp': s.timestamp, 'numFiles': s.num_files, 'numRequests': s.num_requests, 'humanSize': s.h_size, 'humanTotalSize': s.h_total_size } for s in self._get_overviews(slug) ], } }
def remove_all(cls, slug): game = get_game_by_slug(slug) if game is None: response.status_int = 400 return {'ok': False, 'msg': 'No game with that slug exists'} GameProfile.remove_all(game) return {'ok': True}
def from_dict(cls, gamesession): game = get_game_by_slug(gamesession['game']) # remove any sessions pointing at old games / users if game: return GameSession(game, get_user(gamesession['user']), gamesession.get('gameSessionId', None), gamesession.get('created', None)) else: raise InvalidGameSession('No gamesession with that id')
def app(cls, slug, asset): game = get_game_by_slug(slug) if not game: abort(404, 'Game does not exist: %s' % slug) asset_url = '/play/' + slug + '/' querystring = '?assetpath=%s&baseurl=%s&mapping_table=%s' % (asset, asset_url, game.mapping_table) viewer_url = '/%s#/play/%s/%s.%s.%s.html' % (querystring, cls.viewer_app, cls.viewer_app, cls.viewer_type, cls.viewer_mode) redirect(viewer_url)
def set_properties(cls, slug, datashare_id, params=None): game = get_game_by_slug(slug) datashare = DataShareList.get(game).get(datashare_id) if 'joinable' in params: try: joinable = asbool(params['joinable']) except ValueError: raise BadRequest('Joinable must be a boolean value') datashare.set_joinable(get_current_user(), joinable) return {'ok': True}
def overview(cls, slug): """ Show "Manage Game" form. """ game = get_game_by_slug(slug, reload_game=True) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} return _details(game)
def read_expanded(cls, slug, key): game = get_game_by_slug(slug) if game is None: response.status_int = 404 return {'ok': False, 'msg': 'No game with that slug'} params = request.GET method_type = params.get('type', 'top') def get_size(default_size, max_size): try: size = int(params.get('size', default_size)) if size <= 0 or size > max_size: raise BadRequest('size must be a positive integer smaller than %d' % max_size) except ValueError: raise BadRequest('size must be a positive integer smaller than %d' % max_size) return size try: leaderboards = LeaderboardsList.get(game) is_above = (method_type == 'above') if method_type == 'below' or is_above: try: score = float(params.get('score')) score_time = float(params.get('time', 0)) if isinf(score) or isnan(score) or isinf(score_time) or isnan(score_time): response.status_int = 400 return { 'ok': False, 'msg': 'Score or time are incorrectly formated' } except (TypeError, ValueError): response.status_int = 400 return {'ok': False, 'msg': 'Score or time parameter missing'} return {'ok': True, 'data': leaderboards.get_page(key, get_current_user(), get_size(5, cls.max_page_size), is_above, score, score_time)} if method_type == 'near': return {'ok': True, 'data': leaderboards.get_near(key, get_current_user(), get_size(9, cls.max_near_size))} else: # method_type == 'top' return {'ok': True, 'data': leaderboards.get_top_players(key, get_current_user(), get_size(9, cls.max_top_size))} except ValidationException as e: response.status_int = 400 return {'ok': False, 'msg': str(e)} except LeaderboardError as e: response.status_int = e.response_code return {'ok': False, 'msg': str(e)}
def post(self, slug, filename): """ Saves given contents to file to game folder. """ game = get_game_by_slug(slug) if not game: self.set_status(404) return self.finish({'ok': False, 'msg': 'Game does not exist: %s' % slug}) if not filename: self.set_status(400) return self.finish({'ok': False, 'msg': 'Missing filename'}) if '..' in filename: self.set_status(403) return self.finish({'ok': False, 'msg': 'Cannot write outside game folder'}) content = self.get_argument('content') self.request.body = None self.request.arguments = None file_path = path_join(get_absolute_path(game.get_path()), normpath(filename)) file_dir = dirname(file_path) if not create_dir(file_dir): LOG.error('Failed to create directory at "%s"', file_dir) self.set_status(500) return self.finish({'ok': False, 'msg': 'Failed to create directory'}) if content: try: content = content.encode('utf-8') except UnicodeEncodeError as e: LOG.error('Failed to encode file contents: %s', str(e)) self.set_status(500) return self.finish({'ok': False, 'msg': 'Failed to encode file contents'}) LOG.info('Writing file at "%s" (%d bytes)', file_path, len(content)) else: LOG.info('Writing empty file at "%s"', file_path) try: file_obj = open(file_path, 'wb') try: file_obj.write(content) finally: file_obj.close() except IOError as e: LOG.error('Failed to write file at "%s": %s', file_path, str(e)) self.set_status(500) return self.finish({'ok': False, 'msg': 'Failed to write file'}) return self.finish({'ok': True})
def find(cls, slug): game = get_game_by_slug(slug) username = request.params.get('username') datashares = DataShareList.get(game).find(get_current_user(), username_to_find=username) return { 'ok': True, 'data': { 'datashares': [datashare.summary_dict() for datashare in datashares] } }
def create(cls, slug): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Unknown game.'} try: num_slots = int(request.params['slots']) _ = request.params['gameSessionId'] # Check for compatibility with gamesite API which does use this except (KeyError, ValueError): response.status_int = 400 return {'ok': False, 'msg': 'Missing session information.'} with cls.lock: cls.last_player_id += 1 player_id = str(cls.last_player_id) sessions = cls.sessions cls.last_session_id += 1 session_id = str(cls.last_session_id) server_address = None secret = None if cls.secret is not None: stale_time = time() - 80 for ip, server in cls.servers.iteritems(): if stale_time < server.updated: server_address = '%s:%d' % (ip, server.port) secret = cls.secret break session = MultiplayerSession(session_id, slug, num_slots, server_address, secret) LOG.info('Created session %s (%d slots)', session_id, num_slots) sessions[session_id] = session request_ip = get_remote_addr(request) session.add_player(player_id, request_ip) LOG.info('Player %s joins session %s', player_id, session_id) info = {'server': session.get_player_address(request.host, request_ip, player_id), 'sessionid': session_id, 'playerid': player_id, 'numplayers': session.get_num_players()} return {'ok': True, 'data': info}
def details(self, slug, timestamp): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} self._update_metrics(slug, game) session = MetricsSession.get_data(slug, timestamp) if not session: response.status_int = 404 return {'ok': False, 'msg': 'Session does not exist: %s' % timestamp} return {'ok': True, 'data': session}
def overview(cls, slug): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} return { 'ok': True, 'data': { 'slug': game.slug, 'staticFilePrefix' : 'staticmax', 'mappingTable': game.mapping_table } }
def list(cls, slug): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Unknown game.'} request_host = request.host sessions = [] for session in cls.sessions.itervalues(): if session.game == slug: session.update_status() sessions.append(session.get_info(request_host)) return {'ok': True, 'data': sessions}
def get_asset(asset, slug, userdata=None): game = get_game_by_slug(slug) if userdata: # asset = user / key (username, key) = asset.split('/', 1) user = get_user(username) userdata = UserData(user=user, game=game) json_asset = json.loads(userdata.get(key)) filename = key + '.txt' else: filename = get_absolute_path(os.path.join(game.path, asset)) with open(filename, 'r') as handle: json_asset = json.load(handle) return (json_asset, filename)
def read_aggregates(cls, slug): game = get_game_by_slug(slug) if game is None: response.status_int = 404 return {'ok': False, 'msg': 'No game with that slug'} try: leaderboards = LeaderboardsList.get(game) return {'ok': True, 'data': leaderboards.read_aggregates()} except ValidationException as e: response.status_int = 400 return {'ok': False, 'msg': str(e)} except LeaderboardError as e: response.status_int = e.response_code return {'ok': False, 'msg': str(e)}
def versions(cls, slug): """ Display a list of all play pages in the game's folder. """ game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} versions = game.get_versions() if versions: versions.sort(key=lambda s: (s['title'], s)) else: versions = '' return {'ok': True, 'data': {'game': game.title, 'versions': versions}}
def details(self, slug, timestamp): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} self._update_metrics(slug, game) session = MetricsSession.get_data(slug, timestamp) if not session: response.status_int = 404 return { 'ok': False, 'msg': 'Session does not exist: %s' % timestamp } return {'ok': True, 'data': session}
def app(cls, slug, asset): game = get_game_by_slug(slug) if not game: abort(404, 'Invalid game: %s' % slug) try: depth = int(request.params.get('depth', cls.default_depth)) list_cull = int(request.params.get('list_cull', cls.default_list_cull)) dict_cull = int(request.params.get('dict_cull', cls.default_dict_cull)) expand = bool(request.params.get('expand', False)) userdata = int(request.params.get('userdata', 0)) except TypeError as e: abort(404, 'Invalid parameter: %s' % str(e)) depth = max(1, depth) list_cull = max(1, list_cull) dict_cull = max(1, dict_cull) node = request.params.get('node', None) if node: try: (json_asset, filename) = get_asset(asset, slug, userdata) link_prefix = '/disassemble/%s' % slug disassembler = Disassembler(Json2htmlRenderer(), list_cull, dict_cull, depth, link_prefix) response.status = 200 Compactor.disable(request) return disassembler.mark_up_asset({'root': json_asset}, expand, node) except IOError as e: abort(404, str(e)) except json.JSONDecodeError as e: _, ext = os.path.splitext(filename) if ext == '.json': abort(404, 'Failed decoding JSON asset: %s\nError was: %s' % (asset, str(e))) else: abort(404, 'Currently unable to disassemble this asset: %s' % asset) else: c.game = game local_context = { 'asset': asset, 'list_cull': list_cull, 'dict_cull': dict_cull, 'depth': depth, 'userdata': userdata } return render('/disassembler/disassembler.html', local_context)
def overview(cls, slug): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} abs_static_path = join(cls.datapath, slug) users = listdir(abs_static_path) if exists(abs_static_path) else [ ] return { 'ok': True, 'data': { 'title': game.title, 'slug': game.slug, 'userdata': exists(join(cls.datapath, slug)), 'users': users } }
def overview(cls, slug): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} abs_static_path = join(cls.datapath, slug) users = listdir(abs_static_path) if exists(abs_static_path) else [] return { 'ok': True, 'data': { 'title': game.title, 'slug': game.slug, 'userdata': exists(join(cls.datapath, slug)), 'users': users } }
def read_meta(cls, slug): game = get_game_by_slug(slug) if game is None: response.status_int = 404 return {'ok': False, 'msg': 'No game with slug %s' % slug} try: store = StoreList.get(game) return {'ok': True, 'data': {'items': store.read_meta(), 'resources': store.read_resources()}} except StoreUnsupported: return {'ok': True, 'data': {'items': {}, 'resources': {}}} except ValidationException as e: response.status_int = 400 return {'ok': False, 'msg': str(e)} except StoreError as e: response.status_int = e.response_code return {'ok': False, 'msg': str(e)}
def remove_all(cls, slug): # This is for testing only and is not present on the Hub or Gamesite game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'No game with that slug exists'} try: leaderboards = LeaderboardsList.get(game) leaderboards.remove_all() except ValidationException as e: response.status_int = 400 return {'ok': False, 'msg': str(e)} except LeaderboardError as e: response.status_int = e.response_code return {'ok': False, 'msg': str(e)} return {'ok': True}
def save(cls, slug): """ Send a signal to save the data passed via the request parameters to a game. """ game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} try: game.save(dict(request.params)) except (GamePathNotFoundError, GamePathError) as e: response.status_int = 400 return {'ok': False, 'msg': str(e)} else: GameList.get_instance().save_game_list() return _details(game)
def remove_all(cls, slug): user = get_current_user() game = get_game_by_slug(slug) if game is None: response.status_int = 404 return {'ok': False, 'msg': 'No game with slug %s' % slug} try: store = StoreList.get(game) store.get_store_user(user).remove_items() return {'ok': True} except ValidationException as e: response.status_int = 400 return {'ok': False, 'msg': str(e)} except StoreError as e: response.status_int = e.response_code return {'ok': False, 'msg': str(e)}
def join_any(cls, slug): params = request.params try: _ = params['gameSessionId'] # Check for compatibility with gamesite API which does use this except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Missing game information.'} game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Unknown game.'} with cls.lock: cls.last_player_id += 1 player_id = str(cls.last_player_id) sessions = cls.sessions session = session_id = None for existing_session in sessions.itervalues(): if existing_session.game == slug: existing_session.update_status() if existing_session.can_join(player_id): session = existing_session session_id = existing_session.session_id break if session is not None: request_ip = get_remote_addr(request) session.add_player(player_id, request_ip) LOG.info('Player %s joins session %s', player_id, session_id) info = {'server': session.get_player_address(request.host, request_ip, player_id), 'sessionid': session_id, 'playerid': player_id, 'numplayers': session.get_num_players()} else: # No session to join info = {} return {'ok': True, 'data': info}
def files(cls, slug, path=''): game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} try: asset_list = game.get_static_files(game.path, cls.request_path, path) except GamePathNotFoundError as e: response.status_int = 404 return {'ok': False, 'msg': str(e)} else: return { 'ok': True, 'data': { 'items': [ i.as_dict() for i in asset_list ], 'path': path.strip('/'), 'mappingTable': game.has_mapping_table } }
def read_user_items(cls, slug): user = get_current_user() game = get_game_by_slug(slug) if game is None: response.status_int = 404 return {'ok': False, 'msg': 'No game with slug %s' % slug} try: store = StoreList.get(game) store_user = store.get_store_user(user) return {'ok': True, 'data': {'userItems': store_user.get_items()}} except StoreUnsupported: return {'ok': True, 'data': {'userItems': {}}} except ValidationException as e: response.status_int = 400 return {'ok': False, 'msg': str(e)} except StoreError as e: response.status_int = e.response_code return {'ok': False, 'msg': str(e)}
def create_session(cls, slug, mode=None): """ Returns application settings for local. """ game = get_game_by_slug(slug) if not game: response.status_int = 404 return {'ok': False, 'msg': 'Game does not exist: %s' % slug} if 'canvas' == mode: prefix = 'play/%s/' % slug else: prefix = '' mapping_table = 'mapping_table.json' if game: mapping_table = str(game.mapping_table) user = get_current_user() game_session_list = GameSessionList.get_instance() if asbool(request.params.get('closeExistingSessions', False)): game_session_list.remove_game_sessions(user, game) game_session = game_session_list.create_session(user, game) # Reset API's (so YAML files are reloaded on a page refresh) StoreList.reset() DataShareList.reset() GameNotificationKeysList.reset() return { 'ok': True, 'mappingTable': { 'mappingTableURL': prefix + mapping_table, 'mappingTablePrefix': prefix + 'staticmax/', 'assetPrefix': 'missing/' }, 'gameSessionId': game_session.gamesession_id }
def find(cls, slug): game = get_game_by_slug(slug) username = request.params.get('username') datashares = DataShareList.get(game).find(get_current_user(), username_to_find=username) return {'ok': True, 'data': {'datashares': [datashare.summary_dict() for datashare in datashares]}}
def postupload_progress(cls): response.headers['Cache-Control'] = 'no-store, no-cache, max-age=0' form = request.params try: hub_project = form['project'] hub_version = form['version'] except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Wrong project information.'} deploy_key = hub_project + hub_version deploy_info = cls._deploying.get(deploy_key, None) if not deploy_info: response.status_int = 404 return {'ok': False, 'msg': 'Unknown deploy session.'} if deploy_info.error: LOG.error(deploy_info.error) response.status_int = 400 return {'ok': False, 'msg': deploy_info.error} if not deploy_info.done: return { 'ok': True, 'data': { 'total': 1, 'processed': 0 } } if not deploy_info.hub_session: response.status_int = 404 return {'ok': False, 'msg': 'No deploy session found.'} try: r = cls.hub_pool.request('POST', '/dynamic/upload/progress/%s' % deploy_info.hub_session, headers={'Cookie': deploy_info.hub_cookie}, redirect=False) except (HTTPError, SSLError) as e: LOG.error(e) response.status_int = 500 return {'ok': False, 'msg': 'Post-upload progress check failed.'} if r.status != 200: response.status_int = 500 return {'ok': False, 'msg': 'Wrong Hub answer.'} r_data = json_loads(r.data) # pylint: disable=E1103 progress = int(r_data.get('progress', -1)) upload_info = str(r_data.get('info', '')) failed = r_data.get('failed', False) # pylint: enable=E1103 if failed: response.status_int = 500 return {'ok': False, 'msg': 'Post-upload processing failed: %s' % upload_info} if -1 == progress: response.status_int = 500 return {'ok': False, 'msg': 'Invalid post-upload progress.'} if 100 <= progress: del cls._deploying[deploy_key] try: cls.hub_pool.request('POST', '/dynamic/logout', headers={'Cookie': deploy_info.hub_cookie}, redirect=False) except (HTTPError, SSLError) as e: LOG.error(e) try: game = form['local'] except KeyError: response.status_int = 400 return {'ok': False, 'msg': 'Wrong request.'} game = get_game_by_slug(game) if game: game.set_deployed() return { 'ok': True, 'data': { 'total': 100, 'processed': progress, 'msg': upload_info } }