VIStk 0.3.6__tar.gz → 0.3.8__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 VIStk might be problematic. Click here for more details.

Files changed (57) hide show
  1. vistk-0.3.8/.vscode/c_cpp_properties.json +18 -0
  2. vistk-0.3.8/.vscode/launch.json +24 -0
  3. vistk-0.3.8/.vscode/settings.json +59 -0
  4. {vistk-0.3.6/VIStk.egg-info → vistk-0.3.8}/PKG-INFO +1 -1
  5. vistk-0.3.8/VIS/Form.zip +0 -0
  6. {vistk-0.3.6 → vistk-0.3.8}/VIS/Templates/screen.txt +0 -2
  7. {vistk-0.3.6 → vistk-0.3.8}/VIS/Templates/spec.txt +2 -2
  8. vistk-0.3.8/VIS/Templates/version.txt +30 -0
  9. vistk-0.3.8/VIS/VIS.py +53 -0
  10. vistk-0.3.8/VIS/project.py +362 -0
  11. vistk-0.3.8/VIS/release.py +158 -0
  12. {vistk-0.3.6 → vistk-0.3.8/VIStk.egg-info}/PKG-INFO +1 -1
  13. {vistk-0.3.6 → vistk-0.3.8}/VIStk.egg-info/SOURCES.txt +4 -4
  14. {vistk-0.3.6 → vistk-0.3.8}/changelog.md +27 -1
  15. vistk-0.3.8/documentation.md +67 -0
  16. vistk-0.3.8/knownissues.md +27 -0
  17. {vistk-0.3.6 → vistk-0.3.8}/pyproject.toml +1 -1
  18. vistk-0.3.6/VIS/Form.zip +0 -0
  19. vistk-0.3.6/VIS/VIS.py +0 -96
  20. vistk-0.3.6/VIS/elements.py +0 -27
  21. vistk-0.3.6/VIS/patch.py +0 -11
  22. vistk-0.3.6/VIS/project.py +0 -16
  23. vistk-0.3.6/VIS/release.py +0 -107
  24. vistk-0.3.6/VIS/screen.py +0 -15
  25. vistk-0.3.6/VIS/stitch.py +0 -37
  26. vistk-0.3.6/documentation.md +0 -3
  27. vistk-0.3.6/knownissues.md +0 -11
  28. {vistk-0.3.6 → vistk-0.3.8}/.github/workflows/publish.yml +0 -0
  29. {vistk-0.3.6 → vistk-0.3.8}/.gitignore +0 -0
  30. {vistk-0.3.6 → vistk-0.3.8}/Form/Icons/VIS.ico +0 -0
  31. {vistk-0.3.6 → vistk-0.3.8}/Form/README.txt +0 -0
  32. {vistk-0.3.6 → vistk-0.3.8}/Form/Screens/__init__.py +0 -0
  33. {vistk-0.3.6 → vistk-0.3.8}/Form/Screens/root.py +0 -0
  34. {vistk-0.3.6 → vistk-0.3.8}/Form/Screens/styles.py +0 -0
  35. {vistk-0.3.6 → vistk-0.3.8}/Form/modules/__init__.py +0 -0
  36. {vistk-0.3.6 → vistk-0.3.8}/LICENSE +0 -0
  37. {vistk-0.3.6 → vistk-0.3.8}/README.md +0 -0
  38. {vistk-0.3.6 → vistk-0.3.8}/Untitled.xcf +0 -0
  39. {vistk-0.3.6 → vistk-0.3.8}/VIS/Templates/collect.txt +0 -0
  40. {vistk-0.3.6 → vistk-0.3.8}/VIS/Templates/f_element.txt +0 -0
  41. {vistk-0.3.6 → vistk-0.3.8}/VIS/__init__.py +0 -0
  42. {vistk-0.3.6 → vistk-0.3.8}/VIS/__pycache__/__init__.cpython-313.pyc +0 -0
  43. {vistk-0.3.6 → vistk-0.3.8}/VIS/menu.py +0 -0
  44. {vistk-0.3.6 → vistk-0.3.8}/VIStk.egg-info/dependency_links.txt +0 -0
  45. {vistk-0.3.6 → vistk-0.3.8}/VIStk.egg-info/entry_points.txt +0 -0
  46. {vistk-0.3.6 → vistk-0.3.8}/VIStk.egg-info/requires.txt +0 -0
  47. {vistk-0.3.6 → vistk-0.3.8}/VIStk.egg-info/top_level.txt +0 -0
  48. {vistk-0.3.6 → vistk-0.3.8}/__pycache__/VIS.cpython-313.pyc +0 -0
  49. {vistk-0.3.6 → vistk-0.3.8}/__pycache__/__init__.cpython-313.pyc +0 -0
  50. {vistk-0.3.6 → vistk-0.3.8}/__pycache__/cleanup.cpython-313.pyc +0 -0
  51. {vistk-0.3.6 → vistk-0.3.8}/__pycache__/elements.cpython-313.pyc +0 -0
  52. {vistk-0.3.6 → vistk-0.3.8}/__pycache__/menu.cpython-313.pyc +0 -0
  53. {vistk-0.3.6 → vistk-0.3.8}/__pycache__/patch.cpython-313.pyc +0 -0
  54. {vistk-0.3.6 → vistk-0.3.8}/__pycache__/project.cpython-313.pyc +0 -0
  55. {vistk-0.3.6 → vistk-0.3.8}/__pycache__/screen.cpython-313.pyc +0 -0
  56. {vistk-0.3.6 → vistk-0.3.8}/__pycache__/stitch.cpython-313.pyc +0 -0
  57. {vistk-0.3.6 → vistk-0.3.8}/setup.cfg +0 -0
@@ -0,0 +1,18 @@
1
+ {
2
+ "configurations": [
3
+ {
4
+ "name": "windows-gcc-x64",
5
+ "includePath": [
6
+ "${workspaceFolder}/**"
7
+ ],
8
+ "compilerPath": "gcc",
9
+ "cStandard": "${default}",
10
+ "cppStandard": "${default}",
11
+ "intelliSenseMode": "windows-gcc-x64",
12
+ "compilerArgs": [
13
+ ""
14
+ ]
15
+ }
16
+ ],
17
+ "version": 4
18
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "C/C++ Runner: Debug Session",
6
+ "type": "cppdbg",
7
+ "request": "launch",
8
+ "args": [],
9
+ "stopAtEntry": false,
10
+ "externalConsole": true,
11
+ "cwd": "c:/Users/bmiCAD/Documents/Visual_Interfacing_Structure/VIS/Templates",
12
+ "program": "c:/Users/bmiCAD/Documents/Visual_Interfacing_Structure/VIS/Templates/build/Debug/outDebug",
13
+ "MIMode": "gdb",
14
+ "miDebuggerPath": "gdb",
15
+ "setupCommands": [
16
+ {
17
+ "description": "Enable pretty-printing for gdb",
18
+ "text": "-enable-pretty-printing",
19
+ "ignoreFailures": true
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "C_Cpp_Runner.cCompilerPath": "gcc",
3
+ "C_Cpp_Runner.cppCompilerPath": "g++",
4
+ "C_Cpp_Runner.debuggerPath": "gdb",
5
+ "C_Cpp_Runner.cStandard": "",
6
+ "C_Cpp_Runner.cppStandard": "",
7
+ "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat",
8
+ "C_Cpp_Runner.useMsvc": false,
9
+ "C_Cpp_Runner.warnings": [
10
+ "-Wall",
11
+ "-Wextra",
12
+ "-Wpedantic",
13
+ "-Wshadow",
14
+ "-Wformat=2",
15
+ "-Wcast-align",
16
+ "-Wconversion",
17
+ "-Wsign-conversion",
18
+ "-Wnull-dereference"
19
+ ],
20
+ "C_Cpp_Runner.msvcWarnings": [
21
+ "/W4",
22
+ "/permissive-",
23
+ "/w14242",
24
+ "/w14287",
25
+ "/w14296",
26
+ "/w14311",
27
+ "/w14826",
28
+ "/w44062",
29
+ "/w44242",
30
+ "/w14905",
31
+ "/w14906",
32
+ "/w14263",
33
+ "/w44265",
34
+ "/w14928"
35
+ ],
36
+ "C_Cpp_Runner.enableWarnings": true,
37
+ "C_Cpp_Runner.warningsAsError": false,
38
+ "C_Cpp_Runner.compilerArgs": [],
39
+ "C_Cpp_Runner.linkerArgs": [],
40
+ "C_Cpp_Runner.includePaths": [],
41
+ "C_Cpp_Runner.includeSearch": [
42
+ "*",
43
+ "**/*"
44
+ ],
45
+ "C_Cpp_Runner.excludeSearch": [
46
+ "**/build",
47
+ "**/build/**",
48
+ "**/.*",
49
+ "**/.*/**",
50
+ "**/.vscode",
51
+ "**/.vscode/**"
52
+ ],
53
+ "C_Cpp_Runner.useAddressSanitizer": false,
54
+ "C_Cpp_Runner.useUndefinedSanitizer": false,
55
+ "C_Cpp_Runner.useLeakSanitizer": false,
56
+ "C_Cpp_Runner.showCompilationTime": false,
57
+ "C_Cpp_Runner.useLinkTimeOptimization": false,
58
+ "C_Cpp_Runner.msvcSecureNoWarnings": false
59
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: VIStk
3
- Version: 0.3.6
3
+ Version: 0.3.8
4
4
  Summary: Visual Interfacing Structure for python using tkinter
5
5
  Author-email: Elijah Love <elijah2005l@gmail.com>
6
6
  Maintainer-email: Elijah Love <elijah2005l@gmail.com>
Binary file
@@ -6,8 +6,6 @@ import sys
6
6
  #File Specific Imports
7
7
 
8
8
  #Configure Screen
9
- print(cfp)
10
-
11
9
  w = 1080
12
10
  h = 720
13
11
  ws = root.winfo_screenwidth()
@@ -29,5 +29,5 @@ $name$_exe = EXE(
29
29
  target_arch=None,
30
30
  codesign_identity=None,
31
31
  entitlements_file=None,
32
- icon=['../Icons/$icon$.ico'],)
33
-
32
+ icon=['../Icons/$icon$.ico'],
33
+ version='$meta$')
@@ -0,0 +1,30 @@
1
+ # UTF-8
2
+
3
+ VSVersionInfo(
4
+ ffi=FixedFileInfo(
5
+ filevers=($sM$,$sm$,$sp$,0),
6
+ prodvers=($M$,$m$,$p$,0),
7
+ mask=0x3f,
8
+ flags=0x0,
9
+ OS=0x40004,
10
+ fileType=0x1,
11
+ subtype=0x0,
12
+ date=(0, 0)
13
+ ),
14
+ kids=[
15
+ StringFileInfo(
16
+ [
17
+ StringTable(
18
+ u'040904B0',
19
+ [StringStruct(u'CompanyName', u'$company$'),
20
+ StringStruct(u'FileDescription', u'$desc$'),
21
+ StringStruct(u'FileVersion', u'$sM$.$sm$.$sp$'),
22
+ StringStruct(u'InternalName', u'$title$-$name$'),
23
+ StringStruct(u'LegalCopyright', u'Copyright © $year$ $company$'),
24
+ StringStruct(u'OriginalFilename', u'$name$.exe'),
25
+ StringStruct(u'ProductName', u'$name$'),
26
+ StringStruct(u'ProductVersion', u'$M$.$m$.$p$')])
27
+ ]),
28
+ VarFileInfo([VarStruct(u'Translation', [1033, 1200])])
29
+ ]
30
+ )
vistk-0.3.8/VIS/VIS.py ADDED
@@ -0,0 +1,53 @@
1
+ import sys
2
+ import os
3
+ import zipfile
4
+ from VIS.project import *
5
+ from importlib import metadata
6
+ from VIS.release import newRelease
7
+
8
+ inp = sys.argv
9
+ print(f"VIS Version {metadata.version("VIStk")}")
10
+
11
+
12
+ #Copied from source https://stackoverflow.com/a/75246706
13
+ def unzip_without_overwrite(src_path, dst_dir):
14
+ with zipfile.ZipFile(src_path, "r") as zf:
15
+ for member in zf.infolist():
16
+ file_path = os.path.join(dst_dir, member.filename)
17
+ if not os.path.exists(file_path):
18
+ zf.extract(member, dst_dir)
19
+ def __main__():
20
+ match inp[1]:
21
+ case "new"|"New"|"N"|"n":#Create a new VIS project
22
+ project = VINFO()
23
+
24
+ case "add" | "Add" | "a" | "A":
25
+ project = Project()
26
+ match inp[2]:
27
+ case "screen" | "Screen" | "s" | "S":
28
+ if not inp[3] == None:
29
+ screen = project.verScreen(inp[3])
30
+ if len(inp) >= 5:
31
+ match inp[4]:
32
+ case "menu" | "Menu" | "m" | "M":
33
+ screen.addMenu(inp[5])
34
+ case "elements" | "Elements" | "e" | "E":
35
+ for i in inp[5].split("-"):
36
+ screen.addElement(i)
37
+ screen.stitch()
38
+ else:
39
+ project.newScreen(inp[3])
40
+
41
+ case "stitch" | "Stitch" | "s" | "S":
42
+ project = Project()
43
+ screen = project.getScreen(inp[2])
44
+ if not screen == None:
45
+ screen.stitch()
46
+ else:
47
+ print("Screen does not exist")
48
+
49
+ case "release" | "Release" | "r" | "R":
50
+ if len(inp) == 4:
51
+ newRelease(inp[2],inp[3])
52
+ else:
53
+ newRelease(inp[2])
@@ -0,0 +1,362 @@
1
+ import os
2
+ import json
3
+ import zipfile
4
+ import shutil
5
+ import re
6
+ import glob
7
+ import subprocess
8
+
9
+ #Copied from source
10
+ #https://stackoverflow.com/a/75246706
11
+ def unzip_without_overwrite(src_path, dst_dir):
12
+ with zipfile.ZipFile(src_path, "r") as zf:
13
+ for member in zf.infolist():
14
+ file_path = os.path.join(dst_dir, member.filename)
15
+ if not os.path.exists(file_path):
16
+ zf.extract(member, dst_dir)
17
+
18
+ def getPath():
19
+ """Searches for .VIS folder and returns from path.cfg
20
+ """
21
+ sto = 0
22
+ while True:
23
+ try:
24
+ step=""
25
+ for i in range(0,sto,1): #iterate on sto to step backwards and search for project info
26
+ step = "../" + step
27
+ if os.path.exists(step+".VIS/"):
28
+ return open(step+".VIS/path.cfg","r").read().replace("\\","/") #return stored path
29
+ else:
30
+ if os.path.exists(step):
31
+ sto += 1
32
+ else:
33
+ return None #return none if cant escape more
34
+ except:
35
+ return None #if failed return none
36
+
37
+ def validName(name:str):
38
+ """Checks if provided path is a valid filename
39
+ """
40
+ if " " in name:
41
+ print("Cannot have spaces in file name.")
42
+ return False
43
+ if "/" in name or "\\" in name:
44
+ print("Cannot have filepath deliminator in file name.")
45
+ return False
46
+ if "<" in name or ">" in name or ":" in name or '"' in name or "|" in name or "?" in name or "*" in name:
47
+ print('Invlaid ASCII characters for windows file creation, please remove all <>:"|?* from file name.')
48
+ return False
49
+ if name.split(".")[0] in ["CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"]:
50
+ print(f"Filename {name} reserved by OS.")
51
+ return False
52
+ if "" == name:
53
+ print("Must provide a name for file.")
54
+ return False
55
+ else:
56
+ return True
57
+
58
+
59
+ class VINFO():
60
+ """Overarching control structure within the /.VIS/ folder
61
+ """
62
+ def __init__(self):
63
+ if getPath() == None:
64
+ wd = os.getcwd()
65
+ os.mkdir(wd+"\\.VIS")
66
+ open(wd+"/.VIS/path.cfg","w").write(wd) if os.path.exists(wd+"/.VIS/path.cfg") else open(wd+"/.VIS/path.cfg", 'a').write(wd)
67
+ print(f"Stored project path in path.cfg as {wd} in {wd}/.VIS/path.cfg")
68
+
69
+ unzip_without_overwrite("./Form.zip",wd)
70
+ print(f"Copied structure to {wd}")
71
+
72
+ shutil.copytree("./Templates",wd+"/.VIS/Templates",dirs_exist_ok=True)
73
+ print(f"Loaded default templates into {wd}/.VIS/Templates/")
74
+
75
+
76
+ #DO NOT MESS WITH THE TEMPLATE HEADERS
77
+
78
+ title = input("Enter a name for the VIS project: ")
79
+ self.title = title
80
+ info = {}
81
+ info[self.title] = {}
82
+ info[self.title]["Screens"]={}
83
+ info[self.title]["defaults"]={}
84
+ info[self.title]["defaults"]["icon"]="VIS"#default icon
85
+ self.d_icon = "VIS"
86
+ self[self.title]["metadata"]={}
87
+ comp = input("What company is this for(or none)? ")
88
+ if not comp in ["none","None"]:
89
+ info[self.title]["metadata"]["company"] = comp
90
+ self.company = comp
91
+ else:
92
+ info[self.title]["metadata"]["company"] = None
93
+ self.company = None
94
+
95
+ version = input("What is the initial version for the project (0.0.1 default): ")
96
+ vers = version.split(".")
97
+ if len(vers)==3:
98
+ if vers[0].isnumeric() and vers[1].isnumeric() and vers[2].isnumeric():
99
+ self.version = version
100
+ else:
101
+ self.version = "0.0.1"
102
+ else:
103
+ self.version = "0.0.1"
104
+ info[self.title]["metadata"]["version"] = self.version
105
+
106
+ with open(wd+"/.VIS/project.json","w") as f:
107
+ f.write("{}")
108
+ json.dump(info,f,indent=4)
109
+ print(f"Setup project.json for project {self.title} in {wd}/.VIS/")
110
+
111
+
112
+ #Need to get current python location where VIS is installed
113
+ self.p_vis = subprocess.check_output('python -c "import os, sys; print(os.path.dirname(sys.executable))"').decode().strip("\r\n")+"\\Lib\\site-packages\\VIS\\"
114
+
115
+
116
+ self.p_project = getPath()
117
+ self.p_vinfo = self.p_project + "/.VIS"
118
+ self.p_sinfo = self.p_vinfo + "/project.json"
119
+ with open(self.p_sinfo,"r") as f:
120
+ info = json.load(f)
121
+ self.title = list(info.keys())[0]
122
+ self.version = info[self.title]["metadata"]["version"]
123
+ self.company = info[self.title]["metadata"]["company"]
124
+
125
+ self.screenlist = []
126
+ self.p_screens = self.p_project +"/Screens"
127
+ self.p_modules = self.p_project +"/modules"
128
+ self.p_templates = self.p_vinfo + "/Templates"
129
+ self.p_icons = self.p_project + "/Icons"
130
+ self.p_images = self.p_project + "/Images"
131
+
132
+ def setVersion(self,version:str):
133
+ """Sets a new project version
134
+ """
135
+ with open(self.p_sinfo,"r") as f:
136
+ info = json.load(f)
137
+
138
+ info[self.title]["metadata"]["version"] = version
139
+
140
+ with open(self.p_sinfo,"w") as f:
141
+ json.dump(info,f,indent=4)
142
+
143
+
144
+ class Screen(VINFO):
145
+ """A VIS screen object
146
+ """
147
+ def __init__(self,name:str,script:str,release:bool=False,icon:str=None,exists:bool=True,desc:str=None):
148
+ super().__init__()
149
+ self.name=name
150
+ self.script=script
151
+ self.release=release
152
+ self.icon=icon
153
+ self.path = self.p_screens+"/"+self.name
154
+ self.m_path = self.p_modules+"/"+self.name
155
+
156
+ if not exists:
157
+ with open(self.p_sinfo,"r") as f:
158
+ info = json.load(f)
159
+
160
+ info[self.title]["Screens"][self.name] = {"script":script,"release":release}
161
+ if not icon == None:
162
+ info[self.title]["Screens"][self.name]["icon"] = icon
163
+
164
+ if not desc == None:
165
+ info[self.title]["Screens"][self.name]["desc"] = desc
166
+ else:
167
+ info[self.title]["Screens"][self.name]["desc"] = "A VIS Created Executable"
168
+
169
+ info[self.title]["Screens"][self.name]["version"] = "1.0.0"#always making first major version of screen
170
+
171
+ info[self.title]["Screens"][self.name]["current"] = None#always making first major version of screen
172
+
173
+ with open(self.p_sinfo,"w") as f:
174
+ json.dump(info,f,indent=4)
175
+
176
+ shutil.copyfile(self.p_templates+"/screen.txt",self.p_project+"/"+script)
177
+ os.mkdir(self.p_screens+"/"+self.name)
178
+ os.mkdir(self.p_modules+"/"+self.name)
179
+
180
+ with open(self.p_sinfo,"r") as f:
181
+ info = json.load(f)
182
+ self.desc = info[self.title]["Screens"][self.name]["desc"]
183
+ self.s_version = info[self.title]["Screens"][self.name]["version"]
184
+ self.current = info[self.title]["Screens"][self.name]["current"]
185
+
186
+
187
+ def addElement(self,element:str) -> int:
188
+ if validName(element):
189
+ if not os.path.exists(self.path+"/f_"+element+".py"):
190
+ shutil.copyfile(self.p_templates+"/f_element.txt",self.path+"/f_"+element+".py")
191
+ print(f"Created element f_{element}.py in {self.path}")
192
+ self.patch(element)
193
+ if not os.path.exists(self.m_path+"/m_"+element+".py"):
194
+ with open(self.m_path+"/m_"+element+".py", "w"): pass
195
+ print(f"Created module m_{element}.py in {self.m_path}")
196
+ return 1
197
+ else:
198
+ return 0
199
+
200
+ def addMenu(self,menu:str) -> int:
201
+ pass #will be command line menu creation tool
202
+
203
+ def patch(self,element:str) -> int:
204
+ """Patches up the template after its copied
205
+ """
206
+ if os.path.exists(self.path+"/f_"+element+".py"):
207
+ with open(self.path+"/f_"+element+".py","r") as f:
208
+ text = f.read()
209
+ text = text.replace("<frame>","f_"+element)
210
+ with open(self.path+"/f_"+element+".py","w") as f:
211
+ f.write(text)
212
+ print(f"patched f_{element}.py")
213
+ return 1
214
+ else:
215
+ print(f"Could not patch, element does not exist.")
216
+ return 0
217
+
218
+ def stitch(self) -> int:
219
+ """Connects screen elements to a screen
220
+ """
221
+ with open(self.p_project+"/"+self.script,"r") as f: text = f.read()
222
+ stitched = []
223
+ #Elements
224
+ pattern = r"#Screen Elements.*#Screen Grid"
225
+
226
+ elements = glob.glob(self.path+'/f_*')#get all elements
227
+ for i in range(0,len(elements),1):#iterate into module format
228
+ elements[i] = elements[i].replace("\\","/")
229
+ elements[i] = elements[i].replace(self.path+"/","Screens."+self.name+".")[:-3]
230
+ stitched.append(elements[i])
231
+ #combine and change text
232
+ elements = "from " + " import *\nfrom ".join(elements) + " import *\n"
233
+ text = re.sub(pattern, "#Screen Elements\n" + elements + "\n#Screen Grid", text, flags=re.DOTALL)
234
+
235
+ #Modules
236
+ pattern = r"#Screen Modules.*#Handle Arguments"
237
+
238
+ modules = glob.glob(self.m_path+'/m_*')#get all modules
239
+ for i in range(0,len(modules),1):#iterate into module format
240
+ modules[i] = modules[i].replace("\\","/")
241
+ modules[i] = modules[i].replace(self.m_path+"/","modules."+self.name+".")[:-3]
242
+ stitched.append(modules[i])
243
+ #combine and change text
244
+ modules = "from " + " import *\nfrom ".join(modules) + " import *\n"
245
+ text = re.sub(pattern, "#Screen Modules\n" + modules + "\n#Handle Arguments", text, flags=re.DOTALL)
246
+
247
+ #write out
248
+ with open(self.p_project+"/"+self.script,"w") as f:
249
+ f.write(text)
250
+ print("Stitched: ")
251
+ for i in stitched:
252
+ print(f"\t{i} to {self.name}")
253
+
254
+ def syncVersion(self) -> int:
255
+ """Syncs the version stored in sinfo with the version in memory
256
+ """
257
+ with open(self.p_sinfo,"r") as f:
258
+ info = json.load(f)
259
+ info[self.title]["Screens"][self.name]["current"] = self.current
260
+ with open(self.p_sinfo,"w") as f:
261
+ json.dump(info,f)
262
+ return 1
263
+
264
+ def crntVersion(self) -> int:
265
+ """Checks if the version needs to be synced and returns 1 if its synced
266
+ """
267
+ if not self.s_version == self.current:
268
+ self.current = self.version
269
+ self.syncVersion()
270
+ return 1
271
+ else:
272
+ return 0
273
+
274
+
275
+ class Project(VINFO):
276
+ """VIS Project Object
277
+ """
278
+ def __init__(self):
279
+ """Initializes or load a VIS project
280
+ """
281
+ super().__init__()
282
+ with open(self.p_sinfo,"r") as f:
283
+ info = json.load(f)
284
+ self.name = list(info.keys())[0]
285
+
286
+ for screen in list(info[self.name]["Screens"].keys()):
287
+ scr = Screen(screen,
288
+ info[self.name]["Screens"][screen]["script"],
289
+ info[self.name]["Screens"][screen]["release"],
290
+ info[self.name]["Screens"][screen].get("icon"),
291
+ exists=True)
292
+ self.screenlist.append(scr)
293
+ self.d_icon = info[self.name]["defaults"]["icon"]
294
+
295
+ def newScreen(self,screen:str) -> int:
296
+ """Creates a new screen with some prompting
297
+
298
+ Returns:
299
+ 0 Failed
300
+ 1 Success
301
+ """
302
+ #Check for valid filename
303
+ if not validName(screen):
304
+ return 0
305
+
306
+ with open(self.p_sinfo,"r") as f:
307
+ info = json.load(f) #Load info
308
+
309
+ name = self.title
310
+ if info[name]["Screens"].get(screen) == None: #If Screen does not exist in VINFO
311
+ while True: #ensures a valid name is used for script
312
+ match input(f"Should python script use name {screen}.py? "):
313
+ case "Yes" | "yes" | "Y" | "y":
314
+ script = screen + ".py"
315
+ break
316
+ case _:
317
+ script = input("Enter the name for the script file: ").strip(".py")+".py"
318
+ if validName(script):
319
+ break
320
+
321
+ match input("Should this screen have its own .exe?: "):
322
+ case "Yes" | "yes" | "Y" | "y":
323
+ release = True
324
+ case _:
325
+ release = False
326
+ ictf =input("What is the icon for this screen (or none)?: ")
327
+ icon = ictf.strip(".ico") if ".ICO" in ictf.upper() else None
328
+ desc = input("Write a description for this screen: ")
329
+ self.screenlist.append(Screen(screen,script,release,icon,False,desc))
330
+
331
+ return 1
332
+ else:
333
+ print(f"Information for {screen} already in project.")
334
+ return 1
335
+
336
+ def hasScreen(self,screen:str) -> bool:
337
+ """Checks if the project has the correct screen
338
+ """
339
+ for i in self.screenlist:
340
+ if i.name == screen:
341
+ return True
342
+ return False
343
+
344
+ def getScreen(self,screen:str) -> Screen:
345
+ """Returns a screen object by its name
346
+ """
347
+ for i in self.screenlist:
348
+ if i.name == screen:
349
+ return i
350
+ return None
351
+
352
+ def verScreen(self,screen:str) -> Screen:
353
+ """Verifies a screen exists and returns it
354
+
355
+ Returns:
356
+ screen (Screen): Verified screen
357
+ """
358
+ if not self.hasScreen(screen):
359
+ self.newScreen(screen)
360
+ scr = self.getScreen(screen)
361
+ return scr
362
+