mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-14 08:17:13 +03:00
First pass utilising 'futurize' to do most of the work. There's an issue with ur'\"' in l10n.py which I'm not sure how to properly fix. This now has errors when hitting the 'Update' button.
138 lines
4.9 KiB
Python
138 lines
4.9 KiB
Python
from __future__ import division
|
|
from __future__ import print_function
|
|
from past.utils import old_div
|
|
import json
|
|
from calendar import timegm
|
|
from operator import itemgetter
|
|
from os import listdir
|
|
from os.path import isdir, isfile, join, getsize
|
|
from sys import platform
|
|
import time
|
|
|
|
if __debug__:
|
|
from traceback import print_exc
|
|
|
|
from config import config
|
|
|
|
|
|
if platform=='darwin':
|
|
from watchdog.observers import Observer
|
|
from watchdog.events import FileSystemEventHandler
|
|
|
|
elif platform=='win32':
|
|
from watchdog.observers import Observer
|
|
from watchdog.events import FileSystemEventHandler
|
|
|
|
else:
|
|
# Linux's inotify doesn't work over CIFS or NFS, so poll
|
|
FileSystemEventHandler = object # dummy
|
|
|
|
|
|
# Status.json handler
|
|
class Dashboard(FileSystemEventHandler):
|
|
|
|
_POLL = 1 # Fallback polling interval
|
|
|
|
def __init__(self):
|
|
FileSystemEventHandler.__init__(self) # futureproofing - not need for current version of watchdog
|
|
self.root = None
|
|
self.currentdir = None # The actual logdir that we're monitoring
|
|
self.observer = None
|
|
self.observed = None # a watchdog ObservedWatch, or None if polling
|
|
self.status = {} # Current status for communicating status back to main thread
|
|
|
|
def start(self, root, started):
|
|
self.root = root
|
|
self.session_start = started
|
|
|
|
logdir = config.get('journaldir') or config.default_journal_dir
|
|
if not logdir or not isdir(logdir):
|
|
self.stop()
|
|
return False
|
|
|
|
if self.currentdir and self.currentdir != logdir:
|
|
self.stop()
|
|
self.currentdir = logdir
|
|
|
|
# Set up a watchdog observer.
|
|
# File system events are unreliable/non-existent over network drives on Linux.
|
|
# We can't easily tell whether a path points to a network drive, so assume
|
|
# any non-standard logdir might be on a network drive and poll instead.
|
|
polling = platform != 'win32'
|
|
if not polling and not self.observer:
|
|
self.observer = Observer()
|
|
self.observer.daemon = True
|
|
self.observer.start()
|
|
elif polling and self.observer:
|
|
self.observer.stop()
|
|
self.observer = None
|
|
|
|
if not self.observed and not polling:
|
|
self.observed = self.observer.schedule(self, self.currentdir)
|
|
|
|
if __debug__:
|
|
print('%s Dashboard "%s"' % (polling and 'Polling' or 'Monitoring', self.currentdir))
|
|
|
|
# Even if we're not intending to poll, poll at least once to process pre-existing
|
|
# data and to check whether the watchdog thread has crashed due to events not
|
|
# being supported on this filesystem.
|
|
self.root.after(old_div(self._POLL * 1000,2), self.poll, True)
|
|
|
|
return True
|
|
|
|
def stop(self):
|
|
if __debug__:
|
|
print('Stopping monitoring Dashboard')
|
|
self.currentdir = None
|
|
if self.observed:
|
|
self.observed = None
|
|
self.observer.unschedule_all()
|
|
self.status = {}
|
|
|
|
def close(self):
|
|
self.stop()
|
|
if self.observer:
|
|
self.observer.stop()
|
|
if self.observer:
|
|
self.observer.join()
|
|
self.observer = None
|
|
|
|
def poll(self, first_time=False):
|
|
if not self.currentdir:
|
|
# Stopped
|
|
self.status = {}
|
|
else:
|
|
self.process()
|
|
|
|
if first_time:
|
|
# Watchdog thread
|
|
emitter = self.observed and self.observer._emitter_for_watch[self.observed] # Note: Uses undocumented attribute
|
|
if emitter and emitter.is_alive():
|
|
return # Watchdog thread still running - stop polling
|
|
|
|
self.root.after(self._POLL * 1000, self.poll) # keep polling
|
|
|
|
def on_modified(self, event):
|
|
# watchdog callback - DirModifiedEvent on macOS, FileModifiedEvent on Windows
|
|
if event.is_directory or (isfile(event.src_path) and getsize(event.src_path)): # Can get on_modified events when the file is emptied
|
|
self.process(event.src_path if not event.is_directory else None)
|
|
|
|
# Can be called either in watchdog thread or, if polling, in main thread.
|
|
def process(self, logfile=None):
|
|
try:
|
|
with open(join(self.currentdir, 'Status.json'), 'rb') as h:
|
|
data = h.read().strip()
|
|
if data: # Can be empty if polling while the file is being re-written
|
|
entry = json.loads(data)
|
|
|
|
# Status file is shared between beta and live. So filter out status not in this game session.
|
|
if (timegm(time.strptime(entry['timestamp'], '%Y-%m-%dT%H:%M:%SZ')) >= self.session_start and
|
|
self.status != entry):
|
|
self.status = entry
|
|
self.root.event_generate('<<DashboardEvent>>', when="tail")
|
|
except:
|
|
if __debug__: print_exc()
|
|
|
|
# singleton
|
|
dashboard = Dashboard()
|