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()
Ejemplo n.º 2
0
    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()
Ejemplo n.º 3
0
	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
Ejemplo n.º 4
0
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()
Ejemplo n.º 5
0
 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()
Ejemplo n.º 6
0
    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()
Ejemplo n.º 7
0
	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()        
Ejemplo n.º 9
0
 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()
Ejemplo n.º 10
0
    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()        
Ejemplo n.º 11
0
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()
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
 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 = []
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
Archivo: vm.py Proyecto: openSUSE/vdsm
 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)
Ejemplo n.º 16
0
Archivo: vm.py Proyecto: openSUSE/vdsm
 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"}}
Ejemplo n.º 17
0
Archivo: vm.py Proyecto: openSUSE/vdsm
    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)
Ejemplo n.º 18
0
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()
Ejemplo n.º 19
0
 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()
Ejemplo n.º 21
0
    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()
Ejemplo n.º 22
0
        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
Ejemplo n.º 23
0
        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
Ejemplo n.º 24
0
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()
Ejemplo n.º 25
0
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'
Ejemplo n.º 26
0
    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()
Ejemplo n.º 27
0
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()
Ejemplo n.º 28
0
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()
Ejemplo n.º 30
0
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()
Ejemplo n.º 31
0
 def _destroy(self):
     self.parent.wm_attributes('-topmost',
                               config.getint('always_ontop') and 1 or 0)
     self.destroy()
     if self.callback: self.callback(None)
Ejemplo n.º 32
0
    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()
Ejemplo n.º 33
0
 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()
Ejemplo n.º 35
0
def start_http(host, port):
    logger.warning(" RUNNING IN NON SSL CONTEXT ")
    web.run_app(
        app, host=host, port=config.getint("Webserver", "port"),
    )
Ejemplo n.º 36
0
    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
Ejemplo n.º 37
0
                            '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')
Ejemplo n.º 38
0
    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)
Ejemplo n.º 43
0
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)
Ejemplo n.º 44
0
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)
Ejemplo n.º 45
0
    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)
Ejemplo n.º 46
0
# 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()
Ejemplo n.º 47
0
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
Ejemplo n.º 48
0
    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
Ejemplo n.º 49
0
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))
Ejemplo n.º 50
0
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)
Ejemplo n.º 51
0
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
Ejemplo n.º 52
0
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)
Ejemplo n.º 53
0
 def get_blur_radius(self):
     return config.getint("lyrics", "blur_radius")
Ejemplo n.º 54
0
def main():
    host = config.get('SST Server', 'host')
    port = config.getint('SST Server', 'port')
    run_server(port, host, Service=SSTService, template_path='templates')
Ejemplo n.º 55
0
def export(data, edsmlookupfn):

    querytime = config.getint('querytime') or int(time.time())

    writelog(querytime, data['lastSystem']['name'], edsmlookupfn)
Ejemplo n.º 56
0
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)
Ejemplo n.º 57
0
    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)
Ejemplo n.º 58
0
#!/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)
Ejemplo n.º 60
0
 def get_outline_width(self):
     return config.getint("lyrics", "outline_width")