diff --git a/EDMC.py b/EDMC.py index 6819a219..99586312 100755 --- a/EDMC.py +++ b/EDMC.py @@ -8,6 +8,8 @@ import sys from time import time, sleep import l10n +l10n.Translations().install_dummy() + import companion import bpc import outfitting @@ -15,11 +17,11 @@ import loadout import coriolis import shipyard import eddb +import stats import prefs from config import appcmdname, appversion, config -l10n.Translations().install_dummy() EDDB = eddb.EDDB() SERVER_RETRY = 5 # retry pause for Companion servers [s] @@ -27,13 +29,15 @@ EXIT_SUCCESS, EXIT_SERVER, EXIT_CREDENTIALS, EXIT_VERIFICATION, EXIT_NOT_DOCKED, try: # arg parsing - parser = argparse.ArgumentParser(prog=appcmdname, description='Prints the current system and station (if docked) to stdout and optionally writes ship loadout and/or station data to file. Requires prior setup through the accompanying GUI app.') + parser = argparse.ArgumentParser(prog=appcmdname, description='Prints the current system and station (if docked) to stdout and optionally writes player status, ship locations, ship loadout and/or station data to file. Requires prior setup through the accompanying GUI app.') parser.add_argument('-v', '--version', help='print program version and exit', action='store_const', const=True) parser.add_argument('-c', metavar='FILE', help='write ship loadout to FILE in Coriolis json format') parser.add_argument('-e', metavar='FILE', help='write ship loadout to FILE in E:D Shipyard format') + parser.add_argument('-l', metavar='FILE', help='write ship locations to FILE in CSV format') parser.add_argument('-m', metavar='FILE', help='write station commodity market data to FILE in CSV format') parser.add_argument('-o', metavar='FILE', help='write station outfitting data to FILE in CSV format') parser.add_argument('-s', metavar='FILE', help='write station shipyard data to FILE in CSV format') + parser.add_argument('-t', metavar='FILE', help='write player status to FILE in CSV format') args = parser.parse_args() if args.version: print '%.2f' % (float(''.join(appversion.split('.')[:3])) / 100) # just first three digits @@ -62,6 +66,10 @@ try: coriolis.export(data, args.c) if args.e: loadout.export(data, args.e) + if args.l: + stats.export_ships(data, args.l) + if args.t: + stats.export_status(data, args.t) if not data['commander'].get('docked'): print data['lastSystem']['name'] diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 6588ef5e..bc1c6730 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -18,6 +18,8 @@ if __debug__: from traceback import print_exc import l10n +l10n.Translations().install() + import companion import bpc import td @@ -27,12 +29,12 @@ import loadout import coriolis import flightlog import eddb +import stats import prefs from config import appname, applongname, config from hotkey import hotkeymgr from monitor import monitor -l10n.Translations().install() EDDB = eddb.EDDB() SERVER_RETRY = 5 # retry pause for Companion servers [s] @@ -78,9 +80,9 @@ class AppWindow: frame.columnconfigure(1, weight=1) frame.rowconfigure(4, weight=1) - ttk.Label(frame, text=_('Cmdr:')).grid(row=0, column=0, sticky=tk.W) # Main window - ttk.Label(frame, text=_('System:')).grid(row=1, column=0, sticky=tk.W) # Main window - ttk.Label(frame, text=_('Station:')).grid(row=2, column=0, sticky=tk.W) # Main window + ttk.Label(frame, text=_('Cmdr')+':').grid(row=0, column=0, sticky=tk.W) # Main window + ttk.Label(frame, text=_('System')+':').grid(row=1, column=0, sticky=tk.W) # Main window + ttk.Label(frame, text=_('Station')+':').grid(row=2, column=0, sticky=tk.W) # Main window self.cmdr = ttk.Label(frame, width=-21) self.system = HyperlinkLabel(frame, compound=tk.RIGHT, url = self.system_url, popup_copy = True) @@ -111,6 +113,9 @@ class AppWindow: self.edit_menu.add_command(label=_('Copy'), accelerator='Command-c', state=tk.DISABLED, command=self.copy) # As in Copy and Paste menubar.add_cascade(label=_('Edit'), menu=self.edit_menu) # Menu title self.w.bind('', self.copy) + self.view_menu = tk.Menu(menubar, name='view') + self.view_menu.add_command(label=_('Status'), state=tk.DISABLED, command=lambda:stats.StatsDialog(self.w, self.session)) # Menu item + menubar.add_cascade(label=_('View'), menu=self.view_menu) # Menu title on OSX window_menu = tk.Menu(menubar, name='window') menubar.add_cascade(label=_('Window'), menu=window_menu) # Menu title on OSX # https://www.tcl.tk/man/tcl/TkCmd/tk_mac.htm @@ -121,7 +126,8 @@ class AppWindow: self.w.createcommand("::tk::mac::ReopenApplication", self.w.deiconify) # click on app in dock = restore self.w.protocol("WM_DELETE_WINDOW", self.w.withdraw) # close button shouldn't quit app else: - file_menu = tk.Menu(menubar, tearoff=tk.FALSE) + file_menu = self.view_menu = tk.Menu(menubar, tearoff=tk.FALSE) + file_menu.add_command(label=_('Status'), state=tk.DISABLED, command=lambda:stats.StatsDialog(self.w, self.session)) # Menu item if platform == 'win32': file_menu.add_command(label=_("Check for Updates..."), command=lambda:self.updater.checkForUpdates()) file_menu.add_command(label=_("Settings"), command=lambda:prefs.PreferencesDialog(self.w, self.login)) # Item in the File menu on Windows @@ -183,16 +189,8 @@ class AppWindow: self.w.update_idletasks() try: self.session.login(config.get('username'), config.get('password')) + self.view_menu.entryconfigure(_('Status'), state=tk.NORMAL) self.status['text'] = '' - - # 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() - self.status['text'] = unicode(e) - except companion.VerificationRequired: # don't worry about authentication now - prompt on query self.status['text'] = '' @@ -202,8 +200,18 @@ 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 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() # callback after verification code @@ -231,7 +239,7 @@ class AppWindow: hotkeymgr.play_good() self.cmdr['text'] = self.system['text'] = self.station['text'] = '' self.system['image'] = '' - self.status['text'] = _('Fetching station data...') + self.status['text'] = _('Fetching data...') self.button['state'] = tk.DISABLED self.edit_menu.entryconfigure(_('Copy'), state=tk.DISABLED) self.w.update_idletasks() @@ -259,6 +267,7 @@ class AppWindow: self.station['text'] = data.get('commander') and data.get('commander').get('docked') and data.get('lastStarport') and data.get('lastStarport').get('name') or (EDDB.system(self.system['text']) and self.STATION_UNDOCKED or '') self.status['text'] = '' self.edit_menu.entryconfigure(_('Copy'), state=tk.NORMAL) + self.view_menu.entryconfigure(_('Status'), state=tk.NORMAL) # stuff we can do when not docked if config.getint('output') & config.OUT_SHIP_EDS: diff --git a/L10n/en.template b/L10n/en.template index cf9d23ab..c6bb3a68 100644 --- a/L10n/en.template +++ b/L10n/en.template @@ -4,26 +4,59 @@ /* App menu entry on OSX. [EDMarketConnector.py] */ "About {APP}" = "About {APP}"; +/* Federation rank. [stats.py] */ +"Admiral" = "Admiral"; + +/* Explorer rank. [stats.py] */ +"Aimless" = "Aimless"; + +/* CQC rank. [stats.py] */ +"Amateur" = "Amateur"; + /* EDSM setting. [prefs.py] */ "API Key" = "API Key"; /* Output setting. [prefs.py] */ "Automatically make a log entry on entering a system" = "Automatically make a log entry on entering a system"; +/* Cmdr stats. [stats.py] */ +"Balance" = "Balance"; + +/* Empire rank. [stats.py] */ +"Baron" = "Baron"; + +/* Trade rank. [stats.py] */ +"Broker" = "Broker"; + /* Folder selection button on Windows. [prefs.py] */ "Browse..." = "Browse..."; +/* Federation rank. [stats.py] */ +"Cadet" = "Cadet"; + +/* CQC rank. [stats.py] */ +"Champion" = "Champion"; + /* Folder selection button on OSX. [prefs.py] */ "Change..." = "Change..."; /* [EDMarketConnector.py] */ "Check for Updates..." = "Check for Updates..."; +/* Federation rank. [stats.py] */ +"Chief Petty Officer" = "Chief Petty Officer"; + +/* Main window. [EDMarketConnector.py] */ +"Cmdr" = "Cmdr"; + /* EDSM & privacy setting. [prefs.py] */ "Cmdr name" = "Cmdr name"; -/* Main window. [EDMarketConnector.py] */ -"Cmdr:" = "Cmdr:"; +/* Ranking. [stats.py] */ +"Combat" = "Combat"; + +/* Combat rank. [stats.py] */ +"Competent" = "Competent"; /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "cooldown {SS}s"; @@ -31,15 +64,48 @@ /* As in Copy and Paste. [EDMarketConnector.py] */ "Copy" = "Copy"; +/* Empire rank. [stats.py] */ +"Count" = "Count"; + +/* Ranking. [stats.py] */ +"CQC" = "CQC"; + /* Section heading in settings. [prefs.py] */ "Credentials" = "Credentials"; +/* Combat rank. [stats.py] */ +"Dangerous" = "Dangerous"; + +/* Combat rank. [stats.py] */ +"Deadly" = "Deadly"; + +/* Trade rank. [stats.py] */ +"Dealer" = "Dealer"; + +/* Empire rank. [stats.py] */ +"Duke" = "Duke"; + +/* Empire rank. [stats.py] */ +"Earl" = "Earl"; + /* Menu title. [EDMarketConnector.py] */ "Edit" = "Edit"; +/* Top rank. [stats.py] */ +"Elite" = "Elite"; + /* Section heading in settings. [prefs.py] */ "Elite Dangerous Star Map credentials" = "Elite Dangerous Star Map credentials"; +/* Ranking. [stats.py] */ +"Empire" = "Empire"; + +/* Federation rank. [stats.py] */ +"Ensign" = "Ensign"; + +/* Trade rank. [stats.py] */ +"Entrepreneur" = "Entrepreneur"; + /* [EDMarketConnector.py] */ "Error: Can't connect to EDDN" = "Error: Can't connect to EDDN"; @@ -64,8 +130,17 @@ /* Item in the File menu on Windows. [EDMarketConnector.py] */ "Exit" = "Exit"; +/* Combat rank. [stats.py] */ +"Expert" = "Expert"; + +/* Ranking. [stats.py] */ +"Explorer" = "Explorer"; + +/* Ranking. [stats.py] */ +"Federation" = "Federation"; + /* [EDMarketConnector.py] */ -"Fetching station data..." = "Fetching station data..."; +"Fetching data..." = "Fetching data..."; /* Menu title on Windows. [EDMarketConnector.py] */ "File" = "File"; @@ -76,6 +151,18 @@ /* [prefs.py] */ "Flight log in CSV format file" = "Flight log in CSV format file"; +/* CQC rank. [stats.py] */ +"Gladiator" = "Gladiator"; + +/* Combat rank. [stats.py] */ +"Harmless" = "Harmless"; + +/* CQC rank. [stats.py] */ +"Helpless" = "Helpless"; + +/* CQC rank. [stats.py] */ +"Hero" = "Hero"; + /* Section heading in settings on Windows. [prefs.py] */ "Hotkey" = "Hotkey"; @@ -85,12 +172,30 @@ /* Section heading in settings on OSX. [prefs.py] */ "Keyboard shortcut" = "Keyboard shortcut"; +/* Empire rank. [stats.py] */ +"King" = "King"; + +/* Empire rank. [stats.py] */ +"Knight" = "Knight"; + /* [EDMarketConnector.py] */ "Last updated at {HH}:{MM}:{SS}" = "Last updated at {HH}:{MM}:{SS}"; +/* Federation rank. [stats.py] */ +"Lieutenant" = "Lieutenant"; + +/* Federation rank. [stats.py] */ +"Lieutenant Commander" = "Lieutenant Commander"; + +/* Cmdr stats. [stats.py] */ +"Loan" = "Loan"; + /* [EDMarketConnector.py] */ "Logging in..." = "Logging in..."; +/* Empire rank. [stats.py] */ +"Lord" = "Lord"; + /* [prefs.py] */ "Market data in CSV format file" = "Market data in CSV format file"; @@ -100,8 +205,35 @@ /* [prefs.py] */ "Market data in Trade Dangerous format file" = "Market data in Trade Dangerous format file"; +/* Empire rank. [stats.py] */ +"Marquis" = "Marquis"; + +/* Combat rank. [stats.py] */ +"Master" = "Master"; + +/* Trade rank. [stats.py] */ +"Merchant" = "Merchant"; + +/* Federation rank. [stats.py] */ +"Midshipman" = "Midshipman"; + +/* Explorer rank. [stats.py] */ +"Mostly Aimless" = "Mostly Aimless"; + +/* Combat rank. [stats.py] */ +"Mostly Harmless" = "Mostly Harmless"; + +/* CQC rank. [stats.py] */ +"Mostly Helpless" = "Mostly Helpless"; + +/* Trade rank. [stats.py] */ +"Mostly Penniless" = "Mostly Penniless"; + /* No hotkey/shortcut currently defined. [prefs.py] */ -"none" = "none"; +"None" = "None"; + +/* Combat rank. [stats.py] */ +"Novice" = "Novice"; /* [prefs.py] */ "OK" = "OK"; @@ -115,9 +247,27 @@ /* Section heading in settings. [prefs.py] */ "Output" = "Output"; +/* Empire rank. [stats.py] */ +"Outsider" = "Outsider"; + /* Use same text as E:D Launcher's login dialog. [prefs.py] */ "Password" = "Password"; +/* Explorer rank. [stats.py] */ +"Pathfinder" = "Pathfinder"; + +/* Trade rank. [stats.py] */ +"Pedlar" = "Pedlar"; + +/* Trade rank. [stats.py] */ +"Penniless" = "Penniless"; + +/* Federation rank. [stats.py] */ +"Petty Officer" = "Petty Officer"; + +/* Explorer rank. [stats.py] */ +"Pioneer" = "Pioneer"; + /* Hotkey/Shortcut setting. [prefs.py] */ "Play sound" = "Play sound"; @@ -130,15 +280,48 @@ /* Use same text as E:D Launcher's login dialog. [prefs.py] */ "Please log in with your Elite: Dangerous account details" = "Please log in with your Elite: Dangerous account details"; +/* Federation rank. [stats.py] */ +"Post Captain" = "Post Captain"; + +/* Federation rank. [stats.py] */ +"Post Commander" = "Post Commander"; + +/* Ranking. [stats.py] */ +"Powerplay" = "Powerplay"; + /* [prefs.py] */ "Preferences" = "Preferences"; +/* Empire rank. [stats.py] */ +"Prince" = "Prince"; + /* Section heading in settings. [prefs.py] */ "Privacy" = "Privacy"; +/* CQC rank. [stats.py] */ +"Professional" = "Professional"; + /* Privacy setting. [prefs.py] */ "Pseudo-anonymized ID" = "Pseudo-anonymized ID"; +/* Explorer rank. [stats.py] */ +"Ranger" = "Ranger"; + +/* Power rank. [stats.py] */ +"Rating 1" = "Rating 1"; + +/* Power rank. [stats.py] */ +"Rating 2" = "Rating 2"; + +/* Power rank. [stats.py] */ +"Rating 3" = "Rating 3"; + +/* Power rank. [stats.py] */ +"Rating 4" = "Rating 4"; + +/* Power rank. [stats.py] */ +"Rating 5" = "Rating 5"; + /* Status bar message on launch. [EDMarketConnector.py] */ "Re-start Elite: Dangerous for automatic log entries" = "Re-start Elite: Dangerous for automatic log entries"; @@ -148,6 +331,18 @@ /* Shortcut settings prompt on OSX. [prefs.py] */ "Re-start {APP} to use shortcuts" = "Re-start {APP} to use shortcuts"; +/* Federation rank. [stats.py] */ +"Rear Admiral" = "Rear Admiral"; + +/* Federation rank. [stats.py] */ +"Recruit" = "Recruit"; + +/* Explorer rank. [stats.py] */ +"Scout" = "Scout"; + +/* CQC rank. [stats.py] */ +"Semi Professional" = "Semi Professional"; + /* [prefs.py] */ "Send flight log to Elite Dangerous Star Map" = "Send flight log to Elite Dangerous Star Map"; @@ -160,26 +355,53 @@ /* [EDMarketConnector.py] */ "Sending data to EDSM..." = "Sending data to EDSM..."; +/* Empire rank. [stats.py] */ +"Serf" = "Serf"; + /* Item in the File menu on Windows. [EDMarketConnector.py] */ "Settings" = "Settings"; +/* Status dialog subtitle. [stats.py] */ +"Ship" = "Ship"; + /* [prefs.py] */ "Ship loadout in Coriolis format file" = "Ship loadout in Coriolis format file"; /* [prefs.py] */ "Ship loadout in E:D Shipyard format file" = "Ship loadout in E:D Shipyard format file"; +/* Status dialog title. [stats.py] */ +"Ships" = "Ships"; + +/* Empire rank. [stats.py] */ +"Squire" = "Squire"; + +/* Main window. [EDMarketConnector.py] */ +"Station" = "Station"; + /* [EDMarketConnector.py] */ "Station doesn't have a market!" = "Station doesn't have a market!"; /* [EDMarketConnector.py] */ "Station doesn't have anything!" = "Station doesn't have anything!"; -/* Main window. [EDMarketConnector.py] */ -"Station:" = "Station:"; +/* Menu item. [EDMarketConnector.py] */ +"Status" = "Status"; + +/* Explorer rank. [stats.py] */ +"Surveyor" = "Surveyor"; /* Main window. [EDMarketConnector.py] */ -"System:" = "System:"; +"System" = "System"; + +/* Ranking. [stats.py] */ +"Trade" = "Trade"; + +/* Explorer rank. [stats.py] */ +"Trailblazer" = "Trailblazer"; + +/* Trade rank. [stats.py] */ +"Tycoon" = "Tycoon"; /* Update button in main window. [EDMarketConnector.py] */ "Update" = "Update"; @@ -187,6 +409,18 @@ /* Use same text as E:D Launcher's login dialog. [prefs.py] */ "Username (Email)" = "Username (Email)"; +/* Federation rank. [stats.py] */ +"Vice Admiral" = "Vice Admiral"; + +/* Menu title on OSX. [EDMarketConnector.py] */ +"View" = "View"; + +/* Empire rank. [stats.py] */ +"Viscount" = "Viscount"; + +/* Federation rank. [stats.py] */ +"Warrant Officer" = "Warrant Officer"; + /* Shouldn't happen. [EDMarketConnector.py] */ "What are you flying?!" = "What are you flying?!"; diff --git a/L10n/fr.strings b/L10n/fr.strings index a6672b77..ee347b80 100644 --- a/L10n/fr.strings +++ b/L10n/fr.strings @@ -17,7 +17,7 @@ "Cmdr name" = "Nom de Cmd"; /* Main window. [EDMarketConnector.py] */ -"Cmdr:" = "Cmd:"; +"Cmdr" = "Cmd"; /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "Temps de recharge {SS}s"; @@ -41,7 +41,7 @@ "Exit" = "Quitter"; /* [EDMarketConnector.py] */ -"Fetching station data..." = "Récupération des données de la station..."; +"Fetching data..." = "Récupération des données..."; /* Menu title on Windows. [EDMarketConnector.py] */ "File" = "Fichier"; @@ -119,10 +119,10 @@ "Station doesn't have anything!" = "La station n'a rien du tout !"; /* Main window. [EDMarketConnector.py] */ -"Station:" = "Station:"; +"Station" = "Station"; /* Main window. [EDMarketConnector.py] */ -"System:" = "Système:"; +"System" = "Système"; /* Update button in main window. [EDMarketConnector.py] */ "Update" = "Mettre à jour"; @@ -146,7 +146,7 @@ "Hotkey" = "Raccourci clavier"; /* No hotkey/shortcut currently defined. [prefs.py] */ -"none" = "aucun"; +"None" = "Aucun"; /* Shortcut settings button on OSX. [prefs.py] */ "Open System Preferences" = "Ouvrir Préférences Système"; @@ -202,5 +202,239 @@ /* [EDMarketConnector.py] */ "Error: Can't get market data!" = "Erreur: Impossible d'obtenir les données du marché!"; +/* Federation rank. [stats.py] */ +"Admiral" = "Amiral"; + +/* Explorer rank. [stats.py] */ +"Aimless" = "Vagabond"; + +/* CQC rank. [stats.py] */ +"Amateur" = ""; + +/* Cmdr stats. [stats.py] */ +"Balance" = "Solde"; + +/* Empire rank. [stats.py] */ +"Baron" = "Baron"; + +/* Trade rank. [stats.py] */ +"Broker" = "Courtier"; + +/* Federation rank. [stats.py] */ +"Cadet" = "Cadet"; + +/* CQC rank. [stats.py] */ +"Champion" = ""; + +/* Federation rank. [stats.py] */ +"Chief Petty Officer" = "Premier Maître"; + +/* Ranking. [stats.py] */ +"Combat" = "Combattant"; + +/* Combat rank. [stats.py] */ +"Competent" = "Compétent"; + +/* Empire rank. [stats.py] */ +"Count" = "Comte"; + +/* Ranking. [stats.py] */ +"CQC" = "CQC"; + +/* Combat rank. [stats.py] */ +"Dangerous" = "Vétéran"; + +/* Combat rank. [stats.py] */ +"Deadly" = "Létal"; + +/* Trade rank. [stats.py] */ +"Dealer" = "Revendeur"; + +/* Empire rank. [stats.py] */ +"Duke" = "Archiduc"; + +/* Empire rank. [stats.py] */ +"Earl" = "Marquis"; + +/* Top rank. [stats.py] */ +"Elite" = "Élite"; + +/* Ranking. [stats.py] */ +"Empire" = "Empire"; + +/* Federation rank. [stats.py] */ +"Ensign" = "Enseigne"; + +/* Trade rank. [stats.py] */ +"Entrepreneur" = "Entrepreneur"; + +/* Combat rank. [stats.py] */ +"Expert" = "Expert"; + +/* Ranking. [stats.py] */ +"Explorer" = "Explorateur"; + +/* Ranking. [stats.py] */ +"Federation" = "Fédération"; + +/* CQC rank. [stats.py] */ +"Gladiator" = ""; + +/* Combat rank. [stats.py] */ +"Harmless" = "Inoffensif"; + +/* CQC rank. [stats.py] */ +"Helpless" = ""; + +/* CQC rank. [stats.py] */ +"Hero" = ""; + +/* Empire rank. [stats.py] */ +"King" = "Roi"; + +/* Empire rank. [stats.py] */ +"Knight" = "Chevalier"; + +/* Federation rank. [stats.py] */ +"Lieutenant" = "Lieutenant"; + +/* Federation rank. [stats.py] */ +"Lieutenant Commander" = "Capitaine de Corvette"; + +/* Cmdr stats. [stats.py] */ +"Loan" = "Emprunt"; + +/* Empire rank. [stats.py] */ +"Lord" = "Banneret"; + +/* Empire rank. [stats.py] */ +"Marquis" = "Duc"; + +/* Combat rank. [stats.py] */ +"Master" = "Vilain"; + +/* Trade rank. [stats.py] */ +"Merchant" = "Marchand"; + +/* Federation rank. [stats.py] */ +"Midshipman" = "Matelot"; + +/* Explorer rank. [stats.py] */ +"Mostly Aimless" = "Touriste"; + +/* Combat rank. [stats.py] */ +"Mostly Harmless" = "Bleu"; + +/* CQC rank. [stats.py] */ +"Mostly Helpless" = ""; + +/* Trade rank. [stats.py] */ +"Mostly Penniless" = "Mendiant"; + +/* Combat rank. [stats.py] */ +"Novice" = "Novice"; + +/* Empire rank. [stats.py] */ +"Outsider" = "Étranger"; + +/* Explorer rank. [stats.py] */ +"Pathfinder" = "Découvreur"; + +/* Trade rank. [stats.py] */ +"Pedlar" = "Boutiquier"; + +/* Trade rank. [stats.py] */ +"Penniless" = "Sans-le-sou"; + +/* Federation rank. [stats.py] */ +"Petty Officer" = "Second Maître"; + +/* Explorer rank. [stats.py] */ +"Pioneer" = "Pionnier"; + +/* Federation rank. [stats.py] */ +"Post Captain" = "Capitaine de Vaisseau"; + +/* Federation rank. [stats.py] */ +"Post Commander" = "Capitaine de Frégate"; + +/* Ranking. [stats.py] */ +"Powerplay" = "Powerplay"; + +/* Empire rank. [stats.py] */ +"Prince" = "Prince"; + +/* CQC rank. [stats.py] */ +"Professional" = ""; + +/* Explorer rank. [stats.py] */ +"Ranger" = "Navigateur"; + +/* Power rank. [stats.py] */ +"Rating 1" = "Rang 1"; + +/* Power rank. [stats.py] */ +"Rating 2" = "Rang 2"; + +/* Power rank. [stats.py] */ +"Rating 3" = "Rang 3"; + +/* Power rank. [stats.py] */ +"Rating 4" = "Rang 4"; + +/* Power rank. [stats.py] */ +"Rating 5" = "Rang 5"; + /* 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"; + +/* Federation rank. [stats.py] */ +"Rear Admiral" = "Contre-Amiral"; + +/* Federation rank. [stats.py] */ +"Recruit" = "Recrue"; + +/* Explorer rank. [stats.py] */ +"Scout" = "Voyageur"; + +/* CQC rank. [stats.py] */ +"Semi Professional" = ""; + +/* Empire rank. [stats.py] */ +"Serf" = "Serf"; + +/* Status dialog subtitle. [stats.py] */ +"Ship" = "Vaisseau"; + +/* Status dialog title. [stats.py] */ +"Ships" = "Vaisseaux"; + +/* Empire rank. [stats.py] */ +"Squire" = "Écuyer"; + +/* Menu item. [EDMarketConnector.py] */ +"Status" = "État"; + +/* Explorer rank. [stats.py] */ +"Surveyor" = "Éclaireur"; + +/* Ranking. [stats.py] */ +"Trade" = "Commerçant"; + +/* Explorer rank. [stats.py] */ +"Trailblazer" = "Prospecteur"; + +/* Trade rank. [stats.py] */ +"Tycoon" = "Magnat"; + +/* Federation rank. [stats.py] */ +"Vice Admiral" = "Vice-Amiral"; + +/* Menu title on OSX. [EDMarketConnector.py] */ +"View" = "Présentation"; + +/* Empire rank. [stats.py] */ +"Viscount" = "Vicomte"; + +/* Federation rank. [stats.py] */ +"Warrant Officer" = "Major"; diff --git a/L10n/it.strings b/L10n/it.strings index a84a9bf9..0440839e 100644 --- a/L10n/it.strings +++ b/L10n/it.strings @@ -17,7 +17,7 @@ "Cmdr name" = "Nome Cmdr"; /* Main window. [EDMarketConnector.py] */ -"Cmdr:" = "Cmdr:"; +"Cmdr" = "Cmdr"; /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "disponibile tra {SS} secondi"; @@ -41,7 +41,7 @@ "Exit" = "Esci"; /* [EDMarketConnector.py] */ -"Fetching station data..." = "Raccogliendo i dati della Stazione..."; +"Fetching data..." = "Raccogliendo i dati..."; /* Menu title on Windows. [EDMarketConnector.py] */ "File" = "File"; @@ -119,10 +119,10 @@ "Station doesn't have anything!" = "La Stazione non ha niente !"; /* Main window. [EDMarketConnector.py] */ -"Station:" = "Stazione:"; +"Station" = "Stazione"; /* Main window. [EDMarketConnector.py] */ -"System:" = "Sistema:"; +"System" = "Sistema"; /* Update button in main window. [EDMarketConnector.py] */ "Update" = "Recupera"; @@ -146,7 +146,7 @@ "Hotkey" = "Hotkey"; /* No hotkey/shortcut currently defined. [prefs.py] */ -"none" = "nessuna"; +"None" = "Nessuna"; /* Shortcut settings button on OSX. [prefs.py] */ "Open System Preferences" = "Apri Preferenze di Systema"; @@ -202,5 +202,239 @@ /* [EDMarketConnector.py] */ "Error: Can't get market data!" = "Errore: Non riesco a ottenere il market data!"; +/* Federation rank. [stats.py] */ +"Admiral" = ""; + +/* Explorer rank. [stats.py] */ +"Aimless" = ""; + +/* CQC rank. [stats.py] */ +"Amateur" = ""; + +/* Cmdr stats. [stats.py] */ +"Balance" = ""; + +/* Empire rank. [stats.py] */ +"Baron" = ""; + +/* Trade rank. [stats.py] */ +"Broker" = ""; + +/* Federation rank. [stats.py] */ +"Cadet" = ""; + +/* CQC rank. [stats.py] */ +"Champion" = ""; + +/* Federation rank. [stats.py] */ +"Chief Petty Officer" = ""; + +/* Ranking. [stats.py] */ +"Combat" = ""; + +/* Combat rank. [stats.py] */ +"Competent" = ""; + +/* Empire rank. [stats.py] */ +"Count" = ""; + +/* Ranking. [stats.py] */ +"CQC" = ""; + +/* Combat rank. [stats.py] */ +"Dangerous" = ""; + +/* Combat rank. [stats.py] */ +"Deadly" = ""; + +/* Trade rank. [stats.py] */ +"Dealer" = ""; + +/* Empire rank. [stats.py] */ +"Duke" = ""; + +/* Empire rank. [stats.py] */ +"Earl" = ""; + +/* Top rank. [stats.py] */ +"Elite" = ""; + +/* Ranking. [stats.py] */ +"Empire" = ""; + +/* Federation rank. [stats.py] */ +"Ensign" = ""; + +/* Trade rank. [stats.py] */ +"Entrepreneur" = ""; + +/* Combat rank. [stats.py] */ +"Expert" = ""; + +/* Ranking. [stats.py] */ +"Explorer" = ""; + +/* Ranking. [stats.py] */ +"Federation" = ""; + +/* CQC rank. [stats.py] */ +"Gladiator" = ""; + +/* Combat rank. [stats.py] */ +"Harmless" = ""; + +/* CQC rank. [stats.py] */ +"Helpless" = ""; + +/* CQC rank. [stats.py] */ +"Hero" = ""; + +/* Empire rank. [stats.py] */ +"King" = ""; + +/* Empire rank. [stats.py] */ +"Knight" = ""; + +/* Federation rank. [stats.py] */ +"Lieutenant" = ""; + +/* Federation rank. [stats.py] */ +"Lieutenant Commander" = ""; + +/* Cmdr stats. [stats.py] */ +"Loan" = ""; + +/* Empire rank. [stats.py] */ +"Lord" = ""; + +/* Empire rank. [stats.py] */ +"Marquis" = ""; + +/* Combat rank. [stats.py] */ +"Master" = ""; + +/* Trade rank. [stats.py] */ +"Merchant" = ""; + +/* Federation rank. [stats.py] */ +"Midshipman" = ""; + +/* Explorer rank. [stats.py] */ +"Mostly Aimless" = ""; + +/* Combat rank. [stats.py] */ +"Mostly Harmless" = ""; + +/* CQC rank. [stats.py] */ +"Mostly Helpless" = ""; + +/* Trade rank. [stats.py] */ +"Mostly Penniless" = ""; + +/* Combat rank. [stats.py] */ +"Novice" = ""; + +/* Empire rank. [stats.py] */ +"Outsider" = ""; + +/* Explorer rank. [stats.py] */ +"Pathfinder" = ""; + +/* Trade rank. [stats.py] */ +"Pedlar" = ""; + +/* Trade rank. [stats.py] */ +"Penniless" = ""; + +/* Federation rank. [stats.py] */ +"Petty Officer" = ""; + +/* Explorer rank. [stats.py] */ +"Pioneer" = ""; + +/* Federation rank. [stats.py] */ +"Post Captain" = ""; + +/* Federation rank. [stats.py] */ +"Post Commander" = ""; + +/* Ranking. [stats.py] */ +"Powerplay" = ""; + +/* Empire rank. [stats.py] */ +"Prince" = ""; + +/* CQC rank. [stats.py] */ +"Professional" = ""; + +/* Explorer rank. [stats.py] */ +"Ranger" = ""; + +/* Power rank. [stats.py] */ +"Rating 1" = ""; + +/* Power rank. [stats.py] */ +"Rating 2" = ""; + +/* Power rank. [stats.py] */ +"Rating 3" = ""; + +/* Power rank. [stats.py] */ +"Rating 4" = ""; + +/* Power rank. [stats.py] */ +"Rating 5" = ""; + /* Status bar message on launch. [EDMarketConnector.py] */ "Re-start Elite: Dangerous for automatic log entries" = "Riavviare Elite: Dangerous per una log entry automatica"; + +/* Federation rank. [stats.py] */ +"Rear Admiral" = ""; + +/* Federation rank. [stats.py] */ +"Recruit" = ""; + +/* Explorer rank. [stats.py] */ +"Scout" = ""; + +/* CQC rank. [stats.py] */ +"Semi Professional" = ""; + +/* Empire rank. [stats.py] */ +"Serf" = ""; + +/* Status dialog subtitle. [stats.py] */ +"Ship" = "Nave"; + +/* Status dialog title. [stats.py] */ +"Ships" = "Navi"; + +/* Empire rank. [stats.py] */ +"Squire" = ""; + +/* Menu item. [EDMarketConnector.py] */ +"Status" = "Status"; + +/* Explorer rank. [stats.py] */ +"Surveyor" = ""; + +/* Ranking. [stats.py] */ +"Trade" = ""; + +/* Explorer rank. [stats.py] */ +"Trailblazer" = ""; + +/* Trade rank. [stats.py] */ +"Tycoon" = ""; + +/* Federation rank. [stats.py] */ +"Vice Admiral" = ""; + +/* Menu title on OSX. [EDMarketConnector.py] */ +"View" = "Vista"; + +/* Empire rank. [stats.py] */ +"Viscount" = ""; + +/* Federation rank. [stats.py] */ +"Warrant Officer" = ""; diff --git a/L10n/pl.strings b/L10n/pl.strings index 40143da9..f424c50d 100644 --- a/L10n/pl.strings +++ b/L10n/pl.strings @@ -17,7 +17,7 @@ "Cmdr name" = "Nazwa gracza"; /* Main window. [EDMarketConnector.py] */ -"Cmdr:" = "Cmdr:"; +"Cmdr" = "Cmdr"; /* Update button in main window. [EDMarketConnector.py] */ "cooldown {SS}s" = "Oczekiwanie {SS} sek."; @@ -41,7 +41,7 @@ "Exit" = "Zakończ"; /* [EDMarketConnector.py] */ -"Fetching station data..." = "Pobieranie danych o stacji..."; +"Fetching data..." = "Pobieranie danych..."; /* Menu title on Windows. [EDMarketConnector.py] */ "File" = "Plik"; @@ -119,10 +119,10 @@ "Station doesn't have anything!" = "Stacja jest pusta!"; /* Main window. [EDMarketConnector.py] */ -"Station:" = "Stacja:"; +"Station" = "Stacja"; /* Main window. [EDMarketConnector.py] */ -"System:" = "System:"; +"System" = "System"; /* Update button in main window. [EDMarketConnector.py] */ "Update" = "Aktualizacja"; @@ -146,7 +146,7 @@ "Hotkey" = "Skr. Klaw."; /* No hotkey/shortcut currently defined. [prefs.py] */ -"none" = "brak"; +"None" = "Brak"; /* Shortcut settings button on OSX. [prefs.py] */ "Open System Preferences" = "Otwórz Preferencje systemowe"; @@ -193,5 +193,248 @@ /* [EDMarketConnector.py] */ "Sending data to EDSM..." = "Wysłanie danych do EDSM..."; +/* Output setting. [prefs.py] */ +"Automatically make a log entry on entering a system" = ""; + /* Output settings prompt. [prefs.py] */ "Re-start Elite: Dangerous to use this feature" = ""; + +/* [EDMarketConnector.py] */ +"Error: Can't get market data!" = ""; + +/* Federation rank. [stats.py] */ +"Admiral" = ""; + +/* Explorer rank. [stats.py] */ +"Aimless" = ""; + +/* CQC rank. [stats.py] */ +"Amateur" = ""; + +/* Cmdr stats. [stats.py] */ +"Balance" = ""; + +/* Empire rank. [stats.py] */ +"Baron" = ""; + +/* Trade rank. [stats.py] */ +"Broker" = ""; + +/* Federation rank. [stats.py] */ +"Cadet" = ""; + +/* CQC rank. [stats.py] */ +"Champion" = ""; + +/* Federation rank. [stats.py] */ +"Chief Petty Officer" = ""; + +/* Ranking. [stats.py] */ +"Combat" = ""; + +/* Combat rank. [stats.py] */ +"Competent" = ""; + +/* Empire rank. [stats.py] */ +"Count" = ""; + +/* Ranking. [stats.py] */ +"CQC" = ""; + +/* Combat rank. [stats.py] */ +"Dangerous" = ""; + +/* Combat rank. [stats.py] */ +"Deadly" = ""; + +/* Trade rank. [stats.py] */ +"Dealer" = ""; + +/* Empire rank. [stats.py] */ +"Duke" = ""; + +/* Empire rank. [stats.py] */ +"Earl" = ""; + +/* Top rank. [stats.py] */ +"Elite" = ""; + +/* Ranking. [stats.py] */ +"Empire" = ""; + +/* Federation rank. [stats.py] */ +"Ensign" = ""; + +/* Trade rank. [stats.py] */ +"Entrepreneur" = ""; + +/* Combat rank. [stats.py] */ +"Expert" = ""; + +/* Ranking. [stats.py] */ +"Explorer" = ""; + +/* Ranking. [stats.py] */ +"Federation" = ""; + +/* CQC rank. [stats.py] */ +"Gladiator" = ""; + +/* Combat rank. [stats.py] */ +"Harmless" = ""; + +/* CQC rank. [stats.py] */ +"Helpless" = ""; + +/* CQC rank. [stats.py] */ +"Hero" = ""; + +/* Empire rank. [stats.py] */ +"King" = ""; + +/* Empire rank. [stats.py] */ +"Knight" = ""; + +/* Federation rank. [stats.py] */ +"Lieutenant" = ""; + +/* Federation rank. [stats.py] */ +"Lieutenant Commander" = ""; + +/* Cmdr stats. [stats.py] */ +"Loan" = ""; + +/* Empire rank. [stats.py] */ +"Lord" = ""; + +/* Empire rank. [stats.py] */ +"Marquis" = ""; + +/* Combat rank. [stats.py] */ +"Master" = ""; + +/* Trade rank. [stats.py] */ +"Merchant" = ""; + +/* Federation rank. [stats.py] */ +"Midshipman" = ""; + +/* Explorer rank. [stats.py] */ +"Mostly Aimless" = ""; + +/* Combat rank. [stats.py] */ +"Mostly Harmless" = ""; + +/* CQC rank. [stats.py] */ +"Mostly Helpless" = ""; + +/* Trade rank. [stats.py] */ +"Mostly Penniless" = ""; + +/* Combat rank. [stats.py] */ +"Novice" = ""; + +/* Empire rank. [stats.py] */ +"Outsider" = ""; + +/* Explorer rank. [stats.py] */ +"Pathfinder" = ""; + +/* Trade rank. [stats.py] */ +"Pedlar" = ""; + +/* Trade rank. [stats.py] */ +"Penniless" = ""; + +/* Federation rank. [stats.py] */ +"Petty Officer" = ""; + +/* Explorer rank. [stats.py] */ +"Pioneer" = ""; + +/* Federation rank. [stats.py] */ +"Post Captain" = ""; + +/* Federation rank. [stats.py] */ +"Post Commander" = ""; + +/* Ranking. [stats.py] */ +"Powerplay" = ""; + +/* Empire rank. [stats.py] */ +"Prince" = ""; + +/* CQC rank. [stats.py] */ +"Professional" = ""; + +/* Explorer rank. [stats.py] */ +"Ranger" = ""; + +/* Power rank. [stats.py] */ +"Rating 1" = ""; + +/* Power rank. [stats.py] */ +"Rating 2" = ""; + +/* Power rank. [stats.py] */ +"Rating 3" = ""; + +/* Power rank. [stats.py] */ +"Rating 4" = ""; + +/* Power rank. [stats.py] */ +"Rating 5" = ""; + +/* Status bar message on launch. [EDMarketConnector.py] */ +"Re-start Elite: Dangerous for automatic log entries" = ""; + +/* Federation rank. [stats.py] */ +"Rear Admiral" = ""; + +/* Federation rank. [stats.py] */ +"Recruit" = ""; + +/* Explorer rank. [stats.py] */ +"Scout" = ""; + +/* CQC rank. [stats.py] */ +"Semi Professional" = ""; + +/* Empire rank. [stats.py] */ +"Serf" = ""; + +/* Status dialog subtitle. [stats.py] */ +"Ship" = "Statek"; + +/* Status dialog title. [stats.py] */ +"Ships" = "Statki"; + +/* Empire rank. [stats.py] */ +"Squire" = ""; + +/* Menu item. [EDMarketConnector.py] */ +"Status" = "Status"; + +/* Explorer rank. [stats.py] */ +"Surveyor" = ""; + +/* Ranking. [stats.py] */ +"Trade" = ""; + +/* Explorer rank. [stats.py] */ +"Trailblazer" = ""; + +/* Trade rank. [stats.py] */ +"Tycoon" = ""; + +/* Federation rank. [stats.py] */ +"Vice Admiral" = ""; + +/* Menu title on OSX. [EDMarketConnector.py] */ +"View" = "Widok"; + +/* Empire rank. [stats.py] */ +"Viscount" = ""; + +/* Federation rank. [stats.py] */ +"Warrant Officer" = ""; diff --git a/README.md b/README.md index ac5cfe2e..539ebf1f 100644 --- a/README.md +++ b/README.md @@ -106,8 +106,8 @@ Linux: Command-line -------- -The command-line program `EDMC.py` writes the current system and station (if docked) to stdout and optionally -writes ship loadout and/or station data to file. This program requires that the user has performed [setup](#setup) and verification through the app. +The command-line program `EDMC.py` writes the current system and station (if docked) to stdout and optionally writes player status, ship locations, ship loadout and/or station data to file. +This program requires that the user has performed [setup](#setup) and verification through the app. Arguments: @@ -116,9 +116,11 @@ Arguments: -v, --version print program version and exit -c FILE write ship loadout to FILE in Coriolis json format -e FILE write ship loadout to FILE in E:D Shipyard format + -l FILE write ship locations to FILE in CSV format -m FILE write station commodity market data to FILE in CSV format -o FILE write station outfitting data to FILE in CSV format -s FILE write station shipyard data to FILE in CSV format + -t FILE write player status to FILE in CSV format ``` The program returns one of the following exit codes. Further information may be written to stderr. diff --git a/l10n.py b/l10n.py index b0fec932..41a03dcd 100755 --- a/l10n.py +++ b/l10n.py @@ -52,7 +52,7 @@ class Translations: match = regexp.match(line) if match: self.translations[match.group(1)] = match.group(2).replace(u'{CR}', u'\n') - elif not comment.match(line): + elif __debug__ and not comment.match(line): print 'Bad translation: %s' % line.strip() __builtin__.__dict__['_'] = self.translate diff --git a/prefs.py b/prefs.py index d25653c8..76507dc0 100644 --- a/prefs.py +++ b/prefs.py @@ -167,7 +167,7 @@ class PreferencesDialog(tk.Toplevel): ttk.Button(hotkeyframe, text = _('Open System Preferences'), command = self.enableshortcuts).grid(row=1, column=1, padx=5, pady=(0,5), sticky=tk.E) # Shortcut settings button on OSX else: self.hotkey_text = ttk.Entry(hotkeyframe, width = (platform == 'darwin' and 20 or 30), justify=tk.CENTER) - self.hotkey_text.insert(0, self.hotkey_code and hotkeymgr.display(self.hotkey_code, self.hotkey_mods) or _('none')) # No hotkey/shortcut currently defined + self.hotkey_text.insert(0, self.hotkey_code and hotkeymgr.display(self.hotkey_code, self.hotkey_mods) or _('None')) # No hotkey/shortcut currently defined self.hotkey_text.bind('', self.hotkeystart) self.hotkey_text.bind('', self.hotkeyend) self.hotkey_text.grid(row=0, padx=5, pady=5, sticky=tk.NSEW) @@ -277,7 +277,7 @@ class PreferencesDialog(tk.Toplevel): event.widget.unbind('') hotkeymgr.acquire_stop() # in case focus was lost while in the middle of acquiring event.widget.delete(0, tk.END) - self.hotkey_text.insert(0, self.hotkey_code and hotkeymgr.display(self.hotkey_code, self.hotkey_mods) or _('none')) # No hotkey/shortcut currently defined + self.hotkey_text.insert(0, self.hotkey_code and hotkeymgr.display(self.hotkey_code, self.hotkey_mods) or _('None')) # No hotkey/shortcut currently defined def hotkeylisten(self, event): good = hotkeymgr.fromevent(event) @@ -300,7 +300,7 @@ class PreferencesDialog(tk.Toplevel): self.hotkey_only_btn['state'] = tk.NORMAL self.hotkey_play_btn['state'] = tk.NORMAL else: - event.widget.insert(0, _('none')) # No hotkey/shortcut currently defined + event.widget.insert(0, _('None')) # No hotkey/shortcut currently defined self.hotkey_only_btn['state'] = tk.DISABLED self.hotkey_play_btn['state'] = tk.DISABLED self.hotkey_only_btn.focus() # move to next widget - calls hotkeyend() implicitly diff --git a/stats.py b/stats.py new file mode 100644 index 00000000..b5f1a6a3 --- /dev/null +++ b/stats.py @@ -0,0 +1,337 @@ +from collections import OrderedDict +from sys import platform +import time +if __debug__: + from traceback import print_exc + +import Tkinter as tk +import ttk + +import companion +import prefs +from shipyard import ship_map + + +# Hack to fix notebook page background. Doesn't seem possible to do this with styles. +if platform == 'darwin': + from platform import mac_ver + PAGEFG = 'systemButtonText' + PAGEBG = map(int, mac_ver()[0].split('.')) >= [10,10] and '#dbdbdb' or '#dfdfdf' # want e2 or e5 on screen +elif platform == 'win32': + PAGEFG = 'SystemWindowText' + PAGEBG = 'SystemWindow' # typically white + +RANKS = [ # in output order + (_('Combat') , 'combat'), # Ranking + (_('Trade') , 'trade'), # Ranking + (_('Explorer') , 'explore'), # Ranking + (_('CQC') , 'cqc'), # Ranking + (_('Federation') , 'federation'), # Ranking + (_('Empire') , 'empire'), # Ranking + (_('Powerplay') , 'power'), # Ranking + # ??? , 'crime'), # Ranking + # ??? , 'service'), # Ranking +] + +RANK_NAMES = { + + # http://elite-dangerous.wikia.com/wiki/Pilots_Federation#Ranks + 'combat' : [_('Harmless'), # Combat rank + _('Mostly Harmless'), # Combat rank + _('Novice'), # Combat rank + _('Competent'), # Combat rank + _('Expert'), # Combat rank + _('Master'), # Combat rank + _('Dangerous'), # Combat rank + _('Deadly'), # Combat rank + _('Elite')], # Top rank + 'trade' : [_('Penniless'), # Trade rank + _('Mostly Penniless'), # Trade rank + _('Pedlar'), # Trade rank + _('Dealer'), # Trade rank + _('Merchant'), # Trade rank + _('Broker'), # Trade rank + _('Entrepreneur'), # Trade rank + _('Tycoon'), # Trade rank + _('Elite')], # Top rank + 'explore' : [_('Aimless'), # Explorer rank + _('Mostly Aimless'), # Explorer rank + _('Scout'), # Explorer rank + _('Surveyor'), # Explorer rank + _('Trailblazer'), # Explorer rank + _('Pathfinder'), # Explorer rank + _('Ranger'), # Explorer rank + _('Pioneer'), # Explorer rank + _('Elite')], # Top rank + 'cqc' : [_('Helpless'), # CQC rank + _('Mostly Helpless'), # CQC rank + _('Amateur'), # CQC rank + _('Semi Professional'), # CQC rank + _('Professional'), # CQC rank + _('Champion'), # CQC rank + _('Hero'), # CQC rank + _('Gladiator'), # CQC rank + _('Elite')], # Top rank + + # http://elite-dangerous.wikia.com/wiki/Federation#Ranks + 'federation' : [_('None'), # No rank + _('Recruit'), # Federation rank + _('Cadet'), # Federation rank + _('Midshipman'), # Federation rank + _('Petty Officer'), # Federation rank + _('Chief Petty Officer'), # Federation rank + _('Warrant Officer'), # Federation rank + _('Ensign'), # Federation rank + _('Lieutenant'), # Federation rank + _('Lieutenant Commander'), # Federation rank + _('Post Commander'), # Federation rank + _('Post Captain'), # Federation rank + _('Rear Admiral'), # Federation rank + _('Vice Admiral'), # Federation rank + _('Admiral')], # Federation rank + + # http://elite-dangerous.wikia.com/wiki/Empire#Ranks + 'empire' : [_('None'), # No rank + _('Outsider'), # Empire rank + _('Serf'), # Empire rank + _('Master'), # Empire rank + _('Squire'), # Empire rank + _('Knight'), # Empire rank + _('Lord'), # Empire rank + _('Baron'), # Empire rank + _('Viscount'), # Empire rank + _('Count'), # Empire rank + _('Earl'), # Empire rank + _('Marquis'), # Empire rank + _('Duke'), # Empire rank + _('Prince'), # Empire rank + _('King')], # Empire rank + + # http://elite-dangerous.wikia.com/wiki/Ratings + 'power' : [_('None'), # No rank + _('Rating 1'), # Power rank + _('Rating 2'), # Power rank + _('Rating 3'), # Power rank + _('Rating 4'), # Power rank + _('Rating 5')], # Power rank +} + + +def status(data): + + # StatsResults assumes these three things are first + res = [ [_('Cmdr'), data['commander']['name']], + [_('Balance'), str(data['commander'].get('credits', 0))], # Cmdr stats + [_('Loan'), str(data['commander'].get('debt', 0))], # Cmdr stats + ] + + ranks = data['commander'].get('rank', {}) + for title, thing in RANKS: + rank = ranks.get(thing) + names = RANK_NAMES[thing] + if isinstance(rank, int): + res.append([title, rank < len(names) and names[rank] or ('Rank %d' % rank)]) + else: + res.append([title, _('None')]) # No rank + + return res + + +def export_status(data, filename): + h = open(filename, 'wt') + h.write('Category,Value\n') + for thing in status(data): + h.write(','.join(thing) + '\n') + h.close() + + +def ships(data): + + ships = companion.listify(data.get('ships')) + current = data['commander'].get('currentShipId') + + if isinstance(current, int) and ships[current]: + ships.insert(0, ships.pop(current)) # Put current ship first + + if not data['commander'].get('docked'): + # Set current system, not last docked + return [ [ship_map.get(ships[0]['name'].lower(), ships[0]['name']), data['lastSystem']['name'], ''] ] + [ [ship_map.get(ship['name'].lower(), ship['name']), ship['starsystem']['name'], ship['station']['name']] for ship in ships[1:] if ship] + + return [ [ship_map.get(ship['name'].lower(), ship['name']), ship['starsystem']['name'], ship['station']['name']] for ship in ships if ship] + +def export_ships(data, filename): + h = open(filename, 'wt') + h.write('Ship,System,Station\n') + for thing in ships(data): + h.write(','.join(thing) + '\n') + h.close() + + +class StatsDialog(tk.Toplevel): + + def __init__(self, parent, session): + tk.Toplevel.__init__(self, parent) + + self.parent = parent + self.session = session + self.title('Statistics') + + if parent.winfo_viewable(): + self.transient(parent) + + # position over parent + if platform!='darwin' or parent.winfo_rooty()>0: # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 + self.geometry("+%d+%d" % (parent.winfo_rootx(), parent.winfo_rooty())) + + # remove decoration + self.resizable(tk.FALSE, tk.FALSE) + if platform=='win32': + self.attributes('-toolwindow', tk.TRUE) + elif platform=='darwin': + # http://wiki.tcl.tk/13428 + parent.call('tk::unsupported::MacWindowStyle', 'style', self, 'utility') + + frame = ttk.Frame(self) + frame.grid(sticky=tk.NSEW) + + self.status = ttk.Label(frame, text=_('Fetching data...')) + self.status.grid(padx=10, pady=10) + + # wait for window to appear on screen before calling grab_set + self.wait_visibility() + self.grab_set() + self.update() # update_idletasks() isn't cutting it + + self.showstats() + + # callback after verification code + def verify(self, code): + try: + self.session.verify(code) + except Exception as e: + if __debug__: print_exc() + self.status['text'] = unicode(e) + else: + self.showstats() + + def showstats(self): + try: + data = self.session.query() + except companion.VerificationRequired: + return prefs.AuthenticationDialog(self.parent, self.verify) + except companion.ServerError as e: + self.status['text'] = str(e) + return + except Exception as e: + if __debug__: print_exc() + self.status['text'] = str(e) + return + + if not data.get('commander') or not data['commander'].get('name','').strip(): + self.status['text'] = _("Who are you?!") # Shouldn't happen + elif not data.get('lastSystem') or not data['lastSystem'].get('name','').strip() or not data.get('lastStarport') or not data['lastStarport'].get('name','').strip(): + self.status['text'] = _("Where are you?!") # Shouldn't happen + elif not data.get('ship') or not data['ship'].get('modules') or not data['ship'].get('name','').strip(): + self.status['text'] = _("What are you flying?!") # Shouldn't happen + else: + StatsResults(self.parent, data) + self.destroy() + + +class StatsResults(tk.Toplevel): + + def __init__(self, parent, data): + tk.Toplevel.__init__(self, parent) + + self.parent = parent + + stats = status(data) + self.title(' '.join(stats[0])) # assumes first thing is player name + + if parent.winfo_viewable(): + self.transient(parent) + + # position over parent + if platform!='darwin' or parent.winfo_rooty()>0: # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 + self.geometry("+%d+%d" % (parent.winfo_rootx(), parent.winfo_rooty())) + + # remove decoration + self.resizable(tk.FALSE, tk.FALSE) + if platform=='win32': + self.attributes('-toolwindow', tk.TRUE) + elif platform=='darwin': + # http://wiki.tcl.tk/13428 + parent.call('tk::unsupported::MacWindowStyle', 'style', self, 'utility') + if map(int, mac_ver()[0].split('.')) >= [10,10]: + # Hack for tab appearance with 8.5 on Yosemite. For proper fix see + # https://github.com/tcltk/tk/commit/55c4dfca9353bbd69bbcec5d63bf1c8dfb461e25 + style = ttk.Style().configure('TNotebook.Tab', padding=(12,10,12,2)) + + frame = ttk.Frame(self) + frame.grid(sticky=tk.NSEW) + + notebook = ttk.Notebook(frame) + if platform!='darwin': + notebook.grid(padx=10, pady=10, sticky=tk.NSEW) + else: + notebook.grid(sticky=tk.NSEW) # Already padded apropriately + + page = self.addpage(notebook) + for thing in stats[1:3]: + self.addpagerow(page, [thing[0], thing[1] + ' CR']) # assumes things two and three are money + for thing in stats[3:]: + self.addpagerow(page, thing) + notebook.add(page, text=_('Status')) # Status dialog title + + page = self.addpage(notebook, [_('Ship'), # Status dialog subtitle + _('System'), # Status dialog subtitle + _('Station')], align=tk.W) # Status dialog subtitle + shiplist = ships(data) + for thing in shiplist: + self.addpagerow(page, thing, align=tk.W) + notebook.add(page, text=_('Ships')) # Status dialog title + + if platform!='darwin': + buttonframe = ttk.Frame(frame) + buttonframe.grid(padx=10, pady=(0,10), sticky=tk.NSEW) + buttonframe.columnconfigure(0, weight=1) + ttk.Label(buttonframe).grid(row=0, column=0) # spacer + ttk.Button(buttonframe, text='OK', command=self.destroy).grid(row=0, column=1, sticky=tk.E) + + # wait for window to appear on screen before calling grab_set + self.wait_visibility() + self.grab_set() + + def addpage(self, parent, content=[], align=tk.E): + if platform in ['darwin', 'win32']: + page = tk.Frame(parent, bg=PAGEBG) + else: + page =ttk.Frame(parent) + page.grid(pady=10, sticky=tk.NSEW) + page.columnconfigure(0, weight=1) + if content: + self.addpageheader(page, content, align=align) + return page + + def addpageheader(self, parent, content, align=tk.E): + #if parent.grid_size()[1]: # frame not empty - add spacer + # self.addpagerow(parent, ['']) + self.addpagerow(parent, content, align=align) + ttk.Separator(parent, orient=tk.HORIZONTAL).grid(columnspan=3, padx=10, pady=2, sticky=tk.EW) + + def addpagespacer(self, parent): + self.addpagerow(parent, ['']) + + def addpagerow(self, parent, content, align=tk.E): + for i in range(len(content)): + if platform in ['darwin', 'win32']: + label = tk.Label(parent, text=content[i], fg=PAGEFG, bg=PAGEBG, highlightbackground=PAGEBG) + else: + label =ttk.Label(parent, text=content[i]) + if i == 0: + label.grid(padx=10, sticky=tk.W) + row = parent.grid_size()[1]-1 + elif i == 2: + label.grid(row=row, column=i, padx=10, sticky=align) + else: + label.grid(row=row, column=i, padx=10, sticky=align, columnspan=4-len(content))