Keep cwd and pass dir to player subprocess instead (#1656)

This commit is contained in:
RumovZ 2022-02-11 01:35:48 +01:00 committed by GitHub
parent cc91017bf1
commit 6c8cdc0a0c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 53 deletions

View file

@ -245,7 +245,6 @@ class Collection(DeprecatedNamesMixin):
self._clear_caches()
self._backend.close_collection(downgrade_to_schema11=downgrade)
self.db = None
self.media.close()
def close_for_full_sync(self) -> None:
# save and cleanup, but backend will take care of collection close
@ -253,7 +252,6 @@ class Collection(DeprecatedNamesMixin):
self.save(trx=False)
self._clear_caches()
self.db = None
self.media.close()
def rollback(self) -> None:
self._clear_caches()
@ -285,8 +283,6 @@ class Collection(DeprecatedNamesMixin):
media_db_path=media_db,
log_path=log_path,
)
else:
self.media.connect()
self.db = DBProxy(weakref.proxy(self._backend))
self.db.begin()

View file

@ -29,11 +29,6 @@ def media_paths_from_col_path(col_path: str) -> tuple[str, str]:
CheckMediaResponse = media_pb2.CheckMediaResponse
# fixme: look into whether we can drop chdir() below
# - need to check aa89d06304fecd3597da4565330a3e55bdbb91fe
# - and audio handling code
class MediaManager(DeprecatedNamesMixin):
sound_regexps = [r"(?i)(\[sound:(?P<fname>[^]]+)\])"]
@ -51,45 +46,19 @@ class MediaManager(DeprecatedNamesMixin):
def __init__(self, col: anki.collection.Collection, server: bool) -> None:
self.col = col.weakref()
self._dir: str | None = None
if server:
return
# media directory
self._dir = media_paths_from_col_path(self.col.path)[0]
if not os.path.exists(self._dir):
os.makedirs(self._dir)
try:
self._oldcwd = os.getcwd()
except OSError:
# cwd doesn't exist
self._oldcwd = None
try:
os.chdir(self._dir)
except OSError as exc:
raise Exception("invalidTempFolder") from exc
def __repr__(self) -> str:
dict_ = dict(self.__dict__)
del dict_["col"]
return f"{super().__repr__()} {pprint.pformat(dict_, width=300)}"
def connect(self) -> None:
if self.col.server:
return
os.chdir(self._dir)
def close(self) -> None:
if self.col.server:
return
# change cwd back to old location
if self._oldcwd:
try:
os.chdir(self._oldcwd)
except:
# may have been deleted
pass
def dir(self) -> str | None:
def dir(self) -> str:
return self._dir
def force_resync(self) -> None:

View file

@ -192,7 +192,6 @@ class AnkiQt(QMainWindow):
self.setupKeys()
self.setupThreads()
self.setupMediaServer()
self.setupSound()
self.setupSpellCheck()
self.setupProgress()
self.setupStyle()
@ -449,6 +448,7 @@ class AnkiQt(QMainWindow):
if not self.loadCollection():
return
self.setup_sound()
self.flags = FlagManager(self)
# show main window
if self.pm.profile["mainWindowState"]:
@ -486,6 +486,7 @@ class AnkiQt(QMainWindow):
self.unloadCollection(callback)
def _unloadProfile(self) -> None:
self.cleanup_sound()
saveGeom(self, "mainWindow")
saveState(self, "mainWindow")
self.pm.save()
@ -519,8 +520,11 @@ class AnkiQt(QMainWindow):
# Sound/video
##########################################################################
def setupSound(self) -> None:
aqt.sound.setup_audio(self.taskman, self.pm.base)
def setup_sound(self) -> None:
aqt.sound.setup_audio(self.taskman, self.pm.base, self.col.media.dir())
def cleanup_sound(self) -> None:
aqt.sound.cleanup_audio()
def _add_play_buttons(self, text: str) -> str:
"Return card text with play buttons added, or stripped."

View file

@ -3,7 +3,6 @@
from __future__ import annotations
import atexit
import os
import platform
import re
@ -271,8 +270,9 @@ class SimpleProcessPlayer(Player): # pylint: disable=abstract-method
args: list[str] = []
env: dict[str, str] | None = None
def __init__(self, taskman: TaskManager) -> None:
def __init__(self, taskman: TaskManager, media_folder: str | None = None) -> None:
self._taskman = taskman
self._media_folder = media_folder
self._terminate_flag = False
self._process: subprocess.Popen | None = None
self._warned_about_missing_player = False
@ -292,6 +292,7 @@ class SimpleProcessPlayer(Player): # pylint: disable=abstract-method
self._process = subprocess.Popen(
self.args + [tag.filename],
env=self.env,
cwd=self._media_folder,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
@ -359,8 +360,10 @@ class SimpleMpvPlayer(SimpleProcessPlayer, VideoPlayer):
]
)
def __init__(self, taskman: TaskManager, base_folder: str) -> None:
super().__init__(taskman)
def __init__(
self, taskman: TaskManager, base_folder: str, media_folder: str
) -> None:
super().__init__(taskman, media_folder)
self.args += [f"--config-dir={base_folder}"]
@ -381,7 +384,8 @@ class MpvManager(MPV, SoundOrVideoPlayer):
"--input-media-keys=no",
]
def __init__(self, base_path: str) -> None:
def __init__(self, base_path: str, media_folder: str) -> None:
self.media_folder = media_folder
mpvPath, self.popenEnv = _packagedCmd(["mpv"])
self.executable = mpvPath[0]
self._on_done: OnDoneCallback | None = None
@ -407,7 +411,7 @@ class MpvManager(MPV, SoundOrVideoPlayer):
assert isinstance(tag, SoundOrVideoTag)
self._on_done = on_done
filename = hooks.media_file_filter(tag.filename)
path = os.path.join(os.getcwd(), filename)
path = os.path.join(self.media_folder, filename)
self.command("loadfile", path, "replace", "pause=no")
gui_hooks.av_player_did_begin_playing(self, tag)
@ -446,8 +450,9 @@ class MpvManager(MPV, SoundOrVideoPlayer):
class SimpleMplayerSlaveModePlayer(SimpleMplayerPlayer):
def __init__(self, taskman: TaskManager) -> None:
super().__init__(taskman)
def __init__(self, taskman: TaskManager, media_folder: str) -> None:
self.media_folder = media_folder
super().__init__(taskman, media_folder)
self.args.append("-slave")
def _play(self, tag: AVTag) -> None:
@ -458,6 +463,7 @@ class SimpleMplayerSlaveModePlayer(SimpleMplayerPlayer):
self._process = subprocess.Popen(
self.args + [filename],
env=self.env,
cwd=self.media_folder,
stdin=subprocess.PIPE,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
@ -819,12 +825,12 @@ def play_clicked_audio(pycmd: str, card: Card) -> None:
##########################################################################
def setup_audio(taskman: TaskManager, base_folder: str) -> None:
def setup_audio(taskman: TaskManager, base_folder: str, media_folder: str) -> None:
# legacy global var
global mpvManager
try:
mpvManager = MpvManager(base_folder)
mpvManager = MpvManager(base_folder, media_folder)
except FileNotFoundError:
print("mpv not found, reverting to mplayer")
except aqt.mpv.MPVProcessError:
@ -834,10 +840,10 @@ def setup_audio(taskman: TaskManager, base_folder: str) -> None:
av_player.players.append(mpvManager)
if is_win:
mpvPlayer = SimpleMpvPlayer(taskman, base_folder)
mpvPlayer = SimpleMpvPlayer(taskman, base_folder, media_folder)
av_player.players.append(mpvPlayer)
else:
mplayer = SimpleMplayerSlaveModePlayer(taskman)
mplayer = SimpleMplayerSlaveModePlayer(taskman, media_folder)
av_player.players.append(mplayer)
# tts support
@ -857,5 +863,6 @@ def setup_audio(taskman: TaskManager, base_folder: str) -> None:
if int(platform.version().split(".")[-1]) >= 17763:
av_player.players.append(WindowsRTTTSFilePlayer(taskman))
# cleanup at shutdown
atexit.register(av_player.shutdown)
def cleanup_audio() -> None:
av_player.shutdown()