Skip to content

Commit f094586

Browse files
committed
Fixed history, interal updates
1 parent b966b9c commit f094586

6 files changed

Lines changed: 121 additions & 52 deletions

File tree

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@
3434
"esbonio.sphinx.confDir": "${workspaceFolder}/docs",
3535
"python.linting.pylintEnabled": true,
3636
"python.linting.enabled": true,
37-
"python.linting.flake8Enabled": false
37+
"python.linting.flake8Enabled": false,
38+
"pre-commit-helper.runOnSave": "fixes"
3839
}

HISTORY.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
History
33
=======
44

5+
1.2.1 (2022-04-26)
6+
------------------
7+
8+
* Fixed history
9+
* Callback class to make life easier internally
10+
11+
1.2.0 (2022-04-21)
12+
------------------
13+
14+
* Added overwrite handling in the GUI
15+
516
1.1.1 (2022-04-18)
617
------------------
718

docs/rpgmaker_mv_decoder.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ rpgmaker\_mv\_decoder package
44
Submodules
55
----------
66

7+
rpgmaker\_mv\_decoder.callback module
8+
-------------------------------------
9+
10+
.. automodule:: rpgmaker_mv_decoder.callback
11+
:members:
12+
:undoc-members:
13+
:show-inheritance:
14+
715
rpgmaker\_mv\_decoder.exceptions module
816
---------------------------------------
917

gui.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import rpgmaker_mv_decoder
1515
from icon_data import ABOUT_ICON, TITLE_BAR_ICON
16+
from rpgmaker_mv_decoder.callback import Callback
1617
from rpgmaker_mv_decoder.exceptions import NoValidFilesFound
1718
from rpgmaker_mv_decoder.utils import decode_files, encode_files, guess_at_key
1819

@@ -244,7 +245,7 @@ def __init__(self, master=None):
244245
self.window.title(f"RPGMaker MV Decoder / Encoder v{rpgmaker_mv_decoder.__version__}")
245246
self.window.configure(height="200", padx="10", pady="5", width="500")
246247
self.window.resizable(0, 0)
247-
self.dialog = _ProgressUI(self.window)
248+
self.progress = _ProgressUI(self.window)
248249
self.about = _AboutUI(self.window)
249250

250251
# Main widget
@@ -253,6 +254,7 @@ def __init__(self, master=None):
253254
self.src_path = ""
254255
self.dst_path = ""
255256
self.gui_key = ""
257+
self.callbacks = Callback(self.progress.set_progress, self._overwrite_cb)
256258

257259
def _build_frame_act(self):
258260
self.frame_action = ttk.Frame(self.window)
@@ -369,20 +371,20 @@ def _show_about(self):
369371

370372
def _show_dialog(self, title: str, text: str):
371373
self.dialog_shown = True
372-
if self.dialog is None:
373-
self.dialog = _ProgressUI(self.window)
374-
self.dialog.set_title(title)
375-
self.dialog.set_label(text)
376-
self.dialog.run()
374+
if self.progress is None:
375+
self.progress = _ProgressUI(self.window)
376+
self.progress.set_title(title)
377+
self.progress.set_label(text)
378+
self.progress.run()
377379
else:
378-
self.dialog.set_title(title)
379-
self.dialog.set_label(text)
380-
self.dialog.show()
380+
self.progress.set_title(title)
381+
self.progress.set_label(text)
382+
self.progress.show()
381383

382384
def _hide_dialog(self):
383-
if self.dialog is not None:
385+
if self.progress is not None:
384386
if self.dialog_shown:
385-
self.dialog.close()
387+
self.progress.close()
386388
self.dialog_shown = False
387389

388390
def _validate_text(self, new_text: str) -> bool:
@@ -410,7 +412,7 @@ def _show_dialog():
410412

411413
threading.Thread(target=_show_dialog).start()
412414
try:
413-
self.gui_key = guess_at_key(self.src_path, self.dialog.set_progress)
415+
self.gui_key = guess_at_key(self.src_path, self.callbacks)
414416
self.entry_key.delete(0, tk.END)
415417
self.entry_key.insert(0, self.gui_key)
416418
except NoValidFilesFound:
@@ -439,8 +441,7 @@ def _decode_files():
439441
self.dst_path,
440442
self.entry_key.get(),
441443
self.detect_file_ext.get() == "1",
442-
self.dialog.set_progress,
443-
self._overwrite_cb,
444+
self.callbacks,
444445
)
445446
self._hide_dialog()
446447
self._set_button_state()
@@ -459,8 +460,7 @@ def _encode_files():
459460
self.src_path,
460461
self.dst_path,
461462
self.entry_key.get(),
462-
self.dialog.set_progress,
463-
self._overwrite_cb,
463+
self.callbacks,
464464
)
465465
self._hide_dialog()
466466
self._set_button_state()

rpgmaker_mv_decoder/callback.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""`callback` module
2+
3+
Used to handle callbacks in a single object rather than multiple parameters
4+
"""
5+
from typing import Callable
6+
7+
from click._termui_impl import ProgressBar
8+
9+
10+
def _default_progressbar_callback(_: ProgressBar) -> bool:
11+
return False
12+
13+
14+
def _default_overwrite_callback(_: str) -> bool:
15+
return True
16+
17+
18+
def _default_error_callback(_: str) -> bool:
19+
return False
20+
21+
22+
class Callback:
23+
"""`Callback` encapsulates all the callbacks that might be used during execution"""
24+
25+
def __init__(
26+
self,
27+
progressbar_callback: Callable[[ProgressBar], bool] = _default_progressbar_callback,
28+
overwrite_callback: Callable[[str], bool] = _default_overwrite_callback,
29+
error_callback: Callable[[str], bool] = _default_error_callback,
30+
):
31+
self._progressbar_callback = progressbar_callback
32+
self._overwrite_callback = overwrite_callback
33+
self._error_callback = error_callback
34+
35+
@property
36+
def progressbar(self):
37+
"""`progressbar` callback for updating the progress of the operation
38+
39+
Returns:
40+
- `Callable[[ProgressBar], bool]`: Function to call. Progress data should \
41+
be specified via the parameter. If the user cancels the operation, this \
42+
should return `True`
43+
"""
44+
return self._progressbar_callback
45+
46+
@property
47+
def overwrite(self):
48+
"""`overwrite` callback executed when a file is about to be overwitten
49+
50+
Returns:
51+
- `Callable[[str], bool]`: Function to call. Path to overwite should be specified \
52+
as the string. If the function returns `True` the file should be overwritten. If the \
53+
user cancels the operation this function should return None
54+
"""
55+
return self._overwrite_callback
56+
57+
@property
58+
def error(self):
59+
"""`error` callback executed when an error occurs
60+
61+
Returns:
62+
- `Callable[[str], bool]`: Function to call. Error message should be specified via \
63+
the parameter. If the user cancels the operation, this should return `True`
64+
"""
65+
return self._error_callback

rpgmaker_mv_decoder/utils.py

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
from binascii import crc32
77
from pathlib import Path, PurePath
88
from time import sleep
9-
from tkinter.ttk import Progressbar
109
from typing import Callable, Dict, List, Tuple
1110
from uuid import UUID, uuid4
1211

1312
import click
1413
import magic
1514
from click._termui_impl import ProgressBar
1615

16+
from rpgmaker_mv_decoder.callback import Callback
1717
from rpgmaker_mv_decoder.exceptions import (
1818
FileFormatError,
1919
NoValidFilesFound,
@@ -151,17 +151,16 @@ def __get_likely_key(keys: Dict[str, int], count) -> str:
151151
return main_key
152152

153153

154-
def guess_at_key(src: Path, pb_cb: Callable[[Progressbar], bool] = None) -> str:
154+
def guess_at_key(src: Path, callbacks: Callback = Callback()) -> str:
155155
"""`guess_at_key` Check the path for PNG images and return the decoding key
156156
157157
Finds image files under the specified path and looks for a key to decode all the files.
158158
This can fail if only a small number (less than 3) of the .rpgmvp files are .png images.
159159
160160
Args:
161161
- `src` (`Path`): Path to search for .rpgmvp files
162-
- `pb_cb` (`Callable[[click._termui_impl.Progressbar], bool]`, optional): Callback to\
163-
display current progress. Call with `None` when bar is complete. Returns `True` if the\
164-
user has canceled the operation. Defaults to `None`.
162+
- `callbacks` (`Callback`, optional): Callbacks to use for the UI. Defaults to an empty\
163+
set of callbacks
165164
166165
Raises:
167166
- `NoValidFilesFound`: If no valid PNG images are found
@@ -174,9 +173,8 @@ def guess_at_key(src: Path, pb_cb: Callable[[Progressbar], bool] = None) -> str:
174173
keys: Dict[str, int] = {}
175174
count: int
176175
with click.progressbar(files, label="Finding key") as all_files:
177-
count = _handle_files(pb_cb, keys, all_files)
178-
if pb_cb is not None:
179-
pb_cb(None)
176+
count = _handle_files(callbacks.progressbar, keys, all_files)
177+
callbacks.progressbar(None)
180178

181179
if count == 0:
182180
raise NoValidFilesFound(f"No png files found under: '{Path}'")
@@ -290,14 +288,12 @@ def get_file_ext(data: bytes) -> str:
290288
return "." + filetype.split("/")[-1]
291289

292290

293-
# pylint: disable=too-many-arguments
294291
def decode_files(
295292
src: str,
296293
dst: str,
297294
key: str,
298295
detect_type: bool,
299-
pb_cb: Callable[[Progressbar], bool] = None,
300-
overwrite_callback: Callable[[str], bool] = None,
296+
callbacks: Callback = Callback(),
301297
) -> None:
302298
"""`decode_files` Decodes the files
303299
@@ -308,12 +304,8 @@ def decode_files(
308304
- `dst` (`str`): Destination directory for output
309305
- `key` (`str`): Key to use for decoding
310306
- `detect_type` (`bool`): If file extensions should be detected from the file contents
311-
- `pb_cb` (`Callable[[click._termui_impl.Progressbar], bool]`, optional): Callback to\
312-
display current progress. Call with `None` when bar is complete. Returns `True` if the\
313-
user has canceled the operation. Defaults to `None`.
314-
- `overwrite_callback` (`Callable[[str], bool`, optional): Callback to use if files are\
315-
about to be overwritten. Call with the filename in question. `None` indicates user has\
316-
canceled the operation. Returns if the file should be overwritten. Defaults to `None`.
307+
- `callbacks` (`Callback`, optional): Callbacks to use for the UI. Defaults to an empty\
308+
set of callbacks
317309
"""
318310
# pylint: disable=too-many-locals
319311
source_dir = Path(src).resolve()
@@ -328,7 +320,7 @@ def decode_files(
328320
with click.progressbar(files, label="Decoding files") as all_files:
329321
filename: Path
330322
for filename in all_files:
331-
if pb_cb and pb_cb(all_files):
323+
if callbacks.progressbar(all_files):
332324
break
333325
output_file: PurePath = destination.joinpath(PurePath(filename).relative_to(source))
334326
result: bytes
@@ -352,18 +344,16 @@ def decode_files(
352344
continue
353345
else:
354346
output_file = _get_std_ext(output_file)
355-
if not _save_file(output_file, result, overwrite_callback):
347+
if not _save_file(output_file, result, callbacks.overwrite):
356348
break
357-
if pb_cb:
358-
pb_cb(None)
349+
callbacks.progressbar(None)
359350

360351

361352
def encode_files(
362353
src: str,
363354
dst: str,
364355
key: str,
365-
pb_cb: Callable[[Progressbar], bool] = None,
366-
overwrite_callback: Callable[[str], bool] = None,
356+
callbacks: Callback = Callback(),
367357
) -> None:
368358
"""`encode_files` Encodes the files
369359
@@ -373,12 +363,8 @@ def encode_files(
373363
- `src` (`str`): Source directory to search
374364
- `dst` (`str`): Destination directory for output
375365
- `key` (`str`): Key to use for encoding
376-
- `pb_cb` (`Callable[[click._termui_impl.Progressbar], bool]`, optional): Callback to\
377-
display current progress. Call with `None` when bar is complete. Returns `True` if the\
378-
user has canceled the operation. Defaults to `None`.
379-
- `overwrite_callback` (`Callable[[str], bool`, optional): Callback to use if files are\
380-
about to be overwritten. Call with the filename in question. `None` indicates user has\
381-
canceled the operation. Returns if the file should be overwritten. Defaults to `None`.
366+
- `callbacks` (`Callback`, optional): Callbacks to use for the UI. Defaults to an empty\
367+
set of callbacks
382368
"""
383369
# pylint: disable=too-many-locals
384370
source_dir = Path(src).resolve()
@@ -393,9 +379,8 @@ def encode_files(
393379
with click.progressbar(files, label="Encoding files") as all_files:
394380
filename: Path
395381
for filename in all_files:
396-
if pb_cb is not None:
397-
if pb_cb(all_files):
398-
break
382+
if callbacks.progress(all_files):
383+
break
399384
output_file: PurePath = destination.joinpath(PurePath(filename).relative_to(source))
400385
filetype: str
401386
with click.open_file(filename, "rb") as file:
@@ -408,10 +393,9 @@ def encode_files(
408393
output_file = output_file.with_suffix(".rpgmvp")
409394
elif filetype.startswith("audio"):
410395
output_file = output_file.with_suffix(".rpgmvp")
411-
if not _save_file(output_file, data, overwrite_callback):
396+
if not _save_file(output_file, data, callbacks.overwrite):
412397
break
413-
if pb_cb is not None:
414-
pb_cb(None)
398+
callbacks.progressbar(None)
415399

416400

417401
def _get_std_ext(output_file):

0 commit comments

Comments
 (0)