def locateTileset(which): """locate the file with a tileset""" path = KStandardDirs.locate("kmahjonggtileset", QString(which)) if path is None: logException(TileException('cannot find kmahjonggtileset %s' % (which))) return QString(path)
def pixmap(self, size): """returns a background pixmap or None for isPlain""" self.__pmap = QBrush() if not self.isPlain: width = size.width() height = size.height() if self.tiled: width = self.imageWidth height = self.imageHeight cachekey = '{name}W{width}H{height}'.format(name=self.name, width=width, height=height) self.__pmap = QPixmapCache.find(cachekey) if not self.__pmap: renderer = QSvgRenderer(self.graphicsPath) if not renderer.isValid(): logException( i18n( 'file <filename>%1</filename> contains no valid SVG', self.graphicsPath)) self.__pmap = QPixmap(width, height) self.__pmap.fill(Qt.transparent) painter = QPainter(self.__pmap) renderer.render(painter) QPixmapCache.insert(cachekey, self.__pmap) return self.__pmap
def __startLocalServer(self): """start a local server""" try: args = self.__findServerProgram() if self.useSocket or os.name == 'nt': # for nt --socket tells the server to bind to 127.0.0.1 args.append('--socket=%s' % socketName()) if removeIfExists(socketName()): logInfo( i18n('removed stale socket <filename>%1</filename>', socketName())) if not self.useSocket: args.append('--port=%d' % self.port) if self.isLocalGame: args.append('--db={}'.format( os.path.normpath(os.path.join(appdataDir(), 'local3.db')))) if Debug.argString: args.append('--debug=%s' % Debug.argString) if os.name == 'nt': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW else: startupinfo = None process = subprocess.Popen( args, startupinfo=startupinfo) # , shell=os.name == 'nt') if Debug.connections: logDebug( i18n( 'started the local kajongg server: pid=<numid>%1</numid> %2', process.pid, ' '.join(args))) except OSError as exc: exc.filename = ' '.join(args) logException(exc)
def close(self): log.debug('closing down libgphoto2 client') if not self.opened: return log.debug('closing down gphotoremote.exe') try: self.api.stop() except: log.logException('failed trying to stop gphotoremote.exe main loop',log.WARNING) start = time.time() while self.process.poll() is None and (time.time()-start) < 2: time.sleep(0.05) if self.process.poll(): log.warning('failed to shut down gphotoremote.exe -- trying to kill it') try: self.process.kill() except: log.logException('failed to kill gphotoremote.exe -- please kill the process manually using the Task Manager',log.ERROR) else: log.debug('gphotoremote.exe closed down cleanly') try: uriPath = os.path.join(self.basePath,'uri.txt') if os.path.exists(uriPath): os.remove(uriPath) except: pass self.opened = False
def handle_accept(self): try: sock, addr = self.accept() log.log('Incoming connection from %s' % repr(addr)) self.network.makeConnectionFromSocket(sock) except: log.logException()
def optimizeComplete(self): optimizer = self.optimizer self.optimizer = None if optimizer.exc_info: log.logException(*optimizer.exc_info) return logging.debug('Optimize done: %s' % ','.join(map(str, optimizer.res.x))) self.parameterChanged_peaks.block() for p, v in zip(optimizer.params, optimizer.res.x): p.setValue(v) for p, v in optimizer.calcConstraintValues(optimizer.res.x): p.setValue(v) self.parameterChanged_peaks.unblock() for f in optimizer.srcfuncs: self.parameterChanged_peaks(f) self.calcIntersections() self.calcPeakPositions() if optimizer.callback: optimizer.callback(optimizer.exc_info is None, optimizer.params, optimizer.res.x)
def byName(self, playerName): """lookup the player by name""" for player in self: if player.name == playerName: return player logException("no player has name %s - we have %s" % (playerName, [x.name for x in self]))
def __upgrade(self): """upgrade the structure of an existing kajongg database""" try: Internal.db = DBHandle(self.path) if isPython3: allVersions = list(['4.13.0', '8300']) else: allVersions = list(['4.13.0', '8200']) assert allVersions[-1] == str(Internal.defaultPort), '{} != {}'.format( allVersions[-1], str(Internal.defaultPort)) # skip versions before current db versions: currentVersion = self.__currentVersion() while allVersions and allVersions[0] <= currentVersion: allVersions = allVersions[1:] for version in allVersions: currentVersion = self.__currentVersion() with Internal.db: # transaction updateMethodName = 'updateToVersion{}'.format(version.replace('.', '_')) if hasattr(self, updateMethodName): getattr(self, updateMethodName)() Query('UPDATE general SET schemaversion=?', (version,)) logInfo(m18n('Database %1 updated from schema %2 to %3', Internal.db.path, currentVersion, version), showDialog=True) except sqlite3.Error as exc: logException( u'opening %s: %s' % (unicodeString(self.path), exc.message)) finally: Internal.db.close(silent=True)
def __handleReconnectTimeout(self): # Timeout was pointless if we're already connected: if self.isConnected(): return log.log("Link reconnect timeout: connecting") URL = urlparse(self.remoteURL) remoteHost = URL.hostname remotePort = settings.defaultPort if URL.port == None else URL.port #TODO: maybe read and check remoteID in URL? #Or maybe remove redundancy between remoteID and remoteURL. try: self.connection = network.Connection(self.context, (remoteHost, remotePort)) self.__registerConnectionHandlers() log.log("Link: Connection established (created)") # Send a link establishment message: self.connection.sendMessage(messages.Link(self.remoteID, self.dice)) # Send URLs self.connection.sendMessage(messages.MyURLs([self.localURL])) except: log.log("Link: Connection creation failed:") log.logException() if self.connection != None: self.connection.close() self.connection = None # Register again, to retry in the future: self.__registerReconnectTimeoutHandler()
def shutdownHumanClients(exception=None): """close connections to servers except maybe one""" clients = HumanClient.humanClients def done(): """return True if clients is cleaned""" return len(clients) == 0 or (exception and clients == [exception]) def disconnectedClient(dummyResult, client): """now the client is really disconnected from the server""" if client in clients: # HumanClient.serverDisconnects also removes it! clients.remove(client) if isinstance(exception, Failure): logException(exception) for client in clients[:]: if client.tableList: client.tableList.hide() if done(): return succeed(None) deferreds = [] for client in clients[:]: if client != exception and client.connection: deferreds.append( client.logout( ).addCallback( disconnectedClient, client)) return DeferredList(deferreds)
def isConnected(self): """ Return value: bool Returns whether this object is connected. """ if self.access is None: log.log( 'Bitcoind access object does not exist (e.g. because the Bitcoin-RPC URL is incorrect)' ) return False try: info = self.access.getinfo() except: log.log( 'Bitcoind access object exists, but gives an error when executing a command:' ) log.logException() return False log.log('Connected to bitcoind version %s' % info['version']) return True
def execute(self, script, scriptName='<unknown>'): try: return self.camera.execute(script) except CHDKError: log.logException( 'LUA script error in %s->%s' % (self.getName(), scriptName), log.ERROR)
def processReceivedMessageData(self, msgData): log.log("Received data: %s\n" % msgData) try: container = serializable.deserialize(msgData) if 'received' in container.keys(): #Process received confirmation: index = container['received'] self.network.callback.handleMessage( messages.Confirmation(localID=self.localID, index=index) ) elif 'message' in container.keys(): index = container['index'] msg = container['message'] #print "Got message: ", str(msg.__class__) if isinstance(msg, messages.Connect): if not (self.localID is None): raise Exception("Received connect message while already connected") self.localID = msg.ID self.dice = msg.dice self.network.checkForDuplicateConnections(self.localID) else: #Send confirmation on non-connect messages: confirmation = {'received': index} self.send(serializable.serialize(confirmation) + '\n') #TODO: filter for acceptable message types, IDs etc. before #sending them to a general-purpose message handler self.network.callback.handleMessage(msg) else: log.log("Received message with invalid format") except Exception as e: log.logException()
def renderer(self): """initialise the svg renderer with the selected svg file""" if self.__renderer is None: self.__renderer = QSvgRenderer(self.__graphicspath) if not self.__renderer.isValid(): logException(TileException( m18n( 'file <filename>%1</filename> contains no valid SVG'), self.__graphicspath)) distance = 0 if self.desktopFileName == 'classic': distance = 2 distanceSize = QSizeF(distance, distance) self.faceSize = self.__renderer.boundsOnElement( 'BAMBOO_1').size() + distanceSize self.tileSize = self.__renderer.boundsOnElement( 'TILE_2').size() + distanceSize if not Internal.scaleScene: self.faceSize /= 2 self.tileSize /= 2 shW = self.shadowWidth() shH = self.shadowHeight() self.__shadowOffsets = [ [(-shW, 0), (0, 0), (0, shH), (-shH, shW)], [(0, 0), (shH, 0), (shW, shH), (0, shW)], [(0, -shH), (shH, -shW), (shW, 0), (0, 0)], [(-shW, -shH), (0, -shW), (0, 0), (-shH, 0)]] return self.__renderer
def byName(self, playerName): """lookup the player by name""" for player in self: if player.name == playerName: return player logException( "no player has name %s - we have %s" % (playerName, [x.name for x in self]))
def playerByName(self, playerName): """return None or the matching player""" if playerName is None: return None for myPlayer in self.players: if myPlayer.name == playerName: return myPlayer logException('Move references unknown player %s' % playerName)
def locate(cls, which): """locate the file with a resource""" for directory in cls.__directories(): path = os.path.join(directory, which) if os.path.exists(path): return path logException('cannot find kmahjongg%s %s in %s' % (cls.resourceName, which, cls.__directories()))
def __noTilesetFound(cls): """No resources found""" directories = '\n\n' + '\n'.join(cls.__directories()) logException( i18n( 'cannot find any %1 in the following directories, ' 'is libkmahjongg installed?', cls.resourceName) + directories) # TODO: nicht schoen
def add(self, rule): """use add instead of append""" if rule.key() in self: logException( '%s is already defined as %s, not accepting new rule %s/%s' % (rule.key(), self[rule.key()].definition, rule.name, rule.definition)) self[rule.key()] = rule
def validate(self): """check for validity""" payers = int(self.options.get('payers', 1)) payees = int(self.options.get('payees', 1)) if not 2 <= payers + payees <= 4: logException( i18nc('%1 can be a sentence', '%4 have impossible values %2/%3 in rule "%1"', self.name, payers, payees, 'payers/payees'))
def __noTilesetFound(): """No tilesets found""" directories = '\n'.join( str(x) for x in KGlobal.dirs().resourceDirs("kmahjonggtileset")) directories = '\n\n' + directories logException( TileException(m18n( 'cannot find any tileset in the following directories, ' 'is libkmahjongg installed?') + directories))
def lightSource(self, lightSource): """set active lightSource""" if self._lightSource != lightSource: if lightSource not in LIGHTSOURCES: logException( TileException( 'lightSource %s illegal' % lightSource)) self._reload(self.tileset, lightSource)
def validate(self): """check for validity""" payers = int(self.options.get('payers', 1)) payees = int(self.options.get('payees', 1)) if not 2 <= payers + payees <= 4: logException( m18nc( '%1 can be a sentence', '%4 have impossible values %2/%3 in rule "%1"', self.name, payers, payees, 'payers/payees'))
def __scanHandId(self, string, stringIdx): """gets the --game option. stringIdx 0 is the part in front of .. stringIdx 1 is the part after .. """ # pylint: disable=too-many-return-statements,too-many-branches if not string: return seed = int(string.split('/')[0]) assert self.seed is None or self.seed == seed, string self.seed = seed if '/' not in string: if stringIdx == 1: self.roundsFinished = 100 return string1 = string.split('/')[1] if not string1: logException('--game=%s must specify the wanted round' % string) parts = string1.split('..') if stringIdx == 1 and len(parts) == 2 and parts[1] == '': self.roundsFinished = 100 return if stringIdx == 0 and len(parts) == 2 and parts[0] == '': return if stringIdx == 1 and len(parts) == 2 and parts[1] == '': self.roundsFinished = 100 return handId = parts[min(stringIdx, len(parts) - 1)] if handId[0].lower() not in 'eswn': logException('--game=%s must specify the round wind' % string) handWind = Wind(handId[0]) ruleset = self.game.ruleset self.roundsFinished = handWind.__index__() if self.roundsFinished > ruleset.minRounds: logWarning( u'Ruleset %s has %d minimum rounds but you want round %d(%s)' % (ruleset.name, ruleset.minRounds, self.roundsFinished + 1, handWind)) self.roundsFinished = ruleset.minRounds return self.rotated = int(handId[1]) - 1 if self.rotated > 3: logWarning( u'You want %d rotations, reducing to maximum of 3' % self.rotated) self.rotated = 3 return for char in handId[2:]: if char < 'a': logWarning(u'you want %s, changed to a' % char) char = 'a' if char > 'z': logWarning(u'you want %s, changed to z' % char) char = 'z' self.notRotated = self.notRotated * 26 + ord(char) - ord('a') + 1
def __scanHandId(self, string, stringIdx): """gets the --game option. stringIdx 0 is the part in front of .. stringIdx 1 is the part after .. """ # pylint: disable=too-many-return-statements,too-many-branches if not string: return seed = int(string.split('/')[0]) assert self.seed is None or self.seed == seed, string self.seed = seed if '/' not in string: if stringIdx == 1: self.roundsFinished = 100 return string1 = string.split('/')[1] if not string1: logException('--game=%s must specify the wanted round' % string) parts = string1.split('..') if stringIdx == 1 and len(parts) == 2 and parts[1] == '': self.roundsFinished = 100 return if stringIdx == 0 and len(parts) == 2 and parts[0] == '': return if stringIdx == 1 and len(parts) == 2 and parts[1] == '': self.roundsFinished = 100 return handId = parts[min(stringIdx, len(parts) - 1)] if handId[0].lower() not in 'eswn': logException('--game=%s must specify the round wind' % string) handWind = Wind(handId[0]) ruleset = self.game.ruleset self.roundsFinished = handWind.__index__() if self.roundsFinished > ruleset.minRounds: logWarning( 'Ruleset %s has %d minimum rounds but you want round %d(%s)' % (ruleset.name, ruleset.minRounds, self.roundsFinished + 1, handWind)) self.roundsFinished = ruleset.minRounds return self.rotated = int(handId[1]) - 1 if self.rotated > 3: logWarning('You want %d rotations, reducing to maximum of 3' % self.rotated) self.rotated = 3 return for char in handId[2:]: if char < 'a': logWarning('you want %s, changed to a' % char) char = 'a' if char > 'z': logWarning('you want %s, changed to z' % char) char = 'z' self.notRotated = self.notRotated * 26 + ord(char) - ord('a') + 1
def findFreePort(self): """find an unused port on the current system. used when we want to start a local server on windows""" assert self.isLocalHost for port in chain([Internal.defaultPort], range(2000, 19000)): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(1) try: sock.connect((self.host, port)) sock.close() except socket.error: return port logException('cannot find a free port')
def __computeMd5sum(self): """update md5sum file. If it changed, return True. If unchanged or no ogg files exist, remove archive and md5sum and return False. If ogg files exist but no archive, return True.""" if self.__md5sum: # we already checked return md5FileName = os.path.join(self.directory, 'md5sum') archiveExists = os.path.exists(self.archiveName()) ogg = self.oggFiles() if not ogg: removeIfExists(self.archiveName()) removeIfExists(md5FileName) self.__md5sum = None logDebug('no ogg files in %s' % self) return md5sum = md5() for oggFile in ogg: md5sum.update( open(os.path.join(self.directory, oggFile), 'rb').read()) # the md5 stamp goes into the old archive directory 'username' self.__md5sum = md5sum.hexdigest() existingMd5sum = self.savedmd5Sum() md5Name = self.md5FileName() if self.__md5sum != existingMd5sum: if Debug.sound: if not os.path.exists(md5Name): logDebug('creating new %s' % md5Name) else: logDebug('md5sum %s changed, rewriting %s with %s' % (existingMd5sum, md5Name, self.__md5sum)) try: open(md5Name, 'w').write('%s\n' % self.__md5sum) except BaseException as exception: logException('\n'.join([ i18n('cannot write <filename>%1</filename>: %2', md5Name, str(exception)), i18n( 'The voice files have changed, their checksum has changed.' ), i18n( 'Please reinstall kajongg or do, with sufficient permissions:' ), 'cd {} ; cat *.ogg | md5sum > md5sum'.format( self.directory) ])) if archiveExists: archiveIsOlder = os.path.getmtime(md5Name) > os.path.getmtime( self.archiveName()) if self.__md5sum != existingMd5sum or archiveIsOlder: os.remove(self.archiveName())
def run(self): """ The thread function. Intended for internal use by Amiko. Not intended to be part of the API. """ log.log("\n\nAmiko thread started") #Start listening listener = network.Listener(self.context, self.settings.listenHost, self.settings.listenPort) #TODO: (re-)enable creation of new transactions self.__stop = False while True: self.context.dispatchNetworkEvents() self.context.dispatchTimerEvents() self.watchdog.check() with self._commandFunctionLock: s = self._commandFunction if s != None: try: self._commandReturnValue = s[0](self, *s[1], **s[2]) except Exception as e: self._commandReturnValue = e log.logException() self._commandProcessed.set() self._commandFunction = None if self.__doSave: self.__saveState() self.__doSave = False self.__movePayeesToPayLog() if self.__stop: #TODO: stop creation of new transactions #TODO: only break once there are no more open transactions break #This closes all network connections etc. self.context.sendSignal(None, event.signals.quit) log.log("Amiko thread terminated\n\n")
def processReceivedMessageData(self, msgData): log.log("Received from %s: %s\n" % (str(self.localID), msgData)) try: container = serializable.deserialize(msgData) if 'received' in container.keys(): #Process received confirmation: index = container['received'] self.network.callback.handleMessage( messages.Confirmation(localID=self.localID, index=index)) elif 'message' in container.keys(): index = container['index'] msg = container['message'] if msg.__class__ == messages.ConnectLink: if not (self.localID is None): raise Exception( "Received ConnectLink message while already connected" ) self.localID = msg.ID self.dice = msg.dice self.network.checkForDuplicateConnections(self.localID) elif msg.__class__ == messages.Pay: if not (self.localID is None): raise Exception( "Received Pay message while already connected") if self.network.interfaceExists(msg.ID): log.log( "Received Pay message for payment that already has a connection; closing the new one." ) self.network.closeConnection(self) self.localID = msg.ID else: #Send confirmation on non-connect messages: confirmation = {'received': index} self.send(serializable.serialize(confirmation) + '\n') #Always set/overwrite the ID attribute with our own localID msg.ID = self.localID #TODO: filter for acceptable message types etc. before #sending them to a general-purpose message handler self.network.callback.handleMessage(msg) else: log.log("Received message with invalid format") except Exception as e: log.logException()
def run(self): try: while 1: if self.app.closingDown() or getattr(self.app,'allDone',None): return try: item = self.app.processingQueue.get(True,0.1) except Queue.Empty: continue item.execute() self.app.MainWindow.processingCompleted.emit(item) except: log.logException('processing thread error',log.ERROR) raise finally: log.debug('processing thread exiting')
def close(self): if not self.opened: return try: self.viewfinderThread.stopped = True except: pass try: if 'capture' in self.configWidgets and self.configWidgets['capture']['value'] != 0: self.configWidgets['capture']['value'] = 0 self.configWidgets['capture']['changed'] = True self.configurationToCamera() except: log.logException('unable to turn off capture mode', log.WARNING) self.opened = False self.camera.exit()
def __init__(self): # pylint: disable=super-init-not-called if Internal.Preferences: logException('Preferences is not None') self.__watching = defaultdict(list) Internal.Preferences = self KConfigSkeleton.__init__(self) self.configChanged.connect(self.callTriggers) self.__oldValues = defaultdict(str) self.addString('General', 'tilesetName', 'default') self.addString('General', 'windTilesetName', 'traditional') self.addString('General', 'backgroundName', 'wood_light') self.addBool('Display', 'showShadows', True) self.addBool('Display', 'rearrangeMelds', False) self.addBool('Display', 'showOnlyPossibleActions', True) self.addBool('Display', 'propose', True) self.addInteger('Display', 'animationSpeed', 70, 0, 99) self.addBool('Display', 'useSounds', True) self.addBool('Display', 'uploadVoice', False)
def run(self): try: while 1: if self.app.closingDown() or getattr(self.app, 'allDone', None): return try: item = self.app.processingQueue.get(True, 0.1) except Queue.Empty: continue item.execute() self.app.MainWindow.processingCompleted.emit(item) except: log.logException('processing thread error', log.ERROR) raise finally: log.debug('processing thread exiting')
def __init__(self, dummyName): """continue __build""" self.group = KConfig(self.path).group(self.configGroupName) self.name = self.group.readEntry("Name") or i18n("unknown name") self.author = self.group.readEntry("Author") or i18n("unknown author") self.description = self.group.readEntry("Description") or i18n( "no description available") self.authorEmail = self.group.readEntry("AuthorEmail") or i18n( "no E-Mail address available") # Version control resourceVersion = self.group.readInteger("VersionFormat", default=0) # Format is increased when we have incompatible changes, meaning that # older clients are not able to use the remaining information safely if resourceVersion > RESOURCEFORMAT: logException('version file / program: %d/%d' % (resourceVersion, RESOURCEFORMAT))
def processReceivedMessageData(self, msgData): log.log("Received from %s: %s\n" % (str(self.localID), msgData)) try: container = serializable.deserialize(msgData) if 'received' in container.keys(): #Process received confirmation: index = container['received'] self.network.callback.handleMessage( messages.Confirmation(localID=self.localID, index=index) ) elif 'message' in container.keys(): index = container['index'] msg = container['message'] if msg.__class__ == messages.ConnectLink: if not (self.localID is None): raise Exception("Received ConnectLink message while already connected") self.localID = msg.ID self.dice = msg.dice self.network.checkForDuplicateConnections(self.localID) elif msg.__class__ == messages.Pay: if not (self.localID is None): raise Exception("Received Pay message while already connected") if self.network.interfaceExists(msg.ID): log.log("Received Pay message for payment that already has a connection; closing the new one.") self.network.closeConnection(self) self.localID = msg.ID else: #Send confirmation on non-connect messages: confirmation = {'received': index} self.send(serializable.serialize(confirmation) + '\n') #Always set/overwrite the ID attribute with our own localID msg.ID = self.localID #TODO: filter for acceptable message types etc. before #sending them to a general-purpose message handler self.network.callback.handleMessage(msg) else: log.log("Received message with invalid format") except Exception as e: log.logException()
def __init__(self, path): assert Internal.db is None, id(self) Internal.db = self self.inTransaction = None self.path = path self.identifier = None try: sqlite3.Connection.__init__(self, self.path, timeout=10.0) except sqlite3.Error as exc: logException( u'opening %s: %s' % (unicodeString(self.path), exc.message)) if self.hasTable('general'): cursor = self.cursor() cursor.execute('select ident from general') self.identifier = cursor.fetchone()[0] if Debug.sql: logDebug(u'Opened %s with identifier %s' % ( unicodeString(self.path), self.identifier))
def configurationToCamera(self): n = 0 toClear = [] for section in self.config['children']: for widget in section['children']: n += 1 if widget['changed']: toClear.append(widget) if toClear: s = ', '.join(['%s (%s)=%r'%(i['name'],i['label'],i['value']) for i in toClear]) try: self.camera.setConfiguration(self.config) except: log.logException('Failed setting camera properties %s'%s,log.WARNING) else: log.debug('Successfully changed camera properties %s'%s) for i in toClear: i['changed'] = False
def delete(self): """delete a game""" def answered(result, games): """question answered, result is True or False""" if result: for game in games: Query("DELETE FROM score WHERE game = ?", (game, )) Query("DELETE FROM game WHERE id = ?", (game, )) self.setQuery() # just reload entire table allGames = self.view.selectionModel().selectedRows(0) deleteGames = list(x.data() for x in allGames) if len(deleteGames) == 0: # should never happen logException('delete: 0 rows selected') WarningYesNo( i18n( "Do you really want to delete <numid>%1</numid> games?<br>" "This will be final, you cannot cancel it with " "the cancel button", len(deleteGames))).addCallback(answered, deleteGames)
def delete(self): """delete a game""" def answered(result, games): """question answered, result is True or False""" if result: for game in games: Query("DELETE FROM score WHERE game = ?", (game, )) Query("DELETE FROM game WHERE id = ?", (game, )) self.setQuery() # just reload entire table allGames = self.view.selectionModel().selectedRows(0) deleteGames = list(variantValue(x.data()) for x in allGames) if len(deleteGames) == 0: # should never happen logException('delete: 0 rows selected') WarningYesNo( m18n( "Do you really want to delete <numid>%1</numid> games?<br>" "This will be final, you cannot cancel it with " "the cancel button", len(deleteGames))).addCallback(answered, deleteGames)
def pixmapFromSvg(self, pmapSize=None, withBorders=None): """returns a pixmap with default size as given in SVG and optional borders/shadows""" if withBorders is None: withBorders = Internal.Preferences.showShadows if withBorders: wantSize = self.tileset.tileSize.toSize() else: wantSize = self.tileset.faceSize.toSize() if not pmapSize: pmapSize = wantSize result = QPixmap(pmapSize) result.fill(Qt.transparent) painter = QPainter(result) if not painter.isActive(): logException( 'painter is not active. Wanted size: %s' % str(pmapSize)) try: xScale = float(pmapSize.width()) / wantSize.width() yScale = float(pmapSize.height()) / wantSize.height() except ZeroDivisionError: xScale = 1 yScale = 1 if not withBorders: painter.scale(*self.tileset.tileFaceRelation()) painter.translate(-self.facePos()) renderer = self.tileset.renderer() renderer.render(painter, self.__elementId()) painter.resetTransform() self._drawDarkness(painter) if self.showFace(): faceSize = self.tileset.faceSize.toSize() faceSize = QSize( faceSize.width() * xScale, faceSize.height() * yScale) painter.translate(self.facePos()) renderer.render(painter, self.tileset.svgName[self.tile.exposed], QRectF(QPointF(), QSizeF(faceSize))) return result
def __handleReadAvailable(self): try: bytes = self.socket.recv(4096) if len(bytes) == 0: log.log("Detected socket close by other side; closing this side too") self.close() self.__readBuffer += bytes if self.protocolVersion == None: self.__tryReadProtocolVersion() if self.protocolVersion == None: return # There can be multiple messages in the read buffer, # so repeat until there is no more complete message while True: # Message detection: if len(self.__readBuffer) < 4: return # 4-byte unsigned int in network byte order: msgLen = struct.unpack("!I", self.__readBuffer[:4])[0] if len(self.__readBuffer) < msgLen + 4: return msg = self.__readBuffer[4 : msgLen + 4] self.__readBuffer = self.__readBuffer[msgLen + 4 :] # print "Received serialized message: ", repr(msg) # de-serialize msg = messages.deserialize(msg) self.__handleMessage(msg) except: log.logException() self.close()
def language(self): """the language code of this voice. Locally defined voices have no language code and return 'local'. remote voices received from other clients return 'remote', they always get predecence.""" if len(self.directory) == self.md5sumLength: if os.path.split(self.directory)[1] == self.md5sum: return 'remote' if 'HOME' in os.environ: home = os.environ['HOME'] elif 'HOMEPATH' in os.environ: home = os.environ['HOMEPATH'] else: logException('have neither HOME nor HOMEPATH') if home: if self.directory.startswith(home): return 'local' result = os.path.split(self.directory)[0] result = os.path.split(result)[1] if result == 'voices': result = 'en_US' return result
def close(self): log.debug('closing down libgphoto2 client') if not self.opened: return log.debug('closing down gphotoremote.exe') try: self.api.stop() except: log.logException( 'failed trying to stop gphotoremote.exe main loop', log.WARNING) start = time.time() while self.process.poll() is None and (time.time() - start) < 2: time.sleep(0.05) if self.process.poll(): log.warning( 'failed to shut down gphotoremote.exe -- trying to kill it') try: self.process.kill() except: log.logException( 'failed to kill gphotoremote.exe -- please kill the process manually using the Task Manager', log.ERROR) else: log.debug('gphotoremote.exe closed down cleanly') try: uriPath = os.path.join(self.basePath, 'uri.txt') if os.path.exists(uriPath): os.remove(uriPath) except: pass self.opened = False
def excepthook(excType, excValue, tracebackobj): """ Global catchall for unhandled exceptions """ global app excInfo = (excType, excValue, tracebackobj) text = log.logException('Unhandled exception after startup',excInfo=excInfo) dialog = CrashDialog(parent=None,html='<pre>%s</pre>'%text.replace('<','<').replace('>','>')) dialog.exec_() try: app.quit() except: pass
def showConcealedTiles(self, tiles, show=True): """show or hide tiles""" if not self.game.playOpen and self != self.game.myself: if not isinstance(tiles, (list, tuple)): tiles = [tiles] assert len(tiles) <= len(self._concealedTiles), \ '%s: showConcealedTiles %s, we have only %s' % ( self, tiles, self._concealedTiles) for tileName in tiles: src, dst = (Tile.unknown, tileName) if show else ( tileName, Tile.unknown) assert src != dst, ( self, src, dst, tiles, self._concealedTiles) if src not in self._concealedTiles: logException('%s: showConcealedTiles(%s): %s not in %s.' % (self, tiles, src, self._concealedTiles)) idx = self._concealedTiles.index(src) self._concealedTiles[idx] = dst if self.lastTile and not self.lastTile.isKnown: self.lastTile = None self._hand = None self.syncHandBoard()
def pixmap(self, size): """returns a background pixmap or None for isPlain""" self.__pmap = None if not self.isPlain: width = size.width() height = size.height() if self.tiled: width = self.imageWidth height = self.imageHeight cachekey = QString(u'{name}W{width}H{height}'.format( name=self.name, width=width, height=height)) self.__pmap = QPixmapCache.find(cachekey) if not self.__pmap: renderer = QSvgRenderer(self.__graphicspath) if not renderer.isValid(): logException(BackgroundException( m18n('file <filename>%1</filename> contains no valid SVG', self.__graphicspath))) self.__pmap = QPixmap(width, height) self.__pmap.fill(Qt.transparent) painter = QPainter(self.__pmap) renderer.render(painter) QPixmapCache.insert(cachekey, self.__pmap) return self.__pmap
def __init__(self, path: str): assert Internal.db is None, id(self) Internal.db = self self.inTransaction = None self.path = path self.identifier = None try: sqlite3.Connection.__init__(self, self.path, timeout=10.0) except sqlite3.Error as exc: if hasattr(exc, 'message'): msg = exc.message elif hasattr(exc, 'args'): msg = ' '.join(exc.args) else: msg = '' logException('opening %s: %s' % (self.path, msg)) if self.hasTable('general'): cursor = self.cursor() cursor.execute('select ident from general') self.identifier = cursor.fetchone()[0] if Debug.sql: logDebug('Opened %s with identifier %s' % ( self.path, self.identifier))
def remote_move(self, playerName, command, *dummyArgs, **kwargs): """the server sends us info or a question and always wants us to answer""" if self.game: player = self.game.playerByName(playerName) elif playerName: player = PlayingPlayer(None, playerName) else: player = None move = Move(player, command, kwargs) if Debug.traffic: if self.isHumanClient(): if self.game: self.game.debug(u'got Move: %s' % move) else: logDebug(u'got Move: %s' % move) if self.game: if move.token: if move.token != self.game.handId.token(): logException( 'wrong token: %s, we have %s' % (move.token, self.game.handId.token())) with Duration('Move %s:' % move): return self.exec_move(move).addCallback(self.__jellyMessage)
def __upgrade(self): """upgrade the structure of an existing kajongg database""" try: Internal.db = DBHandle(self.path) allVersions = list(['4.13.0', '8300', '8301']) assert allVersions[-1] == str(Internal.defaultPort), '{} != {}'.format( allVersions[-1], str(Internal.defaultPort)) # skip versions before current db versions: currentVersion = self.__currentVersion() while allVersions and allVersions[0] <= currentVersion: allVersions = allVersions[1:] for version in allVersions: currentVersion = self.__currentVersion() with Internal.db: # transaction updateMethodName = 'updateToVersion{}'.format(version.replace('.', '_')) if hasattr(self, updateMethodName): getattr(self, updateMethodName)() Query('UPDATE general SET schemaversion=?', (version,)) logInfo(i18n('Database %1 updated from schema %2 to %3', Internal.db.path, currentVersion, version), showDialog=True) except sqlite3.Error as exc: logException('opening %s: %s' % (self.path, exc.message)) finally: Internal.db.close(silent=True)
def __init__(self, name): """continue __build""" super(Background, self).__init__(name) self.__svg = None self.__pmap = None self.graphicsPath = None QPixmapCache.setCacheLimit(20480) # the chinese landscape needs much self.tiled = self.group.readEntry('Tiled') == '1' if self.tiled: try: self.imageWidth = self.group.readInteger('Width') self.imageHeight = self.group.readInteger('Height') except Exception as exc: logException( exc) # TODO: simplify if we switch to twisted logger raise self.isPlain = bool(self.group.readEntry('Plain')) if not self.isPlain: graphName = self.group.readEntry("FileName") self.graphicsPath = self.locate(graphName) if not self.graphicsPath: logException('cannot find kmahjongglib/backgrounds/%s for %s' % (graphName, self.desktopFileName))
def __init__(self, desktopFileName=None): if desktopFileName is None: desktopFileName = 'default' self.__svg = None self.__pmap = None QPixmapCache.setCacheLimit(20480) # the chinese landscape needs much self.defineCatalog() self.desktopFileName = desktopFileName self.path = locatebackground(desktopFileName + '.desktop') if self.path.isEmpty(): self.path = locatebackground('default.desktop') if self.path.isEmpty(): directories = '\n\n' + \ '\n'.join(str(x) for x in KGlobal.dirs().resourceDirs("kmahjonggbackground")) logException(BackgroundException(m18n( 'cannot find any background in the following directories, is libkmahjongg installed?') + directories)) else: logWarning( m18n( 'cannot find background %1, using default', desktopFileName)) self.desktopFileName = 'default' config = KConfig(self.path) group = config.group("KMahjonggBackground") self.name = group.readEntry("Name") or m18n("unknown background") # Version control backgroundversion = int(group.readEntry("VersionFormat")) or 0 # Format is increased when we have incompatible changes, meaning that # older clients are not able to use the remaining information safely if backgroundversion > BACKGROUNDVERSIONFORMAT: logException(BackgroundException('backgroundversion file / program: %d/%d' % (backgroundversion, BACKGROUNDVERSIONFORMAT))) self.tiled = group.readEntry('Tiled') == '1' if self.tiled: self.imageWidth, entryOk = group.readEntry('Width').toInt() if not entryOk: raise Exception('cannot scan Width from background file') self.imageHeight, entryOk = group.readEntry('Height').toInt() if not entryOk: raise Exception('cannot scan Height from background file') self.isPlain = bool(group.readEntry('Plain')) if not self.isPlain: graphName = QString(group.readEntry("FileName")) self.__graphicspath = locatebackground(graphName) if self.__graphicspath.isEmpty(): logException(BackgroundException( 'cannot find kmahjongglib/backgrounds/%s for %s' % (graphName, self.desktopFileName)))
def add(self, rule): """use add instead of append""" if rule.key() in self: logException('%s is already defined as %s, not accepting new rule %s/%s' % ( rule.key(), self[rule.key()].definition, rule.name, rule.definition)) self[rule.key()] = rule