示例#1
0
    def request(self, path, params=dict(), method="GET"):

        if type(path) is list:
            path = self.quiubas.format(path.pop(0), path.pop())

        url = self.formatBaseURL(path)

        request_method = getattr(requests, method.lower())

        headers = {"user-agent": "Quiubas-Python/" + self.quiubas.lib_version}

        auth_info = self.quiubas.getAuth()
        auth_info = auth.HTTPBasicAuth(auth_info["api_key"], auth_info["api_private"])

        timeout = 20

        try:
            if method == "GET":
                request = request_method(
                    url, auth=auth_info, timeout=timeout, headers=headers, verify=False, params=params
                )
            else:
                request = request_method(
                    url, auth=auth_info, timeout=timeout, headers=headers, verify=False, data=params
                )
        except ValueError as e:
            raise error("There was an error trying communicating with Quiubas Server: " + str(e))

        try:
            response = json.loads(request.text)
        except ValueError as e:
            raise error("There was an error parsing the response: " + str(e))

        return response
示例#2
0
    def readTerrain(self, fname):
        """
		Reads the terrain file generated by _terrainW.writeTerrain()
		:str fname:
		:raise exception.error if terrain file version/size mismatched (which means the given file has an error):
		"""
        hFile = open(fname, "rb")
        info = hFile.read(8 * 3)
        ver, tx, ty = [info[n:n + 8] for n in range(0, 24, 8)]
        if raw2struct(ver, uint64).uint != raw2struct(_version_, uint64).uint:
            hFile.close()
            raise exception.error("Terrain File Version Mismatched.  ",
                                  ValueError)
        self._data = []
        tx, ty = raw2struct(tx, uint64).uint, raw2struct(ty, uint64).uint
        for x in range(tx):
            self._data.append([])
            for y in range(ty):
                d = hFile.read(3)
                if not d:
                    self._data = []
                    hFile.close()
                    raise exception.error("Terrain File Size Mismatched.  ",
                                          ValueError)
                self._data[-1].append([raw2struct(d[1:], uint).uint, d[0]])
        hFile.close()
        self.width = tx
        self.height = ty
示例#3
0
	def readTerrain(self, fname):
		"""
		Reads the terrain file generated by _terrainW.writeTerrain()
		:str fname:
		:raise exception.error if terrain file version/size mismatched (which means the given file has an error):
		"""
		hFile = open(fname, "rb")
		info = hFile.read(8*3)
		ver, tx, ty = [info[n:n+8] for n in range(0,24,8)]
		if raw2struct(ver, uint64).uint != raw2struct(_version_, uint64).uint:
			hFile.close()
			raise exception.error("Terrain File Version Mismatched.  ", ValueError)
		self._data = []
		tx, ty = raw2struct(tx, uint64).uint, raw2struct(ty, uint64).uint
		for x in range(tx):
			self._data.append([])
			for y in range(ty):
				d = hFile.read(3)
				if not d:
					self._data = []
					hFile.close()
					raise exception.error("Terrain File Size Mismatched.  ", ValueError)
				self._data[-1].append([raw2struct(d[1:], uint).uint, d[0]])
		hFile.close()
		self.width = tx
		self.height= ty
示例#4
0
    def load_settings() -> None:
        """Read in the settings json file and sets the settings values.

        Returns:
            None
        """
        # Ensure the settings file exists.
        if not os.path.exists(SETTINGS_PATH):
            error(("unable to find settings file at '{}', please ensure it "
                   "exists. continuing to use default values"
                   ).format(SETTINGS_PATH))
            return

        with open(SETTINGS_PATH, 'r') as f:
            # Read in the json from the settings file, if the json is
            # valid. All data verification checks are done by Settings
            # when setting values, so none have to be done here.
            s_data: dict
            try:
                s_data = json.loads(f.read())
            except Exception as e:
                error(("invalid json in settings file '{}' <{}>. continuing "
                       "to use default values").format(SETTINGS_PATH, e))
                return
        # Load the settings from the new data. All data verification
        # checks are done by Settings when setting the new data.
        Settings.load_from(s_data)
示例#5
0
    def save_settings() -> None:
        """Convert Settings to json string and save to the settings json file.

        Returns:
            None
        """
        # Ensure the settings file exists.
        if not os.path.exists(SETTINGS_PATH):
            error(("unable to find settings file at '{}', unable to save. "
                   "please ensure it exists").format(SETTINGS_PATH))
            return

        with open(SETTINGS_PATH, 'w') as f:
            f.write(Settings.as_json())
示例#6
0
    def read_sfmt(file_path: str, data: List[DataObject]) -> bool:
        """Read in sfmt files and adds the loaded DataObjects to `data`.

        sfmt stands for 'Simple Format' which is a file format designed
        to be simple and easy for the user to create.

        Each line in the file represents one DataObject. The lines
        use a '-' delimeter to seperate the segments for that
        DataObject, and each segment uses a '/' delimeter to seperate
        the segments into their respective values. This format does not
        use escape characters, meaning the '-' and '/' delimeters can
        not be used as part of regular text in the files, and should
        only be used to delimit their respective sections.

        An example line would be "this - is / a - test" which would
        turn into a DataObject with 3 segments consisting of
        [["this"], ["is", "a"], ["test"]].

        Args:
            file_path (str): The sfmt file to be read.
            data (List[DataObject]): The list that the newly created
                data objects should be added to.

        Returns:
            bool: If all data was loaded properly (i.e. no errors).
        """
        with open(file_path, 'r', encoding='utf-8') as f:
            for line in f.readlines():
                line = line.strip()
                if line == "":
                    continue
                # Split the current line up into valid data for a DataObject
                line_data: List[List[str]] = \
                    [s.split("/") for s in line.split("-")]
                # Remove space formating from all strings.
                for segment in line_data:
                    for string in segment:
                        string = string.strip()

                d_obj = DataObject.create_new(line_data)
                # Ensure the DataObject was able to be successfully created.
                if d_obj is None:
                    error(("unable to create DataObject, invalid data from "
                           "file '{}': \"{}\"").format(file_path, line_data))
                    return False
                data.append(d_obj)
        return True
示例#7
0
    def request(self, path, params=dict(), method='GET'):

        if type(path) is list:
            path = self.quiubas.format(path.pop(0), path.pop())

        url = self.formatBaseURL(path)

        request_method = getattr(requests, method.lower())

        headers = {
            'user-agent': 'Quiubas-Python/' + self.quiubas.lib_version,
            'Content-Type': 'application/json'
        }

        auth_info = self.quiubas.getAuth()
        auth_info = auth.HTTPBasicAuth(auth_info['api_key'],
                                       auth_info['api_private'])

        timeout = 20

        try:
            if method == 'GET':
                request = request_method(url,
                                         auth=auth_info,
                                         timeout=timeout,
                                         headers=headers,
                                         verify=False,
                                         params=params)
            else:
                request = request_method(url,
                                         auth=auth_info,
                                         timeout=timeout,
                                         headers=headers,
                                         verify=False,
                                         json=params)
        except ValueError as e:
            raise error(
                'There was an error trying communicating with Quiubas Server: '
                + str(e))

        try:
            response = json.loads(request.text)
        except ValueError as e:
            raise error('There was an error parsing the response: ' + str(e))

        return response
示例#8
0
	def readTextureFromFile(self, fname):
		"""
		Reads the texture file generated by _terrainW.writeTextureToFile()
		:str fname:
		:return: :raise exception.error if terrain file version mismatched:
		"""
		hFile = open(fname, "rb")
		info = hFile.read(8*3)
		ver, tx, ty = [info[n:n+8] for n in range(0,24,8)]
		if raw2struct(ver, uint64).uint != raw2struct(_version_, uint64).uint:
			hFile.close()
			raise exception.error("Texture File Version Mismatched.  ", ValueError)
		tx, ty = raw2struct(tx, uint64).uint, raw2struct(ty, uint64).uint
		self._img_texture = pygame.image.frombuffer(hFile.read(), (tx, ty), "RGBA")
		return self.readTextureFromSurface(self._img_texture)
示例#9
0
    def readTextureFromFile(self, fname):
        """
		Reads the texture file generated by _terrainW.writeTextureToFile()
		:str fname:
		:return: :raise exception.error if terrain file version mismatched:
		"""
        hFile = open(fname, "rb")
        info = hFile.read(8 * 3)
        ver, tx, ty = [info[n:n + 8] for n in range(0, 24, 8)]
        if raw2struct(ver, uint64).uint != raw2struct(_version_, uint64).uint:
            hFile.close()
            raise exception.error("Texture File Version Mismatched.  ",
                                  ValueError)
        tx, ty = raw2struct(tx, uint64).uint, raw2struct(ty, uint64).uint
        self._img_texture = pygame.image.frombuffer(hFile.read(), (tx, ty),
                                                    "RGBA")
        return self.readTextureFromSurface(self._img_texture)
示例#10
0
    def read_json(file_path: str, data: List[DataObject]) -> bool:
        """Read in json files and adds the loaded DataObjects to `data`.

        Every json file should contain a 3D list of strings. The
        first dimention is the list containing all of the data
        for each DataObject. The second dimention is a representation
        of each DataObject. The third dimention is each 'segment' of
        the DataObject. Each segment contains strings representing
        the values for that segment.

        Args:
            file_path (str): The json file to be read.
            data (List[DataObject]): The list that the newly created
                data objects should be added to.

        Returns:
            bool: If all data was loaded properly (i.e. no errors).
        """
        with open(file_path, 'r', encoding='utf-8') as f:
            # Read in the json from the file, if the json is valid.
            f_data: List[List[List[str]]]
            try:
                f_data = json.loads(f.read())
            except Exception as e:
                error("invalid json in file '{}' <{}>".format(file_path, e))
                return False

            # Ensure the data read from the file, and is a list as
            # expected.
            if f_data is None or not isinstance(f_data, list):
                error(("json in file '{}' does not contain a list as "
                       "expected").format(file_path))
                return False

            # Attempt to create a DataObject for each element in
            # the list read from the file.
            for elem in f_data:
                d_obj = DataObject.create_new(elem)
                # Ensure the DataObject was able to be successfully created.
                if d_obj is None:
                    error(("unable to create DataObject, invalid data from "
                           "file '{}': \"{}\"").format(file_path, elem))
                    return False
                data.append(d_obj)
        return True
示例#11
0
    def read_files(file_paths: List[str]) -> Optional[List[DataObject]]:
        """Read the given files and loads in DataObjects from them.

        Currently supports the file formats '.json' and '.sfmt'

        Args:
            file_paths (List[str]): A list of all the files to be read.

        Returns:
            DataObject: All the elements that were loaded in from
                the files.
            None: If there was an error loading in any objects.
        """
        data: List[DataObject] = []
        for file_path in file_paths:
            file_path = os.path.join(Settings.directory_path, file_path)

            # Ensure the current file exists.
            if not os.path.exists(file_path):
                error(("unable to load file '{}', file could not be "
                       "found").format(file_path))
                return None

            if file_path.endswith('.json'):  # Json data file.
                if not FileReader.read_json(file_path, data):
                    return None
            elif file_path.endswith('.sfmt'):  # 'Simple Format' data file.
                if not FileReader.read_sfmt(file_path, data):
                    return None
            else:
                error(("the file '{}' is not a valid file format (.json or "
                       ".sfmt)").format(file_path))
                return None

        # Ensure that data was loaded in, and the files were not empty.
        if len(data) == 0:
            error("no elements were able to be found from any of the given "
                  "files")
            return None

        return data
示例#12
0
    def load_from(data: dict) -> None:
        """Set all of the settings values from the provided data.

        This should be used when loading settings from a file.

        Data verification checks are preformed on every item before
        setting their values. These ensure the data is in the correct
        format and won't throw exceptions later when the values are
        used. This is used to combat invalid changes to the settings.json
        file. An error message is logged and displayed any time a
        verification check fails, and the default value is used.

        Args:
            data (dict): The data that contains each of the different
                settings values.

        Returns:
            None
        """
        if not isinstance(data, dict):
            error("settings can not load from type {}, must be type 'dict'".
                  format(type(data)))
            return
        Settings.__raw_data = data

        # Verify and set the new directory path. Ensure the new directory
        # path is a string and that the file path exists.
        new_directory_path: str = data.get("directory_path", None)
        if new_directory_path is not None and \
           isinstance(new_directory_path, str) and \
           os.path.exists(new_directory_path):
            Settings.directory_path = new_directory_path
        else:
            error(("settings unable to load directory path, ensure the path "
                   "exists. expected type 'str', got {}").format(
                       type(new_directory_path)))

        # Verify and set the new active files list. Ensure the data is
        # a list, and that every item in it is a string.
        new_active_files: List[str] = data.get("active_files", None)
        if new_active_files is not None and \
           isinstance(new_active_files, list):
            is_valid: bool = True
            for item in new_active_files:
                if not isinstance(item, str):
                    is_valid = False
            if is_valid:
                Settings.active_files = new_active_files
            else:
                error("settings unable to load active files, list contents "
                      "contained a type that was not a 'str'")
        else:
            error(("settings unable to load active files, expected type "
                   "'list', got {}").format(type(new_active_files)))

        # Verify and set the new display item. Ensure the display item is an
        # integer.
        new_display_item: int = data.get("display_item", None)
        if new_display_item is not None and \
           isinstance(new_display_item, int):
            Settings.display_item = new_display_item
        else:
            error(("settings unable to load display item, expected type "
                   "'int', got {}").format(type(new_display_item)))

        # Verify and set the new font size. Ensure the font size is an integer.
        new_font_size: int = data.get("font_size", None)
        if new_font_size is not None and \
           isinstance(new_font_size, int):
            Settings.font_size = new_font_size
        else:
            error(("settings unable to load font size, expected type 'int', "
                   "got {}").format(type(new_font_size)))

        # Verify and set the new typeface. Ensure the typeface is an integer.
        new_typeface: str = data.get("typeface", None)
        if new_typeface is not None and \
           isinstance(new_typeface, str):
            Settings.typeface = new_typeface
        else:
            error(("settings unable to load typeface, expected type 'str', "
                   "got {}").format(type(new_typeface)))

        # Retrieve the key for the current theme to be loaded.
        theme_colors_key: str = data.get("current_theme", "")
        Settings.current_theme = theme_colors_key
        # Verify and set the new theme colors. Ensure the theme colors
        # is a list of exactly 6 elements (one for each color), and that
        # every element of the list is a valid hex color starting with
        # a '#'. The colors are formatted like so: '#xxxxxx' where each
        # 'x' is a hex value.
        new_theme_colors: List[str] = \
            data.get("all_themes", None).get(theme_colors_key, None)
        if new_theme_colors is not None and \
           isinstance(new_theme_colors, list) and \
           len(new_theme_colors) == 6:
            is_valid = True
            for item in new_theme_colors:
                if isinstance(item, str):
                    if len(item) != 7 or \
                       item[0] != '#':
                        is_valid = False
                    valid_chars: List[str] = [
                        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                        'B', 'C', 'D', 'E', 'F'
                    ]
                    for char in item[1:]:
                        if not char.upper() in valid_chars:
                            is_valid = False
                else:
                    is_valid = False
            if is_valid:
                Settings.theme_colors = new_theme_colors
            else:
                error("settings unable to load theme colors, list contents "
                      "contained value that is not a valid color")
        else:
            error(
                ("settings unable to load theme colors, expected type "
                 "'list' with len(6), got {}").format(type(new_theme_colors)))

        theme_dict: dict = data.get("all_themes", None)
        Settings.theme_names = []  # Prevent duplicate names from being created
        if theme_dict is not None and \
           isinstance(theme_dict, dict):
            for key in theme_dict.keys():
                if key is not None and \
                   isinstance(key, str):
                    Settings.theme_names.append(key)
                else:
                    error(("settings unable to theme name, expected type "
                           "'str', got {}").format(type(key)))
        else:
            error(("settings unable to load theme names, expected type "
                   "'dict', got {}").format(type(theme_dict)))