diff --git a/EDMarketConnector.py b/EDMarketConnector.py index e0829dc5..c70bd9d5 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -300,6 +300,15 @@ class AppWindow(object): self.postprefs(False) # Companion login happens in callback from monitor + plugins_not_py3_last = config.getint('plugins_not_py3_last') or int(time()) + if (plugins_not_py3_last + 86400) < int(time()) and len(plug.PLUGINS_not_py3): + import tkMessageBox + tkMessageBox.showinfo('Plugins Without Python 3.x Support', + "One or more of your enabled plugins do not yet have support for Python 3.x. Please see the list on the 'Plugins' tab of 'File' > 'Settings'. You should check if there is an updated version available, else alert the developer that they will need to update the code when EDMC moves to Python 3.x" + ) + config.set('plugins_not_py3_last', int(time())) + + # callback after the Preferences dialog is applied def postprefs(self, dologin=True): self.prefsdialog = None @@ -575,6 +584,10 @@ class AppWindow(object): return # Startup or in CQC if entry['event'] in ['StartUp', 'LoadGame'] and monitor.started: + # Disable WinSparkle automatic update checks, IFF configured to do so when in-game + if config.getint('disable_autoappupdatecheckingame') and 1: + self.updater.setAutomaticUpdatesCheck(False) + print 'Monitor: Disable WinSparkle automatic update checks' # Can start dashboard monitoring if not dashboard.start(self.w, monitor.started): print("Can't start Status monitoring") @@ -594,6 +607,12 @@ class AppWindow(object): if entry['event'] in ['StartUp', 'Location', 'Docked'] and monitor.station and not config.getint('output') & config.OUT_MKT_MANUAL and config.getint('output') & config.OUT_STATION_ANY and companion.session.state != companion.Session.STATE_AUTH: self.w.after(int(SERVER_RETRY * 1000), self.getandsend) + if entry['event'] == 'ShutDown': + # Enable WinSparkle automatic update checks + # NB: Do this blindly, in case option got changed whilst in-game + self.updater.setAutomaticUpdatesCheck(True) + print 'Monitor: Enable WinSparkle automatic update checks' + # cAPI auth def auth(self, event=None): try: diff --git a/companion.py b/companion.py index 8395e325..30c01106 100644 --- a/companion.py +++ b/companion.py @@ -27,7 +27,9 @@ holdoff = 60 # be nice timeout = 10 # requests timeout auth_timeout = 30 # timeout for initial auth -CLIENT_ID = os.getenv('CLIENT_ID') or '227cd239-ab8c-4728-9d3c-d8f588f247bd' # Obtain from https://auth.frontierstore.net/client/signup +# Currently the "Elite Dangerous Market Connector (EDCD/Athanasius)" one in +# Athanasius' Frontier account +CLIENT_ID = os.getenv('CLIENT_ID') or 'fb88d428-9110-475f-a3d2-dc151c2b9c7a' # Obtain from https://auth.frontierstore.net/client/signup SERVER_AUTH = 'https://auth.frontierstore.net' URL_AUTH = '/auth' URL_TOKEN = '/token' diff --git a/config.py b/config.py index 3e930784..3a9b6d47 100644 --- a/config.py +++ b/config.py @@ -8,10 +8,10 @@ from sys import platform appname = 'EDMarketConnector' applongname = 'E:D Market Connector' appcmdname = 'EDMC' -appversion = '3.5.0.0' +appversion = '3.5.1.0' update_feed = 'https://raw.githubusercontent.com/EDCD/EDMarketConnector/releases/edmarketconnector.xml' -update_interval = 47*60*60 +update_interval = 8*60*60 if platform=='darwin': diff --git a/coriolis-data b/coriolis-data index cee78b31..bb1e5ba8 160000 --- a/coriolis-data +++ b/coriolis-data @@ -1 +1 @@ -Subproject commit cee78b312a862df6b8ef9c1eff077108f24a0b9e +Subproject commit bb1e5ba89acb940465714363b12c250ba399b5b9 diff --git a/monitor.py b/monitor.py index 3f0b8921..b408f2b3 100644 --- a/monitor.py +++ b/monitor.py @@ -431,8 +431,8 @@ class EDLogs(FileSystemEventHandler): self.station = None self.stationtype = None self.stationservices = None - elif entry['event'] in ['Location', 'FSDJump', 'Docked']: - if entry['event'] == 'Location': + elif entry['event'] in ['Location', 'FSDJump', 'Docked', 'CarrierJump']: + if entry['event'] in ('Location', 'CarrierJump'): self.planet = entry.get('Body') if entry.get('BodyType') == 'Planet' else None elif entry['event'] == 'FSDJump': self.planet = None diff --git a/plug.py b/plug.py index bb954c24..ae0fe2be 100644 --- a/plug.py +++ b/plug.py @@ -67,6 +67,7 @@ GuiFocusCodex = 11 # List of loaded Plugins PLUGINS = [] +PLUGINS_not_py3 = [] # For asynchronous error display last_error = { @@ -196,6 +197,16 @@ def load_plugins(master): pass PLUGINS.extend(sorted(found, key = lambda p: operator.attrgetter('name')(p).lower())) + ######################################################### + # Detect plugins that aren't yet ready for Python 3.x + ######################################################### + for p in PLUGINS: + if p.module and p.folder and not p._get_func('plugin_start3'): + PLUGINS_not_py3.append(p) + ######################################################### + + imp.release_lock() + def provides(fn_name): """ Find plugins that provide a function diff --git a/plugins/eddn.py b/plugins/eddn.py index 2f6e6622..c235ec74 100644 --- a/plugins/eddn.py +++ b/plugins/eddn.py @@ -396,8 +396,8 @@ def journal_entry(cmdr, is_beta, system, station, entry, state): return filtered # Track location - if entry['event'] in ['Location', 'FSDJump', 'Docked']: - if entry['event'] == 'Location': + if entry['event'] in ['Location', 'FSDJump', 'Docked', 'CarrierJump']: + if entry['event'] in ('Location', 'CarrierJump'): this.planet = entry.get('Body') if entry.get('BodyType') == 'Planet' else None elif entry['event'] == 'FSDJump': this.planet = None @@ -413,7 +413,7 @@ def journal_entry(cmdr, is_beta, system, station, entry, state): # Send interesting events to EDDN, but not when on a crew if (config.getint('output') & config.OUT_SYS_EDDN and not state['Captain'] and - (entry['event'] in ('Location', 'FSDJump', 'Docked', 'Scan', 'SAASignalsFound')) and + (entry['event'] in ('Location', 'FSDJump', 'Docked', 'Scan', 'SAASignalsFound', 'CarrierJump')) and ('StarPos' in entry or this.coordinates)): # strip out properties disallowed by the schema for thing in ['ActiveFine', 'CockpitBreach', 'BoostUsed', 'FuelLevel', 'FuelUsed', 'JumpDist', 'Latitude', 'Longitude', 'Wanted']: diff --git a/plugins/edsm.py b/plugins/edsm.py index 84bf71a3..266819d1 100644 --- a/plugins/edsm.py +++ b/plugins/edsm.py @@ -300,7 +300,7 @@ def worker(): plug.show_error(_('Error: EDSM {MSG}').format(MSG=msg)) else: for e, r in zip(pending, reply['events']): - if not closing and e['event'] in ['StartUp', 'Location', 'FSDJump']: + if not closing and e['event'] in ['StartUp', 'Location', 'FSDJump', 'CarrierJump']: # Update main window's system status this.lastlookup = r this.system.event_generate('<>', when="tail") # calls update_status in main thread @@ -347,13 +347,13 @@ def should_send(entries): return False -# Call edsm_notify_system() in this and other interested plugins with EDSM's response to a 'StartUp', 'Location' or 'FSDJump' event +# Call edsm_notify_system() in this and other interested plugins with EDSM's response to a 'StartUp', 'Location', 'FSDJump' or 'CarrierJump' event def update_status(event=None): for plugin in plug.provides('edsm_notify_system'): plug.invoke(plugin, None, 'edsm_notify_system', this.lastlookup) -# Called with EDSM's response to a 'StartUp', 'Location' or 'FSDJump' event. https://www.edsm.net/en/api-journal-v1 +# Called with EDSM's response to a 'StartUp', 'Location', 'FSDJump' or 'CarrierJump' event. https://www.edsm.net/en/api-journal-v1 # msgnum: 1xx = OK, 2xx = fatal error, 3xx = error, 4xx = ignorable errors. def edsm_notify_system(reply): if not reply: diff --git a/plugins/inara.py b/plugins/inara.py index 31386c37..24692851 100644 --- a/plugins/inara.py +++ b/plugins/inara.py @@ -377,6 +377,26 @@ def journal_entry(cmdr, is_beta, system, station, entry, state): ('minorfactionReputation', f['MyReputation']/100.0), ]) for f in entry['Factions'] ]) + elif entry['event'] == 'CarrierJump': + this.system = None + add_event('addCommanderTravelCarrierJump', entry['timestamp'], + OrderedDict([ + ('starsystemName', entry['StarSystem']), + ('stationName', entry['StationName']), + ('marketID', entry['MarketID']), + ('shipType', state['ShipType']), + ('shipGameID', state['ShipID']), + ])) + if entry.get('Factions'): + add_event('setCommanderReputationMinorFaction', entry['timestamp'], + [ + OrderedDict([ + ('minorfactionName', f['Name']), + ('minorfactionReputation', f['MyReputation']/100.0), + ]) for f in entry['Factions'] + ]) + # Ignore the following 'Docked' event + this.suppress_docked = True # Override standard URL functions if config.get('system_provider') == 'Inara': @@ -826,7 +846,7 @@ def worker(): print('Inara\t%s %s\t%s' % (reply_event['eventStatus'], reply_event.get('eventStatusText', ''), json.dumps(data_event))) if reply_event['eventStatus'] // 100 != 2: plug.show_error(_('Error: Inara {MSG}').format(MSG = '%s, %s' % (data_event['eventName'], reply_event.get('eventStatusText', reply_event['eventStatus'])))) - if data_event['eventName'] in ['addCommanderTravelDock', 'addCommanderTravelFSDJump', 'setCommanderTravelLocation']: + if data_event['eventName'] in ['addCommanderTravelCarrierJump', 'addCommanderTravelDock', 'addCommanderTravelFSDJump', 'setCommanderTravelLocation']: this.lastlocation = reply_event.get('eventData', {}) this.system_link.event_generate('<>', when="tail") # calls update_location in main thread elif data_event['eventName'] in ['addCommanderShip', 'setCommanderShip']: diff --git a/prefs.py b/prefs.py index 9fa0c5d6..d8e0f700 100644 --- a/prefs.py +++ b/prefs.py @@ -183,6 +183,13 @@ class PreferencesDialog(tk.Toplevel): self.hotkey_play_btn = nb.Checkbutton(configframe, text=_('Play sound'), variable=self.hotkey_play, state = self.hotkey_code and tk.NORMAL or tk.DISABLED) # Hotkey/Shortcut setting self.hotkey_play_btn.grid(columnspan=4, padx=PADX, sticky=tk.W) + # Option to disabled Automatic Check For Updates whilst in-game + ttk.Separator(configframe, orient=tk.HORIZONTAL).grid(columnspan=4, padx=PADX, pady=PADY*4, sticky=tk.EW) + self.disable_autoappupdatecheckingame = tk.IntVar(value = config.getint('disable_autoappupdatecheckingame')) + self.disable_autoappupdatecheckingame_btn = nb.Checkbutton(configframe, text=_('Disable Automatic Application Updates Check when in-game'), variable=self.disable_autoappupdatecheckingame, command=self.disable_autoappupdatecheckingame_changed) + self.disable_autoappupdatecheckingame_btn.grid(columnspan=4, padx=PADX, sticky=tk.W) + + ttk.Separator(configframe, orient=tk.HORIZONTAL).grid(columnspan=4, padx=PADX, pady=PADY*4, sticky=tk.EW) nb.Label(configframe, text=_('Preferred websites')).grid(row=30, columnspan=4, padx=PADX, sticky=tk.W) # Settings prompt for preferred ship loadout, system and station info websites @@ -272,6 +279,20 @@ class PreferencesDialog(tk.Toplevel): label = nb.Label(plugsframe, text='%s (%s)' % (plugin.folder, plugin.name)) label.grid(columnspan=2, padx=PADX*2, sticky=tk.W) + ############################################################ + # Show which plugins don't have Python 3.x support + ############################################################ + if len(plug.PLUGINS_not_py3): + ttk.Separator(plugsframe, orient=tk.HORIZONTAL).grid(columnspan=3, padx=PADX, pady=PADY * 8, sticky=tk.EW) + nb.Label(plugsframe, text=_('Plugins Without Python 3.x Support:')+':').grid(padx=PADX, sticky=tk.W) + for plugin in plug.PLUGINS_not_py3: + if plugin.folder: # 'system' ones have this set to None to suppress listing in Plugins prefs tab + nb.Label(plugsframe, text=plugin.name).grid(columnspan=2, padx=PADX*2, sticky=tk.W) + HyperlinkLabel(plugsframe, text=_('Information on migrating plugins'), background=nb.Label().cget('background'), url='https://github.com/EDCD/EDMarketConnector/blob/master/PLUGINS.md#migration-to-python-37', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) + + + ############################################################ + disabled_plugins = [x for x in plug.PLUGINS if x.folder and not x.module] if len(disabled_plugins): ttk.Separator(plugsframe, orient=tk.HORIZONTAL).grid(columnspan=3, padx=PADX, pady=PADY * 8, sticky=tk.EW) @@ -418,6 +439,11 @@ class PreferencesDialog(tk.Toplevel): self.logdir.set(config.default_journal_dir) self.outvarchanged() + def disable_autoappupdatecheckingame_changed(self): + config.set('disable_autoappupdatecheckingame', self.disable_autoappupdatecheckingame.get()) + # If it's now False, re-enable WinSparkle ? Need access to the AppWindow.updater variable to call down + + def themecolorbrowse(self, index): (rgb, color) = tkColorChooser.askcolor(self.theme_colors[index], title=self.theme_prompts[index], parent=self.parent) if color: diff --git a/update.py b/update.py index 2844fc70..50e1eb12 100644 --- a/update.py +++ b/update.py @@ -20,6 +20,9 @@ if not getattr(sys, 'frozen', False): def __init__(self, master): self.root = master + def setAutomaticUpdatesCheck(self, onoroff): + return + def checkForUpdates(self): thread = threading.Thread(target = self.worker, name = 'update worker') thread.daemon = True @@ -58,6 +61,10 @@ elif sys.platform=='darwin': print_exc() self.updater = None + def setAutomaticUpdatesCheck(self, onoroff): + if self.updater: + self.updater.win_sparkle_set_automatic_check_for_updates(onoroff) + def checkForUpdates(self): if self.updater: self.updater.checkForUpdates_(None) @@ -98,6 +105,10 @@ elif sys.platform=='win32': print_exc() self.updater = None + def setAutomaticUpdatesCheck(self, onoroff): + if self.updater: + self.updater.win_sparkle_set_automatic_check_for_updates(onoroff) + def checkForUpdates(self): if self.updater: self.updater.win_sparkle_check_update_with_ui()