easycoder 251105.1__py2.py3-none-any.whl → 260111.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. easycoder/__init__.py +6 -3
  2. easycoder/debugger/__init__.py +5 -0
  3. easycoder/debugger/ec_dbg_value_display copy.py +195 -0
  4. easycoder/debugger/ec_dbg_value_display.py +24 -0
  5. easycoder/debugger/ec_dbg_watch_list copy.py +219 -0
  6. easycoder/debugger/ec_dbg_watchlist.py +293 -0
  7. easycoder/debugger/ec_debug.py +1025 -0
  8. easycoder/ec_classes.py +487 -11
  9. easycoder/ec_compiler.py +81 -44
  10. easycoder/ec_condition.py +1 -1
  11. easycoder/ec_core.py +1042 -1081
  12. easycoder/ec_gclasses.py +236 -0
  13. easycoder/ec_graphics.py +1683 -0
  14. easycoder/ec_handler.py +18 -14
  15. easycoder/ec_mqtt.py +248 -0
  16. easycoder/ec_program.py +297 -168
  17. easycoder/ec_psutil.py +48 -0
  18. easycoder/ec_value.py +65 -47
  19. easycoder/pre/README.md +3 -0
  20. easycoder/pre/__init__.py +17 -0
  21. easycoder/pre/debugger/__init__.py +5 -0
  22. easycoder/pre/debugger/ec_dbg_value_display copy.py +195 -0
  23. easycoder/pre/debugger/ec_dbg_value_display.py +24 -0
  24. easycoder/pre/debugger/ec_dbg_watch_list copy.py +219 -0
  25. easycoder/pre/debugger/ec_dbg_watchlist.py +293 -0
  26. easycoder/{ec_debug.py → pre/debugger/ec_debug.py} +418 -185
  27. easycoder/pre/ec_border.py +67 -0
  28. easycoder/pre/ec_classes.py +470 -0
  29. easycoder/pre/ec_compiler.py +291 -0
  30. easycoder/pre/ec_condition.py +27 -0
  31. easycoder/pre/ec_core.py +2772 -0
  32. easycoder/pre/ec_gclasses.py +230 -0
  33. easycoder/{ec_pyside.py → pre/ec_graphics.py} +583 -433
  34. easycoder/pre/ec_handler.py +79 -0
  35. easycoder/pre/ec_keyboard.py +439 -0
  36. easycoder/pre/ec_program.py +557 -0
  37. easycoder/pre/ec_psutil.py +48 -0
  38. easycoder/pre/ec_timestamp.py +11 -0
  39. easycoder/pre/ec_value.py +124 -0
  40. easycoder/pre/icons/close.png +0 -0
  41. easycoder/pre/icons/exit.png +0 -0
  42. easycoder/pre/icons/run.png +0 -0
  43. easycoder/pre/icons/step.png +0 -0
  44. easycoder/pre/icons/stop.png +0 -0
  45. easycoder/pre/icons/tick.png +0 -0
  46. {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/METADATA +11 -1
  47. easycoder-260111.1.dist-info/RECORD +59 -0
  48. easycoder-251105.1.dist-info/RECORD +0 -24
  49. {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/WHEEL +0 -0
  50. {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/entry_points.txt +0 -0
  51. {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/licenses/LICENSE +0 -0
easycoder/ec_handler.py CHANGED
@@ -1,4 +1,5 @@
1
- import json
1
+ import sys, json
2
+ from .ec_classes import normalize_type
2
3
 
3
4
  class Handler:
4
5
 
@@ -8,6 +9,7 @@ class Handler:
8
9
  self.getToken = compiler.getToken
9
10
  self.nextToken = compiler.nextToken
10
11
  self.skip = compiler.skip
12
+ self.skipArticles = compiler.skipArticles
11
13
  self.peek = compiler.peek
12
14
  self.getValue = compiler.getValue
13
15
  self.nextValue = compiler.nextValue
@@ -18,8 +20,9 @@ class Handler:
18
20
  self.nextIs = compiler.nextIs
19
21
  self.isSymbol = compiler.isSymbol
20
22
  self.nextIsSymbol = compiler.nextIsSymbol
21
- self.getSymbolRecord = compiler.getSymbolRecord
22
23
  self.compileVariable = compiler.compileVariable
24
+ self.compileSymbol = compiler.compileSymbol
25
+ self.getSymbolRecord = compiler.getSymbolRecord
23
26
  self.rewindTo = compiler.rewindTo
24
27
  self.warning = compiler.warning
25
28
  self.getCodeSize = compiler.getCodeSize
@@ -30,9 +33,15 @@ class Handler:
30
33
  self.compileConstant = compiler.compileConstant
31
34
 
32
35
  self.code = self.program.code
36
+ self.checkObjectType = self.program.checkObjectType
37
+ self.isObjectType = self.program.isObjectType
38
+ self.isObjectType = self.program.isObjectType
39
+ self.getInnerObject = self.program.getInnerObject
40
+ self.getItemType = self.program.getItemType
33
41
  self.evaluate = self.program.evaluate
34
- self.getVariable = self.program.getSymbolRecord
35
- self.getRuntimeValue = self.program.getRuntimeValue
42
+ self.getVariable = self.program.getVariable
43
+ self.getObject = self.program.getObject
44
+ self.textify = self.program.textify
36
45
  self.testCondition = self.program.condition.testCondition
37
46
  self.symbols = self.program.symbols
38
47
  self.stack = self.program.stack
@@ -40,10 +49,9 @@ class Handler:
40
49
  self.getSymbolValue = self.program.getSymbolValue
41
50
  self.putSymbolValue = self.program.putSymbolValue
42
51
  self.run = self.program.run
52
+ self.callback = self.program.callback
43
53
 
44
54
  self.nonNumericValueError = self.program.nonNumericValueError
45
- self.variableDoesNotHoldAValueError = self.program.variableDoesNotHoldAValueError
46
- self.noneValueError = self.program.noneValueError
47
55
 
48
56
  def nextPC(self):
49
57
  return self.program.pc + 1
@@ -64,12 +72,8 @@ class Handler:
64
72
 
65
73
  # Get a condition handler
66
74
  def conditionHandler(self, name):
67
- return getattr(self, f'c_{name}')
75
+ return getattr(self, f'c_{normalize_type(name)}')
68
76
 
69
- @staticmethod
70
- def isJson(value):
71
- try:
72
- json.loads(value)
73
- except ValueError as e:
74
- return False
75
- return True
77
+ # Get the value of an unknown item (domain-specific)
78
+ def getUnknownValue(self, value):
79
+ return value
easycoder/ec_mqtt.py ADDED
@@ -0,0 +1,248 @@
1
+ from easycoder import Handler, ECObject, ECValue, RuntimeError
2
+ import paho.mqtt.client as mqtt
3
+
4
+ #############################################################################
5
+ # MQTT client class
6
+ class MQTTClient():
7
+ def __init__(self):
8
+ super().__init__()
9
+
10
+ def create(self, program, clientID, broker, port, topics):
11
+ self.program = program
12
+ self.clientID = clientID
13
+ self.broker = broker
14
+ self.port = port
15
+ self.topics = topics
16
+ self.onMessagePC = None
17
+ self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=self.clientID) # type: ignore
18
+
19
+ # Setup callbacks
20
+ self.client.on_connect = self.on_connect
21
+ self.client.on_message = self.on_message
22
+
23
+ def on_connect(self, client, userdata, flags, reason_code, properties):
24
+ print(f"Client {self.clientID} connected")
25
+ for item in self.topics:
26
+ topic = self.program.getObject(self.program.getVariable(item))
27
+ self.client.subscribe(topic.getName(), qos=topic.getQOS())
28
+ print(f"Subscribed to topic: {topic.getName()} with QoS {topic.getQOS()}")
29
+
30
+ def on_message(self, client, userdata, msg):
31
+ # print(f"Message received on topic {msg.topic}: {msg.payload.decode()}")
32
+ if self.onMessagePC is not None:
33
+ self.message = msg
34
+ self.program.run(self.onMessagePC)
35
+ self.program.flushCB()
36
+
37
+ def getMessageTopic(self):
38
+ return self.message.topic
39
+
40
+ def getMessagePayload(self):
41
+ return self.message.payload.decode('utf-8')
42
+
43
+ def onMessage(self, pc):
44
+ self.onMessagePC = pc
45
+
46
+ def sendMessage(self, topic, message, qos):
47
+ self.client.publish(topic, message, qos=qos)
48
+
49
+ def run(self):
50
+ self.client.connect(self.broker, int(self.port), 60)
51
+ self.client.loop_start()
52
+
53
+ ###############################################################################
54
+ # An MQTT topic
55
+ class ECTopic(ECObject):
56
+ def __init__(self):
57
+ super().__init__()
58
+
59
+ def create(self, name, qos=1):
60
+ super().__init__()
61
+ self.name = name
62
+ self.qos = qos
63
+
64
+ def getName(self):
65
+ return self.name
66
+
67
+ def getQOS(self):
68
+ return self.qos
69
+
70
+ ###############################################################################
71
+ # The MQTT compiler and rutime handlers
72
+ class MQTT(Handler):
73
+
74
+ def __init__(self, compiler):
75
+ Handler.__init__(self, compiler)
76
+ self.spoke = None
77
+
78
+ def getName(self):
79
+ return 'mqtt'
80
+
81
+ #############################################################################
82
+ # Keyword handlers
83
+
84
+ # init {topic} name {name} qos {qos}
85
+ def k_init(self, command):
86
+ if self.nextIsSymbol():
87
+ record = self.getSymbolRecord()
88
+ self.checkObjectType(record, ECTopic)
89
+ command['topic'] = record['name']
90
+ self.skip('name')
91
+ command['name'] = self.nextValue()
92
+ self.skip('qos')
93
+ command['qos'] = self.nextValue()
94
+ self.add(command)
95
+ return True
96
+ return False
97
+
98
+ def r_init(self, command):
99
+ record = self.getVariable(command['topic'])
100
+ topic = ECTopic()
101
+ topic.create(self.textify(command['name']), qos=int(self.textify(command['qos'])))
102
+ record['object'] = topic
103
+ return self.nextPC()
104
+
105
+ # mqtt id {clientID} broker {broker} port {port} topics {topic} [and {topic} ...]
106
+ def k_mqtt(self, command):
107
+ while True:
108
+ token = self.peek()
109
+ if token == 'id':
110
+ self.nextToken()
111
+ command['clientID'] = self.nextValue()
112
+ elif token == 'broker':
113
+ self.nextToken()
114
+ command['broker'] = self.nextValue()
115
+ elif token == 'port':
116
+ self.nextToken()
117
+ command['port'] = self.nextValue()
118
+ elif token == 'topics':
119
+ self.nextToken()
120
+ topics = []
121
+ while self.nextIsSymbol():
122
+ record = self.getSymbolRecord()
123
+ self.checkObjectType(record, ECTopic())
124
+ topics.append(record['name'])
125
+ if self.peek() == 'and': self.nextToken()
126
+ else:break
127
+ command['topics'] = topics
128
+ else:
129
+ self.add(command)
130
+ return True
131
+ return False
132
+
133
+ def r_mqtt(self, command):
134
+ if hasattr(self.program, 'mqttClient'):
135
+ raise RuntimeError(self.program, 'MQQT client already defined')
136
+ clientID = self.textify(command['clientID'])
137
+ broker = self.textify(command['broker'])
138
+ port = self.textify(command['port'])
139
+ topics = command['topics']
140
+ client = MQTTClient()
141
+ client.create(self.program, clientID, broker, port, topics)
142
+ client.run()
143
+ self.program.mqttClient = client
144
+ return self.nextPC()
145
+
146
+ # on mqtt message {action}
147
+ def k_on(self, command):
148
+ token = self.peek()
149
+ if token == 'mqtt':
150
+ self.nextToken()
151
+ if self.nextIs('message'):
152
+ self.nextToken()
153
+ command['goto'] = 0
154
+ self.add(command)
155
+ cmd = {}
156
+ cmd['domain'] = 'core'
157
+ cmd['lino'] = command['lino']
158
+ cmd['keyword'] = 'gotoPC'
159
+ cmd['goto'] = 0
160
+ cmd['debug'] = False
161
+ self.add(cmd)
162
+ # Add the action and a 'stop'
163
+ self.compileOne()
164
+ cmd = {}
165
+ cmd['domain'] = 'core'
166
+ cmd['lino'] = command['lino']
167
+ cmd['keyword'] = 'stop'
168
+ cmd['debug'] = False
169
+ self.add(cmd)
170
+ # Fixup the link
171
+ command['goto'] = self.getCodeSize()
172
+ return True
173
+ return False
174
+
175
+ def r_on(self, command):
176
+ self.program.mqttClient.onMessage(self.nextPC()+1)
177
+ return command['goto']
178
+
179
+ # send {message} to {topic}
180
+ def k_send(self, command):
181
+ if self.nextIs('mqtt'):
182
+ command['message'] = self.nextValue()
183
+ self.skip('from')
184
+ if self.nextIsSymbol():
185
+ record = self.getSymbolRecord()
186
+ self.checkObjectType(record, MQTTClient)
187
+ command['from'] = record['name']
188
+ self.skip('to')
189
+ if self.nextIsSymbol():
190
+ record = self.getSymbolRecord()
191
+ self.checkObjectType(record, MQTTClient)
192
+ command['to'] = record['name']
193
+ self.add(command)
194
+ return True
195
+ return False
196
+
197
+ def r_send(self, command):
198
+ if not hasattr(self.program, 'mqttClient'):
199
+ raise RuntimeError(self.program, 'No MQTT client defined')
200
+ topic = self.getObject(self.getVariable(command['to']))
201
+ message = self.textify(command['message'])
202
+ self.program.mqttClient.sendMessage(topic.getName(), message, topic.getQOS())
203
+ return self.nextPC()
204
+
205
+ # Declare a topic variable
206
+ def k_topic(self, command):
207
+ self.compiler.addValueType()
208
+ return self.compileVariable(command, 'ECTopic')
209
+
210
+ def r_topic(self, command):
211
+ return self.nextPC()
212
+
213
+ #############################################################################
214
+ # Compile a value in this domain
215
+ def compileValue(self):
216
+ token = self.nextToken()
217
+ if token == 'mqtt':
218
+ value = ECValue(domain=self.getName())
219
+ token = self.nextToken()
220
+ if token in ['topic', 'message']:
221
+ value.setType(token)
222
+ return value
223
+ else:
224
+ return self.getValue()
225
+ return None
226
+
227
+ #############################################################################
228
+ # Modify a value or leave it unchanged.
229
+ def modifyValue(self, value):
230
+ return value
231
+
232
+ #############################################################################
233
+ # Value handlers
234
+
235
+ def v_message(self, v):
236
+ return self.program.mqttClient.getMessagePayload()
237
+
238
+ def v_topic(self, v):
239
+ return self.program.mqttClient.getMessageTopic()
240
+
241
+ #############################################################################
242
+ # Compile a condition
243
+ def compileCondition(self):
244
+ condition = {}
245
+ return condition
246
+
247
+ #############################################################################
248
+ # Condition handlers