From a30d85990b69fd34a80781fd342667fc9e3f397a Mon Sep 17 00:00:00 2001 From: Jonathan Harris Date: Mon, 25 Jul 2016 19:14:12 +0100 Subject: [PATCH] Remove support for edproxy and for flight log file Flight log to file is redundant and little-used. Suitable replacements are EDSM integration and/or other apps such as Captain's Log. edproxy since v2.1 supports sending flight log directly to EDSM, and integration has no other purpose. --- EDMarketConnector.py | 36 +++------- L10n/cs.strings | 6 -- L10n/de.strings | 6 -- L10n/en.template | 6 -- L10n/es.strings | 6 -- L10n/fr.strings | 6 -- L10n/it.strings | 6 -- L10n/ja.strings | 6 -- L10n/lv.strings | 6 -- L10n/nl.strings | 6 -- L10n/pl.strings | 6 -- L10n/ru.strings | 6 -- L10n/sl.strings | 6 -- L10n/uk.strings | 6 -- config.py | 20 +++--- edproxy.py | 155 ------------------------------------------- edsm.py | 19 ------ flightlog.py | 105 ----------------------------- monitor.py | 4 +- prefs.py | 80 ++++++++-------------- 20 files changed, 49 insertions(+), 448 deletions(-) delete mode 100644 edproxy.py delete mode 100644 flightlog.py diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 30fcb3df..c73c7788 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -41,12 +41,10 @@ import eddn import edsm import loadout import coriolis -import flightlog import eddb import stats import prefs import plug -from edproxy import edproxy from hotkey import hotkeymgr from monitor import monitor from theme import theme @@ -252,8 +250,6 @@ class AppWindow: monitor.set_callback('Dock', self.getandsend) monitor.set_callback('Jump', self.system_change) monitor.start(self.w) - edproxy.set_callback(self.system_change) - edproxy.start(self.w) # First run if not config.get('username') or not config.get('password'): @@ -309,15 +305,6 @@ class AppWindow: if __debug__: print_exc() self.status['text'] = unicode(e) - # Try to obtain exclusive lock on flight log ASAP - if config.getint('output') & config.OUT_LOG_FILE: - try: - flightlog.openlog() - except Exception as e: - if __debug__: print_exc() - if not self.status['text']: - self.status['text'] = unicode(e) - if not getattr(sys, 'frozen', False): self.updater.checkForUpdates() # Sparkle / WinSparkle does this automatically for packaged apps @@ -390,9 +377,7 @@ class AppWindow: loadout.export(data) if config.getint('output') & config.OUT_SHIP_CORIOLIS: coriolis.export(data) - if config.getint('output') & config.OUT_LOG_FILE: - flightlog.export(data) - if config.getint('output') & config.OUT_LOG_EDSM: + if config.getint('output') & config.OUT_SYS_EDSM: # Catch any EDSM errors here so that they don't prevent station update try: self.status['text'] = _('Sending data to EDSM...') @@ -406,7 +391,7 @@ class AppWindow: self.edsm.link(self.system['text']) self.edsmpoll() - if not (config.getint('output') & (config.OUT_CSV|config.OUT_TD|config.OUT_BPC|config.OUT_EDDN)): + if not (config.getint('output') & (config.OUT_MKT_CSV|config.OUT_MKT_TD|config.OUT_MKT_BPC|config.OUT_MKT_EDDN)): # no station data requested - we're done pass @@ -421,25 +406,25 @@ class AppWindow: # No EDDN output? - if (config.getint('output') & config.OUT_EDDN) and not (data['lastStarport'].get('commodities') or data['lastStarport'].get('modules')): # Ignore possibly missing shipyard info + if (config.getint('output') & config.OUT_MKT_EDDN) and not (data['lastStarport'].get('commodities') or data['lastStarport'].get('modules')): # Ignore possibly missing shipyard info if not self.status['text']: self.status['text'] = _("Station doesn't have anything!") # No market output? - elif not (config.getint('output') & config.OUT_EDDN) and not data['lastStarport'].get('commodities'): + elif not (config.getint('output') & config.OUT_MKT_EDDN) and not data['lastStarport'].get('commodities'): if not self.status['text']: self.status['text'] = _("Station doesn't have a market!") else: if data['lastStarport'].get('commodities'): - if config.getint('output') & config.OUT_CSV: + if config.getint('output') & config.OUT_MKT_CSV: commodity.export(data, COMMODITY_CSV) - if config.getint('output') & config.OUT_TD: + if config.getint('output') & config.OUT_MKT_TD: td.export(data) - if config.getint('output') & config.OUT_BPC: + if config.getint('output') & config.OUT_MKT_BPC: commodity.export(data, COMMODITY_BPC) - if config.getint('output') & config.OUT_EDDN: + if config.getint('output') & config.OUT_MKT_EDDN: old_status = self.status['text'] if not old_status: self.status['text'] = _('Sending data to EDDN...') @@ -507,9 +492,7 @@ class AppWindow: plug.notify_system_changed(timestamp, system, coordinates) - if config.getint('output') & config.OUT_LOG_FILE: - flightlog.writelog(timestamp, system) - if config.getint('output') & config.OUT_LOG_EDSM: + if config.getint('output') & (config.OUT_SYS_EDSM | config.OUT_SYS_AUTO) == (config.OUT_SYS_EDSM | OUT_SYS_AUTO): try: self.status['text'] = _('Sending data to EDSM...') self.w.update_idletasks() @@ -590,7 +573,6 @@ class AppWindow: def onexit(self, event=None): hotkeymgr.unregister() - flightlog.close() if platform!='darwin' or self.w.winfo_rooty()>0: # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 config.set('geometry', '+{1}+{2}'.format(*self.w.geometry().split('+'))) config.close() diff --git a/L10n/cs.strings b/L10n/cs.strings index 4e7572ed..9f891998 100644 --- a/L10n/cs.strings +++ b/L10n/cs.strings @@ -73,9 +73,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Competent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Připojeno k {EDPROXY} na {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "Čekej {SS}s"; @@ -172,9 +169,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Cesta k souboru"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Letový záznam ve formátu CSV"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiator"; diff --git a/L10n/de.strings b/L10n/de.strings index 66b71224..2c1e3b52 100644 --- a/L10n/de.strings +++ b/L10n/de.strings @@ -73,9 +73,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Kompetent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Verbunden mit {EDPROXY} bei {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "Wartezeit {SS}s"; @@ -172,9 +169,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Speicherort"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Fluglogbuch im CSV-Format"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiator"; diff --git a/L10n/en.template b/L10n/en.template index 49a984ca..fe00545b 100644 --- a/L10n/en.template +++ b/L10n/en.template @@ -73,9 +73,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Competent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Connected to {EDPROXY} at {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "cooldown {SS}s"; @@ -172,9 +169,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "File location"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Flight log in CSV format file"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiator"; diff --git a/L10n/es.strings b/L10n/es.strings index d3e0cb55..82a6fc64 100644 --- a/L10n/es.strings +++ b/L10n/es.strings @@ -73,9 +73,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Competente"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Conectado a {EDPROXY} en {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "Espere {SS}s"; @@ -172,9 +169,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Localización de archivos"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Registro de vuelo en formato CSV"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiador"; diff --git a/L10n/fr.strings b/L10n/fr.strings index 5a174b2e..95234ef3 100644 --- a/L10n/fr.strings +++ b/L10n/fr.strings @@ -70,9 +70,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Compétent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Connecté à {EDPROXY} sur {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "Temps de recharge {SS}s"; @@ -169,9 +166,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Emplacement des fichiers"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Journal de vol au format CSV"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiator"; diff --git a/L10n/it.strings b/L10n/it.strings index f3b1389a..55e4c5dc 100644 --- a/L10n/it.strings +++ b/L10n/it.strings @@ -70,9 +70,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Competent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Connesso a {EDPROXY} all'indirizzo {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "disponibile tra {SS} secondi"; @@ -169,9 +166,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Percorso del file"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Flight log in formato CSV"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiator"; diff --git a/L10n/ja.strings b/L10n/ja.strings index 749823b6..83cc0e56 100644 --- a/L10n/ja.strings +++ b/L10n/ja.strings @@ -73,9 +73,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Competent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "{ADDR} の {EDPROXY} に接続しました"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "次回更新まであと {SS}秒"; @@ -172,9 +169,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "ファイルの出力先"; -/* [prefs.py] */ -"Flight log in CSV format file" = "フライトログをCSV形式で記録する"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiator"; diff --git a/L10n/lv.strings b/L10n/lv.strings index 75083fed..0ae09f4e 100644 --- a/L10n/lv.strings +++ b/L10n/lv.strings @@ -70,9 +70,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Competent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Connected to {EDPROXY} at {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "Atskaite {SS}"; @@ -169,9 +166,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Faila atrašanās vieta"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Lidojuma ieraksts SCV formāta failā"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiators"; diff --git a/L10n/nl.strings b/L10n/nl.strings index ab316c70..3b4bfe52 100644 --- a/L10n/nl.strings +++ b/L10n/nl.strings @@ -73,9 +73,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Competent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Verbonden met {EDPROXY} via {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "wachtperiode {SS}s"; @@ -172,9 +169,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Bestand locatie"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Vlucht log in CSV bestand formaat"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiator"; diff --git a/L10n/pl.strings b/L10n/pl.strings index f3cf656e..5909f705 100644 --- a/L10n/pl.strings +++ b/L10n/pl.strings @@ -70,9 +70,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Competent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Połąćzono do {EDPROXY} na {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "Oczekiwanie {SS} sek."; @@ -169,9 +166,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Położenie pliku"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Dziennik lotu w formacie CSV"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiator"; diff --git a/L10n/ru.strings b/L10n/ru.strings index 38ee3461..eae5f4ed 100644 --- a/L10n/ru.strings +++ b/L10n/ru.strings @@ -70,9 +70,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Специалист"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Connected to {EDPROXY} at {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "пауза {SS} сек"; @@ -169,9 +166,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Сохранять файлы"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Журнал полета в формате CSV"; - /* CQC rank. [stats.py] */ "Gladiator" = "Гладиатор"; diff --git a/L10n/sl.strings b/L10n/sl.strings index 1c8e99d6..e5ecbc05 100644 --- a/L10n/sl.strings +++ b/L10n/sl.strings @@ -70,9 +70,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Competent"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Connected to {EDPROXY} at {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "Posodobitev v {SS}s"; @@ -169,9 +166,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Lokacija datoteke"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Dnevnik leta v CSV formatu"; - /* CQC rank. [stats.py] */ "Gladiator" = "Gladiator"; diff --git a/L10n/uk.strings b/L10n/uk.strings index 7c176cc9..552350d4 100644 --- a/L10n/uk.strings +++ b/L10n/uk.strings @@ -70,9 +70,6 @@ /* Combat rank. [stats.py] */ "Competent" = "Компетентний"; -/* Output settings. [prefs.py] */ -"Connected to {EDPROXY} at {ADDR}" = "Підключено до {EDPROXY}, адреса {ADDR}"; - /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "очикування {SS} сек"; @@ -169,9 +166,6 @@ /* Section heading in settings. [prefs.py] */ "File location" = "Росташування файлу"; -/* [prefs.py] */ -"Flight log in CSV format file" = "Журнал (log) в CSV форматі"; - /* CQC rank. [stats.py] */ "Gladiator" = "Гладіатор"; diff --git a/config.py b/config.py index 66ca7ef2..ae14dc11 100644 --- a/config.py +++ b/config.py @@ -70,17 +70,17 @@ elif platform=='linux2': class Config: - OUT_EDDN = 1 - OUT_BPC = 2 - OUT_TD = 4 - OUT_CSV = 8 - OUT_SHIP_EDS = 16 - OUT_LOG_FILE = 32 - #OUT_STAT = 64 # No longer available + OUT_MKT_EDDN = 1 + OUT_MKT_BPC = 2 + OUT_MKT_TD = 4 + OUT_MKT_CSV = 8 + OUT_SHIP_EDS = 16 + # OUT_SYS_FILE = 32 # No longer supported + # OUT_STAT = 64 # No longer available OUT_SHIP_CORIOLIS = 128 - OUT_LOG_EDSM = 256 - OUT_LOG_AUTO = 512 - OUT_MANUAL = 1024 + OUT_SYS_EDSM = 256 + OUT_SYS_AUTO = 512 + OUT_MKT_MANUAL = 1024 if platform=='darwin': diff --git a/edproxy.py b/edproxy.py deleted file mode 100644 index 6ca14809..00000000 --- a/edproxy.py +++ /dev/null @@ -1,155 +0,0 @@ -# -# Elite: Dangerous Netlog Proxy Server client - https://bitbucket.org/westokyo/edproxy/ -# - -import json -import socket -import struct -import sys -import threading -from time import time, strptime, mktime -from datetime import datetime -from calendar import timegm - -if __debug__: - from traceback import print_exc - -from config import config - - -class _EDProxy: - - DISCOVERY_ADDR = '239.45.99.98' - DISCOVERY_PORT = 45551 - DISCOVERY_QUERY = 'Query' - DISCOVERY_ANNOUNCE = 'Announce' - - SERVICE_NAME = 'edproxy' - SERVICE_HEARTBEAT = 60 # [s] - SERVICE_TIMEOUT = 90 # [s] - - MESSAGE_MAX = 1024 # https://bitbucket.org/westokyo/edproxy/src/master/ednet.py?fileviewer=file-view-default#ednet.py-166 - MESSAGE_SYSTEM = 'System' - - - def __init__(self): - self.root = None - self.lock = threading.Lock() - self.addr = None - self.port = None - - thread = threading.Thread(target = self._listener) - thread.daemon = True - thread.start() - - self.callback = None - self.last_event = None # for communicating the Jump event - - # start - self.discover_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.discover() - - def set_callback(self, callback): - self.callback = callback - - def start(self, root): - self.root = root - self.root.bind_all('<>', self.jump) # user-generated - - def stop(self): - # Still listening, but stop callbacks - if self.root: - self.root.unbind_all('<>') - - def status(self): - self.lock.acquire() - if self.addr and self.port: - status = '%s:%d' % (self.addr, self.port) - self.lock.release() - return status - else: - self.lock.release() - self.discover() # Kick off discovery - return None - - def jump(self, event): - # Called from Tkinter's main loop - if self.callback and self.last_event: - self.callback(event, *self.last_event) - - def close(): - self.discover_sock.shutdown() - self.discover_sock = None - - # Send a query. _listener should get the response. - def discover(self): - self.discover_sock.sendto(json.dumps({ - 'type': self.DISCOVERY_QUERY, - 'name': self.SERVICE_NAME, - }), (self.DISCOVERY_ADDR, self.DISCOVERY_PORT)) - - def _listener(self): - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - if sys.platform == 'win32': - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - else: - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) - s.bind(('', self.DISCOVERY_PORT)) - s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, struct.pack('4sL', socket.inet_aton(self.DISCOVERY_ADDR), socket.INADDR_ANY)) - while True: - try: - (data, addr) = s.recvfrom(self.MESSAGE_MAX) - msg = json.loads(data) - if msg['name'] == self.SERVICE_NAME and msg['type'] == self.DISCOVERY_ANNOUNCE: - # ignore if already connected to a proxy - if not self.addr or not self.port: - thread = threading.Thread(target = self._worker, args = (msg['ipv4'], int(msg['port']))) - thread.daemon = True - thread.start() - except: - if __debug__: print_exc() - - def _worker(self, addr, port): - try: - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((addr, port)) - s.settimeout(0) - s.sendall(json.dumps({ - 'Type' : 'Init', - 'DateUtc' : datetime.utcnow().isoformat(), - 'StartTime' : 'now', - 'Register' : [ 'System' ], - })) - except: - if __debug__: print_exc() - return - - self.lock.acquire() - self.addr = addr - self.port = port - self.lock.release() - - try: - s.settimeout(None) # was self.SERVICE_TIMEOUT, but heartbeat doesn't appear to work so wait indefinitely - while True: - msg = json.loads(s.recv(self.MESSAGE_MAX)) - if msg['Type'] == self.MESSAGE_SYSTEM and config.getint('output') & config.OUT_LOG_AUTO: - if 'DateUtc' in msg: - timestamp = timegm(datetime.strptime(msg['DateUtc'], '%Y-%m-%d %H:%M:%S').utctimetuple()) - else: - timestamp = mktime(strptime(msg['Date'], '%Y-%m-%d %H:%M:%S')) # from local time - self.last_event = (timestamp, msg['System'], None) - self.root.event_generate('<>', when="tail") - except: - if __debug__: print_exc() - - self.lock.acquire() - self.addr = self.port = None - self.lock.release() - - # Kick off discovery for another proxy - self.discover() - - -# singleton -edproxy = _EDProxy() diff --git a/edsm.py b/edsm.py index 73b10a26..f6c66526 100644 --- a/edsm.py +++ b/edsm.py @@ -7,7 +7,6 @@ import urllib import Tkinter as tk from config import applongname, appversion, config -import flightlog if __debug__: from traceback import print_exc @@ -139,21 +138,3 @@ def writelog(timestamp, system, edsmlookupfn, coordinates=None): # Message numbers: 1xx = OK, 2xx = fatal error, 3xx = error (but not generated in practice), 4xx = ignorable errors if msgnum // 100 not in (1,4): raise Exception(_('Error: EDSM {MSG}').format(MSG=msg)) - - if not config.getint('edsm_historical'): - config.set('edsm_historical', 1) - thread = threading.Thread(target = export_historical, name = 'EDSM export') - thread.daemon = True - thread.start() - -# Make best effort to export existing flight log file. Be silent on error. -def export_historical(): - try: - for (timestamp, system_name) in flightlog.logs(): - r = requests.get('https://www.edsm.net/api-logs-v1/set-log?commanderName=%s&apiKey=%s&systemName=%s&dateVisited=%s&fromSoftware=%s&fromSoftwareVersion=%s' % (urllib.quote(config.get('edsm_cmdrname').encode('utf-8')), urllib.quote(config.get('edsm_apikey')), urllib.quote(system_name), urllib.quote(time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(timestamp))), urllib.quote(applongname), urllib.quote(appversion)), timeout=EDSM._TIMEOUT) - r.raise_for_status() - - if r.json()['msgnum'] // 100 == 2: - raise Exception() - except: - if __debug__: print_exc() diff --git a/flightlog.py b/flightlog.py deleted file mode 100644 index 42e74d46..00000000 --- a/flightlog.py +++ /dev/null @@ -1,105 +0,0 @@ -# Export poor man's flight log - -from collections import defaultdict -import errno -import os -from os.path import join -from sys import platform -import time - -from config import config -from companion import ship_map - - -logfile = None -last_timestamp = last_system = last_ship = None -last_commodities = {} - -def openlog(): - - global logfile - if logfile: return - - try: - logfile = open(join(config.get('outdir'), 'Flight Log.csv'), 'a+b') - if platform != 'win32': # open for writing is automatically exclusive on Windows - from fcntl import lockf, LOCK_SH, LOCK_NB - lockf(logfile, LOCK_SH|LOCK_NB) - logfile.seek(0, os.SEEK_END) - if not logfile.tell(): - logfile.write('Date,Time,System,Station,Ship,Cargo\r\n') - except EnvironmentError as e: - logfile = None - if e.errno in [errno.EACCES, errno.EAGAIN]: - raise Exception('Can\'t write "Flight Log.csv". Are you editing it in another app?') - else: - raise - except: - logfile = None - raise - - -def export(data): - - querytime = config.getint('querytime') or int(time.time()) - - commodities = defaultdict(int) - for item in data['ship'].get('cargo',{}).get('items',[]): - if item['commodity'] != 'drones': - commodities[item['commodity']] += item['qty'] - - writelog(querytime, - data['lastSystem']['name'], - data['commander']['docked'] and data['lastStarport']['name'], - ship_map.get(data['ship']['name'].lower(), data['ship']['name']), - commodities) - - -def writelog(timestamp, system, station=None, ship=None, commodities={}): - - global last_timestamp, last_system, last_ship, last_commodities - if last_system and last_system != system: - _writelog(last_timestamp, last_system, None, last_ship, last_commodities) - - if not station: - # If not docked, hold off writing log entry until docked or until system changes - last_timestamp, last_system, last_ship, last_commodities = timestamp, system, ship, commodities - else: - last_system = None - _writelog(timestamp, system, station, ship, commodities) - - -def _writelog(timestamp, system, station=None, ship=None, commodities={}): - - openlog() - - logfile.write('%s,%s,%s,%s,%s,%s\r\n' % ( - time.strftime('%Y-%m-%d', time.localtime(timestamp)), - time.strftime('%H:%M:%S', time.localtime(timestamp)), - system, - station or '', - ship or '', - ','.join([('%d %s' % (commodities[k], k)) for k in sorted(commodities)]))) - - logfile.flush() - - -def close(): - global last_timestamp, last_system - - if last_system: - _writelog(last_timestamp, last_system, None, last_ship, last_commodities) - last_system = None - - -# return log as list of (timestamp, system_name) -def logs(): - entries = [] - with open(join(config.get('outdir'), 'Flight Log.csv'), 'rU') as f: - f.readline() # Assume header - for line in f: - if not line.strip(): continue - cols = line.split(',') - assert len(cols) >= 3, cols - entries.append((time.mktime(time.strptime('%sT%s' % (cols[0], cols[1]), '%Y-%m-%dT%H:%M:%S')), cols[2])) # Convert from local time to UTC - return entries diff --git a/monitor.py b/monitor.py index 42742fca..2fd46e4b 100644 --- a/monitor.py +++ b/monitor.py @@ -154,7 +154,7 @@ class EDLogs(FileSystemEventHandler): while True: - if docked and not updated and not config.getint('output') & config.OUT_MANUAL: + if docked and not updated and not config.getint('output') & config.OUT_MKT_MANUAL: self.root.event_generate('<>', when="tail") updated = True if __debug__: @@ -190,7 +190,7 @@ class EDLogs(FileSystemEventHandler): if __debug__: print "%s :\t%s %s" % (match.group(2), docked and " docked" or "!docked", updated and " updated" or "!updated") - if system and not docked and config.getint('output') & config.OUT_LOG_AUTO: + if system and not docked and config.getint('output'): # Convert local time string to UTC date and time visited_struct = strptime(visited, '%H:%M:%S') now = localtime() diff --git a/prefs.py b/prefs.py index c3958a48..3acb533c 100644 --- a/prefs.py +++ b/prefs.py @@ -11,7 +11,6 @@ from ttkHyperlinkLabel import HyperlinkLabel import myNotebook as nb from config import applongname, config -from edproxy import edproxy from hotkey import hotkeymgr from l10n import Translations from monitor import monitor @@ -114,33 +113,27 @@ class PreferencesDialog(tk.Toplevel): outframe = nb.Frame(notebook) outframe.columnconfigure(0, weight=1) - output = config.getint('output') or (config.OUT_EDDN | config.OUT_SHIP_EDS) # default settings + output = config.getint('output') or (config.OUT_MKT_EDDN | config.OUT_SHIP_EDS) # default settings + nb.Label(outframe, text=_('Please choose what data to save')).grid(columnspan=2, padx=PADX, sticky=tk.W) - self.out_eddn= tk.IntVar(value = (output & config.OUT_EDDN) and 1) + self.out_eddn= tk.IntVar(value = (output & config.OUT_MKT_EDDN) and 1) nb.Checkbutton(outframe, text=_('Send station data to the Elite Dangerous Data Network'), variable=self.out_eddn, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, sticky=tk.W) - self.out_csv = tk.IntVar(value = (output & config.OUT_CSV ) and 1) + self.out_csv = tk.IntVar(value = (output & config.OUT_MKT_CSV ) and 1) nb.Checkbutton(outframe, text=_('Market data in CSV format file'), variable=self.out_csv, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, sticky=tk.W) - self.out_bpc = tk.IntVar(value = (output & config.OUT_BPC ) and 1) + self.out_bpc = tk.IntVar(value = (output & config.OUT_MKT_BPC ) and 1) nb.Checkbutton(outframe, text=_("Market data in Slopey's BPC format file"), variable=self.out_bpc, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, sticky=tk.W) - self.out_td = tk.IntVar(value = (output & config.OUT_TD ) and 1) + self.out_td = tk.IntVar(value = (output & config.OUT_MKT_TD ) and 1) nb.Checkbutton(outframe, text=_('Market data in Trade Dangerous format file'), variable=self.out_td, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, sticky=tk.W) - self.out_auto = tk.IntVar(value = 0 if output & config.OUT_MANUAL else 1) # inverted - self.out_auto_button = nb.Checkbutton(outframe, text=_('Automatically update on docking'), variable=self.out_auto, command=self.outvarchanged) # Output setting - self.out_auto_button.grid(columnspan=2, padx=BUTTONX, sticky=tk.W) self.out_ship_eds= tk.IntVar(value = (output & config.OUT_SHIP_EDS) and 1) nb.Checkbutton(outframe, text=_('Ship loadout in E:D Shipyard format file'), variable=self.out_ship_eds, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W) self.out_ship_coriolis= tk.IntVar(value = (output & config.OUT_SHIP_CORIOLIS) and 1) nb.Checkbutton(outframe, text=_('Ship loadout in Coriolis format file'), variable=self.out_ship_coriolis, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, sticky=tk.W) - self.out_log_file = tk.IntVar(value = (output & config.OUT_LOG_FILE) and 1) - nb.Checkbutton(outframe, text=_('Flight log in CSV format file'), variable=self.out_log_file, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W) - self.out_log_auto = tk.IntVar(value = output & config.OUT_LOG_AUTO and 1 or 0) - self.out_log_auto_button = nb.Checkbutton(outframe, text=_('Automatically make a log entry on entering a system'), variable=self.out_log_auto, command=self.outvarchanged) # Output setting - self.out_log_auto_button.grid(columnspan=2, padx=BUTTONX, sticky=tk.W) - self.out_log_auto_text = nb.Label(outframe, foreground='firebrick') - self.out_log_auto_text.grid(columnspan=2, padx=(30,0), sticky=tk.W) + self.out_auto = tk.IntVar(value = 0 if output & config.OUT_MKT_MANUAL else 1) # inverted + self.out_auto_button = nb.Checkbutton(outframe, text=_('Automatically update on docking'), variable=self.out_auto, command=self.outvarchanged) # Output setting + self.out_auto_button.grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W) self.outdir_label = nb.Label(outframe, text=_('File location')) # Section heading in settings - self.outdir_label.grid(padx=BUTTONX, sticky=tk.W) + self.outdir_label.grid(padx=BUTTONX, pady=(5,0), sticky=tk.W) self.outdir = nb.Entry(outframe, takefocus=False) if config.get('outdir').startswith(config.home): self.outdir.insert(0, '~' + config.get('outdir')[len(config.home):]) @@ -159,14 +152,13 @@ class PreferencesDialog(tk.Toplevel): edsmframe.columnconfigure(1, weight=1) HyperlinkLabel(edsmframe, text='Elite Dangerous Star Map', background=nb.Label().cget('background'), url='https://www.edsm.net/', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate - ttk.Separator(edsmframe, orient=tk.HORIZONTAL).grid(columnspan=2, padx=PADX, pady=PADY, sticky=tk.EW) - self.out_log_edsm = tk.IntVar(value = (output & config.OUT_LOG_EDSM) and 1) - nb.Checkbutton(edsmframe, text=_('Send flight log to Elite Dangerous Star Map'), variable=self.out_log_edsm, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, sticky=tk.W) - self.edsm_log_auto_button = nb.Checkbutton(edsmframe, text=_('Automatically make a log entry on entering a system'), variable=self.out_log_auto, command=self.outvarchanged) # Output setting + self.edsm_log = tk.IntVar(value = (output & config.OUT_SYS_EDSM) and 1) + nb.Checkbutton(edsmframe, text=_('Send flight log to Elite Dangerous Star Map'), variable=self.edsm_log, command=self.outvarchanged).grid(columnspan=2, padx=BUTTONX, sticky=tk.W) + self.edsm_log_auto = tk.IntVar(value = output & config.OUT_SYS_AUTO and 1 or 0) + self.edsm_log_auto_button = nb.Checkbutton(edsmframe, text=_('Automatically make a log entry on entering a system'), variable=self.edsm_log_auto, command=self.outvarchanged) # Output setting self.edsm_log_auto_button.grid(columnspan=2, padx=BUTTONX, sticky=tk.W) - self.edsm_log_auto_text = nb.Label(edsmframe, foreground='firebrick') - self.edsm_log_auto_text.grid(columnspan=2, padx=(30,0), sticky=tk.W) + nb.Label(edsmframe).grid(sticky=tk.W) # big spacer self.edsm_label = HyperlinkLabel(edsmframe, text=_('Elite Dangerous Star Map credentials'), background=nb.Label().cget('background'), url='https://www.edsm.net/settings/api', underline=True) # Section heading in settings self.edsm_label.grid(columnspan=2, padx=PADX, sticky=tk.W) @@ -270,7 +262,7 @@ class PreferencesDialog(tk.Toplevel): self.protocol("WM_DELETE_WINDOW", self._destroy) # Selectively disable buttons depending on output settings - self.proxypoll() + self.outvarchanged() self.themevarchanged() # disable hotkey for the duration @@ -282,39 +274,24 @@ class PreferencesDialog(tk.Toplevel): self.grab_set() - def proxypoll(self): - self.outvarchanged() - self.after(1000, self.proxypoll) - - def outvarchanged(self): - local = self.out_bpc.get() or self.out_td.get() or self.out_csv.get() or self.out_ship_eds.get() or self.out_ship_coriolis.get() or self.out_log_file.get() + local = self.out_bpc.get() or self.out_td.get() or self.out_csv.get() or self.out_ship_eds.get() or self.out_ship_coriolis.get() self.outdir_label['state'] = local and tk.NORMAL or tk.DISABLED self.outbutton['state'] = local and tk.NORMAL or tk.DISABLED self.outdir['state'] = local and 'readonly' or tk.DISABLED - edsm_state = self.out_log_edsm.get() and tk.NORMAL or tk.DISABLED + edsm_state = self.edsm_log.get() and tk.NORMAL or tk.DISABLED self.edsm_label['state'] = edsm_state self.edsm_cmdr_label['state'] = edsm_state self.edsm_apikey_label['state'] = edsm_state self.edsm_cmdr['state'] = edsm_state self.edsm_apikey['state'] = edsm_state - proxyaddr = edproxy.status() - self.out_log_auto_text['text'] = '' - self.edsm_log_auto_text['text'] = '' - if monitor.logdir or proxyaddr: - self.out_auto_button['state'] = monitor.logdir and tk.NORMAL or tk.DISABLED # edproxy doesn't send docking status - self.out_log_auto_button['state'] = self.out_log_file.get() and tk.NORMAL or tk.DISABLED - if self.out_log_file.get() and self.out_log_auto.get() and proxyaddr: - self.out_log_auto_text['text'] = _('Connected to {EDPROXY} at {ADDR}').format(EDPROXY = 'edproxy', ADDR = proxyaddr) # Output settings - + if monitor.logdir: + self.out_auto_button['state'] = tk.NORMAL self.edsm_log_auto_button['state'] = edsm_state - if self.out_log_edsm.get() and self.out_log_auto.get() and proxyaddr: - self.edsm_log_auto_text['text'] = _('Connected to {EDPROXY} at {ADDR}').format(EDPROXY = 'edproxy', ADDR = proxyaddr) # Output settings else: self.out_auto_button['state'] = tk.DISABLED - self.out_log_auto_button['state'] = tk.DISABLED self.edsm_log_auto_button['state'] = tk.DISABLED def outbrowse(self): @@ -418,16 +395,15 @@ class PreferencesDialog(tk.Toplevel): config.set('password', self.password.get().strip()) config.set('output', - (self.out_eddn.get() and config.OUT_EDDN) + - (self.out_bpc.get() and config.OUT_BPC) + - (self.out_td.get() and config.OUT_TD) + - (self.out_csv.get() and config.OUT_CSV) + - (config.OUT_MANUAL if not self.out_auto.get() else 0) + - (self.out_ship_eds.get() and config.OUT_SHIP_EDS) + + (self.out_eddn.get() and config.OUT_MKT_EDDN) + + (self.out_bpc.get() and config.OUT_MKT_BPC) + + (self.out_td.get() and config.OUT_MKT_TD) + + (self.out_csv.get() and config.OUT_MKT_CSV) + + (config.OUT_MKT_MANUAL if not self.out_auto.get() else 0) + + (self.out_ship_eds.get() and config.OUT_SHIP_EDS) + (self.out_ship_coriolis.get() and config.OUT_SHIP_CORIOLIS) + - (self.out_log_file.get() and config.OUT_LOG_FILE) + - (self.out_log_edsm.get() and config.OUT_LOG_EDSM) + - (self.out_log_auto.get() and config.OUT_LOG_AUTO)) + (self.edsm_log.get() and config.OUT_SYS_EDSM) + + (self.edsm_log_auto.get() and config.OUT_SYS_AUTO)) config.set('outdir', self.outdir.get().startswith('~') and join(config.home, self.outdir.get()[2:]) or self.outdir.get()) config.set('edsm_cmdrname', self.edsm_cmdr.get().strip())