From aa26f2b06e9771db6d8f7b60c6a9a6c188ab84e1 Mon Sep 17 00:00:00 2001 From: TLu Date: Tue, 7 Jan 2025 00:25:10 +0100 Subject: [PATCH 1/3] 5.1.5 in progress --- CHANGES.md | 4 +++ LICENSE | 2 +- fotokilof/__main__.py | 18 +++++----- fotokilof/common.py | 19 ++++------- fotokilof/convert_common.py | 29 +++++++++++++---- fotokilof/convert_pillow.py | 65 ++++++++++++++----------------------- fotokilof/convert_wand.py | 61 ++++++++++++++-------------------- fotokilof/gui.py | 7 ++-- fotokilof/magick.py | 6 ++-- fotokilof/version.py | 4 +-- 10 files changed, 103 insertions(+), 112 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 97963a6..3f7cb63 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Changelog +## 2025 + +5.1.5 fixed right mouse button for crop, small code polishing + ## 2024 5.1.4 updated locale and pot file, added missing entry poinyt into toml diff --git a/LICENSE b/LICENSE index 8405159..0b20dfa 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2024 Tomasz Łuczak, TeaM-TL +Copyright (c) 2019-2025 Tomasz Łuczak, TeaM-TL MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/fotokilof/__main__.py b/fotokilof/__main__.py index 227cae0..99ad870 100644 --- a/fotokilof/__main__.py +++ b/fotokilof/__main__.py @@ -7,7 +7,7 @@ # pylint: disable=line-too-long """ -Copyright (c) 2019-2024 Tomasz Łuczak, TeaM-TL +Copyright (c) 2019-2025 Tomasz Łuczak, TeaM-TL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -237,7 +237,7 @@ def preview_new(file_out): preview_new_clear() else: preview_picture = convert_common.preview( - file_out, int(co_preview_selector_new.get()), PILLOW, OS + file_out, int(co_preview_selector_new.get()), PILLOW ) try: pi_preview_new.configure(file=preview_picture["filename"]) @@ -856,7 +856,7 @@ def open_file(): def open_file_common(cwd, filename): """common function for: open, first, last, next, prev""" if filename is not None: - file_in_path.set(common.spacja(os.path.join(cwd, filename), OS)) + file_in_path.set(common.spacja(os.path.join(cwd, filename))) root.title(window_title + file_in_path.get()) image_size = convert_common.get_image_size(file_in_path.get(), PILLOW) if image_size != (0, 0): @@ -983,7 +983,7 @@ def open_screenshot(): except: if OS == "UNIX": message = _( - "Sorry, xclip (X11) or wl-clipboard (Wayland) is not installed\n Install xclip or wl-clipboard and try again!" + "Sorry, nothing in clipboard\nOr xclip (X11) or wl-clipboard (Wayland) is not installed\n Install xclip or wl-clipboard and try again!" ) Messagebox.show_error(message, title=_("Missing package")) try: @@ -1528,7 +1528,6 @@ def preview_orig(): file_in_path.get(), int(co_preview_selector_orig.get()), PILLOW, - OS, crop_rectangle, ) @@ -1564,7 +1563,7 @@ def preview_logo(): if os.path.isfile(file_logo_path.get()): l_logo_filename.configure(text=os.path.basename(file_logo_path.get())) preview_picture = convert_common.preview( - file_logo_path.get(), PREVIEW_LOGO, PILLOW, OS + file_logo_path.get(), PREVIEW_LOGO, PILLOW ) try: @@ -1591,7 +1590,7 @@ def preview_compose(): if os.path.isfile(img_compose_file.get()): # l_compose_preview.configure(text=os.path.basename(img_compose_file.get())) preview_picture = convert_common.preview( - img_compose_file.get(), int(co_compose_preview_selector.get()), PILLOW, OS + img_compose_file.get(), int(co_compose_preview_selector.get()), PILLOW ) try: @@ -3150,7 +3149,10 @@ def text_tool_hide_show(): co_compose_preview_selector.bind("<>", preview_compose_refresh) co_text_font.bind("<>", font_selected) c_preview_orig_pi.bind("", mouse_crop_nw) -c_preview_orig_pi.bind("", mouse_crop_se) +if OS == "MACOS": + c_preview_orig_pi.bind("", mouse_crop_se) +else: + c_preview_orig_pi.bind("", mouse_crop_se) c_preview_new_pi.bind("", preview_new_button) root.bind("", help_info) root.bind("", change_ttk_theme) diff --git a/fotokilof/common.py b/fotokilof/common.py index b704f81..8d14494 100644 --- a/fotokilof/common.py +++ b/fotokilof/common.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -Copyright (c) 2019-2024 Tomasz Łuczak, TeaM-TL +Copyright (c) 2019-2025 Tomasz Łuczak, TeaM-TL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -39,6 +39,7 @@ import fnmatch import logging from pathlib import PurePosixPath, PureWindowsPath +import platform import os import os.path @@ -52,8 +53,7 @@ def resize_subdir(resize_vatiant, pixel_x, pixel_y, percent): command = str(pixel_x) + "x" + str(pixel_y) sub_dir = str(pixel_x) + "x" + str(pixel_y) case 2: - if percent > 100: - percent = 100 + percent = min(percent, 100) if percent == 0: percent = 1 command = str(percent) + "%" @@ -120,10 +120,10 @@ def mouse_crop_calculation(x_orig, y_orig, size): return dict_return -def spacja(file_path, operating_system): +def spacja(file_path): """escaping space and special char in pathname""" if len(file_path): - if operating_system == "Windows": + if platform.system() == "Windows": result = PureWindowsPath(os.path.normpath(file_path)) else: result = PurePosixPath(os.path.normpath(file_path)) @@ -259,9 +259,7 @@ def file_from_list_of_images(file_list, current_file, request): def arrow_gravity(position, length, x0, y0): """calculate coordinated to draw arrow""" - length = int(length) - x0 = int(x0) - y0 = int(y0) + width = int(length / 3 / 2) length_1_2 = int(length / 2) length_1_3 = int(length / 3) @@ -270,9 +268,6 @@ def arrow_gravity(position, length, x0, y0): offset_x = 0 offset_y = 0 c = (x0, y0) - a = (x0, y0) - d = (x0, y0) - e = (x0, y0) match position: case "N": a = (x0, y0 + length) @@ -380,7 +375,7 @@ def gravitation(gravity, text_x, text_y, image_width, image_height): result0 = "0" result1 = "0" - return (result0, result1), text_x, text_y + return (result0, result1), int(text_x), int(text_y) def compose_calculate_half(clone, compose, auto_resize, gravity): diff --git a/fotokilof/convert_common.py b/fotokilof/convert_common.py index 37aefda..d7b15e4 100644 --- a/fotokilof/convert_common.py +++ b/fotokilof/convert_common.py @@ -2,7 +2,7 @@ # pylint: disable=bare-except """ -Copyright (c) 2024 Tomasz Łuczak, TeaM-TL +Copyright (c) 2024-2025 Tomasz Łuczak, TeaM-TL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -78,7 +78,6 @@ def fonts_list(set_pillow): def display_image(file_to_display, set_pillow): """display image""" - # file_in = common.spacja(file_to_display) module_logger.info(" Display file: %s", file_to_display) start_time = time.time() result = None @@ -134,13 +133,23 @@ def get_image_size(file_in, is_pillow): return size -def preview(file_logo, size, set_pillow, operating_system, coord=""): +def preview(file_logo, size, set_pillow, coord=""): """preview""" start_time = time.time() + if set_pillow: - result = convert_pillow.preview(file_logo, size, operating_system, coord) + result = convert_pillow.preview(file_logo, size, coord) else: - result = convert_wand.preview(file_logo, size, operating_system, coord) + result = convert_wand.preview(file_logo, size, coord) + if result is None: + result = { + "filename": None, + "size": "0", + "width": "0", + "height": "0", + "preview_width": "0", + "preview_height": "0", + } module_logger.info("preview: %s s", str(time.time() - start_time)) return result @@ -170,10 +179,16 @@ def save_close_clone(clone, file_out, exif_on, set_pillow): def rotate(clone, angle, color, angle_own, set_pillow): """rotate""" start_time = time.time() + if angle == 0: + angle = common.empty(angle_own) + if angle == 0: + color = None + else: + color = None if set_pillow: - result = convert_pillow.rotate(clone, angle, color, angle_own) + result = convert_pillow.rotate(clone, angle, color) else: - convert_wand.rotate(clone, angle, color, angle_own) + convert_wand.rotate(clone, angle, color) result = clone module_logger.info("Rotate: %ss", str(time.time() - start_time)) return result diff --git a/fotokilof/convert_pillow.py b/fotokilof/convert_pillow.py index e0553dd..58eb529 100644 --- a/fotokilof/convert_pillow.py +++ b/fotokilof/convert_pillow.py @@ -2,7 +2,7 @@ # pylint: disable=bare-except """ -Copyright (c) 2024 Tomasz Łuczak, TeaM-TL +Copyright (c) 2024-2025 Tomasz Łuczak, TeaM-TL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -117,32 +117,26 @@ def pip(clone, logo, logo_data, image_height, image_width): original image size: image_height, image_width """ if len(logo): - with Image(filename=logo) as logo_img: - with Drawing() as draw: - position = common.crop_gravity(logo_data, image_height, image_width) - draw.composite( - operator="over", - left=common.empty(position[0]), - top=common.empty(position[1]), - width=common.empty(logo_data[2]), - height=common.empty(logo_data[3]), - image=logo_img, - ) - draw(clone) - module_logger.debug(" Conversion: logo") - - -def rotate(clone, angle, color, own): + if os.path.isfile(logo): + pass + # with Image(logo) as logo_img: + # with Drawing() as draw: + # position = common.crop_gravity(logo_data, image_height, image_width) + # draw.composite( + # operator="over", + # left=common.empty(position[0]), + # top=common.empty(position[1]), + # width=common.empty(logo_data[2]), + # height=common.empty(logo_data[3]), + # image=logo_img, + # ) + # draw(clone) + module_logger.warning("PIP is not available for PILLOW yet, install ImageMagick") + + +def rotate(clone, angle, color): """rotate""" - if angle == 0: - angle = common.empty(own) - if angle == 0: - color = None - else: - color = None - result = clone.rotate(angle=angle, fillcolor=color, expand=True) - module_logger.debug(" Conversion: rotate %s", str(angle)) - return result + return clone.rotate(angle=angle, fillcolor=color, expand=True) def mirror(clone, flip, flop): @@ -189,7 +183,7 @@ def text(convert_data): font = ImageFont.truetype(font, text_size) result = clone - if len(text_string): + if text_string: if in_out == 0: # inside if gravity_onoff == 0: @@ -403,12 +397,11 @@ def compose(clone, compose_file, right, autoresize, color, gravity): # ------------------------------------ Preview -def preview(file_in, max_size, operating_system, coord=""): +def preview(file_in, max_size, coord=""): """ preview generation by Pillow file_in - fullname image file max_size - required size of image - operating_system - operating system: Windows, MACOS, UNIX coord - coordinates for crop -- return: @@ -417,15 +410,6 @@ def preview(file_in, max_size, operating_system, coord=""): - width and height """ - result = { - "filename": None, - "size": "0", - "width": "0", - "height": "0", - "preview_width": "0", - "preview_height": "0", - } - if file_in is not None: if os.path.isfile(file_in): filesize = common.humansize(os.path.getsize(file_in)) @@ -458,14 +442,15 @@ def preview(file_in, max_size, operating_system, coord=""): file_preview = os.path.join(tempfile.gettempdir(), "fotokilof_preview.ppm") save_close_clone(clone, file_preview) result = { - "filename": common.spacja(file_preview, operating_system), + "filename": common.spacja(file_preview), "size": filesize, "width": str(width), "height": str(height), "preview_width": str(preview_width), "preview_height": str(preview_height), } - module_logger.debug("preview: %s", str(result)) + else: + result = None return result diff --git a/fotokilof/convert_wand.py b/fotokilof/convert_wand.py index 8180494..4b83fcf 100644 --- a/fotokilof/convert_wand.py +++ b/fotokilof/convert_wand.py @@ -2,7 +2,7 @@ # pylint: disable=bare-except """ -Copyright (c) 2022-2024 Tomasz Łuczak, TeaM-TL +Copyright (c) 2022-2025 Tomasz Łuczak, TeaM-TL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -103,26 +103,23 @@ def pip(clone, logo, logo_data, image_height, image_width): original image size: image_height, image_width """ if len(logo): - with Image(filename=logo) as logo_img: - with Drawing() as draw: - position = common.crop_gravity(logo_data, image_height, image_width) - draw.composite( - operator="over", - left=common.empty(position[0]), - top=common.empty(position[1]), - width=common.empty(logo_data[2]), - height=common.empty(logo_data[3]), - image=logo_img, - ) - draw(clone) + if os.path.isfile(logo): + with Image(filename=logo) as logo_img: + with Drawing() as draw: + position = common.crop_gravity(logo_data, image_height, image_width) + draw.composite( + operator="over", + left=common.empty(position[0]), + top=common.empty(position[1]), + width=common.empty(logo_data[2]), + height=common.empty(logo_data[3]), + image=logo_img, + ) + draw(clone) -def rotate(clone, angle, color, angle_own): +def rotate(clone, angle, color): """rotate""" - if angle == 0: - angle = common.empty(angle_own) - if angle == 0: - color = None clone.rotate(angle, background=color) @@ -147,13 +144,13 @@ def text(convert_data): angle = convert_data[3] text_color = convert_data[4] font = convert_data[5] - text_size = convert_data[6] + text_size = int(convert_data[6]) gravity_onoff = convert_data[7] gravity = convert_data[8] box = convert_data[9] box_color = convert_data[10] - text_x = convert_data[11] - text_y = convert_data[12] + text_x = int(common.empty(convert_data[11])) + text_y = int(common.empty(convert_data[12])) text_string = convert_data[13] arrow = convert_data[14] @@ -161,7 +158,7 @@ def text(convert_data): if text_string: gravity_common, new_x, new_y = common.gravitation( - gravity, int(text_x), int(text_y), image_width, image_height + gravity, text_x, text_y, image_width, image_height ) draw_gravity = gravity_common[1] if in_out == 0: @@ -185,8 +182,8 @@ def text(convert_data): arrow_coord_all = common.gravitation( gravity, - int(text_x), - int(text_y), + text_x, + text_y, image_width, image_height, ) @@ -390,12 +387,11 @@ def compose(clone, compose_file, right, autoresize, color, gravity): # ------------------------------------ Preview -def preview(file_in, size, operating_system, coord=""): +def preview(file_in, size, coord=""): """ preview generation by Wand file_in - fullname image file size - required size of image - os - operating system: Windows, MACOS, UNIX coord - coordinates for crop -- return: @@ -404,15 +400,7 @@ def preview(file_in, size, operating_system, coord=""): - width and height """ - result = { - "filename": None, - "size": "0", - "width": "0", - "height": "0", - "preview_width": "0", - "preview_height": "0", - } - + result = None if file_in: if os.path.isfile(file_in): filesize = common.humansize(os.path.getsize(file_in)) @@ -438,14 +426,13 @@ def preview(file_in, size, operating_system, coord=""): with clone.convert("ppm") as converted: save_close_clone(converted, file_preview) result = { - "filename": common.spacja(file_preview, operating_system), + "filename": common.spacja(file_preview), "size": filesize, "width": str(width), "height": str(height), "preview_width": str(preview_width), "preview_height": str(preview_height), } - return result diff --git a/fotokilof/gui.py b/fotokilof/gui.py index eb8711d..dc83528 100644 --- a/fotokilof/gui.py +++ b/fotokilof/gui.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Copyright (c) 2019-2024 Tomasz Łuczak, TeaM-TL +Copyright (c) 2019-2025 Tomasz Łuczak, TeaM-TL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -37,6 +37,9 @@ if platform.system() in ("Linux", "Darwin", "Windows"): import pyperclipimg + USE_PYPERCLIP = 1 +else: + USE_PYPERCLIP = 0 module_logger = logging.getLogger(__name__) @@ -49,7 +52,7 @@ def copy_to_clipboard(file_in): https://stackoverflow.com/questions/54008175/copy-an-image-to-macos-clipboard-using-python?rq=4 debug needed! """ - if platform.system() in ("Darwin", "Linux", "Windows"): + if USE_PYPERCLIP: pyperclipimg.copy(file_in) else: # e.g. FreeBSD diff --git a/fotokilof/magick.py b/fotokilof/magick.py index 956faf5..caf56b6 100644 --- a/fotokilof/magick.py +++ b/fotokilof/magick.py @@ -2,7 +2,7 @@ # pylint: disable=bare-except """ -Copyright (c) 2019-2024 Tomasz Łuczak, TeaM-TL +Copyright (c) 2019-2025 Tomasz Łuczak, TeaM-TL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -46,8 +46,8 @@ def magick(cmd, file_in, file_out, command, operating_system): result = None if cmd != "": if file_in is not None: - file_in = common.spacja(file_in, operating_system) - file_out = common.spacja(file_out, operating_system) + file_in = common.spacja(file_in) + file_out = common.spacja(file_out) if operating_system == 'Windows': prefix_cmd = "magick.exe " else: diff --git a/fotokilof/version.py b/fotokilof/version.py index b79ddf7..3257a5a 100644 --- a/fotokilof/version.py +++ b/fotokilof/version.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """ -Copyright (c) 2019-2024 Tomasz Łuczak, TeaM-TL +Copyright (c) 2019-2025 Tomasz Łuczak, TeaM-TL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -22,7 +22,7 @@ THE SOFTWARE. """ -__version__ = "5.1.4" +__version__ = "5.1.5" __author__ = "Tomasz Łuczak" __email__ = "tlu@team-tl.pl" __appname__ = "FotoKilof" From 625b41bbd84223c39ec13f63b1e8a9ea68567512 Mon Sep 17 00:00:00 2001 From: TLu Date: Tue, 7 Jan 2025 00:53:01 +0100 Subject: [PATCH 2/3] 5.1.5 --- .github/workflows/publish_to_pypi.yml | 10 +++++++++- fotokilof/fotokilof.sh | 10 +++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish_to_pypi.yml b/.github/workflows/publish_to_pypi.yml index 4552f19..5a34290 100644 --- a/.github/workflows/publish_to_pypi.yml +++ b/.github/workflows/publish_to_pypi.yml @@ -1,4 +1,4 @@ -name: Upload FotoKilof Package to PyPI when a Release is Created +name: Build and upload to PyPI when a Release is Created on: release: @@ -23,6 +23,14 @@ jobs: with: python-version: '3.12' + - name: Compile *po files for localisation + run: | + for L in fotokilof/locale/??; do + if [ -e fotokilof/$L/LC_MESSAGES/fotokilof.po ]; then + msgfmt fotokilof/$L/LC_MESSAGES/fotokilof.po -o fotokilof/$L/LC_MESSAGES/fotokilof.mo + fi + done + - name: "Install build" run: pip install build diff --git a/fotokilof/fotokilof.sh b/fotokilof/fotokilof.sh index 8ee4464..186ea1b 100755 --- a/fotokilof/fotokilof.sh +++ b/fotokilof/fotokilof.sh @@ -7,15 +7,11 @@ cd $MYPATH # compile MO files, usable for testing tanslations NAME=fotokilof -cd locale/ -for I in ??; do - cd $I/LC_MESSAGES - if [ -e $NAME.po ]; then - msgfmt $NAME.po -o $NAME.mo +for L in locale/??; do + if [ -e $L/LC_MESSAGES/$NAME.po ]; then + msgfmt $L/LC_MESSAGES/$NAME.po -o $L/LC_MESSAGES/$NAME.mo fi - cd ../../ done -cd .. # run FotoKilof #python3 –m compileall $MAIN & From e57b7f18bfc082e7a8df0b431298747f8602049d Mon Sep 17 00:00:00 2001 From: TLu Date: Tue, 7 Jan 2025 20:59:07 +0100 Subject: [PATCH 3/3] fix publish to pypi, next approach --- .github/workflows/publish_to_pypi.yml | 53 +++++++++++++++------------ README.md | 2 - 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/.github/workflows/publish_to_pypi.yml b/.github/workflows/publish_to_pypi.yml index 5a34290..192a3c9 100644 --- a/.github/workflows/publish_to_pypi.yml +++ b/.github/workflows/publish_to_pypi.yml @@ -15,32 +15,37 @@ jobs: contents: write id-token: write steps: - - name: Checkout code - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 - - name: Set up Python 3.12 - uses: actions/setup-python@v5 - with: - python-version: '3.12' + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: '3.12' - - name: Compile *po files for localisation - run: | - for L in fotokilof/locale/??; do - if [ -e fotokilof/$L/LC_MESSAGES/fotokilof.po ]; then - msgfmt fotokilof/$L/LC_MESSAGES/fotokilof.po -o fotokilof/$L/LC_MESSAGES/fotokilof.mo - fi - done + - name: Compile *po files for localisation + run: | + apt-get install -y gettext tree + ls + tree + L_PRE=fotokilof/locale + L_LAST=LC_MESSAGES/fotokilof + for L in $L_PRE/??; do + if [ -e $L_PRE/$L/$L_LAST.po ]; then + msgfmt $L_PRE/$L/$L_LAST.po -o fotokilof/$L/$L_LAST.mo + fi + done - - name: "Install build" - run: pip install build + - name: "Install build" + run: pip install build - - name: Build package - run: python -m build - - - name: Publish distribution to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 + - name: Build package + run: python -m build + + - name: Publish distribution to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 - - name: Upload artifact signatures to GitHub Release - env: - GITHUB_TOKEN: ${{ github.token }} - run: gh release upload '${{ github.pypi }}' dist/** --repo '${{ github.repository }}' \ No newline at end of file + # - name: Upload artifact signatures to GitHub Release + # env: + # GITHUB_TOKEN: ${{ github.token }} + # run: gh release upload '${{ github.pypi }}' dist/** --repo '${{ github.repository }}' \ No newline at end of file diff --git a/README.md b/README.md index b14b0b3..b2d9de2 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@ GUI for the most used (by me) ImageMagick functionality for processing pictures. If ImageMagick or Wand are unavailable, Pillow is in use. There some limitation, but works in general. -![Happy new Year](https://raw.githubusercontent.com/TeaM-TL/FotoKilof/master/screenshots/january_happy_new_year.jpg) - ## Screenshots ### Linux