Merge branch '276-use-bleach'
This commit is contained in:
@@ -8,6 +8,8 @@ from pathlib import Path
|
||||
from time import sleep
|
||||
from typing import Any, Callable, cast, Dict, Iterable, Optional, Tuple, Type, Union
|
||||
|
||||
import bleach
|
||||
|
||||
from gi.repository import GLib, GObject, Gtk, Pango
|
||||
|
||||
from . import ConfigurationStore
|
||||
@@ -252,8 +254,6 @@ class ConfigureServerForm(Gtk.Box):
|
||||
def _set_verification_status(
|
||||
self, verifying: bool, is_valid: bool = False, error_text: str = None
|
||||
):
|
||||
from sublime_music.ui import util
|
||||
|
||||
if verifying:
|
||||
if not self.verifying_in_progress:
|
||||
for c in self.config_verification_box.get_children():
|
||||
@@ -288,7 +288,7 @@ class ConfigureServerForm(Gtk.Box):
|
||||
set_icon_and_label(
|
||||
"config-ok-symbolic", "<b>Configuration is valid</b>"
|
||||
)
|
||||
elif escaped := util.esc(error_text):
|
||||
elif escaped := bleach.clean(error_text or ""):
|
||||
set_icon_and_label("config-error-symbolic", escaped)
|
||||
|
||||
self.config_verification_box.show_all()
|
||||
|
@@ -1191,14 +1191,12 @@ class SublimeMusicApp(Gtk.Application):
|
||||
if glib_notify_exists:
|
||||
notification_lines = []
|
||||
if album := song.album:
|
||||
notification_lines.append(
|
||||
f"<i>{bleach.clean(album.name)}</i>"
|
||||
)
|
||||
notification_lines.append(f"<i>{album.name}</i>")
|
||||
if artist := song.artist:
|
||||
notification_lines.append(bleach.clean(artist.name))
|
||||
notification_lines.append(artist.name)
|
||||
song_notification = Notify.Notification.new(
|
||||
song.title,
|
||||
"\n".join(notification_lines),
|
||||
bleach.clean("\n".join(notification_lines)),
|
||||
)
|
||||
song_notification.add_action(
|
||||
"clicked",
|
||||
|
@@ -3,6 +3,8 @@ from functools import partial
|
||||
from random import randint
|
||||
from typing import cast, List, Sequence
|
||||
|
||||
import bleach
|
||||
|
||||
from gi.repository import Gio, GLib, GObject, Gtk, Pango
|
||||
|
||||
from ..adapters import (
|
||||
@@ -93,10 +95,9 @@ class ArtistList(Gtk.Box):
|
||||
list_scroll_window = Gtk.ScrolledWindow(min_content_width=250)
|
||||
|
||||
def create_artist_row(model: _ArtistModel) -> Gtk.ListBoxRow:
|
||||
label_text = [f"<b>{util.esc(model.name)}</b>"]
|
||||
label_text = [f"<b>{model.name}</b>"]
|
||||
|
||||
album_count = model.album_count
|
||||
if album_count:
|
||||
if album_count := model.album_count:
|
||||
label_text.append(
|
||||
"{} {}".format(album_count, util.pluralize("album", album_count))
|
||||
)
|
||||
@@ -107,7 +108,7 @@ class ArtistList(Gtk.Box):
|
||||
)
|
||||
row.add(
|
||||
Gtk.Label(
|
||||
label="\n".join(label_text),
|
||||
label=bleach.clean("\n".join(label_text)),
|
||||
use_markup=True,
|
||||
margin=12,
|
||||
halign=Gtk.Align.START,
|
||||
@@ -368,7 +369,7 @@ class ArtistDetailPanel(Gtk.Box):
|
||||
"Collapse" if self.artist_details_expanded else "Expand"
|
||||
)
|
||||
|
||||
self.artist_name.set_markup(util.esc(f"<b>{artist.name}</b>"))
|
||||
self.artist_name.set_markup(bleach.clean(f"<b>{artist.name}</b>"))
|
||||
self.artist_name.set_tooltip_text(artist.name)
|
||||
|
||||
if self.artist_details_expanded:
|
||||
@@ -378,7 +379,7 @@ class ArtistDetailPanel(Gtk.Box):
|
||||
self.artist_stats.set_markup(self.format_stats(artist))
|
||||
|
||||
if artist.biography:
|
||||
self.artist_bio.set_markup(util.esc(artist.biography))
|
||||
self.artist_bio.set_markup(bleach.clean(artist.biography))
|
||||
self.artist_bio.show()
|
||||
else:
|
||||
self.artist_bio.hide()
|
||||
|
@@ -1,6 +1,8 @@
|
||||
from functools import partial
|
||||
from typing import Any, cast, List, Optional, Tuple
|
||||
|
||||
import bleach
|
||||
|
||||
from gi.repository import Gdk, Gio, GLib, GObject, Gtk, Pango
|
||||
|
||||
from ..adapters import AdapterManager, api_objects as API, CacheMissError, Result
|
||||
@@ -383,7 +385,7 @@ class MusicDirectoryList(Gtk.Box):
|
||||
in ("folder-download-symbolic", "view-pin-symbolic")
|
||||
),
|
||||
status_icon,
|
||||
util.esc(song.title),
|
||||
bleach.clean(song.title),
|
||||
util.format_song_duration(song.duration),
|
||||
song.id,
|
||||
]
|
||||
@@ -442,7 +444,7 @@ class MusicDirectoryList(Gtk.Box):
|
||||
rowbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
rowbox.add(
|
||||
Gtk.Label(
|
||||
label=f"<b>{util.esc(model.name)}</b>",
|
||||
label=bleach.clean(f"<b>{model.name}</b>"),
|
||||
use_markup=True,
|
||||
margin=8,
|
||||
halign=Gtk.Align.START,
|
||||
|
@@ -1,6 +1,8 @@
|
||||
from functools import partial
|
||||
from typing import Any, Callable, Dict, Optional, Set, Tuple
|
||||
|
||||
import bleach
|
||||
|
||||
from gi.repository import Gdk, GLib, GObject, Gtk, Pango
|
||||
|
||||
from ..adapters import (
|
||||
@@ -1089,13 +1091,13 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
self._remove_all_from_widget(self.song_results)
|
||||
for song in search_results.songs:
|
||||
label_text = util.dot_join(
|
||||
f"<b>{util.esc(song.title)}</b>",
|
||||
util.esc(song.artist.name if song.artist else None),
|
||||
f"<b>{song.title}</b>",
|
||||
song.artist.name if song.artist else None,
|
||||
)
|
||||
assert song.album and song.album.id
|
||||
self.song_results.add(
|
||||
self._create_search_result_row(
|
||||
label_text, "album", song.album.id, song.cover_art
|
||||
bleach.clean(label_text), "album", song.album.id, song.cover_art
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1106,13 +1108,13 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
self._remove_all_from_widget(self.album_results)
|
||||
for album in search_results.albums:
|
||||
label_text = util.dot_join(
|
||||
f"<b>{util.esc(album.name)}</b>",
|
||||
util.esc(album.artist.name if album.artist else None),
|
||||
f"<b>{album.name}</b>",
|
||||
album.artist.name if album.artist else None,
|
||||
)
|
||||
assert album.id
|
||||
self.album_results.add(
|
||||
self._create_search_result_row(
|
||||
label_text, "album", album.id, album.cover_art
|
||||
bleach.clean(label_text), "album", album.id, album.cover_art
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1122,11 +1124,13 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
if search_results.artists is not None:
|
||||
self._remove_all_from_widget(self.artist_results)
|
||||
for artist in search_results.artists:
|
||||
label_text = util.esc(artist.name)
|
||||
assert artist.id
|
||||
self.artist_results.add(
|
||||
self._create_search_result_row(
|
||||
label_text, "artist", artist.id, artist.artist_image_url
|
||||
bleach.clean(artist.name),
|
||||
"artist",
|
||||
artist.id,
|
||||
artist.artist_image_url,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1136,10 +1140,12 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
if search_results.playlists:
|
||||
self._remove_all_from_widget(self.playlist_results)
|
||||
for playlist in search_results.playlists:
|
||||
label_text = util.esc(playlist.name)
|
||||
self.playlist_results.add(
|
||||
self._create_search_result_row(
|
||||
label_text, "playlist", playlist.id, playlist.cover_art
|
||||
bleach.clean(playlist.name),
|
||||
"playlist",
|
||||
playlist.id,
|
||||
playlist.cover_art,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1182,10 +1188,10 @@ class DownloadStatusBox(Gtk.Box):
|
||||
)
|
||||
self.add(image)
|
||||
|
||||
artist = util.esc(self.song.artist.name if self.song.artist else None)
|
||||
label_text = util.dot_join(f"<b>{util.esc(self.song.title)}</b>", artist)
|
||||
artist = self.song.artist.name if self.song.artist else None
|
||||
label_text = util.dot_join(f"<b>{self.song.title}</b>", artist)
|
||||
self.song_label = Gtk.Label(
|
||||
label=label_text,
|
||||
label=bleach.clean(label_text),
|
||||
ellipsize=Pango.EllipsizeMode.END,
|
||||
max_width_chars=30,
|
||||
name="currently-downloading-song-title",
|
||||
|
@@ -4,6 +4,8 @@ from datetime import timedelta
|
||||
from functools import partial
|
||||
from typing import Any, Callable, Dict, Optional, Set, Tuple
|
||||
|
||||
import bleach
|
||||
|
||||
from gi.repository import Gdk, GdkPixbuf, GLib, GObject, Gtk, Pango
|
||||
|
||||
from . import util
|
||||
@@ -168,18 +170,20 @@ class PlayerControls(Gtk.ActionBar):
|
||||
order_token=self.cover_art_update_order_token,
|
||||
)
|
||||
|
||||
self.song_title.set_markup(util.esc(app_config.state.current_song.title))
|
||||
self.song_title.set_markup(
|
||||
bleach.clean(app_config.state.current_song.title)
|
||||
)
|
||||
# TODO (#71): use walrus once MYPY gets its act together
|
||||
album = app_config.state.current_song.album
|
||||
artist = app_config.state.current_song.artist
|
||||
if album:
|
||||
self.album_name.set_markup(util.esc(album.name))
|
||||
self.album_name.set_markup(bleach.clean(album.name))
|
||||
self.artist_name.show()
|
||||
else:
|
||||
self.album_name.set_markup("")
|
||||
self.album_name.hide()
|
||||
if artist:
|
||||
self.artist_name.set_markup(util.esc(artist.name))
|
||||
self.artist_name.set_markup(bleach.clean(artist.name))
|
||||
self.artist_name.show()
|
||||
else:
|
||||
self.artist_name.set_markup("")
|
||||
@@ -228,13 +232,13 @@ class PlayerControls(Gtk.ActionBar):
|
||||
new_store = []
|
||||
|
||||
def calculate_label(song_details: Song) -> str:
|
||||
title = util.esc(song_details.title)
|
||||
# TODO (#71): use walrus once MYPY works with this
|
||||
# album = util.esc(album.name if (album := song_details.album) else None)
|
||||
# artist = util.esc(artist.name if (artist := song_details.artist) else None) # noqa
|
||||
album = util.esc(song_details.album.name if song_details.album else None)
|
||||
artist = util.esc(song_details.artist.name if song_details.artist else None)
|
||||
return f"<b>{title}</b>\n{util.dot_join(album, artist)}"
|
||||
title = song_details.title
|
||||
# TODO (#71): use walrus once MYPY gets its act together
|
||||
# album = a.name if (a := song_details.album) else None
|
||||
# artist = a.name if (a := song_details.artist) else None
|
||||
album = song_details.album.name if song_details.album else None
|
||||
artist = song_details.artist.name if song_details.artist else None
|
||||
return bleach.clean(f"<b>{title}</b>\n{util.dot_join(album, artist)}")
|
||||
|
||||
def make_idle_index_capturing_function(
|
||||
idx: int,
|
||||
|
@@ -94,18 +94,6 @@ def format_sequence_duration(duration: Optional[timedelta]) -> str:
|
||||
return ", ".join(format_components)
|
||||
|
||||
|
||||
def esc(string: Optional[str]) -> str:
|
||||
"""
|
||||
>>> esc("test & <a href='ohea' target='_blank'>test</a>")
|
||||
"test & <a href='ohea'>test</a>"
|
||||
>>> esc(None)
|
||||
''
|
||||
"""
|
||||
if string is None:
|
||||
return ""
|
||||
return string.replace("&", "&").replace(" target='_blank'", "")
|
||||
|
||||
|
||||
def dot_join(*items: Any) -> str:
|
||||
"""
|
||||
Joins the given strings with a dot character. Filters out ``None`` values.
|
||||
|
Reference in New Issue
Block a user