1
0
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:
Athanasius 2021-03-15 16:09:21 +00:00
commit 7707a811cb
3 changed files with 30 additions and 13 deletions

View File

@ -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.")

View File

@ -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')

View File

@ -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'