From 14110add551dbb4b8b6857336513a16bb129cb06 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sun, 4 Jul 2021 15:27:29 +1000 Subject: [PATCH] stop (un)escaping media filenames Back in the WebKit days, images with Unicode filenames would fail to appear if they weren't percent-escaped. This no longer seems to be the case - with this patch, images appear correctly on the Mac and Windows platforms I tested with. Fixes https://forums.ankiweb.net/t/anki-2-1-45-beta/10664/96 Fixes #1219 --- pylib/anki/media.py | 27 +++++---------------------- pylib/tests/test_media.py | 4 ---- qt/aqt/editor.py | 17 ++--------------- qt/aqt/main.py | 1 - qt/aqt/utils.py | 4 ++-- 5 files changed, 9 insertions(+), 44 deletions(-) diff --git a/pylib/anki/media.py b/pylib/anki/media.py index 9935a5817..e54f43485 100644 --- a/pylib/anki/media.py +++ b/pylib/anki/media.py @@ -8,13 +8,11 @@ import pprint import re import sys import time -import urllib.error -import urllib.parse -import urllib.request -from typing import Any, Callable, List, Match, Optional, Tuple +from typing import Any, Callable, List, Optional, Tuple import anki import anki._backend.backend_pb2 as _pb +from anki._legacy import deprecated from anki.consts import * from anki.latex import render_latex, render_latex_returning_errors from anki.models import NotetypeId @@ -186,27 +184,12 @@ class MediaManager: txt = re.sub(reg, "", txt) return txt + @deprecated(info="no longer required") def escapeImages(self, string: str, unescape: bool = False) -> str: - "escape_media_filenames alias for compatibility with add-ons." - return self.escape_media_filenames(string, unescape) + return string + @deprecated(info="no longer required") def escape_media_filenames(self, string: str, unescape: bool = False) -> str: - "Apply or remove percent encoding to filenames in html tags (audio, image, object)." - fn: Callable - if unescape: - fn = urllib.parse.unquote - else: - fn = urllib.parse.quote - - def repl(match: Match) -> str: - tag = match.group(0) - fname = match.group("fname") - if re.match("(https?|ftp)://", fname): - return tag - return tag.replace(fname, fn(fname)) - - for reg in self.html_media_regexps: - string = re.sub(reg, repl, string) return string # Checking media diff --git a/pylib/tests/test_media.py b/pylib/tests/test_media.py index 30e2b8056..73dd9bb41 100644 --- a/pylib/tests/test_media.py +++ b/pylib/tests/test_media.py @@ -49,10 +49,6 @@ def test_strings(): assert sp("aoeu") == "aoeu" assert sp("aoeu[sound:foo.mp3]aoeu") == "aoeuaoeu" assert sp("aoeu") == "aoeu" - es = col.media.escape_media_filenames - assert es("aoeu") == "aoeu" - assert es("") == "" - assert es('') == '' def test_deckIntegration(): diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index 7766dd9e8..174fa18b7 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -435,10 +435,7 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{ if not self.note: return - data = [ - (fld, self.mw.col.media.escape_media_filenames(val)) - for fld, val in self.note.items() - ] + data = self.note.items() self.widget.show() self.updateTags() @@ -588,13 +585,9 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{ if html.find(">") > -1: # filter html through beautifulsoup so we can strip out things like a # leading - html_escaped = self.mw.col.media.escape_media_filenames(html) with warnings.catch_warnings(): warnings.simplefilter("ignore", UserWarning) - html_escaped = str(BeautifulSoup(html_escaped, "html.parser")) - html = self.mw.col.media.escape_media_filenames( - html_escaped, unescape=True - ) + html = str(BeautifulSoup(html, "html.parser")) self.note.fields[field] = html if not self.addMode: self._save_current_note() @@ -1268,15 +1261,9 @@ def remove_null_bytes(txt: str, editor: Editor) -> str: return txt.replace("\x00", "") -def reverse_url_quoting(txt: str, editor: Editor) -> str: - # reverse the url quoting we added to get images to display - return editor.mw.col.media.escape_media_filenames(txt, unescape=True) - - gui_hooks.editor_will_use_font_for_field.append(fontMungeHack) gui_hooks.editor_will_munge_html.append(munge_html) gui_hooks.editor_will_munge_html.append(remove_null_bytes) -gui_hooks.editor_will_munge_html.append(reverse_url_quoting) def set_cloze_button(editor: Editor) -> None: diff --git a/qt/aqt/main.py b/qt/aqt/main.py index 4eac01f5e..da4b9f69d 100644 --- a/qt/aqt/main.py +++ b/qt/aqt/main.py @@ -482,7 +482,6 @@ class AnkiQt(QMainWindow): return aqt.sound.av_refs_to_play_icons(text) def prepare_card_text_for_display(self, text: str) -> str: - text = self.col.media.escape_media_filenames(text) text = self._add_play_buttons(text) return text diff --git a/qt/aqt/utils.py b/qt/aqt/utils.py index 83484eb56..0b674dbd2 100644 --- a/qt/aqt/utils.py +++ b/qt/aqt/utils.py @@ -35,6 +35,7 @@ from PyQt5.QtWidgets import ( import aqt from anki import Collection +from anki._legacy import deprecated from anki.lang import TR, tr_legacyglobal # pylint: disable=unused-import from anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild from aqt.qt import * @@ -679,9 +680,8 @@ def restore_combo_history(comboBox: QComboBox, name: str) -> List[str]: return history +@deprecated(info="use mw.prepare_card_text_for_display()") def mungeQA(col: Collection, txt: str) -> str: - print("mungeQA() deprecated; use mw.prepare_card_text_for_display()") - txt = col.media.escape_media_filenames(txt) return txt