diff --git a/scripts/opt-comp-experiment.py b/scripts/opt-comp-experiment.py index 389367b4..363a2e0b 100755 --- a/scripts/opt-comp-experiment.py +++ b/scripts/opt-comp-experiment.py @@ -98,7 +98,7 @@ def compress_worker( out_f=out_f, opt_comp=opt_comp, cb=Callback(), - cb_return=CallbackReturn(), + _cb_return=CallbackReturn(), ) results_queue.put( ( diff --git a/scripts/update-xcode-imessage-iconset.py b/scripts/update-xcode-imessage-iconset.py index b1d45d3f..1fdfc5c0 100644 --- a/scripts/update-xcode-imessage-iconset.py +++ b/scripts/update-xcode-imessage-iconset.py @@ -5,16 +5,16 @@ ROOT_DIR = Path(__file__).parents[1] -def main(): +def main() -> None: xcode_imessage_iconset: Dict[str, Tuple[int, int]] = {} with open( ROOT_DIR / "src/sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json" ) as f: - dict = json.load(f) + contents_json = json.load(f) - for i in dict["images"]: + for i in contents_json["images"]: filename = i["filename"] size = i["size"] size_w = int(size.split("x")[0]) diff --git a/src/sticker_convert/cli.py b/src/sticker_convert/cli.py index 618f2e60..b0bae506 100755 --- a/src/sticker_convert/cli.py +++ b/src/sticker_convert/cli.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import argparse import signal +import sys from argparse import Namespace from json.decoder import JSONDecodeError from math import ceil @@ -28,7 +29,7 @@ def cli(self) -> None: try: from sticker_convert.utils.files.json_resources_loader import COMPRESSION_JSON, EMOJI_JSON, HELP_JSON, INPUT_JSON, OUTPUT_JSON except RuntimeError as e: - self.cb.msg(e.__str__()) + self.cb.msg(str(e)) return self.help = HELP_JSON @@ -181,7 +182,7 @@ def cli(self) -> None: signal.signal(signal.SIGINT, job.cancel) status = job.start() - exit(status) + sys.exit(status) def get_opt_input(self, args: Namespace) -> InputOption: download_options = { @@ -207,7 +208,7 @@ def get_opt_input(self, args: Namespace) -> InputOption: self.cb.msg(f"Detected URL input source: {download_option}") else: self.cb.msg(f"Error: Unrecognied URL input source for url: {url}") - exit() + sys.exit() opt_input = InputOption( option=download_option, diff --git a/src/sticker_convert/converter.py b/src/sticker_convert/converter.py index 9c554b25..95cedda0 100755 --- a/src/sticker_convert/converter.py +++ b/src/sticker_convert/converter.py @@ -11,15 +11,15 @@ import numpy as np from PIL import Image -if TYPE_CHECKING: - from av.video.plane import VideoPlane # type: ignore - from sticker_convert.job_option import CompOption from sticker_convert.utils.callback import Callback, CallbackReturn from sticker_convert.utils.files.cache_store import CacheStore from sticker_convert.utils.media.codec_info import CodecInfo from sticker_convert.utils.media.format_verify import FormatVerify +if TYPE_CHECKING: + from av.video.plane import VideoPlane # type: ignore + CbQueueItemType = Union[ Tuple[str, Optional[Tuple[str]], Optional[Dict[str, str]]], str, @@ -45,8 +45,8 @@ def rounding(value: float) -> Decimal: def get_step_value( - max: Optional[int], - min: Optional[int], + max_step: Optional[int], + min_step: Optional[int], step: int, steps: int, power: float = 1.0, @@ -62,14 +62,12 @@ def get_step_value( else: factor = 0 - if max is not None and min is not None: - v = round((max - min) * step / steps * factor + min) + if max_step is not None and min_step is not None: + v = round((max_step - min_step) * step / steps * factor + min_step) if even is True and v % 2 == 1: return v + 1 - else: - return v - else: - return None + return v + return None def useful_array( @@ -151,7 +149,7 @@ def convert( out_f: Path, opt_comp: CompOption, cb: "Union[Queue[CbQueueItemType], Callback]", - cb_return: CallbackReturn, + _cb_return: CallbackReturn, ) -> Tuple[bool, Path, Union[None, bytes, Path], int]: sticker = StickerConvert(in_f, out_f, opt_comp, cb) result = sticker._convert() @@ -272,8 +270,8 @@ def check_if_compatible(self) -> Optional[bytes]: self.result_size = len(self.in_f) return result - else: - return None + + return None def generate_steps_list(self) -> List[Tuple[Optional[int], ...]]: steps_list: List[Tuple[Optional[int], ...]] = [] @@ -378,7 +376,7 @@ def frames_import(self) -> None: def _frames_import_pillow(self) -> None: with Image.open(self.in_f) as im: # Note: im.convert("RGBA") would return rgba image of current frame only - if "n_frames" in im.__dir__(): + if "n_frames" in dir(im): for i in range(im.n_frames): im.seek(i) self.frames_raw.append(np.asarray(im.convert("RGBA"))) @@ -764,10 +762,10 @@ def quantize(self, image: Image.Image) -> Image.Image: return image.copy() if self.opt_comp.quantize_method == "imagequant": return self._quantize_by_imagequant(image) - elif self.opt_comp.quantize_method == "fastoctree": + if self.opt_comp.quantize_method == "fastoctree": return self._quantize_by_fastoctree(image) - else: - return image + + return image def _quantize_by_imagequant(self, image: Image.Image) -> Image.Image: import imagequant # type: ignore @@ -812,17 +810,17 @@ def fix_fps(self, fps: float) -> Fraction: # # For GIF, we need to adjust fps such that delay is matching to hundreths of second return self._fix_fps_duration(fps, 100) - elif self.out_f.suffix in (".webp", ".apng", ".png"): + if self.out_f.suffix in (".webp", ".apng", ".png"): return self._fix_fps_duration(fps, 1000) - else: - return self._fix_fps_pyav(fps) + + return self._fix_fps_pyav(fps) def _fix_fps_duration(self, fps: float, denominator: int) -> Fraction: delay = int(rounding(denominator / fps)) fps_fraction = Fraction(denominator, delay) if self.opt_comp.fps_max and fps_fraction > self.opt_comp.fps_max: return Fraction(denominator, (delay + 1)) - elif self.opt_comp.fps_min and fps_fraction < self.opt_comp.fps_min: + if self.opt_comp.fps_min and fps_fraction < self.opt_comp.fps_min: return Fraction(denominator, (delay - 1)) return fps_fraction diff --git a/src/sticker_convert/definitions.py b/src/sticker_convert/definitions.py index 5a144a77..dfd8d791 100644 --- a/src/sticker_convert/definitions.py +++ b/src/sticker_convert/definitions.py @@ -48,8 +48,7 @@ def check_root_dir_exe_writable() -> bool: or "site-packages" in ROOT_DIR_EXE.as_posix() ): return False - else: - return True + return True ROOT_DIR_EXE_WRITABLE = check_root_dir_exe_writable() @@ -58,13 +57,11 @@ def check_root_dir_exe_writable() -> bool: def get_default_dir() -> Path: if ROOT_DIR_EXE_WRITABLE: return ROOT_DIR_EXE - else: - home_dir = Path.home() - desktop_dir = home_dir / "Desktop" - if desktop_dir.is_dir(): - return desktop_dir - else: - return home_dir + home_dir = Path.home() + desktop_dir = home_dir / "Desktop" + if desktop_dir.is_dir(): + return desktop_dir + return home_dir # Default directory for stickers_input and stickers_output @@ -79,9 +76,8 @@ def get_config_dir() -> Path: if ROOT_DIR_EXE_WRITABLE: return ROOT_DIR_EXE - else: - os.makedirs(fallback_dir, exist_ok=True) - return fallback_dir + os.makedirs(fallback_dir, exist_ok=True) + return fallback_dir # Directory for saving configs diff --git a/src/sticker_convert/downloaders/download_base.py b/src/sticker_convert/downloaders/download_base.py index e53857d1..c8b74d9e 100755 --- a/src/sticker_convert/downloaders/download_base.py +++ b/src/sticker_convert/downloaders/download_base.py @@ -75,8 +75,7 @@ def download_file( if response.status_code != 200: return b"" - else: - self.cb.put(f"Downloading {url}") + self.cb.put(f"Downloading {url}") if show_progress: steps = (total_length / chunk_size) + 1 @@ -101,11 +100,10 @@ def download_file( if not result: return b"" - elif dest: + if dest: with open(dest, "wb+") as f: f.write(result) msg = f"Downloaded {url}" self.cb.put(msg) return b"" - else: - return result + return result diff --git a/src/sticker_convert/downloaders/download_kakao.py b/src/sticker_convert/downloaders/download_kakao.py index a6f5378e..48bc224f 100755 --- a/src/sticker_convert/downloaders/download_kakao.py +++ b/src/sticker_convert/downloaders/download_kakao.py @@ -41,7 +41,7 @@ def get_info_from_share_link(url: str) -> Tuple[Optional[str], Optional[str]]: data_urls = app_scheme_link_tag.get("data-url") if not data_urls: return None, None - elif isinstance(data_urls, list): + if isinstance(data_urls, list): data_url = data_urls[0] else: data_url = data_urls @@ -113,7 +113,7 @@ def get_title_from_id(item_code: str, auth_token: str) -> Optional[str]: class DownloadKakao(DownloadBase): def __init__(self, *args: Any, **kwargs: Any) -> None: - super(DownloadKakao, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.pack_title: Optional[str] = None self.author: Optional[str] = None @@ -129,13 +129,10 @@ def download_stickers_kakao(self) -> bool: if item_code: return self.download_animated(item_code) - else: - self.cb.put( - "Download failed: Cannot download metadata for sticker pack" - ) - return False + self.cb.put("Download failed: Cannot download metadata for sticker pack") + return False - elif self.url.isnumeric() or self.url.startswith("kakaotalk://store/emoticon/"): + if self.url.isnumeric() or self.url.startswith("kakaotalk://store/emoticon/"): item_code = self.url.replace("kakaotalk://store/emoticon/", "") self.pack_title = None @@ -150,7 +147,7 @@ def download_stickers_kakao(self) -> bool: return self.download_animated(item_code) - elif urlparse(self.url).netloc == "e.kakao.com": + if urlparse(self.url).netloc == "e.kakao.com": self.pack_title = self.url.replace("https://e.kakao.com/t/", "") ( self.author, @@ -172,24 +169,22 @@ def download_stickers_kakao(self) -> bool: item_code = MetadataKakao.get_item_code(title_ko, auth_token) if item_code: return self.download_animated(item_code) + msg = "Warning: Cannot get item code.\n" + msg += "Is auth_token invalid / expired? Try to regenerate it.\n" + msg += "Continue to download static stickers instead?" + self.cb.put(("ask_bool", (msg,), None)) + if self.cb_return: + response = self.cb_return.get_response() else: - msg = "Warning: Cannot get item code.\n" - msg += "Is auth_token invalid / expired? Try to regenerate it.\n" - msg += "Continue to download static stickers instead?" - self.cb.put(("ask_bool", (msg,), None)) - if self.cb_return: - response = self.cb_return.get_response() - else: - response = False - - if response is False: - return False + response = False + + if response is False: + return False return self.download_static(thumbnail_urls) - else: - self.cb.put("Download failed: Unrecognized URL") - return False + self.cb.put("Download failed: Unrecognized URL") + return False def download_static(self, thumbnail_urls: str) -> bool: MetadataHandler.set_metadata( diff --git a/src/sticker_convert/downloaders/download_line.py b/src/sticker_convert/downloaders/download_line.py index d6197d80..4ffff948 100755 --- a/src/sticker_convert/downloaders/download_line.py +++ b/src/sticker_convert/downloaders/download_line.py @@ -23,7 +23,7 @@ from sticker_convert.utils.files.metadata_handler import MetadataHandler from sticker_convert.utils.media.apple_png_normalize import ApplePngNormalize -"""Reference: https://github.com/doubleplusc/Line-sticker-downloader/blob/master/sticker_dl.py""" +# Reference: https://github.com/doubleplusc/Line-sticker-downloader/blob/master/sticker_dl.py class MetadataLine: @@ -162,7 +162,7 @@ def get_metadata_stickers( class DownloadLine(DownloadBase): def __init__(self, *args: Any, **kwargs: Any) -> None: - super(DownloadLine, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.headers = { "referer": "https://store.line.me", "user-agent": "Android", @@ -444,13 +444,13 @@ def download_stickers_line(self) -> bool: self.decompress_stickers(zip_file) custom_sticker_text_urls: List[Tuple[str, Path]] = [] - if self.sticker_text_dict != {} and ( + if self.sticker_text_dict and ( self.resource_type == "PER_STICKER_TEXT" - or (self.resource_type == "NAME_TEXT" and self.cookies != {}) + or (self.resource_type == "NAME_TEXT" and self.cookies) ): self.edit_custom_sticker_text() custom_sticker_text_urls = self.get_custom_sticker_text_urls() - elif self.resource_type == "NAME_TEXT" and self.cookies == {}: + elif self.resource_type == "NAME_TEXT" and not self.cookies: self.cb.put('Warning: Line "Custom stickers" is supplied as input') self.cb.put( "However, adding custom message requires Line cookies, and it is not supplied" diff --git a/src/sticker_convert/downloaders/download_signal.py b/src/sticker_convert/downloaders/download_signal.py index d49e977e..af6139ae 100755 --- a/src/sticker_convert/downloaders/download_signal.py +++ b/src/sticker_convert/downloaders/download_signal.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from pathlib import Path from queue import Queue -from typing import Any, Dict, Optional, Union +from typing import Dict, Optional, Union import anyio from signalstickers_client import StickersClient # type: ignore @@ -17,8 +17,8 @@ class DownloadSignal(DownloadBase): - def __init__(self, *args: Any, **kwargs: Any) -> None: - super(DownloadSignal, self).__init__(*args, **kwargs) + # def __init__(self, *args: Any, **kwargs: Any) -> None: + # super().__init__(*args, **kwargs) @staticmethod async def get_pack(pack_id: str, pack_key: str) -> StickerPack: diff --git a/src/sticker_convert/downloaders/download_telegram.py b/src/sticker_convert/downloaders/download_telegram.py index b92921ea..c7b6ce88 100755 --- a/src/sticker_convert/downloaders/download_telegram.py +++ b/src/sticker_convert/downloaders/download_telegram.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from pathlib import Path from queue import Queue -from typing import Any, Dict, Optional, Union +from typing import Dict, Optional, Union from urllib.parse import urlparse import anyio @@ -16,8 +16,8 @@ class DownloadTelegram(DownloadBase): - def __init__(self, *args: Any, **kwargs: Any) -> None: - super(DownloadTelegram, self).__init__(*args, **kwargs) + # def __init__(self, *args: Any, **kwargs: Any) -> None: + # super().__init__(*args, **kwargs) def download_stickers_telegram(self) -> bool: self.token = "" diff --git a/src/sticker_convert/gui.py b/src/sticker_convert/gui.py index e4cefcd2..31ab733a 100755 --- a/src/sticker_convert/gui.py +++ b/src/sticker_convert/gui.py @@ -35,7 +35,7 @@ class GUI(Window): def __init__(self) -> None: - super(GUI, self).__init__(themename="darkly", alpha=0) # type: ignore + super().__init__(themename="darkly", alpha=0) # type: ignore self.init_done = False self.load_jsons() @@ -224,7 +224,7 @@ def load_jsons(self) -> None: try: from sticker_convert.utils.files.json_resources_loader import COMPRESSION_JSON, EMOJI_JSON, HELP_JSON, INPUT_JSON, OUTPUT_JSON except RuntimeError as e: - self.cb_msg(e.__str__()) + self.cb_msg(str(e)) return self.help = HELP_JSON @@ -399,12 +399,12 @@ def get_output_name(self) -> str: if v["full_name"] == self.output_option_true_var.get() ][0] - def get_output_display_name(self) -> str: - return [ - k - for k, v in self.output_presets.items() - if v["full_name"] == self.output_option_display_var.get() - ][0] + # def get_output_display_name(self) -> str: + # return [ + # k + # for k, v in self.output_presets.items() + # if v["full_name"] == self.output_option_display_var.get() + # ][0] def get_preset(self) -> str: selection = self.comp_preset_var.get() @@ -412,13 +412,11 @@ def get_preset(self) -> str: output_option = self.get_output_name() if output_option == "imessage": return "imessage_small" - elif output_option == "local": + if output_option == "local": return selection - else: - return output_option + return output_option - else: - return selection + return selection def start_job(self) -> None: self.save_config() @@ -569,7 +567,7 @@ def set_inputs(self, state: str) -> None: self.input_frame.cb_input_option() self.comp_frame.cb_no_compress() - def exec_in_main(self, evt: Any) -> Any: + def exec_in_main(self, _evt: Any) -> Any: if self.action: self.response = self.action() self.response_event.set() @@ -617,10 +615,10 @@ def cb_msg(self, *args: Any, **kwargs: Any) -> None: def cb_msg_block( self, + *args: Any, message: Optional[str] = None, parent: Optional[object] = None, - *args: Any, - **kwargs: Any, + **_kwargs: Any, ) -> Any: if message is None and len(args) > 0: message = " ".join(str(i) for i in args) @@ -638,10 +636,10 @@ def cb_msg_block( def cb_bar( self, + *args: Any, set_progress_mode: Optional[str] = None, steps: int = 0, update_bar: bool = False, - *args: Any, **kwargs: Any, ): with self.bar_lock: @@ -659,13 +657,10 @@ def highlight_fields(self) -> bool: # output_option_display = self.get_output_display_name() url = self.input_address_var.get() - if ( + in_out_dir_same = ( Path(self.input_setdir_var.get()).absolute() == Path(self.output_setdir_var.get()).absolute() - ): - in_out_dir_same = True - else: - in_out_dir_same = False + ) # Input if in_out_dir_same is True: diff --git a/src/sticker_convert/gui_components/frames/comp_frame.py b/src/sticker_convert/gui_components/frames/comp_frame.py index 08105f2d..cf1e6bdb 100644 --- a/src/sticker_convert/gui_components/frames/comp_frame.py +++ b/src/sticker_convert/gui_components/frames/comp_frame.py @@ -3,17 +3,17 @@ from ttkbootstrap import Button, Checkbutton, Entry, Label, LabelFrame, OptionMenu # type: ignore -if TYPE_CHECKING: - from sticker_convert.gui import GUI # type: ignore - from sticker_convert.gui_components.frames.right_clicker import RightClicker from sticker_convert.gui_components.windows.advanced_compression_window import AdvancedCompressionWindow +if TYPE_CHECKING: + from sticker_convert.gui import GUI # type: ignore + class CompFrame(LabelFrame): def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: self.gui = gui - super(CompFrame, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.grid_columnconfigure(2, weight=1) @@ -102,7 +102,7 @@ def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: self.cb_comp_apply_preset() self.cb_no_compress() - def cb_comp_apply_preset(self, *args: Any) -> None: + def cb_comp_apply_preset(self, *_: Any) -> None: selection = self.gui.get_preset() if selection == "auto": if self.gui.get_input_name() == "local": @@ -181,10 +181,10 @@ def cb_comp_apply_preset(self, *args: Any) -> None: self.cb_no_compress() self.gui.highlight_fields() - def cb_compress_advanced(self, *args: Any) -> None: + def cb_compress_advanced(self, *_: Any) -> None: AdvancedCompressionWindow(self.gui) - def cb_no_compress(self, *args: Any) -> None: + def cb_no_compress(self, *_: Any) -> None: if self.gui.no_compress_var.get() is True: state = "disabled" else: diff --git a/src/sticker_convert/gui_components/frames/config_frame.py b/src/sticker_convert/gui_components/frames/config_frame.py index b1e7f0fd..05d25ff4 100644 --- a/src/sticker_convert/gui_components/frames/config_frame.py +++ b/src/sticker_convert/gui_components/frames/config_frame.py @@ -5,17 +5,17 @@ from ttkbootstrap import Button, Checkbutton, Label, LabelFrame # type: ignore -if TYPE_CHECKING: - from sticker_convert.gui import GUI # type: ignore - from sticker_convert.definitions import CONFIG_DIR from sticker_convert.utils.files.run_bin import RunBin +if TYPE_CHECKING: + from sticker_convert.gui import GUI # type: ignore + class ConfigFrame(LabelFrame): def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: self.gui = gui - super(ConfigFrame, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.grid_columnconfigure(1, weight=1) self.grid_columnconfigure(3, weight=1) @@ -77,7 +77,7 @@ def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: column=3, row=1, sticky="w", padx=3, pady=3 ) - def cb_clear_cred(self, *args: Any, **kwargs: Any) -> None: + def cb_clear_cred(self, *_: Any, **kwargs: Any) -> None: response = self.gui.cb_ask_bool("Are you sure you want to clear credentials?") if response is True: self.gui.delete_creds() @@ -86,7 +86,7 @@ def cb_clear_cred(self, *args: Any, **kwargs: Any) -> None: self.gui.highlight_fields() self.gui.cb_msg_block("Credentials cleared.") - def cb_restore_default(self, *args: Any, **kwargs: Any) -> None: + def cb_restore_default(self, *_: Any, **kwargs: Any) -> None: response = self.gui.cb_ask_bool( "Are you sure you want to restore default config? (This will not clear credentials.)" ) @@ -97,7 +97,7 @@ def cb_restore_default(self, *args: Any, **kwargs: Any) -> None: self.gui.highlight_fields() self.gui.cb_msg_block("Restored to default config.") - def cb_open_config_directory(self, *args: Any, **kwargs: Any) -> None: + def cb_open_config_directory(self, *_: Any, **kwargs: Any) -> None: self.gui.cb_msg(msg=f"Config is located at {CONFIG_DIR}") if platform.system() == "Windows": os.startfile(CONFIG_DIR) # type: ignore diff --git a/src/sticker_convert/gui_components/frames/control_frame.py b/src/sticker_convert/gui_components/frames/control_frame.py index 664fe263..5b0258a1 100644 --- a/src/sticker_convert/gui_components/frames/control_frame.py +++ b/src/sticker_convert/gui_components/frames/control_frame.py @@ -10,7 +10,7 @@ class ControlFrame(Frame): def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: self.gui = gui - super(ControlFrame, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.start_btn = Button( self, diff --git a/src/sticker_convert/gui_components/frames/cred_frame.py b/src/sticker_convert/gui_components/frames/cred_frame.py index 09e45420..8430c96c 100644 --- a/src/sticker_convert/gui_components/frames/cred_frame.py +++ b/src/sticker_convert/gui_components/frames/cred_frame.py @@ -4,19 +4,19 @@ from ttkbootstrap import Button, Entry, Label, LabelFrame # type: ignore -if TYPE_CHECKING: - from sticker_convert.gui import GUI # type: ignore - from sticker_convert.gui_components.frames.right_clicker import RightClicker from sticker_convert.gui_components.windows.kakao_get_auth_window import KakaoGetAuthWindow from sticker_convert.gui_components.windows.line_get_auth_window import LineGetAuthWindow from sticker_convert.gui_components.windows.signal_get_auth_window import SignalGetAuthWindow +if TYPE_CHECKING: + from sticker_convert.gui import GUI # type: ignore + class CredFrame(LabelFrame): def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: self.gui = gui - super(CredFrame, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.grid_columnconfigure(1, weight=1) @@ -135,19 +135,19 @@ def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: self.line_get_auth_btn.grid(column=2, row=6, sticky="e", padx=3, pady=3) self.help_btn.grid(column=2, row=8, sticky="e", padx=3, pady=3) - def cb_cred_help(self, *args: Any) -> None: + def cb_cred_help(self, *_: Any) -> None: faq_site = "https://github.com/laggykiller/sticker-convert#faq" success = webbrowser.open(faq_site) if not success: self.gui.cb_ask_str("You can get help from:", initialvalue=faq_site) - def cb_kakao_get_auth(self, *args: Any) -> None: + def cb_kakao_get_auth(self, *_: Any) -> None: KakaoGetAuthWindow(self.gui) - def cb_signal_get_auth(self, *args: Any) -> None: + def cb_signal_get_auth(self, *_: Any) -> None: SignalGetAuthWindow(self.gui) - def cb_line_get_auth(self, *args: Any) -> None: + def cb_line_get_auth(self, *_: Any) -> None: LineGetAuthWindow(self.gui) def set_states(self, state: str) -> None: diff --git a/src/sticker_convert/gui_components/frames/input_frame.py b/src/sticker_convert/gui_components/frames/input_frame.py index 0fad9025..ab035a6b 100644 --- a/src/sticker_convert/gui_components/frames/input_frame.py +++ b/src/sticker_convert/gui_components/frames/input_frame.py @@ -5,18 +5,18 @@ from ttkbootstrap import Button, Entry, Label, LabelFrame, OptionMenu # type: ignore -if TYPE_CHECKING: - from sticker_convert.gui import GUI # type: ignore - from sticker_convert.definitions import DEFAULT_DIR from sticker_convert.gui_components.frames.right_clicker import RightClicker from sticker_convert.utils.url_detect import UrlDetect +if TYPE_CHECKING: + from sticker_convert.gui import GUI # type: ignore + class InputFrame(LabelFrame): def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: self.gui = gui - super(InputFrame, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.input_option_lbl = Label( self, text="Input source", width=15, justify="left", anchor="w" @@ -100,7 +100,7 @@ def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: else: self.address_entry.config(state="normal") - def cb_set_indir(self, *args: Any) -> None: + def cb_set_indir(self, *_args: Any) -> None: orig_input_dir = self.gui.input_setdir_var.get() if not Path(orig_input_dir).is_dir(): orig_input_dir = DEFAULT_DIR @@ -108,7 +108,7 @@ def cb_set_indir(self, *args: Any) -> None: if input_dir: self.gui.input_setdir_var.set(input_dir) - def cb_input_option(self, *args: Any) -> bool: + def cb_input_option(self, *_: Any) -> bool: input_option_display = self.gui.get_input_display_name() if input_option_display == "auto": diff --git a/src/sticker_convert/gui_components/frames/output_frame.py b/src/sticker_convert/gui_components/frames/output_frame.py index dff943c9..e3d0f170 100644 --- a/src/sticker_convert/gui_components/frames/output_frame.py +++ b/src/sticker_convert/gui_components/frames/output_frame.py @@ -5,17 +5,17 @@ from ttkbootstrap import Button, Entry, Label, LabelFrame, OptionMenu # type: ignore -if TYPE_CHECKING: - from sticker_convert.gui import GUI # type: ignore - from sticker_convert.definitions import DEFAULT_DIR from sticker_convert.gui_components.frames.right_clicker import RightClicker +if TYPE_CHECKING: + from sticker_convert.gui import GUI # type: ignore + class OutputFrame(LabelFrame): def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: self.gui = gui - super(OutputFrame, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.output_option_lbl = Label( self, text="Output options", width=18, justify="left", anchor="w" @@ -89,7 +89,7 @@ def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: column=1, columnspan=2, row=3, sticky="w", padx=3, pady=3 ) - def cb_set_outdir(self, *args: Any) -> None: + def cb_set_outdir(self, *_args: Any) -> None: orig_output_dir = self.gui.output_setdir_var.get() if not Path(orig_output_dir).is_dir(): orig_output_dir = DEFAULT_DIR @@ -97,7 +97,7 @@ def cb_set_outdir(self, *args: Any) -> None: if output_dir: self.gui.output_setdir_var.set(output_dir) - def cb_output_option(self, *args: Any) -> None: + def cb_output_option(self, *_: Any) -> None: self.gui.output_option_true_var.set(self.gui.output_option_display_var.get()) self.gui.comp_frame.cb_comp_apply_preset() self.gui.highlight_fields() diff --git a/src/sticker_convert/gui_components/frames/progress_frame.py b/src/sticker_convert/gui_components/frames/progress_frame.py index 32f76617..6cd17b3d 100644 --- a/src/sticker_convert/gui_components/frames/progress_frame.py +++ b/src/sticker_convert/gui_components/frames/progress_frame.py @@ -5,11 +5,11 @@ from ttkbootstrap import LabelFrame, Progressbar # type: ignore from ttkbootstrap.scrolled import ScrolledText # type: ignore +from sticker_convert.gui_components.frames.right_clicker import RightClicker + if TYPE_CHECKING: from sticker_convert.gui import GUI # type: ignore -from sticker_convert.gui_components.frames.right_clicker import RightClicker - class ProgressFrame(LabelFrame): progress_bar_cli = None @@ -18,7 +18,7 @@ class ProgressFrame(LabelFrame): def __init__(self, gui: "GUI", *args: Any, **kwargs: Any) -> None: self.gui = gui - super(ProgressFrame, self).__init__(*args, **kwargs) # type: ignore + super().__init__(*args, **kwargs) # type: ignore self.message_box = ScrolledText(self, height=15, wrap="word") self.message_box._text.bind("", RightClicker) # type: ignore @@ -90,8 +90,8 @@ def update_message_box(self, *args: Any, **kwargs: Any) -> None: self.message_box._text.config(state="disabled") # type: ignore - def cb_disable_autoscroll(self, *args: Any) -> None: + def cb_disable_autoscroll(self, *_: Any) -> None: self.auto_scroll = False - def cb_enable_autoscroll(self, *args: Any) -> None: + def cb_enable_autoscroll(self, *_: Any) -> None: self.auto_scroll = True diff --git a/src/sticker_convert/gui_components/gui_utils.py b/src/sticker_convert/gui_components/gui_utils.py index 319c8169..93e2fecc 100644 --- a/src/sticker_convert/gui_components/gui_utils.py +++ b/src/sticker_convert/gui_components/gui_utils.py @@ -80,10 +80,8 @@ def finalize_window(window: Union["GUI", "BaseWindow"]) -> None: window_width = frame_width + window.y_scrollbar.winfo_width() window_height = frame_height + window.x_scrollbar.winfo_height() - if window_width > screen_width: - window_width = screen_width - if window_height > screen_height: - window_height = screen_height + window_width = min(window_width, screen_width) + window_height = min(window_height, screen_height) frame_width = window_width - window.y_scrollbar.winfo_width() frame_height = window_height - window.x_scrollbar.winfo_height() diff --git a/src/sticker_convert/gui_components/windows/advanced_compression_window.py b/src/sticker_convert/gui_components/windows/advanced_compression_window.py index 69f7465e..37fd0cd7 100644 --- a/src/sticker_convert/gui_components/windows/advanced_compression_window.py +++ b/src/sticker_convert/gui_components/windows/advanced_compression_window.py @@ -18,7 +18,7 @@ class AdvancedCompressionWindow(BaseWindow): emoji_btns: List[Tuple[Button, ImageTk.PhotoImage]] = [] def __init__(self, *args: Any, **kwargs: Any) -> None: - super(AdvancedCompressionWindow, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.categories = list({entry["category"] for entry in self.gui.emoji_list}) self.title("Advanced compression options") @@ -559,7 +559,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: GUIUtils.finalize_window(self) - def cb_disable_fps(self, *args: Any) -> None: + def cb_disable_fps(self, *_: Any) -> None: if self.gui.fps_disable_var.get() is True: state = "disabled" else: @@ -568,7 +568,7 @@ def cb_disable_fps(self, *args: Any) -> None: self.fps_min_entry.config(state=state) self.fps_max_entry.config(state=state) - def cb_disable_res_w(self, *args: Any) -> None: + def cb_disable_res_w(self, *_: Any) -> None: if self.gui.res_w_disable_var.get() is True: state = "disabled" else: @@ -577,7 +577,7 @@ def cb_disable_res_w(self, *args: Any) -> None: self.res_w_min_entry.config(state=state) self.res_w_max_entry.config(state=state) - def cb_disable_res_h(self, *args: Any) -> None: + def cb_disable_res_h(self, *_: Any) -> None: if self.gui.res_h_disable_var.get() is True: state = "disabled" else: @@ -586,7 +586,7 @@ def cb_disable_res_h(self, *args: Any) -> None: self.res_h_min_entry.config(state=state) self.res_h_max_entry.config(state=state) - def cb_disable_quality(self, *args: Any) -> None: + def cb_disable_quality(self, *_: Any) -> None: if self.gui.quality_disable_var.get() is True: state = "disabled" else: @@ -595,7 +595,7 @@ def cb_disable_quality(self, *args: Any) -> None: self.quality_min_entry.config(state=state) self.quality_max_entry.config(state=state) - def cb_disable_color(self, *args: Any) -> None: + def cb_disable_color(self, *_: Any) -> None: if self.gui.color_disable_var.get() is True: state = "disabled" else: @@ -604,7 +604,7 @@ def cb_disable_color(self, *args: Any) -> None: self.color_min_entry.config(state=state) self.color_max_entry.config(state=state) - def cb_disable_duration(self, *args: Any) -> None: + def cb_disable_duration(self, *_: Any) -> None: if ( self.gui.duration_disable_var.get() is True or self.gui.comp_preset_var.get() == "auto" @@ -616,7 +616,7 @@ def cb_disable_duration(self, *args: Any) -> None: self.duration_min_entry.config(state=state) self.duration_max_entry.config(state=state) - def cb_disable_size(self, *args: Any) -> None: + def cb_disable_size(self, *_: Any) -> None: if ( self.gui.size_disable_var.get() is True or self.gui.comp_preset_var.get() == "auto" @@ -628,7 +628,7 @@ def cb_disable_size(self, *args: Any) -> None: self.img_size_max_entry.config(state=state) self.vid_size_max_entry.config(state=state) - def cb_disable_format(self, *args: Any) -> None: + def cb_disable_format(self, *_: Any) -> None: if self.gui.comp_preset_var.get() == "auto": state = "disabled" else: @@ -637,7 +637,7 @@ def cb_disable_format(self, *args: Any) -> None: self.img_format_entry.config(state=state) self.vid_format_entry.config(state=state) - def cb_disable_fake_vid(self, *args: Any) -> None: + def cb_disable_fake_vid(self, *_: Any) -> None: if self.gui.comp_preset_var.get() == "auto": state = "disabled" else: @@ -657,7 +657,7 @@ def set_emoji_btn(self) -> None: self.ph_im = ImageTk.PhotoImage(self.im) self.default_emoji_dsp.config(image=self.ph_im) - def render_emoji_list(self, *args: Any) -> None: + def render_emoji_list(self, *_: Any) -> None: category = self.categories_var.get() for emoji_btn, ph_im in self.emoji_btns: diff --git a/src/sticker_convert/gui_components/windows/base_window.py b/src/sticker_convert/gui_components/windows/base_window.py index 7cf1b67b..7986d629 100644 --- a/src/sticker_convert/gui_components/windows/base_window.py +++ b/src/sticker_convert/gui_components/windows/base_window.py @@ -4,15 +4,15 @@ from ttkbootstrap import Toplevel # type: ignore +from sticker_convert.gui_components.gui_utils import GUIUtils + if TYPE_CHECKING: from sticker_convert.gui import GUI # type: ignore -from sticker_convert.gui_components.gui_utils import GUIUtils - class BaseWindow(Toplevel): def __init__(self, gui: "GUI") -> None: - super(BaseWindow, self).__init__(alpha=0) # type: ignore + super().__init__(alpha=0) # type: ignore self.gui = gui GUIUtils.set_icon(self) diff --git a/src/sticker_convert/gui_components/windows/kakao_get_auth_window.py b/src/sticker_convert/gui_components/windows/kakao_get_auth_window.py index 6057ac61..64019259 100644 --- a/src/sticker_convert/gui_components/windows/kakao_get_auth_window.py +++ b/src/sticker_convert/gui_components/windows/kakao_get_auth_window.py @@ -13,7 +13,7 @@ class KakaoGetAuthWindow(BaseWindow): def __init__(self, *args: Any, **kwargs: Any) -> None: - super(KakaoGetAuthWindow, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.title("Get Kakao auth_token") @@ -162,7 +162,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: def cb_login(self) -> None: Thread(target=self.cb_login_thread, daemon=True).start() - def cb_login_thread(self, *args: Any) -> None: + def cb_login_thread(self, *_: Any) -> None: self.gui.save_creds() m = GetKakaoAuth( opt_cred=self.gui.get_opt_cred(), diff --git a/src/sticker_convert/gui_components/windows/line_get_auth_window.py b/src/sticker_convert/gui_components/windows/line_get_auth_window.py index 18e1ec7b..3f825453 100644 --- a/src/sticker_convert/gui_components/windows/line_get_auth_window.py +++ b/src/sticker_convert/gui_components/windows/line_get_auth_window.py @@ -13,7 +13,7 @@ class LineGetAuthWindow(BaseWindow): def __init__(self, *args: Any, **kwargs: Any) -> None: - super(LineGetAuthWindow, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.title("Get Line cookie") @@ -80,7 +80,7 @@ def cb_open_browser(self) -> None: def cb_get_cookies(self) -> None: Thread(target=self.cb_get_cookies_thread, daemon=True).start() - def cb_get_cookies_thread(self, *args: Any) -> None: + def cb_get_cookies_thread(self, *_: Any) -> None: m = GetLineAuth() line_cookies = None diff --git a/src/sticker_convert/gui_components/windows/signal_get_auth_window.py b/src/sticker_convert/gui_components/windows/signal_get_auth_window.py index cf126dd0..62733b44 100644 --- a/src/sticker_convert/gui_components/windows/signal_get_auth_window.py +++ b/src/sticker_convert/gui_components/windows/signal_get_auth_window.py @@ -14,7 +14,7 @@ class SignalGetAuthWindow(BaseWindow): def __init__(self, *args: Any, **kwargs: Any) -> None: - super(SignalGetAuthWindow, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.title("Get Signal uuid and password") diff --git a/src/sticker_convert/job.py b/src/sticker_convert/job.py index 1e1533e5..da16fc24 100755 --- a/src/sticker_convert/job.py +++ b/src/sticker_convert/job.py @@ -94,13 +94,13 @@ def cb_thread( else: args = tuple() if len(i) >= 3: - kwargs: Dict[str, str] = i[2] if i[2] else dict() + kwargs: Dict[str, str] = i[2] if i[2] else {} else: - kwargs = dict() + kwargs = {} else: action = i args = tuple() - kwargs = dict() + kwargs = {} if action == "msg": self.cb_msg(*args, **kwargs) elif action == "bar": @@ -186,7 +186,7 @@ def join_workers(self) -> None: self.processes.clear() - def kill_workers(self, *args: Any, **kwargs: Any) -> None: + def kill_workers(self, *_: Any, **__: Any) -> None: self.is_cancel_job.value = 1 # type: ignore while not self.work_queue.empty(): self.work_queue.get() @@ -206,8 +206,7 @@ def cleanup(self) -> None: def get_result(self) -> Generator[Any, None, None]: gen: Iterator[Any] = iter(self.results_queue.get, None) - for result in gen: - yield result + yield from gen def cb( self, @@ -279,7 +278,7 @@ def start(self) -> int: code = 2 self.executor.cb("Job cancelled.") break - elif not success: + if not success: code = 1 self.executor.cb("An error occured during this run.") break @@ -289,7 +288,7 @@ def start(self) -> int: return code - def cancel(self, *args: Any, **kwargs: Any) -> None: + def cancel(self, *_: Any, **_kwargs: Any) -> None: self.executor.kill_workers() def verify_input(self) -> bool: @@ -450,7 +449,7 @@ def verify_input(self) -> bool: or not any(path.iterdir()) ): continue - elif path_type == "Output" and ( + if path_type == "Output" and ( path.name == "stickers_output" or self.opt_comp.no_compress or not any(path.iterdir()) @@ -458,7 +457,7 @@ def verify_input(self) -> bool: continue related_files = MetadataHandler.get_files_related_to_sticker_convert(path) - if any([i for i in path.iterdir() if i not in related_files]): + if any(i for i in path.iterdir() if i not in related_files): msg = "WARNING: {} directory is set to {}.\n" msg += 'It does not have default name of "{}",\n' msg += "and It seems like it contains PERSONAL DATA.\n" @@ -611,9 +610,7 @@ def compress(self) -> bool: if not in_f.is_file(): continue - elif ( - CodecInfo.get_file_ext(i) in (".txt", ".m4a") or Path(i).stem == "cover" - ): + if CodecInfo.get_file_ext(i) in (".txt", ".m4a") or Path(i).stem == "cover": shutil.copy(in_f, output_dir / i.name) else: in_fs.append(i) @@ -682,7 +679,9 @@ def export(self) -> bool: self.out_urls.extend(result) if self.out_urls: - with open(Path(self.opt_output.dir, "export-result.txt"), "w+") as f: + with open( + Path(self.opt_output.dir, "export-result.txt"), "w+", encoding="utf-8" + ) as f: f.write("\n".join(self.out_urls)) else: self.executor.cb("An error occured while exporting stickers") @@ -696,14 +695,14 @@ def report(self) -> bool: msg += "##########\n" msg += "\n" - if self.compress_fails != []: + if self.compress_fails: msg += f'Warning: Could not compress the following {len(self.compress_fails)} file{"s" if len(self.compress_fails) > 1 else ""}:\n' msg += "\n".join(self.compress_fails) msg += "\n" msg += "\nConsider adjusting compression parameters" msg += "\n" - if self.out_urls != []: + if self.out_urls: msg += "Export results:\n" msg += "\n".join(self.out_urls) else: diff --git a/src/sticker_convert/job_option.py b/src/sticker_convert/job_option.py index 7cfd06f6..7ff09583 100755 --- a/src/sticker_convert/job_option.py +++ b/src/sticker_convert/job_option.py @@ -24,7 +24,7 @@ def __repr__(self) -> str: return json.dumps(self.to_dict(), indent=2) def to_dict(self) -> Dict[str, str]: - return dict() + return {} @dataclass diff --git a/src/sticker_convert/uploaders/compress_wastickers.py b/src/sticker_convert/uploaders/compress_wastickers.py index ba47e3da..cbf2f99e 100755 --- a/src/sticker_convert/uploaders/compress_wastickers.py +++ b/src/sticker_convert/uploaders/compress_wastickers.py @@ -19,7 +19,7 @@ class CompressWastickers(UploadBase): def __init__(self, *args: Any, **kwargs: Any) -> None: - super(CompressWastickers, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.base_spec.size_max_img = 100000 self.base_spec.size_max_vid = 500000 self.base_spec.duration_min = 8 diff --git a/src/sticker_convert/uploaders/upload_signal.py b/src/sticker_convert/uploaders/upload_signal.py index 1ba70d5a..e91602c5 100755 --- a/src/sticker_convert/uploaders/upload_signal.py +++ b/src/sticker_convert/uploaders/upload_signal.py @@ -20,7 +20,7 @@ class UploadSignal(UploadBase): def __init__(self, *args: Any, **kwargs: Any) -> None: - super(UploadSignal, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.base_spec.set_size_max(300000) self.base_spec.set_res_max(512) @@ -117,7 +117,7 @@ def upload_stickers_signal(self) -> List[str]: msg_block += f"Default emoji is set to {self.opt_comp.default_emoji}.\n" msg_block += "Please edit emoji.txt now, then continue" MetadataHandler.generate_emoji_file( - dir=self.opt_output.dir, default_emoji=self.opt_comp.default_emoji + directory=self.opt_output.dir, default_emoji=self.opt_comp.default_emoji ) self.cb.put(("msg_block", (msg_block,), None)) diff --git a/src/sticker_convert/uploaders/upload_telegram.py b/src/sticker_convert/uploaders/upload_telegram.py index 823bbf17..b9b220c7 100755 --- a/src/sticker_convert/uploaders/upload_telegram.py +++ b/src/sticker_convert/uploaders/upload_telegram.py @@ -19,7 +19,7 @@ class UploadTelegram(UploadBase): def __init__(self, *args: Any, **kwargs: Any) -> None: - super(UploadTelegram, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.base_spec.size_max_img = 512000 self.base_spec.size_max_vid = 256000 @@ -209,6 +209,7 @@ async def upload_pack( Path(f"bytes{ext}"), # type: ignore self.opt_comp_cover_merged, self.cb, + self.cb_return, ) try: @@ -248,7 +249,7 @@ def upload_stickers_telegram(self) -> List[str]: msg_block += f"Default emoji is set to {self.opt_comp.default_emoji}.\n" msg_block += "Please edit emoji.txt now, then continue" MetadataHandler.generate_emoji_file( - dir=self.opt_output.dir, default_emoji=self.opt_comp.default_emoji + directory=self.opt_output.dir, default_emoji=self.opt_comp.default_emoji ) self.cb.put(("msg_block", (msg_block,), None)) diff --git a/src/sticker_convert/uploaders/xcode_imessage.py b/src/sticker_convert/uploaders/xcode_imessage.py index 0fb34589..df7b5e7f 100755 --- a/src/sticker_convert/uploaders/xcode_imessage.py +++ b/src/sticker_convert/uploaders/xcode_imessage.py @@ -14,31 +14,15 @@ from sticker_convert.job_option import CompOption, CredOption, OutputOption from sticker_convert.uploaders.upload_base import UploadBase from sticker_convert.utils.callback import Callback, CallbackReturn -from sticker_convert.utils.files.metadata_handler import MetadataHandler +from sticker_convert.utils.files.metadata_handler import XCODE_IMESSAGE_ICONSET, MetadataHandler from sticker_convert.utils.files.sanitize_filename import sanitize_filename from sticker_convert.utils.media.codec_info import CodecInfo from sticker_convert.utils.media.format_verify import FormatVerify -XCODE_IMESSAGE_ICONSET = { - "App-Store-1024x1024pt.png": (1024, 1024), - "iPad-Settings-29pt@2x.png": (58, 58), - "iPhone-settings-29pt@2x.png": (58, 58), - "iPhone-settings-29pt@3x.png": (87, 87), - "Messages27x20pt@2x.png": (54, 40), - "Messages27x20pt@3x.png": (81, 60), - "Messages32x24pt@2x.png": (64, 48), - "Messages32x24pt@3x.png": (96, 72), - "Messages-App-Store-1024x768pt.png": (1024, 768), - "Messages-iPad-67x50pt@2x.png": (134, 100), - "Messages-iPad-Pro-74x55pt@2x.png": (148, 110), - "Messages-iPhone-60x45pt@2x.png": (120, 90), - "Messages-iPhone-60x45pt@3x.png": (180, 135), -} - class XcodeImessage(UploadBase): def __init__(self, *args: Any, **kwargs: Any) -> None: - super(XcodeImessage, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.base_spec.set_size_max(500000) self.base_spec.set_res(300) self.base_spec.set_format(("png", ".apng", ".gif", ".jpeg", "jpg")) @@ -137,9 +121,9 @@ def add_metadata(self, author: str, title: str) -> None: spec_cover.set_fps(0) icon_path = self.opt_output.dir / icon - if Path(icon) in [ - i for i in self.opt_output.dir.iterdir() - ] and not FormatVerify.check_file(icon_path, spec=spec_cover): + if Path(icon) in list( + self.opt_output.dir.iterdir() + ) and not FormatVerify.check_file(icon_path, spec=spec_cover): StickerConvert.convert( icon_path, icon_path, spec_cover, self.cb, self.cb_return ) @@ -244,18 +228,18 @@ def create_xcode_proj(self, author: str, title: str) -> None: } # packname StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/0.sticker/Contents.json - with open(sticker_path / "Contents.json", "w+") as f: + with open(sticker_path / "Contents.json", "w+", encoding="utf-8") as f: json.dump(sticker_json_content, f, indent=2) # packname StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Contents.json - with open(stickers_path / "Contents.json") as f: + with open(stickers_path / "Contents.json", encoding="utf-8") as f: stickerpack_json_content: Dict[str, List[Dict[str, str]]] = json.load(f) stickerpack_json_content["stickers"] = [] for sticker in stickers_lst: stickerpack_json_content["stickers"].append({"filename": sticker}) - with open(stickers_path / "Contents.json", "w+") as f: + with open(stickers_path / "Contents.json", "w+", encoding="utf-8") as f: json.dump(stickerpack_json_content, f, indent=2) # packname StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset diff --git a/src/sticker_convert/utils/auth/get_kakao_auth.py b/src/sticker_convert/utils/auth/get_kakao_auth.py index 5f4579c0..a472140c 100755 --- a/src/sticker_convert/utils/auth/get_kakao_auth.py +++ b/src/sticker_convert/utils/auth/get_kakao_auth.py @@ -117,13 +117,12 @@ def enter_phone(self) -> bool: if self.verify_method == "passcode": return self.verify_receive_sms() - elif self.verify_method == "mo-send": + if self.verify_method == "mo-send": dest_number = response_json["viewData"]["moNumber"] msg = response_json["viewData"]["moMessage"] return self.verify_send_sms(dest_number, msg) - else: - self.cb_msg_block(f"Unknown verification method: {response.text}") - return False + self.cb_msg_block(f"Unknown verification method: {response.text}") + return False def verify_send_sms(self, dest_number: str, msg: str) -> bool: self.cb_msg("Verification by sending SMS") diff --git a/src/sticker_convert/utils/auth/get_line_auth.py b/src/sticker_convert/utils/auth/get_line_auth.py index a362bff7..1eef0409 100755 --- a/src/sticker_convert/utils/auth/get_line_auth.py +++ b/src/sticker_convert/utils/auth/get_line_auth.py @@ -77,5 +77,4 @@ def validate_cookies(cookies: Union[CookieJar, Dict[str, str]]) -> bool: if response_dict["errorMessage"]: return False - else: - return True + return True diff --git a/src/sticker_convert/utils/auth/get_signal_auth.py b/src/sticker_convert/utils/auth/get_signal_auth.py index 81d3484f..e0a94359 100755 --- a/src/sticker_convert/utils/auth/get_signal_auth.py +++ b/src/sticker_convert/utils/auth/get_signal_auth.py @@ -45,10 +45,10 @@ def get_signal_desktop(self) -> Tuple[Optional[str], Optional[str]]: if Path(signal_bin_path_prod).is_file(): return signal_bin_path_prod, signal_user_data_dir_prod - elif Path(signal_bin_path_beta).is_file(): + if Path(signal_bin_path_beta).is_file(): return signal_bin_path_beta, signal_user_data_dir_beta - else: - return None, None + + return None, None def get_cred( self, @@ -76,7 +76,7 @@ def get_cred( msg += f"{signal_user_data_dir=}\n" return None, None, msg - with open(signal_config) as f: + with open(signal_config, encoding="utf-8") as f: config = json.load(f) key = config.get("key") db_key = f"x'{key}'" diff --git a/src/sticker_convert/utils/callback.py b/src/sticker_convert/utils/callback.py index 69f4aadf..74d4f5f3 100644 --- a/src/sticker_convert/utils/callback.py +++ b/src/sticker_convert/utils/callback.py @@ -122,16 +122,15 @@ def cb_ask_bool(self, *args: Any, **kwargs: Any) -> bool: '"--no-confirm" flag is set. Continue with this run without asking questions' ) return True - else: - self.msg( - '[If you do not want to get asked by this question, add "--no-confirm" flag]' - ) - self.msg() - result = input("Continue? [y/N] > ") - if result.lower() != "y": - return False - else: - return True + + self.msg( + '[If you do not want to get asked by this question, add "--no-confirm" flag]' + ) + self.msg() + result = input("Continue? [y/N] > ") + if result.lower() != "y": + return False + return True def cb_ask_str( self, @@ -166,18 +165,18 @@ def put( else: args = tuple() if len(i) >= 3: - kwargs: Dict[str, Any] = i[2] if i[2] else dict() + kwargs: Dict[str, Any] = i[2] if i[2] else {} else: - kwargs = dict() + kwargs = {} else: action = i args = tuple() - kwargs = dict() + kwargs = {} # Fake implementation for Queue.put() if action is None: return None - elif action == "msg": + if action == "msg": self.msg(*args, **kwargs) elif action == "bar": self.bar(**kwargs) diff --git a/src/sticker_convert/utils/files/cache_store.py b/src/sticker_convert/utils/files/cache_store.py index 0cedcfa0..ee4c8ed6 100755 --- a/src/sticker_convert/utils/files/cache_store.py +++ b/src/sticker_convert/utils/files/cache_store.py @@ -2,7 +2,10 @@ import os import platform import shutil +from contextlib import contextmanager from pathlib import Path +from tempfile import TemporaryDirectory +from typing import Any, ContextManager, Generator, Optional, Union from uuid import uuid4 if platform.system() == "Linux": @@ -12,10 +15,6 @@ else: import tempfile -from contextlib import contextmanager -from tempfile import TemporaryDirectory -from typing import Any, ContextManager, Generator, Optional, Union - def debug_cache_dir(path: str) -> ContextManager[Path]: @contextmanager @@ -37,5 +36,4 @@ def get_cache_store( ) -> "Union[ContextManager[Path], TemporaryDirectory[str]]": if path: return debug_cache_dir(path) - else: - return tempfile.TemporaryDirectory() # type: ignore + return tempfile.TemporaryDirectory() # type: ignore diff --git a/src/sticker_convert/utils/files/json_manager.py b/src/sticker_convert/utils/files/json_manager.py index fdd3159a..e8363a1e 100755 --- a/src/sticker_convert/utils/files/json_manager.py +++ b/src/sticker_convert/utils/files/json_manager.py @@ -9,10 +9,9 @@ class JsonManager: def load_json(path: Path) -> Dict[Any, Any]: if not path.is_file(): raise RuntimeError(f"{path} cannot be found") - else: - with open(path, encoding="utf-8") as f: - data = json.load(f) - return data + with open(path, encoding="utf-8") as f: + data = json.load(f) + return data @staticmethod def save_json(path: Path, data: Dict[Any, Any]) -> None: diff --git a/src/sticker_convert/utils/files/metadata_handler.py b/src/sticker_convert/utils/files/metadata_handler.py index 79c274bd..7ff5d380 100755 --- a/src/sticker_convert/utils/files/metadata_handler.py +++ b/src/sticker_convert/utils/files/metadata_handler.py @@ -38,6 +38,22 @@ BLACKLIST_PREFIX = ("cover",) BLACKLIST_SUFFIX = (".txt", ".m4a", ".wastickers", ".DS_Store", "._.DS_Store") +XCODE_IMESSAGE_ICONSET = { + "App-Store-1024x1024pt.png": (1024, 1024), + "iPad-Settings-29pt@2x.png": (58, 58), + "iPhone-settings-29pt@2x.png": (58, 58), + "iPhone-settings-29pt@3x.png": (87, 87), + "Messages27x20pt@2x.png": (54, 40), + "Messages27x20pt@3x.png": (81, 60), + "Messages32x24pt@2x.png": (64, 48), + "Messages32x24pt@3x.png": (96, 72), + "Messages-App-Store-1024x768pt.png": (1024, 768), + "Messages-iPad-67x50pt@2x.png": (134, 100), + "Messages-iPad-Pro-74x55pt@2x.png": (148, 110), + "Messages-iPhone-60x45pt@2x.png": (120, 90), + "Messages-iPhone-60x45pt@3x.png": (180, 135), +} + def check_if_xcodeproj(path: Path) -> bool: if not path.is_dir(): @@ -51,13 +67,11 @@ def check_if_xcodeproj(path: Path) -> bool: class MetadataHandler: @staticmethod def get_files_related_to_sticker_convert( - dir: Path, include_archive: bool = True + directory: Path, include_archive: bool = True ) -> List[Path]: - from sticker_convert.uploaders.xcode_imessage import XCODE_IMESSAGE_ICONSET - files = [ i - for i in sorted(dir.iterdir()) + for i in sorted(directory.iterdir()) if i.stem in RELATED_NAME or i.name in XCODE_IMESSAGE_ICONSET or i.suffix in RELATED_EXTENSIONS @@ -68,13 +82,11 @@ def get_files_related_to_sticker_convert( return files @staticmethod - def get_stickers_present(dir: Path) -> List[Path]: - from sticker_convert.uploaders.xcode_imessage import XCODE_IMESSAGE_ICONSET - + def get_stickers_present(directory: Path) -> List[Path]: stickers_present = [ i - for i in sorted(dir.iterdir()) - if Path(dir, i.name).is_file() + for i in sorted(directory.iterdir()) + if Path(directory, i.name).is_file() and not i.name.startswith(BLACKLIST_PREFIX) and i.suffix not in BLACKLIST_SUFFIX and i.name not in XCODE_IMESSAGE_ICONSET @@ -83,32 +95,32 @@ def get_stickers_present(dir: Path) -> List[Path]: return stickers_present @staticmethod - def get_cover(dir: Path) -> Optional[Path]: - stickers_present = sorted(dir.iterdir()) + def get_cover(directory: Path) -> Optional[Path]: + stickers_present = sorted(directory.iterdir()) for i in stickers_present: if Path(i).stem == "cover": - return Path(dir, i.name) + return Path(directory, i.name) return None @staticmethod def get_metadata( - dir: Path, + directory: Path, title: Optional[str] = None, author: Optional[str] = None, emoji_dict: Optional[Dict[str, str]] = None, ) -> Tuple[Optional[str], Optional[str], Optional[Dict[str, str]]]: - title_path = Path(dir, "title.txt") + title_path = Path(directory, "title.txt") if not title and title_path.is_file(): with open(title_path, encoding="utf-8") as f: title = f.read().strip() - author_path = Path(dir, "author.txt") + author_path = Path(directory, "author.txt") if not author and author_path.is_file(): with open(author_path, encoding="utf-8") as f: author = f.read().strip() - emoji_path = Path(dir, "emoji.txt") + emoji_path = Path(directory, "emoji.txt") if not emoji_dict and emoji_path.is_file(): with open(emoji_path, "r", encoding="utf-8") as f: emoji_dict = json.load(f) @@ -117,22 +129,22 @@ def get_metadata( @staticmethod def set_metadata( - dir: Path, + directory: Path, title: Optional[str] = None, author: Optional[str] = None, emoji_dict: Optional[Dict[str, str]] = None, ): - title_path = Path(dir, "title.txt") + title_path = Path(directory, "title.txt") if title is not None: with open(title_path, "w+", encoding="utf-8") as f: f.write(title) - author_path = Path(dir, "author.txt") + author_path = Path(directory, "author.txt") if author is not None: with open(author_path, "w+", encoding="utf-8") as f: f.write(author) - emoji_path = Path(dir, "emoji.txt") + emoji_path = Path(directory, "emoji.txt") if emoji_dict is not None: with open(emoji_path, "w+", encoding="utf-8") as f: json.dump(emoji_dict, f, indent=4, ensure_ascii=False) @@ -155,7 +167,7 @@ def check_metadata_provided( metadata_provided = metadata_file_path.is_file() if metadata_provided: with open(metadata_file_path, encoding="utf-8") as f: - metadata_provided = True if f.read() else False + metadata_provided = bool(f.read()) else: metadata_provided = input_presets[input_option]["metadata_provides"][ metadata @@ -171,16 +183,16 @@ def check_metadata_required(output_option: str, metadata: str) -> bool: return output_presets[output_option]["metadata_requirements"][metadata] @staticmethod - def generate_emoji_file(dir: Path, default_emoji: str = "") -> None: - emoji_path = Path(dir, "emoji.txt") + def generate_emoji_file(directory: Path, default_emoji: str = "") -> None: + emoji_path = Path(directory, "emoji.txt") emoji_dict = None if emoji_path.is_file(): with open(emoji_path, "r", encoding="utf-8") as f: emoji_dict = json.load(f) emoji_dict_new = {} - for file in sorted(dir.iterdir()): - if not Path(dir, file).is_file() and CodecInfo.get_file_ext(file) in ( + for file in sorted(directory.iterdir()): + if not Path(directory, file).is_file() and CodecInfo.get_file_ext(file) in ( ".txt", ".m4a", ): @@ -196,7 +208,7 @@ def generate_emoji_file(dir: Path, default_emoji: str = "") -> None: @staticmethod def split_sticker_packs( - dir: Path, + directory: Path, title: str, file_per_pack: Optional[int] = None, file_per_anim_pack: Optional[int] = None, @@ -216,7 +228,7 @@ def split_sticker_packs( file_per_anim_pack = file_per_pack file_per_image_pack = file_per_pack - stickers_present = MetadataHandler.get_stickers_present(dir) + stickers_present = MetadataHandler.get_stickers_present(directory) processed = 0 @@ -231,7 +243,7 @@ def split_sticker_packs( image_present = False for processed, file in enumerate(stickers_present): - file_path = dir / file + file_path = directory / file if CodecInfo.is_anim(file_path): anim_stickers.append(file_path) @@ -241,7 +253,7 @@ def split_sticker_packs( anim_present = anim_present or len(anim_stickers) > 0 image_present = image_present or len(image_stickers) > 0 - finished_all = True if processed == len(stickers_present) - 1 else False + finished_all = processed == len(stickers_present) - 1 if len(anim_stickers) == file_per_anim_pack or ( finished_all and len(anim_stickers) > 0 @@ -265,11 +277,11 @@ def split_sticker_packs( pack_count = 0 for processed, file in enumerate(stickers_present): - file_path = Path(dir, file) + file_path = Path(directory, file) stickers.append(file_path) - finished_all = True if processed == len(stickers_present) - 1 else False + finished_all = processed == len(stickers_present) - 1 if len(stickers) == file_per_pack or ( finished_all and len(stickers) > 0 diff --git a/src/sticker_convert/utils/files/run_bin.py b/src/sticker_convert/utils/files/run_bin.py index 8faab4d2..e7b6eaae 100755 --- a/src/sticker_convert/utils/files/run_bin.py +++ b/src/sticker_convert/utils/files/run_bin.py @@ -9,19 +9,19 @@ class RunBin: @staticmethod def get_bin( - bin: str, silent: bool = False, cb_msg: Callable[..., Any] = print + executable: str, silent: bool = False, cb_msg: Callable[..., Any] = print ) -> Union[str, None]: - if Path(bin).is_file(): - return bin + if Path(executable).is_file(): + return executable if platform.system() == "Windows": - bin = bin + ".exe" + executable = executable + ".exe" - which_result = shutil.which(bin) + which_result = shutil.which(executable) if which_result is not None: return str(Path(which_result).resolve()) - elif silent is False: - cb_msg(f"Warning: Cannot find binary file {bin}") + if silent is False: + cb_msg(f"Warning: Cannot find binary file {executable}") return None @@ -46,6 +46,7 @@ def run_cmd( stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + check=False, ) output_str = sp.stdout.decode() diff --git a/src/sticker_convert/utils/files/sanitize_filename.py b/src/sticker_convert/utils/files/sanitize_filename.py index 0e7ca487..c47a44ba 100755 --- a/src/sticker_convert/utils/files/sanitize_filename.py +++ b/src/sticker_convert/utils/files/sanitize_filename.py @@ -46,7 +46,7 @@ def sanitize_filename(filename: str) -> str: filename = unicodedata.normalize("NFKD", filename) filename = filename.rstrip(". ") # Windows does not allow these at end filename = filename.strip() - if all([x == "." for x in filename]): + if all(x == "." for x in filename): filename = "__" + filename if filename in RESERVED_FILENAME: filename = "__" + filename diff --git a/src/sticker_convert/utils/media/apple_png_normalize.py b/src/sticker_convert/utils/media/apple_png_normalize.py index d3a7573c..a22ae593 100755 --- a/src/sticker_convert/utils/media/apple_png_normalize.py +++ b/src/sticker_convert/utils/media/apple_png_normalize.py @@ -56,8 +56,8 @@ def normalize(old_png: bytes) -> bytes: assert width assert height - bufSize = width * height * 4 + height - chunk_data = zlib.decompress(chunk_d, -8, bufSize) + buf_size = width * height * 4 + height + chunk_data = zlib.decompress(chunk_d, -8, buf_size) # Swapping red & blue bytes for each pixel chunk_data = bytearray(chunk_data) diff --git a/src/sticker_convert/utils/media/codec_info.py b/src/sticker_convert/utils/media/codec_info.py index 6c613334..d0d761e0 100755 --- a/src/sticker_convert/utils/media/codec_info.py +++ b/src/sticker_convert/utils/media/codec_info.py @@ -24,7 +24,7 @@ def __init__( ) self.codec = CodecInfo.get_file_codec(file) self.res = CodecInfo.get_file_res(file) - self.is_animated = True if self.fps > 1 else False + self.is_animated = self.fps > 1 @staticmethod def get_file_fps_frames_duration( @@ -63,7 +63,7 @@ def get_file_fps(file: Union[Path, bytes], file_ext: Optional[str] = None) -> fl if file_ext == ".tgs": return CodecInfo._get_file_fps_tgs(file) - elif file_ext == ".webp": + if file_ext == ".webp": frames, duration = CodecInfo._get_file_frames_duration_webp(file) elif file_ext in (".gif", ".apng", ".png"): frames, duration = CodecInfo._get_file_frames_duration_pillow(file) @@ -74,8 +74,7 @@ def get_file_fps(file: Union[Path, bytes], file_ext: Optional[str] = None) -> fl if duration > 0: return frames / duration * 1000 - else: - return 0 + return 0 @staticmethod def get_file_frames( @@ -89,7 +88,7 @@ def get_file_frames( if file_ext == ".tgs": return CodecInfo._get_file_frames_tgs(file) - elif file_ext in (".gif", ".webp", ".png", ".apng"): + if file_ext in (".gif", ".webp", ".png", ".apng"): frames, _ = CodecInfo._get_file_frames_duration_pillow( file, frames_only=True ) @@ -183,7 +182,7 @@ def _get_file_frames_duration_pillow( total_duration = 0 with Image.open(file) as im: - if "n_frames" in im.__dir__(): + if "n_frames" in dir(im): frames = im.n_frames if frames_only is True: return frames, 1 @@ -191,8 +190,8 @@ def _get_file_frames_duration_pillow( im.seek(i) total_duration += im.info.get("duration", 1000) return frames, total_duration - else: - return 1, 0 + + return 1, 0 @staticmethod def _get_file_frames_duration_webp( @@ -201,13 +200,12 @@ def _get_file_frames_duration_webp( total_duration = 0 frames = 0 - f: BinaryIO - if isinstance(file, Path): - f = open(file, "r+b") - else: - f = BytesIO(file) + def _open_f(file: Union[Path, bytes]) -> BinaryIO: + if isinstance(file, Path): + return open(file, "r+b") + return BytesIO(file) - try: + with _open_f(file) as f: with mmap.mmap(f.fileno(), 0) as mm: while True: anmf_pos = mm.find(b"ANMF") @@ -220,13 +218,11 @@ def _get_file_frames_duration_webp( ) total_duration += int.from_bytes(frame_duration, "little") frames += 1 - finally: - f.close() if frames == 0: return 1, 0 - else: - return frames, total_duration + + return frames, total_duration @staticmethod def _get_file_frames_duration_av( @@ -274,11 +270,10 @@ def _get_file_frames_duration_av( ) if frame_count <= 1 or duration_metadata != 0: return frame_count, duration_metadata - else: - duration_n_minus_one = last_frame.pts * time_base_ms - ms_per_frame = duration_n_minus_one / (frame_count - 1) - duration = frame_count * ms_per_frame - return frame_count, int(Decimal(duration).quantize(0, ROUND_HALF_UP)) + duration_n_minus_one = last_frame.pts * time_base_ms + ms_per_frame = duration_n_minus_one / (frame_count - 1) + duration = frame_count * ms_per_frame + return frame_count, int(Decimal(duration).quantize(0, ROUND_HALF_UP)) return 0, 0 @@ -300,7 +295,7 @@ def get_file_codec(file: Union[Path, bytes], file_ext: Optional[str] = None) -> try: with Image.open(file) as im: codec = im.format - if "is_animated" in im.__dir__(): + if "is_animated" in dir(im): animated = im.is_animated else: animated = False @@ -311,9 +306,8 @@ def get_file_codec(file: Union[Path, bytes], file_ext: Optional[str] = None) -> # Unable to distinguish apng and png if animated: return "apng" - else: - return "png" - elif codec is not None: + return "png" + if codec is not None: return codec.lower() import av # type: ignore @@ -375,5 +369,4 @@ def get_file_ext(file: Path) -> str: def is_anim(file: Union[Path, bytes]) -> bool: if CodecInfo.get_file_frames(file, check_anim=True) > 1: return True - else: - return False + return False diff --git a/src/sticker_convert/utils/media/decrypt_kakao.py b/src/sticker_convert/utils/media/decrypt_kakao.py index 3da2f1fe..9303c9ee 100644 --- a/src/sticker_convert/utils/media/decrypt_kakao.py +++ b/src/sticker_convert/utils/media/decrypt_kakao.py @@ -3,11 +3,9 @@ from typing import List -""" -References: -https://github.com/blluv/KakaoTalkEmoticonDownloader -https://github.com/star-39/moe-sticker-bot -""" +# References: +# https://github.com/blluv/KakaoTalkEmoticonDownloader +# https://github.com/star-39/moe-sticker-bot class DecryptKakao: diff --git a/src/sticker_convert/utils/media/format_verify.py b/src/sticker_convert/utils/media/format_verify.py index d51dec5c..d59dfc39 100755 --- a/src/sticker_convert/utils/media/format_verify.py +++ b/src/sticker_convert/utils/media/format_verify.py @@ -40,8 +40,7 @@ def check_file(file: Union[Path, bytes], spec: CompOption) -> bool: def check_presence(file: Union[Path, bytes]) -> bool: if isinstance(file, Path): return Path(file).is_file() - else: - return True + return True @staticmethod def check_file_res( @@ -184,11 +183,10 @@ def check_format( if len(valid_fmt) == 0: return True - elif file_ext in valid_fmt: + if file_ext in valid_fmt: return True - elif file_ext in jpg_exts and (".jpg" in valid_fmt or ".jpeg" in valid_fmt): + if file_ext in jpg_exts and (".jpg" in valid_fmt or ".jpeg" in valid_fmt): return True - elif file_ext in png_exts and (".png" in valid_fmt or ".apng" in valid_fmt): + if file_ext in png_exts and (".png" in valid_fmt or ".apng" in valid_fmt): return True - else: - return False + return False diff --git a/src/sticker_convert/utils/url_detect.py b/src/sticker_convert/utils/url_detect.py index 24608122..89fec958 100755 --- a/src/sticker_convert/utils/url_detect.py +++ b/src/sticker_convert/utils/url_detect.py @@ -12,20 +12,19 @@ def detect(url: str) -> Optional[str]: if domain == "signal.art": return "signal" - elif domain in ("telegram.me", "t.me"): + if domain in ("telegram.me", "t.me"): return "telegram" - elif ( + if ( domain in ("store.line.me", "line.me") or url.startswith("line://shop/detail/") or (len(url) == 24 and all(c in string.hexdigits for c in url)) ): return "line" - elif domain in ("e.kakao.com", "emoticon.kakao.com") or url.startswith( + if domain in ("e.kakao.com", "emoticon.kakao.com") or url.startswith( "kakaotalk://store/emoticon/" ): return "kakao" - else: - return None + return None