src/eric7/EricNetwork/EricJsonStreamReader.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 9090
224c634a1808
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a JSON based reader class.
8 """
9
10 import json
11
12 from PyQt6.QtCore import pyqtSignal, pyqtSlot
13 from PyQt6.QtNetwork import QTcpServer, QHostAddress
14
15 from EricWidgets import EricMessageBox
16
17 import Preferences
18 import Utilities
19
20
21 class EricJsonReader(QTcpServer):
22 """
23 Class implementing a JSON based reader class.
24
25 The reader is responsible for opening a socket to listen for writer
26 connections.
27
28 @signal dataReceived(object) emitted after a data object was received
29 """
30 dataReceived = pyqtSignal(object)
31
32 def __init__(self, name="", ip=None, parent=None):
33 """
34 Constructor
35
36 @param name name of the server (used for output only)
37 @type str
38 @param ip IP address to listen at
39 @type str
40 @param parent parent object
41 @type QObject
42 """
43 super().__init__(parent)
44
45 self.__name = name
46 self.__connection = None
47
48 # setup the network interface
49 if ip is None:
50 networkInterface = Preferences.getDebugger("NetworkInterface")
51 if networkInterface == "all" or '.' in networkInterface:
52 # IPv4
53 self.__hostAddress = '127.0.0.1'
54 else:
55 # IPv6
56 self.__hostAddress = '::1'
57 else:
58 self.__hostAddress = ip
59 self.listen(QHostAddress(self.__hostAddress))
60
61 self.newConnection.connect(self.handleNewConnection)
62
63 ## Note: Need the port if writer is started external in debugger.
64 print('JSON reader ({1}) listening on: {0:d}' # __IGNORE_WARNING__
65 .format(self.serverPort(), self.__name))
66
67 def address(self):
68 """
69 Public method to get the host address.
70
71 @return host address
72 @rtype str
73 """
74 return self.__hostAddress
75
76 def port(self):
77 """
78 Public method to get the port number to connect to.
79
80 @return port number
81 @rtype int
82 """
83 return self.serverPort()
84
85 @pyqtSlot()
86 def handleNewConnection(self):
87 """
88 Public slot for new incoming connections from a writer.
89 """
90 connection = self.nextPendingConnection()
91 if not connection.isValid():
92 return
93
94 if self.__connection is not None:
95 self.__connection.close()
96
97 self.__connection = connection
98
99 connection.readyRead.connect(self.__receiveJson)
100 connection.disconnected.connect(self.__handleDisconnect)
101
102 @pyqtSlot()
103 def __handleDisconnect(self):
104 """
105 Private slot handling a disconnect of the writer.
106 """
107 if self.__connection is not None:
108 self.__receiveJson() # read all buffered data first
109 self.__connection.close()
110
111 self.__connection = None
112
113 @pyqtSlot()
114 def __receiveJson(self):
115 """
116 Private slot handling received data from the writer.
117 """
118 while self.__connection and self.__connection.canReadLine():
119 dataStr = self.__connection.readLine()
120 jsonLine = bytes(dataStr).decode("utf-8", 'backslashreplace')
121
122 #- print("JSON Reader ({0}): {1}".format(self.__name, jsonLine))
123 #- this is for debugging only
124
125 try:
126 data = json.loads(jsonLine.strip())
127 except (TypeError, ValueError) as err:
128 EricMessageBox.critical(
129 None,
130 self.tr("JSON Protocol Error"),
131 self.tr("""<p>The data received from the writer"""
132 """ could not be decoded. Please report"""
133 """ this issue with the received data to the"""
134 """ eric bugs email address.</p>"""
135 """<p>Error: {0}</p>"""
136 """<p>Data:<br/>{1}</p>""").format(
137 str(err), Utilities.html_encode(jsonLine.strip())),
138 EricMessageBox.Ok)
139 return
140
141 self.dataReceived.emit(data)

eric ide

mercurial