TouchPortalAPI v1.7.8
TouchPortalAPI.TpToPy
1#!/usr/bin/env python3 2__copyright__ = """ 3This file is part of the TouchPortal-API project. 4Copyright TouchPortal-API Developers 5Copyright (c) 2021 DamienS 6All rights reserved. 7 8This program is free software: you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation, either version 3 of the License, or 11(at your option) any later version. 12 13This program is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with this program. If not, see <https://www.gnu.org/licenses/>. 20""" 21 22 23import json 24import re 25from pathlib import Path 26 27 28class TpToPy(): 29 """ 30 This is used to convert entry.tp to a fully usable python version entry. 31 """ 32 33 def __init__(self, entry): 34 self.entry = json.loads(Path(entry).resolve().read_text()) 35 self.structState = {} 36 self.structAction = {} 37 self.structEvent = {} 38 self.structConnector = {} 39 self.structCalegories = {} 40 41 def getPluginId(self): 42 """ 43 A helper method that returns the plugin id from entry.tp 44 """ 45 return self.entry.get("id", "") 46 47 def __convertData(self, data): 48 """ 49 convert Action and connector data to python struct format 50 """ 51 newData = {} 52 if isinstance(data, list): 53 for item in range(len(data)): 54 newData[item] = data[item] 55 return newData 56 57 def __convertFormat(self, actionFormat, data): 58 """ 59 This will automatically convert `format`. eg `{$dataid$}` to `$[data_index starts from 1] 60 """ 61 62 newFormat = actionFormat 63 for item in range(len(data)): 64 if data[item]['id'] in actionFormat: 65 newFormat = newFormat.replace("{$" + data[item]['id'] + "$}", "$[" + str(item+1) + "]") 66 67 return newFormat 68 69 def generateInfo(self): 70 """ 71 This will generate TP_PLUGIN_INFO struct 72 """ 73 74 generatedInfo = {} 75 infoKeys = ["sdk", "version", "name", "id", "configuration", "plugin_start_cmd_windows", "plugin_start_cmd_linux", "plugin_start_cmd_mac", "plugin_start_cmd"] 76 77 for key in self.entry.keys(): 78 if key in infoKeys: 79 generatedInfo[key] = self.entry[key] 80 81 return generatedInfo 82 83 def generateSettings(self): 84 """ 85 This will generate TP_PLUGIN_SETTINGS struct 86 """ 87 88 generatedSetting = {} 89 if not self.entry.get("settings", True): return generatedSetting 90 91 settings = self.entry.get("settings", []) 92 93 if isinstance(settings, list): 94 for setting in range(len(settings)): 95 generatedSetting[setting+1] = settings[setting] 96 97 return generatedSetting 98 99 def generateStates(self, data, category): 100 """ 101 This generates TP_PLUGIN_STATES struct 102 """ 103 104 startIndex = len(self.structState) 105 106 for state in data: 107 self.structState[startIndex] = state 108 self.structState[startIndex]["category"] = category 109 110 startIndex += 1 111 112 return self.structState 113 114 115 def generateActions(self, data, category): 116 """ 117 This generates TP_PLUGIN_ACTION struct 118 """ 119 120 startIndex = len(self.structAction) 121 122 for action in data: 123 startIndex += 1 124 self.structAction[startIndex] = action 125 if self.structAction[startIndex].get("format", False): 126 self.structAction[startIndex]['format'] = self.__convertFormat(action["format"], action['data']) 127 if action.get('data', False): 128 self.structAction[startIndex]['data'] = self.__convertData(action['data']) 129 self.structAction[startIndex]["category"] = category 130 131 return self.structAction 132 133 def generateEvents(self, data, category): 134 """ 135 This will generates TP_PLUGIN_EVENTS struct 136 """ 137 138 startIndex = len(self.structEvent) 139 140 for event in data: 141 self.structEvent[startIndex] = event 142 self.structEvent[startIndex]["category"] = category 143 144 return self.structEvent 145 146 def generateConnectors(self, data, category): 147 """ 148 This generates TP_PLUGIN_CONNECTORS struct 149 """ 150 151 startIndex = len(self.structConnector) 152 153 for connector in data: 154 self.structConnector[startIndex] = connector 155 self.structConnector[startIndex]['category'] = category 156 if self.structConnector[startIndex].get('format', False): 157 self.structConnector[startIndex]['format'] = self.__convertFormat(connector['format'], connector['data']) 158 if connector.get("data", False): 159 self.structConnector[startIndex]['data'] = self.__convertData(connector['data']) 160 161 return self.structConnector 162 163 def generateCalegories(self): 164 """ 165 This generates TP_PLUGIN_CATEGORIES struct and also when looping each category it will 166 populate Actions, States, Connectors and Event struct. 167 """ 168 169 generatedCalegory = {} 170 categories = self.entry.get("categories", []) 171 172 for category in categories: 173 categId = category.get("id", "").split(".") 174 generatedCalegory[categId[-1]] = { 175 "id": category.get("id"), 176 "name": category.get("name", ""), 177 "imagepath": category.get("imagepath", ""), 178 } 179 180 todoList = {"actions": self.generateActions, "states": self.generateStates, 181 "connectors": self.generateConnectors, "events": self.generateEvents} 182 183 for todo in todoList: # hack 184 if (data := category.get(todo)) and isinstance(data, list): 185 todoList[todo](data, categId[-1]) 186 187 return generatedCalegory 188 189 def writetoFile(self, fileName): 190 """ 191 This method will collects struct INFO, SETTINGS, STATES etc... and write python 192 version of entry.tp to file. 193 """ 194 195 TP_PLUGIN_INFO = self.generateInfo() 196 TP_PLUGIN_SETTINGS = self.generateSettings() 197 TP_PLUGIN_STATES = self.structState 198 TP_PLUGIN_ACTIONS = self.structAction 199 TP_PLUGIN_CONNECTORS = self.structConnector 200 TP_PLUGIN_EVENTS = self.structEvent 201 TP_PLUGIN_CATEGORIES = self.generateCalegories() 202 203 with open(fileName, 'w') as f: 204 f.write("#!/usr/bin/env python3\n") 205 for entryVar in ["TP_PLUGIN_INFO", "TP_PLUGIN_SETTINGS", "TP_PLUGIN_CATEGORIES", "TP_PLUGIN_CONNECTORS", "TP_PLUGIN_ACTIONS", "TP_PLUGIN_STATES", "TP_PLUGIN_EVENTS"]: 206 struct = json.dumps(locals()[entryVar], indent=4, sort_keys=False, skipkeys=True) 207 struct = re.sub(r'": (true|false)(,?)\n', lambda m: f'": {m.group(1).title()}{m.group(2)}\n', struct) 208 f.write(f"{entryVar} = {struct}\n\n") 209 210class toString(): 211 """ 212 This basically `emulate` import a python struct. for example 213 214 ```py 215 import TPPEntry # Python file 216 217 TPPEntry.TP_PLUGIN_INFO # because it contain `TP_PLUGIN_INFO` variable in that file 218 ``` 219 220 and This trys to do same thing as that. 221 ```py 222 import TpToPy 223 224 myEntry = TpToPy.toString(TpToPy.TpToPy("entry.tp")) 225 myEntry.TP_PLUGIN_INFO 226 ``` 227 """ 228 229 def __init__(self, entry): 230 self.entry = TpToPy(entry) 231 232 self.TP_PLUGIN_INFO = self.entry.generateInfo() 233 self.TP_PLUGIN_SETTINGS = self.entry.generateSettings() 234 self.TP_PLUGIN_CATEGORIES = self.entry.generateCalegories() 235 self.TP_PLUGIN_STATES = self.entry.structState 236 self.TP_PLUGIN_ACTIONS = self.entry.structAction 237 self.TP_PLUGIN_CONNECTORS = self.entry.structConnector 238 self.TP_PLUGIN_EVENTS = self.entry.structEvent
class
TpToPy:
29class TpToPy(): 30 """ 31 This is used to convert entry.tp to a fully usable python version entry. 32 """ 33 34 def __init__(self, entry): 35 self.entry = json.loads(Path(entry).resolve().read_text()) 36 self.structState = {} 37 self.structAction = {} 38 self.structEvent = {} 39 self.structConnector = {} 40 self.structCalegories = {} 41 42 def getPluginId(self): 43 """ 44 A helper method that returns the plugin id from entry.tp 45 """ 46 return self.entry.get("id", "") 47 48 def __convertData(self, data): 49 """ 50 convert Action and connector data to python struct format 51 """ 52 newData = {} 53 if isinstance(data, list): 54 for item in range(len(data)): 55 newData[item] = data[item] 56 return newData 57 58 def __convertFormat(self, actionFormat, data): 59 """ 60 This will automatically convert `format`. eg `{$dataid$}` to `$[data_index starts from 1] 61 """ 62 63 newFormat = actionFormat 64 for item in range(len(data)): 65 if data[item]['id'] in actionFormat: 66 newFormat = newFormat.replace("{$" + data[item]['id'] + "$}", "$[" + str(item+1) + "]") 67 68 return newFormat 69 70 def generateInfo(self): 71 """ 72 This will generate TP_PLUGIN_INFO struct 73 """ 74 75 generatedInfo = {} 76 infoKeys = ["sdk", "version", "name", "id", "configuration", "plugin_start_cmd_windows", "plugin_start_cmd_linux", "plugin_start_cmd_mac", "plugin_start_cmd"] 77 78 for key in self.entry.keys(): 79 if key in infoKeys: 80 generatedInfo[key] = self.entry[key] 81 82 return generatedInfo 83 84 def generateSettings(self): 85 """ 86 This will generate TP_PLUGIN_SETTINGS struct 87 """ 88 89 generatedSetting = {} 90 if not self.entry.get("settings", True): return generatedSetting 91 92 settings = self.entry.get("settings", []) 93 94 if isinstance(settings, list): 95 for setting in range(len(settings)): 96 generatedSetting[setting+1] = settings[setting] 97 98 return generatedSetting 99 100 def generateStates(self, data, category): 101 """ 102 This generates TP_PLUGIN_STATES struct 103 """ 104 105 startIndex = len(self.structState) 106 107 for state in data: 108 self.structState[startIndex] = state 109 self.structState[startIndex]["category"] = category 110 111 startIndex += 1 112 113 return self.structState 114 115 116 def generateActions(self, data, category): 117 """ 118 This generates TP_PLUGIN_ACTION struct 119 """ 120 121 startIndex = len(self.structAction) 122 123 for action in data: 124 startIndex += 1 125 self.structAction[startIndex] = action 126 if self.structAction[startIndex].get("format", False): 127 self.structAction[startIndex]['format'] = self.__convertFormat(action["format"], action['data']) 128 if action.get('data', False): 129 self.structAction[startIndex]['data'] = self.__convertData(action['data']) 130 self.structAction[startIndex]["category"] = category 131 132 return self.structAction 133 134 def generateEvents(self, data, category): 135 """ 136 This will generates TP_PLUGIN_EVENTS struct 137 """ 138 139 startIndex = len(self.structEvent) 140 141 for event in data: 142 self.structEvent[startIndex] = event 143 self.structEvent[startIndex]["category"] = category 144 145 return self.structEvent 146 147 def generateConnectors(self, data, category): 148 """ 149 This generates TP_PLUGIN_CONNECTORS struct 150 """ 151 152 startIndex = len(self.structConnector) 153 154 for connector in data: 155 self.structConnector[startIndex] = connector 156 self.structConnector[startIndex]['category'] = category 157 if self.structConnector[startIndex].get('format', False): 158 self.structConnector[startIndex]['format'] = self.__convertFormat(connector['format'], connector['data']) 159 if connector.get("data", False): 160 self.structConnector[startIndex]['data'] = self.__convertData(connector['data']) 161 162 return self.structConnector 163 164 def generateCalegories(self): 165 """ 166 This generates TP_PLUGIN_CATEGORIES struct and also when looping each category it will 167 populate Actions, States, Connectors and Event struct. 168 """ 169 170 generatedCalegory = {} 171 categories = self.entry.get("categories", []) 172 173 for category in categories: 174 categId = category.get("id", "").split(".") 175 generatedCalegory[categId[-1]] = { 176 "id": category.get("id"), 177 "name": category.get("name", ""), 178 "imagepath": category.get("imagepath", ""), 179 } 180 181 todoList = {"actions": self.generateActions, "states": self.generateStates, 182 "connectors": self.generateConnectors, "events": self.generateEvents} 183 184 for todo in todoList: # hack 185 if (data := category.get(todo)) and isinstance(data, list): 186 todoList[todo](data, categId[-1]) 187 188 return generatedCalegory 189 190 def writetoFile(self, fileName): 191 """ 192 This method will collects struct INFO, SETTINGS, STATES etc... and write python 193 version of entry.tp to file. 194 """ 195 196 TP_PLUGIN_INFO = self.generateInfo() 197 TP_PLUGIN_SETTINGS = self.generateSettings() 198 TP_PLUGIN_STATES = self.structState 199 TP_PLUGIN_ACTIONS = self.structAction 200 TP_PLUGIN_CONNECTORS = self.structConnector 201 TP_PLUGIN_EVENTS = self.structEvent 202 TP_PLUGIN_CATEGORIES = self.generateCalegories() 203 204 with open(fileName, 'w') as f: 205 f.write("#!/usr/bin/env python3\n") 206 for entryVar in ["TP_PLUGIN_INFO", "TP_PLUGIN_SETTINGS", "TP_PLUGIN_CATEGORIES", "TP_PLUGIN_CONNECTORS", "TP_PLUGIN_ACTIONS", "TP_PLUGIN_STATES", "TP_PLUGIN_EVENTS"]: 207 struct = json.dumps(locals()[entryVar], indent=4, sort_keys=False, skipkeys=True) 208 struct = re.sub(r'": (true|false)(,?)\n', lambda m: f'": {m.group(1).title()}{m.group(2)}\n', struct) 209 f.write(f"{entryVar} = {struct}\n\n")
This is used to convert entry.tp to a fully usable python version entry.
def
getPluginId(self)
42 def getPluginId(self): 43 """ 44 A helper method that returns the plugin id from entry.tp 45 """ 46 return self.entry.get("id", "")
A helper method that returns the plugin id from entry.tp
def
generateInfo(self)
70 def generateInfo(self): 71 """ 72 This will generate TP_PLUGIN_INFO struct 73 """ 74 75 generatedInfo = {} 76 infoKeys = ["sdk", "version", "name", "id", "configuration", "plugin_start_cmd_windows", "plugin_start_cmd_linux", "plugin_start_cmd_mac", "plugin_start_cmd"] 77 78 for key in self.entry.keys(): 79 if key in infoKeys: 80 generatedInfo[key] = self.entry[key] 81 82 return generatedInfo
This will generate TP_PLUGIN_INFO struct
def
generateSettings(self)
84 def generateSettings(self): 85 """ 86 This will generate TP_PLUGIN_SETTINGS struct 87 """ 88 89 generatedSetting = {} 90 if not self.entry.get("settings", True): return generatedSetting 91 92 settings = self.entry.get("settings", []) 93 94 if isinstance(settings, list): 95 for setting in range(len(settings)): 96 generatedSetting[setting+1] = settings[setting] 97 98 return generatedSetting
This will generate TP_PLUGIN_SETTINGS struct
def
generateStates(self, data, category)
100 def generateStates(self, data, category): 101 """ 102 This generates TP_PLUGIN_STATES struct 103 """ 104 105 startIndex = len(self.structState) 106 107 for state in data: 108 self.structState[startIndex] = state 109 self.structState[startIndex]["category"] = category 110 111 startIndex += 1 112 113 return self.structState
This generates TP_PLUGIN_STATES struct
def
generateActions(self, data, category)
116 def generateActions(self, data, category): 117 """ 118 This generates TP_PLUGIN_ACTION struct 119 """ 120 121 startIndex = len(self.structAction) 122 123 for action in data: 124 startIndex += 1 125 self.structAction[startIndex] = action 126 if self.structAction[startIndex].get("format", False): 127 self.structAction[startIndex]['format'] = self.__convertFormat(action["format"], action['data']) 128 if action.get('data', False): 129 self.structAction[startIndex]['data'] = self.__convertData(action['data']) 130 self.structAction[startIndex]["category"] = category 131 132 return self.structAction
This generates TP_PLUGIN_ACTION struct
def
generateEvents(self, data, category)
134 def generateEvents(self, data, category): 135 """ 136 This will generates TP_PLUGIN_EVENTS struct 137 """ 138 139 startIndex = len(self.structEvent) 140 141 for event in data: 142 self.structEvent[startIndex] = event 143 self.structEvent[startIndex]["category"] = category 144 145 return self.structEvent
This will generates TP_PLUGIN_EVENTS struct
def
generateConnectors(self, data, category)
147 def generateConnectors(self, data, category): 148 """ 149 This generates TP_PLUGIN_CONNECTORS struct 150 """ 151 152 startIndex = len(self.structConnector) 153 154 for connector in data: 155 self.structConnector[startIndex] = connector 156 self.structConnector[startIndex]['category'] = category 157 if self.structConnector[startIndex].get('format', False): 158 self.structConnector[startIndex]['format'] = self.__convertFormat(connector['format'], connector['data']) 159 if connector.get("data", False): 160 self.structConnector[startIndex]['data'] = self.__convertData(connector['data']) 161 162 return self.structConnector
This generates TP_PLUGIN_CONNECTORS struct
def
generateCalegories(self)
164 def generateCalegories(self): 165 """ 166 This generates TP_PLUGIN_CATEGORIES struct and also when looping each category it will 167 populate Actions, States, Connectors and Event struct. 168 """ 169 170 generatedCalegory = {} 171 categories = self.entry.get("categories", []) 172 173 for category in categories: 174 categId = category.get("id", "").split(".") 175 generatedCalegory[categId[-1]] = { 176 "id": category.get("id"), 177 "name": category.get("name", ""), 178 "imagepath": category.get("imagepath", ""), 179 } 180 181 todoList = {"actions": self.generateActions, "states": self.generateStates, 182 "connectors": self.generateConnectors, "events": self.generateEvents} 183 184 for todo in todoList: # hack 185 if (data := category.get(todo)) and isinstance(data, list): 186 todoList[todo](data, categId[-1]) 187 188 return generatedCalegory
This generates TP_PLUGIN_CATEGORIES struct and also when looping each category it will populate Actions, States, Connectors and Event struct.
def
writetoFile(self, fileName)
190 def writetoFile(self, fileName): 191 """ 192 This method will collects struct INFO, SETTINGS, STATES etc... and write python 193 version of entry.tp to file. 194 """ 195 196 TP_PLUGIN_INFO = self.generateInfo() 197 TP_PLUGIN_SETTINGS = self.generateSettings() 198 TP_PLUGIN_STATES = self.structState 199 TP_PLUGIN_ACTIONS = self.structAction 200 TP_PLUGIN_CONNECTORS = self.structConnector 201 TP_PLUGIN_EVENTS = self.structEvent 202 TP_PLUGIN_CATEGORIES = self.generateCalegories() 203 204 with open(fileName, 'w') as f: 205 f.write("#!/usr/bin/env python3\n") 206 for entryVar in ["TP_PLUGIN_INFO", "TP_PLUGIN_SETTINGS", "TP_PLUGIN_CATEGORIES", "TP_PLUGIN_CONNECTORS", "TP_PLUGIN_ACTIONS", "TP_PLUGIN_STATES", "TP_PLUGIN_EVENTS"]: 207 struct = json.dumps(locals()[entryVar], indent=4, sort_keys=False, skipkeys=True) 208 struct = re.sub(r'": (true|false)(,?)\n', lambda m: f'": {m.group(1).title()}{m.group(2)}\n', struct) 209 f.write(f"{entryVar} = {struct}\n\n")
This method will collects struct INFO, SETTINGS, STATES etc... and write python version of entry.tp to file.
class
toString:
211class toString(): 212 """ 213 This basically `emulate` import a python struct. for example 214 215 ```py 216 import TPPEntry # Python file 217 218 TPPEntry.TP_PLUGIN_INFO # because it contain `TP_PLUGIN_INFO` variable in that file 219 ``` 220 221 and This trys to do same thing as that. 222 ```py 223 import TpToPy 224 225 myEntry = TpToPy.toString(TpToPy.TpToPy("entry.tp")) 226 myEntry.TP_PLUGIN_INFO 227 ``` 228 """ 229 230 def __init__(self, entry): 231 self.entry = TpToPy(entry) 232 233 self.TP_PLUGIN_INFO = self.entry.generateInfo() 234 self.TP_PLUGIN_SETTINGS = self.entry.generateSettings() 235 self.TP_PLUGIN_CATEGORIES = self.entry.generateCalegories() 236 self.TP_PLUGIN_STATES = self.entry.structState 237 self.TP_PLUGIN_ACTIONS = self.entry.structAction 238 self.TP_PLUGIN_CONNECTORS = self.entry.structConnector 239 self.TP_PLUGIN_EVENTS = self.entry.structEvent
This basically emulate
import a python struct. for example
import TPPEntry # Python file
TPPEntry.TP_PLUGIN_INFO # because it contain `TP_PLUGIN_INFO` variable in that file
and This trys to do same thing as that.
import TpToPy
myEntry = TpToPy.toString(TpToPy.TpToPy("entry.tp"))
myEntry.TP_PLUGIN_INFO
toString(entry)
230 def __init__(self, entry): 231 self.entry = TpToPy(entry) 232 233 self.TP_PLUGIN_INFO = self.entry.generateInfo() 234 self.TP_PLUGIN_SETTINGS = self.entry.generateSettings() 235 self.TP_PLUGIN_CATEGORIES = self.entry.generateCalegories() 236 self.TP_PLUGIN_STATES = self.entry.structState 237 self.TP_PLUGIN_ACTIONS = self.entry.structAction 238 self.TP_PLUGIN_CONNECTORS = self.entry.structConnector 239 self.TP_PLUGIN_EVENTS = self.entry.structEvent