v0.49.1: image pickers see uppercase suffixes like IMG_1897.JPG

This commit is contained in:
2026-10-10 23:42:40 -07:00
parent 660740992a
commit 3dcd30eab6
6 changed files with 33 additions and 5 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
"""LinTunes — iTunes-style music library manager and player for Linux.""" """LinTunes — iTunes-style music library manager and player for Linux."""
__version__ = "0.49.0" __version__ = "0.49.1"
+1 -2
View File
@@ -19,8 +19,7 @@ from PyQt6.QtWidgets import (
from lintunes import theme from lintunes import theme
from lintunes.export import exporter, upload from lintunes.export import exporter, upload
from lintunes.gui.file_filters import WEB_IMAGE_FILTER as _IMAGE_FILTER
_IMAGE_FILTER = "Images (*.png *.jpg *.jpeg *.gif *.webp)"
class ExportKindDialog(QDialog): class ExportKindDialog(QDialog):
+17
View File
@@ -0,0 +1,17 @@
"""File-dialog name filters.
Qt matches a filter's patterns case-sensitively on Linux, so "*.jpg" hides
a phone photo called IMG_1897.JPG. Every pattern is listed in both cases.
"""
_IMAGE_SUFFIXES = ("png", "jpg", "jpeg", "gif", "bmp", "webp")
def image_filter(suffixes=_IMAGE_SUFFIXES) -> str:
patterns = " ".join(f"*.{s} *.{s.upper()}" for s in suffixes)
return f"Images ({patterns})"
IMAGE_FILTER = image_filter()
# What a web page can show: no BMP.
WEB_IMAGE_FILTER = image_filter(("png", "jpg", "jpeg", "gif", "webp"))
+2 -1
View File
@@ -13,6 +13,7 @@ from PyQt6.QtGui import QPixmap, QImage, QKeySequence, QShortcut
from lintunes import tagging from lintunes import tagging
from lintunes.gui.art_ops import embed_artwork from lintunes.gui.art_ops import embed_artwork
from lintunes.player import VOLUME_ADJUSTMENT_MAX from lintunes.player import VOLUME_ADJUSTMENT_MAX
from lintunes.gui.file_filters import IMAGE_FILTER
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@@ -206,7 +207,7 @@ class ArtSquare(QLabel):
def choose_file(self): def choose_file(self):
file_name, _filter = QFileDialog.getOpenFileName( file_name, _filter = QFileDialog.getOpenFileName(
self, "Choose Artwork", "", self, "Choose Artwork", "",
"Images (*.jpg *.jpeg *.png *.gif *.bmp *.webp)") IMAGE_FILTER)
if file_name and not self._stage_file(Path(file_name)): if file_name and not self._stage_file(Path(file_name)):
self.hint_changed.emit("That file isn't a readable image") self.hint_changed.emit("That file isn't a readable image")
+2 -1
View File
@@ -24,6 +24,7 @@ from lintunes.cassette import syncthing_api as st
from lintunes.cassette.state import ( from lintunes.cassette.state import (
FOLLOW_LIBRARY, FOLLOW_SEPARATE, LAYOUT_FOLDER, LAYOUT_MIXED, OPEN, in_dir, FOLLOW_LIBRARY, FOLLOW_SEPARATE, LAYOUT_FOLDER, LAYOUT_MIXED, OPEN, in_dir,
) )
from lintunes.gui.file_filters import IMAGE_FILTER
AVATAR_PX = 256 AVATAR_PX = 256
AVATAR_PREVIEW_PX = 72 AVATAR_PREVIEW_PX = 72
@@ -244,7 +245,7 @@ class GeneralPage(QWidget):
def _choose_avatar(self): def _choose_avatar(self):
path, _ = QFileDialog.getOpenFileName( path, _ = QFileDialog.getOpenFileName(
self, "Choose an Avatar", str(Path.home()), self, "Choose an Avatar", str(Path.home()),
"Images (*.png *.jpg *.jpeg *.gif *.bmp *.webp)") IMAGE_FILTER)
if not path: if not path:
return return
image = load_avatar_image(Path(path)) image = load_avatar_image(Path(path))
+10
View File
@@ -535,3 +535,13 @@ def test_several_images_land_in_order_with_a_gap(tmp_path):
assert page[spots[0]:spots[1]].count("<br><br>") == 1 assert page[spots[0]:spots[1]].count("<br><br>") == 1
assert (dest / "cover 2.png").read_bytes() == b"B" assert (dest / "cover 2.png").read_bytes() == b"B"
assert not (dest / "placeholder.png").exists() assert not (dest / "placeholder.png").exists()
def test_image_filters_see_uppercase_suffixes():
"""Qt filters are case-sensitive on Linux; a phone's IMG_1897.JPG hid."""
import fnmatch
from lintunes.gui.file_filters import IMAGE_FILTER, WEB_IMAGE_FILTER
for flt in (IMAGE_FILTER, WEB_IMAGE_FILTER):
patterns = flt[flt.index("(") + 1:-1].split()
for name in ("IMG_1897.JPG", "a.jpeg", "b.PNG", "c.WebP"[:-4] + "WEBP"):
assert any(fnmatch.fnmatchcase(name, p) for p in patterns), name