mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
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
This commit is contained in:
parent
c01c4b642b
commit
14110add55
5 changed files with 9 additions and 44 deletions
|
@ -8,13 +8,11 @@ import pprint
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import urllib.error
|
from typing import Any, Callable, List, Optional, Tuple
|
||||||
import urllib.parse
|
|
||||||
import urllib.request
|
|
||||||
from typing import Any, Callable, List, Match, Optional, Tuple
|
|
||||||
|
|
||||||
import anki
|
import anki
|
||||||
import anki._backend.backend_pb2 as _pb
|
import anki._backend.backend_pb2 as _pb
|
||||||
|
from anki._legacy import deprecated
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
from anki.latex import render_latex, render_latex_returning_errors
|
from anki.latex import render_latex, render_latex_returning_errors
|
||||||
from anki.models import NotetypeId
|
from anki.models import NotetypeId
|
||||||
|
@ -186,27 +184,12 @@ class MediaManager:
|
||||||
txt = re.sub(reg, "", txt)
|
txt = re.sub(reg, "", txt)
|
||||||
return txt
|
return txt
|
||||||
|
|
||||||
|
@deprecated(info="no longer required")
|
||||||
def escapeImages(self, string: str, unescape: bool = False) -> str:
|
def escapeImages(self, string: str, unescape: bool = False) -> str:
|
||||||
"escape_media_filenames alias for compatibility with add-ons."
|
return string
|
||||||
return self.escape_media_filenames(string, unescape)
|
|
||||||
|
|
||||||
|
@deprecated(info="no longer required")
|
||||||
def escape_media_filenames(self, string: str, unescape: bool = False) -> str:
|
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
|
return string
|
||||||
|
|
||||||
# Checking media
|
# Checking media
|
||||||
|
|
|
@ -49,10 +49,6 @@ def test_strings():
|
||||||
assert sp("aoeu") == "aoeu"
|
assert sp("aoeu") == "aoeu"
|
||||||
assert sp("aoeu[sound:foo.mp3]aoeu") == "aoeuaoeu"
|
assert sp("aoeu[sound:foo.mp3]aoeu") == "aoeuaoeu"
|
||||||
assert sp("a<img src=yo>oeu") == "aoeu"
|
assert sp("a<img src=yo>oeu") == "aoeu"
|
||||||
es = col.media.escape_media_filenames
|
|
||||||
assert es("aoeu") == "aoeu"
|
|
||||||
assert es("<img src='http://foo.com'>") == "<img src='http://foo.com'>"
|
|
||||||
assert es('<img src="foo bar.jpg">') == '<img src="foo%20bar.jpg">'
|
|
||||||
|
|
||||||
|
|
||||||
def test_deckIntegration():
|
def test_deckIntegration():
|
||||||
|
|
|
@ -435,10 +435,7 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
|
||||||
if not self.note:
|
if not self.note:
|
||||||
return
|
return
|
||||||
|
|
||||||
data = [
|
data = self.note.items()
|
||||||
(fld, self.mw.col.media.escape_media_filenames(val))
|
|
||||||
for fld, val in self.note.items()
|
|
||||||
]
|
|
||||||
self.widget.show()
|
self.widget.show()
|
||||||
self.updateTags()
|
self.updateTags()
|
||||||
|
|
||||||
|
@ -588,13 +585,9 @@ $editorToolbar.then(({{ toolbar }}) => toolbar.appendGroup({{
|
||||||
if html.find(">") > -1:
|
if html.find(">") > -1:
|
||||||
# filter html through beautifulsoup so we can strip out things like a
|
# filter html through beautifulsoup so we can strip out things like a
|
||||||
# leading </div>
|
# leading </div>
|
||||||
html_escaped = self.mw.col.media.escape_media_filenames(html)
|
|
||||||
with warnings.catch_warnings():
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter("ignore", UserWarning)
|
warnings.simplefilter("ignore", UserWarning)
|
||||||
html_escaped = str(BeautifulSoup(html_escaped, "html.parser"))
|
html = str(BeautifulSoup(html, "html.parser"))
|
||||||
html = self.mw.col.media.escape_media_filenames(
|
|
||||||
html_escaped, unescape=True
|
|
||||||
)
|
|
||||||
self.note.fields[field] = html
|
self.note.fields[field] = html
|
||||||
if not self.addMode:
|
if not self.addMode:
|
||||||
self._save_current_note()
|
self._save_current_note()
|
||||||
|
@ -1268,15 +1261,9 @@ def remove_null_bytes(txt: str, editor: Editor) -> str:
|
||||||
return txt.replace("\x00", "")
|
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_use_font_for_field.append(fontMungeHack)
|
||||||
gui_hooks.editor_will_munge_html.append(munge_html)
|
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(remove_null_bytes)
|
||||||
gui_hooks.editor_will_munge_html.append(reverse_url_quoting)
|
|
||||||
|
|
||||||
|
|
||||||
def set_cloze_button(editor: Editor) -> None:
|
def set_cloze_button(editor: Editor) -> None:
|
||||||
|
|
|
@ -482,7 +482,6 @@ class AnkiQt(QMainWindow):
|
||||||
return aqt.sound.av_refs_to_play_icons(text)
|
return aqt.sound.av_refs_to_play_icons(text)
|
||||||
|
|
||||||
def prepare_card_text_for_display(self, text: str) -> str:
|
def prepare_card_text_for_display(self, text: str) -> str:
|
||||||
text = self.col.media.escape_media_filenames(text)
|
|
||||||
text = self._add_play_buttons(text)
|
text = self._add_play_buttons(text)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ from PyQt5.QtWidgets import (
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki import Collection
|
from anki import Collection
|
||||||
|
from anki._legacy import deprecated
|
||||||
from anki.lang import TR, tr_legacyglobal # pylint: disable=unused-import
|
from anki.lang import TR, tr_legacyglobal # pylint: disable=unused-import
|
||||||
from anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild
|
from anki.utils import invalidFilename, isMac, isWin, noBundledLibs, versionWithBuild
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
|
@ -679,9 +680,8 @@ def restore_combo_history(comboBox: QComboBox, name: str) -> List[str]:
|
||||||
return history
|
return history
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(info="use mw.prepare_card_text_for_display()")
|
||||||
def mungeQA(col: Collection, txt: str) -> str:
|
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
|
return txt
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue