|
24 | 24 | <memberTool name="vertex_animation_textures"/> |
25 | 25 | </toolshelf> |
26 | 26 |
|
27 | | - <tool name="update_toolset" label="Update Toolset" icon="CHOP_joystick"> |
28 | | - <helpURL>tool:update_toolset</helpURL> |
29 | | - <script scriptType="python"><![CDATA[import os, shutil, urllib, json, zipfile, platform, hou |
30 | | -
|
31 | | -from PySide2.QtCore import * |
32 | | -from PySide2.QtGui import * |
33 | | -from PySide2.QtWidgets import * |
34 | | -
|
35 | | -REPO_URL = 'https://api.github.com/repos/sideeffects/GameDevelopmentToolset' |
36 | | -BRANCHES = ["Stable", "Development"] |
37 | | -
|
38 | | -SETTINGS_FILE = os.path.join(os.getenv("HOUDINI_USER_PREF_DIR"), "gamedevtoolset.json") |
39 | | -HOUDINI_ENV = os.path.join(os.getenv("HOUDINI_USER_PREF_DIR"), "houdini.env") |
40 | | -
|
41 | | -if platform.system() == "Windows": |
42 | | - HOU_TEMP_PATH = os.path.join(os.getenv("APPDATA"), "SideFX", "GameDevToolset") |
43 | | - HOU_TEMP_PATH_STR = "$APPDATA\\SideFX\\GameDevToolset" |
44 | | -else: |
45 | | - HOU_TEMP_PATH = os.path.join(os.getenv("HOUDINI_USER_PREF_DIR"), "GameDevToolset") |
46 | | - HOU_TEMP_PATH_STR = HOU_TEMP_PATH |
47 | | -
|
48 | | -class UpdateDialog(QDialog): |
49 | | -
|
50 | | - def __init__(self, parent, updater_object): |
51 | | - super(UpdateDialog, self).__init__(parent) |
52 | | - self.setWindowTitle("Game Development Toolset") |
53 | | - self.updater_object = updater_object |
54 | | -
|
55 | | - self.current_version = None |
56 | | - self.current_branch = None |
57 | | -
|
58 | | - if self.updater_object.current_version: |
59 | | - self.current_version = self.updater_object.current_version |
60 | | - if self.updater_object.current_branch: |
61 | | - self.current_branch = self.updater_object.current_branch |
62 | | -
|
63 | | - self.build_ui() |
64 | | -
|
65 | | - def build_ui(self): |
66 | | - installed_group = QGroupBox("Installed Version") |
67 | | - change_group = QGroupBox("Change To") |
68 | | - spacer = QLabel("") |
69 | | -
|
70 | | - # Current Version |
71 | | - current_version_layout = QHBoxLayout() |
72 | | - current_version_lbl = QLabel("Release: ") |
73 | | - current_version = self.current_version |
74 | | - if not current_version: |
75 | | - current_version = "Unknown" |
76 | | -
|
77 | | - current_version_value_lbl = QLabel(current_version) |
78 | | -
|
79 | | - current_version_layout.addWidget(current_version_lbl) |
80 | | - current_version_layout.addWidget(current_version_value_lbl) |
81 | | -
|
82 | | - # Current Branch |
83 | | - current_branch_layout = QHBoxLayout() |
84 | | - current_branch_lbl = QLabel("Branch: ") |
85 | | - current_branch = self.current_branch |
86 | | - if not current_branch: |
87 | | - current_branch = "Unknown" |
88 | | - current_branch_value_lbl = QLabel(current_branch) |
89 | | -
|
90 | | - current_branch_layout.addWidget(current_branch_lbl) |
91 | | - current_branch_layout.addWidget(current_branch_value_lbl) |
92 | | -
|
93 | | - installedgroup_layout = QVBoxLayout(installed_group) |
94 | | -
|
95 | | - installedgroup_layout.addLayout(current_version_layout) |
96 | | - installedgroup_layout.addLayout(current_branch_layout) |
97 | | -
|
98 | | - # Update |
99 | | - version_layout = QHBoxLayout() |
100 | | - update_version_label = QLabel("Release:") |
101 | | -
|
102 | | - self.version_combo = QComboBox(self) |
103 | | - for release in self.updater_object.releases[-10:]: |
104 | | - self.version_combo.addItem(release) |
105 | | -
|
106 | | - version_layout.addWidget(update_version_label) |
107 | | - version_layout.addWidget(self.version_combo) |
108 | | -
|
109 | | - branch_layout = QHBoxLayout() |
110 | | - update_branch_label = QLabel("Branch:") |
111 | | - self.branch_combo = QComboBox(self) |
112 | | - for branch in BRANCHES: |
113 | | - self.branch_combo.addItem(branch) |
114 | | -
|
115 | | - if self.current_branch: |
116 | | - current_index = BRANCHES.index(self.current_branch) |
117 | | - self.branch_combo.setCurrentIndex(current_index) |
118 | | -
|
119 | | - changedgroup_layout = QVBoxLayout(change_group) |
120 | | -
|
121 | | - branch_layout.addWidget(update_branch_label) |
122 | | - branch_layout.addWidget(self.branch_combo) |
123 | | -
|
124 | | - changedgroup_layout.addLayout(version_layout) |
125 | | - changedgroup_layout.addLayout(branch_layout) |
126 | | -
|
127 | | - self.button = QPushButton("Update") |
128 | | - self.uninstallButton = QPushButton("Uninstall") |
129 | | -
|
130 | | - self.button.clicked.connect(self.on_updatebtn_press) |
131 | | - self.uninstallButton.clicked.connect(self.on_uninstallbtn_press) |
132 | | - layout = QVBoxLayout() |
133 | | -
|
134 | | - layout.addWidget(installed_group) |
135 | | - layout.addWidget(change_group) |
136 | | -
|
137 | | - layout.addWidget(spacer) |
138 | | - layout.addWidget(self.button) |
139 | | - layout.addWidget(self.uninstallButton) |
140 | | - self.setLayout(layout) |
141 | | -
|
142 | | - def on_updatebtn_press(self): |
143 | | - version = self.version_combo.currentText() |
144 | | - branch = self.branch_combo.currentText() |
145 | | - self.updater_object.on_dialog_close(version, branch, "change") |
146 | | - self.close() |
147 | | -
|
148 | | - def on_uninstallbtn_press(self): |
149 | | - version = self.version_combo.currentText() |
150 | | - branch = self.branch_combo.currentText() |
151 | | - self.updater_object.on_dialog_close(version, branch, "uninstall") |
152 | | - self.close() |
153 | | -
|
154 | | -
|
155 | | -class GameDevelopmentUpdater(object): |
156 | | -
|
157 | | - def __init__(self): |
158 | | - self.releases = [] |
159 | | - self.desired_version = None |
160 | | - self.desired_branch = None |
161 | | - |
162 | | - self.cleanup_old_installs() |
163 | | - self.load_settings() |
164 | | - self.get_releases() |
165 | | - self.show_dialog() |
166 | | -
|
167 | | - def cleanup_old_installs(self): |
168 | | - houdini_pref_dir = os.getenv("HOUDINI_USER_PREF_DIR") |
169 | | - |
170 | | - otl = os.path.join(houdini_pref_dir, "otls", "SideFX_GameDevelopmentToolset.hda") |
171 | | - desktop = os.path.join(houdini_pref_dir, "desktop", "Games_Minimal.desk") |
172 | | - toolbar = os.path.join(houdini_pref_dir, "toolbar", "game_development_toolset.shelf") |
173 | | - script = os.path.join(houdini_pref_dir, "scripts", "python", "hou_settings.py") |
174 | | - |
175 | | - to_delete = [otl, desktop, toolbar, script] |
176 | | - for filename in to_delete: |
177 | | - if os.path.exists(filename): |
178 | | - os.remove(filename) |
179 | | - |
180 | | - def get_releases(self): |
181 | | - response = urllib.urlopen(REPO_URL + "/releases") |
182 | | - data = response.read() |
183 | | - if ( data == "" ): |
184 | | - raise ValueError("Unable to get the release list") |
185 | | - j_data = json.loads(data.decode('utf-8')) |
186 | | - for release in j_data: |
187 | | - self.releases.append(release["tag_name"]) |
188 | | -
|
189 | | - def show_dialog(self): |
190 | | - dialog = UpdateDialog(hou.ui.mainQtWindow(), self) |
191 | | - dialog.show() |
192 | | -
|
193 | | - def download_url(self, url): |
194 | | - filename = os.path.basename(url) |
195 | | - local_path = os.path.join(HOU_TEMP_PATH, filename) |
196 | | - if not os.path.exists(os.path.dirname(local_path)): |
197 | | - os.makedirs(os.path.dirname(local_path)) |
198 | | - urllib.urlretrieve(url, local_path) |
199 | | - return local_path |
200 | | -
|
201 | | - def get_download_path(self, version, branch): |
202 | | - response = urllib.urlopen(REPO_URL + "/releases/tags/" + version) |
203 | | - data = response.read() |
204 | | - if ( data == "" ): |
205 | | - raise ValueError("Unable to get the release tags") |
206 | | - j_data = json.loads(data.decode('utf-8')) |
207 | | - for asset in j_data["assets"]: |
208 | | - if branch in os.path.basename(asset["browser_download_url"]): |
209 | | - return asset["browser_download_url"] |
210 | | - |
211 | | - def unzip_file(self, zip_file, destination_path): |
212 | | - zipf = zipfile.ZipFile(zip_file, 'r', zipfile.ZIP_DEFLATED) |
213 | | - zipf.extractall(destination_path) |
214 | | -
|
215 | | - def load_settings(self): |
216 | | - try: |
217 | | - with open(SETTINGS_FILE, 'r') as fp: |
218 | | - settings = json.load(fp) |
219 | | - self.current_version = settings["current_version"] |
220 | | - self.current_branch = settings["current_branch"] |
221 | | - except: |
222 | | - self.current_version = None |
223 | | - self.current_branch = None |
224 | | -
|
225 | | - def store_settings(self): |
226 | | - settings = {"current_version": self.desired_version, |
227 | | - "current_branch": self.desired_branch} |
228 | | -
|
229 | | - with open(SETTINGS_FILE, 'w') as fp: |
230 | | - json.dump(settings, fp) |
231 | | -
|
232 | | - def show_success_dialog(self, mode): |
233 | | - msg = QMessageBox() |
234 | | - msg.setIcon(QMessageBox.Information) |
235 | | -
|
236 | | - if mode == "change": |
237 | | - msg.setText("Game Development Toolset Updated Successfully") |
238 | | - msg.setInformativeText("Please Restart Houdini to load all of the new tools") |
239 | | - msg.setWindowTitle("Success") |
240 | | - elif mode == "uninstall": |
241 | | - msg.setText("Game Development Toolset Uninstalled Successfully") |
242 | | - msg.setInformativeText("Please Restart Houdini for changes to take effect") |
243 | | - msg.setWindowTitle("Success") |
244 | | - retval = msg.exec_() |
245 | | -
|
246 | | - def on_dialog_close(self, version, branch, mode): |
247 | | - self.desired_version = version |
248 | | - self.desired_branch = branch |
249 | | -
|
250 | | - if mode == "change": |
251 | | - download_url = self.get_download_path(version, branch) |
252 | | - if not download_url: |
253 | | - hou.ui.displayMessage("Package not Available for this branch", severity=hou.severityType.Error) |
254 | | - return |
255 | | - |
256 | | - local_path = self.download_url(download_url) |
257 | | - self.unzip_file(local_path, os.path.join(HOU_TEMP_PATH, version, branch)) |
258 | | - os.remove(local_path) |
259 | | - self.patch_houdini_env(version, branch, "change") |
260 | | - self.store_settings() |
261 | | - self.show_success_dialog("change") |
262 | | -
|
263 | | - elif mode == "uninstall": |
264 | | - #Patch ENV var |
265 | | - self.patch_houdini_env(version, branch, "uninstall") |
266 | | - self.desired_branch = None |
267 | | - self.desired_version = None |
268 | | - self.store_settings() |
269 | | -
|
270 | | - #Delete Installed Files |
271 | | - removedir = os.path.join(HOU_TEMP_PATH, version) |
272 | | - if os.path.exists(removedir): |
273 | | - shutil.rmtree(removedir, ignore_errors=True) |
274 | | - |
275 | | - self.show_success_dialog("uninstall") |
276 | | -
|
277 | | - def patch_houdini_env(self, version, branch, mode): |
278 | | - filepath = HOUDINI_ENV |
279 | | - if platform.system() == "Windows": |
280 | | - sep = ";" |
281 | | - quote_char = "" |
282 | | - else: |
283 | | - sep = ":" |
284 | | - quote_char = "\"" |
285 | | -
|
286 | | - to_write = [] |
287 | | - with open(filepath, "r") as fp: |
288 | | - for line in fp.readlines(): |
289 | | - if "# GAME DEVELOPMENT TOOLSET" in line: |
290 | | - continue |
291 | | -
|
292 | | - if HOU_TEMP_PATH_STR in line: |
293 | | - continue |
294 | | -
|
295 | | - to_write.append(line) |
296 | | -
|
297 | | - if to_write[-1] != "\n": |
298 | | - to_write.append("\n") |
299 | | -
|
300 | | - if mode == "change": |
301 | | - to_write.append("# GAME DEVELOPMENT TOOLSET\n") |
302 | | -
|
303 | | - entry = "HOUDINI_PATH = " |
304 | | - entry += quote_char + HOU_TEMP_PATH_STR + "\\" |
305 | | - entry += version + "\\" + branch |
306 | | - entry += sep + "&" + quote_char + "\n" |
307 | | - to_write.append(entry) |
308 | | -
|
309 | | - with open(filepath, "w") as fp: |
310 | | - for line in to_write: |
311 | | - fp.write(line) |
312 | | -
|
313 | | -GameDevelopmentUpdater()]]></script> |
314 | | - </tool> |
315 | | - |
316 | 27 | <tool name="rop_games_baker" label="Games Baker" icon="COMMON_bake"> |
317 | 28 | <helpURL>operator:Driver/rop_games_baker</helpURL> |
318 | 29 | <script scriptType="python"><![CDATA[import roptoolutils |
|
0 commit comments