easycoder 250609.1__tar.gz → 250609.2__tar.gz

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.

Files changed (166) hide show
  1. {easycoder-250609.1 → easycoder-250609.2}/PKG-INFO +2 -1
  2. {easycoder-250609.1 → easycoder-250609.2}/easycoder/__init__.py +1 -1
  3. {easycoder-250609.1 → easycoder-250609.2}/easycoder/ec_core.py +91 -19
  4. {easycoder-250609.1 → easycoder-250609.2}/easycoder/ec_program.py +2 -3
  5. {easycoder-250609.1 → easycoder-250609.2}/pyproject.toml +1 -0
  6. easycoder-250609.1/easycoder/.syncthing.ec_core.py.tmp +0 -0
  7. easycoder-250609.1/easycoder/.syncthing.ec_program.py.tmp +0 -0
  8. {easycoder-250609.1 → easycoder-250609.2}/.gitignore +0 -0
  9. {easycoder-250609.1 → easycoder-250609.2}/LICENSE +0 -0
  10. {easycoder-250609.1 → easycoder-250609.2}/README.md +0 -0
  11. {easycoder-250609.1 → easycoder-250609.2}/backdrop.jpg +0 -0
  12. {easycoder-250609.1 → easycoder-250609.2}/doc/README.md +0 -0
  13. {easycoder-250609.1 → easycoder-250609.2}/doc/core/README.md +0 -0
  14. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/boolean.md +0 -0
  15. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/empty.md +0 -0
  16. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/ends.md +0 -0
  17. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/even.md +0 -0
  18. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/exists.md +0 -0
  19. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/greater.md +0 -0
  20. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/hasProperty.md +0 -0
  21. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/includes.md +0 -0
  22. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/is.md +0 -0
  23. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/less.md +0 -0
  24. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/list.md +0 -0
  25. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/none.md +0 -0
  26. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/not.md +0 -0
  27. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/numeric.md +0 -0
  28. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/object.md +0 -0
  29. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/odd.md +0 -0
  30. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/starts.md +0 -0
  31. {easycoder-250609.1 → easycoder-250609.2}/doc/core/conditions/string.md +0 -0
  32. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/add.md +0 -0
  33. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/append.md +0 -0
  34. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/assert.md +0 -0
  35. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/begin.md +0 -0
  36. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/clear.md +0 -0
  37. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/close.md +0 -0
  38. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/create.md +0 -0
  39. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/debug.md +0 -0
  40. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/decrement.md +0 -0
  41. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/delete.md +0 -0
  42. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/divide.md +0 -0
  43. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/exit.md +0 -0
  44. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/file.md +0 -0
  45. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/fork.md +0 -0
  46. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/get.md +0 -0
  47. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/go.md +0 -0
  48. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/gosub.md +0 -0
  49. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/if.md +0 -0
  50. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/import.md +0 -0
  51. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/increment.md +0 -0
  52. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/index.md +0 -0
  53. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/init.md +0 -0
  54. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/input.md +0 -0
  55. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/load.md +0 -0
  56. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/lock.md +0 -0
  57. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/log.md +0 -0
  58. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/module.md +0 -0
  59. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/multiply.md +0 -0
  60. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/negate.md +0 -0
  61. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/open.md +0 -0
  62. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/pop.md +0 -0
  63. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/post.md +0 -0
  64. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/print.md +0 -0
  65. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/push.md +0 -0
  66. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/put.md +0 -0
  67. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/read.md +0 -0
  68. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/release.md +0 -0
  69. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/replace.md +0 -0
  70. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/return.md +0 -0
  71. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/run.md +0 -0
  72. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/save.md +0 -0
  73. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/script.md +0 -0
  74. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/set.md +0 -0
  75. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/split.md +0 -0
  76. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/stack.md +0 -0
  77. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/stop.md +0 -0
  78. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/system.md +0 -0
  79. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/take.md +0 -0
  80. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/toggle.md +0 -0
  81. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/truncate.md +0 -0
  82. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/unlock.md +0 -0
  83. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/variable.md +0 -0
  84. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/wait.md +0 -0
  85. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/while.md +0 -0
  86. {easycoder-250609.1 → easycoder-250609.2}/doc/core/keywords/write.md +0 -0
  87. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/arg.md +0 -0
  88. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/args.md +0 -0
  89. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/cos.md +0 -0
  90. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/datime.md +0 -0
  91. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/decode.md +0 -0
  92. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/element.md +0 -0
  93. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/elements.md +0 -0
  94. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/empty.md +0 -0
  95. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/encode.md +0 -0
  96. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/error.md +0 -0
  97. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/files.md +0 -0
  98. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/float.md +0 -0
  99. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/from.md +0 -0
  100. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/hash.md +0 -0
  101. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/index.md +0 -0
  102. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/integer.md +0 -0
  103. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/json.md +0 -0
  104. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/keys.md +0 -0
  105. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/left.md +0 -0
  106. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/length.md +0 -0
  107. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/lowercase.md +0 -0
  108. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/memory.md +0 -0
  109. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/modification.md +0 -0
  110. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/modulo.md +0 -0
  111. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/newline.md +0 -0
  112. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/now.md +0 -0
  113. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/position.md +0 -0
  114. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/property.md +0 -0
  115. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/random.md +0 -0
  116. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/right.md +0 -0
  117. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/sin.md +0 -0
  118. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/stringify.md +0 -0
  119. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/tab.md +0 -0
  120. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/tan.md +0 -0
  121. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/timestamp.md +0 -0
  122. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/today.md +0 -0
  123. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/trim.md +0 -0
  124. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/type.md +0 -0
  125. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/uppercase.md +0 -0
  126. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/value.md +0 -0
  127. {easycoder-250609.1 → easycoder-250609.2}/doc/core/values/weekday.md +0 -0
  128. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/README.md +0 -0
  129. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/attach.md +0 -0
  130. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/close.md +0 -0
  131. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/create.md +0 -0
  132. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/ellipse.md +0 -0
  133. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/image.md +0 -0
  134. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/move.md +0 -0
  135. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/on.md +0 -0
  136. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/rectangle.md +0 -0
  137. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/render.md +0 -0
  138. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/run.md +0 -0
  139. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/set.md +0 -0
  140. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/keywords/text.md +0 -0
  141. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/values/attribute.md +0 -0
  142. {easycoder-250609.1 → easycoder-250609.2}/doc/graphics/values/window.md +0 -0
  143. {easycoder-250609.1 → easycoder-250609.2}/easycoder/README.md +0 -0
  144. {easycoder-250609.1 → easycoder-250609.2}/easycoder/ec_classes.py +0 -0
  145. {easycoder-250609.1 → easycoder-250609.2}/easycoder/ec_compiler.py +0 -0
  146. {easycoder-250609.1 → easycoder-250609.2}/easycoder/ec_condition.py +0 -0
  147. {easycoder-250609.1 → easycoder-250609.2}/easycoder/ec_handler.py +0 -0
  148. {easycoder-250609.1 → easycoder-250609.2}/easycoder/ec_pyside.py +0 -0
  149. {easycoder-250609.1 → easycoder-250609.2}/easycoder/ec_timestamp.py +0 -0
  150. {easycoder-250609.1 → easycoder-250609.2}/easycoder/ec_value.py +0 -0
  151. {easycoder-250609.1 → easycoder-250609.2}/images/Semoigo Dawn.jpg +0 -0
  152. {easycoder-250609.1 → easycoder-250609.2}/json/graphics-demo.json +0 -0
  153. {easycoder-250609.1 → easycoder-250609.2}/plugins/ec_keyboard.py +0 -0
  154. {easycoder-250609.1 → easycoder-250609.2}/plugins/ec_p100.py +0 -0
  155. {easycoder-250609.1 → easycoder-250609.2}/plugins/ec_pyside6.py +0 -0
  156. {easycoder-250609.1 → easycoder-250609.2}/plugins/points.py +0 -0
  157. {easycoder-250609.1 → easycoder-250609.2}/scripts/benchmark.ecs +0 -0
  158. {easycoder-250609.1 → easycoder-250609.2}/scripts/config.ecg +0 -0
  159. {easycoder-250609.1 → easycoder-250609.2}/scripts/ec_keyboard.py +0 -0
  160. {easycoder-250609.1 → easycoder-250609.2}/scripts/findxr.ecs +0 -0
  161. {easycoder-250609.1 → easycoder-250609.2}/scripts/fizzbuzz.ecs +0 -0
  162. {easycoder-250609.1 → easycoder-250609.2}/scripts/hello.ecs +0 -0
  163. {easycoder-250609.1 → easycoder-250609.2}/scripts/points.ecs +0 -0
  164. {easycoder-250609.1 → easycoder-250609.2}/scripts/test.ecs +0 -0
  165. {easycoder-250609.1 → easycoder-250609.2}/scripts/tests.ecs +0 -0
  166. {easycoder-250609.1 → easycoder-250609.2}/testrc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: easycoder
3
- Version: 250609.1
3
+ Version: 250609.2
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
 
@@ -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__ = "250609.2"
@@ -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, 'Unable to read data')
755
+ else:
756
+ filename = self.getRuntimeValue(command['file'])
757
+ try:
758
+ with open(filename) as f: content = f.read()
759
+ except:
760
+ content = ''
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
@@ -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()
@@ -1276,16 +1295,40 @@ class Core(Handler):
1276
1295
 
1277
1296
  # Set a value
1278
1297
  # set {variable}
1298
+ # set {ssh} host {host} user {user} password {password}
1279
1299
  # set the elements of {variable} to {value}
1280
1300
  # set element/property of {variable} to {value}
1281
1301
  def k_set(self, command):
1282
1302
  if self.nextIsSymbol():
1283
- target = self.getSymbolRecord()
1284
- if target['hasValue']:
1303
+ record = self.getSymbolRecord()
1304
+ command['target'] = record['name']
1305
+ if record['hasValue']:
1285
1306
  command['type'] = 'set'
1286
- command['target'] = target['name']
1287
1307
  self.add(command)
1288
1308
  return True
1309
+ elif record['keyword'] == 'ssh':
1310
+ host = None
1311
+ user = None
1312
+ password = None
1313
+ while True:
1314
+ token = self.peek()
1315
+ if token == 'host':
1316
+ self.nextToken()
1317
+ host = self.nextValue()
1318
+ elif token == 'user':
1319
+ self.nextToken()
1320
+ user = self.nextValue()
1321
+ elif token == 'password':
1322
+ self.nextToken()
1323
+ password = self.nextValue()
1324
+ else: break
1325
+ command['host'] = host
1326
+ command['user'] = user
1327
+ command['password'] = password
1328
+ command['type'] = 'ssh'
1329
+ self.add(command)
1330
+ return True
1331
+
1289
1332
  return False
1290
1333
 
1291
1334
  token = self.getToken()
@@ -1333,6 +1376,12 @@ class Core(Handler):
1333
1376
  command['value'] = self.nextValue()
1334
1377
  self.add(command)
1335
1378
  return True
1379
+
1380
+ elif token == 'path':
1381
+ command['path'] = self.nextValue()
1382
+ self.add(command)
1383
+ return True
1384
+
1336
1385
  return False
1337
1386
 
1338
1387
  def r_set(self, command):
@@ -1384,6 +1433,11 @@ class Core(Handler):
1384
1433
  self.encoding = self.getRuntimeValue(command['encoding'])
1385
1434
  return self.nextPC()
1386
1435
 
1436
+ elif cmdType == 'path':
1437
+ path = self.getRuntimeValue(command['path'])
1438
+ os.chdir(path)
1439
+ return self.nextPC()
1440
+
1387
1441
  elif cmdType == 'property':
1388
1442
  value = self.getRuntimeValue(command['value'])
1389
1443
  name = self.getRuntimeValue(command['name'])
@@ -1403,6 +1457,17 @@ class Core(Handler):
1403
1457
  val['content'] = content
1404
1458
  self.putSymbolValue(targetVariable, val)
1405
1459
  return self.nextPC()
1460
+
1461
+ elif cmdType == 'ssh':
1462
+ target = self.getVariable(command['target'])
1463
+ host = self.getRuntimeValue(command['host'])
1464
+ user = self.getRuntimeValue(command['user'])
1465
+ password = self.getRuntimeValue(command['password'])
1466
+ ssh = paramiko.SSHClient()
1467
+ ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
1468
+ ssh.connect(host, username=user, password=password)
1469
+ target['sftp'] = ssh.open_sftp()
1470
+ return self.nextPC()
1406
1471
 
1407
1472
  # Shuffle a list
1408
1473
  def k_shuffle(self, command):
@@ -1473,6 +1538,12 @@ class Core(Handler):
1473
1538
 
1474
1539
  return self.nextPC()
1475
1540
 
1541
+ def k_ssh(self, command):
1542
+ return self.compileVariable(command, False)
1543
+
1544
+ def r_ssh(self, command):
1545
+ return self.nextPC()
1546
+
1476
1547
  # Declare a stack variable
1477
1548
  def k_stack(self, command):
1478
1549
  return self.compileVariable(command)
@@ -1624,6 +1695,7 @@ class Core(Handler):
1624
1695
  target['locked'] = False
1625
1696
  return self.nextPC()
1626
1697
 
1698
+ # Use a plugin module
1627
1699
  def k_use(self, command):
1628
1700
  if self.nextIs('graphics'):
1629
1701
  print('Loading graphics module')
@@ -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
 
@@ -14,6 +14,7 @@ dynamic = ["version"]
14
14
  dependencies = [
15
15
  "pytz",
16
16
  "requests",
17
+ "paramiko",
17
18
  "pyside6"
18
19
  ]
19
20
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes