Skip to content

xpuz.import_export ¤

Crossword editor-related utilities for importing and exporting a user's crosswords through JSON files.

Export ¤

Export(blocks: List[UserCrosswordBlock])

Bases: list

Export all the crosswords a user has made into a single JSON file.

Parameters:

Name Type Description Default
blocks List[UserCrosswordBlock]

The available user crossword blocks

required
Source code in src/xpuz/import_export.py
16
17
18
19
20
21
22
23
24
def __init__(self, blocks: List["UserCrosswordBlock"]) -> None:
    """Initialise the `self.blocks` array and export-related booleans.

    Args:
        blocks: The available user crossword blocks
    """
    self.blocks = blocks
    self.exported: bool = False
    self.no_filepath: bool = False

_assemble ¤

_assemble() -> None

Append all the user crossword crosswords to self.

Source code in src/xpuz/import_export.py
62
63
64
65
66
67
68
69
70
71
72
73
74
def _assemble(self) -> None:
    """Append all the user crossword crosswords to ``self``."""
    for block in self.blocks:
        cwrapper = block.cwrapper
        self.append(
            [
                cwrapper.fullname,
                {
                    "info": cwrapper.info,
                    "definitions": cwrapper.definitions,
                },
            ]
        )

_export ¤

_export() -> None

Write self to filepath.

Source code in src/xpuz/import_export.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
def _export(self) -> None:
    """Write ``self`` to ``filepath``."""
    filepath = _get_saveas_filename(
        _("Select a destination to export your crosswords to"),
        _("my-crosswords"),
        ".json",
        [("JSON files", "*.json")],
    )

    if not filepath:
        self.no_filepath = True
        return

    if not filepath.endswith(".json"):
        filepath += ".json"
    try:
        with open(filepath, "w") as f:
            dump(self, f, indent=4)
    except Exception:
        return

    self.exported = True

start ¤

start() -> None

Commence the export process and provide information once it is done.

Source code in src/xpuz/import_export.py
26
27
28
29
30
31
32
33
34
35
36
37
def start(self) -> None:
    """Commence the export process and provide information once it is done."""
    self._assemble()
    self._export()

    if self.no_filepath:
        return None

    if self.exported:
        return GUIHelper.show_messagebox(export_success=True)
    else:
        return GUIHelper.show_messagebox(export_failure=True)

Import ¤

Import(master: CrosswordPane, fp: PathLike)

Import a valid user-selected file to fp.

Parameters:

Name Type Description Default
master CrosswordPane

The instance of the crossword pane.

required
fp PathLike

The filepath to which the crosswords will be imported.

required
Source code in src/xpuz/import_export.py
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
def __init__(self, master: "CrosswordPane", fp: PathLike) -> None:
    """Initialise import-related booleans and lists.

    Args:
        master: The instance of the crossword pane.
        fp: The filepath to which the crosswords will be imported.
    """
    self.master = master
    self.fp = fp

    self.conflicting_fullnames: List[str] = []
    self.skipped_crossword_fullnames: List[str] = []
    self.imported_crossword_fullnames: List[str] = []
    self.imported: bool = False
    self.invalid_file: bool = False
    self.no_filepath: bool = False

_import ¤

_import() -> None

Read the contents of filepath and call self._write.

Source code in src/xpuz/import_export.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
def _import(self) -> None:
    """Read the contents of ``filepath`` and call ``self._write``."""
    filepath = _get_open_filename(
        _(
            "Select a valid crossword JSON file that was exported using xpuz"
        ),
        [("JSON files", "*.json")],
    )

    if not filepath:
        self.no_filepath = True
        return

    with open(filepath) as f:
        try:
            crosswords: Any = load(f)
        except Exception:
            self.invalid_file = True
            return

    if not isinstance(crosswords, list):
        self.invalid_file = True
        return

    self._write(crosswords)

_write ¤

_write(crosswords: Any) -> None

Write crosswords to self.fp, collecting information on invalid and conflicting crosswords.

Parameters:

Name Type Description Default
crosswords Any

The crosswords to import.

required
Source code in src/xpuz/import_export.py
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
def _write(self, crosswords: Any) -> None:
    """Write ``crosswords`` to ``self.fp``, collecting information on invalid
    and conflicting crosswords.

    Args:
        crosswords: The crosswords to import.
    """
    for crossword in crosswords:
        if not isinstance(crossword, list) or len(crossword) != 2:
            self.invalid_file = True
            return

        name: str = crossword[0]
        crossword_data = crossword[1]
        toplevel: PathLike = path.join(self.fp, name)
        try:
            mkdir(toplevel)
        except FileExistsError:
            self.conflicting_fullnames.append(name)
            continue

        try:
            info: CrosswordInfo = crossword_data["info"]
            definitions: CrosswordData = crossword_data["definitions"]
            if not all(
                key in info
                for key in CrosswordInfo.__dict__["__annotations__"]
            ):
                self.skipped_crossword_fullnames.append(name)
                rmdir(toplevel)
                continue

            self.master.master._write_data(toplevel, info, "info")
            self.master.master._write_data(
                toplevel, definitions, "definitions"
            )
        except Exception:
            self.skipped_crossword_fullnames.append(name)
            continue

        self.imported_crossword_fullnames.append(name)

    self.imported = True

start ¤

start() -> None

Commence the import process and provide information once it is done.

Source code in src/xpuz/import_export.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def start(self) -> None:
    """Commence the import process and provide information once it is done."""
    self._import()

    if self.no_filepath:
        return None

    if self.invalid_file:
        return GUIHelper.show_messagebox(import_failure=True)
    elif (
        self.imported
        and not self.conflicting_fullnames
        and not self.skipped_crossword_fullnames
    ):
        GUIHelper.show_messagebox(import_success=True)
    else:
        GUIHelper.show_messagebox(
            self.conflicting_fullnames,
            self.skipped_crossword_fullnames,
            partial_import_success=True,
        )