mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-18 09:57:40 +03:00
Use watchdog module instead of polling for new log files.
Notify user at startup if client restart required.
This commit is contained in:
parent
393ade32af
commit
a94cf4cfd9
@ -155,12 +155,6 @@ class AppWindow:
|
|||||||
if platform != 'linux2': # update_idletasks() doesn't allow for the menubar on Linux
|
if platform != 'linux2': # update_idletasks() doesn't allow for the menubar on Linux
|
||||||
self.w.maxsize(-1, h) # Maximum height = initial height
|
self.w.maxsize(-1, h) # Maximum height = initial height
|
||||||
|
|
||||||
# First run
|
|
||||||
if not config.get('username') or not config.get('password'):
|
|
||||||
prefs.PreferencesDialog(self.w, self.login)
|
|
||||||
else:
|
|
||||||
self.login()
|
|
||||||
|
|
||||||
# Load updater after UI creation (for WinSparkle)
|
# Load updater after UI creation (for WinSparkle)
|
||||||
import update
|
import update
|
||||||
self.updater = update.Updater(self.w)
|
self.updater = update.Updater(self.w)
|
||||||
@ -176,6 +170,12 @@ class AppWindow:
|
|||||||
monitor.enable_logging()
|
monitor.enable_logging()
|
||||||
monitor.start(self.w)
|
monitor.start(self.w)
|
||||||
|
|
||||||
|
# First run
|
||||||
|
if not config.get('username') or not config.get('password'):
|
||||||
|
prefs.PreferencesDialog(self.w, self.login)
|
||||||
|
else:
|
||||||
|
self.login()
|
||||||
|
|
||||||
# call after credentials have changed
|
# call after credentials have changed
|
||||||
def login(self):
|
def login(self):
|
||||||
self.status['text'] = _('Logging in...')
|
self.status['text'] = _('Logging in...')
|
||||||
@ -201,6 +201,9 @@ class AppWindow:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
if __debug__: print_exc()
|
if __debug__: print_exc()
|
||||||
self.status['text'] = unicode(e)
|
self.status['text'] = unicode(e)
|
||||||
|
|
||||||
|
if not self.status['text'] and monitor.restart_required():
|
||||||
|
self.status['text'] = _('Re-start Elite: Dangerous for automatic log entries') # Status bar message on launch
|
||||||
self.cooldown()
|
self.cooldown()
|
||||||
|
|
||||||
# callback after verification code
|
# callback after verification code
|
||||||
|
@ -139,6 +139,9 @@
|
|||||||
/* Privacy setting. [prefs.py] */
|
/* Privacy setting. [prefs.py] */
|
||||||
"Pseudo-anonymized ID" = "Pseudo-anonymized ID";
|
"Pseudo-anonymized ID" = "Pseudo-anonymized ID";
|
||||||
|
|
||||||
|
/* Status bar message on launch. [EDMarketConnector.py] */
|
||||||
|
"Re-start Elite: Dangerous for automatic log entries" = "Re-start Elite: Dangerous for automatic log entries";
|
||||||
|
|
||||||
/* Output settings prompt. [prefs.py] */
|
/* Output settings prompt. [prefs.py] */
|
||||||
"Re-start Elite: Dangerous to use this feature" = "Re-start Elite: Dangerous to use this feature";
|
"Re-start Elite: Dangerous to use this feature" = "Re-start Elite: Dangerous to use this feature";
|
||||||
|
|
||||||
|
@ -201,3 +201,6 @@
|
|||||||
|
|
||||||
/* [EDMarketConnector.py] */
|
/* [EDMarketConnector.py] */
|
||||||
"Error: Can't get market data!" = "Erreur: Impossible d'obtenir les données du marché!";
|
"Error: Can't get market data!" = "Erreur: Impossible d'obtenir les données du marché!";
|
||||||
|
|
||||||
|
/* Status bar message on launch. [EDMarketConnector.py] */
|
||||||
|
"Re-start Elite: Dangerous for automatic log entries" = "Re-démarrer Elite: Dangereux pour les entrées de journal automatique";
|
||||||
|
@ -197,7 +197,10 @@
|
|||||||
"Automatically make a log entry on entering a system" = "Inserire automaticamente una log entry entrando in un sistema";
|
"Automatically make a log entry on entering a system" = "Inserire automaticamente una log entry entrando in un sistema";
|
||||||
|
|
||||||
/* Output settings prompt. [prefs.py] */
|
/* Output settings prompt. [prefs.py] */
|
||||||
"Re-start Elite: Dangerous to use this feature" = "Riavviare Elite:Dangerous per usare questa funzione";
|
"Re-start Elite: Dangerous to use this feature" = "Riavviare Elite: Dangerous per usare questa funzione";
|
||||||
|
|
||||||
/* [EDMarketConnector.py] */
|
/* [EDMarketConnector.py] */
|
||||||
"Error: Can't get market data!" = "Errore: Non riesco a ottenere il market data!";
|
"Error: Can't get market data!" = "Errore: Non riesco a ottenere il market data!";
|
||||||
|
|
||||||
|
/* Status bar message on launch. [EDMarketConnector.py] */
|
||||||
|
"Re-start Elite: Dangerous for automatic log entries" = "Riavviare Elite: Dangerous per una log entry automatica";
|
||||||
|
@ -192,3 +192,6 @@
|
|||||||
|
|
||||||
/* [EDMarketConnector.py] */
|
/* [EDMarketConnector.py] */
|
||||||
"Sending data to EDSM..." = "Wysłanie danych do EDSM...";
|
"Sending data to EDSM..." = "Wysłanie danych do EDSM...";
|
||||||
|
|
||||||
|
/* Output settings prompt. [prefs.py] */
|
||||||
|
"Re-start Elite: Dangerous to use this feature" = "";
|
||||||
|
61
monitor.py
61
monitor.py
@ -1,12 +1,16 @@
|
|||||||
|
import atexit
|
||||||
import re
|
import re
|
||||||
import threading
|
import threading
|
||||||
from os import listdir, pardir, rename, unlink
|
from os import listdir, pardir, rename, unlink
|
||||||
from os.path import exists, isdir, isfile, join
|
from os.path import basename, exists, isdir, isfile, join
|
||||||
from platform import machine
|
from platform import machine
|
||||||
from sys import platform
|
from sys import platform
|
||||||
from time import strptime, localtime, mktime, sleep, time
|
from time import strptime, localtime, mktime, sleep, time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
from watchdog.observers import Observer
|
||||||
|
from watchdog.events import FileSystemEventHandler
|
||||||
|
|
||||||
if __debug__:
|
if __debug__:
|
||||||
from traceback import print_exc
|
from traceback import print_exc
|
||||||
|
|
||||||
@ -60,15 +64,29 @@ elif platform=='win32':
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class EDLogs:
|
class EDLogs(FileSystemEventHandler):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
FileSystemEventHandler.__init__(self) # futureproofing - not need for current version of watchdog
|
||||||
self.root = None
|
self.root = None
|
||||||
self.logdir = self._logdir()
|
self.logdir = self._logdir()
|
||||||
|
self.logfile = None
|
||||||
self.logging_enabled = self._logging_enabled
|
self.logging_enabled = self._logging_enabled
|
||||||
self._restart_required = False
|
self._restart_required = False
|
||||||
self.observer = None
|
self.thread = None
|
||||||
self.last_event = None
|
self.last_event = None # for communicating the Jump event
|
||||||
|
|
||||||
|
if self.logdir:
|
||||||
|
# Set up a watchog observer. This is low overhead so is left running irrespective of whether monitoring is desired.
|
||||||
|
observer = Observer()
|
||||||
|
observer.daemon = True
|
||||||
|
observer.schedule(self, self.logdir)
|
||||||
|
observer.start()
|
||||||
|
atexit.register(observer.stop)
|
||||||
|
|
||||||
|
# Latest pre-existing logfile - e.g. if E:D is already running. Assumes logs sort alphabetically.
|
||||||
|
logfiles = sorted([x for x in listdir(self.logdir) if x.startswith('netLog.')])
|
||||||
|
self.logfile = logfiles and join(self.logdir, logfiles[-1]) or None
|
||||||
|
|
||||||
def enable_logging(self):
|
def enable_logging(self):
|
||||||
if self.logging_enabled():
|
if self.logging_enabled():
|
||||||
@ -137,17 +155,22 @@ class EDLogs:
|
|||||||
return False
|
return False
|
||||||
if self.running():
|
if self.running():
|
||||||
return True
|
return True
|
||||||
self.observer = threading.Thread(target = self.worker, name = 'netLog worker')
|
self.thread = threading.Thread(target = self.worker, name = 'netLog worker')
|
||||||
self.observer.daemon = True
|
self.thread.daemon = True
|
||||||
self.observer.start()
|
self.thread.start()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.observer = None # Orphan the worker thread
|
self.thread = None # Orphan the worker thread
|
||||||
self.last_event = None
|
self.last_event = None
|
||||||
|
|
||||||
def running(self):
|
def running(self):
|
||||||
return self.observer and self.observer.is_alive()
|
return self.thread and self.thread.is_alive()
|
||||||
|
|
||||||
|
def on_created(self, event):
|
||||||
|
# watchdog callback, e.g. client (re)started.
|
||||||
|
if not event.is_directory and basename(event.src_path).startswith('netLog.'):
|
||||||
|
self.logfile = event.src_path
|
||||||
|
|
||||||
def worker(self):
|
def worker(self):
|
||||||
# e.g. "{18:11:44} System:22(Gamma Doradus) Body:3 Pos:(3.69928e+07,1.13173e+09,-1.75892e+08) \r\n".
|
# e.g. "{18:11:44} System:22(Gamma Doradus) Body:3 Pos:(3.69928e+07,1.13173e+09,-1.75892e+08) \r\n".
|
||||||
@ -155,27 +178,21 @@ class EDLogs:
|
|||||||
regexp = re.compile(r'\{(.+)\} System:\d+\((.+)\) Body:')
|
regexp = re.compile(r'\{(.+)\} System:\d+\((.+)\) Body:')
|
||||||
|
|
||||||
# Seek to the end of the latest log file
|
# Seek to the end of the latest log file
|
||||||
logfiles = sorted([x for x in listdir(self.logdir) if x.startswith('netLog.')])
|
logfile = self.logfile
|
||||||
logfile = logfiles and logfiles[-1] or None
|
|
||||||
if logfile:
|
if logfile:
|
||||||
loghandle = open(join(self.logdir, logfile), 'rt')
|
loghandle = open(logfile, 'rt')
|
||||||
loghandle.seek(0, 2) # seek to EOF
|
loghandle.seek(0, 2) # seek to EOF
|
||||||
else:
|
else:
|
||||||
loghandle = None
|
loghandle = None
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# Check whether we're still supposed to be running
|
# Check whether new log file started, e.g. client (re)started.
|
||||||
if threading.current_thread() != self.observer:
|
newlogfile = self.logfile
|
||||||
return # Terminate
|
|
||||||
|
|
||||||
# Check whether new log file started, e.g. client restarted. Assumes logs sort alphabetically.
|
|
||||||
logfiles = sorted([x for x in listdir(self.logdir) if x.startswith('netLog.')])
|
|
||||||
newlogfile = logfiles and logfiles[-1] or None
|
|
||||||
if logfile != newlogfile:
|
if logfile != newlogfile:
|
||||||
logfile = newlogfile
|
logfile = newlogfile
|
||||||
if loghandle:
|
if loghandle:
|
||||||
loghandle.close()
|
loghandle.close()
|
||||||
loghandle = open(join(self.logdir, logfile), 'rt')
|
loghandle = open(logfile, 'rt')
|
||||||
|
|
||||||
if logfile:
|
if logfile:
|
||||||
system = visited = None
|
system = visited = None
|
||||||
@ -201,6 +218,10 @@ class EDLogs:
|
|||||||
|
|
||||||
sleep(10) # New system gets posted to log file before hyperspace ends, so don't need to poll too often
|
sleep(10) # New system gets posted to log file before hyperspace ends, so don't need to poll too often
|
||||||
|
|
||||||
|
# Check whether we're still supposed to be running
|
||||||
|
if threading.current_thread() != self.thread:
|
||||||
|
return # Terminate
|
||||||
|
|
||||||
|
|
||||||
if platform=='darwin':
|
if platform=='darwin':
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user