Fix autostart working directory breaking paths

This commit is contained in:
DevilXD committed 2022-03-17 12:33:53 +01:00
1 parent ccf7fbf96d
commit a30aa6f403
6 files changed
+34 -27

No files matched your search

+9 -4
View File
@@ -1,7 +1,9 @@
from __future__ import annotations from __future__ import annotations
import sys
import logging import logging
from copy import copy from copy import copy
from pathlib import Path
from enum import Enum, auto from enum import Enum, auto
from datetime import timedelta from datetime import timedelta
from typing import Any, Dict, Literal, TYPE_CHECKING from typing import Any, Dict, Literal, TYPE_CHECKING
@@ -14,6 +16,13 @@ if TYPE_CHECKING:
from collections import abc # noqa from collections import abc # noqa
# Base Paths
SELF_PATH = Path(sys.argv[0])
WORKING_DIR = SELF_PATH.absolute().parent
# Other Paths
LOG_PATH = Path(WORKING_DIR, "log.txt")
COOKIES_PATH = Path(WORKING_DIR, "cookies.jar")
SETTINGS_PATH = Path(WORKING_DIR, "settings.json")
# Typing # Typing
JsonType = Dict[str, Any] JsonType = Dict[str, Any]
TopicProcess: TypeAlias = "abc.Callable[[int, JsonType], Any]" TopicProcess: TypeAlias = "abc.Callable[[int, JsonType], Any]"
@@ -27,10 +36,6 @@ USER_AGENT = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/99.0.4844.51 Safari/537.36" "Chrome/99.0.4844.51 Safari/537.36"
) )
# Paths
LOG_PATH = "log.txt"
COOKIES_PATH = "cookies.jar"
SETTINGS_PATH = "settings.json"
# Intervals and Delays # Intervals and Delays
PING_INTERVAL = timedelta(minutes=3) PING_INTERVAL = timedelta(minutes=3)
PING_TIMEOUT = timedelta(seconds=10) PING_TIMEOUT = timedelta(seconds=10)
+2 -4
View File
@@ -1,10 +1,8 @@
from __future__ import annotations from __future__ import annotations
import sys
import asyncio import asyncio
import logging import logging
import tkinter as tk import tkinter as tk
from pathlib import Path
from math import log10, ceil from math import log10, ceil
from functools import partial from functools import partial
from tkinter.font import Font from tkinter.font import Font
@@ -19,7 +17,7 @@ except ModuleNotFoundError as exc:
from utils import resource_path from utils import resource_path
from registry import RegistryKey, ValueType from registry import RegistryKey, ValueType
from constants import FORMATTER, WS_TOPICS_LIMIT, MAX_WEBSOCKETS, WINDOW_TITLE, State from constants import SELF_PATH, FORMATTER, WS_TOPICS_LIMIT, MAX_WEBSOCKETS, WINDOW_TITLE, State
if TYPE_CHECKING: if TYPE_CHECKING:
from twitch import Twitch from twitch import Twitch
@@ -1099,7 +1097,7 @@ class SettingsPanel:
self._settings.autostart_tray = tray self._settings.autostart_tray = tray
if enabled: if enabled:
# NOTE: we need double quotes in case the path contains spaces # NOTE: we need double quotes in case the path contains spaces
self_path = f'"{Path(sys.argv[0]).resolve()!s}"' self_path = f'"{SELF_PATH.absolute().resolve()!s}"'
if tray: if tray:
self_path += " --tray" self_path += " --tray"
with RegistryKey("HKCU/Software/Microsoft/Windows/CurrentVersion/Run") as key: with RegistryKey("HKCU/Software/Microsoft/Windows/CurrentVersion/Run") as key:
+2 -3
View File
@@ -9,7 +9,6 @@ import logging
import argparse import argparse
import traceback import traceback
import tkinter as tk import tkinter as tk
from pathlib import Path
from tkinter import messagebox from tkinter import messagebox
from typing import IO, NoReturn from typing import IO, NoReturn
@@ -17,7 +16,7 @@ from twitch import Twitch
from settings import Settings from settings import Settings
from version import __version__ from version import __version__
from exceptions import CaptchaRequired from exceptions import CaptchaRequired
from constants import FORMATTER, LOG_PATH, WINDOW_TITLE from constants import SELF_PATH, FORMATTER, LOG_PATH, WINDOW_TITLE
class Parser(argparse.ArgumentParser): class Parser(argparse.ArgumentParser):
@@ -84,7 +83,7 @@ root.overrideredirect(True)
root.withdraw() root.withdraw()
root.update() root.update()
parser = Parser( parser = Parser(
Path(sys.argv[0]).name, SELF_PATH.name,
description="A program that allows you to mine timed drops on Twitch.", description="A program that allows you to mine timed drops on Twitch.",
) )
parser.add_argument("--version", action="version", version=f"v{__version__}") parser.add_argument("--version", action="version", version=f"v{__version__}")
+3 -7
View File
@@ -2,7 +2,6 @@ from __future__ import annotations
import json import json
from enum import Enum from enum import Enum
from pathlib import Path
from typing import Any, TypedDict, TYPE_CHECKING from typing import Any, TypedDict, TYPE_CHECKING
from constants import JsonType, SETTINGS_PATH from constants import JsonType, SETTINGS_PATH
@@ -11,9 +10,6 @@ if TYPE_CHECKING:
from main import ParsedArgs from main import ParsedArgs
PATH = Path(SETTINGS_PATH)
class SettingsFile(TypedDict): class SettingsFile(TypedDict):
autostart: bool autostart: bool
exclude: set[str] exclude: set[str]
@@ -72,8 +68,8 @@ class Settings:
def __init__(self, args: ParsedArgs): def __init__(self, args: ParsedArgs):
self._settings: SettingsFile = default_settings.copy() self._settings: SettingsFile = default_settings.copy()
if PATH.exists(): if SETTINGS_PATH.exists():
with open(PATH, 'r') as file: with open(SETTINGS_PATH, 'r') as file:
self._settings.update(json.load(file, object_hook=deserialize)) self._settings.update(json.load(file, object_hook=deserialize))
self._args: ParsedArgs = args self._args: ParsedArgs = args
@@ -98,5 +94,5 @@ class Settings:
raise RuntimeError("settings can't be deleted") raise RuntimeError("settings can't be deleted")
def save(self) -> None: def save(self) -> None:
with open(PATH, 'w') as file: with open(SETTINGS_PATH, 'w') as file:
json.dump(self._settings, file, default=serialize, sort_keys=True, indent=4) json.dump(self._settings, file, default=serialize, sort_keys=True, indent=4)
+3 -3
View File
@@ -1,6 +1,5 @@
from __future__ import annotations from __future__ import annotations
import os
import asyncio import asyncio
import logging import logging
from yarl import URL from yarl import URL
@@ -84,7 +83,7 @@ class Twitch:
def initialize(self) -> None: def initialize(self) -> None:
cookie_jar = aiohttp.CookieJar() cookie_jar = aiohttp.CookieJar()
if os.path.isfile(COOKIES_PATH): if COOKIES_PATH.exists():
cookie_jar.load(COOKIES_PATH) cookie_jar.load(COOKIES_PATH)
self._session = aiohttp.ClientSession( self._session = aiohttp.ClientSession(
cookie_jar=cookie_jar, cookie_jar=cookie_jar,
@@ -101,7 +100,8 @@ class Twitch:
self._watching_task = None self._watching_task = None
# close session, save cookies and stop websocket # close session, save cookies and stop websocket
if self._session is not None: if self._session is not None:
self._session.cookie_jar.save(COOKIES_PATH) # type: ignore cookie_jar = cast(aiohttp.CookieJar, self._session.cookie_jar)
cookie_jar.save(COOKIES_PATH)
await self._session.close() await self._session.close()
self._session = None self._session = None
await self.websocket.stop() await self.websocket.stop()
+15 -6
View File
@@ -1,18 +1,18 @@
from __future__ import annotations from __future__ import annotations
import os
import sys import sys
import random import random
import string import string
import asyncio import asyncio
import logging import logging
from pathlib import Path
from functools import wraps from functools import wraps
from contextlib import suppress from contextlib import suppress
from datetime import datetime, timezone from datetime import datetime, timezone
from collections import abc, OrderedDict from collections import abc, OrderedDict
from typing import Any, Literal, MutableSet, Generic, TypeVar, cast, TYPE_CHECKING from typing import Any, Literal, MutableSet, Generic, TypeVar, cast, TYPE_CHECKING
from constants import JsonType from constants import WORKING_DIR, JsonType
if TYPE_CHECKING: if TYPE_CHECKING:
from typing_extensions import ParamSpec from typing_extensions import ParamSpec
@@ -30,10 +30,19 @@ logger = logging.getLogger("TwitchDrops")
NONCE_CHARS = string.ascii_letters + string.digits NONCE_CHARS = string.ascii_letters + string.digits
def resource_path(relative_path): def resource_path(relative_path: Path | str) -> Path:
"""Get absolute path to resource, works for dev and for PyInstaller""" """
base_path = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__))) Get an absolute path to a bundled resource.
return os.path.join(base_path, relative_path)
Works for dev and for PyInstaller.
"""
if hasattr(sys, "_MEIPASS"):
# PyInstaller's folder where the one-file app is unpacked
meipass: str = getattr(sys, "_MEIPASS")
base_path = Path(meipass)
else:
base_path = WORKING_DIR
return base_path.joinpath(relative_path)
def timestamp(string: str) -> datetime: def timestamp(string: str) -> datetime: