src/eric7/EricNetwork/EricJsonStreamReader.py

branch
eric7-maintenance
changeset 9264
18a7312cfdb3
parent 9192
a763d57e23bc
parent 9221
bf71ee032bb4
child 9442
906485dcd210
equal deleted inserted replaced
9241:d23e9854aea4 9264:18a7312cfdb3
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
31 dataReceived = pyqtSignal(object)
32
33 def __init__(self, name="", ip=None, parent=None):
34 """
35 Constructor
36
37 @param name name of the server (used for output only)
38 @type str
39 @param ip IP address to listen at
40 @type str
41 @param parent parent object
42 @type QObject
43 """
44 super().__init__(parent)
45
46 self.__name = name
47 self.__connection = None
48
49 # setup the network interface
50 if ip is None:
51 networkInterface = Preferences.getDebugger("NetworkInterface")
52 if networkInterface == "all" or "." in networkInterface:
53 # IPv4
54 self.__hostAddress = "127.0.0.1"
55 else:
56 # IPv6
57 self.__hostAddress = "::1"
58 else:
59 self.__hostAddress = ip
60 self.listen(QHostAddress(self.__hostAddress))
61
62 self.newConnection.connect(self.handleNewConnection)
63
64 ## Note: Need the port if writer is started external in debugger.
65 print( # __IGNORE_WARNING_M801__
66 "JSON reader ({1}) listening on: {0:d}".format(
67 self.serverPort(), self.__name
68 )
69 )
70
71 def address(self):
72 """
73 Public method to get the host address.
74
75 @return host address
76 @rtype str
77 """
78 return self.__hostAddress
79
80 def port(self):
81 """
82 Public method to get the port number to connect to.
83
84 @return port number
85 @rtype int
86 """
87 return self.serverPort()
88
89 @pyqtSlot()
90 def handleNewConnection(self):
91 """
92 Public slot for new incoming connections from a writer.
93 """
94 connection = self.nextPendingConnection()
95 if not connection.isValid():
96 return
97
98 if self.__connection is not None:
99 self.__connection.close()
100
101 self.__connection = connection
102
103 connection.readyRead.connect(self.__receiveJson)
104 connection.disconnected.connect(self.__handleDisconnect)
105
106 @pyqtSlot()
107 def __handleDisconnect(self):
108 """
109 Private slot handling a disconnect of the writer.
110 """
111 if self.__connection is not None:
112 self.__receiveJson() # read all buffered data first
113 self.__connection.close()
114
115 self.__connection = None
116
117 @pyqtSlot()
118 def __receiveJson(self):
119 """
120 Private slot handling received data from the writer.
121 """
122 while self.__connection and self.__connection.canReadLine():
123 dataStr = self.__connection.readLine()
124 jsonLine = bytes(dataStr).decode("utf-8", "backslashreplace")
125
126 # - print("JSON Reader ({0}): {1}".format(self.__name, jsonLine))
127 # - this is for debugging only
128
129 try:
130 data = json.loads(jsonLine.strip())
131 except (TypeError, ValueError) as err:
132 EricMessageBox.critical(
133 None,
134 self.tr("JSON Protocol Error"),
135 self.tr(
136 """<p>The data received from the writer"""
137 """ could not be decoded. Please report"""
138 """ this issue with the received data to the"""
139 """ eric bugs email address.</p>"""
140 """<p>Error: {0}</p>"""
141 """<p>Data:<br/>{1}</p>"""
142 ).format(str(err), Utilities.html_encode(jsonLine.strip())),
143 EricMessageBox.Ok,
144 )
145 return
146
147 self.dataReceived.emit(data)

eric ide

mercurial