Skip to content

Commit 2b8b8f1

Browse files
committed
fix: handle special characters in filenames
1 parent 4e1c91a commit 2b8b8f1

1 file changed

Lines changed: 91 additions & 6 deletions

File tree

haru.py

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
import shutil
55
import sys
6+
import unicodedata
67
from urllib.parse import parse_qsl, quote_plus
78

89
import requests
@@ -142,7 +143,7 @@ def nyaa_menu():
142143
True,
143144
),
144145
],
145-
),
146+
)
146147
xbmcplugin.endOfDirectory(HANDLE)
147148

148149

@@ -185,7 +186,7 @@ def sukebei_menu():
185186
True,
186187
),
187188
],
188-
),
189+
)
189190
xbmcplugin.endOfDirectory(HANDLE)
190191

191192

@@ -307,15 +308,99 @@ def _play_nyaa(selected_file=None, url=None, magnet=None):
307308
resolved_url = resolveurl.HostedMediaFile(url=magnet).resolve()
308309
else:
309310
all_urls = resolveurl.resolve(magnet, return_all=True)
311+
log(
312+
"resolveurl return_all for selected_file={} -> type={} value={}".format(
313+
selected_file, type(all_urls).__name__, all_urls
314+
)
315+
)
310316
if isinstance(all_urls, str):
311317
# sometimes we get it already resolved as a single string?
312318
# this should fix: string indices must be integers, not 'str'
313319
resolved_url = all_urls
320+
elif not all_urls:
321+
log("resolveurl return_all empty; falling back to magnet resolve")
322+
resolved_url = resolveurl.resolve(magnet)
314323
else:
315-
selected_url = next(
316-
filter(lambda x: selected_file in x["name"], all_urls)
317-
)["link"]
318-
resolved_url = resolveurl.resolve(selected_url)
324+
325+
def normalize_match_text(value, ascii_only=False):
326+
if not value:
327+
return ""
328+
normalized = unicodedata.normalize("NFKC", value)
329+
if ascii_only:
330+
normalized = normalized.encode("ascii", "ignore").decode(
331+
"ascii"
332+
)
333+
return " ".join(normalized.split()).casefold()
334+
335+
selected_normalized = normalize_match_text(selected_file)
336+
selected_ascii = normalize_match_text(selected_file, ascii_only=True)
337+
338+
entries = []
339+
for item in all_urls:
340+
name = item.get("name", "") if isinstance(item, dict) else str(item)
341+
entries.append(
342+
{
343+
"item": item,
344+
"normalized": normalize_match_text(name),
345+
"ascii": normalize_match_text(name, ascii_only=True),
346+
}
347+
)
348+
349+
def is_exact_match(entry):
350+
return (
351+
entry["normalized"]
352+
and selected_normalized
353+
and entry["normalized"] == selected_normalized
354+
) or (
355+
entry["ascii"]
356+
and selected_ascii
357+
and entry["ascii"] == selected_ascii
358+
)
359+
360+
def is_partial_match(entry):
361+
return (
362+
entry["normalized"]
363+
and selected_normalized
364+
and (
365+
selected_normalized in entry["normalized"]
366+
or entry["normalized"] in selected_normalized
367+
)
368+
) or (
369+
entry["ascii"]
370+
and selected_ascii
371+
and (
372+
selected_ascii in entry["ascii"]
373+
or entry["ascii"] in selected_ascii
374+
)
375+
)
376+
377+
matched_entry = next(
378+
(entry["item"] for entry in entries if is_exact_match(entry)),
379+
None,
380+
)
381+
if not matched_entry:
382+
matched_entry = next(
383+
(entry["item"] for entry in entries if is_partial_match(entry)),
384+
None,
385+
)
386+
if not matched_entry:
387+
log(
388+
"resolveurl could not match selected_file={}; normalized={} ascii={}; using first entry".format(
389+
selected_file, selected_normalized, selected_ascii
390+
)
391+
)
392+
matched_entry = all_urls[0]
393+
if isinstance(matched_entry, dict):
394+
selected_url = matched_entry.get("link")
395+
else:
396+
selected_url = matched_entry
397+
if not selected_url:
398+
log(
399+
"resolveurl selected_url missing; falling back to magnet resolve"
400+
)
401+
resolved_url = resolveurl.resolve(magnet)
402+
else:
403+
resolved_url = resolveurl.resolve(selected_url)
319404
play_item = xbmcgui.ListItem(path=resolved_url)
320405
xbmcplugin.setResolvedUrl(HANDLE, True, listitem=play_item)
321406

0 commit comments

Comments
 (0)