mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-06-10 12:22:27 +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
|
# After the redirect in case config does logging setup
|
||||||
from config import appversion, appversion_nobuild, config, copyright
|
from config import appversion, appversion_nobuild, config, copyright
|
||||||
from EDMCLogging import edmclogger, logger, logging
|
from EDMCLogging import edmclogger, logger, logging
|
||||||
from journal_lock import JournalLock
|
from journal_lock import JournalLock, JournalLockResult
|
||||||
|
|
||||||
if __name__ == '__main__': # noqa: C901
|
if __name__ == '__main__': # noqa: C901
|
||||||
# Command-line arguments
|
# Command-line arguments
|
||||||
@ -72,16 +72,14 @@ if __name__ == '__main__': # noqa: C901
|
|||||||
config.set_auth_force_localserver()
|
config.set_auth_force_localserver()
|
||||||
|
|
||||||
def handle_edmc_callback_or_foregrounding(): # noqa: CCR001
|
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...')
|
logger.trace('Begin...')
|
||||||
|
|
||||||
if platform == 'win32':
|
if platform == 'win32':
|
||||||
|
|
||||||
# If *this* instance hasn't locked, then another already has and we
|
# If *this* instance hasn't locked, then another already has and we
|
||||||
# now need to do the edmc:// checks for auth callback
|
# now need to do the edmc:// checks for auth callback
|
||||||
if not locked:
|
if locked != JournalLockResult.LOCKED:
|
||||||
import ctypes
|
import ctypes
|
||||||
from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPCWSTR, LPWSTR
|
from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPCWSTR, LPWSTR
|
||||||
|
|
||||||
@ -190,7 +188,7 @@ if __name__ == '__main__': # noqa: C901
|
|||||||
|
|
||||||
handle_edmc_callback_or_foregrounding()
|
handle_edmc_callback_or_foregrounding()
|
||||||
|
|
||||||
if not locked:
|
if locked == JournalLockResult.ALREADY_LOCKED:
|
||||||
# There's a copy already running.
|
# There's a copy already running.
|
||||||
|
|
||||||
logger.info("An EDMarketConnector.exe process was already running, exiting.")
|
logger.info("An EDMarketConnector.exe process was already running, exiting.")
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import pathlib
|
import pathlib
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
|
from enum import Enum
|
||||||
from os import getpid as os_getpid
|
from os import getpid as os_getpid
|
||||||
from sys import platform
|
from sys import platform
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
@ -17,6 +18,15 @@ if TYPE_CHECKING:
|
|||||||
return x
|
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:
|
class JournalLock:
|
||||||
"""Handle locking of journal directory."""
|
"""Handle locking of journal directory."""
|
||||||
|
|
||||||
@ -27,12 +37,13 @@ class JournalLock:
|
|||||||
self.journal_dir_lockfile_name: Optional[pathlib.Path] = None
|
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.
|
# 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.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.
|
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'
|
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}')
|
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
|
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+\""
|
logger.warning(f"Couldn't open \"{self.journal_dir_lockfile_name}\" for \"w+\""
|
||||||
f" Aborting duplicate process checks: {e!r}")
|
f" Aborting duplicate process checks: {e!r}")
|
||||||
return False
|
return JournalLockResult.JOURNALDIR_READONLY
|
||||||
|
|
||||||
if platform == 'win32':
|
if platform == 'win32':
|
||||||
logger.trace('win32, using msvcrt')
|
logger.trace('win32, using msvcrt')
|
||||||
@ -57,7 +68,7 @@ class JournalLock:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\""
|
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\""
|
||||||
f", assuming another process running: {e!r}")
|
f", assuming another process running: {e!r}")
|
||||||
return False
|
return JournalLockResult.ALREADY_LOCKED
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.trace('NOT win32, using fcntl')
|
logger.trace('NOT win32, using fcntl')
|
||||||
@ -67,7 +78,7 @@ class JournalLock:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
logger.warning("Not on win32 and we have no fcntl, can't use a file lock!"
|
logger.warning("Not on win32 and we have no fcntl, can't use a file lock!"
|
||||||
"Allowing multiple instances!")
|
"Allowing multiple instances!")
|
||||||
return True # Lie about being locked
|
return JournalLockResult.LOCKED
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fcntl.flock(self.journal_dir_lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
fcntl.flock(self.journal_dir_lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||||
@ -75,13 +86,15 @@ class JournalLock:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\", "
|
logger.info(f"Exception: Couldn't lock journal directory \"{self.journal_dir}\", "
|
||||||
f"assuming another process running: {e!r}")
|
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.write(f"Path: {self.journal_dir}\nPID: {os_getpid()}\n")
|
||||||
self.journal_dir_lockfile.flush()
|
self.journal_dir_lockfile.flush()
|
||||||
|
|
||||||
logger.trace('Done')
|
logger.trace('Done')
|
||||||
return True
|
self.locked = True
|
||||||
|
|
||||||
|
return JournalLockResult.LOCKED
|
||||||
|
|
||||||
def release_lock(self) -> bool:
|
def release_lock(self) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -89,6 +102,9 @@ class JournalLock:
|
|||||||
|
|
||||||
:return: bool - Success of unlocking operation.
|
:return: bool - Success of unlocking operation.
|
||||||
"""
|
"""
|
||||||
|
if not self.locked:
|
||||||
|
return True # We weren't locked, and still aren't
|
||||||
|
|
||||||
unlocked = False
|
unlocked = False
|
||||||
if platform == 'win32':
|
if platform == 'win32':
|
||||||
logger.trace('win32, using msvcrt')
|
logger.trace('win32, using msvcrt')
|
||||||
|
@ -4,3 +4,6 @@ watchdog==0.10.3
|
|||||||
# argh==0.26.2 watchdog dep
|
# argh==0.26.2 watchdog dep
|
||||||
# pyyaml==5.3.1 watchdog dep
|
# pyyaml==5.3.1 watchdog dep
|
||||||
semantic-version==2.8.5
|
semantic-version==2.8.5
|
||||||
|
|
||||||
|
# Base requirement for MacOS
|
||||||
|
pyobjc; sys_platform == 'darwin'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user