mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-15 08:40:34 +03:00
Merge branch 'release-4.2.1'
This commit is contained in:
commit
7707a811cb
@ -33,7 +33,7 @@ if __name__ == '__main__':
|
||||
# After the redirect in case config does logging setup
|
||||
from config import appversion, appversion_nobuild, config, copyright
|
||||
from EDMCLogging import edmclogger, logger, logging
|
||||
from journal_lock import JournalLock
|
||||
from journal_lock import JournalLock, JournalLockResult
|
||||
|
||||
if __name__ == '__main__': # noqa: C901
|
||||
# Command-line arguments
|
||||
@ -72,16 +72,14 @@ if __name__ == '__main__': # noqa: C901
|
||||
config.set_auth_force_localserver()
|
||||
|
||||
def handle_edmc_callback_or_foregrounding(): # noqa: CCR001
|
||||
"""
|
||||
Handle any edmc:// auth callback, else foreground existing window.
|
||||
"""
|
||||
"""Handle any edmc:// auth callback, else foreground existing window."""
|
||||
logger.trace('Begin...')
|
||||
|
||||
if platform == 'win32':
|
||||
|
||||
# If *this* instance hasn't locked, then another already has and we
|
||||
# now need to do the edmc:// checks for auth callback
|
||||
if not locked:
|
||||
if locked != JournalLockResult.LOCKED:
|
||||
import ctypes
|
||||
from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPCWSTR, LPWSTR
|
||||
|
||||
@ -190,7 +188,7 @@ if __name__ == '__main__': # noqa: C901
|
||||
|
||||
handle_edmc_callback_or_foregrounding()
|
||||
|
||||
if not locked:
|
||||
if locked == JournalLockResult.ALREADY_LOCKED:
|
||||
# There's a copy already running.
|
||||
|
||||
logger.info("An EDMarketConnector.exe process was already running, exiting.")
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
import pathlib
|
||||
import tkinter as tk
|
||||
from enum import Enum
|
||||
from os import getpid as os_getpid
|
||||
from sys import platform
|
||||
from tkinter import ttk
|
||||
@ -17,6 +18,15 @@ if TYPE_CHECKING:
|
||||
return x
|
||||
|
||||
|
||||
class JournalLockResult(Enum):
|
||||
"""Enumeration of possible outcomes of trying to lock the Journal Directory."""
|
||||
|
||||
LOCKED = 1
|
||||
JOURNALDIR_NOTEXIST = 2
|
||||
JOURNALDIR_READONLY = 3
|
||||
ALREADY_LOCKED = 4
|
||||
|
||||
|
||||
class JournalLock:
|
||||
"""Handle locking of journal directory."""
|
||||
|
||||
@ -27,12 +37,13 @@ class JournalLock:
|
||||
self.journal_dir_lockfile_name: Optional[pathlib.Path] = None
|
||||
# We never test truthiness of this, so let it be defined when first assigned. Avoids type hint issues.
|
||||
# self.journal_dir_lockfile: Optional[IO] = None
|
||||
self.locked = False
|
||||
|
||||
def obtain_lock(self) -> bool:
|
||||
def obtain_lock(self) -> JournalLockResult:
|
||||
"""
|
||||
Attempt to obtain a lock on the journal directory.
|
||||
|
||||
:return: bool - True if we successfully obtained the lock
|
||||
:return: LockResult - See the class Enum definition
|
||||
"""
|
||||
self.journal_dir_lockfile_name = self.journal_dir_path / 'edmc-journal-lock.txt'
|
||||
logger.trace(f'journal_dir_lockfile_name = {self.journal_dir_lockfile_name!r}')
|
||||
@ -44,7 +55,7 @@ class JournalLock:
|
||||
except Exception as e: # For remote FS this could be any of a wide range of exceptions
|
||||
logger.warning(f"Couldn't open \"{self.journal_dir_lockfile_name}\" for \"w+\""
|
||||
f" Aborting duplicate process checks: {e!r}")
|
||||
return False
|
||||
return JournalLockResult.JOURNALDIR_READONLY
|
||||
|
||||
if platform == 'win32':
|
||||
logger.trace('win32, using msvcrt')
|
||||
@ -57,7 +68,7 @@ class JournalLock:
|
||||
except Exception as e:
|
||||
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\""
|
||||
f", assuming another process running: {e!r}")
|
||||
return False
|
||||
return JournalLockResult.ALREADY_LOCKED
|
||||
|
||||
else:
|
||||
logger.trace('NOT win32, using fcntl')
|
||||
@ -67,7 +78,7 @@ class JournalLock:
|
||||
except ImportError:
|
||||
logger.warning("Not on win32 and we have no fcntl, can't use a file lock!"
|
||||
"Allowing multiple instances!")
|
||||
return True # Lie about being locked
|
||||
return JournalLockResult.LOCKED
|
||||
|
||||
try:
|
||||
fcntl.flock(self.journal_dir_lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
@ -75,13 +86,15 @@ class JournalLock:
|
||||
except Exception as e:
|
||||
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\", "
|
||||
f"assuming another process running: {e!r}")
|
||||
return False
|
||||
return JournalLockResult.ALREADY_LOCKED
|
||||
|
||||
self.journal_dir_lockfile.write(f"Path: {self.journal_dir}\nPID: {os_getpid()}\n")
|
||||
self.journal_dir_lockfile.flush()
|
||||
|
||||
logger.trace('Done')
|
||||
return True
|
||||
self.locked = True
|
||||
|
||||
return JournalLockResult.LOCKED
|
||||
|
||||
def release_lock(self) -> bool:
|
||||
"""
|
||||
@ -89,6 +102,9 @@ class JournalLock:
|
||||
|
||||
:return: bool - Success of unlocking operation.
|
||||
"""
|
||||
if not self.locked:
|
||||
return True # We weren't locked, and still aren't
|
||||
|
||||
unlocked = False
|
||||
if platform == 'win32':
|
||||
logger.trace('win32, using msvcrt')
|
||||
|
@ -4,3 +4,6 @@ watchdog==0.10.3
|
||||
# argh==0.26.2 watchdog dep
|
||||
# pyyaml==5.3.1 watchdog dep
|
||||
semantic-version==2.8.5
|
||||
|
||||
# Base requirement for MacOS
|
||||
pyobjc; sys_platform == 'darwin'
|
||||
|
Loading…
x
Reference in New Issue
Block a user