easycoder 250609.1__py2.py3-none-any.whl → 250611.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.

Potentially problematic release.


This version of easycoder might be problematic. Click here for more details.

easycoder/__init__.py CHANGED
@@ -9,4 +9,4 @@ from .ec_program import *
9
9
  from .ec_timestamp import *
10
10
  from .ec_value import *
11
11
 
12
- __version__ = "250609.1"
12
+ __version__ = "250611.1"
easycoder/ec_core.py CHANGED
@@ -1,4 +1,5 @@
1
- import json, math, hashlib, threading, os, subprocess, sys, time, numbers, base64, binascii, random, requests
1
+ import json, math, hashlib, threading, os, subprocess, sys, time
2
+ import numbers, base64, binascii, random, requests, paramiko
2
3
  from psutil import Process
3
4
  from datetime import datetime
4
5
  from random import randrange
@@ -386,7 +387,7 @@ class Core(Handler):
386
387
  return True
387
388
 
388
389
  def r_exit(self, command):
389
- if self.program.graphics != None:
390
+ if self.program.parent == None and self.program.graphics != None:
390
391
  self.program.graphics.force_exit(None)
391
392
  return -1
392
393
 
@@ -601,6 +602,7 @@ class Core(Handler):
601
602
  variable['name'] = name
602
603
  variable['keyword'] = keyword
603
604
  variable['import'] = None
605
+ variable['used'] = False
604
606
  self.addCommand(variable)
605
607
  if self.peek() != 'and':
606
608
  break
@@ -711,7 +713,7 @@ class Core(Handler):
711
713
  return self.nextPC()
712
714
 
713
715
  # 1 Load a plugin. This is done at compile time.
714
- # 2 Load text from a file
716
+ # 2 Load text from a file or ssh
715
717
  def k_load(self, command):
716
718
  self.nextToken()
717
719
  if self.tokenIs('plugin'):
@@ -725,7 +727,15 @@ class Core(Handler):
725
727
  if symbolRecord['hasValue']:
726
728
  command['target'] = symbolRecord['name']
727
729
  if self.nextIs('from'):
728
- command['file'] = self.nextValue()
730
+ if self.nextIsSymbol():
731
+ record = self.getSymbolRecord()
732
+ if record['keyword'] == 'ssh':
733
+ command['ssh'] = record['name']
734
+ command['path'] = self.nextValue()
735
+ self.add(command)
736
+ return True
737
+
738
+ command['file'] = self.getValue()
729
739
  self.add(command)
730
740
  return True
731
741
  else:
@@ -734,15 +744,24 @@ class Core(Handler):
734
744
 
735
745
  def r_load(self, command):
736
746
  target = self.getVariable(command['target'])
737
- filename = self.getRuntimeValue(command['file'])
738
- try:
739
- with open(filename) as f: content = f.read()
740
- except:
741
- content = ''
742
- try:
743
- if filename.endswith('.json'): content = json.loads(content)
744
- except:
745
- RuntimeError(self.program, 'Bad or null JSON string')
747
+ if 'ssh' in command:
748
+ ssh = self.getVariable(command['ssh'])
749
+ path = self.getRuntimeValue(command['path'])
750
+ sftp = ssh['sftp']
751
+ try:
752
+ with sftp.open(path, 'r') as remote_file: content = remote_file.read().decode()
753
+ except:
754
+ RuntimeError(self.program, f'Unable to read from {path}')
755
+ else:
756
+ filename = self.getRuntimeValue(command['file'])
757
+ try:
758
+ with open(filename) as f: content = f.read()
759
+ except:
760
+ RuntimeError(self.program, f'Unable to read from {filename}')
761
+ try:
762
+ if filename.endswith('.json'): content = json.loads(content)
763
+ except:
764
+ RuntimeError(self.program, 'Bad or null JSON string')
746
765
  value = {}
747
766
  value['type'] = 'text'
748
767
  value['content'] = content
@@ -1036,10 +1055,10 @@ class Core(Handler):
1036
1055
  program = command['program']
1037
1056
  code = program.code[program.pc]
1038
1057
  lino = str(code['lino'] + 1)
1039
- while len(lino) < 5: lino = f' {lino}'
1058
+ # while len(lino) < 5: lino = f' {lino}'
1040
1059
  if value == None: value = '<empty>'
1041
1060
  if 'log' in command:
1042
- print(f'{datetime.now().time()}:{lino}-> {value}')
1061
+ print(f'{datetime.now().time()}:{self.program.name}:{lino}->{value}')
1043
1062
  else:
1044
1063
  print(value)
1045
1064
  return self.nextPC()
@@ -1203,9 +1222,9 @@ class Core(Handler):
1203
1222
  if record['keyword'] == 'module':
1204
1223
  name = record['name']
1205
1224
  command['module'] = name
1206
- else: RuntimeError(self.program, f'Symbol \'name\' is not a module')
1207
- else: RuntimeError(self.program, 'Module name expected after \'as\'')
1208
- else: RuntimeError(self.program, '\'as {module name}\' expected')
1225
+ else: FatalError(self.compiler, f'Symbol \'name\' is not a module')
1226
+ else: FatalError(self.compiler, 'Module name expected after \'as\'')
1227
+ else: FatalError(self.compiler, '\'as {module name}\' expected')
1209
1228
  exports = []
1210
1229
  if self.peek() == 'with':
1211
1230
  self.nextToken()
@@ -1244,16 +1263,35 @@ class Core(Handler):
1244
1263
  def k_save(self, command):
1245
1264
  command['content'] = self.nextValue()
1246
1265
  if self.nextIs('to'):
1247
- command['file'] = self.nextValue()
1266
+ if self.nextIsSymbol():
1267
+ record = self.getSymbolRecord()
1268
+ if record['keyword'] == 'ssh':
1269
+ command['ssh'] = record['name']
1270
+ command['path'] = self.nextValue()
1271
+ self.add(command)
1272
+ return True
1273
+ command['file'] = self.getValue()
1248
1274
  self.add(command)
1249
1275
  return True
1250
1276
  return False
1251
1277
 
1252
1278
  def r_save(self, command):
1253
1279
  content = self.getRuntimeValue(command['content'])
1254
- filename = self.getRuntimeValue(command['file'])
1255
- if filename.endswith('.json'): content = json.dumps(content)
1256
- with open(filename, 'w') as f: f.write(content)
1280
+ if 'ssh' in command:
1281
+ ssh = self.getVariable(command['ssh'])
1282
+ path = self.getRuntimeValue(command['path'])
1283
+ sftp = ssh['sftp']
1284
+ try:
1285
+ with sftp.open(path, 'w') as remote_file: remote_file.write(content.encode())
1286
+ except:
1287
+ RuntimeError(self.program, 'Unable to write to {path}')
1288
+ else:
1289
+ filename = self.getRuntimeValue(command['file'])
1290
+ if filename.endswith('.json'): content = json.dumps(content)
1291
+ try:
1292
+ with open(filename, 'w') as f: f.write(content)
1293
+ except:
1294
+ RuntimeError(self.program, f'Unable to write to {filename}')
1257
1295
  return self.nextPC()
1258
1296
 
1259
1297
  # Send a message to a module
@@ -1276,16 +1314,40 @@ class Core(Handler):
1276
1314
 
1277
1315
  # Set a value
1278
1316
  # set {variable}
1317
+ # set {ssh} host {host} user {user} password {password}
1279
1318
  # set the elements of {variable} to {value}
1280
1319
  # set element/property of {variable} to {value}
1281
1320
  def k_set(self, command):
1282
1321
  if self.nextIsSymbol():
1283
- target = self.getSymbolRecord()
1284
- if target['hasValue']:
1322
+ record = self.getSymbolRecord()
1323
+ command['target'] = record['name']
1324
+ if record['hasValue']:
1285
1325
  command['type'] = 'set'
1286
- command['target'] = target['name']
1287
1326
  self.add(command)
1288
1327
  return True
1328
+ elif record['keyword'] == 'ssh':
1329
+ host = None
1330
+ user = None
1331
+ password = None
1332
+ while True:
1333
+ token = self.peek()
1334
+ if token == 'host':
1335
+ self.nextToken()
1336
+ host = self.nextValue()
1337
+ elif token == 'user':
1338
+ self.nextToken()
1339
+ user = self.nextValue()
1340
+ elif token == 'password':
1341
+ self.nextToken()
1342
+ password = self.nextValue()
1343
+ else: break
1344
+ command['host'] = host
1345
+ command['user'] = user
1346
+ command['password'] = password
1347
+ command['type'] = 'ssh'
1348
+ self.add(command)
1349
+ return True
1350
+
1289
1351
  return False
1290
1352
 
1291
1353
  token = self.getToken()
@@ -1333,6 +1395,12 @@ class Core(Handler):
1333
1395
  command['value'] = self.nextValue()
1334
1396
  self.add(command)
1335
1397
  return True
1398
+
1399
+ elif token == 'path':
1400
+ command['path'] = self.nextValue()
1401
+ self.add(command)
1402
+ return True
1403
+
1336
1404
  return False
1337
1405
 
1338
1406
  def r_set(self, command):
@@ -1384,6 +1452,11 @@ class Core(Handler):
1384
1452
  self.encoding = self.getRuntimeValue(command['encoding'])
1385
1453
  return self.nextPC()
1386
1454
 
1455
+ elif cmdType == 'path':
1456
+ path = self.getRuntimeValue(command['path'])
1457
+ os.chdir(path)
1458
+ return self.nextPC()
1459
+
1387
1460
  elif cmdType == 'property':
1388
1461
  value = self.getRuntimeValue(command['value'])
1389
1462
  name = self.getRuntimeValue(command['name'])
@@ -1403,6 +1476,17 @@ class Core(Handler):
1403
1476
  val['content'] = content
1404
1477
  self.putSymbolValue(targetVariable, val)
1405
1478
  return self.nextPC()
1479
+
1480
+ elif cmdType == 'ssh':
1481
+ target = self.getVariable(command['target'])
1482
+ host = self.getRuntimeValue(command['host'])
1483
+ user = self.getRuntimeValue(command['user'])
1484
+ password = self.getRuntimeValue(command['password'])
1485
+ ssh = paramiko.SSHClient()
1486
+ ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
1487
+ ssh.connect(host, username=user, password=password)
1488
+ target['sftp'] = ssh.open_sftp()
1489
+ return self.nextPC()
1406
1490
 
1407
1491
  # Shuffle a list
1408
1492
  def k_shuffle(self, command):
@@ -1473,6 +1557,12 @@ class Core(Handler):
1473
1557
 
1474
1558
  return self.nextPC()
1475
1559
 
1560
+ def k_ssh(self, command):
1561
+ return self.compileVariable(command, False)
1562
+
1563
+ def r_ssh(self, command):
1564
+ return self.nextPC()
1565
+
1476
1566
  # Declare a stack variable
1477
1567
  def k_stack(self, command):
1478
1568
  return self.compileVariable(command)
@@ -1624,6 +1714,7 @@ class Core(Handler):
1624
1714
  target['locked'] = False
1625
1715
  return self.nextPC()
1626
1716
 
1717
+ # Use a plugin module
1627
1718
  def k_use(self, command):
1628
1719
  if self.nextIs('graphics'):
1629
1720
  print('Loading graphics module')
easycoder/ec_program.py CHANGED
@@ -317,9 +317,8 @@ class Program:
317
317
  queue = deque()
318
318
  if self.parent != None:
319
319
  self.releaseParent()
320
- else:
321
- self.running = False
322
- break
320
+ self.running = False
321
+ break
323
322
  elif self.pc == None or self.pc == 0 or self.pc >= len(self.code):
324
323
  break
325
324
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: easycoder
3
- Version: 250609.1
3
+ Version: 250611.1
4
4
  Summary: Rapid scripting in English
5
5
  Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
6
6
  Author-email: Graham Trott <gtanyware@gmail.com>
@@ -8,6 +8,7 @@ Description-Content-Type: text/markdown
8
8
  Classifier: License :: OSI Approved :: MIT License
9
9
  Requires-Dist: pytz
10
10
  Requires-Dist: requests
11
+ Requires-Dist: paramiko
11
12
  Requires-Dist: pyside6
12
13
  Project-URL: Home, https://github.com/easycoder/easycoder-py
13
14
 
@@ -0,0 +1,16 @@
1
+ easycoder/README.md,sha256=BVXmYphcTJ6q6RN_9L6HtQukgCnOjSLVIsTM3lk-9aM,587
2
+ easycoder/__init__.py,sha256=YHVXt82vfS0c3zSol9yOtOFFnHuvrKOBwvIGFyf0YsQ,262
3
+ easycoder/ec_classes.py,sha256=L6-6yWHDHw8yF9TGL4WWc4p1aUyXzYz6Gom7jJ43h8o,1823
4
+ easycoder/ec_compiler.py,sha256=zKZXXUrQyHbwZ1gJARnwfdAPHWTARa5SN9Y31iuty8o,5086
5
+ easycoder/ec_condition.py,sha256=YXvSBQKEzKGCcgUGo3Qp8iHolXmm2BpEm0NimSDszIM,785
6
+ easycoder/ec_core.py,sha256=h0yGdqGMKxvF5BGIyVlPHd-FMjrj9kvLAlLIzXsA3L8,96119
7
+ easycoder/ec_handler.py,sha256=zPDZ_hqdgNnkCd8B5HmSLkqsGgf4aDmqcUBOPHgo47U,2305
8
+ easycoder/ec_program.py,sha256=FmC9Oz4IpkmNq6D2TgMzVa3ha2TDv7jA15uwX_HFJVs,10080
9
+ easycoder/ec_pyside.py,sha256=I1y8QZgMHLWWxWbKLm_JzHJo6bwASak7tdnuAcuh66c,39904
10
+ easycoder/ec_timestamp.py,sha256=myQnnF-mT31_1dpQKv2VEAu4BCcbypvMdzq7_DUi1xc,277
11
+ easycoder/ec_value.py,sha256=zgDJTJhIg3yOvmnnKIfccIizmIhGbtvL_ghLTL1T5fg,2516
12
+ easycoder-250611.1.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
13
+ easycoder-250611.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
14
+ easycoder-250611.1.dist-info/WHEEL,sha256=ssQ84EZ5gH1pCOujd3iW7HClo_O_aDaClUbX4B8bjKY,100
15
+ easycoder-250611.1.dist-info/METADATA,sha256=EKv2N_T9PNM8eV1Qkn7ADJx76THgGSwaMJzinGug3oI,6853
16
+ easycoder-250611.1.dist-info/RECORD,,
Binary file
Binary file
@@ -1,18 +0,0 @@
1
- easycoder/.syncthing.ec_core.py.tmp,sha256=-TD3mz9sOGt1WMB7Sm-aA3Z6emzi8k4e04KR6H5beEI,92830
2
- easycoder/.syncthing.ec_program.py.tmp,sha256=0j_gHubyxZ84l8lWiai4Luocsf0fIqHIWOxX0h6wX-M,10080
3
- easycoder/README.md,sha256=BVXmYphcTJ6q6RN_9L6HtQukgCnOjSLVIsTM3lk-9aM,587
4
- easycoder/__init__.py,sha256=AODlCTfDI8YMdlZxd0PMKa2s4qpRIEt55QjeANrIf8c,262
5
- easycoder/ec_classes.py,sha256=L6-6yWHDHw8yF9TGL4WWc4p1aUyXzYz6Gom7jJ43h8o,1823
6
- easycoder/ec_compiler.py,sha256=zKZXXUrQyHbwZ1gJARnwfdAPHWTARa5SN9Y31iuty8o,5086
7
- easycoder/ec_condition.py,sha256=YXvSBQKEzKGCcgUGo3Qp8iHolXmm2BpEm0NimSDszIM,785
8
- easycoder/ec_core.py,sha256=IH7lvxr1ZSFcZvd00RV8wzG_fvWX8bSW4YHKLOL3m04,92443
9
- easycoder/ec_handler.py,sha256=zPDZ_hqdgNnkCd8B5HmSLkqsGgf4aDmqcUBOPHgo47U,2305
10
- easycoder/ec_program.py,sha256=HnJJhd0umQyw8CwUv3wxwG73DFLxciGTry8b3tYG-6w,10094
11
- easycoder/ec_pyside.py,sha256=I1y8QZgMHLWWxWbKLm_JzHJo6bwASak7tdnuAcuh66c,39904
12
- easycoder/ec_timestamp.py,sha256=myQnnF-mT31_1dpQKv2VEAu4BCcbypvMdzq7_DUi1xc,277
13
- easycoder/ec_value.py,sha256=zgDJTJhIg3yOvmnnKIfccIizmIhGbtvL_ghLTL1T5fg,2516
14
- easycoder-250609.1.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
15
- easycoder-250609.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
- easycoder-250609.1.dist-info/WHEEL,sha256=ssQ84EZ5gH1pCOujd3iW7HClo_O_aDaClUbX4B8bjKY,100
17
- easycoder-250609.1.dist-info/METADATA,sha256=k2M5UyNazI3BhOp4LqN7ncu-qwO5R3T8OIUu9RrP0rQ,6829
18
- easycoder-250609.1.dist-info/RECORD,,