Skip to content

Commit

Permalink
Merge pull request #189 from thenaterhood/dev
Browse files Browse the repository at this point in the history
Next Release
  • Loading branch information
thenaterhood authored Jun 29, 2024
2 parents de7890e + fd6ff6c commit e32d190
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 76 deletions.
4 changes: 2 additions & 2 deletions specs/gscreenshot.spec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%define name gscreenshot
%define version 3.5.0
%define unmangled_version 3.5.0
%define version 3.5.1
%define unmangled_version 3.5.1
%define release 1

Summary: A simple screenshot tool
Expand Down
52 changes: 26 additions & 26 deletions src/gscreenshot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
import typing

from datetime import datetime
from pkg_resources import resource_string, require, resource_filename
from PIL import Image
from gscreenshot.compat import get_resource_file, get_resource_string, get_version
from gscreenshot.screenshot import ScreenshotCollection
from gscreenshot.screenshooter import Screenshooter
from gscreenshot.screenshooter.factory import ScreenshooterFactory
Expand Down Expand Up @@ -57,7 +57,7 @@ def __init__(self, screenshooter=None):
constructor
"""
try:
locale_path = resource_filename('gscreenshot.resources', 'locale')
locale_path = get_resource_file("gscreenshot.resources", "locale")
locale.setlocale(locale.LC_ALL, '')
# I don't know what's going on with this. This call appears to exist,
# works fine, and seems required for glade localization to work.
Expand Down Expand Up @@ -124,24 +124,24 @@ def get_available_cursors(self) -> typing.Dict[str, typing.Optional[Image.Image]
Get the alternate pointer pixmaps gscreenshot can use
Returns {name: PIL.Image}
'''
pixmaps_path = "gscreenshot.resources.pixmaps"

adwaita_path = get_resource_file(pixmaps_path, "cursor-adwaita.png")
prohibit_path = get_resource_file(pixmaps_path, "cursor-prohibit.png")
allow_path = get_resource_file(pixmaps_path, "cursor-allow.png")

available = {
'theme': None,
'adwaita': Image.open(
resource_filename(
'gscreenshot.resources.pixmaps', 'cursor-adwaita.png'
)
),
'prohibit': Image.open(
resource_filename(
'gscreenshot.resources.pixmaps', 'cursor-prohibit.png'
)
),
'allow': Image.open(
resource_filename(
'gscreenshot.resources.pixmaps', 'cursor-allow.png'
)
)
}
'theme': None,
'adwaita': Image.open(
adwaita_path
),
'prohibit': Image.open(
prohibit_path
),
'allow': Image.open(
allow_path
)
}

if session_is_wayland():
del available['theme']
Expand Down Expand Up @@ -681,9 +681,9 @@ def get_program_authors(self) -> typing.List[str]:

def get_app_icon(self) -> Image.Image:
"""Returns the application icon"""
return Image.open(
resource_filename('gscreenshot.resources.pixmaps', 'gscreenshot.png')
)
pixmaps_path = 'gscreenshot.resources.pixmaps'
filename = get_resource_file(pixmaps_path, "gscreenshot.png")
return Image.open(filename)

def get_program_description(self) -> str:
"""Returns the program description"""
Expand All @@ -699,7 +699,7 @@ def get_program_name(self) -> str:

def get_program_license_text(self) -> str:
"""Returns the license text"""
return resource_string('gscreenshot.resources', 'LICENSE').decode('UTF-8')
return get_resource_string("gscreenshot.resources", "LICENSE")

def get_program_license(self) -> str:
"""Returns the license name"""
Expand All @@ -708,10 +708,10 @@ def get_program_license(self) -> str:
def get_program_version(self, padded: bool=False) -> str:
"""Returns the program version"""
if not padded:
return require("gscreenshot")[0].version
return get_version()
else:
version = require("gscreenshot")[0].version.split(".")
padded_version = [v.rjust(2, "0") for v in version]
version_str = get_version().split(".")
padded_version = [v.rjust(2, "0") for v in version_str]
return ".".join(padded_version)

def __repr__(self) -> str:
Expand Down
44 changes: 44 additions & 0 deletions src/gscreenshot/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
Compatibility functions
"""
try:
from importlib.resources import as_file, files
except ImportError:
from pkg_resources import resource_string, resource_filename


try:
from importlib.metadata import version
except ImportError:
from pkg_resources import require


def get_resource_file(resource: str, filename: str):
"""Compatibility function until pkg_resources is fully removed"""
# pylint: disable=missing-parentheses-for-call-in-test
if as_file and files:
with as_file(files(resource).joinpath(filename)) as fpath:
return fpath

# pylint: disable=used-before-assignment
return resource_filename(resource, filename)


def get_resource_string(resource: str, filename: str):
"""Compatibility function until pkg_resources is fully removed"""
# pylint: disable=missing-parentheses-for-call-in-test
if as_file and files:
return files(resource).joinpath(filename).read_text(encoding="UTF-8")

# pylint: disable=used-before-assignment
return resource_string(resource, filename).decode("UTF-8")


def get_version():
"""Compatibility function until pkg_resources is fully removed"""
# pylint: disable=missing-parentheses-for-call-in-test,using-constant-test
if version:
return version("gscreenshot")

# pylint: disable=used-before-assignment
return require("gscreenshot")[0].version
53 changes: 31 additions & 22 deletions src/gscreenshot/frontend/gtk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
import threading
import typing
from time import sleep
from pkg_resources import resource_string, resource_filename
import pygtkcompat
from gscreenshot import Gscreenshot, GscreenshotClipboardException
from gscreenshot.compat import get_resource_file, get_resource_string
from gscreenshot.frontend.gtk.dialogs import OpenWithDialog, WarningDialog
from gscreenshot.frontend.gtk.dialogs import FileSaveDialog, FileOpenDialog
from gscreenshot.frontend.gtk.view import View
Expand Down Expand Up @@ -457,13 +457,10 @@ def on_button_about_clicked(self, *_):
version = self._app.get_program_version()
about.set_version(version)

png_filename = get_resource_file("gscreenshot.resources.pixmaps", "gscreenshot.png")
about.set_logo(
Gtk.gdk.pixbuf_new_from_file(
resource_filename(
'gscreenshot.resources.pixmaps', 'gscreenshot.png'
)
)
)
Gtk.gdk.pixbuf_new_from_file(str(png_filename))
)

self._view.run_dialog(about)

Expand All @@ -489,26 +486,35 @@ def quit(self, *_):
self._app.quit()

def _image_to_pixbuf(self, image):
descriptor = io.BytesIO()
image = image.convert("RGB")
image.save(descriptor, "ppm")
contents = descriptor.getvalue()
descriptor.close()
loader = Gtk.gdk.PixbufLoader("pnm")
loader.write(contents)
pixbuf = loader.get_pixbuf()
try:
loader.close()
except GLib.GError:
pass
pixbuf = None
for img_format in [("pnm", "ppm"), ("png", "png"), ("jpeg", "jpeg")]:
try:
loader = Gtk.gdk.PixbufLoader(img_format[0])
descriptor = io.BytesIO()
image = image.convert("RGB")
image.save(descriptor, img_format[1])
contents = descriptor.getvalue()
descriptor.close()

loader.write(contents)
pixbuf = loader.get_pixbuf()
except GLib.GError:
continue
finally:
try:
loader.close()
except GLib.GError:
pass

return pixbuf

def _show_preview(self):
height, width = self._view.get_preview_dimensions()

preview_img = self._app.get_thumbnail(width, height, with_border=True)

self._view.update_preview(self._image_to_pixbuf(preview_img))
pixbuf = self._image_to_pixbuf(preview_img)
self._view.update_preview(pixbuf)


def main():
Expand All @@ -534,9 +540,12 @@ def main():

builder = Gtk.Builder()
builder.set_translation_domain('gscreenshot')
builder.add_from_string(resource_string(
'gscreenshot.resources.gui.glade', 'main.glade').decode('UTF-8'))

builder.add_from_string(
get_resource_string(
"gscreenshot.resources.gui.glade", "main.glade"
)
)
window = builder.get_object('window_main')

capabilities = application.get_capabilities()
Expand Down
8 changes: 4 additions & 4 deletions src/gscreenshot/frontend/gtk/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
import threading
from time import sleep
import typing
from pkg_resources import resource_filename
import pygtkcompat
from gscreenshot.compat import get_resource_file
from gscreenshot.screenshot import ScreenshotCollection
from gscreenshot.util import GSCapabilities

Expand Down Expand Up @@ -184,9 +184,9 @@ def connect_signals(self, presenter):

self._window.connect("check-resize", presenter.on_window_resize)
self._window.connect("window-state-event", presenter.window_state_event_handler)
self._window.set_icon_from_file(
resource_filename('gscreenshot.resources.pixmaps', 'gscreenshot.png')
)

png = get_resource_file("gscreenshot.resources.pixmaps", "gscreenshot.png")
self._window.set_icon_from_file(str(png))

if self._prev_btn is not None:
self._prev_btn.connect('clicked', presenter.on_preview_prev_clicked)
Expand Down
22 changes: 18 additions & 4 deletions src/gscreenshot/selector/slop.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,15 @@ def region_select(self) -> typing.Tuple[int, int, int, int]:
Returns:
(x top left, y top left, x bottom right, y bottom right)
"""
return self._get_boundary_interactive(
['slop', '--nodecorations=0', '-f', 'X=%x,Y=%y,W=%w,H=%h'])
return self._get_boundary_interactive([
'slop',
'--nodecorations=0',
'-l',
'-c',
'0.8,0.8,0.8,0.6',
'-f',
'X=%x,Y=%y,W=%w,H=%h'
])

def window_select(self) -> typing.Tuple[int, int, int, int]:
"""
Expand All @@ -40,8 +47,15 @@ def window_select(self) -> typing.Tuple[int, int, int, int]:
Returns:
(x top left, y top left, x bottom right, y bottom right)
"""
return self._get_boundary_interactive(
['slop', '--nodecorations=0', '-f', 'X=%x,Y=%y,W=%w,H=%h'])
return self._get_boundary_interactive([
'slop',
'--nodecorations=0',
'-l',
'-c',
'0.8,0.8,0.8,0.6',
'-f',
'X=%x,Y=%y,W=%w,H=%h'
])

@staticmethod
def can_run() -> bool:
Expand Down
4 changes: 2 additions & 2 deletions src/gscreenshot/selector/slurp.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def region_select(self) -> typing.Tuple[int, int, int, int]:
"""
ret = self._get_boundary_interactive([
'slurp', '-f', 'X=%x,Y=%y,W=%w,H=%h',
'-b', '#00000011', '-s', '#00000011', '-c', '#808080FF'])
'-b', '#00000011', '-s', '#cccccc55', '-c', '#808080FF'])
# Sleep so we hopefully don't catch the edge of slurp closing
sleep(0.1)
return ret
Expand All @@ -56,7 +56,7 @@ def window_select(self) -> typing.Tuple[int, int, int, int]:
"""
ret = self._get_boundary_interactive([
'slurp', '-f', 'X=%x,Y=%y,W=%w,H=%h',
'-b', '#00000011', '-s', '#00000011', '-c', '#808080FF'])
'-b', '#00000011', '-s', '#cccccc55', '-c', '#808080FF'])
# Sleep so we hopefully don't catch the edge of slurp closing
sleep(0.1)
return ret
Expand Down
10 changes: 6 additions & 4 deletions test/gscreenshot/frontend/test_gtk_presenter.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from importlib.resources import as_file, files
import unittest
from unittest.mock import Mock
from PIL import Image
import mock
from pkg_resources import resource_filename

from src.gscreenshot.frontend.gtk import Presenter

Expand All @@ -12,9 +12,11 @@ class GtkPresenterTest(unittest.TestCase):
def setUp(self):
self.app = Mock()
self.app.get_available_cursors.return_value = {}
self.app.get_thumbnail.return_value = Image.open(
resource_filename('gscreenshot.resources.pixmaps', 'gscreenshot.png')
)
pixmaps_path = "gscreenshot.resources.pixmaps"
with as_file(files(pixmaps_path).joinpath('gscreenshot.png')) as png_path:
self.app.get_thumbnail.return_value = Image.open(
png_path
)
self.screenshot_collection = Mock()
self.app.get_screenshot_collection.return_value = self.screenshot_collection
self.view = Mock()
Expand Down
19 changes: 8 additions & 11 deletions test/gscreenshot/screenshot/test_screenshot.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from importlib.resources import as_file, files
import unittest
from unittest.mock import Mock
import mock

from pkg_resources import resource_filename
from PIL import Image
from PIL import ImageChops
from src.gscreenshot.screenshooter import Screenshooter
from src.gscreenshot.screenshot import Screenshot
from src.gscreenshot.screenshot.effects.stamp import StampEffect

Expand All @@ -17,15 +16,13 @@ def setUp(self):
self.screenshot = Screenshot(self.image)

def test_add_fake_cursor(self):
original_img = Image.open(
resource_filename('gscreenshot.resources.pixmaps', 'gscreenshot.png')
)

cursor_img = Image.open(
resource_filename(
'gscreenshot.resources.pixmaps', 'cursor-adwaita.png'
)
)
pixmaps_path = "gscreenshot.resources.pixmaps"
with \
as_file(files(pixmaps_path).joinpath('gscreenshot.png')) as gscreenshot_png,\
as_file(files(pixmaps_path).joinpath('cursor-adwaita.png')) as adwaita:

original_img = Image.open(gscreenshot_png)
cursor_img = Image.open(adwaita)

expected_img = Image.open("../test/gscreenshot/screenshot/cursor_overlay_expected.png").convert("RGB")

Expand Down
1 change: 0 additions & 1 deletion test/gscreenshot/selector/test_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from unittest.mock import Mock
import mock

from pkg_resources import resource_filename
from PIL import Image
from PIL import ImageChops
from gscreenshot.selector import SelectionCancelled, SelectionParseError
Expand Down

0 comments on commit e32d190

Please sign in to comment.