Ejemplo n.º 1
0
    def __init__(self, id, *argv):

        super(QSingleApplication, self).__init__(*argv)
        self._id = id
        self._activationWindow = None
        self._activateOnMessage = False
        self._server = None

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._outSocket.error.connect(self.handleError)
        self._isRunning = self._outSocket.waitForConnected()

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            # No, there isn't.
            self._outSocket = None
            self._outStream = None
            self._inSocket = None
            self._inStream = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            self._server.newConnection.connect(self._onNewConnection)
            self.aboutToQuit.connect(self.removeServer)
Ejemplo n.º 2
0
def main():
    # ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("AirMemo_appid")
    app = QApplication(sys.argv)

    serverName = 'AirMemo_client'
    socket = QLocalSocket()
    socket.connectToServer(serverName)

    # 如果连接成功,表明server已经存在,当前已有实例在运行
    if socket.waitForConnected(500):
        sys.exit(app.quit())

    # 没有实例运行,创建服务器
    localServer = QLocalServer()
    localServer.listen(serverName)
    try:
        setApp(app)
        link_db(config.LDB_FILENAME)
        tray = AirTray()
        mainWindow = Ui_MainWindow(tray)
        setting_win = Ui_Settings(tray)
        dict = {'main_win': mainWindow, 'setting_win': setting_win}
        tray.set_menu(dict)
        tray.show()
        # mainWindow.show()
        setting_win.show()
        sys.exit(app.exec_())
    finally:
        localServer.close()
Ejemplo n.º 3
0
    def __readCommands(self, connection: QLocalSocket) -> None:
        line = connection.readLine()
        while len(line) != 0:    # There is also a .canReadLine()
            try:
                payload = json.loads(str(line, encoding = "ascii").strip())
                command = payload["command"]

                # Command: Remove all models from the build plate.
                if command == "clear-all":
                    self._application.callLater(lambda: self._application.deleteAll())

                # Command: Load a model file
                elif command == "open":
                    self._application.callLater(lambda f = payload["filePath"]: self._application._openFile(f))

                # Command: Activate the window and bring it to the top.
                elif command == "focus":
                    # Operating systems these days prevent windows from moving around by themselves.
                    # 'alert' or flashing the icon in the taskbar is the best thing we do now.
                    main_window = self._application.getMainWindow()
                    if main_window is not None:
                        self._application.callLater(lambda: main_window.alert(0)) # type: ignore # I don't know why MyPy complains here

                # Command: Close the socket connection. We're done.
                elif command == "close-connection":
                    connection.close()

                else:
                    Logger.log("w", "Received an unrecognized command " + str(command))
            except json.decoder.JSONDecodeError as ex:
                Logger.log("w", "Unable to parse JSON command '%s': %s", line, repr(ex))
            line = connection.readLine()
Ejemplo n.º 4
0
    def __readCommands(self, connection: QLocalSocket) -> None:
        line = connection.readLine()
        while len(line) != 0:    # There is also a .canReadLine()
            try:
                payload = json.loads(str(line, encoding = "ascii").strip())
                command = payload["command"]

                # Command: Remove all models from the build plate.
                if command == "clear-all":
                    self._application.callLater(lambda: self._application.deleteAll())

                # Command: Load a model file
                elif command == "open":
                    self._application.callLater(lambda f = payload["filePath"]: self._application._openFile(f))

                # Command: Activate the window and bring it to the top.
                elif command == "focus":
                    # Operating systems these days prevent windows from moving around by themselves.
                    # 'alert' or flashing the icon in the taskbar is the best thing we do now.
                    main_window = self._application.getMainWindow()
                    if main_window is not None:
                        self._application.callLater(lambda: main_window.alert(0)) # type: ignore # I don't know why MyPy complains here

                # Command: Close the socket connection. We're done.
                elif command == "close-connection":
                    connection.close()

                else:
                    Logger.log("w", "Received an unrecognized command " + str(command))
            except json.decoder.JSONDecodeError as ex:
                Logger.log("w", "Unable to parse JSON command '%s': %s", line, repr(ex))
            line = connection.readLine()
Ejemplo n.º 5
0
    def __init__(self, id, *argv):

        super().__init__(*argv)
        self._id = id

        if sys.platform.startswith('linux'):
            self.setStyle('Fusion')

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            # No, there isn't.
            self._outSocket = None
            self._outStream = None
            self._inSocket = None
            self._inStream = None
            self._server = QLocalServer()
            self._server.removeServer(self._id)
            self._server.listen(self._id)
            self._server.newConnection.connect(self._onNewConnection)
Ejemplo n.º 6
0
def main():
    import sys
    app = QApplication(sys.argv)
    translator = QTranslator()
    locale = QLocale.system().name()
    translateFile = os.path.join(BASEDIR, 'i18n\\translations', '{}.qm'.format(locale))
    if translator.load(translateFile):
        app.installTranslator(translator)

    # QApplication.setStyle(QStyleFactory.create('Fusion'))

    if boolean(conf.value('General/LargeFont')):
        font = QFont('Courier New', 14)
        app.setFont(font)

    serverName = 'Tafor'
    socket = QLocalSocket()
    socket.connectToServer(serverName)

    # 如果连接成功,表明server已经存在,当前已有实例在运行
    if socket.waitForConnected(500):
        return(app.quit())

    # 没有实例运行,创建服务器     
    localServer = QLocalServer()
    localServer.listen(serverName)

    try:          
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())
    except Exception as e:
        logger.error(e, exc_info=True)
    finally:  
        localServer.close()
Ejemplo n.º 7
0
    def __init__(self, *args, **kwargs):
        super(QSingleApplication, self).__init__(*args, **kwargs)
        appid = QApplication.applicationFilePath().lower().split("/")[-1]
        self._socketName = "qtsingleapp-" + appid
        print("socketName", self._socketName)
        self._activationWindow = None
        self._activateOnMessage = False
        self._socketServer = None
        self._socketIn = None
        self._socketOut = None
        self._running = False

        # 先尝试连接
        self._socketOut = QLocalSocket(self)
        self._socketOut.connectToServer(self._socketName)
        self._socketOut.error.connect(self.handleError)
        self._running = self._socketOut.waitForConnected()

        if not self._running:  # 程序未运行
            self._socketOut.close()
            del self._socketOut
            self._socketServer = QLocalServer(self)
            self._socketServer.listen(self._socketName)
            self._socketServer.newConnection.connect(self._onNewConnection)
            self.aboutToQuit.connect(self.removeServer)
Ejemplo n.º 8
0
 def singleStart(self, appMain):
     self.appMain = appMain
     # Socket
     self.m_socket = QLocalSocket()
     self.m_socket.connected.connect(self.connectToExistingApp)
     self.m_socket.error.connect(
         lambda: self.startApplication(first_start=True))
     self.m_socket.connectToServer(self.sock_file, QIODevice.WriteOnly)
Ejemplo n.º 9
0
def get():
    """Return a remote Frescobaldi, or None if not available."""
    socket = QLocalSocket()
    name = os.environ.get("FRESCOBALDI_SOCKET")
    for name in (name, ) if name else ids():
        socket.connectToServer(name)
        if socket.waitForConnected(5000):
            from . import api
            return api.Remote(socket)
Ejemplo n.º 10
0
def get():
    """Return a remote Frescobaldi, or None if not available."""
    socket = QLocalSocket()
    name = os.environ.get("FRESCOBALDI_SOCKET")
    for name in (name,) if name else ids():
        socket.connectToServer(name)
        if socket.waitForConnected(5000):
            from . import api
            return api.Remote(socket)
Ejemplo n.º 11
0
def is_running():
    local_socket = QLocalSocket()
    local_socket.connectToServer("ninja_ide")
    if local_socket.state():
        # It's running
        result = (True, local_socket)
    else:
        # It's not running
        result = (False, local_socket)
    return result
Ejemplo n.º 12
0
def is_running():
    local_socket = QLocalSocket()
    local_socket.connectToServer("percentage_ide")
    if local_socket.state():
        # It's running
        result = (True, local_socket)
    else:
        # It's not running
        result = (False, local_socket)
    return result
Ejemplo n.º 13
0
    def test_other_error(self, ipc_server, monkeypatch):
        socket = QLocalSocket()
        ipc_server._socket = socket
        monkeypatch.setattr(socket, 'error',
                            lambda: QLocalSocket.ConnectionRefusedError)
        monkeypatch.setattr(socket, 'errorString',
                            lambda: "Connection refused")
        socket.setErrorString("Connection refused.")

        with pytest.raises(ipc.Error, match=r"Error while handling IPC "
                           r"connection: Connection refused \(error 0\)"):
            ipc_server.on_error(QLocalSocket.ConnectionRefusedError)
Ejemplo n.º 14
0
    def test_other_error(self, ipc_server, monkeypatch):
        socket = QLocalSocket()
        ipc_server._socket = socket
        monkeypatch.setattr(socket, 'error',
                            lambda: QLocalSocket.ConnectionRefusedError)
        monkeypatch.setattr(socket, 'errorString',
                            lambda: "Connection refused")
        socket.setErrorString("Connection refused.")

        with pytest.raises(ipc.Error, match=r"Error while handling IPC "
                           r"connection: Connection refused \(error 0\)"):
            ipc_server.on_error(QLocalSocket.ConnectionRefusedError)
Ejemplo n.º 15
0
 def __init__(self, parent, name):
     super(__class__, self).__init__(parent)
     self._parent = parent
     self._name = name
     self._timeout = 1000
     self._socket = QLocalSocket(self)
     self._socket.connectToServer(self._name)
     self._is_already_running = self._socket.waitForConnected(self._timeout)
     if not self.isAlreadyRunning():
         self._server = QLocalServer(self)
         self._server.newConnection.connect(self._receive_data)
         self._server.removeServer(self._name)
         self._server.listen(self._name)
class connection(object):
	"""docstring for connection"""
	def __init__(self, servername):
		super(connection, self).__init__()
		self.servername = servername
	
	def connectAndSend(self, content):
		self.content = json.dumps(content)
		self.socket = QLocalSocket()
		self.socket.connectToServer(self.servername)
		# self.socket.connected.connect(self.ready)
		self.socket.write(self.content.encode('utf-8'))
		pass
Ejemplo n.º 17
0
    def hasPrevious(self, name, args):
        socket = QLocalSocket()
        socket.connectToServer(name, QLocalSocket.ReadWrite)
        if socket.waitForConnected():
            if len(args) > 1:
                socket.write(args[1])

            socket.flush()
            return True
        return False
Ejemplo n.º 18
0
    def sendMessage(self, message):
        assert (self._isRunning)

        if self.isRunning():
            socket = QLocalSocket(self)
            socket.connectToServer(self._key, QIODevice.WriteOnly)
            if not socket.waitForConnected(self._timeout):
                return False
            socket.write(message.encode('utf-8'))
            if not socket.waitForBytesWritten(self._timeout):
                return False
            socket.disconnectFromServer()
            return True
        return False
Ejemplo n.º 19
0
 def hasPrevious(self, name, args):
     print("önceki socket kontrol ediliyor...")
     socket = QLocalSocket()
     socket.connectToServer(name, QLocalSocket.ReadWrite)
     if socket.waitForConnected():
         print("Önceki instansa argümanlar gönderiliyor.")
         if len(args) > 1:
             socket.write(args[1])
         else:
             pass
         socket.flush()
         return True
     print(socket.errorString())
     return False
Ejemplo n.º 20
0
def main(now_version, new_version):
    try:
        serverName = 'dig_word_update_Server'
        socket = QLocalSocket()
        socket.connectToServer(serverName)
        # 如果连接成功,表明server已经存在,当前已有实例在运行
        if socket.waitForConnected(500):
            pass
        else:
            localServer = QLocalServer()  # 没有实例运行,创建服务器
            localServer.listen(serverName)
            # 处理其他
            downwin_class(now_version, new_version)
    except:
        pass
Ejemplo n.º 21
0
    def test_other_error(self, ipc_server, monkeypatch):
        socket = QLocalSocket()
        ipc_server._socket = socket
        monkeypatch.setattr(socket, 'error',
                            lambda: QLocalSocket.ConnectionRefusedError)
        monkeypatch.setattr(socket, 'errorString',
                            lambda: "Connection refused")
        socket.setErrorString("Connection refused.")

        with pytest.raises(ipc.Error) as excinfo:
            ipc_server.on_error(QLocalSocket.ConnectionRefusedError)

        expected = ("Error while handling IPC connection: Connection refused "
                    "(error 0)")
        assert str(excinfo.value) == expected
Ejemplo n.º 22
0
    def test_other_error(self, ipc_server, monkeypatch):
        socket = QLocalSocket()
        ipc_server._socket = socket
        monkeypatch.setattr(socket, 'error',
                            lambda: QLocalSocket.ConnectionRefusedError)
        monkeypatch.setattr(socket, 'errorString',
                            lambda: "Connection refused")
        socket.setErrorString("Connection refused.")

        with pytest.raises(ipc.Error) as excinfo:
            ipc_server.on_error(QLocalSocket.ConnectionRefusedError)

        expected = ("Error while handling IPC connection: Connection refused "
                    "(error 0)")
        assert str(excinfo.value) == expected
Ejemplo n.º 23
0
    def __init__(self, parent: QWidget = None):
        super().__init__(parent)

        self._in = QDataStream()
        self.blockSize = 0

        self.currentFortune = ""

        self.hostLineEdit = QLineEdit("fortune")
        self.getFortuneButton = QPushButton(self.tr("Get Fortune"))
        self.statusLabel = QLabel(
            self.
            tr("This examples requires that you run the Local Fortune Server example as well."
               ))
        self.socket = QLocalSocket(self)

        self.setWindowFlags(self.windowFlags()
                            & ~Qt.WindowContextHelpButtonHint)
        hostLabel = QLabel(self.tr("&Server name:"))
        hostLabel.setBuddy(self.hostLineEdit)

        self.statusLabel.setWordWrap(True)

        self.getFortuneButton.setDefault(True)
        quitButton = QPushButton(self.tr("Quit"))

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self._in.setDevice(self.socket)
        self._in.setVersion(QDataStream.Qt_5_10)

        self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton)

        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.socket.readyRead.connect(self.readFortune)
        self.socket.errorOccurred.connect(self.displayError)

        mainLayout = QGridLayout(self)
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostLineEdit, 0, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)

        self.setWindowTitle(QGuiApplication.applicationDisplayName())
        self.hostLineEdit.setFocus()
Ejemplo n.º 24
0
    def __init__(self, id, *argv):

        super(QtSingleApplication, self).__init__(*argv)
        self._id = id
        self._activationWindow = None
        self._activateOnMessage = False

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec("UTF-8")
        else:
            # No, there isn't.
            self._outSocket = None
            self._outStream = None
            self._inSocket = None
            self._inStream = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            self._server.newConnection.connect(self._onNewConnection)
Ejemplo n.º 25
0
    def __init__(self, _id, _viewer_id, *argv):

        super(QtSingleApplication, self).__init__(*argv)
        self._id = _id
        self._viewer_id = _viewer_id
        self._activationWindow = None
        self._activateOnMessage = False

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected(-1)

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
            # Is there another viewer runnging?
            self._outSocketViewer = QLocalSocket()
            self._outSocketViewer.connectToServer(self._viewer_id)
            self._isRunningViewer = self._outSocketViewer.waitForConnected(-1)
            if self._isRunningViewer:
                self._outStreamViewer = QTextStream(self._outSocketViewer)
                self._outStreamViewer.setCodec('UTF-8')
            else:
                # app is running, we announce us as viewer app
                # First we remove existing servers of that name that might not have been properly closed as the server died
                QLocalServer.removeServer(self._viewer_id)
                self._outSocketViewer = None
                self._outStreamViewer = None
                self._inSocket = None
                self._inStream = None
                self._server = QLocalServer()
                self._server.listen(self._viewer_id)
                self._server.newConnection.connect(self._onNewConnection)
        else:
            self._isRunningViewer = False
            # No, there isn't.
            # First we remove existing servers of that name that might not have been properly closed as the server died
            QLocalServer.removeServer(self._id)
            self._outSocket = None
            self._outStream = None
            self._inSocket = None
            self._inStream = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            self._server.newConnection.connect(self._onNewConnection)
Ejemplo n.º 26
0
class QSingleApplication(QApplication):
    sock_file = 'sumokoin_wallet_sock'
    if sys.platform == 'win32':
        sock_file = "\\\\.\\pipe\\%s" % sock_file
    elif sys.platform == 'darwin':
        sock_file = os.path.join(DATA_DIR, '.%s' % sock_file)
    else:
        sock_file = os.path.join(getSockDir(), sock_file)

    def singleStart(self, appMain):
        self.appMain = appMain
        # Socket
        self.m_socket = QLocalSocket()
        self.m_socket.connected.connect(self.connectToExistingApp)
        self.m_socket.error.connect(
            lambda: self.startApplication(first_start=True))
        self.m_socket.connectToServer(self.sock_file, QIODevice.WriteOnly)

    def connectToExistingApp(self):
        # Quit application in 250 ms
        QTimer.singleShot(250, self.quit)
        print("App is already running.", file=sys.stderr)

    def startApplication(self, first_start=True):
        self.m_server = QLocalServer()
        if self.m_server.listen(self.sock_file):
            print("Starting app...")
            self.appMain.run()
        else:
            if not first_start:
                print("Error listening the socket. App can't start!",
                      file=sys.stderr)
                QTimer.singleShot(250, self.quit)
                return

            # remove the listener path file and try to restart app one more time
            print("Error listening the socket. Try to restart application...",
                  file=sys.stderr)
            if sys.platform != 'win32':
                try:
                    os.unlink(self.sock_file)
                except Exception, err:
                    print(err, file=sys.stderr)

            QTimer.singleShot(250,
                              lambda: self.startApplication(first_start=False))
Ejemplo n.º 27
0
def init():
    """Start listening to incoming connections."""
    global _server
    if _server is not None:
        return

    server = QLocalServer(None)

    # find a free socket name to use
    for name in ids():
        if server.listen(name):
            break
    else:
        # all names failed, try to contact and remove stale file if that fails
        socket = QLocalSocket()
        for name in ids():
            socket.connectToServer(name)
            if not socket.waitForConnected(10000):
                QLocalServer.removeServer(name)
                if server.listen(name):
                    break
            else:
                socket.disconnectFromServer()
        else:
            # no ids left, don't listen
            return
    app.aboutToQuit.connect(server.close)
    server.newConnection.connect(slot_new_connection)
    os.environ["FRESCOBALDI_SOCKET"] = name
    _server = server
Ejemplo n.º 28
0
    def __init__(self, win_id, *argv):

        logfunc = logging.info
        logfunc(sys._getframe().f_code.co_name + '()')

        QApplication.__init__(self, *argv)

        self._id = win_id
        self._activation_window = None
        self._activate_on_message = False

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        self._outStream = None
        self._inSocket = None
        self._inStream = None
        self._server = None

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            # No, there isn't, at least not properly.
            # Cleanup any past, crashed server.
            error = self._outSocket.error()
            logfunc(LOGVARSTR % ('self._outSocket.error()', error))
            if error == QLocalSocket.ConnectionRefusedError:
                logfunc('received QLocalSocket.ConnectionRefusedError; ' + \
                        'removing server.')
                self.close()
                QLocalServer.removeServer(self._id)
            self._outSocket = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            self._server.newConnection.connect(self._on_new_connection)

        logfunc(sys._getframe().f_code.co_name + '(): returning')
Ejemplo n.º 29
0
    def __init__(self, win_id, *argv):
        self.logger = logging.getLogger(self.__class__.__name__)
        self.logger.info(f'Start Tribler application. Win id: "{win_id}". '
                         f'Sys argv: "{sys.argv}"')

        QApplication.__init__(self, *argv)

        self._id = win_id
        self._activation_window = None
        self._activate_on_message = False

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        self._outStream = None
        self._inSocket = None
        self._inStream = None
        self._server = None

        if self._isRunning:
            # Yes, there is.
            self.logger.info('Another instance is running')
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            # No, there isn't, at least not properly.
            # Cleanup any past, crashed server.
            error = self._outSocket.error()
            self.logger.info(f'No running instances (socket error: {error})')
            if error == QLocalSocket.ConnectionRefusedError:
                self.logger.info(
                    'Received QLocalSocket.ConnectionRefusedError; removing server.'
                )
                self.close()
                QLocalServer.removeServer(self._id)
            self._outSocket = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            connect(self._server.newConnection, self._on_new_connection)
Ejemplo n.º 30
0
 def connect(self):
     """
     Public method to connect the single application client to its server.
     
     @return value indicating success or an error number. Value is one of:
         <table>
             <tr><td>0</td><td>No application is running</td></tr>
             <tr><td>1</td><td>Application is already running</td></tr>
         </table>
     """
     self.sock = QLocalSocket()
     self.sock.connectToServer(self.name)
     if self.sock.waitForConnected(10000):
         self.connected = True
         return 1
     else:
         err = self.sock.error()
         if err == QLocalSocket.ServerNotFoundError:
             return 0
         else:
             return -err
Ejemplo n.º 31
0
 def connect(cls, single=False):
     """连接启动器
     :param single: 如果是单实例则客户端必须由启动器启动
     """
     name = os.environ.get('SplashConnectName', None)
     if not name:
         if single:
             # 单实例客户端必须由启动器启动
             sys.exit(-1)
         return
     cls.client = QLocalSocket()
     cls.client.connectToServer(name)
Ejemplo n.º 32
0
def init():
    """Start listening to incoming connections."""
    global _server
    if _server is not None:
        return
    
    server = QLocalServer(None)
    
    # find a free socket name to use
    for name in ids():
        if server.listen(name):
            break
    else:
        # all names failed, try to contact and remove stale file if that fails
        socket = QLocalSocket()
        for name in ids():
            socket.connectToServer(name)
            if not socket.waitForConnected(10000):
                QLocalServer.removeServer(name)
                if server.listen(name):
                    break
            else:
                socket.disconnectFromServer()
        else:
            # no ids left, don't listen
            return
    app.aboutToQuit.connect(server.close)
    server.newConnection.connect(slot_new_connection)
    os.environ["FRESCOBALDI_SOCKET"] = name
    _server = server
Ejemplo n.º 33
0
class InstanceHandler(QObject):
    """ Makes sure that only one instance of this application can be run. """

    received = pyqtSignal(str)

    def __init__(self, parent, name):
        super(__class__, self).__init__(parent)
        self._parent = parent
        self._name = name
        self._timeout = 1000
        self._socket = QLocalSocket(self)
        self._socket.connectToServer(self._name)
        self._is_already_running = self._socket.waitForConnected(self._timeout)
        if not self.isAlreadyRunning():
            self._server = QLocalServer(self)
            self._server.newConnection.connect(self._receive_data)
            self._server.removeServer(self._name)
            self._server.listen(self._name)

    def _send_data(self, data=None):
        """ Sends model to an server-application. """
        if not data:
            data = ""
        self._socket.write(data.encode())
        self._socket.waitForBytesWritten(self._timeout)
        self._socket.disconnectFromServer()

    def _receive_data(self):
        """ Receives model from an client-application. """
        socket = self._server.nextPendingConnection()
        if socket.waitForReadyRead(self._timeout):
            # Emit transmitted model.
            self.received.emit(socket.readAll().data().decode(
                "utf-8", "surrogateescape"))
        else:
            # When no model was transmitted just emit empty string.
            self.received.emit("")

    def newTab(self, input):
        """ Opens a new tab in an already running instance. """
        self._send_data(input)

    def isAlreadyRunning(self) -> bool:
        """ Returns True when an instance of the application is already running, otherwise False. """
        return self._is_already_running
Ejemplo n.º 34
0
    def __init__(self, parent=None):
        super(Client, self).__init__(parent)

        self.blockSize = 0
        self.currentFortune = None

        hostLabel = QLabel("&Server name:")
        self.hostLineEdit = QLineEdit("fortune")
        hostLabel.setBuddy(self.hostLineEdit)

        self.statusLabel = QLabel(
            "This examples requires that you run the Fortune Server "
            "example as well.")
        self.statusLabel.setWordWrap(True)

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)

        quitButton = QPushButton("Quit")
        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.socket = QLocalSocket()

        self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.socket.readyRead.connect(self.readFortune)
        self.socket.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostLineEdit, 0, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Fortune Client")
        self.hostLineEdit.setFocus()
Ejemplo n.º 35
0
    def __init__(self, timeout=2000, size=2**28):
        self.app = QCoreApplication.instance()
        if self.app is None:
            self.app = QCoreApplication([])
        self.sock = QLocalSocket()
        self.sock.connectToServer("LivePlot")
        if not self.sock.waitForConnected():
            raise EnvironmentError("Couldn't find LivePlotter instance")
        self.sock.disconnected.connect(self.disconnect_received)

        key = str(uuid.uuid4())
        self.shared_mem = QSharedMemory(key)
        if not self.shared_mem.create(size):
            raise Exception("Couldn't create shared memory %s" % self.shared_mem.errorString())
        logging.debug('Memory created with key %s and size %s' % (key, self.shared_mem.size()))
        self.sock.write(key.encode())
        self.sock.waitForBytesWritten()

        self.is_connected = True
        self.timeout = timeout

        atexit.register(self.close)
Ejemplo n.º 36
0
    def __init__(self, name, *args, **kwargs):
        super(QSingleApplication, self).__init__(*args, **kwargs)
        self._socketName = name
        self._activationWindow = None
        self._socketServer = None
        self._socketIn = None
        self._socketOut = None
        self._running = False

        # 先尝试连接
        self._socketOut = QLocalSocket(self)
        self._socketOut.connectToServer(self._socketName)
        self._socketOut.error.connect(self.handleError)
        self._running = self._socketOut.waitForConnected()

        if not self._running:  # 程序未运行
            self._socketOut.close()
            del self._socketOut
            # 创建本地server
            self._socketServer = QLocalServer(self)
            self._socketServer.listen(self._socketName)
            self._socketServer.newConnection.connect(self._onNewConnection)
            self.aboutToQuit.connect(self.removeServer)
Ejemplo n.º 37
0
class OutputFilter(object):
    """
    Filter what is send on stderr file descriptor, on unix systems only.
    """
    def __init__(self, regexes):
        # duplicate stderr on a new file descriptor that we assign to
        # sys.stderr (so from python there is no difference when writing to the
        # standard error) and redirect stderr to a pipe that we will read,
        # filter and log manually.
        sys.stderr.flush()
        r, w = os.pipe()

        newerr = os.dup(sys.stderr.fileno())
        os.dup2(w, sys.stderr.fileno())

        os.close(w)
        sys.stderr = os.fdopen(newerr, "w")

        def _excepthook(e, v, tb):
            # use our custom stderr
            traceback.print_exception(e, v, tb, None, sys.stderr)
            sys.exit(1)

        sys.excepthook = _excepthook

        self._notifier = QLocalSocket()
        self._fd = r
        self._regexes = regexes

    def enable(self):
        self._notifier.setSocketDescriptor(self._fd)
        self._notifier.readyRead.connect(self._redirect)

    def _redirect(self):
        while self._notifier.canReadLine():
            line = self._notifier.readLine().data().rstrip().decode("utf-8")
            logging.log(self._regexes.get_level_for_line(line), line)
Ejemplo n.º 38
0
 def connectToRunning(self):
    self.socket = QLocalSocket()
    self.socket.connectToServer('nemuSocket')
    self.socket.waitForConnected(1000)
    
    if self.socket.state() == QLocalSocket.ConnectedState:
       print 'Server found'
       if self.socket.waitForReadyRead(3000):
          line = self.socket.readLine()
          print line
       else:
          print self.socket.errorString()
       sys.exit()
    else:
       print 'No server running'
Ejemplo n.º 39
0
    def __init__(self, win_id, *argv):

        logfunc = logging.info
        logfunc(sys._getframe().f_code.co_name + '()')

        QApplication.__init__(self, *argv)

        self._id = win_id
        self._activation_window = None
        self._activate_on_message = False

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        self._outStream = None
        self._inSocket = None
        self._inStream = None
        self._server = None

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            # No, there isn't, at least not properly.
            # Cleanup any past, crashed server.
            error = self._outSocket.error()
            logfunc(LOGVARSTR % ('self._outSocket.error()', error))
            if error == QLocalSocket.ConnectionRefusedError:
                logfunc('received QLocalSocket.ConnectionRefusedError; ' + \
                        'removing server.')
                self.close()
                QLocalServer.removeServer(self._id)
            self._outSocket = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            self._server.newConnection.connect(self._on_new_connection)

        logfunc(sys._getframe().f_code.co_name + '(): returning')
Ejemplo n.º 40
0
 def connect(self):
     """
     Public method to connect the single application client to its server.
     
     @return value indicating success or an error number. Value is one of:
         <table>
             <tr><td>0</td><td>No application is running</td></tr>
             <tr><td>1</td><td>Application is already running</td></tr>
         </table>
     """
     self.sock = QLocalSocket()
     self.sock.connectToServer(self.name)
     if self.sock.waitForConnected(10000):
         self.connected = True
         return 1
     else:
         err = self.sock.error()
         if err == QLocalSocket.ServerNotFoundError:
             return 0
         else:
             return -err
Ejemplo n.º 41
0
    def __init__(self, parent=None):
        super(Client, self).__init__(parent)

        self.blockSize = 0
        self.currentFortune = None

        hostLabel = QLabel("&Server name:")
        self.hostLineEdit = QLineEdit("fortune")
        hostLabel.setBuddy(self.hostLineEdit)

        self.statusLabel = QLabel(
                "This examples requires that you run the Fortune Server "
                "example as well.")
        self.statusLabel.setWordWrap(True)

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)

        quitButton = QPushButton("Quit")
        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.socket = QLocalSocket()

        self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.socket.readyRead.connect(self.readFortune)
        self.socket.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostLineEdit, 0, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Fortune Client")
        self.hostLineEdit.setFocus()
Ejemplo n.º 42
0
    def __init__(self, id, *argv):

        super(SingleApplication, self).__init__(*argv)
        self._id = id
        self._activationWindow = None
        self._activateOnMessage = False

        # Check if another instance is running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        if self._isRunning:
            self._outStream = QtCore.QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            self._outSocket = None
            self._outStream = None
            self._inSocket = None
            self._inStream = None
            self._server = QLocalServer()
            self._server.removeServer(self._id)  # if existing after crash-exit
            self._server.listen(self._id)
            self._server.newConnection.connect(self._onNewConnection)
Ejemplo n.º 43
0
    def startClient(self) -> bool:
        Logger.log("i", "Checking for the presence of an ready running Cura instance.")
        single_instance_socket = QLocalSocket(self._application)
        Logger.log("d", "Full single instance server name: %s", single_instance_socket.fullServerName())
        single_instance_socket.connectToServer("ultimaker-cura")
        single_instance_socket.waitForConnected(msecs = 3000)  # wait for 3 seconds

        if single_instance_socket.state() != QLocalSocket.ConnectedState:
            return False

        # We only send the files that need to be opened.
        if not self._files_to_open:
            Logger.log("i", "No file need to be opened, do nothing.")
            return True

        if single_instance_socket.state() == QLocalSocket.ConnectedState:
            Logger.log("i", "Connection has been made to the single-instance Cura socket.")

            # Protocol is one line of JSON terminated with a carriage return.
            # "command" field is required and holds the name of the command to execute.
            # Other fields depend on the command.

            payload = {"command": "clear-all"}
            single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding = "ascii"))

            payload = {"command": "focus"}
            single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding = "ascii"))

            for filename in self._files_to_open:
                payload = {"command": "open", "filePath": os.path.abspath(filename)}
                single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding = "ascii"))

            payload = {"command": "close-connection"}
            single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding = "ascii"))

            single_instance_socket.flush()
            single_instance_socket.waitForDisconnected()
        return True
Ejemplo n.º 44
0
class QtSingleApplication(QApplication):
    """
    This class makes sure that we can only start one Tribler application.
    When a user tries to open a second Tribler instance, the current active one will be brought to front.
    """

    messageReceived = pyqtSignal(unicode)

    def __init__(self, win_id, *argv):

        logfunc = logging.info
        logfunc(sys._getframe().f_code.co_name + '()')

        QApplication.__init__(self, *argv)

        self._id = win_id
        self._activation_window = None
        self._activate_on_message = False

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        self._outStream = None
        self._inSocket = None
        self._inStream = None
        self._server = None

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            # No, there isn't, at least not properly.
            # Cleanup any past, crashed server.
            error = self._outSocket.error()
            logfunc(LOGVARSTR % ('self._outSocket.error()', error))
            if error == QLocalSocket.ConnectionRefusedError:
                logfunc('received QLocalSocket.ConnectionRefusedError; ' + \
                        'removing server.')
                self.close()
                QLocalServer.removeServer(self._id)
            self._outSocket = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            self._server.newConnection.connect(self._on_new_connection)

        logfunc(sys._getframe().f_code.co_name + '(): returning')

    def close(self):
        logfunc = logging.info
        logfunc(sys._getframe().f_code.co_name + '()')
        if self._inSocket:
            self._inSocket.disconnectFromServer()
        if self._outSocket:
            self._outSocket.disconnectFromServer()
        if self._server:
            self._server.close()
        logfunc(sys._getframe().f_code.co_name + '(): returning')

    def is_running(self):
        return self._isRunning

    def get_id(self):
        return self._id

    def activation_window(self):
        return self._activation_window

    def set_activation_window(self, activation_window, activate_on_message=True):
        self._activation_window = activation_window
        self._activate_on_message = activate_on_message

    def activate_window(self):
        if not self._activation_window:
            return
        self._activation_window.setWindowState(
            self._activation_window.windowState() & ~Qt.WindowMinimized)
        self._activation_window.raise_()

    def send_message(self, msg):
        if not self._outStream:
            return False
        self._outStream << msg << '\n'
        self._outStream.flush()
        return self._outSocket.waitForBytesWritten()

    def _on_new_connection(self):
        if self._inSocket:
            self._inSocket.readyRead.disconnect(self._on_ready_read)
        self._inSocket = self._server.nextPendingConnection()
        if not self._inSocket:
            return
        self._inStream = QTextStream(self._inSocket)
        self._inStream.setCodec('UTF-8')
        self._inSocket.readyRead.connect(self._on_ready_read)
        if self._activate_on_message:
            self.activate_window()

    def _on_ready_read(self):
        while True:
            msg = self._inStream.readLine()
            if not msg:
                break
            self.messageReceived.emit(msg)
Ejemplo n.º 45
0
def send_to_running_instance(socketname, command, target_arg, *, socket=None):
    """Try to send a commandline to a running instance.

    Blocks for CONNECT_TIMEOUT ms.

    Args:
        socketname: The name which should be used for the socket.
        command: The command to send to the running instance.
        target_arg: --target command line argument
        socket: The socket to read data from, or None.

    Return:
        True if connecting was successful, False if no connection was made.
    """
    if socket is None:
        socket = QLocalSocket()

    log.ipc.debug("Connecting to {}".format(socketname))
    socket.connectToServer(socketname)

    connected = socket.waitForConnected(CONNECT_TIMEOUT)
    if connected:
        log.ipc.info("Opening in existing instance")
        json_data = {'args': command, 'target_arg': target_arg,
                     'version': qutebrowser.__version__,
                     'protocol_version': PROTOCOL_VERSION}
        try:
            cwd = os.getcwd()
        except OSError:
            pass
        else:
            json_data['cwd'] = cwd
        line = json.dumps(json_data) + '\n'
        data = line.encode('utf-8')
        log.ipc.debug("Writing: {!r}".format(data))
        socket.writeData(data)
        socket.waitForBytesWritten(WRITE_TIMEOUT)
        if socket.error() != QLocalSocket.UnknownSocketError:
            raise SocketError("writing to running instance", socket)
        else:
            socket.disconnectFromServer()
            if socket.state() != QLocalSocket.UnconnectedState:
                socket.waitForDisconnected(CONNECT_TIMEOUT)
            return True
    else:
        if socket.error() not in [QLocalSocket.ConnectionRefusedError,
                                  QLocalSocket.ServerNotFoundError]:
            raise SocketError("connecting to running instance", socket)
        else:
            log.ipc.debug("No existing instance present (error {})".format(
                socket.error()))
            return False
Ejemplo n.º 46
0
def send_to_running_instance(socketname, command):
    """Try to send a commandline to a running instance.

    Blocks for CONNECT_TIMEOUT ms.

    Args:
        socketname: The name which should be used for the socket.
        command: The command to send to the running instance.

    Return:
        True if connecting was successful, False if no connection was made.
    """
    socket = QLocalSocket()
    log.ipc.debug("Connecting to {}".format(socketname))
    socket.connectToServer(socketname)
    connected = socket.waitForConnected(100)
    if connected:
        log.ipc.info("Opening in existing instance")
        json_data = {'args': command}
        try:
            cwd = os.getcwd()
        except OSError:
            pass
        else:
            json_data['cwd'] = cwd
        line = json.dumps(json_data) + '\n'
        data = line.encode('utf-8')
        log.ipc.debug("Writing: {}".format(data))
        socket.writeData(data)
        socket.waitForBytesWritten(WRITE_TIMEOUT)
        if socket.error() != QLocalSocket.UnknownSocketError:
            _socket_error("writing to running instance", socket)
        else:
            socket.disconnectFromServer()
            if socket.state() != QLocalSocket.UnconnectedState:
                socket.waitForDisconnected(100)
            return True
    else:
        if socket.error() not in (QLocalSocket.ConnectionRefusedError,
                                  QLocalSocket.ServerNotFoundError):
            _socket_error("connecting to running instance", socket)
        else:
            log.ipc.debug("No existing instance present (error {})".format(
                socket.error()))
            return False
Ejemplo n.º 47
0
def qlocalsocket(qapp):
    socket = QLocalSocket()
    yield socket
    socket.disconnectFromServer()
    if socket.state() != QLocalSocket.UnconnectedState:
        socket.waitForDisconnected(1000)
Ejemplo n.º 48
0
class SingleApplication(QtWidgets.QApplication):
    '''
    Inheriting from QApplication, executing main App instead.
    Watching whether the app is already running.
    If so, quit befor execution.
    '''
    messageReceived = QtCore.pyqtSignal(str)

    def __init__(self, id, *argv):

        super(SingleApplication, self).__init__(*argv)
        self._id = id
        self._activationWindow = None
        self._activateOnMessage = False

        # Check if another instance is running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        if self._isRunning:
            self._outStream = QtCore.QTextStream(self._outSocket)
            self._outStream.setCodec('UTF-8')
        else:
            self._outSocket = None
            self._outStream = None
            self._inSocket = None
            self._inStream = None
            self._server = QLocalServer()
            self._server.removeServer(self._id)  # if existing after crash-exit
            self._server.listen(self._id)
            self._server.newConnection.connect(self._onNewConnection)

    def isRunning(self):
        return self._isRunning

    def id(self):
        return self._id

    def activationWindow(self):
        return self._activationWindow

    def setActivationWindow(self, activationWindow, activateOnMessage=True):
        self._activationWindow = activationWindow
        self._activateOnMessage = activateOnMessage

    def activateWindow(self):
        if not self._activationWindow:
            return
        self._activationWindow.setWindowState(
            self._activationWindow.windowState() & ~QtCore.Qt.WindowMinimized)
        self._activationWindow.show()
        self._activationWindow.activateWindow()

    def sendMessage(self, msg):
        if not self._outStream:
            return False
        self._outStream << msg << '\n'
        self._outStream.flush()
        return self._outSocket.waitForBytesWritten()

    def _onNewConnection(self):
        if self._inSocket:
            self._inSocket.readyRead.disconnect(self._onReadyRead)
        self._inSocket = self._server.nextPendingConnection()
        if not self._inSocket:
            return
        self._inStream = QtCore.QTextStream(self._inSocket)
        self._inStream.setCodec('UTF-8')
        self._inSocket.readyRead.connect(self._onReadyRead)
        if self._activateOnMessage:
            self.activateWindow()

    def _onReadyRead(self):
        while True:
            msg = self._inStream.readLine()
            if not msg:
                break
            self.messageReceived.emit(msg)
Ejemplo n.º 49
0
 def __init__(self):
     self.socket = QLocalSocket()
     self.socket.setServerName(piony.G_SOCKET_NAME)
     self.socket.error.connect(self.displayError)
     self.socket.disconnected.connect(self.socket.deleteLater)
Ejemplo n.º 50
0
def send_to_running_instance(cmdlist):
    """Try to send a commandline to a running instance.

    Blocks for CONNECT_TIMEOUT ms.

    Args:
        cmdlist: A list to send (URLs/commands)

    Return:
        True if connecting was successful, False if no connection was made.
    """
    socket = QLocalSocket()
    socket.connectToServer(SOCKETNAME)
    connected = socket.waitForConnected(100)
    if connected:
        log.ipc.info("Opening in existing instance")
        json_data = {'args': cmdlist}
        try:
            cwd = os.getcwd()
        except OSError:
            pass
        else:
            json_data['cwd'] = cwd
        line = json.dumps(json_data) + '\n'
        data = line.encode('utf-8')
        log.ipc.debug("Writing: {}".format(data))
        socket.writeData(data)
        socket.waitForBytesWritten(WRITE_TIMEOUT)
        if socket.error() != QLocalSocket.UnknownSocketError:
            _socket_error("writing to running instance", socket)
        else:
            return True
    else:
        if socket.error() not in (QLocalSocket.ConnectionRefusedError,
                                  QLocalSocket.ServerNotFoundError):
            _socket_error("connecting to running instance", socket)
        else:
            log.ipc.debug("No existing instance present (error {})".format(
                socket.error()))
            return False
Ejemplo n.º 51
0
class Client(QDialog):
    def __init__(self, parent=None):
        super(Client, self).__init__(parent)

        self.blockSize = 0
        self.currentFortune = None

        hostLabel = QLabel("&Server name:")
        self.hostLineEdit = QLineEdit("fortune")
        hostLabel.setBuddy(self.hostLineEdit)

        self.statusLabel = QLabel("This examples requires that you run the Fortune Server " "example as well.")
        self.statusLabel.setWordWrap(True)

        self.getFortuneButton = QPushButton("Get Fortune")
        self.getFortuneButton.setDefault(True)

        quitButton = QPushButton("Quit")
        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole)
        buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole)

        self.socket = QLocalSocket()

        self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton)
        self.getFortuneButton.clicked.connect(self.requestNewFortune)
        quitButton.clicked.connect(self.close)
        self.socket.readyRead.connect(self.readFortune)
        self.socket.error.connect(self.displayError)

        mainLayout = QGridLayout()
        mainLayout.addWidget(hostLabel, 0, 0)
        mainLayout.addWidget(self.hostLineEdit, 0, 1)
        mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2)
        mainLayout.addWidget(buttonBox, 3, 0, 1, 2)
        self.setLayout(mainLayout)

        self.setWindowTitle("Fortune Client")
        self.hostLineEdit.setFocus()

    def requestNewFortune(self):
        self.getFortuneButton.setEnabled(False)
        self.blockSize = 0
        self.socket.abort()
        self.socket.connectToServer(self.hostLineEdit.text())

    def readFortune(self):
        ins = QDataStream(self.socket)
        ins.setVersion(QDataStream.Qt_4_0)

        if self.blockSize == 0:
            if self.socket.bytesAvailable() < 2:
                return
            self.blockSize = ins.readUInt16()

        if ins.atEnd():
            return

        nextFortune = ins.readQString()
        if nextFortune == self.currentFortune:
            QTimer.singleShot(0, self.requestNewFortune)
            return

        self.currentFortune = nextFortune
        self.statusLabel.setText(self.currentFortune)
        self.getFortuneButton.setEnabled(True)

    def displayError(self, socketError):
        errors = {
            QLocalSocket.ServerNotFoundError: "The host was not found. Please check the host name and port "
            "settings.",
            QLocalSocket.ConnectionRefusedError: "The connection was refused by the peer. Make sure the "
            "fortune server is running, and check that the host name and "
            "port settings are correct.",
            QLocalSocket.PeerClosedError: None,
        }

        msg = errors.get(socketError, "The following error occurred: %s." % self.socket.errorString())
        if msg is not None:
            QMessageBox.information(self, "Fortune Client", msg)

        self.getFortuneButton.setEnabled(True)

    def enableGetFortuneButton(self):
        self.getFortuneButton.setEnabled(self.hostLineEdit.text() != "")
Ejemplo n.º 52
0
class Client:
    def __init__(self):
        self.socket = QLocalSocket()
        self.socket.setServerName(piony.G_SOCKET_NAME)
        self.socket.error.connect(self.displayError)
        self.socket.disconnected.connect(self.socket.deleteLater)

    def _log_(self, text, *args):
        logger.info(self.__class__.__qualname__ + ': ' + text, *args)

    def connect(self):
        self.socket.abort()
        self._log_("connection attempt")
        self.socket.connectToServer()

    def send(self, argv):
        data = QByteArray()
        out = QDataStream(data, QIODevice.WriteOnly)
        out.setVersion(QDataStream.Qt_5_0)
        out.writeQVariant(argv)
        self._log_("writes: %s", str(data))
        self.socket.write(data)
        self.socket.flush()
        self.socket.disconnectFromServer()

    def displayError(self, err):
        msg = {
            QLocalSocket.ServerNotFoundError:
                "The host was not found. Check the host name and port.",
            QLocalSocket.ConnectionRefusedError:
                "The connection was refused by the peer. "
                "Check server is running, it's host and port.",
            QLocalSocket.PeerClosedError:
                "Peer was closed",  # None,
        }.get(err, "Client error: {}.".format(self.socket.errorString()))
        self._log_(msg)
Ejemplo n.º 53
0
def _has_legacy_server(name):
    """Check if there is a legacy server.

    Args:
        name: The name to try to connect to.

    Return:
        True if there is a server with the given name, False otherwise.
    """
    socket = QLocalSocket()
    log.ipc.debug("Trying to connect to {}".format(name))
    socket.connectToServer(name)

    err = socket.error()

    if err != QLocalSocket.UnknownSocketError:
        log.ipc.debug("Socket error: {} ({})".format(socket.errorString(), err))

    os_x_fail = (
        sys.platform == "darwin" and socket.errorString() == "QLocalSocket::connectToServer: " "Unknown error 38"
    )

    if err not in [QLocalSocket.ServerNotFoundError, QLocalSocket.ConnectionRefusedError] and not os_x_fail:
        return True

    socket.disconnectFromServer()
    if socket.state() != QLocalSocket.UnconnectedState:
        socket.waitForDisconnected(CONNECT_TIMEOUT)
    return False
Ejemplo n.º 54
0
class MainForm(QDialog):
   def __init__(self, parent = None):
      QDialog.__init__(self, parent)
      
      # If a Nemu instance is already running, this is as far as we go
      self.connectToRunning()
      
      self.holdOpen = False
      self.menuItems = []
      self.allItems = []
      self.favorites = []
      self.currentItem = None
      self.menuFile = os.path.expanduser('~/.nemu/menu')
      self.favoritesFile = os.path.expanduser('~/.nemu/favorites')
      # NOTE: If you change this, also update migrate-settings
      self.settingsFile = os.path.expanduser('~/.nemu/settings')
      self.initSettings()

      self.server = QLocalServer()
      self.server.newConnection.connect(self.handleConnection)
      QLocalServer.removeServer('nemuSocket')
      self.server.listen('nemuSocket')
      
      self.configDir = os.path.expanduser('~/.nemu')
      if not os.path.isdir(self.configDir):
         os.mkdir(self.configDir)
      self.menuItems = self.loadConfig(self.menuFile, self.menuItems)
      self.favorites = self.loadConfig(self.favoritesFile, self.favorites)
      # Don't load directly into self.settings so we can add new default values as needed
      try:
         tempSettings = self.loadConfig(self.settingsFile, self.settings)
         for key, value in tempSettings.items():
            self.settings[key] = value
      except SystemError:
         print('ERROR: Failed to load settings. You may need to run migrate-settings.')
         raise
      # This should never happen, but unfortunately bugs do, so clean up orphaned items.
      # We need to do this because these items won't show up in the UI, but may interfere with
      # merges if they duplicate something that is being merged in.
      self.menuItems[:] = [i for i in self.menuItems if i.parent == None or i.parent in self.menuItems]
      # Look for broken icon paths
      needSave = False
      for i in self.menuItems + self.favorites:
          if not os.path.exists(i.icon):
              i.findIcon()
              needSave = True
      if needSave:
         self.saveMenu()


      for i in self.menuItems:
         if not hasattr(i, 'imported'):
            i.imported = False
      
      self.setupUI()
      
      self.setContextMenuPolicy(Qt.ActionsContextMenu)
      self.createMenu(self)
      
      self.refresh(False)
      
      if len(self.menuItems) == 0:
         self.firstRun()
      
      self.show()
      
      self.keepaliveTimer = QTimer(self)
      self.keepaliveTimer.timeout.connect(self.keepalive)
      self.keepaliveTimer.start(60000)
      
      
   def initSettings(self):
      self.settings = dict()
      self.settings['width'] = 400
      self.settings['height'] = 400
      self.settings['quit'] = False
      self.settings['imported'] = []
      self.settings['iconTheme'] = None
      
      
   def loadConfig(self, filename, default):
      if os.path.exists(filename):
         with open(filename, 'rb') as f:
            data = f.read().replace('PyQt4', 'PyQt5')
            return cPickle.loads(data)
      else:
         return default
      
      
   def setupUI(self):
      self.resize(self.settings['width'], self.settings['height'])
      self.setWindowFlags(Qt.FramelessWindowHint | Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint)
      #self.setWindowFlags(Qt.X11BypassWindowManagerHint)
      self.setWindowTitle('Nemu')
      self.setMouseTracking(True)
      
      iconPath = os.path.join(os.path.dirname(__file__), 'images')
      iconPath = os.path.join(iconPath, 'nemu.png')
      self.setWindowIcon(IconCache()[iconPath])
      
      self.place()
      
      self.buttonListLayout = QVBoxLayout(self)
      self.setMargins(self.buttonListLayout)
      
      self.buttonLayout = QHBoxLayout()
      self.setMargins(self.buttonLayout)
      
      # Settings and Filter box
      self.filterLayout = QHBoxLayout()
      self.settingsButton = QPushButton()
      self.settingsButton.setIcon(QIcon(iconPath))
      self.settingsButton.setMinimumHeight(35)
      self.settingsButton.clicked.connect(self.settingsClicked)
      self.filterLayout.addWidget(self.settingsButton, 0)
      
      self.filterLabel = QLabel("Filter")
      self.filterLayout.addWidget(self.filterLabel)
      
      self.filterBox = QLineEdit()
      self.filterBox.textChanged.connect(self.refresh)
      self.filterLayout.addWidget(self.filterBox)
      
      self.sizeGrip = QSizeGrip(self)
      self.sizeGrip.setMinimumSize(QSize(25, 25))
      self.filterLayout.addWidget(self.sizeGrip, 0, Qt.AlignRight | Qt.AlignTop)
      
      self.buttonListLayout.addLayout(self.filterLayout)
      
      # Top buttons and labels
      self.backButton = QPushButton('Favorites')
      self.backButton.setMinimumHeight(35)
      self.backButton.clicked.connect(self.backClicked)
      self.buttonLayout.addWidget(self.backButton, 1)
      
      self.currentLabel = QLabel()
      self.currentLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
      self.buttonLayout.addWidget(self.currentLabel, 1)
      
      self.buttonListLayout.addLayout(self.buttonLayout, 0)
      
      # Menu item display
      self.listSplitter = QSplitter()
      self.buttonListLayout.addWidget(self.listSplitter, 1)
      
      self.leftList = ListWidget(self.clearListMouseOver)
      self.listSplitter.addWidget(self.leftList)
      
      self.rightList = ListWidget(self.clearListMouseOver)
      self.listSplitter.addWidget(self.rightList)
      
      # Has to be done after adding widgets to the splitter or the size will get reset again
      if 'splitterState' in self.settings:
         self.listSplitter.restoreState(self.settings['splitterState'])
      
   def setMargins(self, layout, margin = 0):
      layout.setSpacing(margin)
      layout.setContentsMargins(margin, margin, margin, margin)
      
      
   def createMenu(self, widget):
      addFavoriteAction = QAction('Add to Favorites', self)
      addFavoriteAction.triggered.connect(self.addFavoriteClicked)
      widget.insertAction(None, addFavoriteAction)
      addAction = QAction("New...", self)
      addAction.triggered.connect(self.newClicked)
      widget.insertAction(None, addAction)
      editAction = QAction("Edit...", self)
      editAction.triggered.connect(self.editClicked)
      widget.insertAction(None, editAction)
      deleteAction = QAction("Delete", self)
      deleteAction.triggered.connect(self.deleteClicked)
      widget.insertAction(None, deleteAction)
      
      
   def hideOrClose(self):
      if self.settings['quit']:
         self.close()
      else:
         self.hide()
         
   def closeEvent(self, event):
      self.saveSettings()
      
   def hideEvent(self, event):
      self.releaseMouse()
      self.saveSettings()
      
   def mouseMoveEvent(self, event):
      if self.hasMouse():
         self.releaseMouse()
      
   def leaveEvent(self, event):
      # If we set holdOpen, it means that we've opened a dialog, so we shouldn't grab
      if not self.hasMouse():
         self.grabMouse()
      
   def mousePressEvent(self, event):
      if not self.hasMouse():
         self.hideOrClose()
         
   def hasMouse(self):
      return self.geometry().contains(QCursor.pos())
         

   def saveSettings(self):
      self.settings['splitterState'] = self.listSplitter.saveState()
      self.settings['width'] = self.width()
      self.settings['height'] = self.height()
      with open(self.settingsFile, 'wb') as f:
         cPickle.dump(self.settings, f)
         
   def place(self):
      desktop = qApp.desktop()
      screenSize = desktop.availableGeometry(QCursor.pos())
      self.move(screenSize.x(), screenSize.y() + screenSize.height() - self.height())
         
         
   def newClicked(self):
      form = AddForm()
      
      self.holdOpen = True
      form.exec_()
      self.checkMouse()
      self.holdOpen = False
      
      if form.accepted:
         item = MenuItem()
         item.name = form.name
         item.command = form.command
         item.working = form.working
         item.folder = form.folder
         item.icon = form.icon
         item.findIcon()
         
         clicked = self.getClicked()
         if clicked:
            parent = clicked.item.parent
         elif self.leftList.mouseOver:
            if self.currentItem != None:
               parent = self.currentItem.parent
            else:
               parent = None
         else:
            parent = self.currentItem
         item.parent = parent
         
         self.menuItems.append(item)
         self.refresh()
      
   def editClicked(self):
      form = AddForm()
      clicked = self.getClicked()
      if clicked == None:
         return
      item = clicked.item
      
      form.name = item.name
      form.command = item.command
      form.working = item.working
      form.folder = item.folder
      form.icon = item.icon
      form.populateFields()
      
      self.holdOpen = True
      form.exec_()
      self.checkMouse()
      self.holdOpen = False
      
      if form.accepted:
         item.name = form.name
         item.command = form.command
         item.working = form.working
         item.folder = form.folder
         item.icon = form.icon
         item.imported = False
         item.findIcon()
         self.refresh()
         
         
   def checkMouse(self):
      if not self.hasMouse():
         self.grabMouse()
      
      
   def deleteClicked(self):
      clicked = self.getClicked()
      if clicked == None:
         return
      self.delete(clicked.item)
      self.refresh()
      
   # Delete item and all of its children so we don't leave around orphaned items
   def delete(self, item):
      for i in self.menuItems:
         if i.parent == item:
            i.deleted = True
      
      if item in self.menuItems:
         item.deleted = True
         item.imported = False
      if item in self.favorites:
         self.favorites.remove(item)
      
      
   def addFavoriteClicked(self):
      newFavorite = copy.copy(self.getClicked().item)
      newFavorite.parent = None
      self.favorites.append(newFavorite)
      self.refresh()
      
      
   def getClicked(self):
      for i in self.allItems:
         if i.mouseOver:
            return i
            
   def clearMouseOver(self):
      for i in self.allItems:
         i.mouseOver = False
         
   def clearListMouseOver(self):
      self.leftList.mouseOver = False
      self.rightList.mouseOver = False
      
      
   def refresh(self, save = True):
      self.leftList.clear()
      self.rightList.clear()
      self.allItems = []
      sortedLeft = []
      sortedRight = []
      self.updateFilter()
      
      if self.currentItem != None:
         currParent = self.currentItem.parent
         for i in self.menuItems:
            if i.parent == currParent and not i.deleted and i.matchedFilter:
               sortedLeft.append(i)
      else:
         for i in self.favorites:
            sortedLeft.append(i)
      
      for i in self.menuItems:
         if i.parent == self.currentItem and not i.deleted and i.matchedFilter:
            sortedRight.append(i)
            
      sortedLeft.sort(key = lambda x: x.name)
      sortedLeft.sort(key = lambda x: not x.folder)
      sortedRight.sort(key = lambda x: x.name)
      sortedRight.sort(key = lambda x: not x.folder)
      for i in sortedLeft:
         self.leftList.add(self.createItem(i))
      for i in sortedRight:
         self.rightList.add(self.createItem(i))
         
      if save:
         self.saveMenu()

   def saveMenu(self):
      # Save the current menu status
      with open(self.menuFile, 'wb') as f:
         cPickle.dump(self.menuItems, f)
      with open(self.favoritesFile, 'wb') as f:
         cPickle.dump(self.favorites, f)

   def createItem(self, item):
      newItem = ListItem(item, self.clearMouseOver)
      newItem.clicked.connect(self.itemClicked)
      self.allItems.append(newItem)
      return newItem
      
   def updateFilter(self):
      filterValue = str(self.filterBox.text())
      
      for i in self.menuItems:
         i.checkFilter(filterValue)
            
      
   def itemClicked(self):
      sender = self.sender()
      if sender.item.folder:
         self.setCurrentItem(sender.item)
         self.refresh(False)
      else:
         flags = ['f', 'F', 'u', 'U', 'd', 'D', 'n', 'N', 'i', 'k', 'v', 'm']
         command = sender.item.command
         for i in flags:
            command = command.replace('%' + i, '')
         # %c needs a proper value in some cases
         command = command.replace('%c', '"%s"' % sender.item.name)
         working = sender.item.working
         if not os.path.isdir(working):
            working = None
            
         # Need to redirect stdout and stderr so if the process writes something it won't fail
         with open(os.path.devnull, 'w') as devnull:
            Popen(command + '&', stdout=devnull, stderr=devnull, shell=True, cwd=working)
         self.hideOrClose()
         
         
   def backClicked(self):
      if self.currentItem:
         self.setCurrentItem(self.currentItem.parent)
         self.refresh(False)
         
         
   def setCurrentItem(self, item):
      self.currentItem = item
      if item != None:
         self.currentLabel.setText(item.name)
         if item.parent != None:
            self.backButton.setText(item.parent.name)
         else:
            self.backButton.setText('Favorites')
      else:
         self.currentLabel.setText('')
         self.backButton.setText('Favorites')
         
         
   def settingsClicked(self):
      form = SettingsForm(self)
      form.quitCheck.setChecked(self.settings['quit'])
      theme = self.settings.get('iconTheme')
      if theme:
         form.themeCombo.setCurrentIndex(form.themeCombo.findText(theme))
      
      self.holdOpen = True
      form.exec_()
      self.checkMouse()
      self.holdOpen = False
      
      if form.accepted:
         self.settings['quit'] = form.quitCheck.isChecked()
      
      
   def firstRun(self):
      QMessageBox.information(self, 'First Time?', 'Your menu is currently empty.  It is recommended that you import an existing menu file.')
      self.settingsClicked()
      
      
   def connectToRunning(self):
      self.socket = QLocalSocket()
      self.socket.connectToServer('nemuSocket')
      self.socket.waitForConnected(1000)
      
      if self.socket.state() == QLocalSocket.ConnectedState:
         print 'Server found'
         if self.socket.waitForReadyRead(3000):
            line = self.socket.readLine()
            print line
         else:
            print self.socket.errorString()
         sys.exit()
      else:
         print 'No server running'
      
      
   def handleConnection(self):
      import datetime
      print "Got connection", datetime.datetime.now()
      
      connection = self.server.nextPendingConnection()
      connection.write('connected')
      del connection
      
      self.setCurrentItem(None)
      self.filterBox.setText('')
      self.refresh(False)
      self.show()
      print "Showed", datetime.datetime.now()
      return
      
      
   # Call periodically to keep data resident in memory (hopefully)
   def keepalive(self):
      if self.isHidden():
         self.refresh(False)
Ejemplo n.º 55
0
class SingleApplicationClient(object):
    """
    Class implementing the single application client base class.
    """
    def __init__(self, name):
        """
        Constructor
        
        @param name name of the local server to connect to (string)
        """
        self.name = name
        self.connected = False
        
    def connect(self):
        """
        Public method to connect the single application client to its server.
        
        @return value indicating success or an error number. Value is one of:
            <table>
                <tr><td>0</td><td>No application is running</td></tr>
                <tr><td>1</td><td>Application is already running</td></tr>
            </table>
        """
        self.sock = QLocalSocket()
        self.sock.connectToServer(self.name)
        if self.sock.waitForConnected(10000):
            self.connected = True
            return 1
        else:
            err = self.sock.error()
            if err == QLocalSocket.ServerNotFoundError:
                return 0
            else:
                return -err
        
    def disconnect(self):
        """
        Public method to disconnect from the Single Appliocation server.
        """
        self.sock.disconnectFromServer()
        self.connected = False
    
    def processArgs(self, args):
        """
        Public method to process the command line args passed to the UI.
        
        <b>Note</b>: This method must be overridden by subclasses.
        
        @param args command line args (list of strings)
        @exception RuntimeError raised to indicate that this method must be
            implemented by a subclass
        """
        raise RuntimeError("'processArgs' must be overridden")
    
    def sendCommand(self, cmd):
        """
        Public method to send the command to the application server.
        
        @param cmd command to be sent (string)
        """
        if self.connected:
            self.sock.write(cmd)
            self.sock.flush()
        
    def errstr(self):
        """
        Public method to return a meaningful error string for the last error.
        
        @return error string for the last error (string)
        """
        return self.sock.errorString()
Ejemplo n.º 56
0
class QtSingleApplication(QApplication):

    messageReceived = pyqtSignal(str)

    def __init__(self, id, *argv):

        super(QtSingleApplication, self).__init__(*argv)
        self._id = id
        self._activationWindow = None
        self._activateOnMessage = False

        # Is there another instance running?
        self._outSocket = QLocalSocket()
        self._outSocket.connectToServer(self._id)
        self._isRunning = self._outSocket.waitForConnected()

        if self._isRunning:
            # Yes, there is.
            self._outStream = QTextStream(self._outSocket)
            self._outStream.setCodec("UTF-8")
        else:
            # No, there isn't.
            self._outSocket = None
            self._outStream = None
            self._inSocket = None
            self._inStream = None
            self._server = QLocalServer()
            self._server.listen(self._id)
            self._server.newConnection.connect(self._onNewConnection)

    def isRunning(self):
        return self._isRunning

    def id(self):
        return self._id

    def activationWindow(self):
        return self._activationWindow

    def setActivationWindow(self, activationWindow, activateOnMessage=True):
        self._activationWindow = activationWindow
        self._activateOnMessage = activateOnMessage

    def activateWindow(self):
        if not self._activationWindow:
            return

        self._activationWindow.show()
        self._activationWindow.setWindowState(self._activationWindow.windowState() & ~Qt.WindowMinimized)
        self._activationWindow.raise_()
        self._activationWindow.activateWindow()

    def sendMessage(self, msg):
        if not self._outStream:
            return False
        self._outStream << msg << "\n"
        self._outStream.flush()
        return self._outSocket.waitForBytesWritten()

    def _onNewConnection(self):
        if self._inSocket:
            self._inSocket.readyRead.disconnect(self._onReadyRead)
        self._inSocket = self._server.nextPendingConnection()
        if not self._inSocket:
            return
        self._inStream = QTextStream(self._inSocket)
        self._inStream.setCodec("UTF-8")
        self._inSocket.readyRead.connect(self._onReadyRead)
        if self._activateOnMessage:
            self.activateWindow()

    def _onReadyRead(self):
        while True:
            msg = self._inStream.readLine()
            if not msg:
                break
            self.messageReceived.emit(msg)
Ejemplo n.º 57
0
def send_to_running_instance(socketname, command, target_arg, *, legacy_name=None, socket=None):
    """Try to send a commandline to a running instance.

    Blocks for CONNECT_TIMEOUT ms.

    Args:
        socketname: The name which should be used for the socket.
        command: The command to send to the running instance.
        target_arg: --target command line argument
        socket: The socket to read data from, or None.
        legacy_name: The legacy name to first try to connect to.

    Return:
        True if connecting was successful, False if no connection was made.
    """
    if socket is None:
        socket = QLocalSocket()

    if legacy_name is not None and _has_legacy_server(legacy_name):
        name_to_use = legacy_name
    else:
        name_to_use = socketname

    log.ipc.debug("Connecting to {}".format(name_to_use))
    socket.connectToServer(name_to_use)

    connected = socket.waitForConnected(CONNECT_TIMEOUT)
    if connected:
        log.ipc.info("Opening in existing instance")
        json_data = {
            "args": command,
            "target_arg": target_arg,
            "version": qutebrowser.__version__,
            "protocol_version": PROTOCOL_VERSION,
        }
        try:
            cwd = os.getcwd()
        except OSError:
            pass
        else:
            json_data["cwd"] = cwd
        line = json.dumps(json_data) + "\n"
        data = line.encode("utf-8")
        log.ipc.debug("Writing: {}".format(data))
        socket.writeData(data)
        socket.waitForBytesWritten(WRITE_TIMEOUT)
        if socket.error() != QLocalSocket.UnknownSocketError:
            raise SocketError("writing to running instance", socket)
        else:
            socket.disconnectFromServer()
            if socket.state() != QLocalSocket.UnconnectedState:
                socket.waitForDisconnected(CONNECT_TIMEOUT)
            return True
    else:
        if socket.error() not in (QLocalSocket.ConnectionRefusedError, QLocalSocket.ServerNotFoundError):
            raise SocketError("connecting to running instance", socket)
        else:
            log.ipc.debug("No existing instance present (error {})".format(socket.error()))
            return False
Ejemplo n.º 58
0
    def __init__(self, argv):
        """
        Initialize Eddy.
        :type argv: list
        """
        super().__init__(argv)

        parser = ArgumentParser()
        parser.add_argument('--nosplash', dest='nosplash', action='store_true')
        parser.add_argument('--tests', dest='tests', action='store_true')

        options, args = parser.parse_known_args(args=argv)

        self.inSocket = None
        self.inStream = None
        self.outSocket = QLocalSocket()
        self.outSocket.connectToServer(APPID)
        self.outStream = None
        self.isRunning = self.outSocket.waitForConnected()
        self.mainwindow = None
        self.pendingOpen = []
        self.server = None

        # We do not initialize a new instance of Eddy if there is a process running
        # and we are not executing the tests suite: we'll create a socket instead so we can
        # exchange messages between the 2 processes (this one and the already running one).
        if self.isRunning and not options.tests:
            self.outStream = QTextStream(self.outSocket)
            self.outStream.setCodec('UTF-8')
        else:
            self.server = QLocalServer()
            self.server.listen(APPID)
            self.outSocket = None
            self.outStream = None

            connect(self.server.newConnection, self.newConnection)
            connect(self.messageReceived, self.readMessage)

            ############################################################################################################
            #                                                                                                          #
            #   PERFORM EDDY INITIALIZATION                                                                            #
            #                                                                                                          #
            ############################################################################################################

            # Draw the splashscreen.
            self.splashscreen = None
            if not options.nosplash:
                self.splashscreen = SplashScreen(min_splash_time=4)
                self.splashscreen.show()

            # Setup layout.
            self.setStyle(Clean('Fusion'))
            with open(expandPath('@eddy/ui/clean.qss')) as sheet:
                self.setStyleSheet(sheet.read())

            # Create the main window.
            self.mainwindow = MainWindow()

            # Close the splashscreen.
            if self.splashscreen:
                self.splashscreen.wait(self.splashscreen.remaining)
                self.splashscreen.close()

            # Display the mainwindow.
            self.mainwindow.show()

            if Platform.identify() is Platform.Darwin:
                # On MacOS files being opened are handled as a QFileOpenEvent but since we don't
                # have a Main Window initialized we store them locally and we open them here.
                for filepath in self.pendingOpen:
                    self.openFile(filepath)
                self.pendingOpen = []
            else:
                # Perform document opening if files have been added to sys.argv. This is not
                # executed on Mac OS since this is already handled as a QFileOpenEvent instance.
                for filepath in argv:
                    self.openFile(filepath)
Ejemplo n.º 59
0
class Eddy(QApplication):
    """
    This class implements the main Qt application.
    """
    messageReceived = pyqtSignal(str)

    def __init__(self, argv):
        """
        Initialize Eddy.
        :type argv: list
        """
        super().__init__(argv)

        parser = ArgumentParser()
        parser.add_argument('--nosplash', dest='nosplash', action='store_true')
        parser.add_argument('--tests', dest='tests', action='store_true')

        options, args = parser.parse_known_args(args=argv)

        self.inSocket = None
        self.inStream = None
        self.outSocket = QLocalSocket()
        self.outSocket.connectToServer(APPID)
        self.outStream = None
        self.isRunning = self.outSocket.waitForConnected()
        self.mainwindow = None
        self.pendingOpen = []
        self.server = None

        # We do not initialize a new instance of Eddy if there is a process running
        # and we are not executing the tests suite: we'll create a socket instead so we can
        # exchange messages between the 2 processes (this one and the already running one).
        if self.isRunning and not options.tests:
            self.outStream = QTextStream(self.outSocket)
            self.outStream.setCodec('UTF-8')
        else:
            self.server = QLocalServer()
            self.server.listen(APPID)
            self.outSocket = None
            self.outStream = None

            connect(self.server.newConnection, self.newConnection)
            connect(self.messageReceived, self.readMessage)

            ############################################################################################################
            #                                                                                                          #
            #   PERFORM EDDY INITIALIZATION                                                                            #
            #                                                                                                          #
            ############################################################################################################

            # Draw the splashscreen.
            self.splashscreen = None
            if not options.nosplash:
                self.splashscreen = SplashScreen(min_splash_time=4)
                self.splashscreen.show()

            # Setup layout.
            self.setStyle(Clean('Fusion'))
            with open(expandPath('@eddy/ui/clean.qss')) as sheet:
                self.setStyleSheet(sheet.read())

            # Create the main window.
            self.mainwindow = MainWindow()

            # Close the splashscreen.
            if self.splashscreen:
                self.splashscreen.wait(self.splashscreen.remaining)
                self.splashscreen.close()

            # Display the mainwindow.
            self.mainwindow.show()

            if Platform.identify() is Platform.Darwin:
                # On MacOS files being opened are handled as a QFileOpenEvent but since we don't
                # have a Main Window initialized we store them locally and we open them here.
                for filepath in self.pendingOpen:
                    self.openFile(filepath)
                self.pendingOpen = []
            else:
                # Perform document opening if files have been added to sys.argv. This is not
                # executed on Mac OS since this is already handled as a QFileOpenEvent instance.
                for filepath in argv:
                    self.openFile(filepath)

    ####################################################################################################################
    #                                                                                                                  #
    #   EVENTS                                                                                                         #
    #                                                                                                                  #
    ####################################################################################################################

    def event(self, event):
        """
        Executed when an event is received.
        :type event: T <= QEvent | QFileOpenEvent
        """
        if event.type() == QEvent.FileOpen:
            self.pendingOpen = [event.file()]
            return True
        return super().event(event)

    ####################################################################################################################
    #                                                                                                                  #
    #   INTERFACE                                                                                                      #
    #                                                                                                                  #
    ####################################################################################################################

    def activate(self):
        """
        Activate the application by raising the main window.
        """
        if self.mainwindow:
            self.mainwindow.setWindowState((self.mainwindow.windowState() & ~Qt.WindowMinimized) | Qt.WindowActive)
            self.mainwindow.activateWindow()
            self.mainwindow.raise_()

    def openFile(self, filepath):
        """
        Open the given file in the activation window.
        :type filepath: str
        :rtype: bool
        """
        if self.mainwindow:
            if not isEmpty(filepath) and os.path.isfile(filepath) and filepath.endswith(Filetype.Graphol.extension):
                self.mainwindow.openFile(filepath)
                return True
        return False

    def sendMessage(self, message):
        """
        Send a message to the other alive Eddy's process.
        :type message: str
        :rtype: bool
        """
        if self.outStream:
            self.outStream = self.outStream << message << '\n'
            self.outStream.flush()
            return self.outSocket.waitForBytesWritten()
        return False

    ####################################################################################################################
    #                                                                                                                  #
    #   SLOTS                                                                                                          #
    #                                                                                                                  #
    ####################################################################################################################

    @pyqtSlot()
    def newConnection(self):
        """
        Executed whenever a message is received.
        """
        if self.inSocket:
            # Disconnect previously connected signal slot.
            disconnect(self.inSocket.readyRead, self.readyRead)

        # Create a new socket.
        self.inSocket = self.server.nextPendingConnection()

        if self.inSocket:
            self.inStream = QTextStream(self.inSocket)
            self.inStream.setCodec('UTF-8')
            connect(self.inSocket.readyRead, self.readyRead)
            self.activate()

    @pyqtSlot()
    def readyRead(self):
        """
        Executed whenever we need to read a message.
        """
        while True:
            message = self.inStream.readLine()
            if isEmpty(message):
                break
            self.messageReceived.emit(message)

    @pyqtSlot(str)
    def readMessage(self, message):
        """
        Read a received message.
        :type message: str
        """
        for filepath in message.split(' '):
            self.openFile(filepath)
Ejemplo n.º 60
0
    def _send_to_running_instance(self, payload: bytes, pid: int) -> None:
        from PyQt5.QtCore import QByteArray
        from PyQt5.QtNetwork import QLocalSocket

        named_pipe = f"{BUNDLE_IDENTIFIER}.protocol.{pid}"
        log.debug(
            f"Opening a local socket to the running instance on {named_pipe} "
            f"(payload={self.redact_payload(payload)})"
        )
        client = QLocalSocket()
        try:
            client.connectToServer(named_pipe)

            if not client.waitForConnected():
                log.error(f"Unable to open client socket: {client.errorString()}")
                return

            client.write(QByteArray(payload))
            client.waitForBytesWritten()
            client.disconnectFromServer()
            if client.state() == QLocalSocket.ConnectedState:
                client.waitForDisconnected()
        finally:
            del client
        log.debug("Successfully closed client socket")