summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Pierre Ledure <jp@ledure.be>2021-03-09 11:37:07 +0100
committerJean-Pierre Ledure <jp@ledure.be>2021-03-09 15:36:32 +0100
commit055ba7014587b09e0a3166f0cc8d61db0b358a1c (patch)
treedb836ffe687d5631bd230168432dff2c828aee3b
parente3f62ee770afe34dceb467eb8ccda55eba0a2243 (diff)
ScriptForge - (scriptforge.py) FileSystem and TextStream classes
Addition of SF_FileSystem and SF_TextStream classes Machinery tuning: - freeze a predefined list of standard modules in the python persistent storage - error management reviewed to mimic Basic behaviour on wrong arguments Standard modules are predefined in scriptforge.py as well Both lists must be synchronized on a hardcoded entry number Basic has minor revisions: - complex boolean expressions return -1 and 0 to Python i.o. True and False => Add a CBool() function - [User]TemplatesFolder properties of FileSystem omitted the final "/" Change-Id: Ice138de956f5f87269557cdb3db023849081b99d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112199 Tested-by: Jean-Pierre Ledure <jp@ledure.be> Tested-by: Jenkins Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
-rw-r--r--wizards/source/scriptforge/SF_FileSystem.xba6
-rw-r--r--wizards/source/scriptforge/SF_PythonHelper.xba33
-rw-r--r--wizards/source/scriptforge/SF_Root.xba31
-rw-r--r--wizards/source/scriptforge/SF_TextStream.xba4
-rw-r--r--wizards/source/scriptforge/python/scriptforge.py195
5 files changed, 236 insertions, 33 deletions
diff --git a/wizards/source/scriptforge/SF_FileSystem.xba b/wizards/source/scriptforge/SF_FileSystem.xba
index f626eba6fd92..11ec24c67a61 100644
--- a/wizards/source/scriptforge/SF_FileSystem.xba
+++ b/wizards/source/scriptforge/SF_FileSystem.xba
@@ -188,7 +188,7 @@ Const cstThisSub = &quot;FileSystem.getTemplatesFolder&quot;
SF_Utils._EnterFunction(cstThisSub)
sPath = SF_Utils._GetUNOService(&quot;PathSettings&quot;).Template
- TemplatesFolder = SF_FileSystem._ConvertFromUrl(Split(sPath, &quot;;&quot;)(0))
+ TemplatesFolder = SF_FileSystem._ConvertFromUrl(Split(sPath, &quot;;&quot;)(0) &amp; &quot;/&quot;)
SF_Utils._ExitFunction(cstThisSub)
End Property &apos; ScriptForge.SF_FileSystem.TemplatesFolder
@@ -214,7 +214,7 @@ Const cstThisSub = &quot;FileSystem.getUserTemplatesFolder&quot;
SF_Utils._EnterFunction(cstThisSub)
sPath = SF_Utils._GetUNOService(&quot;PathSettings&quot;).Template_writable
- UserTemplatesFolder = SF_FileSystem._ConvertFromUrl(sPath)
+ UserTemplatesFolder = SF_FileSystem._ConvertFromUrl(sPath &amp; &quot;/&quot;)
SF_Utils._ExitFunction(cstThisSub)
End Property &apos; ScriptForge.SF_FileSystem.UserTemplatesFolder
@@ -934,7 +934,7 @@ CatchNotExists:
End Function &apos; ScriptForge.SF_FileSystem.GetFileLen
REM -----------------------------------------------------------------------------
-Public Function GetFileModified(Optional ByVal FileName As Variant) As Date
+Public Function GetFileModified(Optional ByVal FileName As Variant) As Variant
&apos;&apos;&apos; Returns the last modified date for the given file
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FileName: a string representing an existing file
diff --git a/wizards/source/scriptforge/SF_PythonHelper.xba b/wizards/source/scriptforge/SF_PythonHelper.xba
index b90454dcd88d..c54d799ae282 100644
--- a/wizards/source/scriptforge/SF_PythonHelper.xba
+++ b/wizards/source/scriptforge/SF_PythonHelper.xba
@@ -557,6 +557,7 @@ Const cstNoArgs = &quot;+++NOARGS+++&quot;, cstSymEmpty = &quot;+++EMPTY+++&quot
&apos; Determines the CallType
Const vbGet = 2, vbLet = 4, vbMethod = 1, vbSet = 8
&apos; Protocol flags
+Const cstDateRet = 128 &apos; Return value can be a date
Const cstArgArray = 512 &apos; 1st argument can be a 2D array
Const cstRetArray = 1024 &apos; Return value can be an array
Const cstUno = 256 &apos; Return value can be a UNO object
@@ -580,7 +581,8 @@ Check:
If vArg = cstNoArgs Then Exit For
End If
If VarType(vArg) = V_STRING Then
- If vArg = cstSymEmpty Then
+ If Len(vArg) = 0 Then
+ ElseIf vArg = cstSymEmpty Then
vArg = Empty
ElseIf vArg = cstSymNull Then
vArg = Null
@@ -613,6 +615,11 @@ Try:
&apos; may be considered as properties when no argument
&apos; Requires Python and Basic update in the concerned library but is transparent for this dispatcher
+ &apos; Initialize Python persistent storage at 1st call
+ If IsEmpty(_SF_.PythonStorage) Then _SF_._InitPythonStorage()
+ &apos; Reset any error
+ _SF_._Stackreset()
+
Select case VarType(BasicObject)
Case V_STRING
&apos; Special entry for CreateScriptService()
@@ -644,9 +651,18 @@ Try:
bBasicClass = ( Left(sObjectType, 3) &lt;&gt; &quot;SF_&quot; )
sLibrary = Split(vBasicObject.ServiceName, &quot;.&quot;)(0)
+ &apos; Methods in standard modules returning a date are hardcoded as exceptions
+ If Not bBasicClass And ((CallType And vbMethod) = vbMethod) And ((CallType And cstDateRet) = cstDateRet) Then
+ Select Case sLibrary
+ Case &quot;ScriptForge&quot;
+ If sObjectType = &quot;SF_FileSystem&quot; And Script = &quot;GetFileModified&quot; Then vReturn = SF_FileSystem.GetFileModified(vArgs(0))
+ End Select
+
&apos; Methods in usual modules are called by ExecuteBasicScript() except if they use a ParamArray
- If Not bBasicClass And (CallType And vbMethod) = vbMethod Then
+ ElseIf Not bBasicClass And (CallType And vbMethod) = vbMethod Then
sScript = sLibrary &amp; &quot;.&quot; &amp; sObjectType &amp; &quot;.&quot; &amp; Script
+ &apos; Force validation in targeted function, not in ExecuteBasicScript()
+ _SF_.StackLevel = -1
Select Case UBound(vArgs)
Case -1 : vReturn = sess.ExecuteBasicScript(, sScript)
Case 0 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0))
@@ -658,6 +674,7 @@ Try:
Case 6 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6))
Case 7 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7))
End Select
+ _SF_.StackLevel = 0
&apos; Properties in any service are got and set with obj.GetProperty/SetProperty(...)
ElseIf (CallType And vbGet) = vbGet Then
@@ -677,8 +694,6 @@ Try:
ElseIf bBasicClass And ((CallType And vbMethod) = vbMethod) Then
Select Case UBound(vArgs)
Case -1 : vReturn = CallByName(vBasicObject, Script, vbMethod)
- &apos; Special case: Dispose() must update the cache for class objects created in Python scripts
- If Script = &quot;Dispose&quot; Then Set _SF_.PythonStorage(BasicObject) = Nothing
Case 0 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0))
Case 1 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1))
Case 2 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2))
@@ -689,6 +704,12 @@ Try:
Case 7 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7))
End Select
End If
+
+ &apos; Post processing
+ If Script = &quot;Dispose&quot; Then
+ &apos; Special case: Dispose() must update the cache for class objects created in Python scripts
+ Set _SF_.PythonStorage(BasicObject) = Nothing
+ End If
Case Else
End Select
@@ -725,7 +746,7 @@ Try:
End If
Else &apos; Scalar or Nothing
ReDim vReturnArray(0 To 1)
- vReturnArray(0) = vReturn
+ If VarType(vReturn) = V_DATE Then vReturnArray(0) = SF_Utils._CDateToIso(vReturn) Else vReturnArray(0) = vReturn
vReturnArray(1) = VarType(vReturn)
End If
@@ -749,4 +770,4 @@ Private Function _Repr() As String
End Function &apos; ScriptForge.SF_PythonHelper._Repr
REM ================================================= END OF SCRIPTFORGE.SF_PythonHelper
-</script:module>
+</script:module> \ No newline at end of file
diff --git a/wizards/source/scriptforge/SF_Root.xba b/wizards/source/scriptforge/SF_Root.xba
index 379cb3586a2b..fcbba9039596 100644
--- a/wizards/source/scriptforge/SF_Root.xba
+++ b/wizards/source/scriptforge/SF_Root.xba
@@ -74,6 +74,7 @@ Private OSName As String &apos; WIN, LINUX, MACOS
Private SFDialogs As Variant &apos; Persistent storage for the SFDialogs library
Private SFForms As Variant &apos; Persistent storage for the SF_Form class in the SFDocuments library
Private PythonStorage As Variant &apos; Persistent storage for the objects created and processed in Python
+Private PythonPermanent As Long &apos; Number of permanent entries in PythonStorage containing standard module objects
REM ====================================================== CONSTRUCTOR/DESTRUCTOR
@@ -122,6 +123,7 @@ Private Sub Class_Initialize()
SFDialogs = Empty
SFForms = Empty
PythonStorage = Empty
+ PythonPermanent = -1
End Sub &apos; ScriptForge.SF_Root Constructor
REM -----------------------------------------------------------------------------
@@ -186,12 +188,11 @@ Check:
lIndex = -1
If IsNull(poObject) Then Exit Function
On Local Error GoTo Finally
- If IsEmpty(PythonStorage) Then PythonStorage = Array()
lSize = UBound(PythonStorage)
Try:
&apos; Can an empty entry be reused ?
- For i = 0 To lSize
+ For i = PythonPermanent + 1 To lSize
If IsNull(PythonStorage(i)) Then
lIndex = i
Exit For
@@ -214,6 +215,32 @@ Finally:
End Function &apos; ScriptForge.SF_Root._AddToPythonStorage
REM -----------------------------------------------------------------------------
+Public Sub _InitPythonStorage()
+&apos;&apos;&apos; Make PythonStorage an array
+&apos;&apos;&apos; In prevision to an abundant use of those objects in Python, hardcode to optimize the performance and memory :
+&apos;&apos;&apos; Initialize the first entries with the standard module objects located in the ScriptForge library
+
+Try:
+ If Not IsArray(PythonStorage) Then
+ PythonPermanent = 7
+ PythonStorage = Array()
+ ReDim PythonStorage(0 To PythonPermanent)
+ &apos; Initialize each entry
+ PythonStorage(0) = ScriptForge.SF_Array
+ PythonStorage(1) = ScriptForge.SF_Exception
+ PythonStorage(2) = ScriptForge.SF_FileSystem
+ PythonStorage(3) = ScriptForge.SF_Platform
+ PythonStorage(4) = ScriptForge.SF_Services
+ PythonStorage(5) = ScriptForge.SF_Session
+ PythonStorage(6) = ScriptForge.SF_String
+ PythonStorage(7) = ScriptForge.SF_UI
+ End If
+
+Finally:
+ Exit Sub
+End Sub &apos; ScriptForge.SF_Root._InitPythonStorage
+
+REM -----------------------------------------------------------------------------
Public Sub _LoadLocalizedInterface(Optional ByVal psMode As String)
&apos;&apos;&apos; Build the user interface in a persistent L10N object
&apos;&apos;&apos; Executed - only once - at first ScriptForge invocation by a user script
diff --git a/wizards/source/scriptforge/SF_TextStream.xba b/wizards/source/scriptforge/SF_TextStream.xba
index bb8ea78486f6..27ff3d9bb4c9 100644
--- a/wizards/source/scriptforge/SF_TextStream.xba
+++ b/wizards/source/scriptforge/SF_TextStream.xba
@@ -499,7 +499,7 @@ Public Sub WriteBlankLines(Optional ByVal Lines As Variant)
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; FILENOTOPENERROR File not open or already closed
-&apos;&apos;&apos; FILEOPENMODEERROR File opened in in read mode
+&apos;&apos;&apos; FILEOPENMODEERROR File opened in read mode
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; myFile.WriteBlankLines(10)
Dim i As Long
@@ -657,7 +657,7 @@ Dim cstSubArgs As String
Case UCase(&quot;AtEndOfStream&quot;)
Select Case _IOMode
Case SF_FileSystem.ForReading
- If IsNull(_InputStream) Then _PropertyGet = True Else _PropertyGet = _InputStream.isEOF() And Not _ForceBlankLine
+ If IsNull(_InputStream) Then _PropertyGet = True Else _PropertyGet = CBool(_InputStream.isEOF() And Not _ForceBlankLine)
Case Else : _PropertyGet = True
End Select
Case UCase(&quot;Encoding&quot;)
diff --git a/wizards/source/scriptforge/python/scriptforge.py b/wizards/source/scriptforge/python/scriptforge.py
index fd1b3e0df957..a131329308bb 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -56,7 +56,6 @@
import uno
-from platform import system as _opsys
import datetime
import os
@@ -106,6 +105,8 @@ class ScriptForge(object, metaclass = _Singleton):
#
# Basic dispatcher for Python scripts
basicdispatcher = 'ScriptForge.SF_PythonHelper._PythonDispatcher'
+ # Python helper functions module
+ pythonhelpermodule = 'ScriptForgeHelper.py'
#
# VarType() constants
V_EMPTY, V_NULL, V_INTEGER, V_LONG, V_SINGLE, V_DOUBLE = 0, 1, 2, 3, 4, 5
@@ -115,6 +116,15 @@ class ScriptForge(object, metaclass = _Singleton):
objMODULE, objCLASS, objUNO = 1, 2, 3
# Special argument symbols
cstSymEmpty, cstSymNull, cstSymMissing = '+++EMPTY+++', '+++NULL+++', '+++MISSING+++'
+ # Predefined references for services implemented as standard Basic modules
+ servicesmodules = dict([('ScriptForge.Array', 0),
+ ('ScriptForge.Exception', 1),
+ ('ScriptForge.FileSystem', 2),
+ ('ScriptForge.Platform', 3),
+ ('ScriptForge.Services', 4),
+ ('ScriptForge.Session', 5),
+ ('ScriptForge.String', 6),
+ ('ScriptForge.UI', 7)])
def __init__(self, hostname = '', port = 0):
"""
@@ -266,17 +276,19 @@ class ScriptForge(object, metaclass = _Singleton):
if returntuple[cstClass] == ScriptForge.objUNO:
pass
else:
- # Create the new class instance of the right subclass of Service()
+ # Create the new class instance of the right subclass of SFServices()
servname = returntuple[cstService]
- for subcls in SFServices.__subclasses__():
- if servname == subcls.servicename:
- return subcls(returntuple[cstValue], returntuple[cstType], returntuple[cstClass],
- returntuple[cstName])
+ subcls = cls.serviceslist[servname]
+ if subcls is not None:
+ return subcls(returntuple[cstValue], returntuple[cstType], returntuple[cstClass],
+ returntuple[cstName])
# When service not found
raise RuntimeError("The service '" + servname + "' is not available in Python. Execution stops.")
elif returntuple[cstVarType] >= ScriptForge.V_ARRAY:
pass
- else: # All scalar values
+ elif returntuple[cstVarType] == ScriptForge.V_DATE:
+ return datetime.datetime.fromisoformat(returntuple[cstValue])
+ else: # All other scalar values
pass
return returntuple[cstValue]
@@ -340,6 +352,7 @@ class SFServices(object):
"""
# Python-Basic protocol constants and flags
vbGet, vbLet, vbMethod, vbSet = 2, 4, 1, 8 # CallByName constants
+ flgDateRet = 128 # Invoked service method can return a date
flgArrayArg = 512 # 1st argument can be a 2D array
flgArrayRet = 1024 # Invoked service method can return an array
flgUno = 256 # Invoked service method/property can return a UNO object
@@ -409,7 +422,7 @@ class SFServices(object):
def Dispose(self):
if self.serviceimplementation == 'basic':
- if self.classmodule == self.moduleClass and self.objectreference >= 0:
+ if self.objectreference >= 0:
self.Execute(self.vbMethod, 'Dispose')
self.objectreference = -1
@@ -425,6 +438,9 @@ class SFServices(object):
"""
return self.EXEC(self.objectreference, self.vbGet, propertyname)
+ def Properties(self):
+ return list(self.serviceProperties)
+
def SetProperty(self, propertyname, value):
"""
Set the given property to a new value in the Basic world
@@ -442,7 +458,7 @@ class SFScriptForge:
class SF_Basic(SFServices, metaclass = _Singleton):
"""
This service proposes a collection of Basic methods to be executed in a Python context
- to simulate the exact syntax and behaviour of the identical Basic builtin method.
+ simulating the exact syntax and behaviour of the identical Basic builtin method.
Typical example:
SF_Basic.MsgBox('This has to be displayed in a message box')
"""
@@ -495,6 +511,10 @@ class SFScriptForge:
value = value.isoformat()
return self.SIMPLEEXEC(self.module + '.PyFormat', value, pattern)
+ @staticmethod
+ def GetDefaultContext():
+ return ScriptForge.componentcontext
+
def GetGuiType(self):
return self.SIMPLEEXEC(self.module + '.PyGetGuiType')
@@ -502,21 +522,17 @@ class SFScriptForge:
return self.SIMPLEEXEC(self.module + '.PyGetSystemTicks')
@staticmethod
- def GetDefaultContext():
- return ScriptForge.componentcontext
-
- @staticmethod
def GetPathSeparator():
return os.sep
class GlobalScope(object, metaclass = _Singleton):
@classmethod # Mandatory because the GlobalScope class is normally not instantiated
def BasicLibraries(cls):
- return SFScriptForge.SF_Basic().SIMPLEEXEC(SFScriptForge.SF_Basic.module + '.PyGlobalScope', 'Basic')
+ return ScriptForge.InvokeSimpleScript(SFScriptForge.SF_Basic.module + '.PyGlobalScope', 'Basic')
@classmethod
def DialogLibraries(cls):
- return SFScriptForge.SF_Basic().SIMPLEEXEC(SFScriptForge.SF_Basic.module + '.PyGlobalScope', 'Dialog')
+ return ScriptForge.InvokeSimpleScript(SFScriptForge.SF_Basic.module + '.PyGlobalScope', 'Dialog')
def InputBox(self, msg, title = '', default = '', xpos = -1, ypos = -1):
if xpos < 0 or ypos < 0:
@@ -563,6 +579,8 @@ class SFScriptForge:
serviceProperties = dict(FileNaming = True, ConfigFolder = False, ExtensionsFolder = False, HomeFolder = False,
InstallFolder = False, TemplatesFolder = False, TemporaryFolder = False,
UserTemplatesFolder = False)
+ # Open TextStream constants
+ ForReading, ForWriting, ForAppending = 1, 2, 8
@property
def ConfigFolder(self):
@@ -571,9 +589,139 @@ class SFScriptForge:
def BuildPath(self, foldername, name):
return self.Execute(self.vbMethod, 'BuildPath', foldername, name)
+ def CompareFiles(self, filename1, filename2, comparecontents = False):
+ py = ScriptForge.pythonhelpermodule + '$' + '_SF_FileSystem__CompareFiles'
+ if self.FileExists(filename1) and self.FileExists(filename2):
+ file1 = self._ConvertFromUrl(filename1)
+ file2 = self._ConvertFromUrl(filename2)
+ return self.SIMPLEEXEC(py, file1, file2, comparecontents)
+ else:
+ return False
+
+ def CopyFile(self, source, destination, overwrite = True):
+ return self.Execute(self.vbMethod, 'CopyFile', source, destination, overwrite)
+
+ def CopyFolder(self, source, destination, overwrite = True):
+ return self.Execute(self.vbMethod, 'CopyFolder', source, destination, overwrite)
+
+ def CreateFolder(self, foldername):
+ return self.Execute(self.vbMethod, 'CreateFolder', foldername)
+
+ def CreateTextFile(self, filename, overwrite = True, encoding = 'UTF-8'):
+ return self.Execute(self.vbMethod, 'CreateTextFile', filename, overwrite, encoding)
+
+ def DeleteFile(self, filename):
+ return self.Execute(self.vbMethod, 'DeleteFile', filename)
+
+ def DeleteFolder(self, foldername):
+ return self.Execute(self.vbMethod, 'DeleteFolder', foldername)
+
+ def FileExists(self, filename):
+ return self.Execute(self.vbMethod, 'FileExists', filename)
+
+ def Files(self, foldername, filter = ''):
+ return self.Execute(self.vbMethod + self.flgArrayRet, 'Files', foldername, filter)
+
def FolderExists(self, foldername):
return self.Execute(self.vbMethod, 'FolderExists', foldername)
+ def GetBaseName(self, filename):
+ return self.Execute(self.vbMethod, 'GetBaseName', filename)
+
+ def GetExtension(self, filename):
+ return self.Execute(self.vbMethod, 'GetExtension', filename)
+
+ def GetFileLen(self, filename):
+ py = ScriptForge.pythonhelpermodule + '$' + '_SF_FileSystem__GetFilelen'
+ if self.FileExists(filename):
+ file = self._ConvertFromUrl(filename)
+ return int(self.SIMPLEEXEC(py, file))
+ else:
+ return 0
+
+ def GetFileModified(self, filename):
+ return self.Execute(self.vbMethod + self.flgDateRet, 'GetFileModified', filename)
+
+ def GetName(self, filename):
+ return self.Execute(self.vbMethod, 'GetName', filename)
+
+ def GetParentFolderName(self, filename):
+ return self.Execute(self.vbMethod, 'GetParentFolderName', filename)
+
+ def GetTempName(self):
+ return self.Execute(self.vbMethod, 'GetTempName')
+
+ def HashFile(self, filename, algorithm):
+ py = ScriptForge.pythonhelpermodule + '$' + '_SF_FileSystem__HashFile'
+ if self.FileExists(filename):
+ file = self._ConvertFromUrl(filename)
+ return self.SIMPLEEXEC(py, file, algorithm.lower())
+ else:
+ return ''
+
+ def MoveFile(self, source, destination):
+ return self.Execute(self.vbMethod, 'MoveFile', source, destination)
+
+ def MoveFolder(self, source, destination):
+ return self.Execute(self.vbMethod, 'MoveFolder', source, destination)
+
+ def OpenTextFile(self, filename, iomode = 1, create = False, encoding = 'UTF-8'):
+ return self.Execute(self.vbMethod, 'OpenTextFile', filename, iomode, create, encoding)
+
+ def PickFile(self, defaultfile = ScriptForge.cstSymEmpty, mode = 'OPEN', filter = ''):
+ return self.Execute(self.vbMethod, 'PickFile', defaultfile, mode, filter)
+
+ def PickFolder(self, defaultfolder = ScriptForge.cstSymEmpty, freetext = ''):
+ return self.Execute(self.vbMethod, 'PickFolder', defaultfolder, freetext)
+
+ def SubFolders(self, foldername, filter = ''):
+ return self.Execute(self.vbMethod + self.flgArrayRet, 'SubFolders', foldername, filter)
+
+ def _ConvertFromUrl(self, filename):
+ # Alias for same function in FileSystem Basic module
+ return self.SIMPLEEXEC('ScriptForge.SF_FileSystem._ConvertFromUrl', filename)
+
+ # #########################################################################
+ # SF_TextStream CLASS
+ # #########################################################################
+ class SF_TextStream(SFServices):
+ """
+ The TextStream service is used to sequentially read from and write to files opened or created
+ using the ScriptForge.FileSystem service..
+ """
+ # Mandatory class properties for service registration
+ serviceimplementation = 'basic'
+ servicename = 'ScriptForge.TextStream'
+ serviceProperties = dict(AtEndOfStream = False, Encoding = False, FileName = False,
+ IOMode = False, Line = False, NewLine = True)
+
+ @property
+ def AtEndOfStream(self):
+ return self.GetProperty('AtEndOfStream')
+
+ @property
+ def Line(self):
+ return self.GetProperty('Line')
+
+ def CloseFile(self):
+ return self.Execute(self.vbMethod, 'CloseFile')
+
+ def ReadAll(self):
+ return self.Execute(self.vbMethod, 'ReadAll')
+
+ def ReadLine(self):
+ return self.Execute(self.vbMethod, 'ReadLine')
+
+ def SkipLine(self):
+ return self.Execute(self.vbMethod, 'SkipLine')
+
+ def WriteBlankLines(self, lines):
+ return self.Execute(self.vbMethod, 'WriteBlankLines', lines)
+
+ def WriteLine(self, line):
+ return self.Execute(self.vbMethod, 'WriteLine', line)
+
+
# #########################################################################
# SF_Timer CLASS
# #########################################################################
@@ -640,21 +788,27 @@ def CreateScriptService(service, *args):
def ResolveSynonyms(servicename):
"""
- Synonyms within service names implemented in Python are resolved here
+ Synonyms within service names implemented in Python or predefined are resolved here
:param servicename: The short name of the service
:return: The official service name
"""
if servicename.lower() in ('basic', 'scriptforge.basic'):
return 'ScriptForge.Basic'
+ if servicename.lower() in ('filesystem', 'scriptforge.filesystem'):
+ return 'ScriptForge.FileSystem'
return servicename
#
- # Check the list of available services to examine if the requested service is within the Python world
+ # Check the list of available services
scriptservice = ResolveSynonyms(service)
if scriptservice in ScriptForge.serviceslist:
serv = ScriptForge.serviceslist[scriptservice]
+ # Check if the requested service is within the Python world
if serv.serviceimplementation == 'python':
return serv()
+ # Check if the service is a predefined standard Basic service
+ elif scriptservice in ScriptForge.servicesmodules:
+ return serv(ScriptForge.servicesmodules[scriptservice], classmodule = SFServices.moduleStandard)
# The requested service is to be found in the Basic world
if len(args) == 0:
serv = ScriptForge.InvokeBasicService('SF_Services', SFServices.vbMethod, 'CreateScriptService', service)
@@ -662,15 +816,16 @@ def CreateScriptService(service, *args):
serv = ScriptForge.InvokeBasicService('SF_Services', SFServices.vbMethod, 'CreateScriptService', service, *args)
return serv
+
# #####################################################################################################################
# Services shortcuts ###
# #####################################################################################################################
-# SF_Basic = CreateScriptService('SFPython.Basic')
-# SF_String = _ScriptForge.SF_String
+SF_Basic = SFScriptForge.SF_Basic()
+# SF_String = None
# ######################################################################
-# lists the scripts, that shall be visible inside the Basic/Python IDE
+# Lists the scripts, that shall be visible inside the Basic/Python IDE
# ######################################################################
g_exportedScripts = ()