def __init__(self, user, game):
        self.lock = Lock()
        self.game = game
        self.user = user

        try:
            path = config['gameprofile_db']
        except KeyError:
            LOG.error('gameprofile_db path config variable not set')
            return

        # Create gameprofile folder and user folder on the game path
        path = join_path(path, game.slug)
        if not create_dir(path):
            error_msg = 'User GameProfile path \"%s\" could not be created.' % path
            LOG.error(error_msg)
            raise GameProfileError(error_msg)
        self.path = get_absolute_path(path)

        self.defaults = {}
        default_yaml_path = unicode(
            get_absolute_path(join_path(game.path,
                                        'defaultgameprofiles.yaml')))
        if path_exists(default_yaml_path):
            with open(default_yaml_path, 'rt') as f:
                try:
                    file_defaults = yaml.load(f)
                    self.defaults = dict((v['user'], v['value'])
                                         for v in file_defaults['profiles'])
                except (yaml.YAMLError, KeyError, TypeError) as e:
                    LOG.error('Failed loading default game profiles: %s' %
                              str(e))
示例#2
0
    def __init__(self, user, game):
        self.lock = Lock()
        self.game = game
        self.user = user

        try:
            path = config['gameprofile_db']
        except KeyError:
            LOG.error('gameprofile_db path config variable not set')
            return

        # Create gameprofile folder and user folder on the game path
        path = join_path(path, game.slug)
        if not create_dir(path):
            error_msg = 'User GameProfile path \"%s\" could not be created.' % path
            LOG.error(error_msg)
            raise GameProfileError(error_msg)
        self.path = get_absolute_path(path)

        self.defaults = {}
        default_yaml_path = unicode(get_absolute_path(join_path(game.path, 'defaultgameprofiles.yaml')))
        if path_exists(default_yaml_path):
            with open(default_yaml_path, 'r') as f:
                try:
                    file_defaults = yaml.load(f)
                    self.defaults = dict((v['user'], v['value']) for v in file_defaults['profiles'])
                except (yaml.YAMLError, KeyError, TypeError) as e:
                    LOG.error('Failed loading default game profiles: %s', str(e))
示例#3
0
    def __init__(self, game):
        self.lock = Lock()

        self.game = game
        self.userbadges_path = None

        self.abs_game_path = get_absolute_path(game.path)

        try:
            self.lock.acquire()
            yaml_path = norm_path(
                get_absolute_path(join_path(game.path, 'badges.yaml')))
            if not access(yaml_path, R_OK):
                raise BadgesUnsupportedException()
            f = open(unicode(yaml_path), 'r')
            try:
                self.badges = yaml.load(f)

            finally:
                f.close()
        except IOError as e:
            LOG.error('Failed loading badges: %s', str(e))
            raise ApiException('Failed loading badges.yaml file %s' % str(e))
        finally:
            self.lock.release()
示例#4
0
 def is_correct(self):
     try:
         abs_path = get_absolute_path(self.__str__())
         return access(abs_path, W_OK)
     except (AttributeError, TypeError):
         # TODO: These are thrown by get_absolute_path when called on None and probably shouldn't be needed
         return False
示例#5
0
    def __init__(self, game, hub_pool, hub_project, hub_version, hub_versiontitle, hub_cookie, cache_dir):
        self.path = abspath(get_absolute_path(game.path))
        self.plugin_main = game.plugin_main
        self.canvas_main = game.canvas_main
        self.flash_main = game.flash_main
        self.mapping_table = game.mapping_table
        self.files = game.deploy_files.items
        self.engine_version = game.engine_version
        self.is_multiplayer = game.is_multiplayer
        self.aspect_ratio = game.aspect_ratio

        self.cache_dir = cache_dir
        self.game_cache_dir = join(abspath(cache_dir), game.slug)

        self.stopped = False
        self.hub_project = hub_project
        self.hub_version = hub_version
        self.hub_versiontitle = hub_versiontitle
        self.hub_session = None
        self.hub_pool = hub_pool
        self.hub_cookie = hub_cookie
        self.hub_timeout = 200
        self.total_files = 0
        self.num_files = 0
        self.num_bytes = 0
        self.uploaded_files = 0
        self.uploaded_bytes = 0
        self.done = False
        self.error = None

        try:
            makedirs(self.get_gzip_dir())
        except OSError as e:
            if e.errno != EEXIST:
                LOG.error(str(e))
示例#6
0
 def get_versions(self):
     # if the game path is defined, find play-html files.
     versions = [ ]
     if self.path.is_correct():
         abs_path = get_absolute_path(self.path)
         slug = self.slug + '/'
         executable_extensions = self._executable_extensions
         flash_dict = None
         for file_name in listdir(abs_path):
             if file_name.endswith(executable_extensions):
                 version = { 'title': os.path.basename(file_name),
                             'url': slug + file_name }
                 if file_name.endswith('.swf'):
                     if flash_dict is None:
                         flash_dict = {}
                         flash_config_path = join_path(abs_path, 'flash.yaml')
                         if access(flash_config_path, R_OK):
                             f = open(unicode(flash_config_path), 'r')
                             try:
                                 flash_dict = yaml.load(f)
                             finally:
                                 f.close()
                     version['flash'] = flash_dict
                 versions.append(version)
     return versions
示例#7
0
 def get_versions(self):
     # if the game path is defined, find play-html files.
     versions = []
     if self.path.is_correct():
         abs_path = get_absolute_path(self.path)
         slug = self.slug + '/'
         executable_extensions = self._executable_extensions
         flash_dict = None
         for file_name in listdir(abs_path):
             if file_name.endswith(executable_extensions):
                 version = {
                     'title': os.path.basename(file_name),
                     'url': slug + file_name
                 }
                 if file_name.endswith('.swf'):
                     if flash_dict is None:
                         flash_dict = {}
                         flash_config_path = join_path(
                             abs_path, 'flash.yaml')
                         if access(flash_config_path, R_OK):
                             f = open(unicode(flash_config_path), 'r')
                             try:
                                 flash_dict = yaml.load(f)
                             finally:
                                 f.close()
                     version['flash'] = flash_dict
                 versions.append(version)
     return versions
示例#8
0
    def __init__(self, game, hub_pool, hub_project, hub_version, hub_versiontitle, hub_cookie, cache_dir):
        self.path = abspath(get_absolute_path(game.path))
        self.plugin_main = game.plugin_main
        self.canvas_main = game.canvas_main
        self.flash_main = game.flash_main
        self.mapping_table = game.mapping_table
        self.files = game.deploy_files.items
        self.engine_version = game.engine_version
        self.is_multiplayer = game.is_multiplayer
        self.aspect_ratio = game.aspect_ratio

        self.cache_dir = cache_dir
        self.game_cache_dir = join(abspath(cache_dir), game.slug)

        self.stopped = False
        self.hub_project = hub_project
        self.hub_version = hub_version
        self.hub_versiontitle = hub_versiontitle
        self.hub_session = None
        self.hub_pool = hub_pool
        self.hub_cookie = hub_cookie
        self.hub_timeout = 200
        self.total_files = 0
        self.num_files = 0
        self.num_bytes = 0
        self.uploaded_files = 0
        self.uploaded_bytes = 0
        self.done = False
        self.error = None

        try:
            makedirs(self.get_gzip_dir())
        except OSError as e:
            if e.errno != EEXIST:
                LOG.error(str(e))
 def __init__(self):
     self.lock = Lock()
     self.lock.acquire()
     self._sessions = {}
     path = config.get('gamesessions.yaml', 'gamesessions.yaml')
     self.path = get_absolute_path(path)
     self.load_sessions()
     self.lock.release()
 def __init__(self):
     self.lock = Lock()
     self.lock.acquire()
     self._sessions = {}
     path = config.get('gamesessions.yaml', 'gamesessions.yaml')
     self.path = get_absolute_path(path)
     self.load_sessions()
     self.lock.release()
示例#11
0
 def is_correct(self):
     try:
         path = get_absolute_path(self.game.path)
         path = join_path(path, self.image_path)
     except (AttributeError, TypeError):
         # TODO: These are thrown by get_absolute_path when called on None and probably shouldn't be needed
         return None
     else:
         return access(path, R_OK)
    def __call__(self, environ, start_response):
        request_path = environ.get('PATH_INFO', '')

        # check if the request is for static files at all
        path_parts = request_path.strip('/').split('/', 2)
        if len(path_parts) == 3 and path_parts[0] in ['play', 'game-meta']:

            slug = path_parts[1]
            game = self.game_list.get_by_slug(slug)
            if game and game.path.is_set():
                asset_path = path_parts[2]
                file_asset_path = normpath(join(get_absolute_path(game.path), asset_path))

                def build_file_iter(f, block_size):
                    return StaticFileIter(file_asset_path, normpath(join(slug, asset_path)), f, block_size)

                def remove_ranges_start_response(status, headers, exc_info=None):
                    if status == '200 OK':
                        headers = [t for t in headers if t[0] != 'Accept-Ranges' and t[0] != 'Content-Range']
                    return start_response(status, headers, exc_info)

                # check if the request is already cached
                app = self.cached_apps.get(request_path)
                if app:
                    environ['wsgi.file_wrapper'] = build_file_iter

                    try:
                        return app(environ, remove_ranges_start_response)
                    except OSError as e:
                        LOG.error(e)

                elif access(file_asset_path, R_OK):
                    content_type, _ = guess_type(file_asset_path)
                    if content_type in self.utf8_mimetypes:
                        content_type += '; charset=utf-8'

                    app = FileApp(file_asset_path, content_type=content_type)

                    if asset_path.startswith('staticmax'):
                        app.cache_control(max_age=self.staticmax_max_age)
                    else:
                        app.cache_control(max_age=0)

                    self.cached_apps[request_path] = app

                    environ['wsgi.file_wrapper'] = build_file_iter
                    return app(environ, remove_ranges_start_response)

                start_response(
                    '404 Not Found',
                    [('Content-Type', 'text/html; charset=UTF-8'),
                    ('Content-Length', '0')]
                )
                return ['']

        return self.app(environ, start_response)
示例#13
0
    def path_in_use(self, query_path):
        """
        Return True if the given path is already being used in the GameList.
        Otherwise False.
        """
        # turn path absolute
        query_path = get_absolute_path(query_path)

        # check all games...
        for game in self._slugs.itervalues():
            # ... that have a path ...
            test_path = game.path
            if test_path is not None:

                # .. if they are using the given path
                test_path = get_absolute_path(test_path)
                if query_path == test_path:
                    return True

        return False
示例#14
0
    def _read_users(self):
        do_save = False
        try:
            path = config['user.yaml']
        except KeyError:
            LOG.error('Config variable not set for path to "user.yaml"')

        if exists(get_absolute_path(path)):
            try:
                f = open(path, 'rt')
                try:
                    user_info = yaml.load(f)
                    if 'users' in user_info:
                        self.active = user_info.get('active', None)
                        for u in user_info['users']:
                            user = self._add_user(u)
                            if self.active is None:
                                self.active = user.username
                    else:
                        user = self._add_user(user_info)
                        self.active = user.username
                        do_save = True
                finally:
                    f.close()
            except IOError as e:
                LOG.error('Failed loading users: %s' % str(e))
        else:
            self._add_user(User.default_username)
            self.active = User.default_username
            do_save = True

        try:
            path = path_join(CONFIG_PATH, 'defaultusers.yaml')
            f = open(path, 'rt')
            try:
                user_info = yaml.load(f)
                for u in user_info['users']:
                    # dont overwrite changed user settings
                    if u['username'].lower() not in self.users:
                        user = User(u, default=True)
                        username = user.username.lower()
                        self.users[username] = user
                        do_save = True
            finally:
                f.close()
        except IOError as e:
            LOG.error('Failed loading default users: %s' % str(e))
        except KeyError:
            LOG.error('Username missing for default user "defaultusers.yaml"')
        except ValueError:
            LOG.error('Username invalid for default user "defaultusers.yaml"')

        if do_save:
            self._write_users()
示例#15
0
    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})
示例#16
0
    def _set_userbadges_path(self):
        if not self.userbadges_path:
            try:
                path = config['userbadges_db']
            except KeyError:
                LOG.error('badges_db path config variable not set')
                return

            if not create_dir(path):
                LOG.error('Game badges path \"%s\" could not be created.' % path)
            self.userbadges_path = norm_path(join_path(get_absolute_path(path), self.game.slug) + '.yaml')
示例#17
0
    def path_in_use(self, query_path):
        """
        Return True if the given path is already being used in the GameList.
        Otherwise False.
        """
        # turn path absolute
        query_path = get_absolute_path(query_path)

        # check all games...
        for game in self._slugs.itervalues():
            # ... that have a path ...
            test_path = game.path
            if test_path is not None:

                # .. if they are using the given path
                test_path = get_absolute_path(test_path)
                if query_path ==  test_path:
                    return True

        return False
示例#18
0
    def _set_userbadges_path(self):
        if not self.userbadges_path:
            try:
                path = config['userbadges_db']
            except KeyError:
                LOG.error('badges_db path config variable not set')
                return

            if not create_dir(path):
                LOG.error('Game badges path \"%s\" could not be created.', path)
            self.userbadges_path = norm_path(join_path(get_absolute_path(path), self.game.slug) + '.yaml')
    def __init__(self, game):

        self.game = game

        self.abs_game_path = get_absolute_path(game.path)

        try:
            yaml_path = norm_path(get_absolute_path(join_path(game.path, 'gamenotifications.yaml')))
            if not access(yaml_path, R_OK):
                raise GameNotificationsUnsupportedException()

            with open(unicode(yaml_path), 'r') as f:
                notifications = {}
                for n_key in yaml.load(f):
                    notifications[n_key['key']] = n_key

                self._notifications = notifications

        except (IOError, KeyError) as e:
            LOG.error('Failed loading gamenotifications: %s', str(e))
            raise ApiException('Failed loading gamenotifications.yaml file %s' % str(e))
示例#20
0
    def get_path(self):
        if self.path is not None:
            return self.path

        try:
            path = config['datashare_db']
        except KeyError:
            LOG.error('datashare_db path config variable not set')
            raise

        path = get_absolute_path(join_path(path, self.game.slug, self.datashare_id + '.yaml'))
        self.path = path
        return path
示例#21
0
    def create_path(self):
        try:
            path = config['datashare_db']
        except KeyError:
            LOG.error('datashare_db path config variable not set')
            raise

        # Create datashare folder
        path = join_path(path, self.game.slug)
        if not create_dir(path):
            LOG.error('DataShare path \"%s\" could not be created.' % path)
            raise IOError('DataShare path \"%s\" could not be created.' % path)
        return get_absolute_path(path)
示例#22
0
    def _read_users(self):
        do_save = False
        try:
            path = config['user.yaml']
        except KeyError:
            LOG.error('Config variable not set for path to "user.yaml"')

        if exists(get_absolute_path(path)):
            try:
                f = open(path, 'r')
                try:
                    user_info = yaml.load(f)
                    if user_info is not None:
                        if 'users' in user_info:
                            for u in user_info['users']:
                                user = self._add_user(u)
                        else:
                            user = self._add_user(user_info)
                            do_save = True
                finally:
                    f.close()
            except IOError as e:
                LOG.error('Failed loading users: %s', str(e))
        else:
            self._add_user(User.default_username)
            do_save = True

        try:
            path = path_join(CONFIG_PATH, 'defaultusers.yaml')
            f = open(path, 'r')
            try:
                user_info = yaml.load(f)
                for u in user_info['users']:
                    # dont overwrite changed user settings
                    if u['username'].lower() not in self.users:
                        user = User(u, default=True)
                        username = user.username.lower()
                        self.users[username] = user
                        do_save = True
            finally:
                f.close()
        except IOError as e:
            LOG.error('Failed loading default users: %s', str(e))
        except KeyError:
            LOG.error('Username missing for default user "defaultusers.yaml"')
        except ValueError:
            LOG.error('Username invalid for default user "defaultusers.yaml"')

        if do_save:
            self._write_users()
    def __init__(self, game):
        self.leaderboards = {}
        self.ordered_leaderboards = []
        self.leaderboard_path = None

        self.issues = []

        yaml_path = unicode(
            get_absolute_path(join_path(game.path, 'leaderboards.yaml')))
        total_yaml_errors = 0
        if path_exists(yaml_path):
            try:
                f = open(yaml_path, 'rt')
                try:
                    file_meta = yaml.load(f)

                    for (i, m) in enumerate(file_meta):
                        key = m['key']
                        leaderboard = Leaderboard(game, key, m, i)

                        num_errors = len(leaderboard.errors)
                        if num_errors > 0:
                            total_yaml_errors += num_errors
                            self.issues.append((key, {
                                'errors':
                                leaderboard.errors,
                                'warnings':
                                leaderboard.warnings
                            }))
                        elif len(leaderboard.warnings) > 0:
                            self.issues.append((key, {
                                'errors':
                                leaderboard.errors,
                                'warnings':
                                leaderboard.warnings
                            }))

                        self.leaderboards[key] = leaderboard
                        self.ordered_leaderboards.append(leaderboard)
                finally:
                    f.close()
            except (IOError, yaml.YAMLError) as e:
                LOG.error('Failed loading leaderboards: %s' % str(e))
                raise LeaderboardError(
                    'Failed loading leaderboards.yaml file: %s' % str(e))
        else:
            raise LeaderboardsUnsupported()

        if total_yaml_errors > 0:
            raise ValidationException(self.issues)
示例#24
0
    def __init__(self, game):
        self.lock = Lock()

        self.game = game
        self.userbadges_path = None

        self.abs_game_path = get_absolute_path(game.path)

        try:
            self.lock.acquire()
            yaml_path = norm_path(get_absolute_path(join_path(game.path, 'badges.yaml')))
            if not access(yaml_path, R_OK):
                raise BadgesUnsupportedException()
            f = open(unicode(yaml_path), 'r')
            try:
                self.badges = yaml.load(f)

            finally:
                f.close()
        except IOError as e:
            LOG.error('Failed loading badges: %s', str(e))
            raise ApiException('Failed loading badges.yaml file %s' % str(e))
        finally:
            self.lock.release()
示例#25
0
 def is_json(self):
     if self.request_name:
         abs_static_path = self.abs_file_path or get_absolute_path(self.request_name)
         try:
             json_handle = open(abs_static_path)
             json.load(json_handle)
         except IOError as e:
             LOG.error(str(e))
             return False
         except ValueError as e:
             #Expected if file is not valid json
             return False
     else:
         return False
     return True
示例#26
0
    def __init__(self, game):

        self.game = game

        self.abs_game_path = get_absolute_path(game.path)

        try:
            yaml_path = norm_path(
                get_absolute_path(
                    join_path(game.path, 'gamenotifications.yaml')))
            if not access(yaml_path, R_OK):
                raise GameNotificationsUnsupportedException()

            with open(unicode(yaml_path), 'r') as f:
                notifications = {}
                for n_key in yaml.load(f):
                    notifications[n_key['key']] = n_key

                self._notifications = notifications

        except (IOError, KeyError) as e:
            LOG.error('Failed loading gamenotifications: %s', str(e))
            raise ApiException(
                'Failed loading gamenotifications.yaml file %s' % str(e))
示例#27
0
 def is_json(self):
     if self.request_name:
         abs_static_path = self.abs_file_path or get_absolute_path(self.request_name)
         try:
             json_handle = open(abs_static_path)
             json.load(json_handle)
         except IOError as e:
             LOG.error(str(e))
             return False
         except ValueError as e:
             #Expected if file is not valid json
             return False
     else:
         return False
     return True
def _get_task_path(slug, recipient, notification_type, filename=None):
    try:
        path = config['notifications_db']
    except KeyError:
        raise GameNotificationsUnsupportedException('notifications_db path config variable not set')

    path = join_path(path, slug, recipient, notification_type)

    if not create_dir(path):
        raise GameNotificationPathError('User GameNotification path \"%s\" could not be created.' % path)

    if filename:
        return get_absolute_path(join_path(path, filename))
    else:
        return path
示例#29
0
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)
示例#30
0
def read_manifest(game_path, manifest_name):
    """
    Try reading manifest game data in dictionary form from game_path.
    """
    try:
        game_path = get_absolute_path(game_path)
        game_path = join_path(game_path, manifest_name)
        f = open(unicode(game_path), 'r')
        try:
            data = yaml.load(f)
        finally:
            f.close()
    except IOError as e:
        LOG.error('Failed loading manifest: %s', str(e))
        raise GameError
    else:
        return data
示例#31
0
def _get_task_path(slug, recipient, notification_type, filename=None):
    try:
        path = config['notifications_db']
    except KeyError:
        raise GameNotificationsUnsupportedException(
            'notifications_db path config variable not set')

    path = join_path(path, slug, recipient, notification_type)

    if not create_dir(path):
        raise GameNotificationPathError(
            'User GameNotification path \"%s\" could not be created.' % path)

    if filename:
        return get_absolute_path(join_path(path, filename))
    else:
        return path
示例#32
0
def read_manifest(game_path, manifest_name):
    """
    Try reading manifest game data in dictionary form from game_path.
    """
    try:
        game_path = get_absolute_path(game_path)
        game_path = join_path(game_path, manifest_name)
        f = open(unicode(game_path), 'r')
        try:
            data = yaml.load(f)
        finally:
            f.close()
    except IOError as e:
        LOG.error('Failed loading manifest: %s', str(e))
        raise GameError
    else:
        return data
示例#33
0
    def get_asset_list(self, request_path, path=''):
        if self.path.is_correct():
            game_path = self.path
            abs_game_path = get_absolute_path(game_path)

            # Load mapping table
            j = load_json_asset(os.path.join(game_path, self.mapping_table))
            if j:
                # pylint: disable=E1103
                mapping_table = j.get('urnmapping') or j.get(
                    'urnremapping', {})
                # pylint: enable=E1103
                self.has_mapping_table = True
                files = []
                directories = {}
                len_path = len(path)
                if not path.endswith('/') and len_path > 0:
                    len_path += 1
                for k, v in mapping_table.iteritems():
                    if k.startswith(path):
                        parts = k[len_path:].split('/')
                        if len(parts) == 1:
                            abs_file_path = os.path.join(
                                abs_game_path, request_path, v)
                            files.append(
                                _File(parts[0], v, '%s/%s' % (request_path, v),
                                      abs_file_path))
                        else:
                            if parts[0] not in directories:
                                directories[parts[0]] = _File(parts[0])

                result = directories.values() + files
                if len(result) == 0:
                    raise GamePathNotFoundError(
                        'Asset path does not exist: %s' % path)

                return result

            else:
                self.has_mapping_table = False
                # !!! What do we expect if the user asks for Assets and there is no mapping table?
                return self.get_static_files(game_path, request_path, path)

        else:
            raise GamePathError('Game path not found: %s' % self.path)
示例#34
0
    def iterate_dir(cls, path, files, directories):
        abs_static_path = get_absolute_path(path)

        for file_name in listdir(abs_static_path):
            if os.path.isdir(os.path.join(abs_static_path, file_name)) != True:
                #file_name is not directory
                parts = path.split('/')
                if len(parts) > 2:
                    directory = parts[-1]
                else:
                    directory = ''

                files.append(_File(file_name, file_name, directory, os.path.join(abs_static_path, file_name)))
            else:
                if file_name not in directories:
                    directories[file_name] = _File(file_name)

        return directories.values() + files
示例#35
0
    def iterate_dir(cls, path, files, directories):
        abs_static_path = get_absolute_path(path)

        for file_name in listdir(abs_static_path):
            if os.path.isdir(os.path.join(abs_static_path, file_name)) != True:
                #file_name is not directory
                parts = path.split('/')
                if len(parts) > 2:
                    directory = parts[-1]
                else:
                    directory = ''

                files.append(_File(file_name, file_name, directory, os.path.join(abs_static_path, file_name)))
            else:
                if (file_name not in directories):
                    directories[file_name] = _File(file_name)

        return directories.values() + files
示例#36
0
    def __init__(self, game):
        self.leaderboards = {}
        self.ordered_leaderboards = []
        self.leaderboard_path = None

        self.issues = []

        yaml_path = unicode(get_absolute_path(join_path(game.path, 'leaderboards.yaml')))
        total_yaml_errors = 0
        if path_exists(yaml_path):
            try:
                f = open(yaml_path, 'r')
                try:
                    file_meta = yaml.load(f)

                    for (i, m) in enumerate(file_meta):
                        key = m['key']
                        leaderboard = Leaderboard(game, key, m, i)

                        num_errors = len(leaderboard.errors)
                        if num_errors > 0:
                            total_yaml_errors += num_errors
                            self.issues.append((key, {
                                'errors': leaderboard.errors,
                                'warnings': leaderboard.warnings
                            }))
                        elif len(leaderboard.warnings) > 0:
                            self.issues.append((key, {
                                'errors': leaderboard.errors,
                                'warnings': leaderboard.warnings
                            }))

                        self.leaderboards[key] = leaderboard
                        self.ordered_leaderboards.append(leaderboard)
                finally:
                    f.close()
            except (IOError, yaml.YAMLError) as e:
                LOG.error('Failed loading leaderboards: %s', str(e))
                raise LeaderboardError('Failed loading leaderboards.yaml file: %s' % str(e))
        else:
            raise LeaderboardsUnsupported()

        if total_yaml_errors > 0:
            raise ValidationException(self.issues)
示例#37
0
    def __init__(self, user, game, game_store_items):
        self.user = user
        self.game = game
        self.game_store_items = game_store_items
        self.user_items = {}

        try:
            path = config['storeitems_db']
        except KeyError:
            LOG.error('storeitems_db path config variable not set')
            return

        # Create store items folder and user folder on the game path
        path = join_path(path, self.game.slug)
        if not create_dir(path):
            raise StoreError('User store items path \"%s\" could not be created.' % path)
        self.path = get_absolute_path(path)
        self.lock = Lock()
        self._read()
示例#38
0
    def __init__(self, session=None, game=None, user=None):
        if session is None:
            self.game = game
            self.user = user
        else:
            self.game = session.game
            self.user = session.user

        try:
            path = config['userdata_db']
        except KeyError:
            LOG.error('userdata_db path config variable not set')
            return

        # Create userdata folder and user folder on the game path
        path = join_path(path, self.game.slug, self.user.username)
        if not create_dir(path):
            raise UserDataPathError('User UserData path \"%s\" could not be created.' % path)
        self.path = get_absolute_path(path)
示例#39
0
    def __init__(self, session=None, game=None, user=None):
        if session is None:
            self.game = game
            self.user = user
        else:
            self.game = session.game
            self.user = session.user

        try:
            path = config['userdata_db']
        except KeyError:
            LOG.error('userdata_db path config variable not set')
            return

        # Create userdata folder and user folder on the game path
        path = join_path(path, self.game.slug, self.user.username)
        if not create_dir(path):
            raise UserDataPathError('User UserData path \"%s\" could not be created.' % path)
        self.path = get_absolute_path(path)
示例#40
0
def write_manifest(data, manifest_name):
    """
    Write the game metadata to a YAML manifest file
    """
    path = data.get('path')
    if not path:
        raise GamePathError('No path found in game data.\nData=' +\
                            '\n'.join(['%s:\t%s' % (k, v) for k, v in data.iteritems()]))
    path = get_absolute_path(path)

    # write the YAML data
    try:
        f = open(join_path(path, manifest_name), 'w')
        try:
            yaml.dump(data, f, default_flow_style=False)
        finally:
            f.close()
    except IOError as e:
        LOG.error('Failed writing manifest: %s', str(e))
        raise GamePathError('Failed writing manifest file.')
示例#41
0
def write_manifest(data, manifest_name):
    """
    Write the game metadata to a YAML manifest file
    """
    path = data.get('path')
    if not path:
        raise GamePathError('No path found in game data.\nData=' +\
                            '\n'.join(['%s:\t%s' % (k, v) for k, v in data.iteritems()]))
    path = get_absolute_path(path)

    # write the YAML data
    try:
        f = open(join_path(path, manifest_name), 'w')
        try:
            yaml.dump(data, f, default_flow_style=False)
        finally:
            f.close()
    except IOError as e:
        LOG.error('Failed writing manifest: %s', str(e))
        raise GamePathError('Failed writing manifest file.')
示例#42
0
    def __init__(self, user, game, game_store_items):
        self.user = user
        self.game = game
        self.game_store_items = game_store_items
        self.user_items = {}

        try:
            path = config['storeitems_db']
        except KeyError:
            LOG.error('storeitems_db path config variable not set')
            return

        # Create store items folder and user folder on the game path
        path = join_path(path, self.game.slug)
        if not create_dir(path):
            raise StoreError(
                'User store items path \"%s\" could not be created.' % path)
        self.path = get_absolute_path(path)
        self.lock = Lock()
        self._read()
示例#43
0
    def get_asset_list(self, request_path, path=''):
        if self.path.is_correct():
            game_path = self.path
            abs_game_path = get_absolute_path(game_path)

            # Load mapping table
            j = load_json_asset(os.path.join(game_path, self.mapping_table))
            if j:
                # pylint: disable=E1103
                mapping_table = j.get('urnmapping') or j.get('urnremapping', {})
                # pylint: enable=E1103
                self.has_mapping_table = True
                files = [ ]
                directories = { }
                len_path = len(path)
                if not path.endswith('/') and len_path > 0:
                    len_path += 1
                for k, v in mapping_table.iteritems():
                    if k.startswith(path):
                        parts = k[len_path:].split('/')
                        if len(parts) == 1:
                            abs_file_path = os.path.join(abs_game_path, request_path, v)
                            files.append(_File(parts[0], v, '%s/%s' % (request_path, v), abs_file_path))
                        else:
                            if parts[0] not in directories:
                                directories[parts[0]] = _File(parts[0])

                result = directories.values() + files
                if len(result) == 0:
                    raise GamePathNotFoundError('Asset path does not exist: %s' % path)

                return result

            else:
                self.has_mapping_table = False
                # !!! What do we expect if the user asks for Assets and there is no mapping table?
                return self.get_static_files(game_path, request_path, path)

        else:
            raise GamePathError('Game path not found: %s' % self.path)
示例#44
0
    def directory_options(cls):
        directory = request.params.get('dir', None)
        if not directory:
            response.status_int = 400
            return {'ok': False, 'msg': 'Directory not specified'}

        directory = directory.strip()

        # Test for characters not legal in Windows paths
        if not set(directory).isdisjoint(set('*?"<>|\0')):
            response.status_int = 400
            return {'ok': False, 'msg': 'Bad directory'}

        try:
            absDir = get_absolute_path(directory)
        except TypeError:
            response.status_int = 400
            return {'ok': False, 'msg': 'Bad directory'}

        options = {
            'absDir': norm_path(absDir),
            'dir': directory
        }

        if not os.access(absDir, os.F_OK):
            options['create'] = True
        else:
            if not os.access(absDir, os.W_OK):
                options['inaccessible'] = True
            elif os.access(path_join(absDir, 'manifest.yaml'), os.F_OK):
                if GameList.get_instance().path_in_use(absDir):
                    options['inUse'] = True
                else:
                    options['overwrite'] = True
            else:
                options['usable'] = True

        return {'ok': True, 'data': options}
示例#45
0
    def check_completeness(self):
        errors = []
        tmp = []
        if not self.deploy_enable:
            tmp.append('"deploy" is disabled.')
        if self.is_temporary:
            tmp.append('Game is temporary.')

        path = self.path
        if not path or not path.is_set():
            tmp.append('No path set.')
            path_correct = False
        else:
            path_correct = path.is_correct()
            if not path_correct:
                tmp.append('Incorrect path set.')

        if tmp:
            errors.append(('settings', {'errors': tmp}))
            tmp = []

        plugin_main = self.plugin_main
        canvas_main = self.canvas_main
        flash_main = self.flash_main
        main_correct = True
        if (not plugin_main or not plugin_main.is_set()) and \
           (not canvas_main or not canvas_main.is_set()) and \
           (not flash_main or not flash_main.is_set()):
            tmp.append('No "main"-file set. Specify at least one of plugin or canvas main.')
            main_correct = False

        abs_path = get_absolute_path(path)
        if plugin_main:
            plugin_main = join_path(abs_path, plugin_main)
            if not access(plugin_main, R_OK):
                tmp.append('Can\'t access plugin "main"-file.')
        if canvas_main:
            canvas_main = join_path(abs_path, canvas_main)
            if not access(canvas_main, R_OK):
                tmp.append('Can\'t access canvas "main"-file.')
        if flash_main:
            if not flash_main.startswith('https://'):
                flash_main = join_path(abs_path, flash_main)
                if not access(flash_main, R_OK):
                    tmp.append('Can\'t access flash "main"-file.')

        mapping_table = self.mapping_table
        if (not mapping_table or not mapping_table.is_set()) and not flash_main:
            tmp.append('No mapping-table set.')
        elif path_correct and main_correct:
            mapping_table = join_path(abs_path, mapping_table)
            if not access(mapping_table, R_OK):
                tmp.append('Can\'t access mapping-table.')

        deploy_files = self.deploy_files
        if not deploy_files or not deploy_files.is_set():
            tmp.append('No deploy files set.')

        engine_version = self.engine_version
        if not engine_version or not engine_version.is_set():
            tmp.append('No engine version set.')
        elif not engine_version.is_correct():
            tmp.append('Invalid engine version set.')

        aspect_ratio = self.aspect_ratio
        if not aspect_ratio or not aspect_ratio.is_set():
            tmp.append('No aspect ratio set.')
        elif not aspect_ratio.is_correct():
            tmp.append('Invalid aspect ratio set.')

        if tmp:
            errors.append(('files', {'errors': tmp}))

        return (len(errors) == 0, {'Project-Settings': errors})
示例#46
0
    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_type = self.request.headers.get('Content-Type', '')
        if content_type and 'application/x-www-form-urlencoded' in content_type:
            content = self.get_argument('content')
            binary = False
        else:
            content = self.request.body
            binary = True

        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:
            if not binary:
                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})
示例#47
0
    def __init__(self, game, key, meta_data, index):
        self.user_scores = {}
        self.scores = []
        self.aggregate = False
        self.aggregate_score = 0
        self.lock = Lock()

        self.errors = []
        self.warnings = []
        self.path = None

        def error(msg):
            self.errors.append(msg)

        def warning(msg):
            self.warnings.append(msg)

        if not self.validate_key.match(key):
            error('invalid key format "%s"' % key)
        self.key = key
        self.index = index

        if 'title' not in meta_data or meta_data['title'] is None:
            error('title property missing for key "%s"' % key)
            self.title = ''
        else:
            self.title = meta_data['title']

        if 'aggregate' in meta_data:
            if isinstance(meta_data['aggregate'], bool):
                self.aggregate = meta_data['aggregate']
            else:
                warning('aggregate property must be a boolean for key "%s"' % key)
                self.aggregate = False
        else:
            self.aggregate = False

        try:
            sort_by = int(meta_data['sortBy'])
            if sort_by != -1 and sort_by != 1:
                error('sortBy must either -1 or 1 for key "%s"' % key)
        except KeyError:
            warning('sortBy property missing for key "%s"' % key)
            sort_by = 1
        except ValueError:
            error('sortBy must either -1 or 1 for key "%s"' % key)
            sort_by = 1
        self.sort_by = sort_by

        if 'icon' in meta_data:
            warning('"icon" yaml property has been deprecated please use '
                    '"icon256", "icon48" or "icon32" for leaderboard key "%s"' % key)

        try:
            icon_path = meta_data['icon256']
            if path_exists(get_absolute_path(join_path(game.path, icon_path))):
                if splitext(icon_path)[1] != '.png':
                    warning('icon256 must be in PNG format for key "%s"' % key)
            else:
                error('icon256 file does not exist for key "%s"' % key)
        except KeyError:
            warning('no icon256 (using default) for key "%s"' % key)

        self.game = game

        self.default_scores = []
        default_scores = meta_data.get('default-scores', [])
        for (i, s) in enumerate(default_scores):
            if not isinstance(s, dict):
                warning('Default score must an array of objects for key "%s"' % key)
                continue

            user = s.get('user', None)
            if user is None:
                email = s.get('email', None)
                if email is None:
                    warning('Default score must contain user or email for key "%s"' % key)
                    continue
                try:
                    user = email.split('@', 1)[0]
                    # for tests
                    if user.startswith('no-reply+'):
                        user = user[9:]
                except AttributeError:
                    warning('Default score email "%s" must be a string for key "%s"' % (email, key))
                    continue

            if 'score' in s:
                try:
                    score = float(s['score'])
                    if isinf(score) or isnan(score):
                        warning('Default score for user "%s" must be a number for key "%s"' % (user, key))
                        continue
                    user_score = UserScore(user, score, time_now() - i)
                    self.default_scores.append(user_score)
                except (ValueError, TypeError):
                    warning('Default score for user "%s" must be a number for key "%s"' % (user, key))
                    continue
            else:
                warning('Default score for user "%s" missing score for key "%s"' % (user, key))
                continue
示例#48
0
    def __init__(self, game):
        self.offerings = {}
        self.resources = {}
        self.issues = []

        total_yaml_errors = 0
        def add_infos(key, item):
            num_errors = len(item.errors)
            if num_errors > 0 or len(item.warnings) > 0:
                self.issues.append((key, {
                    'errors': item.errors,
                    'warnings': item.warnings
                }))
            return num_errors

        yaml_path = unicode(get_absolute_path(join_path(game.path, 'storeitems.yaml')))
        if path_exists(yaml_path):
            try:
                with open(yaml_path, 'r') as f:
                    items_meta = yaml.load(f)

                    resource_keys = set()
                    offering_keys = set()
                    if isinstance(items_meta, list):
                        for index, m in enumerate(items_meta):
                            resource = StoreResource(game, m, resource_keys)
                            resource.index = index

                            total_yaml_errors += add_infos(resource.key, resource)
                            self.resources[resource.key] = resource

                        index = 0
                        items_meta_end = len(items_meta) - 1
                        for m in items_meta:
                            try:
                                m['output'] = {m['key']: 1}
                            except KeyError:
                                raise StoreError('Store item YAML item missing key')

                            offering = StoreOffering(game, m, offering_keys, resource_keys)
                            # put unavailable items at the end
                            if offering.available:
                                offering.index = index
                                index += 1
                            else:
                                offering.index = items_meta_end
                                items_meta_end -= 1

                            total_yaml_errors += add_infos(offering.key, offering)
                            self.offerings[offering.key] = offering

                    elif isinstance(items_meta, dict):
                        resource_meta = items_meta.get('resources')
                        if not isinstance(resource_meta, list):
                            raise StoreError('Store items YAML file must contain "resources"')

                        for index, m in enumerate(resource_meta):
                            resource = StoreResource(game, m, resource_keys)
                            resource.index = index

                            total_yaml_errors += add_infos(resource.key, resource)
                            self.resources[resource.key] = resource

                        offerings_meta = items_meta.get('offerings')
                        if not isinstance(offerings_meta, list):
                            raise StoreError('Store items YAML file must contain "offerings"')

                        index = 0
                        items_meta_end = len(offerings_meta) - 1
                        for m in offerings_meta:
                            offering = StoreOffering(game, m, offering_keys, resource_keys)
                            # put unavailable items at the end
                            if offering.available:
                                offering.index = index
                                index += 1
                            else:
                                offering.index = items_meta_end
                                items_meta_end -= 1


                            total_yaml_errors += add_infos(offering.key, offering)
                            self.offerings[offering.key] = offering

                    else:
                        raise StoreError('Store items YAML file must be a dictionary or list')
            except (IOError, yaml.YAMLError) as e:
                LOG.error('Failed loading store items: %s', str(e))
                raise StoreError('Failed loading storeitems.yaml file: %s' % str(e))
        else:
            raise StoreUnsupported()

        if total_yaml_errors > 0:
            raise ValidationException(self.issues)

        self.store_users = StoreUserList(game, self)
示例#49
0
    def __init__(self, game, key, meta_data, index):
        self.user_scores = {}
        self.scores = []
        self.aggregate = False
        self.aggregate_score = 0
        self.lock = Lock()

        self.errors = []
        self.warnings = []
        self.path = None

        def error(msg):
            self.errors.append(msg)

        def warning(msg):
            self.warnings.append(msg)

        if not self.validate_key.match(key):
            error('invalid key format "%s"' % key)
        self.key = key
        self.index = index

        if 'title' not in meta_data or meta_data['title'] is None:
            error('title property missing for key "%s"' % key)
            self.title = ''
        else:
            self.title = meta_data['title']

        if 'aggregate' in meta_data:
            if (isinstance(meta_data['aggregate'], bool)):
                self.aggregate = meta_data['aggregate']
            else:
                warning('aggregate property must be a boolean for key "%s"' % key)
                self.aggregate = False
        else:
            self.aggregate = False

        try:
            sort_by = int(meta_data['sortBy'])
            if sort_by != -1 and sort_by != 1:
                error('sortBy must either -1 or 1 for key "%s"' % key)
        except KeyError:
            warning('sortBy property missing for key "%s"' % key)
            sort_by = 1
        except ValueError:
            error('sortBy must either -1 or 1 for key "%s"' % key)
            sort_by = 1
        self.sort_by = sort_by

        if 'icon' in meta_data:
            warning('"icon" yaml property has been deprecated please use '
                    '"icon256", "icon48" or "icon32" for leaderboard key "%s"' % key)

        try:
            icon_path = meta_data['icon256']
            if path_exists(get_absolute_path(join_path(game.path, icon_path))):
                if splitext(icon_path)[1] != '.png':
                    warning('icon256 must be in PNG format for key "%s"' % key)
            else:
                error('icon256 file does not exist for key "%s"' % key)
        except KeyError:
            warning('no icon256 (using default) for key "%s"' % key)

        self.game = game

        self.default_scores = []
        default_scores = meta_data.get('default-scores', [])
        for (i, s) in enumerate(default_scores):
            if not isinstance(s, dict):
                warning('Default score must an array of objects for key "%s"' % key)
                continue

            user = s.get('user', None)
            if user is None:
                email = s.get('email', None)
                if email is None:
                    warning('Default score must contain user or email for key "%s"' % key)
                    continue
                try:
                    user = email.split('@', 1)[0]
                    # for tests
                    if user.startswith('no-reply+'):
                        user = user[9:]
                except AttributeError:
                    warning('Default score email "%s" must be a string for key "%s"' % (email, key))
                    continue

            if 'score' in s:
                try:
                    score = float(s['score'])
                    if isinf(score) or isnan(score):
                        warning('Default score for user "%s" must be a number for key "%s"' % (user, key))
                        continue
                    user_score = UserScore(user, score, time_now() - i)
                    self.default_scores.append(user_score)
                except (ValueError, TypeError):
                    warning('Default score for user "%s" must be a number for key "%s"' % (user, key))
                    continue
            else:
                warning('Default score for user "%s" missing score for key "%s"' % (user, key))
                continue
示例#50
0
    def __init__(self, game):
        self.offerings = {}
        self.resources = {}
        self.issues = []

        total_yaml_errors = 0

        def add_infos(key, item):
            num_errors = len(item.errors)
            if num_errors > 0 or len(item.warnings) > 0:
                self.issues.append((key, {
                    'errors': item.errors,
                    'warnings': item.warnings
                }))
            return num_errors

        yaml_path = unicode(
            get_absolute_path(join_path(game.path, 'storeitems.yaml')))
        if path_exists(yaml_path):
            try:
                with open(yaml_path, 'r') as f:
                    items_meta = yaml.load(f)

                    resource_keys = set()
                    offering_keys = set()
                    if isinstance(items_meta, list):
                        for index, m in enumerate(items_meta):
                            resource = StoreResource(game, m, resource_keys)
                            resource.index = index

                            total_yaml_errors += add_infos(
                                resource.key, resource)
                            self.resources[resource.key] = resource

                        index = 0
                        items_meta_end = len(items_meta) - 1
                        for m in items_meta:
                            try:
                                m['output'] = {m['key']: 1}
                            except KeyError:
                                raise StoreError(
                                    'Store item YAML item missing key')

                            offering = StoreOffering(game, m, offering_keys,
                                                     resource_keys)
                            # put unavailable items at the end
                            if offering.available:
                                offering.index = index
                                index += 1
                            else:
                                offering.index = items_meta_end
                                items_meta_end -= 1

                            total_yaml_errors += add_infos(
                                offering.key, offering)
                            self.offerings[offering.key] = offering

                    elif isinstance(items_meta, dict):
                        resource_meta = items_meta.get('resources')
                        if not isinstance(resource_meta, list):
                            raise StoreError(
                                'Store items YAML file must contain "resources"'
                            )

                        for index, m in enumerate(resource_meta):
                            resource = StoreResource(game, m, resource_keys)
                            resource.index = index

                            total_yaml_errors += add_infos(
                                resource.key, resource)
                            self.resources[resource.key] = resource

                        offerings_meta = items_meta.get('offerings')
                        if not isinstance(offerings_meta, list):
                            raise StoreError(
                                'Store items YAML file must contain "offerings"'
                            )

                        index = 0
                        items_meta_end = len(offerings_meta) - 1
                        for m in offerings_meta:
                            offering = StoreOffering(game, m, offering_keys,
                                                     resource_keys)
                            # put unavailable items at the end
                            if offering.available:
                                offering.index = index
                                index += 1
                            else:
                                offering.index = items_meta_end
                                items_meta_end -= 1

                            total_yaml_errors += add_infos(
                                offering.key, offering)
                            self.offerings[offering.key] = offering

                    else:
                        raise StoreError(
                            'Store items YAML file must be a dictionary or list'
                        )
            except (IOError, yaml.YAMLError) as e:
                LOG.error('Failed loading store items: %s', str(e))
                raise StoreError('Failed loading storeitems.yaml file: %s' %
                                 str(e))
        else:
            raise StoreUnsupported()

        if total_yaml_errors > 0:
            raise ValidationException(self.issues)

        self.store_users = StoreUserList(game, self)
示例#51
0
    def check_completeness(self):
        errors = []
        tmp = []
        if not self.deploy_enable:
            tmp.append('"deploy" is disabled.')
        if self.is_temporary:
            tmp.append('Game is temporary.')

        path = self.path
        if not path or not path.is_set():
            tmp.append('No path set.')
            path_correct = False
        else:
            path_correct = path.is_correct()
            if not path_correct:
                tmp.append('Incorrect path set.')

        if tmp:
            errors.append(('settings', {'errors': tmp}))
            tmp = []

        plugin_main = self.plugin_main
        canvas_main = self.canvas_main
        flash_main = self.flash_main
        main_correct = True
        if (not plugin_main or not plugin_main.is_set()) and \
           (not canvas_main or not canvas_main.is_set()) and \
           (not flash_main or not flash_main.is_set()):
            tmp.append(
                'No "main"-file set. Specify at least one of plugin or canvas main.'
            )
            main_correct = False

        abs_path = get_absolute_path(path)
        if plugin_main:
            plugin_main = join_path(abs_path, plugin_main)
            if not access(plugin_main, R_OK):
                tmp.append('Can\'t access plugin "main"-file.')
        if canvas_main:
            canvas_main = join_path(abs_path, canvas_main)
            if not access(canvas_main, R_OK):
                tmp.append('Can\'t access canvas "main"-file.')
        if flash_main:
            if not flash_main.startswith('https://'):
                flash_main = join_path(abs_path, flash_main)
                if not access(flash_main, R_OK):
                    tmp.append('Can\'t access flash "main"-file.')

        mapping_table = self.mapping_table
        if (not mapping_table
                or not mapping_table.is_set()) and not flash_main:
            tmp.append('No mapping-table set.')
        elif path_correct and main_correct:
            mapping_table = join_path(abs_path, mapping_table)
            if not access(mapping_table, R_OK):
                tmp.append('Can\'t access mapping-table.')

        deploy_files = self.deploy_files
        if not deploy_files or not deploy_files.is_set():
            tmp.append('No deploy files set.')

        engine_version = self.engine_version
        if not engine_version or not engine_version.is_set():
            tmp.append('No engine version set.')
        elif not engine_version.is_correct():
            tmp.append('Invalid engine version set.')

        aspect_ratio = self.aspect_ratio
        if not aspect_ratio or not aspect_ratio.is_set():
            tmp.append('No aspect ratio set.')
        elif not aspect_ratio.is_correct():
            tmp.append('Invalid aspect ratio set.')

        if tmp:
            errors.append(('files', {'errors': tmp}))

        return (len(errors) == 0, {'Project-Settings': errors})