Example #1
0
 def gather_appearance(self):
     a = {}
     a["block", "margin"] = self.block_margin_spinner.get_value_as_int()
     a["border", "width"] = self.border_width_spinner.get_value_as_int()
     a["cell", "size"] = self.cell_size_spinner.get_value_as_int()
     a["line", "width"] = self.line_width_spinner.get_value_as_int()
     a["cell", "color"] = color_tuple(self.cell_color_button)
     a["line", "color"] = color_tuple(self.line_color_button)
     a["border", "color"] = color_tuple(self.border_color_button)
     a["block", "color"] = color_tuple(self.block_color_button)
     a["char", "color"] = color_tuple(self.char_color_button)
     a["number", "color"] = color_tuple(self.number_color_button)
     p = self.char_size_spinner.get_value_as_int()
     key = ("cell", "size")
     a["char", "size"] = (p, _relative_to(key, p / 100.0, d=a))
     p = self.number_size_spinner.get_value_as_int()
     a["number", "size"] = (p, _relative_to(key, p / 100.0, d=a))
     return a
Example #2
0
def read_xpf(filename, warnings=True):
    results = []
    try:
        doc = etree.parse(filename)
    except etree.XMLSyntaxError:
        raise XPFParserError(u"No valid XML syntax.")
    puzzles = doc.getroot()
    if puzzles.tag != "Puzzles":
        raise XPFParserError(u"No root element called Puzzles found.")
    version = puzzles.get("Version")
    if version is None:
        raise XPFParserError(u"No version specified for this XPF file. Possible older than v1.0?")
    try:
        version = float(version)
    except ValueError:
        raise XPFParserError("uXPF version is not a valid number")
    if version < 1.0:
        raise XPFParserError("uXPF versions older than 1.0 are not supported.")
    for puzzle in puzzles:
        if puzzle.tag != "Puzzle":
            if warnings:
                print "Warning: skipping a child of Puzzles that is not a Puzzle."
            continue
        r_meta = {}
        r_width = None
        r_height = None
        r_grid = None
        r_notepad = ""
        r_styles = {}
        r_gstyles = {}
        r_number_mode = constants.NUMBERING_AUTO
        for child in puzzle:
            if child.tag in XPF_META_ELEMS:
                r_meta[XPF_META_ELEMS[child.tag]] = child.text
            elif child.tag == "Size":
                for d in child:
                    try:
                        if d.tag == "Rows":
                            r_height = int(d.text)
                        elif d.tag == "Cols":
                            r_width = int(d.text)
                    except ValueError:
                        raise XPFParserError(u"Invalid grid dimensions were specified.")
            elif child.tag == "Grid":
                if r_width is None:
                    raise XPFParserError(u"The number of columns was not specified.")
                if r_height is None:
                    raise XPFParserError(u"The number of rows was not specified.")
                assert r_width >= 0
                assert r_height >= 0
                r_grid = Grid(r_width, r_height)
                y = 0
                for row in child:
                    if row.tag != "Row":
                        if warnings:
                            print "Warning: skipping a child of Grid that is not a Row."
                        continue
                    if not row.text:# or len(row.text) < r_width:
                        if warnings:
                            print "Warning: skipping a row with missing content."
                        continue
                    for x, c in enumerate(row.text):
                        if c == '.':
                            r_grid.data[y][x]["block"] = True
                        elif c == '~':
                            r_grid.data[y][x]["void"] = True
                        else:
                            r_grid.data[y][x]["char"] = c if c != ' ' else ''
                    y += 1
            elif child.tag == "Circles":
                for circle in child:
                    if circle.tag != "Circle":
                        if warnings:
                            print "Warning: skipping a child of Circles that is not a Circle."
                        continue
                    a_row = circle.get("Row")
                    a_col = circle.get("Col")
                    if not (a_row and a_col):
                        if warnings:
                            print "Warning: skipping a child of Circles with missing content."
                        continue
                    try:
                        x = int(a_col) - 1
                        y = int(a_row) - 1
                    except ValueError:
                        if warnings:
                            print "Warning: skipping child of Circles with invalid coordinates."
                        continue
                    if (x, y) not in r_styles:
                        r_styles[x, y] = CellStyle()
                    r_styles[x, y]["circle"] = True
            elif child.tag == "RebusEntries":
                for rebus in child:
                    if rebus.tag != "Rebus":
                        if warnings:
                            print "Warning: skipping a child of RebusEntries that is not a Rebus."
                        continue
                    a_row = rebus.get("Row")
                    a_col = rebus.get("Col")
                    a_short = rebus.get("Short")
                    content = rebus.text
                    if not (a_row and a_row and a_short and content):
                        if warnings:
                            print "Warning: skipping a child of RebusEntries with missing content."
                        continue
                    try:
                        x = int(a_col) - 1
                        y = int(a_row) - 1
                    except ValueError:
                        if warnings:
                            print "Warning: skipping child of RebusEntries with invalid coordinates."
                        continue
                    r_grid.set_rebus(x, y, a_short, content)
            elif child.tag == "Shades":
                for shade in child:
                    if shade.tag != "Shade":
                        if warnings:
                            print "Warning: skipping a child of Shades that is not a Shade."
                        continue
                    a_row = shade.get("Row")
                    a_col = shade.get("Col")
                    if not (a_row and a_col and shade.text):
                        if warnings:
                            print "Warning: skipping a child of Shades with missing content."
                        continue
                    try:
                        x = int(a_col) - 1
                        y = int(a_row) - 1
                    except ValueError:
                        if warnings:
                            print "Warning: skipping a child of Shades with invalid coordinates."
                        continue
                    if (x, y) not in r_styles:
                        r_styles[x, y] = CellStyle()
                    if shade.text == "gray":
                        rgb = (32767, 32767, 32767)
                    elif shade.text[0] == '#':
                        rgb = hex_to_color(shade.text)
                    r_styles[x, y]["cell", "color"] = rgb
            elif child.tag == "Clues":
                for clue in child:
                    if clue.tag != "Clue":
                        if warnings:
                            print "Warning: skipping a child of Clues that is not a Clue."
                        continue
                    a_row = clue.get("Row")
                    a_col = clue.get("Col")
                    a_num = clue.get("Num")
                    a_dir = clue.get("Dir")
                    a_ans = clue.get("Ans")
                    if not (a_row and a_col and a_dir):
                        if warnings:
                            print "Warning: skipping a child of Clues with missing content."
                        continue
                    try:
                        x = int(a_col) - 1
                        y = int(a_row) - 1
                    except ValueError:
                        if warnings:
                            print "Warning: skipping a child of Clues with invalid coordinates."
                        continue
                    dirs = {"Across": "across", "Down": "down"}
                    if a_dir not in dirs:
                        if warnings:
                            print "Warning: skipping a clue with a direction that is not across or down."
                        continue
                    if not clue.text:
                        if warnings:
                            print "Warning: skipping clue without text."
                        continue
                    r_grid.store_clue(x, y, dirs[a_dir], "text", clue.text)
            elif child.tag == "Notepad":
                r_notepad = child.text
            elif child.tag == "Palabra":
                version = child.get("Version")
                if version > constants.VERSION:
                    # for now, don't try
                    if warnings:
                        print "Warning: Palabra-specific puzzle content was not loaded as it was made in a newer version of Palabra."
                    continue
                for c in child:
                    if c.tag == "Explanation":
                        a_row = c.get("Row")
                        a_col = c.get("Col")
                        a_dir = c.get("Dir")
                        if not (a_row and a_col and a_dir):
                            if warnings:
                                print "Warning: skipping Explanation with missing content"
                            continue
                        try:
                            x = int(a_col) - 1
                            y = int(a_row) - 1
                        except ValueError:
                            if warnings:
                                print "Warning: skipping Explanation with invalid coordinates."
                            continue
                        dirs = {"Across": "across", "Down": "down"}
                        if a_dir not in dirs:
                            if warnings:
                                print "Warning: skipping Explanation with a direction that is not across or down."
                            continue
                        if not c.text:
                            if warnings:
                                print "Warning: skipping explanation without text."
                            continue
                        r_grid.store_clue(x, y, dirs[a_dir], "explanation", c.text)
                    elif c.tag == "Style":
                        for s in c:
                            if s.tag == "Bar":
                                width = s.get("Width")
                                if width is not None:
                                    r_gstyles["bar", "width"] = int(width)
                            elif s.tag == "Border":
                                width = s.get("Width")
                                if width is not None:
                                    r_gstyles["border", "width"] = int(width)
                                color = s.get("Color")
                                if color is not None:
                                    r_gstyles["border", "color"] = hex_to_color(color)
                            elif s.tag == "Cell":
                                size = s.get("Size")
                                if size is not None:
                                    r_gstyles["cell", "size"] = int(size)
                                color = s.get("Color")
                                if color is not None:
                                    r_gstyles["cell", "color"] = hex_to_color(color)
                            elif s.tag == "Line":
                                width = s.get("Width")
                                if width is not None:
                                    r_gstyles["line", "width"] = int(width)
                                color = s.get("Color")
                                if color is not None:
                                    r_gstyles["line", "color"] = hex_to_color(color)
                            elif s.tag == "Block":
                                color = s.get("Color")
                                if color is not None:
                                    r_gstyles["block", "color"] = hex_to_color(color)
                                margin = s.get("Margin")
                                if margin is not None:
                                    r_gstyles["block", "margin"] = int(margin)
                            elif s.tag == "Char":
                                color = s.get("Color")
                                if color is not None:
                                    r_gstyles["char", "color"] = hex_to_color(color)
                                size = s.get("Size")
                                if size is not None:
                                    s_s = int(size)
                                    s_k = ("cell", "size")
                                    s_d = {s_k: (r_gstyles[s_k] if s_k in r_gstyles else DEFAULTS[s_k])}
                                    s_r = _relative_to(s_k, s_s / 100.0, d=s_d)
                                    r_gstyles["char", "size"] = (s_s, s_r)
                            elif s.tag == "Number":
                                color = s.get("Color")
                                if color is not None:
                                    r_gstyles["number", "color"] = hex_to_color(color)
                                size = s.get("Size")
                                if size is not None:
                                    s_s = int(size)
                                    s_k = ("cell", "size")
                                    s_d = {s_k: (r_gstyles[s_k] if s_k in r_gstyles else DEFAULTS[s_k])}
                                    s_r = _relative_to(s_k, s_s / 100.0, d=s_d)
                                    r_gstyles["number", "size"] = (s_s, s_r)
        if r_number_mode == constants.NUMBERING_AUTO:
            r_grid.assign_numbers()
        p = Puzzle(r_grid, r_styles, r_gstyles)
        p.metadata = r_meta
        p.type = constants.PUZZLE_XPF
        p.filename = filename
        p.notepad = r_notepad
        results.append(p)
    return results