ba68764fcb
A few reports like https://forums.ankiweb.net/t/error-report-check-database-did-not-work/25796 indicate that the previous solution has not helped, and has just made things worse. My guess is that AppNap on macOS is preventing the timer from even running before the file gets cleaned up.
92 lines
2.6 KiB
Python
92 lines
2.6 KiB
Python
# Copyright: Ankitects Pty Ltd and contributors
|
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
"""Helpers for the packaged version of Anki."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def _fix_pywin32() -> None:
|
|
# extend sys.path with .pth files
|
|
import site
|
|
|
|
site.addsitedir(sys.path[0])
|
|
|
|
# use updated sys.path to locate dll folder and add it to path
|
|
path = sys.path[-1]
|
|
path = path.replace("Pythonwin", "pywin32_system32")
|
|
os.environ["PATH"] += ";" + path
|
|
|
|
# import Python modules from .dll files
|
|
import importlib.machinery
|
|
|
|
for name in "pythoncom", "pywintypes":
|
|
filename = os.path.join(path, name + "39.dll")
|
|
loader = importlib.machinery.ExtensionFileLoader(name, filename)
|
|
spec = importlib.machinery.ModuleSpec(name=name, loader=loader, origin=filename)
|
|
_mod = importlib._bootstrap._load(spec) # type: ignore
|
|
|
|
|
|
def _patch_pkgutil() -> None:
|
|
"""Teach pkgutil.get_data() how to read files from in-memory resources.
|
|
|
|
This is required for jsonschema."""
|
|
import importlib
|
|
import pkgutil
|
|
|
|
def get_data_custom(package: str, resource: str) -> bytes | None:
|
|
try:
|
|
module = importlib.import_module(package)
|
|
reader = module.__loader__.get_resource_reader(package) # type: ignore[attr-defined]
|
|
with reader.open_resource(resource) as f:
|
|
return f.read()
|
|
except:
|
|
return None
|
|
|
|
pkgutil.get_data = get_data_custom
|
|
|
|
|
|
def _patch_certifi() -> None:
|
|
"""Tell certifi (and thus requests) to use a file in our package folder.
|
|
|
|
By default it creates a copy of the data in a temporary folder, which then gets
|
|
cleaned up by macOS's temp file cleaner."""
|
|
import certifi
|
|
|
|
def where() -> str:
|
|
prefix = Path(sys.prefix)
|
|
if sys.platform == "darwin":
|
|
path = prefix / "../Resources/certifi/cacert.pem"
|
|
else:
|
|
path = prefix / "lib" / "certifi" / "cacert.pem"
|
|
return str(path)
|
|
|
|
certifi.where = where
|
|
|
|
|
|
def packaged_build_setup() -> None:
|
|
if not getattr(sys, "frozen", False):
|
|
return
|
|
|
|
print("Initial setup...")
|
|
|
|
if sys.platform == "win32":
|
|
_fix_pywin32()
|
|
|
|
_patch_pkgutil()
|
|
_patch_certifi()
|
|
|
|
# escape hatch for debugging issues with packaged build startup
|
|
if os.getenv("ANKI_STARTUP_REPL"):
|
|
# mypy incorrectly thinks this does not exist on Windows
|
|
is_tty = os.isatty(sys.stdin.fileno()) # type: ignore
|
|
if is_tty:
|
|
import code
|
|
|
|
code.InteractiveConsole().interact()
|
|
sys.exit(0)
|