def system_change(self, event): if not monitor.last_event: if __debug__: print 'spurious system_change', event # eh? return timestamp, system = monitor.last_event # would like to use event user_data to carry this, but not accessible in Tkinter if self.system['text'] != system: self.system['text'] = system self.system['image'] = '' self.station['text'] = EDDB.system(system) and self.STATION_UNDOCKED or '' if config.getint('output') & config.OUT_LOG_FILE: flightlog.writelog(timestamp, system) if config.getint('output') & config.OUT_LOG_EDSM: try: self.status['text'] = _('Sending data to EDSM...') self.w.update_idletasks() edsm.writelog(timestamp, system, lambda:self.edsm.lookup(system, EDDB.system(system))) # Do EDSM lookup during EDSM export self.status['text'] = strftime(_('Last updated at {HH}:{MM}:{SS}').format(HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(timestamp)).decode('utf-8') except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) if not config.getint('hotkey_mute'): hotkeymgr.play_bad() else: self.edsm.link(system) self.status['text'] = strftime(_('Last updated at {HH}:{MM}:{SS}').format(HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(timestamp)).decode('utf-8') self.edsmpoll()
def system_change(self, timestamp, system): if self.system['text'] != system: self.system['text'] = system self.system['image'] = '' self.station['text'] = EDDB.system(system) and self.STATION_UNDOCKED or '' plug.notify_system_changed(timestamp, system) if config.getint('output') & config.OUT_LOG_FILE: flightlog.writelog(timestamp, system) if config.getint('output') & config.OUT_LOG_EDSM: try: self.status['text'] = _('Sending data to EDSM...') self.w.update_idletasks() edsm.writelog(timestamp, system, lambda:self.edsm.lookup(system, EDDB.system(system))) # Do EDSM lookup during EDSM export self.status['text'] = strftime(_('Last updated at {HH}:{MM}:{SS}').format(HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(timestamp)).decode('utf-8') except Exception as e: if __debug__: print_exc() self.status['text'] = unicode(e) if not config.getint('hotkey_mute'): hotkeymgr.play_bad() else: self.edsm.link(system) self.status['text'] = strftime(_('Last updated at {HH}:{MM}:{SS}').format(HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(timestamp)).decode('utf-8') self.edsmpoll()
def __init__(self, slicedModel): self.slicedModel = slicedModel self.isExtrusionActive = False self.layerIndex = 0 self.layerLines = [] self.lineIndex = 0 self.lines = None self.oldLocation = None self.rowIndex = 0 self.shouldAccumulate = True self.centerX = config.getfloat(name, 'center.x') self.centerY = config.getfloat(name, 'center.y') self.numberOfColumns = config.getint(name, 'columns') self.numberOfRows = config.getint(name, 'rows') self.reverseSequenceEveryOddLayer = config.getboolean(name, 'sequence.reverse.odd.layers') self.separationOverPerimeterWidth = config.getfloat(name, 'separation.over.perimeter.width') self.extrusionWidth = config.getfloat('carve', 'extrusion.width') self.centerOffset = complex(self.centerX, self.centerY) cornerMaximumComplex = self.slicedModel.carvingCornerMaximum.dropAxis() cornerMinimumComplex = self.slicedModel.carvingCornerMinimum.dropAxis() self.extent = cornerMaximumComplex - cornerMinimumComplex self.shapeCenter = 0.5 * (cornerMaximumComplex + cornerMinimumComplex) self.separation = self.separationOverPerimeterWidth * abs(self.extrusionWidth) self.extentPlusSeparation = self.extent + complex(self.separation, self.separation) columnsMinusOne = self.numberOfColumns - 1 rowsMinusOne = self.numberOfRows - 1 self.arrayExtent = complex(self.extentPlusSeparation.real * columnsMinusOne, self.extentPlusSeparation.imag * rowsMinusOne) self.arrayCenter = 0.5 * self.arrayExtent
def export(data, csv=False): querytime = config.getint('querytime') or int(time.time()) filename = join(config.get('outdir'), '%s.%s.%s.%s' % (data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip(), time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)), csv and 'csv' or 'bpc')) timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime)) header = 'System;Station;Commodity;Sell;Buy;Demand;;Supply;;Date;\n' rowheader = '%s;%s' % (data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip()) if not csv: # bpc header = 'userID;' + header cmdr = data['commander']['name'].strip() rowheader = '%s;%s' % (config.getint('anonymous') and hashlib.md5(cmdr.encode('utf-8')).hexdigest() or cmdr.replace(';',':'), rowheader) h = open(filename, 'wt') # codecs can't automatically handle line endings, so encode manually where required h.write(header) for commodity in data['lastStarport']['commodities']: h.write(('%s;%s;%s;%s;%s;%s;%s;%s;%s;\n' % ( rowheader, commodity['name'], commodity['sellPrice'] or '', commodity['buyPrice'] or '', int(commodity['demand']) if commodity['demandBracket'] else '', bracketmap[commodity['demandBracket']], int(commodity['stock']) if commodity['stockBracket'] else '', bracketmap[commodity['stockBracket']], timestamp)).encode('utf-8')) h.close()
def _destroy(self): # Re-enable hotkey and log monitoring before exit hotkeymgr.register(self.parent, config.getint('hotkey_code'), config.getint('hotkey_mods')) if (config.getint('output') & config.OUT_LOG_AUTO) and (config.getint('output') & (config.OUT_LOG_AUTO|config.OUT_LOG_EDSM)): monitor.enable_logging() monitor.start(self.parent) else: monitor.stop() self.destroy()
def update_render_color(self, obj, selection, option, value): color_option = [ "inactive_color_upper", " inactive_color_middle", "inactive_color_bottom", "active_color_upper", "active_color_middle", "active_color_bottom", ] if selection == "lyrics" and option in color_option: self.update_font() if selection == "lyrics" and option == "status": status = config.getboolean("lyrics", "status") if not status: if self.time_source != 0: gobject.source_remove(self.time_source) else: lrc_mode = config.getint("lyrics", "mode") if lrc_mode == 1: self.time_source = gobject.timeout_add(200, self.check_mouse_leave) if selection == "lyrics" and option == "mode": lrc_mode = config.getint("lyrics", "mode") if lrc_mode != 1: if self.time_source != 0: gobject.source_remove(self.time_source) else: status = config.getboolean("lyrics", "status") if status: self.time_source = gobject.timeout_add(200, self.check_mouse_leave) if selection == "lyrics" and option == "font_name": self.set_font_name(value) if selection == "lyrics" and option == "font_size": self.set_font_size(int(value)) if selection == "lyrics" and option == "font_type": self.set_font_type(value) if selection == "lyrics" and option == "line_count": if value == "1": self.line_alignment = LINE_ALIGNMENT[config.get("lyrics", "single_line_align")] elif value == "2": self.line_alignment = LINE_ALIGNMENT[config.get("lyrics", "double_line_align")] self.line_count = int(value) self.update_font() if selection == "lyrics" and option in ["single_line_align", "double_line_align"]: self.line_alignment = LINE_ALIGNMENT[config.get("lyrics", option)] self.update_font() if selection == "lyrics" and option in ["outline_width", "blur_color"]: self.update_font()
def __init__(self, slicedModel): 'Initialize' self.slicedModel = slicedModel self.layerHeight = config.getfloat(name, 'layer.height') self.extrusionWidth = config.getfloat(name, 'extrusion.width') self.infillBridgeDirection = config.getboolean(name, 'infill.bridge.direction') self.importCoarsenessRatio = config.getfloat(name, 'import.coarseness.ratio') self.correctMesh = config.getboolean(name, 'mesh.correct') self.decimalPlaces = config.getint('general', 'decimal.places') self.layerPrintFrom = config.getint(name, 'layer.print.from') self.layerPrintTo = config.getint(name, 'layer.print.to')
def show_scroll_lyrics(self): if config.get("lyrics", "scroll_x") != "-1": x = config.getint("lyrics", "scroll_x") y = config.getint("lyrics", "scroll_y") self.scroll_lyrics.move(int(x), int(y)) try: w = config.getint("lyrics", "scroll_w") h = config.getint("lyrics", "scroll_h") self.scroll_lyrics.resize(int(w), int(h)) except: pass self.scroll_lyrics.show_all()
def _destroy(self): # Re-enable hotkey and log monitoring before exit hotkeymgr.register(self.parent, config.getint('hotkey_code'), config.getint('hotkey_mods')) if (config.getint('output') & config.OUT_LOG_AUTO) and (config.getint('output') & (config.OUT_LOG_FILE|config.OUT_LOG_EDSM)): monitor.enable_logging() monitor.start(self.parent) edproxy.start(self.parent) else: monitor.stop() edproxy.stop() self.parent.wm_attributes('-topmost', config.getint('always_ontop') and 1 or 0) self.destroy()
def show_scroll_lyrics(self): if config.get("lyrics", "scroll_x") != "-1": x = config.getint("lyrics", "scroll_x") y = config.getint("lyrics", "scroll_y") self.scroll_lyrics.move(int(x), int(y)) try: w = config.getint("lyrics", "scroll_w") h = config.getint("lyrics", "scroll_h") self.scroll_lyrics.resize(int(w), int(h)) except: pass if not self.__find_flag: self.update_lrc(None, Player.song) self.scroll_lyrics.show_all()
def export(data, callback): callback('Sending data to EDDN...') querytime = config.getint('querytime') or int(time.time()) header = { 'softwareName': '%s [%s]' % (applongname, platform=='darwin' and "Mac OS" or system()), 'softwareVersion': appversion, 'uploaderID': config.getint('anonymous') and hashlib.md5(data['commander']['name'].strip().encode('utf-8')).hexdigest() or data['commander']['name'].strip(), } systemName = data['lastSystem']['name'].strip() stationName = data['lastStarport']['name'].strip() timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(querytime)) # route all requests through a session in the hope of using keep-alive session = requests.Session() session.headers['connection'] = 'keep-alive' # can help through a proxy? commodities = data['lastStarport']['commodities'] i=0 for commodity in commodities: i = i+1 callback('Sending %d/%d' % (i, len(commodities))) data = { '$schemaRef': schema, 'header': header, 'message': { 'systemName': systemName, 'stationName': stationName, 'itemName': commodity['name'], 'buyPrice': commodity['buyPrice'], 'stationStock': int(commodity['stock']), 'sellPrice': commodity['sellPrice'], 'demand': int(commodity['demand']), 'timestamp': timestamp, } } if commodity['stockBracket']: data['message']['supplyLevel'] = bracketmap[commodity['stockBracket']] if commodity['demandBracket']: data['message']['demandLevel'] = bracketmap[commodity['demandBracket']] r = session.post(upload, data=json.dumps(data)) if __debug__ and r.status_code != requests.codes.ok: print 'Status\t%s' % r.status_code print 'URL\t%s' % r.url print 'Headers\t%s' % r.headers print ('Content:\n%s' % r.text).encode('utf-8') r.raise_for_status() session.close()
def send(cmdr, msg): msg['header'] = { 'softwareName' : '%s [%s]' % (applongname, platform=='darwin' and "Mac OS" or system()), 'softwareVersion' : appversion, 'uploaderID' : config.getint('anonymous') and hashlib.md5(cmdr.encode('utf-8')).hexdigest() or cmdr.encode('utf-8'), } msg['message']['timestamp'] = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(config.getint('querytime') or int(time.time()))) r = requests.post(upload, json=msg, timeout=timeout) if __debug__ and r.status_code != requests.codes.ok: print 'Status\t%s' % r.status_code print 'URL\t%s' % r.url print 'Headers\t%s' % r.headers print ('Content:\n%s' % r.text).encode('utf-8') r.raise_for_status()
def __init__(self, name): self.name = name self.socket = socket.socket() self.socket.connect((config.get('server', 'listen_host'), config.getint('server', 'listen_port'))) self.socket.setblocking(0) self.socket_file = self.socket.makefile() self.responses = []
def send_welcome_email(self, first_name, activation_url): email_vars = { 'name': first_name, 'activation_days': config.getint('nemesis', 'activation_days'), 'activation_url': activation_url } mailer.email_template(self.email, 'new_user', email_vars)
def _acquireCpuLockWithTimeout(self): timeout = self._loadCorrectedTimeout(config.getint("vars", "vm_command_timeout")) end = time.time() + timeout while not self._guestCpuLock.acquire(False): time.sleep(0.1) if time.time() > end: raise RuntimeError("waiting more that %ss for _guestCpuLock" % timeout)
def shutdown(self, timeout, message): try: now = time.time() if self.lastStatus == "Down": return if self.guestAgent and self.guestAgent.isResponsive(): self._guestEventTime = now self._guestEvent = "Powering down" self.log.debug("guestAgent shutdown called") self.guestAgent.desktopShutdown(timeout, message) agent_timeout = int(timeout) + config.getint("vars", "sys_shutdown_timeout") timer = threading.Timer(agent_timeout, self._timedShutdown) timer.start() elif self.conf["acpiEnable"].lower() == "true": self._guestEventTime = now self._guestEvent = "Powering down" self._acpiShutdown() # No tools, no ACPI else: return { "status": { "code": errCode["exist"]["status"]["code"], "message": "VM without ACPI or active SolidICE tools. Try Forced Shutdown.", } } except: self.log.error(traceback.format_exc()) return {"status": {"code": doneCode["code"], "message": "Machine shut down"}}
def _lvExtend(self, block_dev, newsize=None): for d in self._drives: if not d.blockDev: continue if d.name != block_dev: continue if newsize is None: newsize = config.getint("irs", "volume_utilization_chunk_mb") + (d.apparentsize + 2 ** 20 - 1) / 2 ** 20 # TODO cap newsize by max volume size volDict = {"poolID": d.poolID, "domainID": d.domainID, "imageID": d.imageID, "volumeID": d.volumeID} d.needExtend = True d.reqsize = newsize # sendExtendMsg expects size in bytes self.cif.irs.hsm.sendExtendMsg(d.poolID, volDict, newsize * 2 ** 20, self._afterLvExtend) self.log.debug( "%s/%s (%s): apparentsize %s req %s", d.domainID, d.volumeID, d.name, d.apparentsize / constants.MEGAB, newsize, ) # in MiB # store most recently requested size in conf, to be re-requested on # migration destination for drive in self.conf.get("drives", []): if drive.get("volumeID") == d.volumeID: drive["reqsize"] = str(d.reqsize)
def writelog(timestamp, system, edsmlookupfn): try: # Look up the system before adding it to the log, since adding it to the log has the side-effect of creating it edsmlookupfn() r = requests.get( "http://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")), urllib.quote(config.get("edsm_apikey")), urllib.quote(system), 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() reply = r.json() (msgnum, msg) = reply["msgnum"], reply["msg"] except: if __debug__: print_exc() raise Exception(_("Error: Can't connect to EDSM")) # 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()
def __init__(self, slicedModel): self.slicedModel = slicedModel self.additionalHeightRatio = config.getfloat(name, "additional.height.ratio") self.altitude = config.getfloat(name, "altitude") self.layerHeight = config.getfloat("carve", "layer.height") self.perimeterWidth = config.getfloat("carve", "extrusion.width") self.decimalPlaces = config.getint("general", "decimal.places")
def login(self): self.status['text'] = _('Logging in...') self.button['state'] = tk.DISABLED 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'] = '' except companion.VerificationRequired: # don't worry about authentication now - prompt on query self.status['text'] = '' except companion.ServerError as e: self.status['text'] = unicode(e) except Exception as e: 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 elif not getattr(sys, 'frozen', False): self.updater.checkForUpdates() # Sparkle / WinSparkle does this automatically for packaged apps self.cooldown()
def login(self): self.status['text'] = 'Logging in...' self.button['state'] = tk.DISABLED self.w.update_idletasks() try: self.session.login(config.get('username'), config.get('password')) self.status['text'] = '' # Try to obtain exclusive lock on flight log ASAP if config.getint('output') & config.OUT_LOG: try: flightlog.openlog() except Exception as e: if __debug__: print_exc() self.status['text'] = str(e) except companion.VerificationRequired: # don't worry about authentication now - prompt on query self.status['text'] = '' except companion.ServerError as e: self.status['text'] = str(e) except Exception as e: if __debug__: print_exc() self.status['text'] = str(e) self.cooldown()
def worker(self, keycode, modifiers): # Hotkey must be registered by the thread that handles it if not RegisterHotKey(None, 1, modifiers|MOD_NOREPEAT, keycode): self.thread = None return fake = INPUT(INPUT_KEYBOARD, INPUT_union(ki = KEYBDINPUT(keycode, keycode, 0, 0, None))) msg = MSG() while GetMessage(ctypes.byref(msg), None, 0, 0) != 0: if msg.message == WM_HOTKEY: if config.getint('hotkey_always') or WindowTitle(GetForegroundWindow()).startswith('Elite - Dangerous'): self.root.event_generate('<<Invoke>>', when="tail") else: # Pass the key on UnregisterHotKey(None, 1) SendInput(1, fake, ctypes.sizeof(INPUT)) if not RegisterHotKey(None, 1, modifiers|MOD_NOREPEAT, keycode): break elif msg.message == WM_SND_GOOD: winsound.PlaySound(self.snd_good, winsound.SND_MEMORY) # synchronous elif msg.message == WM_SND_BAD: winsound.PlaySound(self.snd_bad, winsound.SND_MEMORY) # synchronous else: TranslateMessage(ctypes.byref(msg)) DispatchMessage(ctypes.byref(msg)) UnregisterHotKey(None, 1) self.thread = None
def worker(self, keycode, modifiers): # Hotkey must be registered by the thread that handles it if not RegisterHotKey(None, 1, modifiers|MOD_NOREPEAT, keycode): self.thread = None return msg = MSG() while GetMessage(ctypes.byref(msg), None, 0, 0) != 0: if msg.message == WM_HOTKEY: if config.getint('hotkey_always'): self.root.event_generate('<<Invoke>>', when="tail") else: # Only trigger if game client is front process h = GetForegroundWindow() if h: l = GetWindowTextLength(h) + 1 buf = ctypes.create_unicode_buffer(l) if GetWindowText(h, buf, l) and buf.value.startswith('Elite - Dangerous'): self.root.event_generate('<<Invoke>>', when="tail") elif msg.message == WM_SND_GOOD: winsound.PlaySound(self.snd_good, winsound.SND_MEMORY) # synchronous elif msg.message == WM_SND_BAD: winsound.PlaySound(self.snd_bad, winsound.SND_MEMORY) # synchronous else: TranslateMessage(ctypes.byref(msg)) DispatchMessage(ctypes.byref(msg)) UnregisterHotKey(None, 1) self.thread = None
def export(data, csv=False): querytime = config.getint('querytime') or int(time.time()) filename = join(config.get('outdir'), '%s.%s.%s.%s' % (data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip(), time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)), csv and 'csv' or 'bpc')) timestamp = time.strftime('%Y-%m-%dT%H:%M:%S', time.gmtime(querytime)) if csv: header = 'System;Station;Commodity;Sell;Buy;Demand;;Supply;;Date;\n' rowheader = '%s;%s' % (data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip()) else: # bpc header = 'userID;System;Station;Commodity;Sell;Buy;Demand;;Supply;;Date;\n' rowheader = '%s;%s;%s' % (data['commander']['name'].replace(';',':').strip(), data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip()) h = open(filename, 'wt') # codecs can't automatically handle line endings, so encode manually where required h.write(header.encode('utf-8')) for commodity in data['lastStarport']['commodities']: if commodity.get('categoryname') and commodity['categoryname'] != 'NonMarketable': h.write('%s;%s;%s;%s;%s;%s;%s;%s;%s;\n' % ( rowheader, commoditymap.get(commodity['name'].strip(), commodity['name'].strip()), commodity.get('sellPrice') and int(commodity['sellPrice']) or '', commodity.get('buyPrice') and int(commodity['buyPrice']) or '', int(commodity['demand']) if commodity.get('demandBracket') else '', bracketmap.get(commodity.get('demandBracket'), ''), int(commodity['stock']) if commodity.get('stockBracket') else '', bracketmap.get(commodity.get('stockBracket'), ''), timestamp)) h.close()
def plugin_start(): # Can't be earlier since can only call PhotoImage after window is created this._IMG_KNOWN = tk.PhotoImage(data = 'R0lGODlhEAAQAMIEAFWjVVWkVWS/ZGfFZ////////////////yH5BAEKAAQALAAAAAAQABAAAAMvSLrc/lAFIUIkYOgNXt5g14Dk0AQlaC1CuglM6w7wgs7rMpvNV4q932VSuRiPjQQAOw==') # green circle this._IMG_UNKNOWN = tk.PhotoImage(data = 'R0lGODlhEAAQAKEDAGVLJ+ddWO5fW////yH5BAEKAAMALAAAAAAQABAAAAItnI+pywYRQBtA2CtVvTwjDgrJFlreEJRXgKSqwB5keQ6vOKq1E+7IE5kIh4kCADs=') # red circle this._IMG_NEW = tk.PhotoImage(data = 'R0lGODlhEAAQAMZwANKVHtWcIteiHuiqLPCuHOS1MN22ZeW7ROG6Zuu9MOy+K/i8Kf/DAuvCVf/FAP3BNf/JCf/KAPHHSv7ESObHdv/MBv/GRv/LGP/QBPXOPvjPQfjQSvbRSP/UGPLSae7Sfv/YNvLXgPbZhP7dU//iI//mAP/jH//kFv7fU//fV//ebv/iTf/iUv/kTf/iZ/vgiP/hc/vgjv/jbfriiPriiv7ka//if//jd//sJP/oT//tHv/mZv/sLf/rRP/oYv/rUv/paP/mhv/sS//oc//lkf/mif/sUf/uPv/qcv/uTv/uUv/vUP/qhP/xP//pm//ua//sf//ubf/wXv/thv/tif/slv/tjf/smf/yYP/ulf/2R//2Sv/xkP/2av/0gP/ylf/2df/0i//0j//0lP/5cP/7a//1p//5gf/7ev/3o//2sf/5mP/6kv/2vP/3y//+jP///////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAQABAAAAePgH+Cg4SFhoJKPIeHYT+LhVppUTiPg2hrUkKPXWdlb2xHJk9jXoNJQDk9TVtkYCUkOy4wNjdGfy1UXGJYOksnPiwgFwwYg0NubWpmX1ArHREOFYUyWVNIVkxXQSoQhyMoNVUpRU5EixkcMzQaGy8xhwsKHiEfBQkSIg+GBAcUCIIBBDSYYGiAAUMALFR6FAgAOw==') this._IMG_ERROR = tk.PhotoImage(data = 'R0lGODlhEAAQAKEBAAAAAP///////////yH5BAEKAAIALAAAAAAQABAAAAIwlBWpeR0AIwwNPRmZuVNJinyWuClhBlZjpm5fqnIAHJPtOd3Hou9mL6NVgj2LplEAADs=') # BBC Mode 5 '?' # Migrate old settings if not config.get('edsm_cmdrs'): if isinstance(config.get('cmdrs'), list) and config.get('edsm_usernames') and config.get('edsm_apikeys'): # Migrate <= 2.34 settings config.set('edsm_cmdrs', config.get('cmdrs')) elif config.get('edsm_cmdrname'): # Migrate <= 2.25 settings. edsm_cmdrs is unknown at this time config.set('edsm_usernames', [config.get('edsm_cmdrname') or '']) config.set('edsm_apikeys', [config.get('edsm_apikey') or '']) config.delete('edsm_cmdrname') config.delete('edsm_apikey') if config.getint('output') & 256: # Migrate <= 2.34 setting config.set('edsm_out', 1) config.delete('edsm_autoopen') config.delete('edsm_historical') this.thread = Thread(target = worker, name = 'EDSM worker') this.thread.daemon = True this.thread.start() return 'EDSM'
def send(self, cmdr, msg): if config.getint('anonymous'): uploaderID = config.get('uploaderID') if not uploaderID: uploaderID = uuid.uuid4().hex config.set('uploaderID', uploaderID) else: uploaderID = cmdr.encode('utf-8') msg = OrderedDict([ ('$schemaRef', msg['$schemaRef']), ('header', OrderedDict([ ('softwareName', '%s [%s]' % (applongname, sys.platform=='darwin' and "Mac OS" or system())), ('softwareVersion', appversion), ('uploaderID', uploaderID), ])), ('message', msg['message']), ]) r = self.session.post(self.UPLOAD, data=json.dumps(msg), timeout=self.TIMEOUT) if __debug__ and r.status_code != requests.codes.ok: print 'Status\t%s' % r.status_code print 'URL\t%s' % r.url print 'Headers\t%s' % r.headers print ('Content:\n%s' % r.text).encode('utf-8') r.raise_for_status()
def export(data): querytime = config.getint('querytime') or int(time.time()) filename = join(config.get('outdir'), '%s.%s.%s.prices' % (data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip(), time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)))) timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(querytime)) # Format described here: https://bitbucket.org/kfsone/tradedangerous/wiki/Price%20Data h = open(filename, 'wt') # codecs can't automatically handle line endings, so encode manually where required h.write(('#! trade.py import -\n# Created by %s %s on %s for Cmdr %s.\n#\n# <item name> <sellCR> <buyCR> <demand> <stock> <timestamp>\n\n@ %s/%s\n' % (applongname, appversion, platform=='darwin' and "Mac OS" or system(), data['commander']['name'].strip(), data['lastSystem']['name'].strip(), data['lastStarport']['name'].strip())).encode('utf-8')) # sort commodities by category bycategory = defaultdict(list) for commodity in data['lastStarport']['commodities']: if commodity.get('categoryname') and commodity.get('categoryname') != 'NonMarketable': bycategory[categorymap.get(commodity['categoryname'], commodity['categoryname'])].append(commodity) for category in sorted(bycategory): h.write(' + %s\n' % category) # corrections to commodity names can change the sort order for commodity in sorted(bycategory[category], key=lambda x:commoditymap.get(x['name'].strip(),x['name'])): h.write(' %-23s %7d %7d %9s%c %8s%c %s\n' % ( commoditymap.get(commodity['name'].strip(), commodity['name'].strip()), commodity.get('sellPrice', 0), commodity.get('buyPrice', 0), int(commodity.get('demand')) if commodity.get('demandBracket') else '', bracketmap.get(commodity.get('demandBracket'), '?')[0], int(commodity.get('stock')) if commodity.get('stockBracket') else '', bracketmap.get(commodity.get('stockBracket'), '-')[0], timestamp)) h.close()
def plugin_prefs(parent, cmdr, is_beta): PADX = 10 BUTTONX = 12 # indent Checkbuttons and Radiobuttons PADY = 2 # close spacing frame = nb.Frame(parent) frame.columnconfigure(1, weight=1) HyperlinkLabel(frame, text='Inara', background=nb.Label().cget('background'), url='https://inara.cz/', underline=True).grid(columnspan=2, padx=PADX, sticky=tk.W) # Don't translate this.log = tk.IntVar(value = config.getint('inara_out') and 1) this.log_button = nb.Checkbutton(frame, text=_('Send flight log and Cmdr status to Inara'), variable=this.log, command=prefsvarchanged) this.log_button.grid(columnspan=2, padx=BUTTONX, pady=(5,0), sticky=tk.W) nb.Label(frame).grid(sticky=tk.W) # big spacer this.label = HyperlinkLabel(frame, text=_('Inara credentials'), background=nb.Label().cget('background'), url='https://inara.cz/settings-api', underline=True) # Section heading in settings this.label.grid(columnspan=2, padx=PADX, sticky=tk.W) this.apikey_label = nb.Label(frame, text=_('API Key')) # EDSM setting this.apikey_label.grid(row=12, padx=PADX, sticky=tk.W) this.apikey = nb.Entry(frame) this.apikey.grid(row=12, column=1, padx=PADX, pady=PADY, sticky=tk.EW) prefs_cmdr_changed(cmdr, is_beta) return frame
def login(self): self.status['text'] = _('Logging in...') self.button['state'] = self.theme_button['state'] = tk.DISABLED self.w.update_idletasks() try: self.session.login(config.get('username'), config.get('password')) self.status['text'] = '' except companion.VerificationRequired: # don't worry about authentication now - prompt on query self.status['text'] = '' except companion.ServerError as e: self.status['text'] = unicode(e) except Exception as e: 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 self.cooldown()
def prefs_changed(cmdr, is_beta): changed = config.getint('inara_out') != this.log.get() config.set('inara_out', this.log.get()) # Override standard URL functions if config.get('system_provider') == 'Inara': this.system_link['url'] = this.system if config.get('station_provider') == 'Inara': this.station_link['url'] = this.station or this.system if cmdr and not is_beta: this.cmdr = cmdr this.FID = None cmdrs = config.get('inara_cmdrs') or [] apikeys = config.get('inara_apikeys') or [] if cmdr in cmdrs: idx = cmdrs.index(cmdr) apikeys.extend([''] * (1 + idx - len(apikeys))) changed |= (apikeys[idx] != this.apikey.get().strip()) apikeys[idx] = this.apikey.get().strip() else: config.set('inara_cmdrs', cmdrs + [cmdr]) changed = True apikeys.append(this.apikey.get().strip()) config.set('inara_apikeys', apikeys) if this.log.get() and changed: this.newuser = True # Send basic info at next Journal event add_event('getCommanderProfile', time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), { 'searchName': cmdr }) call()
def _destroy(self): self.parent.wm_attributes('-topmost', config.getint('always_ontop') and 1 or 0) self.destroy() if self.callback: self.callback(None)
def __init__(self, parent, callback): tk.Toplevel.__init__(self, parent) self.parent = parent self.callback = callback self.title(platform == 'darwin' and _('Preferences') or _('Settings')) 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 if platform == 'win32': self.attributes('-toolwindow', tk.TRUE) elif platform == 'darwin': # http://wiki.tcl.tk/13428 parent.call('tk::unsupported::MacWindowStyle', 'style', self, 'utility') self.resizable(tk.FALSE, tk.FALSE) style = ttk.Style() frame = ttk.Frame(self) frame.grid(sticky=tk.NSEW) notebook = nb.Notebook(frame) PADX = 10 BUTTONX = 12 # indent Checkbuttons and Radiobuttons PADY = 2 # close spacing credframe = nb.Frame(notebook) credframe.columnconfigure(1, weight=1) nb.Label(credframe, text=_('Credentials')).grid( padx=PADX, sticky=tk.W) # Section heading in settings ttk.Separator(credframe, orient=tk.HORIZONTAL).grid(columnspan=2, padx=PADX, pady=PADY, sticky=tk.EW) nb.Label( credframe, text=_('Please log in with your Elite: Dangerous account details') ).grid(padx=PADX, columnspan=2, sticky=tk.W) # Use same text as E:D Launcher's login dialog nb.Label(credframe, text=_('Username (Email)')).grid( row=10, padx=PADX, sticky=tk.W) # Use same text as E:D Launcher's login dialog nb.Label(credframe, text=_('Password')).grid( row=11, padx=PADX, sticky=tk.W) # Use same text as E:D Launcher's login dialog self.username = nb.Entry(credframe) self.username.insert(0, config.get('username') or '') self.username.grid(row=10, column=1, padx=PADX, pady=PADY, sticky=tk.EW) self.username.focus_set() self.password = nb.Entry(credframe, show=u'•') self.password.insert(0, config.get('password') or '') self.password.grid(row=11, column=1, padx=PADX, pady=PADY, sticky=tk.EW) nb.Label(credframe).grid(sticky=tk.W) # big spacer nb.Label(credframe, text=_('Privacy')).grid( padx=PADX, sticky=tk.W) # Section heading in settings ttk.Separator(credframe, orient=tk.HORIZONTAL).grid(columnspan=2, padx=PADX, pady=PADY, sticky=tk.EW) self.out_anon = tk.IntVar(value=config.getint('anonymous') and 1) nb.Label( credframe, text=_('How do you want to be identified in the saved data')).grid( columnspan=2, padx=PADX, sticky=tk.W) nb.Radiobutton(credframe, text=_('Cmdr name'), variable=self.out_anon, value=0).grid(columnspan=2, padx=BUTTONX, sticky=tk.W) # Privacy setting nb.Radiobutton(credframe, text=_('Pseudo-anonymized ID'), variable=self.out_anon, value=1).grid(columnspan=2, padx=BUTTONX, sticky=tk.W) # Privacy setting notebook.add(credframe, text=_('Identity')) # Tab heading in settings outframe = nb.Frame(notebook) outframe.columnconfigure(0, weight=1) output = config.getint('output') or ( config.OUT_MKT_EDDN | config.OUT_SYS_EDDN | config.OUT_SHIP ) # default settings nb.Label(outframe, text=_('Please choose what data to save')).grid(columnspan=2, padx=PADX, sticky=tk.W) 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_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_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_ship = tk.IntVar( value=(output & (config.OUT_SHIP | config.OUT_SHIP_EDS | config.OUT_SHIP_CORIOLIS) and 1)) nb.Checkbutton(outframe, text=_('Ship loadout'), variable=self.out_ship, command=self.outvarchanged).grid( columnspan=2, padx=BUTTONX, pady=(5, 0), sticky=tk.W) # Output setting 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 = tk.StringVar() self.outdir.set(config.get('outdir')) self.outdir_label = nb.Label(outframe, text=_('File location') + ':') # Section heading in settings self.outdir_label.grid(padx=BUTTONX, pady=(5, 0), sticky=tk.W) self.outdir_entry = nb.Entry(outframe, takefocus=False) self.outdir_entry.grid(row=20, padx=(PADX, 0), sticky=tk.EW) self.outbutton = nb.Button( outframe, text=( platform == 'darwin' and _('Change...') or # Folder selection button on OSX _('Browse...')), # Folder selection button on Windows command=lambda: self.filebrowse(_('File location'), self.outdir)) self.outbutton.grid(row=20, column=1, padx=PADX, sticky=tk.NSEW) nb.Frame(outframe).grid(pady=5) # bottom spacer notebook.add(outframe, text=_('Output')) # Tab heading in settings eddnframe = nb.Frame(notebook) HyperlinkLabel(eddnframe, text='Elite Dangerous Data Network', background=nb.Label().cget('background'), url='https://github.com/jamesremuscat/EDDN/wiki', underline=True).grid(padx=PADX, sticky=tk.W) # Don't translate self.eddn_station = tk.IntVar( value=(output & config.OUT_MKT_EDDN) and 1) nb.Checkbutton( eddnframe, text=_('Send station data to the Elite Dangerous Data Network'), variable=self.eddn_station, command=self.outvarchanged).grid(padx=BUTTONX, pady=(5, 0), sticky=tk.W) # Output setting self.eddn_auto_button = nb.Checkbutton( eddnframe, text=_('Automatically update on docking'), variable=self.out_auto, command=self.outvarchanged) # Output setting self.eddn_auto_button.grid(padx=BUTTONX, sticky=tk.W) self.eddn_system = tk.IntVar( value=(output & config.OUT_SYS_EDDN) and 1) self.eddn_system_button = nb.Checkbutton( eddnframe, text=_( 'Send system and scan data to the Elite Dangerous Data Network' ), variable=self.eddn_system, command=self.outvarchanged) # Output setting new in E:D 2.2 self.eddn_system_button.grid(padx=BUTTONX, pady=(5, 0), sticky=tk.W) self.eddn_delay = tk.IntVar( value=(output & config.OUT_SYS_DELAY) and 1) self.eddn_delay_button = nb.Checkbutton( eddnframe, text=_('Delay sending until docked'), variable=self.eddn_delay ) # Output setting under 'Send system and scan data to the Elite Dangerous Data Network' new in E:D 2.2 self.eddn_delay_button.grid(padx=BUTTONX, sticky=tk.W) notebook.add(eddnframe, text='EDDN') # Not translated edsmframe = nb.Frame(notebook) 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 self.edsm_log = tk.IntVar(value=(output & config.OUT_SYS_EDSM) and 1) self.edsm_log_button = nb.Checkbutton( edsmframe, text=_('Send flight log to Elite Dangerous Star Map'), variable=self.edsm_log, command=self.outvarchanged) self.edsm_log_button.grid(columnspan=2, padx=BUTTONX, pady=(5, 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) self.edsm_cmdr_label = nb.Label( edsmframe, text=_('Commander Name')) # EDSM setting self.edsm_cmdr_label.grid(row=10, padx=PADX, sticky=tk.W) self.edsm_cmdr = nb.Entry(edsmframe) self.edsm_cmdr.insert(0, config.get('edsm_cmdrname') or '') self.edsm_cmdr.grid(row=10, column=1, padx=PADX, pady=PADY, sticky=tk.EW) self.edsm_apikey_label = nb.Label(edsmframe, text=_('API Key')) # EDSM setting self.edsm_apikey_label.grid(row=11, padx=PADX, sticky=tk.W) self.edsm_apikey = nb.Entry(edsmframe) self.edsm_apikey.insert(0, config.get('edsm_apikey') or '') self.edsm_apikey.grid(row=11, column=1, padx=PADX, pady=PADY, sticky=tk.EW) notebook.add(edsmframe, text='EDSM') # Not translated # build plugin prefs tabs for plugname in plug.PLUGINS: plugframe = plug.get_plugin_prefs(plugname, notebook) if plugframe: notebook.add(plugframe, text=plugname) configframe = nb.Frame(notebook) configframe.columnconfigure(1, weight=1) self.logdir = tk.StringVar() self.logdir.set( config.get('journaldir') or config.default_journal_dir or '') self.logdir_entry = nb.Entry(configframe, takefocus=False) if platform != 'darwin': # Apple's SMB implementation is way too flaky - no filesystem events and bogus NULLs nb.Label( configframe, text=_('E:D journal file location') + ':').grid( columnspan=3, padx=PADX, sticky=tk.W) # Location of the new Journal file in E:D 2.2 self.logdir_entry.grid(row=10, columnspan=2, padx=(PADX, 0), sticky=tk.EW) self.logbutton = nb.Button( configframe, text=( platform == 'darwin' and _('Change...') or # Folder selection button on OSX _('Browse...')), # Folder selection button on Windows command=lambda: self.filebrowse(_('E:D journal file location'), self.logdir)) self.logbutton.grid(row=10, column=2, padx=PADX, sticky=tk.EW) if config.default_journal_dir: nb.Button( configframe, text=_('Default'), command=self.logdir_reset, state=config.get('journaldir') and tk.NORMAL or tk.DISABLED).grid( column=2, padx=PADX, pady=(5, 0), sticky=tk.EW) # Appearance theme and language setting if platform == 'win32': ttk.Separator(configframe, orient=tk.HORIZONTAL).grid(columnspan=3, padx=PADX, pady=PADY * 8, sticky=tk.EW) if platform in ['darwin', 'win32']: self.hotkey_code = config.getint('hotkey_code') self.hotkey_mods = config.getint('hotkey_mods') self.hotkey_only = tk.IntVar( value=not config.getint('hotkey_always')) self.hotkey_play = tk.IntVar( value=not config.getint('hotkey_mute')) nb.Label( configframe, text=platform == 'darwin' and _('Keyboard shortcut') or # Hotkey/Shortcut settings prompt on OSX _('Hotkey') # Hotkey/Shortcut settings prompt on Windows ).grid(row=20, padx=PADX, sticky=tk.W) if platform == 'darwin' and not was_accessible_at_launch: if AXIsProcessTrusted(): nb.Label( configframe, text=_('Re-start {APP} to use shortcuts').format( APP=applongname), foreground='firebrick').grid( padx=PADX, sticky=tk.W) # Shortcut settings prompt on OSX else: nb.Label( configframe, text=_('{APP} needs permission to use shortcuts' ).format(APP=applongname), foreground='firebrick').grid( columnspan=3, padx=PADX, sticky=tk.W) # Shortcut settings prompt on OSX nb.Button( configframe, text=_('Open System Preferences'), command=self.enableshortcuts).grid( column=2, padx=PADX, sticky=tk.E) # Shortcut settings button on OSX else: self.hotkey_text = nb.Entry(configframe, 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.bind('<FocusIn>', self.hotkeystart) self.hotkey_text.bind('<FocusOut>', self.hotkeyend) self.hotkey_text.grid(row=20, column=1, columnspan=2, padx=PADX, pady=(5, 0), sticky=tk.W) self.hotkey_only_btn = nb.Checkbutton( configframe, text=_('Only when Elite: Dangerous is the active app'), variable=self.hotkey_only, state=self.hotkey_code and tk.NORMAL or tk.DISABLED) # Hotkey/Shortcut setting self.hotkey_only_btn.grid(columnspan=3, padx=PADX, pady=(5, 0), sticky=tk.W) 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=3, padx=PADX, sticky=tk.W) ttk.Separator(configframe, orient=tk.HORIZONTAL).grid(columnspan=3, padx=PADX, pady=PADY * 8, sticky=tk.EW) nb.Label(configframe, text=_('Preferred Shipyard')).grid( columnspan=3, padx=PADX, sticky=tk.W ) # Setting to decide which ship outfitting website to link to - either E:D Shipyard or Coriolis. self.shipyard = tk.IntVar(value=config.getint('shipyard')) nb.Radiobutton(configframe, text='E:D Shipyard', variable=self.shipyard, value=config.SHIPYARD_EDSHIPYARD).grid(columnspan=3, padx=BUTTONX, pady=(5, 0), sticky=tk.W) nb.Radiobutton(configframe, text='Coriolis', variable=self.shipyard, value=config.SHIPYARD_CORIOLIS).grid(columnspan=3, padx=BUTTONX, sticky=tk.W) nb.Label(configframe).grid(sticky=tk.W) # big spacer notebook.add(configframe, text=_('Configuration')) # Tab heading in settings self.languages = Translations().available_names() self.lang = tk.StringVar(value=self.languages.get( config.get('language'), _('Default'))) # Appearance theme and language setting self.always_ontop = tk.BooleanVar(value=config.getint('always_ontop')) self.theme = tk.IntVar(value=config.getint('theme') and 1 or 0) self.theme_colors = [ config.get('dark_text'), config.get('dark_highlight') ] self.theme_prompts = [ _('Normal text'), # Dark theme color setting _('Highlighted text'), # Dark theme color setting ] themeframe = nb.Frame(notebook) themeframe.columnconfigure(2, weight=1) nb.Label(themeframe, text=_('Language')).grid( row=10, padx=PADX, sticky=tk.W) # Appearance setting prompt self.lang_button = nb.OptionMenu(themeframe, self.lang, self.lang.get(), *self.languages.values()) self.lang_button.grid(row=10, column=1, columnspan=2, padx=PADX, sticky=tk.W) ttk.Separator(themeframe, orient=tk.HORIZONTAL).grid(columnspan=3, padx=PADX, pady=PADY * 8, sticky=tk.EW) nb.Label(themeframe, text=_('Theme')).grid(columnspan=3, padx=PADX, sticky=tk.W) # Appearance setting nb.Radiobutton( themeframe, text=_('Default'), variable=self.theme, value=0, command=self.themevarchanged).grid( columnspan=3, padx=BUTTONX, sticky=tk.W) # Appearance theme and language setting nb.Radiobutton(themeframe, text=_('Dark'), variable=self.theme, value=1, command=self.themevarchanged).grid( columnspan=3, padx=BUTTONX, sticky=tk.W) # Appearance theme setting self.theme_label_0 = nb.Label(themeframe, text=self.theme_prompts[0]) self.theme_label_0.grid(row=20, padx=PADX, sticky=tk.W) self.theme_button_0 = nb.ColoredButton( themeframe, text=_('Station'), background='grey4', command=lambda: self.themecolorbrowse(0)) # Main window self.theme_button_0.grid(row=20, column=1, padx=PADX, pady=PADY, sticky=tk.NSEW) self.theme_label_1 = nb.Label(themeframe, text=self.theme_prompts[1]) self.theme_label_1.grid(row=21, padx=PADX, sticky=tk.W) self.theme_button_1 = nb.ColoredButton( themeframe, text=' Hutton Orbital ', background='grey4', command=lambda: self.themecolorbrowse(1)) # Do not translate self.theme_button_1.grid(row=21, column=1, padx=PADX, pady=PADY, sticky=tk.NSEW) ttk.Separator(themeframe, orient=tk.HORIZONTAL).grid(columnspan=3, padx=PADX, pady=PADY * 8, sticky=tk.EW) self.ontop_button = nb.Checkbutton(themeframe, text=_('Always on top'), variable=self.always_ontop, command=self.themevarchanged) self.ontop_button.grid(columnspan=3, padx=BUTTONX, sticky=tk.W) # Appearance setting nb.Label(themeframe).grid(sticky=tk.W) # big spacer notebook.add(themeframe, text=_('Appearance')) # Tab heading in settings if platform == 'darwin': self.protocol("WM_DELETE_WINDOW", self.apply) # close button applies changes else: buttonframe = ttk.Frame(frame) buttonframe.grid(padx=PADX, pady=PADX, sticky=tk.NSEW) buttonframe.columnconfigure(0, weight=1) ttk.Label(buttonframe).grid(row=0, column=0) # spacer button = ttk.Button(buttonframe, text=_('OK'), command=self.apply) button.grid(row=0, column=1, sticky=tk.E) button.bind("<Return>", lambda event: self.apply()) self.protocol("WM_DELETE_WINDOW", self._destroy) # Selectively disable buttons depending on output settings self.outvarchanged() self.themevarchanged() # disable hotkey for the duration hotkeymgr.unregister() # wait for window to appear on screen before calling grab_set self.parent.wm_attributes( '-topmost', 0) # needed for dialog to appear ontop of parent on OSX & Linux self.wait_visibility() self.grab_set()
def load_button_status(self): if not config.getboolean("lyrics", "karaoke_mode"): self.karaoke_button.set_active(True) if config.getint("lyrics", "line_count") == 1: self.line_button.set_active(True)
def getandsend(self, event=None, retrying=False): auto_update = not event play_sound = (auto_update or int(event.type) == self.EVENT_VIRTUAL) and not config.getint('hotkey_mute') play_bad = False if not monitor.cmdr or not monitor.mode or monitor.state['Captain'] or not monitor.system: return # In CQC or on crew - do nothing if companion.session.state == companion.Session.STATE_AUTH: # Attempt another Auth self.login() return if not retrying: if time() < self.holdofftime: # Was invoked by key while in cooldown self.status['text'] = '' if play_sound and (self.holdofftime-time()) < companion.holdoff*0.75: hotkeymgr.play_bad() # Don't play sound in first few seconds to prevent repeats return elif play_sound: hotkeymgr.play_good() self.status['text'] = _('Fetching data...') self.button['state'] = self.theme_button['state'] = tk.DISABLED self.w.update_idletasks() try: querytime = int(time()) data = companion.session.station() config.set('querytime', querytime) # Validation if not data.get('commander', {}).get('name'): self.status['text'] = _("Who are you?!") # Shouldn't happen elif (not data.get('lastSystem', {}).get('name') or (data['commander'].get('docked') and not data.get('lastStarport', {}).get('name'))): # Only care if docked self.status['text'] = _("Where are you?!") # Shouldn't happen elif not data.get('ship', {}).get('name') or not data.get('ship', {}).get('modules'): self.status['text'] = _("What are you flying?!") # Shouldn't happen elif monitor.cmdr and data['commander']['name'] != monitor.cmdr: raise companion.CmdrError() # Companion API return doesn't match Journal elif ((auto_update and not data['commander'].get('docked')) or (data['lastSystem']['name'] != monitor.system) or ((data['commander']['docked'] and data['lastStarport']['name'] or None) != monitor.station) or (data['ship']['id'] != monitor.state['ShipID']) or (data['ship']['name'].lower() != monitor.state['ShipType'])): raise companion.ServerLagging() else: if __debug__: # Recording if isdir('dump'): with open('dump/%s%s.%s.json' % (data['lastSystem']['name'], data['commander'].get('docked') and '.'+data['lastStarport']['name'] or '', strftime('%Y-%m-%dT%H.%M.%S', localtime())), 'wt') as h: h.write(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8')) if not monitor.state['ShipType']: # Started game in SRV or fighter self.ship['text'] = companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name']) monitor.state['ShipID'] = data['ship']['id'] monitor.state['ShipType'] = data['ship']['name'].lower() if data['commander'].get('credits') is not None: monitor.state['Credits'] = data['commander']['credits'] monitor.state['Loan'] = data['commander'].get('debt', 0) # stuff we can do when not docked err = plug.notify_newdata(data, monitor.is_beta) self.status['text'] = err and err or '' if err: play_bad = True # Export market data if config.getint('output') & (config.OUT_STATION_ANY): if not data['commander'].get('docked'): if not self.status['text']: # Signal as error because the user might actually be docked but the server hosting the Companion API hasn't caught up self.status['text'] = _("You're not docked at a station!") play_bad = True elif (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!") elif not data['lastStarport'].get('commodities'): if not self.status['text']: self.status['text'] = _("Station doesn't have a market!") elif config.getint('output') & (config.OUT_MKT_CSV|config.OUT_MKT_TD): # Fixup anomalies in the commodity data fixed = companion.fixup(data) if config.getint('output') & config.OUT_MKT_CSV: commodity.export(fixed, COMMODITY_CSV) if config.getint('output') & config.OUT_MKT_TD: td.export(fixed) self.holdofftime = querytime + companion.holdoff # Companion API problem except companion.ServerLagging as e: if retrying: self.status['text'] = unicode(e) play_bad = True else: # Retry once if Companion server is unresponsive self.w.after(int(SERVER_RETRY * 1000), lambda:self.getandsend(event, True)) return # early exit to avoid starting cooldown count except companion.CmdrError as e: # Companion API return doesn't match Journal self.status['text'] = unicode(e) play_bad = True companion.session.invalidate() self.login() except Exception as e: # Including CredentialsError, ServerError if __debug__: print_exc() self.status['text'] = unicode(e) play_bad = True if not self.status['text']: # no errors self.status['text'] = strftime(_('Last updated at {HH}:{MM}:{SS}').format(HH='%H', MM='%M', SS='%S').encode('utf-8'), localtime(querytime)).decode('utf-8') if play_sound and play_bad: hotkeymgr.play_bad() self.cooldown()
def start_http(host, port): logger.warning(" RUNNING IN NON SSL CONTEXT ") web.run_app( app, host=host, port=config.getint("Webserver", "port"), )
if event == cv2.EVENT_LBUTTONUP: if len(line) < 2: line.append((x, y)) if len(line) == 2: line_defined = True print("Line: ", line) line_resized = reduce_line(line, param[0]) if __name__ == '__main__': debug = config.getboolean('DEBUG') show_binary_image = config.getboolean('SHOW_BINARY_IMAGE') source = config.get('SOURCE') history = config.getint('HISTORY') print('Start to process images...') cap = cv2.VideoCapture(source) # Original FPS try: FPS = float(int(cap.get(cv2.CAP_PROP_FPS))) if FPS == 0.: FPS = 30 except ValueError: FPS = 30 print("Working at", FPS, "FPS") # Getting width and height of captured images
'The message sent by your client was:'), Message(actor, 'NOTICE', line.strip("\n")), Message(actor, 'NOTICE', 'The error was:'), Message(actor, 'NOTICE', str(e)), Message(actor, 'NOTICE', '---'), Message(actor, 'NOTICE', 'Closing connection.') ] quit_resp = dispatcher.dispatch( socket, Message(None, 'QUIT', 'Protocol error')) if isinstance(quit_resp, list): resp += quit_resp else: resp.append(quit_resp) else: resp = Message(actor, 'ERROR') Actor.by_socket(socket).disconnect() try: router.send(resp) except Exception as e: log.exception(e) Actor.by_socket(socket).disconnect() host = config.get('server', 'listen_host') port = config.getint('server', 'listen_port') log.info('Starting server, listening on %s:%s' % (host, port)) server = gevent.server.StreamServer((host, port), handle) server.serve_forever() log.info('Server stopped')
def __init__(self, parent, callback): tk.Toplevel.__init__(self, parent) self.parent = parent self.callback = callback self.title(platform=='darwin' and _('Preferences') or _('Settings')) 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') style = ttk.Style() frame = ttk.Frame(self) frame.grid(sticky=tk.NSEW) credframe = ttk.LabelFrame(frame, text=_('Credentials')) # Section heading in settings credframe.grid(padx=10, pady=5, sticky=tk.NSEW) credframe.columnconfigure(1, weight=1) ttk.Label(credframe, text=_('Please log in with your Elite: Dangerous account details')).grid(row=0, columnspan=2, sticky=tk.W) # Use same text as E:D Launcher's login dialog ttk.Label(credframe, text=_('Username (Email)')).grid(row=1, sticky=tk.W) # Use same text as E:D Launcher's login dialog ttk.Label(credframe, text=_('Password')).grid(row=2, sticky=tk.W) # Use same text as E:D Launcher's login dialog self.username = ttk.Entry(credframe) self.username.insert(0, config.get('username') or '') self.username.grid(row=1, column=1, sticky=tk.NSEW) self.username.focus_set() self.password = ttk.Entry(credframe, show=u'•') self.password.insert(0, config.get('password') or '') self.password.grid(row=2, column=1, sticky=tk.NSEW) for child in credframe.winfo_children(): child.grid_configure(padx=5, pady=3) outframe = ttk.LabelFrame(frame, text=_('Output')) # Section heading in settings outframe.grid(padx=10, pady=5, sticky=tk.NSEW) output = config.getint('output') or (config.OUT_EDDN | config.OUT_SHIP_EDS) ttk.Label(outframe, text=_('Please choose what data to save')).grid(row=0, padx=5, pady=3, sticky=tk.W) self.out_eddn= tk.IntVar(value = (output & config.OUT_EDDN) and 1) ttk.Checkbutton(outframe, text=_('Send station data to the Elite Dangerous Data Network'), variable=self.out_eddn, command=self.outvarchanged).grid(row=1, padx=5, sticky=tk.W) self.out_csv = tk.IntVar(value = (output & config.OUT_CSV ) and 1) ttk.Checkbutton(outframe, text=_('Market data in CSV format file'), variable=self.out_csv, command=self.outvarchanged).grid(row=2, padx=5, sticky=tk.W) self.out_bpc = tk.IntVar(value = (output & config.OUT_BPC ) and 1) ttk.Checkbutton(outframe, text=_("Market data in Slopey's BPC format file"), variable=self.out_bpc, command=self.outvarchanged).grid(row=3, padx=5, sticky=tk.W) self.out_td = tk.IntVar(value = (output & config.OUT_TD ) and 1) ttk.Checkbutton(outframe, text=_('Market data in Trade Dangerous format file'), variable=self.out_td, command=self.outvarchanged).grid(row=4, padx=5, sticky=tk.W) self.out_ship_eds= tk.IntVar(value = (output & config.OUT_SHIP_EDS) and 1) ttk.Checkbutton(outframe, text=_('Ship loadout in E:D Shipyard format file'), variable=self.out_ship_eds, command=self.outvarchanged).grid(row=5, padx=5, pady=(5,0), sticky=tk.W) self.out_ship_coriolis= tk.IntVar(value = (output & config.OUT_SHIP_CORIOLIS) and 1) ttk.Checkbutton(outframe, text=_('Ship loadout in Coriolis format file'), variable=self.out_ship_coriolis, command=self.outvarchanged).grid(row=6, padx=5, sticky=tk.W) self.out_log_edsm = tk.IntVar(value = (output & config.OUT_LOG_EDSM) and 1) ttk.Checkbutton(outframe, text=_('Send flight log to Elite Dangerous Star Map'), variable=self.out_log_edsm, command=self.outvarchanged).grid(row=7, padx=5, pady=(5,0), sticky=tk.W) self.out_log_file = tk.IntVar(value = (output & config.OUT_LOG_FILE) and 1) ttk.Checkbutton(outframe, text=_('Flight log in CSV format file'), variable=self.out_log_file, command=self.outvarchanged).grid(row=8, padx=5, sticky=tk.W) self.out_log_auto = tk.IntVar(value = monitor.logdir and (output & config.OUT_LOG_AUTO) and 1 or 0) if monitor.logdir: self.out_log_auto_button = ttk.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(row=9, padx=5, sticky=tk.W) self.out_log_auto_text = ttk.Label(outframe) self.dir_label = ttk.Label(frame, text=_('File location'), foreground=style.lookup('TLabelframe.Label', 'foreground')) # Section heading in settings dirframe = ttk.LabelFrame(frame, labelwidget = self.dir_label) dirframe.grid(padx=10, pady=5, sticky=tk.NSEW) dirframe.columnconfigure(0, weight=1) self.outdir = ttk.Entry(dirframe, takefocus=False) if config.get('outdir').startswith(expanduser('~')): self.outdir.insert(0, '~' + config.get('outdir')[len(expanduser('~')):]) else: self.outdir.insert(0, config.get('outdir')) self.outdir.grid(row=0, padx=5, pady=5, sticky=tk.NSEW) self.outbutton = ttk.Button(dirframe, text=(platform=='darwin' and _('Change...') or # Folder selection button on OSX _('Browse...')), command=self.outbrowse) # Folder selection button on Windows self.outbutton.grid(row=0, column=1, padx=5, pady=5, sticky=tk.NSEW) self.edsm_label = HyperlinkLabel(frame, text=_('Elite Dangerous Star Map credentials'), disabledforeground=style.lookup('TLabelframe.Label', 'foreground'), url='http://www.edsm.net/settings/api', underline=True) # Section heading in settings edsmframe = ttk.LabelFrame(frame, labelwidget = self.edsm_label) edsmframe.grid(padx=10, pady=5, sticky=tk.NSEW) edsmframe.columnconfigure(1, weight=1) ttk.Label(edsmframe, text=_('Cmdr name')).grid(row=0, sticky=tk.W) # EDSM & privacy setting self.edsm_cmdr = ttk.Entry(edsmframe) self.edsm_cmdr.insert(0, config.get('edsm_cmdrname') or '') self.edsm_cmdr.grid(row=0, column=1, sticky=tk.NSEW) ttk.Label(edsmframe, text=_('API Key')).grid(row=1, sticky=tk.W) # EDSM setting self.edsm_apikey = ttk.Entry(edsmframe) self.edsm_apikey.insert(0, config.get('edsm_apikey') or '') self.edsm_apikey.grid(row=1, column=1, sticky=tk.NSEW) for child in edsmframe.winfo_children(): child.grid_configure(padx=5, pady=3) if platform in ['darwin','win32']: self.hotkey_code = config.getint('hotkey_code') self.hotkey_mods = config.getint('hotkey_mods') self.hotkey_only = tk.IntVar(value = not config.getint('hotkey_always')) self.hotkey_play = tk.IntVar(value = not config.getint('hotkey_mute')) hotkeyframe = ttk.LabelFrame(frame, text=platform == 'darwin' and _('Keyboard shortcut') or # Section heading in settings on OSX _('Hotkey')) # Section heading in settings on Windows hotkeyframe.grid(padx=10, pady=5, sticky=tk.NSEW) hotkeyframe.columnconfigure(1, weight=1) if platform == 'darwin' and not was_accessible_at_launch: if AXIsProcessTrusted(): ttk.Label(hotkeyframe, text = _('Re-start {APP} to use shortcuts').format(APP=applongname)).grid(row=0, padx=5, pady=5, sticky=tk.NSEW) # Shortcut settings prompt on OSX else: ttk.Label(hotkeyframe, text = _('{APP} needs permission to use shortcuts').format(APP=applongname)).grid(row=0, columnspan=2, padx=5, pady=5, sticky=tk.W) # Shortcut settings prompt on OSX 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.bind('<FocusIn>', self.hotkeystart) self.hotkey_text.bind('<FocusOut>', self.hotkeyend) self.hotkey_text.grid(row=0, padx=5, pady=5, sticky=tk.NSEW) self.hotkey_only_btn = ttk.Checkbutton(hotkeyframe, text=_('Only when Elite: Dangerous is the active app'), variable=self.hotkey_only, state = self.hotkey_code and tk.NORMAL or tk.DISABLED) # Hotkey/Shortcut setting self.hotkey_only_btn.grid(row=1, columnspan=2, padx=5, sticky=tk.W) self.hotkey_play_btn = ttk.Checkbutton(hotkeyframe, 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(row=2, columnspan=2, padx=5, sticky=tk.W) privacyframe = ttk.LabelFrame(frame, text=_('Privacy')) # Section heading in settings privacyframe.grid(padx=10, pady=5, sticky=tk.NSEW) self.out_anon= tk.IntVar(value = config.getint('anonymous') and 1) ttk.Label(privacyframe, text=_('How do you want to be identified in the saved data')).grid(row=0, padx=5, sticky=tk.W) ttk.Radiobutton(privacyframe, text=_('Cmdr name'), variable=self.out_anon, value=0).grid(padx=5, sticky=tk.W) # Privacy setting ttk.Radiobutton(privacyframe, text=_('Pseudo-anonymized ID'), variable=self.out_anon, value=1).grid(padx=5, sticky=tk.W) # Privacy setting if platform=='darwin': self.protocol("WM_DELETE_WINDOW", self.apply) # close button applies changes else: buttonframe = ttk.Frame(frame) buttonframe.grid(padx=10, pady=5, sticky=tk.NSEW) buttonframe.columnconfigure(0, weight=1) ttk.Label(buttonframe).grid(row=0, column=0) # spacer button = ttk.Button(buttonframe, text=_('OK'), command=self.apply) button.grid(row=0, column=1, sticky=tk.E) button.bind("<Return>", lambda event:self.apply()) self.protocol("WM_DELETE_WINDOW", self._destroy) # Selectively disable buttons depending on output settings self.outvarchanged() # disable hotkey for the duration hotkeymgr.unregister() # wait for window to appear on screen before calling grab_set self.wait_visibility() self.grab_set()
def onleave(self, event=None): if config.getint('theme') > 1 and event.widget==self.w: self.w.attributes("-transparentcolor", 'grey4') self.theme_menubar.grid_remove() self.blank_menubar.grid(row=0, columnspan=2, sticky=tk.NSEW)
def __init__(self, master): # Start a protocol handler to handle cAPI registration. Requires main window to exist. protocolhandler.start(master) self.holdofftime = config.getint('querytime') + companion.holdoff self.w = master self.w.title(applongname) self.w.rowconfigure(0, weight=1) self.w.columnconfigure(0, weight=1) self.prefsdialog = None plug.load_plugins(master) if platform != 'darwin': if platform == 'win32': self.w.wm_iconbitmap(default='EDMarketConnector.ico') else: self.w.tk.call('wm', 'iconphoto', self.w, '-default', tk.PhotoImage(file = join(config.respath, 'EDMarketConnector.png'))) self.theme_icon = tk.PhotoImage(data = 'R0lGODlhFAAQAMZQAAoKCQoKCgsKCQwKCQsLCgwLCg4LCQ4LCg0MCg8MCRAMCRANChINCREOChIOChQPChgQChgRCxwTCyYVCSoXCS0YCTkdCTseCT0fCTsjDU0jB0EnDU8lB1ElB1MnCFIoCFMoCEkrDlkqCFwrCGEuCWIuCGQvCFs0D1w1D2wyCG0yCF82D182EHE0CHM0CHQ1CGQ5EHU2CHc3CHs4CH45CIA6CIE7CJdECIdLEolMEohQE5BQE41SFJBTE5lUE5pVE5RXFKNaFKVbFLVjFbZkFrxnFr9oFsNqFsVrF8RsFshtF89xF9NzGNh1GNl2GP+KG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAUABAAAAeegAGCgiGDhoeIRDiIjIZGKzmNiAQBQxkRTU6am0tPCJSGShuSAUcLoIIbRYMFra4FAUgQAQCGJz6CDQ67vAFJJBi0hjBBD0w9PMnJOkAiJhaIKEI7HRoc19ceNAolwbWDLD8uAQnl5ga1I9CHEjEBAvDxAoMtFIYCBy+kFDKHAgM3ZtgYSLAGgwkp3pEyBOJCC2ELB31QATGioAoVAwEAOw==') self.theme_minimize = tk.BitmapImage(data = '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f,\n 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };\n') self.theme_close = tk.BitmapImage(data = '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x1c, 0x38, 0x38, 0x1c, 0x70, 0x0e,\n 0xe0, 0x07, 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x07, 0x70, 0x0e, 0x38, 0x1c,\n 0x1c, 0x38, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00 };\n') frame = tk.Frame(self.w, name=appname.lower()) frame.grid(sticky=tk.NSEW) frame.columnconfigure(1, weight=1) self.cmdr_label = tk.Label(frame) self.ship_label = tk.Label(frame) self.system_label = tk.Label(frame) self.station_label = tk.Label(frame) self.cmdr_label.grid(row=1, column=0, sticky=tk.W) self.ship_label.grid(row=2, column=0, sticky=tk.W) self.system_label.grid(row=3, column=0, sticky=tk.W) self.station_label.grid(row=4, column=0, sticky=tk.W) self.cmdr = tk.Label(frame, compound=tk.RIGHT, anchor=tk.W, name = 'cmdr') self.ship = HyperlinkLabel(frame, compound=tk.RIGHT, url = self.shipyard_url, name = 'ship') self.system = HyperlinkLabel(frame, compound=tk.RIGHT, url = self.system_url, popup_copy = True, name = 'system') self.station = HyperlinkLabel(frame, compound=tk.RIGHT, url = self.station_url, name = 'station') self.cmdr.grid(row=1, column=1, sticky=tk.EW) self.ship.grid(row=2, column=1, sticky=tk.EW) self.system.grid(row=3, column=1, sticky=tk.EW) self.station.grid(row=4, column=1, sticky=tk.EW) for plugin in plug.PLUGINS: appitem = plugin.get_app(frame) if appitem: tk.Frame(frame, highlightthickness=1).grid(columnspan=2, sticky=tk.EW) # separator if isinstance(appitem, tuple) and len(appitem)==2: row = frame.grid_size()[1] appitem[0].grid(row=row, column=0, sticky=tk.W) appitem[1].grid(row=row, column=1, sticky=tk.EW) else: appitem.grid(columnspan=2, sticky=tk.EW) self.button = ttk.Button(frame, text=_('Update'), width=28, default=tk.ACTIVE, state=tk.DISABLED) # Update button in main window self.theme_button = tk.Label(frame, width = platform == 'darwin' and 32 or 28, state=tk.DISABLED) self.status = tk.Label(frame, name='status', anchor=tk.W) row = frame.grid_size()[1] self.button.grid(row=row, columnspan=2, sticky=tk.NSEW) self.theme_button.grid(row=row, columnspan=2, sticky=tk.NSEW) theme.register_alternate((self.button, self.theme_button, self.theme_button), {'row':row, 'columnspan':2, 'sticky':tk.NSEW}) self.status.grid(columnspan=2, sticky=tk.EW) self.button.bind('<Button-1>', self.getandsend) theme.button_bind(self.theme_button, self.getandsend) for child in frame.winfo_children(): child.grid_configure(padx=5, pady=(platform!='win32' or isinstance(child, tk.Frame)) and 2 or 0) self.menubar = tk.Menu() if platform=='darwin': # Can't handle (de)iconify if topmost is set, so suppress iconify button # http://wiki.tcl.tk/13428 and p15 of https://developer.apple.com/legacy/library/documentation/Carbon/Conceptual/HandlingWindowsControls/windowscontrols.pdf root.call('tk::unsupported::MacWindowStyle', 'style', root, 'document', 'closeBox resizable') # https://www.tcl.tk/man/tcl/TkCmd/menu.htm self.system_menu = tk.Menu(self.menubar, name='apple') self.system_menu.add_command(command=lambda:self.w.call('tk::mac::standardAboutPanel')) self.system_menu.add_command(command=lambda:self.updater.checkForUpdates()) self.menubar.add_cascade(menu=self.system_menu) self.file_menu = tk.Menu(self.menubar, name='file') self.file_menu.add_command(command=self.save_raw) self.menubar.add_cascade(menu=self.file_menu) self.edit_menu = tk.Menu(self.menubar, name='edit') self.edit_menu.add_command(accelerator='Command-c', state=tk.DISABLED, command=self.copy) self.menubar.add_cascade(menu=self.edit_menu) self.w.bind('<Command-c>', self.copy) self.view_menu = tk.Menu(self.menubar, name='view') self.view_menu.add_command(command=lambda:stats.StatsDialog(self)) self.menubar.add_cascade(menu=self.view_menu) window_menu = tk.Menu(self.menubar, name='window') self.menubar.add_cascade(menu=window_menu) self.help_menu = tk.Menu(self.menubar, name='help') self.w.createcommand("::tk::mac::ShowHelp", self.help_general) self.help_menu.add_command(command=self.help_privacy) self.help_menu.add_command(command=self.help_releases) self.menubar.add_cascade(menu=self.help_menu) self.w['menu'] = self.menubar # https://www.tcl.tk/man/tcl/TkCmd/tk_mac.htm self.w.call('set', 'tk::mac::useCompatibilityMetrics', '0') self.w.createcommand('tkAboutDialog', lambda:self.w.call('tk::mac::standardAboutPanel')) self.w.createcommand("::tk::mac::Quit", self.onexit) self.w.createcommand("::tk::mac::ShowPreferences", lambda:prefs.PreferencesDialog(self.w, self.postprefs)) 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 self.w.resizable(tk.FALSE, tk.FALSE) # Can't be only resizable on one axis else: self.file_menu = self.view_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.file_menu.add_command(command=lambda:stats.StatsDialog(self)) self.file_menu.add_command(command=self.save_raw) self.file_menu.add_command(command=lambda:prefs.PreferencesDialog(self.w, self.postprefs)) self.file_menu.add_separator() self.file_menu.add_command(command=self.onexit) self.menubar.add_cascade(menu=self.file_menu) self.edit_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.edit_menu.add_command(accelerator='Ctrl+C', state=tk.DISABLED, command=self.copy) self.menubar.add_cascade(menu=self.edit_menu) self.help_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.help_menu.add_command(command=self.help_general) self.help_menu.add_command(command=self.help_privacy) self.help_menu.add_command(command=self.help_releases) self.help_menu.add_command(command=lambda:self.updater.checkForUpdates()) self.menubar.add_cascade(menu=self.help_menu) if platform == 'win32': # Must be added after at least one "real" menu entry self.always_ontop = tk.BooleanVar(value = config.getint('always_ontop')) self.system_menu = tk.Menu(self.menubar, name='system', tearoff=tk.FALSE) self.system_menu.add_separator() self.system_menu.add_checkbutton(label=_('Always on top'), variable = self.always_ontop, command=self.ontop_changed) # Appearance setting self.menubar.add_cascade(menu=self.system_menu) self.w.bind('<Control-c>', self.copy) self.w.protocol("WM_DELETE_WINDOW", self.onexit) theme.register(self.menubar) # menus and children aren't automatically registered theme.register(self.file_menu) theme.register(self.edit_menu) theme.register(self.help_menu) # Alternate title bar and menu for dark theme self.theme_menubar = tk.Frame(frame) self.theme_menubar.columnconfigure(2, weight=1) theme_titlebar = tk.Label(self.theme_menubar, text=applongname, image=self.theme_icon, cursor='fleur', anchor=tk.W, compound=tk.LEFT) theme_titlebar.grid(columnspan=3, padx=2, sticky=tk.NSEW) self.drag_offset = None theme_titlebar.bind('<Button-1>', self.drag_start) theme_titlebar.bind('<B1-Motion>', self.drag_continue) theme_titlebar.bind('<ButtonRelease-1>', self.drag_end) if platform == 'win32': # Can't work out how to deiconify on Linux theme_minimize = tk.Label(self.theme_menubar, image=self.theme_minimize) theme_minimize.grid(row=0, column=3, padx=2) theme.button_bind(theme_minimize, self.oniconify, image=self.theme_minimize) theme_close = tk.Label(self.theme_menubar, image=self.theme_close) theme_close.grid(row=0, column=4, padx=2) theme.button_bind(theme_close, self.onexit, image=self.theme_close) self.theme_file_menu = tk.Label(self.theme_menubar, anchor=tk.W) self.theme_file_menu.grid(row=1, column=0, padx=5, sticky=tk.W) theme.button_bind(self.theme_file_menu, lambda e: self.file_menu.tk_popup(e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) self.theme_edit_menu = tk.Label(self.theme_menubar, anchor=tk.W) self.theme_edit_menu.grid(row=1, column=1, sticky=tk.W) theme.button_bind(self.theme_edit_menu, lambda e: self.edit_menu.tk_popup(e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) self.theme_help_menu = tk.Label(self.theme_menubar, anchor=tk.W) self.theme_help_menu.grid(row=1, column=2, sticky=tk.W) theme.button_bind(self.theme_help_menu, lambda e: self.help_menu.tk_popup(e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) tk.Frame(self.theme_menubar, highlightthickness=1).grid(columnspan=5, padx=5, sticky=tk.EW) theme.register(self.theme_minimize) # images aren't automatically registered theme.register(self.theme_close) self.blank_menubar = tk.Frame(frame) tk.Label(self.blank_menubar).grid() tk.Label(self.blank_menubar).grid() tk.Frame(self.blank_menubar, height=2).grid() theme.register_alternate((self.menubar, self.theme_menubar, self.blank_menubar), {'row':0, 'columnspan':2, 'sticky':tk.NSEW}) self.w.resizable(tk.TRUE, tk.FALSE) # update geometry if config.get('geometry'): match = re.match('\+([\-\d]+)\+([\-\d]+)', config.get('geometry')) if match: if platform == 'darwin': if int(match.group(2)) >= 0: # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 self.w.geometry(config.get('geometry')) elif platform == 'win32': # Check that the titlebar will be at least partly on screen import ctypes from ctypes.wintypes import POINT # https://msdn.microsoft.com/en-us/library/dd145064 MONITOR_DEFAULTTONULL = 0 if ctypes.windll.user32.MonitorFromPoint(POINT(int(match.group(1)) + 16, int(match.group(2)) + 16), MONITOR_DEFAULTTONULL): self.w.geometry(config.get('geometry')) else: self.w.geometry(config.get('geometry')) self.w.attributes('-topmost', config.getint('always_ontop') and 1 or 0) theme.register(frame) theme.apply(self.w) self.w.bind('<Map>', self.onmap) # Special handling for overrideredict self.w.bind('<Enter>', self.onenter) # Special handling for transparency self.w.bind('<FocusIn>', self.onenter) # " self.w.bind('<Leave>', self.onleave) # " self.w.bind('<FocusOut>', self.onleave) # " self.w.bind('<Return>', self.getandsend) self.w.bind('<KP_Enter>', self.getandsend) self.w.bind_all('<<Invoke>>', self.getandsend) # Hotkey monitoring self.w.bind_all('<<JournalEvent>>', self.journal_event) # Journal monitoring self.w.bind_all('<<DashboardEvent>>', self.dashboard_event) # Dashboard monitoring self.w.bind_all('<<PluginError>>', self.plugin_error) # Statusbar self.w.bind_all('<<CompanionAuthEvent>>', self.auth) # cAPI auth self.w.bind_all('<<Quit>>', self.onexit) # Updater # Load updater after UI creation (for WinSparkle) import update self.updater = update.Updater(self.w) if not getattr(sys, 'frozen', False): self.updater.checkForUpdates() # Sparkle / WinSparkle does this automatically for packaged apps try: config.get_password('') # Prod SecureStorage on Linux to initialise except RuntimeError: pass # Migration from <= 3.30 for username in config.get('fdev_usernames') or []: config.delete_password(username) config.delete('fdev_usernames') config.delete('username') config.delete('password') config.delete('logdir') self.postprefs(False) # Companion login happens in callback from monitor
def plugin_error(self, event=None): if plug.last_error.get('msg'): self.status['text'] = plug.last_error['msg'] self.w.update_idletasks() if not config.getint('hotkey_mute'): hotkeymgr.play_bad()
def journal_event(self, event): def crewroletext(role): # Return translated crew role. Needs to be dynamic to allow for changing language. return { None: '', 'Idle': '', 'FighterCon': _('Fighter'), # Multicrew role 'FireCon': _('Gunner'), # Multicrew role 'FlightCon': _('Helm'), # Multicrew role }.get(role, role) while True: entry = monitor.get_entry() if not entry: return # Update main window self.cooldown() if monitor.cmdr and monitor.state['Captain']: self.cmdr['text'] = '%s / %s' % (monitor.cmdr, monitor.state['Captain']) self.ship_label['text'] = _('Role') + ':' # Multicrew role label in main window self.ship.configure(state = tk.NORMAL, text = crewroletext(monitor.state['Role']), url = None) elif monitor.cmdr: if monitor.group: self.cmdr['text'] = '%s / %s' % (monitor.cmdr, monitor.group) else: self.cmdr['text'] = monitor.cmdr self.ship_label['text'] = _('Ship') + ':' # Main window self.ship.configure(text = monitor.state['ShipName'] or companion.ship_map.get(monitor.state['ShipType'], monitor.state['ShipType']) or '', url = self.shipyard_url) else: self.cmdr['text'] = '' self.ship_label['text'] = _('Ship') + ':' # Main window self.ship['text'] = '' self.edit_menu.entryconfigure(0, state=monitor.system and tk.NORMAL or tk.DISABLED) # Copy if entry['event'] in ['Undocked', 'StartJump', 'SetUserShipName', 'ShipyardBuy', 'ShipyardSell', 'ShipyardSwap', 'ModuleBuy', 'ModuleSell', 'MaterialCollected', 'MaterialDiscarded', 'ScientificResearch', 'EngineerCraft', 'Synthesis', 'JoinACrew']: self.status['text'] = '' # Periodically clear any old error self.w.update_idletasks() # Companion login if entry['event'] in [None, 'StartUp', 'NewCommander', 'LoadGame'] and monitor.cmdr: if not config.get('cmdrs') or monitor.cmdr not in config.get('cmdrs'): config.set('cmdrs', (config.get('cmdrs') or []) + [monitor.cmdr]) self.login() if not entry['event'] or not monitor.mode: return # Startup or in CQC if entry['event'] in ['StartUp', 'LoadGame'] and monitor.started: # Can start dashboard monitoring if not dashboard.start(self.w, monitor.started): print "Can't start Status monitoring" # Export loadout if entry['event'] == 'Loadout' and not monitor.state['Captain'] and config.getint('output') & config.OUT_SHIP: monitor.export_ship() # Plugins err = plug.notify_journal_entry(monitor.cmdr, monitor.is_beta, monitor.system, monitor.station, entry, monitor.state) if err: self.status['text'] = err if not config.getint('hotkey_mute'): hotkeymgr.play_bad() # Auto-Update after docking, but not if auth callback is pending 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)
def export(data, filename=None): def class_rating(module): if 'guidance' in module: return module['class'] + module['rating'] + '/' + module.get( 'mount', 'F')[0] + module['guidance'][0] + ' ' elif 'mount' in module: return module['class'] + module['rating'] + '/' + module['mount'][ 0] + ' ' else: return module['class'] + module['rating'] + ' ' querytime = config.getint('querytime') or int(time.time()) loadout = defaultdict(list) for slot in sorted(data['ship']['modules']): v = data['ship']['modules'][slot] try: if not v: continue module = outfitting.lookup(v['module'], ship_map) if not module: continue cr = class_rating(module) # Specials if module['name'] in ['Fuel Tank', 'Cargo Rack']: name = '%s (Capacity: %d)' % (module['name'], 2**int( module['class'])) else: name = module['name'] for s in slot_map: if slot.lower().startswith(s): loadout[slot_map[s]].append(cr + name) break else: if slot.lower().startswith('slot'): loadout[slot[-1]].append(cr + name) elif __debug__: print 'Loadout: Unknown slot %s' % slot except AssertionError as e: if __debug__: print 'Loadout: %s' % e continue # Silently skip unrecognized modules except: if __debug__: raise # Construct description string = '[%s]\n' % ship_map.get(data['ship']['name'].lower(), data['ship']['name']) for slot in [ 'H', 'L', 'M', 'S', 'U', None, 'BH', 'RB', 'TM', 'FH', 'EC', 'PC', 'SS', 'FS', None, '9', '8', '7', '6', '5', '4', '3', '2', '1' ]: if not slot: string += '\n' elif slot in loadout: for name in loadout[slot]: string += '%s: %s\n' % (slot, name) string += '---\nCargo : %d T\nFuel : %d T\n' % ( data['ship']['cargo']['capacity'], data['ship']['fuel']['main']['capacity']) if filename: with open(filename, 'wt') as h: h.write(string) return # Look for last ship of this type ship = companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name']) # Use in-game name regexp = re.compile( re.escape(ship) + '\.\d\d\d\d\-\d\d\-\d\dT\d\d\.\d\d\.\d\d\.txt') oldfiles = sorted( [x for x in os.listdir(config.get('outdir')) if regexp.match(x)]) if oldfiles: with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h: if h.read() == string: return # same as last time - don't write # Write filename = join( config.get('outdir'), '%s.%s.txt' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)))) with open(filename, 'wt') as h: h.write(string)
def export(data, filename=None): querytime = config.getint('querytime') or int(time.time()) loadout = OrderedDict([ # Mimic Coriolis export ordering ('$schema', 'http://cdn.coriolis.io/schemas/ship-loadout/2.json#'), ('name', ship_map.get(data['ship']['name'].lower(), data['ship']['name'])), ('ship', ship_map.get(data['ship']['name'].lower(), data['ship']['name'])), ('components', OrderedDict([ ('standard', OrderedDict([(x,None) for x in standard_map.values()])), ('hardpoints', []), ('utility', []), ('internal', []), ])), ]) maxpri = 0 mass = 0.0 fsd = None # Correct module ordering relies on the fact that "Slots" in the data are correctly ordered alphabetically. # Correct hardpoint ordering additionally relies on the fact that "Huge" < "Large" < "Medium" < "Small" for slot in sorted(data['ship']['modules']): v = data['ship']['modules'][slot] try: for s in slot_map: if slot.lower().startswith(s): category = slot_map[s] break else: if __debug__: for skip in ['bobble', 'decal', 'paintjob', 'planetaryapproachsuite', 'enginecolour', 'shipkit', 'weaponcolour']: if slot.lower().startswith(skip): break else: print 'Coriolis: Unknown slot %s' % slot continue if not v: # Need to add nulls for empty slots. Assumes that standard slots can't be empty. loadout['components'][category].append(None) continue module = outfitting.lookup(v['module'], ship_map) if not module: raise AssertionError('Unknown module %s' % v) # Shouldn't happen mass += module.get('mass', 0) thing = OrderedDict([ ('class',int(module['class'])), ('rating', module['rating']), ('enabled', module['enabled']), ('priority', module['priority']+1), # make 1-based ]) maxpri = max(maxpri, thing['priority']) if category == 'standard': # Standard items are indexed by "group" rather than containing a "group" member if module['name'] in bulkheads: loadout['components'][category]['bulkheads'] = module['name'] # Bulkheads are just strings else: loadout['components'][category][standard_map[module['name']]] = thing if module['name'] == 'Frame Shift Drive': fsd = module # save for range calculation else: # All other items have a "group" member, some also have a "name" if module['name'] in fixup_map: thing['group'], name = fixup_map[module['name']] if name: thing['name'] = name else: thing['group'] = module['name'] if 'mount' in module: thing['mount'] = weaponmount_map[module['mount']] if 'guidance' in module: thing['missile'] = module['guidance'][0] # not mentioned in schema loadout['components'][category].append(thing) except AssertionError as e: # Silently skip unrecognized modules if __debug__: print 'Coriolis: %s' % e if category != 'standard': loadout['components'][category].append(None) except: if __debug__: raise # Cargo Hatch status is not available in the data - fake something up loadout['components']['standard']['cargoHatch'] = OrderedDict([ ('enabled', True), ('priority', maxpri), ]) # Add mass and range assert data['ship']['name'].lower() in companion.ship_map, data['ship']['name'] assert companion.ship_map[data['ship']['name'].lower()] in ships, companion.ship_map[data['ship']['name'].lower()] try: # https://github.com/cmmcleod/coriolis/blob/master/app/js/shipyard/module-shipyard.js#L184 hullMass = ships[companion.ship_map[data['ship']['name'].lower()]]['hullMass'] mass += hullMass multiplier = pow(min(data['ship']['fuel']['main']['capacity'], fsd['maxfuel']) / fsd['fuelmul'], 1.0 / fsd['fuelpower']) * fsd['optmass'] loadout['stats'] = OrderedDict([ ('hullMass', hullMass), ('fuelCapacity', data['ship']['fuel']['main']['capacity']), ('cargoCapacity', data['ship']['cargo']['capacity']), ('ladenMass', mass + data['ship']['fuel']['main']['capacity'] + data['ship']['cargo']['capacity']), ('unladenMass', mass), ('unladenRange', round(multiplier / (mass + min(data['ship']['fuel']['main']['capacity'], fsd['maxfuel'])), 2)), # fuel for one jump ('fullTankRange', round(multiplier / (mass + data['ship']['fuel']['main']['capacity']), 2)), ('ladenRange', round(multiplier / (mass + data['ship']['fuel']['main']['capacity'] + data['ship']['cargo']['capacity']), 2)), ]) except: if __debug__: raise # Construct description string = json.dumps(loadout, indent=2, separators=(',', ': ')) if filename: with open(filename, 'wt') as h: h.write(string) return # Look for last ship of this type ship = companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name']) # Use in-game name regexp = re.compile(re.escape(ship) + '\.\d\d\d\d\-\d\d\-\d\dT\d\d\.\d\d\.\d\d\.json') oldfiles = sorted([x for x in os.listdir(config.get('outdir')) if regexp.match(x)]) if oldfiles: with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h: if h.read() == string: return # same as last time - don't write # Write filename = join(config.get('outdir'), '%s.%s.json' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)))) with open(filename, 'wt') as h: h.write(string)
web.run_app( app, host=host, port=port, ssl_context=ctx, ) def start_socket(sock): web.run_app(app, path=sock) if __name__ == "__main__": socket = config.get("Webserver", "socket", fallback=None) if socket: start_socket(socket) else: host = config.get("Webserver", "host") port = config.getint("Webserver", "port") if config.getboolean("Webserver", "ssl"): try: chain = config.get("Webserver", "ssl_fullchain") key = config.get("Webserver", "ssl_privkey") except configparser.NoOptionError: logger.critical( "SSL CONFIGURATION IS NOT CORRECTLY CONFIGURED. ABORTING LAUNCH." ) sys.exit(2) start_https(host, port, chain, key) else: start_http(host, port)
# set a format which is simpler for console use formatter = logging.Formatter('%(message)s') # tell the handler to use this format console.setFormatter(formatter) # add the handler to the root logger logging.getLogger('').addHandler(console) ### Setup the proxy env = dict() env['key'] = None env['realm'] = { 'socket': RealmServer(config.getint('REALM', 'localport'), config.get('REALM', 'remotehost'), config.getint('REALM', 'remoteport'), env) } env['world'] = { 'socket': WorldServer(config.getint('WORLD', 'localport'), config.get('WORLD', 'remotehost'), config.getint('WORLD', 'remoteport'), env) } env['keyserver'] = { 'socket': KeyServer(config.getint('KEYSERVER', 'localport'), env) } asyncore.loop()
import time import simple_queue import simple_http_client from config import config from xlog import getLogger xlog = getLogger("cloudflare_front") show_state_debug = config.getint("system", "show_state_debug", 0) class Task(object): def __init__(self, method, host, path, headers, body, queue, url, timeout): self.method = method self.host = host self.path = path self.headers = headers self.body = body self.queue = queue self.url = url self.timeout = timeout self.start_time = time.time() self.unique_id = "%s:%f" % (url, self.start_time) self.trace_time = [] self.body_queue = simple_queue.Queue() self.body_len = 0 self.body_readed = 0 self.content_length = None self.worker = None self.read_buffer = "" self.responsed = False
def context_builder(ca_certs=None, cipher_suites=None): global ssl_version, support_alpn_npn if not ca_certs: ca_certs = os.path.join(current_path, "cacert.pem") if not ssl_version: if hasattr(OpenSSL.SSL, "TLSv1_2_METHOD"): ssl_version = "TLSv1_2" elif hasattr(OpenSSL.SSL, "TLSv1_1_METHOD"): ssl_version = "TLSv1_1" elif hasattr(OpenSSL.SSL, "TLSv1_METHOD"): ssl_version = "TLSv1" else: ssl_version = "SSLv23" if sys.platform == "darwin": # MacOS pyOpenSSL has TLSv1_2_METHOD attr but can use. # There for we hard code here. # may be try/cache is a better solution. ssl_version = "TLSv1" # freenas openssl support fix from twitter user "himanzero" # https://twitter.com/himanzero/status/645231724318748672 if sys.platform == "freebsd9": ssl_version = "TLSv1" xlog.info("SSL use version:%s", ssl_version) protocol_version = getattr(OpenSSL.SSL, '%s_METHOD' % ssl_version) ssl_context = OpenSSL.SSL.Context(protocol_version) if ca_certs: ssl_context.load_verify_locations(os.path.abspath(ca_certs)) ssl_context.set_verify(OpenSSL.SSL.VERIFY_PEER, lambda c, x, e, d, ok: ok) else: ssl_context.set_verify(OpenSSL.SSL.VERIFY_NONE, lambda c, x, e, d, ok: ok) # change default cipher suites. # Google video ip can act as Google FrontEnd if cipher suits not include # RC4-SHA:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-GCM-SHA256:AES128-GCM-SHA256 # # 'ALL', '!aNULL', '!eNULL' #if not cipher_suites: # cipher_suites = ('ALL:!RC4-SHA:!ECDHE-RSA-RC4-SHA:!ECDHE-RSA-AES128-GCM-SHA256:!AES128-GCM-SHA256:!ECDHE-RSA-AES128-SHA:!AES128-SHA',) #ssl_context.set_cipher_list(':'.join(cipher_suites)) if config.getint("connect_manager", "use_http2", 1): try: ssl_context.set_alpn_protos([b'h2', b'http/1.1']) xlog.info("OpenSSL support alpn") support_alpn_npn = "alpn" return ssl_context except Exception as e: #xlog.exception("set_alpn_protos:%r", e) pass try: ssl_context.set_npn_select_callback( SSLConnection.npn_select_callback) xlog.info("OpenSSL support npn") support_alpn_npn = "npn" except Exception as e: #xlog.exception("set_npn_select_callback:%r", e) xlog.info( "OpenSSL dont't support npn/alpn, no HTTP/2 supported.") return ssl_context
def journal_entry(cmdr, is_beta, system, station, entry, state): # Update display if this.system['text'] != system: this.system['text'] = system or '' this.system['image'] = '' if not system or system in FAKE: this.system['url'] = None this.lastlookup = True else: this.system[ 'url'] = 'https://www.edsm.net/show-system?systemName=%s' % urllib2.quote( system) this.lastlookup = False this.system.update_idletasks() this.multicrew = bool(state['Role']) if 'StarPos' in entry: this.coordinates = entry['StarPos'] elif entry['event'] == 'LoadGame': this.coordinates = None # Send interesting events to EDSM if config.getint( 'edsm_out') and not is_beta and not this.multicrew and credentials( cmdr) and entry['event'] not in this.discardedEvents: # Introduce transient states into the event transient = { '_systemName': system, '_systemCoordinates': this.coordinates, '_stationName': station, '_shipId': state['ShipID'], } entry.update(transient) if entry['event'] == 'LoadGame': # Synthesise Cargo and Materials events on LoadGame since we will have missed them because Cmdr was unknown cargo = { 'timestamp': entry['timestamp'], 'event': 'Cargo', 'Inventory': [{ 'Name': k, 'Count': v } for k, v in state['Cargo'].iteritems()], } cargo.update(transient) this.queue.put((cmdr, cargo)) materials = { 'timestamp': entry['timestamp'], 'event': 'Materials', 'Raw': [{ 'Name': k, 'Count': v } for k, v in state['Raw'].iteritems()], 'Manufactured': [{ 'Name': k, 'Count': v } for k, v in state['Manufactured'].iteritems()], 'Encoded': [{ 'Name': k, 'Count': v } for k, v in state['Encoded'].iteritems()], } materials.update(transient) this.queue.put((cmdr, materials)) this.queue.put((cmdr, entry))
def export(data, filename=None): def class_rating(module): if 'guidance' in module: # Missiles return module['class'] + module['rating'] + '/' + module.get( 'mount', 'F')[0] + module['guidance'][0] + ' ' elif 'mount' in module: # Hardpoints return module['class'] + module['rating'] + '/' + module['mount'][ 0] + ' ' elif 'Cabin' in module['name']: # Passenger cabins return module['class'] + module['rating'] + '/' + module['name'][ 0] + ' ' else: return module['class'] + module['rating'] + ' ' querytime = config.getint('querytime') or int(time.time()) loadout = defaultdict(list) mass = 0.0 fuel = 0 cargo = 0 fsd = None jumpboost = 0 for slot in sorted(data['ship']['modules']): v = data['ship']['modules'][slot] try: if not v: continue module = outfitting.lookup(v['module'], ship_map) if not module: continue cr = class_rating(module) mods = v.get('modifications') or v.get( 'WorkInProgress_modifications') or {} if mods.get('OutfittingFieldType_Mass'): mass += (module.get('mass', 0) * mods['OutfittingFieldType_Mass']['value']) else: mass += module.get('mass', 0) # Specials if 'Fuel Tank' in module['name']: fuel += 2**int(module['class']) name = '%s (Capacity: %d)' % (module['name'], 2**int( module['class'])) elif 'Cargo Rack' in module['name']: cargo += 2**int(module['class']) name = '%s (Capacity: %d)' % (module['name'], 2**int( module['class'])) else: name = module['name'] if name == 'Frame Shift Drive': fsd = module # save for range calculation if mods.get('OutfittingFieldType_FSDOptimalMass'): fsd['optmass'] *= mods[ 'OutfittingFieldType_FSDOptimalMass']['value'] if mods.get('OutfittingFieldType_MaxFuelPerJump'): fsd['maxfuel'] *= mods[ 'OutfittingFieldType_MaxFuelPerJump']['value'] jumpboost += module.get('jumpboost', 0) for s in slot_map: if slot.lower().startswith(s): loadout[slot_map[s]].append(cr + name) break else: if slot.lower().startswith('slot'): loadout[slot[-1]].append(cr + name) elif __debug__ and not slot.lower().startswith( 'planetaryapproachsuite'): print 'EDShipyard: Unknown slot %s' % slot except AssertionError as e: if __debug__: print 'EDShipyard: %s' % e continue # Silently skip unrecognized modules except: if __debug__: raise # Construct description ship = ship_map.get(data['ship']['name'].lower(), data['ship']['name']) string = '[%s]\n' % (data['ship'].get('shipName') and ', '.join( [ship, data['ship']['shipName'].encode('utf-8')]) or ship) for slot in [ 'H', 'L', 'M', 'S', 'U', None, 'BH', 'RB', 'TM', 'FH', 'EC', 'PC', 'SS', 'FS', None, 'MC', None, '9', '8', '7', '6', '5', '4', '3', '2', '1' ]: if not slot: string += '\n' elif slot in loadout: for name in loadout[slot]: string += '%s: %s\n' % (slot, name) string += '---\nCargo : %d T\nFuel : %d T\n' % (cargo, fuel) # Add mass and range assert data['ship']['name'].lower( ) in companion.ship_map, data['ship']['name'] assert companion.ship_map[data['ship']['name'].lower( )] in ships, companion.ship_map[data['ship']['name'].lower()] try: # https://github.com/cmmcleod/coriolis/blob/master/app/js/shipyard/module-shipyard.js#L184 mass += ships[companion.ship_map[data['ship'] ['name'].lower()]]['hullMass'] string += 'Mass : %.2f T empty\n %.2f T full\n' % ( mass, mass + fuel + cargo) multiplier = pow( min(fuel, fsd['maxfuel']) / fsd['fuelmul'], 1.0 / fsd['fuelpower']) * fsd['optmass'] string += 'Range : %.2f LY unladen\n %.2f LY laden\n' % ( multiplier / (mass + fuel) + jumpboost, multiplier / (mass + fuel + cargo) + jumpboost) except: if __debug__: raise if filename: with open(filename, 'wt') as h: h.write(string) return # Look for last ship of this type ship = companion.ship_file_name(data['ship'].get('shipName'), data['ship']['name']) regexp = re.compile( re.escape(ship) + '\.\d\d\d\d\-\d\d\-\d\dT\d\d\.\d\d\.\d\d\.txt') oldfiles = sorted( [x for x in os.listdir(config.get('outdir')) if regexp.match(x)]) if oldfiles: with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h: if h.read() == string: return # same as last time - don't write # Write filename = join( config.get('outdir'), '%s.%s.txt' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)))) with open(filename, 'wt') as h: h.write(string)
def journal_entry(cmdr, is_beta, system, station, entry, state): # Send any unsent events when switching accounts if cmdr and cmdr != this.cmdr: call() this.cmdr = cmdr this.multicrew = bool(state['Role']) if entry['event'] == 'LoadGame': # clear cached state this.undocked = False this.suppress_docked = False this.cargo = None this.materials = None this.lastcredits = 0 this.storedmodules = None this.loadout = None this.fleet = None this.shipswap = False this.system = None this.station = None elif entry['event'] in [ 'Resurrect', 'ShipyardBuy', 'ShipyardSell', 'SellShipOnRebuy' ]: # Events that mean a significant change in credits so we should send credits after next "Update" this.lastcredits = 0 elif entry['event'] in [ 'ShipyardNew', 'ShipyardSwap' ] or (entry['event'] == 'Location' and entry['Docked']): this.suppress_docked = True # Send location and status on new game or StartUp. Assumes Cargo is the last event on a new game (other than Docked). # Always send an update on Docked, FSDJump, Undocked+SuperCruise, Promotion and EngineerProgress. # Also send material and cargo (if changed) whenever we send an update. if config.getint('inara_out' ) and not is_beta and not this.multicrew and credentials( cmdr): try: old_events = len( this.events ) # Will only send existing events if we add a new event below # Send rank info to Inara on startup or change if (entry['event'] in ['StartUp', 'Cargo'] or this.newuser): for k, v in state['Rank'].iteritems(): if v is not None: add_event( 'setCommanderRankPilot', entry['timestamp'], OrderedDict([ ('rankName', k.lower()), ('rankValue', v[0]), ('rankProgress', v[1] / 100.0), ])) for k, v in state['Reputation'].iteritems(): if v is not None: add_event( 'setCommanderReputationMajorFaction', entry['timestamp'], OrderedDict([ ('majorfactionName', k.lower()), ('majorfactionReputation', v / 100.0), ])) elif entry['event'] == 'Promotion': for k, v in state['Rank'].iteritems(): if k in entry: add_event( 'setCommanderRankPilot', entry['timestamp'], OrderedDict([ ('rankName', k.lower()), ('rankValue', v[0]), ('rankProgress', 0), ])) # Send engineer status to Inara on change (not available on startup) if entry['event'] == 'EngineerProgress': if 'Rank' in entry: add_event( 'setCommanderRankEngineer', entry['timestamp'], OrderedDict([ ('engineerName', entry['Engineer']), ('rankValue', entry['Rank']), ])) else: add_event( 'setCommanderRankEngineer', entry['timestamp'], OrderedDict([ ('engineerName', entry['Engineer']), ('rankStage', entry['Progress']), ])) # Send PowerPlay status to Inara on change (not available on startup, and promotion not available at all) if entry['event'] == 'PowerplayJoin': add_event( 'setCommanderRankPower', entry['timestamp'], OrderedDict([ ('powerName', entry['Power']), ('rankValue', 1), ])) elif entry['event'] == 'PowerplayLeave': add_event( 'setCommanderRankPower', entry['timestamp'], OrderedDict([ ('powerName', entry['Power']), ('rankValue', 0), ])) elif entry['event'] == 'PowerplayDefect': add_event( 'setCommanderRankPower', entry['timestamp'], OrderedDict([ ('powerName', entry['ToPower']), ('rankValue', 1), ])) # Update ship if (state['ShipID'] and # Unknown if started in Fighter or SRV (entry['event'] in ['StartUp', 'Cargo'] or (entry['event'] == 'Loadout' and this.shipswap) or this.newuser)): data = OrderedDict([ ('shipType', state['ShipType']), ('shipGameID', state['ShipID']), ('shipName', state['ShipName']), # Can be None ('shipIdent', state['ShipIdent']), # Can be None ('isCurrentShip', True), ]) if state['HullValue']: data['shipHullValue'] = state['HullValue'] if state['ModulesValue']: data['shipModulesValue'] = state['ModulesValue'] data['shipRebuyCost'] = state['Rebuy'] add_event('setCommanderShip', entry['timestamp'], data) this.loadout = make_loadout(state) add_event('setCommanderShipLoadout', entry['timestamp'], this.loadout) this.shipswap = False # Update location if (entry['event'] in ['StartUp', 'Cargo'] or this.newuser) and system: this.undocked = False this.system = None this.station = None add_event( 'setCommanderTravelLocation', entry['timestamp'], OrderedDict([ ('starsystemName', system), ('stationName', station), # Can be None ])) elif entry['event'] == 'Docked': if this.undocked: # Undocked and now docking again. Don't send. this.undocked = False elif this.suppress_docked: # Don't send initial Docked event on new game this.suppress_docked = False else: add_event( 'addCommanderTravelDock', entry['timestamp'], OrderedDict([ ('starsystemName', system), ('stationName', station), ('shipType', state['ShipType']), ('shipGameID', state['ShipID']), ])) elif entry['event'] == 'Undocked': this.undocked = True this.station = None elif entry['event'] == 'SupercruiseEntry': if this.undocked: # Staying in system after undocking - send any pending events from in-station action add_event( 'setCommanderTravelLocation', entry['timestamp'], OrderedDict([ ('starsystemName', system), ('shipType', state['ShipType']), ('shipGameID', state['ShipID']), ])) this.undocked = False elif entry['event'] == 'FSDJump': this.undocked = False this.system = None add_event( 'addCommanderTravelFSDJump', entry['timestamp'], OrderedDict([ ('starsystemName', entry['StarSystem']), ('jumpDistance', entry['JumpDist']), ('shipType', state['ShipType']), ('shipGameID', state['ShipID']), ])) # Override standard URL functions if config.get('system_provider') == 'Inara': this.system_link['url'] = this.system if config.get('station_provider') == 'Inara': this.station_link['url'] = this.station or this.system # Send event(s) to Inara if entry['event'] == 'ShutDown' or len(this.events) > old_events: # Send cargo and materials if changed cargo = [ OrderedDict([('itemName', k), ('itemCount', state['Cargo'][k])]) for k in sorted(state['Cargo']) ] if this.cargo != cargo: add_event('setCommanderInventoryCargo', entry['timestamp'], cargo) this.cargo = cargo materials = [] for category in ['Raw', 'Manufactured', 'Encoded']: materials.extend([ OrderedDict([('itemName', k), ('itemCount', state[category][k])]) for k in sorted(state[category]) ]) if this.materials != materials: add_event('setCommanderInventoryMaterials', entry['timestamp'], materials) this.materials = materials # Queue a call to Inara call() except Exception as e: if __debug__: print_exc() return unicode(e) # # Events that don't need to be sent immediately but will be sent on the next mandatory event # # Send credits and stats to Inara on startup only - otherwise may be out of date if entry['event'] == 'LoadGame': add_event( 'setCommanderCredits', entry['timestamp'], OrderedDict([ ('commanderCredits', state['Credits']), ('commanderLoan', state['Loan']), ])) this.lastcredits = state['Credits'] elif entry['event'] == 'Statistics': add_event('setCommanderGameStatistics', entry['timestamp'], state['Statistics']) # may be out of date # Selling / swapping ships if entry['event'] == 'ShipyardNew': add_event( 'addCommanderShip', entry['timestamp'], OrderedDict([ ('shipType', entry['ShipType']), ('shipGameID', entry['NewShipID']), ])) this.shipswap = True # Want subsequent Loadout event to be sent immediately elif entry['event'] in [ 'ShipyardBuy', 'ShipyardSell', 'SellShipOnRebuy', 'ShipyardSwap' ]: if entry['event'] == 'ShipyardSwap': this.shipswap = True # Don't know new ship name and ident 'til the following Loadout event if 'StoreShipID' in entry: add_event( 'setCommanderShip', entry['timestamp'], OrderedDict([ ('shipType', entry['StoreOldShip']), ('shipGameID', entry['StoreShipID']), ('starsystemName', system), ('stationName', station), ])) elif 'SellShipID' in entry: add_event( 'delCommanderShip', entry['timestamp'], OrderedDict([ ('shipType', entry.get('SellOldShip', entry['ShipType'])), ('shipGameID', entry['SellShipID']), ])) elif entry['event'] == 'SetUserShipName': add_event( 'setCommanderShip', entry['timestamp'], OrderedDict([ ('shipType', state['ShipType']), ('shipGameID', state['ShipID']), ('shipName', state['ShipName']), # Can be None ('shipIdent', state['ShipIdent']), # Can be None ('isCurrentShip', True), ])) elif entry['event'] == 'ShipyardTransfer': add_event( 'setCommanderShipTransfer', entry['timestamp'], OrderedDict([ ('shipType', entry['ShipType']), ('shipGameID', entry['ShipID']), ('starsystemName', system), ('stationName', station), ('transferTime', entry['TransferTime']), ])) # Fleet if entry['event'] == 'StoredShips': fleet = sorted( [{ 'shipType': x['ShipType'], 'shipGameID': x['ShipID'], 'shipName': x.get('Name'), 'isHot': x['Hot'], 'starsystemName': entry['StarSystem'], 'stationName': entry['StationName'], 'marketID': entry['MarketID'], } for x in entry['ShipsHere']] + [ { 'shipType': x['ShipType'], 'shipGameID': x['ShipID'], 'shipName': x.get('Name'), 'isHot': x['Hot'], 'starsystemName': x.get( 'StarSystem'), # Not present for ships in transit 'marketID': x.get('ShipMarketID'), # " } for x in entry['ShipsRemote'] ], key=itemgetter('shipGameID')) if this.fleet != fleet: this.fleet = fleet this.events = [ x for x in this.events if x['eventName'] != 'setCommanderShip' ] # Remove any unsent for ship in this.fleet: add_event('setCommanderShip', entry['timestamp'], ship) # Loadout if entry['event'] == 'Loadout': loadout = make_loadout(state) if this.loadout != loadout: this.loadout = loadout this.events = [ x for x in this.events if x['eventName'] != 'setCommanderShipLoadout' or x['shipGameID'] != this.loadout['shipGameID'] ] # Remove any unsent for this ship add_event('setCommanderShipLoadout', entry['timestamp'], this.loadout) # Stored modules if entry['event'] == 'StoredModules': items = dict([(x['StorageSlot'], x) for x in entry['Items']]) # Impose an order modules = [] for slot in sorted(items): item = items[slot] module = OrderedDict([ ('itemName', item['Name']), ('itemValue', item['BuyPrice']), ('isHot', item['Hot']), ]) # Location can be absent if in transit if 'StarSystem' in item: module['starsystemName'] = item['StarSystem'] if 'MarketID' in item: module['marketID'] = item['MarketID'] if 'EngineerModifications' in item: module['engineering'] = OrderedDict([ ('blueprintName', item['EngineerModifications']) ]) if 'Level' in item: module['engineering']['blueprintLevel'] = item['Level'] if 'Quality' in item: module['engineering']['blueprintQuality'] = item[ 'Quality'] modules.append(module) if this.storedmodules != modules: # Only send on change this.storedmodules = modules this.events = [ x for x in this.events if x['eventName'] != 'setCommanderStorageModules' ] # Remove any unsent add_event('setCommanderStorageModules', entry['timestamp'], this.storedmodules) # Missions if entry['event'] == 'MissionAccepted': data = OrderedDict([ ('missionName', entry['Name']), ('missionGameID', entry['MissionID']), ('influenceGain', entry['Influence']), ('reputationGain', entry['Reputation']), ('starsystemNameOrigin', system), ('stationNameOrigin', station), ('minorfactionNameOrigin', entry['Faction']), ]) # optional mission-specific properties for (iprop, prop) in [ ( 'missionExpiry', 'Expiry' ), # Listed as optional in the docs, but always seems to be present ('starsystemNameTarget', 'DestinationSystem'), ('stationNameTarget', 'DestinationStation'), ('minorfactionNameTarget', 'TargetFaction'), ('commodityName', 'Commodity'), ('commodityCount', 'Count'), ('targetName', 'Target'), ('targetType', 'TargetType'), ('killCount', 'KillCount'), ('passengerType', 'PassengerType'), ('passengerCount', 'PassengerCount'), ('passengerIsVIP', 'PassengerVIPs'), ('passengerIsWanted', 'PassengerWanted'), ]: if prop in entry: data[iprop] = entry[prop] add_event('addCommanderMission', entry['timestamp'], data) elif entry['event'] == 'MissionAbandoned': add_event('setCommanderMissionAbandoned', entry['timestamp'], {'missionGameID': entry['MissionID']}) elif entry['event'] == 'MissionCompleted': for x in entry.get('PermitsAwarded', []): add_event('addCommanderPermit', entry['timestamp'], {'starsystemName': x}) data = OrderedDict([('missionGameID', entry['MissionID'])]) if 'Donation' in entry: data['donationCredits'] = entry['Donation'] if 'Reward' in entry: data['rewardCredits'] = entry['Reward'] if 'PermitsAwarded' in entry: data['rewardPermits'] = [{ 'starsystemName': x } for x in entry['PermitsAwarded']] if 'CommodityReward' in entry: data['rewardCommodities'] = [{ 'itemName': x['Name'], 'itemCount': x['Count'] } for x in entry['CommodityReward']] if 'MaterialsReward' in entry: data['rewardMaterials'] = [{ 'itemName': x['Name'], 'itemCount': x['Count'] } for x in entry['MaterialsReward']] add_event('setCommanderMissionCompleted', entry['timestamp'], data) elif entry['event'] == 'MissionFailed': add_event('setCommanderMissionFailed', entry['timestamp'], {'missionGameID': entry['MissionID']}) # Combat if entry['event'] == 'Died': data = OrderedDict([('starsystemName', system)]) if 'Killers' in entry: data['wingOpponentNames'] = [ x['Name'] for x in entry['Killers'] ] elif 'KillerName' in entry: data['opponentName'] = entry['KillerName'] add_event('addCommanderCombatDeath', entry['timestamp'], data) elif entry['event'] == 'Interdicted': add_event( 'addCommanderCombatInterdicted', entry['timestamp'], OrderedDict([ ('starsystemName', system), ('opponentName', entry['Interdictor']), ('isPlayer', entry['IsPlayer']), ('isSubmit', entry['Submitted']), ])) elif entry['event'] == 'Interdiction': data = OrderedDict([ ('starsystemName', system), ('isPlayer', entry['IsPlayer']), ('isSuccess', entry['Success']), ]) if 'Interdictor' in entry: data['opponentName'] = entry['Interdictor'] elif 'Faction' in entry: data['opponentName'] = entry['Faction'] elif 'Power' in entry: data['opponentName'] = entry['Power'] add_event('addCommanderCombatInterdiction', entry['timestamp'], data) elif entry['event'] == 'EscapeInterdiction': add_event( 'addCommanderCombatInterdictionEscape', entry['timestamp'], OrderedDict([ ('starsystemName', system), ('opponentName', entry['Interdictor']), ('isPlayer', entry['IsPlayer']), ])) elif entry['event'] == 'PVPKill': add_event( 'addCommanderCombatKill', entry['timestamp'], OrderedDict([ ('starsystemName', system), ('opponentName', entry['Victim']), ])) # Community Goals if entry['event'] == 'CommunityGoal': this.events = [ x for x in this.events if x['eventName'] not in ['setCommunityGoal', 'setCommanderCommunityGoalProgress'] ] # Remove any unsent for goal in entry['CurrentGoals']: data = OrderedDict([ ('communitygoalGameID', goal['CGID']), ('communitygoalName', goal['Title']), ('starsystemName', goal['SystemName']), ('stationName', goal['MarketName']), ('goalExpiry', goal['Expiry']), ('isCompleted', goal['IsComplete']), ('contributorsNum', goal['NumContributors']), ('contributionsTotal', goal['CurrentTotal']), ]) if 'TierReached' in goal: data['tierReached'] = int(goal['TierReached'].split()[-1]) if 'TopRankSize' in goal: data['topRankSize'] = goal['TopRankSize'] if 'TopTier' in goal: data['tierMax'] = int(goal['TopTier']['Name'].split()[-1]) data['completionBonus'] = goal['TopTier']['Bonus'] add_event('setCommunityGoal', entry['timestamp'], data) data = OrderedDict([ ('communitygoalGameID', goal['CGID']), ('contribution', goal['PlayerContribution']), ('percentileBand', goal['PlayerPercentileBand']), ]) if 'Bonus' in goal: data['percentileBandReward'] = goal['Bonus'] if 'PlayerInTopRank' in goal: data['isTopRank'] = goal['PlayerInTopRank'] add_event('setCommanderCommunityGoalProgress', entry['timestamp'], data) this.newuser = False
def journal_entry(cmdr, is_beta, system, station, entry, state): # Recursively filter '*_Localised' keys from dict def filter_localised(d): filtered = OrderedDict() for k, v in d.iteritems(): if k.endswith('_Localised'): pass elif hasattr(v, 'iteritems'): # dict -> recurse filtered[k] = filter_localised(v) elif isinstance(v, list): # list of dicts -> recurse filtered[k] = [ filter_localised(x) if hasattr(x, 'iteritems') else x for x in v ] else: filtered[k] = v return filtered # Track location if entry['event'] in ['Location', 'FSDJump', 'Docked']: if entry['event'] == 'Location': this.planet = entry.get('Body') if entry.get( 'BodyType') == 'Planet' else None elif entry['event'] == 'FSDJump': this.planet = None if 'StarPos' in entry: this.coordinates = tuple(entry['StarPos']) elif this.systemaddress != entry.get('SystemAddress'): this.coordinates = None # Docked event doesn't include coordinates this.systemaddress = entry.get('SystemAddress') elif entry['event'] == 'ApproachBody': this.planet = entry['Body'] elif entry['event'] in ['LeaveBody', 'SupercruiseEntry']: this.planet = None # 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'] == 'Location' or entry['event'] == 'FSDJump' or entry['event'] == 'Docked' or entry['event'] == 'Scan' and this.coordinates)): # strip out properties disallowed by the schema for thing in [ 'ActiveFine', 'CockpitBreach', 'BoostUsed', 'FuelLevel', 'FuelUsed', 'JumpDist', 'Latitude', 'Longitude', 'Wanted' ]: entry.pop(thing, None) if 'Factions' in entry: # Filter faction state. `entry` is a shallow copy so replace 'Factions' value rather than modify in-place. entry['Factions'] = [{ k: v for k, v in f.iteritems() if k not in [ 'HappiestSystem', 'HomeSystem', 'MyReputation', 'SquadronFaction' ] } for f in entry['Factions']] # add planet to Docked event for planetary stations if known if entry['event'] == 'Docked' and this.planet: entry['Body'] = this.planet entry['BodyType'] = 'Planet' # add mandatory StarSystem, StarPos and SystemAddress properties to Scan events if 'StarSystem' not in entry: entry['StarSystem'] = system if 'StarPos' not in entry: entry['StarPos'] = list(this.coordinates) if 'SystemAddress' not in entry and this.systemaddress: entry['SystemAddress'] = this.systemaddress try: this.eddn.export_journal_entry(cmdr, is_beta, filter_localised(entry)) except requests.exceptions.RequestException as e: if __debug__: print_exc() return _("Error: Can't connect to EDDN") except Exception as e: if __debug__: print_exc() return unicode(e) elif (config.getint('output') & config.OUT_MKT_EDDN and not state['Captain'] and entry['event'] in ['Market', 'Outfitting', 'Shipyard']): try: if this.marketId != entry['MarketID']: this.commodities = this.outfitting = this.shipyard = None this.marketId = entry['MarketID'] with open( join( config.get('journaldir') or config.default_journal_dir, '%s.json' % entry['event']), 'rb') as h: entry = json.load(h) if entry['event'] == 'Market': this.eddn.export_journal_commodities(cmdr, is_beta, entry) elif entry['event'] == 'Outfitting': this.eddn.export_journal_outfitting(cmdr, is_beta, entry) elif entry['event'] == 'Shipyard': this.eddn.export_journal_shipyard(cmdr, is_beta, entry) except requests.exceptions.RequestException as e: if __debug__: print_exc() return _("Error: Can't connect to EDDN") except Exception as e: if __debug__: print_exc() return unicode(e)
def get_blur_radius(self): return config.getint("lyrics", "blur_radius")
def main(): host = config.get('SST Server', 'host') port = config.getint('SST Server', 'port') run_server(port, host, Service=SSTService, template_path='templates')
def export(data, edsmlookupfn): querytime = config.getint('querytime') or int(time.time()) writelog(querytime, data['lastSystem']['name'], edsmlookupfn)
def export(data, filename=None): # Add a leaf to a dictionary, creating empty dictionaries along the branch if necessary def addleaf(data, to, props): # special handling for completely empty trees p = props[0] if p in data and not data[p]: to[p] = data[p] return # Does the leaf exist ? tail = data for p in props: if not hasattr(data, 'get') or p not in tail: return else: tail = tail[p] for p in props[:-1]: if not hasattr(data, 'get') or p not in data: return elif p not in to: to[p] = {} elif not hasattr(to, 'get'): return # intermediate is not a dictionary - inconsistency! data = data[p] to = to[p] p = props[-1] to[p] = data[p] querytime = config.getint('querytime') or int(time.time()) # subset of "ship" that's not noisy ship = {} for props in [ ('alive', ), ('cargo', 'capacity'), ('free', ), ('fuel', 'main', 'capacity'), ('fuel', 'reserve', 'capacity'), ('fuel', 'superchargedFSD'), ('id', ), ('name', ), ('value', 'hull'), ('value', 'modules'), ('value', 'unloaned'), ]: addleaf(data['ship'], ship, props) ship['modules'] = {} for slot in data['ship'].get('modules', {}): for prop in [ 'free', 'id', 'modifiers', 'name', 'on', 'priority', 'recipeLevel', 'recipeName', 'recipeValue', 'unloaned', 'value' ]: addleaf(data['ship']['modules'], ship['modules'], (slot, 'module', prop)) string = json.dumps(ship, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8') if filename: with open(filename, 'wt') as h: h.write(string) return # Look for last ship of this type ship = companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name']) # Use in-game name regexp = re.compile( re.escape(ship) + '\.\d\d\d\d\-\d\d\-\d\dT\d\d\.\d\d\.\d\d\.txt') oldfiles = sorted( [x for x in os.listdir(config.get('outdir')) if regexp.match(x)]) if oldfiles: with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h: if h.read() == string: return # same as last time - don't write # Write filename = join( config.get('outdir'), '%s.%s.txt' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)))) with open(filename, 'wt') as h: h.write(string)
def apply(self, root): theme = config.getint('theme') self._colors(root, theme) # Apply colors for widget in self.widgets: if isinstance(widget, tk.BitmapImage): # not a widget widget.configure(foreground=self.current['foreground'], background=self.current['background']) elif 'cursor' in widget.keys() and str( widget['cursor']) not in ['', 'arrow']: # Hack - highlight widgets like HyperlinkLabel with a non-default cursor widget.configure(foreground=self.current['highlight'], background=self.current['background'], font=self.current['font']) elif 'activeforeground' in widget.keys(): # e.g. tk.Button, tk.Label, tk.Menu widget.configure( foreground=self.current['foreground'], background=self.current['background'], activeforeground=self.current['activeforeground'], activebackground=self.current['activebackground'], disabledforeground=self.current['disabledforeground'], font=self.current['font']) elif 'foreground' in widget.keys(): # e.g. ttk.Label widget.configure(foreground=self.current['foreground'], background=self.current['background'], font=self.current['font']) elif 'background' in widget.keys(): # e.g. Frame widget.configure(background=self.current['background']) widget.configure( highlightbackground=self.current['disabledforeground']) for pair, gridopts in self.widgets_pair: for widget in pair: widget.grid_remove() if isinstance(pair[0], tk.Menu): if theme: root['menu'] = '' pair[theme].grid(**gridopts) else: root['menu'] = pair[0] else: pair[theme].grid(**gridopts) if self.active == theme: return # Don't need to mess with the window manager else: self.active = theme if platform == 'darwin': from AppKit import NSApplication, NSAppearance, NSMiniaturizableWindowMask, NSResizableWindowMask root.update_idletasks() # need main window to be created appearance = NSAppearance.appearanceNamed_( theme and 'NSAppearanceNameVibrantDark' or 'NSAppearanceNameAqua') for window in NSApplication.sharedApplication().windows(): window.setStyleMask_( window.styleMask() & ~(NSMiniaturizableWindowMask | NSResizableWindowMask) ) # disable zoom window.setAppearance_(appearance) elif platform == 'win32': GWL_STYLE = -16 WS_MAXIMIZEBOX = 0x00010000 # tk8.5.9/win/tkWinWm.c:342 GWL_EXSTYLE = -20 WS_EX_APPWINDOW = 0x00040000 WS_EX_LAYERED = 0x00080000 GetWindowLongW = ctypes.windll.user32.GetWindowLongW SetWindowLongW = ctypes.windll.user32.SetWindowLongW root.overrideredirect(theme and 1 or 0) root.attributes("-transparentcolor", theme > 1 and 'grey4' or '') root.withdraw() root.update_idletasks( ) # Size and windows styles get recalculated here hwnd = ctypes.windll.user32.GetParent(root.winfo_id()) SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) & ~WS_MAXIMIZEBOX) # disable maximize SetWindowLongW(hwnd, GWL_EXSTYLE, theme > 1 and WS_EX_APPWINDOW | WS_EX_LAYERED or WS_EX_APPWINDOW) # Add to taskbar root.deiconify() root.wait_visibility( ) # need main window to be displayed before returning else: root.withdraw() # https://www.tcl-lang.org/man/tcl/TkCmd/wm.htm#M19 # https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#STACKINGORDER root.attributes('-type', theme and 'splash' or 'normal') root.update_idletasks() # Size gets recalculated here root.deiconify() root.wait_visibility( ) # need main window to be displayed before returning if dpy and theme: # Try to display in the taskbar xroot = Window() parent = Window() children = Window() nchildren = c_uint() XQueryTree(dpy, root.winfo_id(), byref(xroot), byref(parent), byref(children), byref(nchildren)) # https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472615568 xevent = XEvent(xclient=XClientMessageEvent( ClientMessage, 0, 0, None, parent, net_wm_state, 32, XClientMessageEvent_data(l=(_NET_WM_STATE_REMOVE, net_wm_state_skip_pager, net_wm_state_skip_taskbar, 1, 0)))) XSendEvent(dpy, xroot, False, SubstructureRedirectMask | SubstructureNotifyMask, byref(xevent)) xevent = XEvent(xclient=XClientMessageEvent( ClientMessage, 0, 0, None, parent, net_wm_state, 32, XClientMessageEvent_data(l=(_NET_WM_STATE_REMOVE, net_wm_state_sticky, 0, 1, 0)))) XSendEvent(dpy, xroot, False, SubstructureRedirectMask | SubstructureNotifyMask, byref(xevent)) XFlush(dpy) if not self.minwidth: self.minwidth = root.winfo_width( ) # Minimum width = width on first creation root.minsize(self.minwidth, -1)
#!/usr/bin/python # -*- coding: UTF-8 -*- from sqlalchemy.exc import OperationalError from config import config, config_file_path from definitions import API_DIR, API_ROOT_PACKAGE from engine import app import loader import logging import database # Read Server configuration host = config.get('Server', 'host', fallback='localhost') port = config.getint('Server', 'port', fallback=8080) debug = config.getboolean('Server', 'debug', fallback=False) # Read SSL configuration enableSSL = config.getboolean('SSL', 'enable', fallback=False) cert = config.get('SSL', 'cert', fallback=None) key = config.get('SSL', 'key', fallback=None) # Logging configuration loglevel = config.get('Log', 'level', fallback=logging.INFO) logfile = config.get('Log', 'file', fallback=None) # Database config db_debug = config.getboolean('Database', 'logs', fallback=False) db_driver = config.get('Database', 'driver', fallback='sqlite') db_dialect = config.get('Database', 'dialect', fallback='') db_host = config.get('Database', 'host', fallback='') db_port = config.get('Database', 'port', fallback='')
def onenter(self, event=None): if config.getint('theme') > 1: self.w.attributes("-transparentcolor", '') self.blank_menubar.grid_remove() self.theme_menubar.grid(row=0, columnspan=2, sticky=tk.NSEW)
def get_outline_width(self): return config.getint("lyrics", "outline_width")